diff --git a/.gitignore b/.gitignore index 9187343927..c60be9a5f9 100644 --- a/.gitignore +++ b/.gitignore @@ -28,8 +28,6 @@ Windows/ARM64 Windows/ipch Windows/bin-release Windows/win-version.h -ui_atlas.zim.png -ui_atlas_high.zim.png android/assets ext/_Output android/lint.xml @@ -87,9 +85,9 @@ __testfinish.txt __testfailure.bmp GameLogNotes.txt screenshots -android/ui_atlas.zim android/assets/lang android/assets/flash0 +ui_atlas.zim.png ppge_atlas.zim.png local.properties r.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 00e5e3ec0f..99a330ed5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -863,7 +863,6 @@ list(APPEND NativeAppSource UI/CwCheatScreen.cpp UI/InstallZipScreen.cpp UI/ProfilerDraw.cpp - UI/ui_atlas.cpp UI/TextureUtil.cpp UI/ComboKeyMappingScreen.cpp ) @@ -1754,8 +1753,6 @@ add_library(${CoreLibName} ${CoreLinkType} Core/Util/BlockAllocator.h Core/Util/PPGeDraw.cpp Core/Util/PPGeDraw.h - Core/Util/ppge_atlas.cpp - Core/Util/ppge_atlas.h ${CORE_NEON} ${GPU_SOURCES} ext/disarm.cpp @@ -1927,6 +1924,7 @@ endif() set(NativeAssets android/assets/ui_atlas.zim + android/assets/ui_atlas.meta assets/lang assets/shaders assets/Roboto-Condensed.ttf @@ -1935,6 +1933,7 @@ set(NativeAssets assets/gamecontrollerdb.txt assets/langregion.ini assets/ppge_atlas.zim + assets/ppge_atlas.meta assets/rargray.png assets/unknown.png assets/zip.png diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 021cbfb153..720673025c 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -71,7 +71,6 @@ - StaticLibrary @@ -834,7 +833,6 @@ - MaxSpeed true @@ -1166,7 +1164,6 @@ - diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index d1257aa716..19698164c2 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -336,9 +336,6 @@ Util - - Util - HLE\Libraries @@ -1000,9 +997,6 @@ Util - - Util - HLE\Libraries diff --git a/Core/Dialog/PSPDialog.cpp b/Core/Dialog/PSPDialog.cpp index 64b5d6197d..9ddc44f630 100644 --- a/Core/Dialog/PSPDialog.cpp +++ b/Core/Dialog/PSPDialog.cpp @@ -144,8 +144,13 @@ void PSPDialog::DoState(PointerWrap &p) p.Do(isFading); p.Do(fadeIn); p.Do(fadeValue); + + // I don't think we should save these two... Let's just ignore them for now for compat. + int okButtonImg = 0; p.Do(okButtonImg); + int cancelButtonImg = 0; p.Do(cancelButtonImg); + p.Do(okButtonFlag); p.Do(cancelButtonFlag); diff --git a/Core/Dialog/PSPDialog.h b/Core/Dialog/PSPDialog.h index d7875078c3..4de49d27f0 100644 --- a/Core/Dialog/PSPDialog.h +++ b/Core/Dialog/PSPDialog.h @@ -17,6 +17,8 @@ #pragma once +#include "gfx/texture_atlas.h" + #include "Common/Common.h" #include "Common/CommonTypes.h" #include "Common/Swap.h" @@ -112,8 +114,8 @@ protected: bool fadeIn; u32 fadeValue; - int okButtonImg; - int cancelButtonImg; + ImageID okButtonImg; + ImageID cancelButtonImg; int okButtonFlag; int cancelButtonFlag; }; diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp index 7ef30d7691..404c375734 100755 --- a/Core/Dialog/PSPMsgDialog.cpp +++ b/Core/Dialog/PSPMsgDialog.cpp @@ -225,14 +225,14 @@ int PSPMsgDialog::Update(int animSpeed) { UpdateButtons(); UpdateFade(animSpeed); - okButtonImg = I_CIRCLE; - cancelButtonImg = I_CROSS; + okButtonImg = ImageID("I_CIRCLE"); + cancelButtonImg = ImageID("I_CROSS"); okButtonFlag = CTRL_CIRCLE; cancelButtonFlag = CTRL_CROSS; if (messageDialog.common.buttonSwap == 1) { - okButtonImg = I_CROSS; - cancelButtonImg = I_CIRCLE; + okButtonImg = ImageID("I_CROSS"); + cancelButtonImg = ImageID("I_CIRCLE"); okButtonFlag = CTRL_CROSS; cancelButtonFlag = CTRL_CIRCLE; } diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index a4f4df8083..9d7a37fc49 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -71,7 +71,7 @@ int PSPNetconfDialog::Update(int animSpeed) { auto di = GetI18NCategory("Dialog"); auto err = GetI18NCategory("Error"); const float WRAP_WIDTH = 254.0f; - const int confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? I_CROSS : I_CIRCLE; + const ImageID confirmBtnImage = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? ImageID("I_CROSS") : ImageID("I_CIRCLE"); const int confirmBtn = g_Config.iButtonPreference == PSP_SYSTEMPARAM_BUTTON_CROSS ? CTRL_CROSS : CTRL_CIRCLE; if (status == SCE_UTILITY_STATUS_INITIALIZE) { diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index b1b7cde8af..683aaf135a 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -919,15 +919,15 @@ int PSPOskDialog::Update(int animSpeed) { auto di = GetI18NCategory("Dialog"); - PPGeDrawImage(I_SQUARE, 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); PPGeDrawText(di->T("Space"), 390, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); if (g_Config.iButtonPreference != PSP_SYSTEMPARAM_BUTTON_CIRCLE) { - PPGeDrawImage(I_CROSS, 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawImage(I_CIRCLE, 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_CIRCLE"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); } else { - PPGeDrawImage(I_CIRCLE, 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawImage(I_CROSS, 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_CIRCLE"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF)); } PPGeDrawText(di->T("Select"), 75, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index e0a27decaf..17fdebd950 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -610,13 +610,13 @@ int PSPSaveDialog::Update(int animSpeed) UpdateButtons(); UpdateFade(animSpeed); - okButtonImg = I_CIRCLE; - cancelButtonImg = I_CROSS; + okButtonImg = ImageID("I_CIRCLE"); + cancelButtonImg = ImageID("I_CROSS"); okButtonFlag = CTRL_CIRCLE; cancelButtonFlag = CTRL_CROSS; if (param.GetPspParam()->common.buttonSwap == 1) { - okButtonImg = I_CROSS; - cancelButtonImg = I_CIRCLE; + okButtonImg = ImageID("I_CROSS"); + cancelButtonImg = ImageID("I_CIRCLE"); okButtonFlag = CTRL_CROSS; cancelButtonFlag = CTRL_CIRCLE; } diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index d0bd9ae4c7..ccd9abc453 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -18,6 +18,8 @@ #include #include "base/stringutil.h" +#include "file/vfs.h" +#include "gfx/texture_atlas.h" #include "image/zim_load.h" #include "image/png_load.h" #include "util/text/utf8.h" @@ -36,6 +38,8 @@ #include "Core/MemMapHelpers.h" #include "Core/System.h" +Atlas g_ppge_atlas; + static u32 atlasPtr; static int atlasWidth; static int atlasHeight; @@ -190,6 +194,12 @@ void __PPGeInit() return; } + size_t atlas_data_size; + uint8_t *atlas_data; + atlas_data = VFSReadFile("ppge_atlas.meta", &atlas_data_size); + g_ppge_atlas.Load(atlas_data, atlas_data_size); + delete[] atlas_data; + u32 atlasSize = height[0] * width[0] / 2; // it's a 4-bit paletted texture in ram atlasWidth = width[0]; atlasHeight = height[0]; @@ -617,7 +627,7 @@ static AtlasTextMetrics BreakLines(const char *text, const AtlasFont &atlasfont, void PPGeMeasureText(float *w, float *h, int *n, const char *text, float scale, int WrapType, int wrapWidth) { - const AtlasFont &atlasfont = *ppge_atlas.fonts[0]; + const AtlasFont &atlasfont = g_ppge_atlas.fonts[0]; AtlasTextMetrics metrics = BreakLines(text, atlasfont, 0, 0, 0, scale, scale, WrapType, wrapWidth, true); if (w) *w = metrics.maxWidth; if (h) *h = metrics.lineHeight; @@ -626,7 +636,7 @@ void PPGeMeasureText(float *w, float *h, int *n, void PPGePrepareText(const char *text, float x, float y, int align, float scale, float lineHeightScale, int WrapType, int wrapWidth) { - const AtlasFont &atlasfont = *ppge_atlas.fonts[0]; + const AtlasFont &atlasfont = g_ppge_atlas.fonts[0]; char_lines_metrics = BreakLines(text, atlasfont, x, y, align, scale, lineHeightScale, WrapType, wrapWidth, false); } @@ -731,15 +741,16 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl } // Draws a "4-patch" for button-like things that can be resized -void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color) -{ +void PPGeDraw4Patch(ImageID atlasImage, float x, float y, float w, float h, u32 color) { if (!dlPtr) return; - const AtlasImage &img = ppge_images[atlasImage]; - float borderx = img.w / 20; - float bordery = img.h / 20; - float u1 = img.u1, uhalf = (img.u1 + img.u2) / 2, u2 = img.u2; - float v1 = img.v1, vhalf = (img.v1 + img.v2) / 2, v2 = img.v2; + const AtlasImage *img = g_ppge_atlas.getImage(atlasImage); + if (!img) + return; + float borderx = img->w / 20; + float bordery = img->h / 20; + float u1 = img->u1, uhalf = (img->u1 + img->u2) / 2, u2 = img->u2; + float v1 = img->v1, vhalf = (img->v1 + img->v2) / 2, v2 = img->v2; float xmid1 = x + borderx; float xmid2 = x + w - borderx; float ymid1 = y + bordery; @@ -771,8 +782,7 @@ void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 colo EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } -void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color) -{ +void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color) { if (!dlPtr) return; @@ -787,29 +797,32 @@ void PPGeDrawRect(float x1, float y1, float x2, float y2, u32 color) } // Just blits an image to the screen, multiplied with the color. -void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color) +void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color) { if (!dlPtr) return; - const AtlasImage &img = ppge_atlas.images[atlasImage]; - float w = img.w; - float h = img.h; + const AtlasImage *img = g_ppge_atlas.getImage(atlasImage); + if (!img) { + return; + } + float w = img->w; + float h = img->h; BeginVertexData(); - Vertex(x, y, img.u1, img.v1, atlasWidth, atlasHeight, color); - Vertex(x + w, y + h, img.u2, img.v2, atlasWidth, atlasHeight, color); + Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color); + Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color); EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } -void PPGeDrawImage(int atlasImage, float x, float y, float w, float h, int align, u32 color) +void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int align, u32 color) { if (!dlPtr) return; - const AtlasImage &img = ppge_atlas.images[atlasImage]; + const AtlasImage *img = g_ppge_atlas.getImage(atlasImage); BeginVertexData(); - Vertex(x, y, img.u1, img.v1, atlasWidth, atlasHeight, color); - Vertex(x + w, y + h, img.u2, img.v2, atlasWidth, atlasHeight, color); + Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color); + Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color); EndVertexDataAndDraw(GE_PRIM_RECTANGLES); } diff --git a/Core/Util/PPGeDraw.h b/Core/Util/PPGeDraw.h index df18dd0dbc..a599c45e37 100644 --- a/Core/Util/PPGeDraw.h +++ b/Core/Util/PPGeDraw.h @@ -19,7 +19,9 @@ #include #include -#include "ppge_atlas.h" + +#include "gfx/texture_atlas.h" + #include "Common/CommonTypes.h" class PointerWrap; @@ -98,11 +100,11 @@ void PPGeDrawText(const char *text, float x, float y, int align, float scale = 1 void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, int align, float scale = 1.0f, u32 color = 0xFFFFFFFF); // Draws a "4-patch" for button-like things that can be resized. -void PPGeDraw4Patch(int atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF); +void PPGeDraw4Patch(ImageID atlasImage, float x, float y, float w, float h, u32 color = 0xFFFFFFFF); // Just blits an image to the screen, multiplied with the color. -void PPGeDrawImage(int atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF); -void PPGeDrawImage(int atlasImage, float x, float y, float w, float h, int align, u32 color = 0xFFFFFFFF); +void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color = 0xFFFFFFFF); +void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int align, u32 color = 0xFFFFFFFF); void PPGeDrawImage(float x, float y, float w, float h, float u1, float v1, float u2, float v2, int tw, int th, u32 color); class PPGeImage { diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 37178dde9b..cdfc3e47f9 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -17,7 +17,6 @@ #include "TouchControlVisibilityScreen.h" #include "Core/Config.h" -#include "UI/ui_atlas.h" #include "i18n/i18n.h" #include "ComboKeyMappingScreen.h" #include "base/colorutil.h" @@ -25,6 +24,7 @@ #include "base/timeutil.h" #include "file/path.h" #include "gfx_es2/draw_buffer.h" +#include "gfx/texture_atlas.h" #include "math/curves.h" #include "base/stringutil.h" #include "ui/ui_context.h" @@ -41,11 +41,11 @@ void Combo_keyScreen::CreateViews() { LinearLayout *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(120, FILL_PARENT)); auto di = GetI18NCategory("Dialog"); - static const int comboKeyImages[5] = { - I_1, I_2, I_3, I_4, I_5, + static const ImageID comboKeyImages[5] = { + ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5"), }; - comboselect = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(10, 10, NONE, NONE)); + comboselect = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(10, 10, NONE, NONE)); comboselect->SetSpacing(10); for (int i = 0; i < 5; i++) { comboselect->AddChoice(comboKeyImages[i]); @@ -95,15 +95,15 @@ void Combo_keyScreen::CreateViews() { break; } - std::map keyImages; - keyImages["Circle"] = I_CIRCLE; - keyImages["Cross"] = I_CROSS; - keyImages["Square"] = I_SQUARE; - keyImages["Triangle"] = I_TRIANGLE; - keyImages["L"] = I_L; - keyImages["R"] = I_R; - keyImages["Start"] = I_START; - keyImages["Select"] = I_SELECT; + std::map keyImages; + keyImages["Circle"] = ImageID("I_CIRCLE"); + keyImages["Cross"] = ImageID("I_CROSS"); + keyImages["Square"] = ImageID("I_SQUARE"); + keyImages["Triangle"] = ImageID("I_TRIANGLE"); + keyImages["L"] = ImageID("I_L"); + keyImages["R"] = ImageID("I_R"); + keyImages["Start"] = ImageID("I_START"); + keyImages["Select"] = ImageID("I_SELECT"); keyToggles["Circle"] = &array[13]; keyToggles["Cross"] = &array[14]; keyToggles["Square"] = &array[15]; @@ -117,7 +117,7 @@ void Combo_keyScreen::CreateViews() { keyToggles["Start"] = &array[3]; keyToggles["Select"] = &array[0]; - std::map::iterator imageFinder; + std::map::iterator imageFinder; auto mc = GetI18NCategory("MappableControls"); diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index e9649eace1..39a9d5104d 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -22,6 +22,7 @@ #include "base/colorutil.h" #include "base/logging.h" #include "base/display.h" +#include "gfx/texture_atlas.h" #include "i18n/i18n.h" #include "input/keycodes.h" #include "input/input_state.h" @@ -35,7 +36,6 @@ #include "Core/System.h" #include "Common/KeyMap.h" #include "Core/Config.h" -#include "UI/ui_atlas.h" #include "UI/ControlMappingScreen.h" #include "UI/GameSettingsScreen.h" @@ -90,15 +90,15 @@ void ControlMapper::Refresh() { Clear(); auto mc = GetI18NCategory("MappableControls"); - std::map keyImages; - keyImages["Circle"] = I_CIRCLE; - keyImages["Cross"] = I_CROSS; - keyImages["Square"] = I_SQUARE; - keyImages["Triangle"] = I_TRIANGLE; - keyImages["Start"] = I_START; - keyImages["Select"] = I_SELECT; - keyImages["L"] = I_L; - keyImages["R"] = I_R; + std::map keyImages; + keyImages["Circle"] = ImageID("I_CIRCLE"); + keyImages["Cross"] = ImageID("I_CROSS"); + keyImages["Square"] = ImageID("I_SQUARE"); + keyImages["Triangle"] = ImageID("I_TRIANGLE"); + keyImages["Start"] = ImageID("I_START"); + keyImages["Select"] = ImageID("I_SELECT"); + keyImages["L"] = ImageID("I_L"); + keyImages["R"] = ImageID("I_R"); using namespace UI; @@ -465,8 +465,11 @@ private: void JoystickHistoryView::Draw(UIContext &dc) { if (xAxis_ > -1 && yAxis_ > -1) { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[I_CROSS]; - float minRadius = std::min(bounds_.w, bounds_.h) * 0.5f - image.w; + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(ImageID("I_CROSS")); + if (!image) { + return; + } + float minRadius = std::min(bounds_.w, bounds_.h) * 0.5f - image->w; dc.BeginNoTex(); dc.Draw()->RectOutline(bounds_.centerX() - minRadius, bounds_.centerY() - minRadius, minRadius * 2.0f, minRadius * 2.0f, 0x80FFFFFF); dc.Flush(); @@ -479,7 +482,7 @@ void JoystickHistoryView::Draw(UIContext &dc) { if (alpha < 0.0f) { alpha = 0.0f; } - dc.Draw()->DrawImage(I_CROSS, x, y, 0.8f, colorAlpha(0xFFFFFF, alpha), ALIGN_CENTER); + dc.Draw()->DrawImage(ImageID("I_CROSS"), x, y, 0.8f, colorAlpha(0xFFFFFF, alpha), ALIGN_CENTER); a++; } dc.Flush(); diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index 095ec55fb6..f6fefceb45 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -16,6 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "input/input_state.h" #include "ui/ui.h" #include "util/text/utf8.h" @@ -28,7 +29,6 @@ #include "Core/MIPS/JitCommon/JitCommon.h" #include "UI/OnScreenDisplay.h" -#include "UI/ui_atlas.h" #include "UI/MainScreen.h" #include "UI/EmuScreen.h" @@ -316,7 +316,7 @@ void CheatCheckBox::Draw(UIContext &dc) { int paddingX = 16; int paddingY = 12; - int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff; + ImageID image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff; UI::Style style = dc.theme->itemStyle; if (!IsEnabled()) diff --git a/UI/DisplayLayoutEditor.cpp b/UI/DisplayLayoutEditor.cpp index 882266112f..77da5f407e 100644 --- a/UI/DisplayLayoutEditor.cpp +++ b/UI/DisplayLayoutEditor.cpp @@ -17,13 +17,17 @@ #include #include "ui/ui_context.h" -#include "ui_atlas.h" #include "UI/DisplayLayoutEditor.h" void MultiTouchDisplay::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[img_]; - w = image.w * scale_; - h = image.h * scale_; + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(img_); + if (image) { + w = image->w * scale_; + h = image->h * scale_; + } else { + w = 0.0f; + h = 0.0f; + } } void MultiTouchDisplay::Touch(const TouchInput &input) { diff --git a/UI/DisplayLayoutEditor.h b/UI/DisplayLayoutEditor.h index a6cfefb1cf..6cdd7a454d 100644 --- a/UI/DisplayLayoutEditor.h +++ b/UI/DisplayLayoutEditor.h @@ -16,13 +16,15 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #pragma once + +#include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "ui/view.h" #include "ui/viewgroup.h" class MultiTouchDisplay : public UI::View { public: - MultiTouchDisplay(int img, float scale, UI::LayoutParams *layoutParams) + MultiTouchDisplay(ImageID img, float scale, UI::LayoutParams *layoutParams) : UI::View(layoutParams), pointerDownMask_(0), scale_(scale), img_(img), angle_(0.0f), flipImageH_(false) { } virtual void Touch(const TouchInput &input) override; @@ -37,14 +39,14 @@ protected: float scale_; private: - int img_; + ImageID img_; float angle_; bool flipImageH_; }; class PSPDisplay : public MultiTouchDisplay { public: - PSPDisplay(int img, float scale, UI::LayoutParams *layoutParams) + PSPDisplay(ImageID img, float scale, UI::LayoutParams *layoutParams) : MultiTouchDisplay(img, scale, layoutParams) { } }; diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 6a5cedbff5..7cf6bbe7cd 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -18,11 +18,11 @@ #include #include "base/colorutil.h" +#include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "ui/ui_context.h" #include "ui/view.h" -#include "ui_atlas.h" #include "DisplayLayoutScreen.h" #include "Core/Config.h" @@ -40,8 +40,8 @@ static float local_dp_yres; class DragDropDisplay : public MultiTouchDisplay { public: - DragDropDisplay(float &x, float &y, int img, float &scale) - : MultiTouchDisplay(img, scale, new UI::AnchorLayoutParams(x*local_dp_xres, y*local_dp_yres, UI::NONE, UI::NONE, true)), + DragDropDisplay(float &x, float &y, ImageID img, float &scale) + : MultiTouchDisplay(img, scale, new UI::AnchorLayoutParams(x * local_dp_xres, y * local_dp_yres, UI::NONE, UI::NONE, true)), x_(x), y_(y), theScale_(scale) { scale_ = theScale_; } @@ -73,7 +73,9 @@ bool DisplayLayoutScreen::touch(const TouchInput &touch) { using namespace UI; int mode = mode_ ? mode_->GetSelection() : 0; - if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { mode = -1; } + if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { + mode = -1; + } const Bounds &screen_bounds = screenManager()->getUIContext()->GetBounds(); if ((touch.flags & TOUCH_MOVE) && picked_ != 0) { @@ -304,11 +306,11 @@ void DisplayLayoutScreen::CreateViews() { mode_->AddChoice(di->T("Resize")); mode_->SetSelection(0); } - displayRepresentation_ = new DragDropDisplay(g_Config.fSmallDisplayOffsetX, g_Config.fSmallDisplayOffsetY, I_PSP_DISPLAY, displayRepresentationScale_); + displayRepresentation_ = new DragDropDisplay(g_Config.fSmallDisplayOffsetX, g_Config.fSmallDisplayOffsetY, ImageID("I_PSP_DISPLAY"), displayRepresentationScale_); displayRepresentation_->SetVisibility(V_VISIBLE); } else { // Stretching label = new HighlightLabel(gr->T("Stretching"), new AnchorLayoutParams(WRAP_CONTENT, 64.0f, local_dp_xres / 2.0f, local_dp_yres / 2.0f, NONE, NONE, true)); - displayRepresentation_ = new DragDropDisplay(g_Config.fSmallDisplayOffsetX, g_Config.fSmallDisplayOffsetY, I_PSP_DISPLAY, displayRepresentationScale_); + displayRepresentation_ = new DragDropDisplay(g_Config.fSmallDisplayOffsetX, g_Config.fSmallDisplayOffsetY, ImageID("I_PSP_DISPLAY"), displayRepresentationScale_); displayRepresentation_->SetVisibility(V_INVISIBLE); float width = previewWidth; float height = previewHeight; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index c4e3574ede..6e5b51acd2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -24,6 +24,7 @@ #include "base/timeutil.h" #include "profiler/profiler.h" +#include "gfx/texture_atlas.h" #include "gfx_es2/gpu_features.h" #include "gfx_es2/draw_text.h" @@ -62,7 +63,6 @@ #include "Core/MIPS/MIPS.h" #include "Core/HLE/__sceAudio.h" -#include "UI/ui_atlas.h" #include "UI/BackgroundAudio.h" #include "UI/OnScreenDisplay.h" #include "UI/GamepadEmu.h" @@ -988,12 +988,13 @@ void EmuScreen::CreateViews() { TextView *loadingTextView = root_->Add(new TextView(sc->T(PSP_GetLoading()), new AnchorLayoutParams(bounds.centerX(), NONE, NONE, 40, true))); loadingTextView_ = loadingTextView; - static const int symbols[4] = { - I_CROSS, - I_CIRCLE, - I_SQUARE, - I_TRIANGLE + static const ImageID symbols[4] = { + ImageID("I_CROSS"), + ImageID("I_CIRCLE"), + ImageID("I_SQUARE"), + ImageID("I_TRIANGLE"), }; + Spinner *loadingSpinner = root_->Add(new Spinner(symbols, ARRAY_SIZE(symbols), new AnchorLayoutParams(NONE, NONE, 45, 45, true))); loadingSpinner_ = loadingSpinner; @@ -1140,19 +1141,22 @@ void EmuScreen::checkPowerDown() { } static void DrawDebugStats(DrawBuffer *draw2d) { + FontID ubuntu24("UBUNTU24"); + char statbuf[4096]; __DisplayGetDebugStats(statbuf, sizeof(statbuf)); draw2d->SetFontScale(.7f, .7f); - draw2d->DrawText(UBUNTU24, statbuf, 11, 31, 0xc0000000, FLAG_DYNAMIC_ASCII); - draw2d->DrawText(UBUNTU24, statbuf, 10, 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, statbuf, 11, 31, 0xc0000000, FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, statbuf, 10, 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); __SasGetDebugStats(statbuf, sizeof(statbuf)); - draw2d->DrawText(UBUNTU24, statbuf, PSP_CoreParameter().pixelWidth / 2 + 11, 31, 0xc0000000, FLAG_DYNAMIC_ASCII); - draw2d->DrawText(UBUNTU24, statbuf, PSP_CoreParameter().pixelWidth / 2 + 10, 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, statbuf, PSP_CoreParameter().pixelWidth / 2 + 11, 31, 0xc0000000, FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, statbuf, PSP_CoreParameter().pixelWidth / 2 + 10, 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); draw2d->SetFontScale(1.0f, 1.0f); } static void DrawAudioDebugStats(DrawBuffer *draw2d) { + FontID ubuntu24("UBUNTU24"); char statbuf[1024] = { 0 }; const AudioDebugStats *stats = __AudioGetDebugStats(); snprintf(statbuf, sizeof(statbuf), @@ -1167,12 +1171,13 @@ static void DrawAudioDebugStats(DrawBuffer *draw2d) { stats->instantSampleRate, stats->lastPushSize); draw2d->SetFontScale(0.7f, 0.7f); - draw2d->DrawText(UBUNTU24, statbuf, 11, 31, 0xc0000000, FLAG_DYNAMIC_ASCII); - draw2d->DrawText(UBUNTU24, statbuf, 10, 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, statbuf, 11, 31, 0xc0000000, FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, statbuf, 10, 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); draw2d->SetFontScale(1.0f, 1.0f); } static void DrawFPS(DrawBuffer *draw2d, const Bounds &bounds) { + FontID ubuntu24("UBUNTU24"); float vps, fps, actual_fps; __DisplayGetFPS(&vps, &fps, &actual_fps); char fpsbuf[256]; @@ -1188,12 +1193,13 @@ static void DrawFPS(DrawBuffer *draw2d, const Bounds &bounds) { } draw2d->SetFontScale(0.7f, 0.7f); - draw2d->DrawText(UBUNTU24, fpsbuf, bounds.x2() - 8, 12, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); - draw2d->DrawText(UBUNTU24, fpsbuf, bounds.x2() - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, fpsbuf, bounds.x2() - 8, 12, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); + draw2d->DrawText(ubuntu24, fpsbuf, bounds.x2() - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII); draw2d->SetFontScale(1.0f, 1.0f); } static void DrawFrameTimes(UIContext *ctx) { + FontID ubuntu24("UBUNTU24"); int valid, pos; double *sleepHistory; double *history = __DisplayGetFrameTimes(&valid, &pos, &sleepHistory); @@ -1216,8 +1222,8 @@ static void DrawFrameTimes(UIContext *ctx) { ctx->Flush(); ctx->Begin(); ctx->Draw()->SetFontScale(0.5f, 0.5f); - ctx->Draw()->DrawText(UBUNTU24, "33.3ms", width, bottom - 0.0333*scale, 0xFF3f3Fff, ALIGN_BOTTOMLEFT | FLAG_DYNAMIC_ASCII); - ctx->Draw()->DrawText(UBUNTU24, "16.7ms", width, bottom - 0.0167*scale, 0xFF3f3Fff, ALIGN_BOTTOMLEFT | FLAG_DYNAMIC_ASCII); + ctx->Draw()->DrawText(ubuntu24, "33.3ms", width, bottom - 0.0333*scale, 0xFF3f3Fff, ALIGN_BOTTOMLEFT | FLAG_DYNAMIC_ASCII); + ctx->Draw()->DrawText(ubuntu24, "16.7ms", width, bottom - 0.0167*scale, 0xFF3f3Fff, ALIGN_BOTTOMLEFT | FLAG_DYNAMIC_ASCII); ctx->Draw()->SetFontScale(1.0f, 1.0f); } diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 33074604af..421914a7b2 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -22,11 +22,11 @@ #include "Core/System.h" #include "Core/HLE/sceCtrl.h" #include "UI/GamepadEmu.h" -#include "UI/ui_atlas.h" #include "base/colorutil.h" #include "base/display.h" #include "base/NativeApp.h" #include "base/timeutil.h" +#include "gfx/texture_atlas.h" #include "math/math_util.h" #include "ui/ui_context.h" @@ -70,9 +70,14 @@ float GamepadView::GetButtonOpacity() { } void MultiTouchButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[bgImg_]; - w = image.w * scale_; - h = image.h * scale_; + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(bgImg_); + if (image) { + w = image->w * scale_; + h = image->h * scale_; + } else { + w = 0.0f; + h = 0.0f; + } } void MultiTouchButton::Touch(const TouchInput &input) { @@ -123,7 +128,7 @@ void MultiTouchButton::Draw(UIContext &dc) { int y = bounds_.centerY(); // Hack round the fact that the center of the rectangular picture the triangle is contained in // is not at the "weight center" of the triangle. - if (img_ == I_TRIANGLE) + if (img_ == ImageID("I_TRIANGLE")) y -= 2.8f * scale; dc.Draw()->DrawImageRotated(img_, bounds_.centerX(), y, scale, angle_ * (M_PI * 2 / 360.0f), color); } @@ -222,7 +227,7 @@ bool PSPButton::IsDown() { return (__CtrlPeekButtons() & pspButtonBit_) != 0; } -PSPDpad::PSPDpad(int arrowIndex, int arrowDownIndex, int overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams) +PSPDpad::PSPDpad(ImageID arrowIndex, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams) : GamepadView(layoutParams), arrowIndex_(arrowIndex), arrowDownIndex_(arrowDownIndex), overlayIndex_(overlayIndex), scale_(scale), spacing_(spacing), dragPointerId_(-1), down_(0) { } @@ -347,20 +352,18 @@ void PSPDpad::Draw(UIContext &dc) { uint32_t color = colorAlpha(0xFFFFFF, imgOpacity); dc.Draw()->DrawImageRotated(arrowIndex_, x, y, imgScale, angle + PI, colorBg, false); - if (overlayIndex_ != -1) + if (overlayIndex_.isValid()) dc.Draw()->DrawImageRotated(overlayIndex_, x2, y2, imgScale, angle + PI, color); } } -PSPStick::PSPStick(int bgImg, int stickImg, int stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams) +PSPStick::PSPStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams) : GamepadView(layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stickDownImg_(stickDownImg), stick_(stick), scale_(scale), centerX_(-1), centerY_(-1) { stick_size_ = 50; } void PSPStick::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[bgImg_]; - w = image.w; - h = image.h; + dc.Draw()->GetAtlas()->measureImage(bgImg_, &w, &h); } void PSPStick::Draw(UIContext &dc) { @@ -591,34 +594,34 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { const int halfW = xres / 2; - const int roundImage = g_Config.iTouchButtonStyle ? I_ROUND_LINE : I_ROUND; + const ImageID roundImage = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); - const int rectImage = g_Config.iTouchButtonStyle ? I_RECT_LINE : I_RECT; - const int shoulderImage = g_Config.iTouchButtonStyle ? I_SHOULDER_LINE : I_SHOULDER; - const int dirImage = g_Config.iTouchButtonStyle ? I_DIR_LINE : I_DIR; - const int stickImage = g_Config.iTouchButtonStyle ? I_STICK_LINE : I_STICK; - const int stickBg = g_Config.iTouchButtonStyle ? I_STICK_BG_LINE : I_STICK_BG; - static const int comboKeyImages[5] = { I_1, I_2, I_3, I_4, I_5 }; + const ImageID rectImage = g_Config.iTouchButtonStyle ? ImageID("I_RECT_LINE") : ImageID("I_RECT"); + const ImageID shoulderImage = g_Config.iTouchButtonStyle ? ImageID("I_SHOULDER_LINE") : ImageID("I_SHOULDER"); + const ImageID dirImage = g_Config.iTouchButtonStyle ? ImageID("I_DIR_LINE") : ImageID("I_DIR"); + const ImageID stickImage = g_Config.iTouchButtonStyle ? ImageID("I_STICK_LINE") : ImageID("I_STICK"); + const ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG"); + static const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") }; - auto addPSPButton = [=](int buttonBit, int bgImg, int bgDownImg, int img, const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) -> PSPButton * { + auto addPSPButton = [=](int buttonBit, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) -> PSPButton * { if (touch.show) { return root->Add(new PSPButton(buttonBit, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch, off))); } return nullptr; }; - auto addComboKey = [=](int buttonBit, bool toggle, int bgImg, int bgDownImg, int img, const ConfigTouchPos &touch) -> ComboKey * { + auto addComboKey = [=](int buttonBit, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> ComboKey * { if (touch.show) { return root->Add(new ComboKey(buttonBit, toggle, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); } return nullptr; }; - auto addBoolButton = [=](bool *value, int bgImg, int bgDownImg, int img, const ConfigTouchPos &touch) -> BoolButton * { + auto addBoolButton = [=](bool *value, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> BoolButton * { if (touch.show) { return root->Add(new BoolButton(value, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); } return nullptr; }; - auto addFPSLimitButton = [=](FPSLimit value, int bgImg, int bgDownImg, int img, const ConfigTouchPos &touch) -> FPSLimitButton * { + auto addFPSLimitButton = [=](FPSLimit value, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> FPSLimitButton * { if (touch.show) { return root->Add(new FPSLimitButton(value, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); } @@ -626,23 +629,23 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { }; if (!System_GetPropertyBool(SYSPROP_HAS_BACK_BUTTON) || g_Config.bShowTouchPause) { - root->Add(new BoolButton(pause, roundImage, I_ROUND, I_ARROW, 1.0f, new AnchorLayoutParams(halfW, 20, NONE, NONE, true)))->SetAngle(90); + root->Add(new BoolButton(pause, roundImage, ImageID("I_ROUND"), ImageID("I_ARROW"), 1.0f, new AnchorLayoutParams(halfW, 20, NONE, NONE, true)))->SetAngle(90); } // touchActionButtonCenter.show will always be true, since that's the default. if (g_Config.bShowTouchCircle) - addPSPButton(CTRL_CIRCLE, roundImage, I_ROUND, I_CIRCLE, g_Config.touchActionButtonCenter, circleOffset); + addPSPButton(CTRL_CIRCLE, roundImage, ImageID("I_ROUND"), ImageID("I_CIRCLE"), g_Config.touchActionButtonCenter, circleOffset); if (g_Config.bShowTouchCross) - addPSPButton(CTRL_CROSS, roundImage, I_ROUND, I_CROSS, g_Config.touchActionButtonCenter, crossOffset); + addPSPButton(CTRL_CROSS, roundImage, ImageID("I_ROUND"), ImageID("I_CROSS"), g_Config.touchActionButtonCenter, crossOffset); if (g_Config.bShowTouchTriangle) - addPSPButton(CTRL_TRIANGLE, roundImage, I_ROUND, I_TRIANGLE, g_Config.touchActionButtonCenter, triangleOffset); + addPSPButton(CTRL_TRIANGLE, roundImage, ImageID("I_ROUND"), ImageID("I_TRIANGLE"), g_Config.touchActionButtonCenter, triangleOffset); if (g_Config.bShowTouchSquare) - addPSPButton(CTRL_SQUARE, roundImage, I_ROUND, I_SQUARE, g_Config.touchActionButtonCenter, squareOffset); + addPSPButton(CTRL_SQUARE, roundImage, ImageID("I_ROUND"), ImageID("I_SQUARE"), g_Config.touchActionButtonCenter, squareOffset); - addPSPButton(CTRL_START, rectImage, I_RECT, I_START, g_Config.touchStartKey); - addPSPButton(CTRL_SELECT, rectImage, I_RECT, I_SELECT, g_Config.touchSelectKey); + addPSPButton(CTRL_START, rectImage, ImageID("I_RECT"), ImageID("I_START"), g_Config.touchStartKey); + addPSPButton(CTRL_SELECT, rectImage, ImageID("I_RECT"), ImageID("I_SELECT"), g_Config.touchSelectKey); - BoolButton *unthrottle = addBoolButton(&PSP_CoreParameter().unthrottle, rectImage, I_RECT, I_ARROW, g_Config.touchUnthrottleKey); + BoolButton *unthrottle = addBoolButton(&PSP_CoreParameter().unthrottle, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchUnthrottleKey); if (unthrottle) { unthrottle->SetAngle(180.0f); unthrottle->OnChange.Add([](UI::EventParams &e) { @@ -654,36 +657,36 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { } if (g_Config.touchRapidFireKey.show) { - auto rapidFire = root->Add(new RapidFireButton(rectImage, I_RECT, I_ARROW, g_Config.touchRapidFireKey.scale, buttonLayoutParams(g_Config.touchRapidFireKey))); + auto rapidFire = root->Add(new RapidFireButton(rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchRapidFireKey.scale, buttonLayoutParams(g_Config.touchRapidFireKey))); rapidFire->SetAngle(90.0f, 180.0f); } - FPSLimitButton *speed1 = addFPSLimitButton(FPSLimit::CUSTOM1, rectImage, I_RECT, I_ARROW, g_Config.touchSpeed1Key); + FPSLimitButton *speed1 = addFPSLimitButton(FPSLimit::CUSTOM1, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed1Key); if (speed1) speed1->SetAngle(170.0f, 180.0f); - FPSLimitButton *speed2 = addFPSLimitButton(FPSLimit::CUSTOM2, rectImage, I_RECT, I_ARROW, g_Config.touchSpeed2Key); + FPSLimitButton *speed2 = addFPSLimitButton(FPSLimit::CUSTOM2, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed2Key); if (speed2) speed2->SetAngle(190.0f, 180.0f); - addPSPButton(CTRL_LTRIGGER, shoulderImage, I_SHOULDER, I_L, g_Config.touchLKey); - PSPButton *rTrigger = addPSPButton(CTRL_RTRIGGER, shoulderImage, I_SHOULDER, I_R, g_Config.touchRKey); + addPSPButton(CTRL_LTRIGGER, shoulderImage, ImageID("I_SHOULDER"), ImageID("I_L"), g_Config.touchLKey); + PSPButton *rTrigger = addPSPButton(CTRL_RTRIGGER, shoulderImage, ImageID("I_SHOULDER"), ImageID("I_R"), g_Config.touchRKey); if (rTrigger) rTrigger->FlipImageH(true); if (g_Config.touchDpad.show) - root->Add(new PSPDpad(dirImage, I_DIR, I_ARROW, g_Config.touchDpad.scale, g_Config.fDpadSpacing, buttonLayoutParams(g_Config.touchDpad))); + root->Add(new PSPDpad(dirImage, ImageID("I_DIR"), ImageID("I_ARROW"), g_Config.touchDpad.scale, g_Config.fDpadSpacing, buttonLayoutParams(g_Config.touchDpad))); if (g_Config.touchAnalogStick.show) - root->Add(new PSPStick(stickBg, stickImage, I_STICK, 0, g_Config.touchAnalogStick.scale, buttonLayoutParams(g_Config.touchAnalogStick))); + root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 0, g_Config.touchAnalogStick.scale, buttonLayoutParams(g_Config.touchAnalogStick))); if (g_Config.touchRightAnalogStick.show) - root->Add(new PSPStick(stickBg, stickImage, I_STICK, 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); + root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); - addComboKey(g_Config.iCombokey0, g_Config.bComboToggle0, roundImage, I_ROUND, comboKeyImages[0], g_Config.touchCombo0); - addComboKey(g_Config.iCombokey1, g_Config.bComboToggle1, roundImage, I_ROUND, comboKeyImages[1], g_Config.touchCombo1); - addComboKey(g_Config.iCombokey2, g_Config.bComboToggle2, roundImage, I_ROUND, comboKeyImages[2], g_Config.touchCombo2); - addComboKey(g_Config.iCombokey3, g_Config.bComboToggle3, roundImage, I_ROUND, comboKeyImages[3], g_Config.touchCombo3); - addComboKey(g_Config.iCombokey4, g_Config.bComboToggle4, roundImage, I_ROUND, comboKeyImages[4], g_Config.touchCombo4); + addComboKey(g_Config.iCombokey0, g_Config.bComboToggle0, roundImage, ImageID("I_ROUND"), comboKeyImages[0], g_Config.touchCombo0); + addComboKey(g_Config.iCombokey1, g_Config.bComboToggle1, roundImage, ImageID("I_ROUND"), comboKeyImages[1], g_Config.touchCombo1); + addComboKey(g_Config.iCombokey2, g_Config.bComboToggle2, roundImage, ImageID("I_ROUND"), comboKeyImages[2], g_Config.touchCombo2); + addComboKey(g_Config.iCombokey3, g_Config.bComboToggle3, roundImage, ImageID("I_ROUND"), comboKeyImages[3], g_Config.touchCombo3); + addComboKey(g_Config.iCombokey4, g_Config.bComboToggle4, roundImage, ImageID("I_ROUND"), comboKeyImages[4], g_Config.touchCombo4); return root; } diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 51b8e2f6b4..83c985cba9 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -43,7 +43,7 @@ protected: class MultiTouchButton : public GamepadView { public: - MultiTouchButton(int bgImg, int bgDownImg, int img, float scale, UI::LayoutParams *layoutParams) + MultiTouchButton(ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) : GamepadView(layoutParams), scale_(scale), bgImg_(bgImg), bgDownImg_(bgDownImg), img_(img) { } @@ -61,9 +61,9 @@ protected: float scale_; private: - int bgImg_; - int bgDownImg_; - int img_; + ImageID bgImg_; + ImageID bgDownImg_; + ImageID img_; float bgAngle_ = 0.0f; float angle_ = 0.0f; bool flipImageH_ = false; @@ -71,7 +71,7 @@ private: class BoolButton : public MultiTouchButton { public: - BoolButton(bool *value, int bgImg, int bgDownImg, int img, float scale, UI::LayoutParams *layoutParams) + BoolButton(bool *value, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), value_(value) { } @@ -86,7 +86,7 @@ private: class FPSLimitButton : public MultiTouchButton { public: - FPSLimitButton(FPSLimit limit, int bgImg, int bgDownImg, int img, float scale, UI::LayoutParams *layoutParams) + FPSLimitButton(FPSLimit limit, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), limit_(limit) { } @@ -99,7 +99,7 @@ private: class RapidFireButton : public MultiTouchButton { public: - RapidFireButton(int bgImg, int bgDownImg, int img, float scale, UI::LayoutParams *layoutParams) + RapidFireButton(ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams) { } void Touch(const TouchInput &input) override; @@ -108,7 +108,7 @@ public: class PSPButton : public MultiTouchButton { public: - PSPButton(int pspButtonBit, int bgImg, int bgDownImg, int img, float scale, UI::LayoutParams *layoutParams) + PSPButton(int pspButtonBit, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) { } void Touch(const TouchInput &input) override; @@ -120,7 +120,7 @@ private: class PSPDpad : public GamepadView { public: - PSPDpad(int arrowIndex, int arrowDownIndex, int overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams); + PSPDpad(ImageID arrowIndex, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams); void Touch(const TouchInput &input) override; void Draw(UIContext &dc) override; @@ -128,9 +128,9 @@ public: private: void ProcessTouch(float x, float y, bool down); - int arrowIndex_; - int arrowDownIndex_; - int overlayIndex_; + ImageID arrowIndex_; + ImageID arrowDownIndex_; + ImageID overlayIndex_; float scale_; float spacing_; @@ -141,7 +141,7 @@ private: class PSPStick : public GamepadView { public: - PSPStick(int bgImg, int stickImg, int stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams); + PSPStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams); void Touch(const TouchInput &input) override; void Draw(UIContext &dc) override; @@ -151,9 +151,10 @@ private: void ProcessTouch(float x, float y, bool down); int dragPointerId_; - int bgImg_; - int stickImageIndex_; - int stickDownImg_; + ImageID bgImg_; + ImageID stickImageIndex_; + ImageID stickDownImg_; + int stick_; float stick_size_; float scale_; @@ -172,8 +173,8 @@ const int baseActionButtonSpacing = 60; class ComboKey : public MultiTouchButton { public: - ComboKey(int pspButtonBit, bool toggle, int bgImg, int bgDownImg, int img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle) { + ComboKey(int pspButtonBit, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) { } void Touch(const TouchInput &input) override; private: diff --git a/UI/InstallZipScreen.cpp b/UI/InstallZipScreen.cpp index a815e01b7a..2a7bda7d1c 100644 --- a/UI/InstallZipScreen.cpp +++ b/UI/InstallZipScreen.cpp @@ -20,7 +20,6 @@ #include "ui/ui.h" #include "ui/view.h" #include "ui/viewgroup.h" -#include "UI/ui_atlas.h" #include "file/file_util.h" #include "Common/StringUtils.h" diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 7fdb8f49c1..9568948291 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -23,6 +23,7 @@ #include "base/display.h" #include "base/timeutil.h" #include "file/path.h" +#include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "math/curves.h" #include "base/stringutil.h" @@ -48,7 +49,6 @@ #include "UI/DisplayLayoutScreen.h" #include "UI/SavedataScreen.h" #include "UI/Store.h" -#include "UI/ui_atlas.h" #include "Core/Config.h" #include "Core/Loaders.h" #include "GPU/GPUInterface.h" @@ -372,25 +372,32 @@ void GameButton::Draw(UIContext &dc) { dc.Draw()->Flush(); } if (ginfo->hasConfig && !ginfo->id.empty()) { - if (gridStyle_) { - dc.Draw()->DrawImage(I_GEAR, x, y + h - ui_images[I_GEAR].h, 1.0f); - } else { - dc.Draw()->DrawImage(I_GEAR, x - ui_images[I_GEAR].w, y, 1.0f); + const AtlasImage *gearImage = dc.Draw()->GetAtlas()->getImage(ImageID("I_GEAR")); + if (gearImage) { + if (gridStyle_) { + dc.Draw()->DrawImage(ImageID("I_GEAR"), x, y + h - gearImage->h, 1.0f); + } else { + dc.Draw()->DrawImage(ImageID("I_GEAR"), x - gearImage->w, y, 1.0f); + } } } if (g_Config.bShowRegionOnGameIcon && ginfo->region >= 0 && ginfo->region < GAMEREGION_MAX && ginfo->region != GAMEREGION_OTHER) { - static const int regionIcons[GAMEREGION_MAX] = { - I_FLAG_JP, - I_FLAG_US, - I_FLAG_EU, - I_FLAG_HK, - I_FLAG_AS, - I_FLAG_KO + const ImageID regionIcons[GAMEREGION_MAX] = { + ImageID("I_FLAG_JP"), + ImageID("I_FLAG_US"), + ImageID("I_FLAG_EU"), + ImageID("I_FLAG_HK"), + ImageID("I_FLAG_AS"), + ImageID("I_FLAG_KO"), + ImageID::invalid(), }; - if (gridStyle_) { - dc.Draw()->DrawImage(regionIcons[ginfo->region], x + w - ui_images[regionIcons[ginfo->region]].w - 5, y + h - ui_images[regionIcons[ginfo->region]].h - 5, 1.0f); - } else { - dc.Draw()->DrawImage(regionIcons[ginfo->region], x - 2 - ui_images[regionIcons[ginfo->region]].w - 3, y + h - ui_images[regionIcons[ginfo->region]].h - 5, 1.0f); + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(regionIcons[ginfo->region]); + if (image) { + if (gridStyle_) { + dc.Draw()->DrawImage(regionIcons[ginfo->region], x + w - image->w - 5, y + h - image->h - 5, 1.0f); + } else { + dc.Draw()->DrawImage(regionIcons[ginfo->region], x - 2 - image->w - 3, y + h - image->h - 5, 1.0f); + } } } if (gridStyle_ && g_Config.bShowIDOnGameIcon) { @@ -439,9 +446,9 @@ void DirButton::Draw(UIContext &dc) { const std::string text = GetText(); - int image = I_FOLDER; + ImageID image = ImageID("I_FOLDER"); if (text == "..") { - image = I_UP_DIRECTORY; + image = ImageID("I_UP_DIRECTORY"); } float tw, th; @@ -452,7 +459,7 @@ void DirButton::Draw(UIContext &dc) { if (compact) { // No icon, except "up" dc.PushScissor(bounds_); - if (image == I_FOLDER) { + if (image == ImageID("I_FOLDER")) { dc.DrawText(text.c_str(), bounds_.x + 5, bounds_.centerY(), style.fgColor, ALIGN_VCENTER); } else { dc.Draw()->DrawImage(image, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); @@ -577,8 +584,8 @@ void GameBrowser::Refresh() { } ChoiceStrip *layoutChoice = topBar->Add(new ChoiceStrip(ORIENT_HORIZONTAL)); - layoutChoice->AddChoice(I_GRID); - layoutChoice->AddChoice(I_LINES); + layoutChoice->AddChoice(ImageID("I_GRID")); + layoutChoice->AddChoice(ImageID("I_LINES")); layoutChoice->SetSelection(*gridStyle_ ? 0 : 1); layoutChoice->OnChoice.Handle(this, &GameBrowser::LayoutChange); Add(topBar); @@ -945,11 +952,11 @@ void MainScreen::CreateViews() { rightColumnItems->SetSpacing(0.0f); LinearLayout *logos = new LinearLayout(ORIENT_HORIZONTAL); if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { - logos->Add(new ImageView(I_ICONGOLD, IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false))); + logos->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false))); } else { - logos->Add(new ImageView(I_ICON, IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false))); + logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false))); } - logos->Add(new ImageView(I_LOGO, IS_DEFAULT, new LinearLayoutParams(Margins(-12, 0, 0, 0)))); + logos->Add(new ImageView(ImageID("I_LOGO"), IS_DEFAULT, new LinearLayoutParams(Margins(-12, 0, 0, 0)))); rightColumnItems->Add(logos); TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0)))); ver->SetSmall(true); @@ -963,7 +970,7 @@ void MainScreen::CreateViews() { if (!System_GetPropertyBool(SYSPROP_APP_GOLD)) { Choice *gold = rightColumnItems->Add(new Choice(mm->T("Buy PPSSPP Gold"))); gold->OnClick.Handle(this, &MainScreen::OnSupport); - gold->SetIcon(I_ICONGOLD); + gold->SetIcon(ImageID("I_ICONGOLD")); } #if !PPSSPP_PLATFORM(UWP) diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 106be32e5b..7fc27f301c 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -32,7 +32,6 @@ #include "ui/ui.h" #include "util/random/rng.h" #include "file/vfs.h" -#include "UI/ui_atlas.h" #include "UI/ControlMappingScreen.h" #include "UI/DisplayLayoutScreen.h" #include "UI/EmuScreen.h" @@ -49,17 +48,15 @@ #include "GPU/GPUState.h" #include "GPU/Common/PostShader.h" -#include "ui_atlas.h" - #ifdef _MSC_VER #pragma execution_character_set("utf-8") #endif -static const int symbols[4] = { - I_CROSS, - I_CIRCLE, - I_SQUARE, - I_TRIANGLE +static const ImageID symbols[4] = { + ImageID("I_CROSS"), + ImageID("I_CIRCLE"), + ImageID("I_SQUARE"), + ImageID("I_TRIANGLE"), }; static const uint32_t colors[4] = { @@ -120,7 +117,7 @@ void DrawBackground(UIContext &dc, float alpha) { dc.Flush(); dc.RebindTexture(); } else { - ImageID img = I_BG; + ImageID img = ImageID("I_BG"); ui_draw2d.DrawImageStretch(img, dc.GetBounds(), bgColor); } @@ -493,11 +490,11 @@ void LogoScreen::render() { // Manually formatting UTF-8 is fun. \xXX doesn't work everywhere. snprintf(temp, sizeof(temp), "%s Henrik Rydg%c%crd", cr->T("created", "Created by"), 0xC3, 0xA5); if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { - dc.Draw()->DrawImage(I_ICONGOLD, bounds.centerX() - 120, bounds.centerY() - 30, 1.2f, textColor, ALIGN_CENTER); + dc.Draw()->DrawImage(ImageID("I_ICONGOLD"), bounds.centerX() - 120, bounds.centerY() - 30, 1.2f, textColor, ALIGN_CENTER); } else { - dc.Draw()->DrawImage(I_ICON, bounds.centerX() - 120, bounds.centerY() - 30, 1.2f, textColor, ALIGN_CENTER); + dc.Draw()->DrawImage(ImageID("I_ICON"), bounds.centerX() - 120, bounds.centerY() - 30, 1.2f, textColor, ALIGN_CENTER); } - dc.Draw()->DrawImage(I_LOGO, bounds.centerX() + 40, bounds.centerY() - 30, 1.5f, textColor, ALIGN_CENTER); + dc.Draw()->DrawImage(ImageID("I_LOGO"), bounds.centerX() + 40, bounds.centerY() - 30, 1.5f, textColor, ALIGN_CENTER); //dc.Draw()->DrawTextShadow(UBUNTU48, "PPSSPP", xres / 2, yres / 2 - 30, textColor, ALIGN_CENTER); dc.SetFontScale(1.0f, 1.0f); dc.SetFontStyle(dc.theme->uiFont); @@ -544,9 +541,9 @@ void CreditsScreen::CreateViews() { root_->Add(new Button(cr->T("Twitter @PPSSPP_emu"), new AnchorLayoutParams(260, 64, NONE, NONE, 10, rightYOffset + 158, false)))->OnClick.Handle(this, &CreditsScreen::OnTwitter); #endif if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { - root_->Add(new ImageView(I_ICONGOLD, IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); + root_->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); } else { - root_->Add(new ImageView(I_ICON, IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); + root_->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); } } diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index c6b6708565..c37968bb7d 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -51,6 +51,7 @@ #include "file/zip_read.h" #include "net/http_client.h" #include "net/resolve.h" +#include "gfx/texture_atlas.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/gpu_features.h" #include "i18n/i18n.h" @@ -90,7 +91,6 @@ #include "Core/WebServer.h" #include "GPU/GPUInterface.h" -#include "ui_atlas.h" #include "UI/EmuScreen.h" #include "UI/GameInfoCache.h" #include "UI/HostTypes.h" @@ -121,6 +121,8 @@ static UI::Theme ui_theme; +Atlas g_ui_atlas; + #if defined(ARM) && defined(__ANDROID__) #include "../../android/jni/ArmEmitterTest.h" #elif defined(ARM64) && defined(__ANDROID__) @@ -750,20 +752,20 @@ static UI::Style MakeStyle(uint32_t fg, uint32_t bg) { static void UIThemeInit() { #if defined(USING_WIN_UI) || PPSSPP_PLATFORM(UWP) || defined(USING_QT_UI) - ui_theme.uiFont = UI::FontStyle(UBUNTU24, g_Config.sFont.c_str(), 22); - ui_theme.uiFontSmall = UI::FontStyle(UBUNTU24, g_Config.sFont.c_str(), 15); - ui_theme.uiFontSmaller = UI::FontStyle(UBUNTU24, g_Config.sFont.c_str(), 12); + ui_theme.uiFont = UI::FontStyle(FontID("UBUNTU24"), g_Config.sFont.c_str(), 22); + ui_theme.uiFontSmall = UI::FontStyle(FontID("UBUNTU24"), g_Config.sFont.c_str(), 15); + ui_theme.uiFontSmaller = UI::FontStyle(FontID("UBUNTU24"), g_Config.sFont.c_str(), 12); #else - ui_theme.uiFont = UI::FontStyle(UBUNTU24, "", 20); - ui_theme.uiFontSmall = UI::FontStyle(UBUNTU24, "", 14); - ui_theme.uiFontSmaller = UI::FontStyle(UBUNTU24, "", 11); + ui_theme.uiFont = UI::FontStyle(FontID("UBUNTU24"), "", 20); + ui_theme.uiFontSmall = UI::FontStyle(FontID("UBUNTU24"), "", 14); + ui_theme.uiFontSmaller = UI::FontStyle(FontID("UBUNTU24"), "", 11); #endif - ui_theme.checkOn = I_CHECKEDBOX; - ui_theme.checkOff = I_SQUARE; - ui_theme.whiteImage = I_SOLIDWHITE; - ui_theme.sliderKnob = I_CIRCLE; - ui_theme.dropShadow4Grid = I_DROP_SHADOW; + ui_theme.checkOn = ImageID("I_CHECKEDBOX"); + ui_theme.checkOff = ImageID("I_SQUARE"); + ui_theme.whiteImage = ImageID("I_SOLIDWHITE"); + ui_theme.sliderKnob = ImageID("I_CIRCLE"); + ui_theme.dropShadow4Grid = ImageID("I_DROP_SHADOW"); ui_theme.itemStyle = MakeStyle(g_Config.uItemStyleFg, g_Config.uItemStyleBg); ui_theme.itemFocusedStyle = MakeStyle(g_Config.uItemFocusedStyleFg, g_Config.uItemFocusedStyleBg); @@ -799,8 +801,17 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) { _assert_msg_(G3D, g_draw, "No draw context available!"); _assert_msg_(G3D, g_draw->GetVshaderPreset(VS_COLOR_2D) != nullptr, "Failed to compile presets"); - ui_draw2d.SetAtlas(&ui_atlas); - ui_draw2d_front.SetAtlas(&ui_atlas); + // Load the atlas. + + size_t atlas_data_size = 0; + if (!g_ui_atlas.IsMetadataLoaded()) { + const uint8_t *atlas_data = VFSReadFile("ui_atlas.meta", &atlas_data_size); + bool load_success = g_ui_atlas.Load(atlas_data, atlas_data_size); + _assert_msg_(G3D, load_success, "Failed to load ui_atlas.meta"); + delete[] atlas_data; + } + ui_draw2d.SetAtlas(&g_ui_atlas); + ui_draw2d_front.SetAtlas(&g_ui_atlas); UIThemeInit(); diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index d308c43d90..66517ad1c0 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -1,8 +1,8 @@ #include "UI/OnScreenDisplay.h" -#include "UI/ui_atlas.h" #include "base/colorutil.h" #include "base/timeutil.h" +#include "gfx/texture_atlas.h" #include "gfx_es2/draw_buffer.h" #include "ui/ui_context.h" diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index a89fc0d90e..e9c58fb5ab 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -31,7 +31,6 @@ #include "UI/SavedataScreen.h" #include "UI/MainScreen.h" #include "UI/GameInfoCache.h" -#include "UI/ui_atlas.h" #include "UI/PauseScreen.h" #include "Common/FileUtil.h" diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 0e8f12618a..69092ea667 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -22,7 +22,6 @@ #include "gfx_es2/draw_buffer.h" #include "i18n/i18n.h" #include "ui/ui_context.h" -#include "ui_atlas.h" #include "TouchControlLayoutScreen.h" #include "TouchControlVisibilityScreen.h" @@ -42,7 +41,7 @@ static u32 GetButtonColor() { class DragDropButton : public MultiTouchButton { public: - DragDropButton(ConfigTouchPos &pos, int bgImg, int img) + DragDropButton(ConfigTouchPos &pos, ImageID bgImg, ImageID img) : MultiTouchButton(bgImg, bgImg, img, pos.scale, new UI::AnchorLayoutParams(fromFullscreenCoord(pos.x), pos.y * local_dp_yres, UI::NONE, UI::NONE, true)), x_(pos.x), y_(pos.y), theScale_(pos.scale) { scale_ = theScale_; @@ -90,16 +89,9 @@ private: class PSPActionButtons : public DragDropButton { public: PSPActionButtons(ConfigTouchPos &pos, float &spacing) - : DragDropButton(pos, -1, -1), spacing_(spacing) { + : DragDropButton(pos, ImageID::invalid(), ImageID::invalid()), spacing_(spacing) { using namespace UI; - roundId_ = g_Config.iTouchButtonStyle ? I_ROUND_LINE : I_ROUND; - - circleId_ = I_CIRCLE; - crossId_ = I_CROSS; - triangleId_ = I_TRIANGLE; - squareId_ = I_SQUARE; - - circleVisible_ = triangleVisible_ = squareVisible_ = crossVisible_ = true; + roundId_ = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); }; void setCircleVisibility(bool visible){ @@ -152,20 +144,23 @@ public: }; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[roundId_]; + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(roundId_); - w = (2 * baseActionButtonSpacing * spacing_) + image.w * scale_; - h = (2 * baseActionButtonSpacing * spacing_) + image.h * scale_; + w = (2.0f * baseActionButtonSpacing * spacing_) + image->w * scale_; + h = (2.0f * baseActionButtonSpacing * spacing_) + image->h * scale_; } float GetSpacing() const override { return spacing_; } void SetSpacing(float s) override { spacing_ = s; } private: - bool circleVisible_, crossVisible_, triangleVisible_, squareVisible_; + bool circleVisible_ = true, crossVisible_ = true, triangleVisible_ = true, squareVisible_ = true; - int roundId_; - int circleId_, crossId_, triangleId_, squareId_; + ImageID roundId_ = ImageID::invalid(); + ImageID circleId_ = ImageID("I_CIRCLE"); + ImageID crossId_ = ImageID("I_CROSS"); + ImageID triangleId_ = ImageID("I_TRIANGLE"); + ImageID squareId_ = ImageID("I_SQUARE"); float &spacing_; }; @@ -173,7 +168,7 @@ private: class PSPDPadButtons : public DragDropButton { public: PSPDPadButtons(ConfigTouchPos &pos, float &spacing) - : DragDropButton(pos, -1, -1), spacing_(spacing) { + : DragDropButton(pos, ImageID::invalid(), ImageID::invalid()), spacing_(spacing) { } void Draw(UIContext &dc) override { @@ -185,7 +180,7 @@ public: static const float xoff[4] = {1, 0, -1, 0}; static const float yoff[4] = {0, 1, 0, -1}; - int dirImage = g_Config.iTouchButtonStyle ? I_DIR_LINE : I_DIR; + ImageID dirImage = g_Config.iTouchButtonStyle ? ImageID("I_DIR_LINE") : ImageID("I_DIR"); for (int i = 0; i < 4; i++) { float r = D_pad_Radius * spacing_; @@ -196,14 +191,14 @@ public: float angle = i * M_PI / 2; dc.Draw()->DrawImageRotated(dirImage, x, y, scale_, angle + PI, colorBg, false); - dc.Draw()->DrawImageRotated(I_ARROW, x2, y2, scale_, angle + PI, color); + dc.Draw()->DrawImageRotated(ImageID("I_ARROW"), x2, y2, scale_, angle + PI, color); } } void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[I_DIR]; - w = 2 * D_pad_Radius * spacing_ + image.w * scale_; - h = 2 * D_pad_Radius * spacing_ + image.h * scale_; + const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(ImageID("I_DIR")); + w = 2 * D_pad_Radius * spacing_ + image->w * scale_; + h = 2 * D_pad_Radius * spacing_ + image->h * scale_; }; float GetSpacing() const override { return spacing_; } @@ -414,57 +409,57 @@ void TouchControlLayoutScreen::CreateViews() { controls_.push_back(actionButtons); - int rectImage = g_Config.iTouchButtonStyle ? I_RECT_LINE : I_RECT; - int shoulderImage = g_Config.iTouchButtonStyle ? I_SHOULDER_LINE : I_SHOULDER; - int dirImage = g_Config.iTouchButtonStyle ? I_DIR_LINE : I_DIR; - int stickImage = g_Config.iTouchButtonStyle ? I_STICK_LINE : I_STICK; - int stickBg = g_Config.iTouchButtonStyle ? I_STICK_BG_LINE : I_STICK_BG; - int roundImage = g_Config.iTouchButtonStyle ? I_ROUND_LINE : I_ROUND; + ImageID rectImage = g_Config.iTouchButtonStyle ? ImageID("I_RECT_LINE") : ImageID("I_RECT"); + ImageID shoulderImage = g_Config.iTouchButtonStyle ? ImageID("I_SHOULDER_LINE") : ImageID("I_SHOULDER"); + ImageID dirImage = g_Config.iTouchButtonStyle ? ImageID("I_DIR_LINE") : ImageID("I_DIR"); + ImageID stickImage = g_Config.iTouchButtonStyle ? ImageID("I_STICK_LINE") : ImageID("I_STICK"); + ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG"); + ImageID roundImage = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); - const int comboKeyImages[5] = { I_1, I_2, I_3, I_4, I_5 }; + const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") }; if (g_Config.touchDpad.show) { controls_.push_back(new PSPDPadButtons(g_Config.touchDpad, g_Config.fDpadSpacing)); } if (g_Config.touchSelectKey.show) { - controls_.push_back(new DragDropButton(g_Config.touchSelectKey, rectImage, I_SELECT)); + controls_.push_back(new DragDropButton(g_Config.touchSelectKey, rectImage, ImageID("I_SELECT"))); } if (g_Config.touchStartKey.show) { - controls_.push_back(new DragDropButton(g_Config.touchStartKey, rectImage, I_START)); + controls_.push_back(new DragDropButton(g_Config.touchStartKey, rectImage, ImageID("I_START"))); } if (g_Config.touchUnthrottleKey.show) { - DragDropButton *unthrottle = new DragDropButton(g_Config.touchUnthrottleKey, rectImage, I_ARROW); + DragDropButton *unthrottle = new DragDropButton(g_Config.touchUnthrottleKey, rectImage, ImageID("I_ARROW")); unthrottle->SetAngle(180.0f); controls_.push_back(unthrottle); } if (g_Config.touchSpeed1Key.show) { - DragDropButton *speed1 = new DragDropButton(g_Config.touchSpeed1Key, rectImage, I_ARROW); + DragDropButton *speed1 = new DragDropButton(g_Config.touchSpeed1Key, rectImage, ImageID("I_ARROW")); speed1->SetAngle(170.0f, 180.0f); controls_.push_back(speed1); } if (g_Config.touchSpeed2Key.show) { - DragDropButton *speed2 = new DragDropButton(g_Config.touchSpeed2Key, rectImage, I_ARROW); + DragDropButton *speed2 = new DragDropButton(g_Config.touchSpeed2Key, rectImage, ImageID("I_ARROW")); speed2->SetAngle(190.0f, 180.0f); controls_.push_back(speed2); } if (g_Config.touchRapidFireKey.show) { - DragDropButton *rapidFire = new DragDropButton(g_Config.touchRapidFireKey, rectImage, I_ARROW); + DragDropButton *rapidFire = new DragDropButton(g_Config.touchRapidFireKey, rectImage, ImageID("I_ARROW")); rapidFire->SetAngle(90.0f, 180.0f); controls_.push_back(rapidFire); } if (g_Config.touchLKey.show) { - controls_.push_back(new DragDropButton(g_Config.touchLKey, shoulderImage, I_L)); + controls_.push_back(new DragDropButton(g_Config.touchLKey, shoulderImage, ImageID("I_L"))); } if (g_Config.touchRKey.show) { - DragDropButton *rbutton = new DragDropButton(g_Config.touchRKey, shoulderImage, I_R); + DragDropButton *rbutton = new DragDropButton(g_Config.touchRKey, shoulderImage, ImageID("I_R")); rbutton->FlipImageH(true); controls_.push_back(rbutton); } diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index 1fd0f89fbd..04b68b4abd 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -15,9 +15,10 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "gfx/texture_atlas.h" + #include "TouchControlVisibilityScreen.h" #include "Core/Config.h" -#include "UI/ui_atlas.h" #include "i18n/i18n.h" static const int leftColumnWidth = 140; @@ -70,26 +71,26 @@ void TouchControlVisibilityScreen::CreateViews() { GridLayout *grid = vert->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); toggles_.clear(); - toggles_.push_back({ "Circle", &g_Config.bShowTouchCircle, I_CIRCLE }); - toggles_.push_back({ "Cross", &g_Config.bShowTouchCross, I_CROSS }); - toggles_.push_back({ "Square", &g_Config.bShowTouchSquare, I_SQUARE }); - toggles_.push_back({ "Triangle", &g_Config.bShowTouchTriangle, I_TRIANGLE }); - toggles_.push_back({ "L", &g_Config.touchLKey.show, I_L }); - toggles_.push_back({ "R", &g_Config.touchRKey.show, I_R }); - toggles_.push_back({ "Start", &g_Config.touchStartKey.show, I_START }); - toggles_.push_back({ "Select", &g_Config.touchSelectKey.show, I_SELECT }); - toggles_.push_back({ "Dpad", &g_Config.touchDpad.show, -1 }); - toggles_.push_back({ "Analog Stick", &g_Config.touchAnalogStick.show, -1 }); - toggles_.push_back({ "Right Analog Stick\n(not used by most games)", &g_Config.touchRightAnalogStick.show, -1 }); - toggles_.push_back({ "Unthrottle", &g_Config.touchUnthrottleKey.show, -1 }); - toggles_.push_back({ "Combo0", &g_Config.touchCombo0.show, I_1 }); - toggles_.push_back({ "Combo1", &g_Config.touchCombo1.show, I_2 }); - toggles_.push_back({ "Combo2", &g_Config.touchCombo2.show, I_3 }); - toggles_.push_back({ "Combo3", &g_Config.touchCombo3.show, I_4 }); - toggles_.push_back({ "Combo4", &g_Config.touchCombo4.show, I_5 }); - toggles_.push_back({ "Alt speed 1", &g_Config.touchSpeed1Key.show, -1 }); - toggles_.push_back({ "Alt speed 2", &g_Config.touchSpeed2Key.show, -1 }); - toggles_.push_back({ "RapidFire", &g_Config.touchRapidFireKey.show, -1 }); + toggles_.push_back({ "Circle", &g_Config.bShowTouchCircle, ImageID("I_CIRCLE") }); + toggles_.push_back({ "Cross", &g_Config.bShowTouchCross, ImageID("I_CROSS") }); + toggles_.push_back({ "Square", &g_Config.bShowTouchSquare, ImageID("I_SQUARE") }); + toggles_.push_back({ "Triangle", &g_Config.bShowTouchTriangle, ImageID("I_TRIANGLE") }); + toggles_.push_back({ "L", &g_Config.touchLKey.show, ImageID("I_L") }); + toggles_.push_back({ "R", &g_Config.touchRKey.show, ImageID("I_R") }); + toggles_.push_back({ "Start", &g_Config.touchStartKey.show, ImageID("I_START") }); + toggles_.push_back({ "Select", &g_Config.touchSelectKey.show, ImageID("I_SELECT") }); + toggles_.push_back({ "Dpad", &g_Config.touchDpad.show, ImageID::invalid() }); + toggles_.push_back({ "Analog Stick", &g_Config.touchAnalogStick.show, ImageID::invalid() }); + toggles_.push_back({ "Right Analog Stick\n(not used by most games)", &g_Config.touchRightAnalogStick.show, ImageID::invalid() }); + toggles_.push_back({ "Unthrottle", &g_Config.touchUnthrottleKey.show, ImageID::invalid() }); + toggles_.push_back({ "Combo0", &g_Config.touchCombo0.show, ImageID("I_1") }); + toggles_.push_back({ "Combo1", &g_Config.touchCombo1.show, ImageID("I_2") }); + toggles_.push_back({ "Combo2", &g_Config.touchCombo2.show, ImageID("I_3") }); + toggles_.push_back({ "Combo3", &g_Config.touchCombo3.show, ImageID("I_4") }); + toggles_.push_back({ "Combo4", &g_Config.touchCombo4.show, ImageID("I_5") }); + toggles_.push_back({ "Alt speed 1", &g_Config.touchSpeed1Key.show, ImageID::invalid() }); + toggles_.push_back({ "Alt speed 2", &g_Config.touchSpeed2Key.show, ImageID::invalid() }); + toggles_.push_back({ "RapidFire", &g_Config.touchRapidFireKey.show, ImageID::invalid() }); auto mc = GetI18NCategory("MappableControls"); @@ -101,7 +102,7 @@ void TouchControlVisibilityScreen::CreateViews() { row->Add(checkbox); Choice *choice; - if (toggle.img != -1) { + if (toggle.img.isValid()) { choice = new CheckBoxChoice(toggle.img, checkbox, new LinearLayoutParams(1.0f)); } else { choice = new CheckBoxChoice(mc->T(toggle.key), checkbox, new LinearLayoutParams(1.0f)); diff --git a/UI/TouchControlVisibilityScreen.h b/UI/TouchControlVisibilityScreen.h index 88455a343e..82efd442b3 100644 --- a/UI/TouchControlVisibilityScreen.h +++ b/UI/TouchControlVisibilityScreen.h @@ -17,6 +17,7 @@ #pragma once +#include "gfx/texture_atlas.h" #include "MiscScreens.h" namespace UI { @@ -26,7 +27,7 @@ namespace UI { struct TouchButtonToggle { const char *key; bool *show; - int img; + ImageID img; }; class TouchControlVisibilityScreen : public UIDialogScreenWithBackground { diff --git a/UI/UI.vcxproj b/UI/UI.vcxproj index ea06201cf5..7c7952131c 100644 --- a/UI/UI.vcxproj +++ b/UI/UI.vcxproj @@ -65,7 +65,6 @@ - @@ -98,7 +97,6 @@ - @@ -426,4 +424,4 @@ - \ No newline at end of file + diff --git a/UI/UI.vcxproj.filters b/UI/UI.vcxproj.filters index 1b79119b4e..bd5b259df2 100644 --- a/UI/UI.vcxproj.filters +++ b/UI/UI.vcxproj.filters @@ -4,7 +4,6 @@ - Screens @@ -78,7 +77,6 @@ - Screens @@ -155,4 +153,4 @@ {faee5dce-633b-4ba6-b19d-ea70ee3c1c38} - \ No newline at end of file + diff --git a/UWP/UI_UWP/UI_UWP.vcxproj b/UWP/UI_UWP/UI_UWP.vcxproj index 98c5b54a0b..120a7b5f86 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj +++ b/UWP/UI_UWP/UI_UWP.vcxproj @@ -409,7 +409,6 @@ - @@ -444,7 +443,6 @@ - Create Create diff --git a/UWP/UI_UWP/UI_UWP.vcxproj.filters b/UWP/UI_UWP/UI_UWP.vcxproj.filters index 89c1fdc6d8..8a4208e1ec 100644 --- a/UWP/UI_UWP/UI_UWP.vcxproj.filters +++ b/UWP/UI_UWP/UI_UWP.vcxproj.filters @@ -32,7 +32,6 @@ - @@ -67,6 +66,5 @@ - diff --git a/Windows/PPSSPP.sln b/Windows/PPSSPP.sln index 84a3d5bcd4..daf8a56189 100644 --- a/Windows/PPSSPP.sln +++ b/Windows/PPSSPP.sln @@ -322,8 +322,7 @@ Global {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Debug|ARM.ActiveCfg = Debug|x64 {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Debug|ARM64.ActiveCfg = Debug|x64 {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Debug|Win32.ActiveCfg = Debug|x64 - {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Debug|x64.ActiveCfg = Debug|x64 - {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Debug|x64.Build.0 = Debug|x64 + {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Debug|x64.ActiveCfg = Release|x64 {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Release|ARM.ActiveCfg = Release|x64 {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Release|ARM64.ActiveCfg = Release|x64 {FBE46262-7C2C-400C-92F9-F8A9E72594DD}.Release|Win32.ActiveCfg = Release|x64 @@ -332,8 +331,7 @@ Global {B7DED405-40A2-48F8-9382-538F10D442F1}.Debug|ARM.ActiveCfg = Debug|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Debug|ARM64.ActiveCfg = Debug|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Debug|Win32.ActiveCfg = Debug|x64 - {B7DED405-40A2-48F8-9382-538F10D442F1}.Debug|x64.ActiveCfg = Debug|x64 - {B7DED405-40A2-48F8-9382-538F10D442F1}.Debug|x64.Build.0 = Debug|x64 + {B7DED405-40A2-48F8-9382-538F10D442F1}.Debug|x64.ActiveCfg = Release|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Release|ARM.ActiveCfg = Release|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Release|ARM64.ActiveCfg = Release|x64 {B7DED405-40A2-48F8-9382-538F10D442F1}.Release|Win32.ActiveCfg = Release|x64 diff --git a/android/.gitignore b/android/.gitignore index 4aa0d52b74..749e376c96 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -7,8 +7,3 @@ gen obj .externalNativeBuild android.iml -#ui_atlas.zim -ui_atlas.zim.png -#assets/ui_atlas.zim -#jni/ui_atlas.cpp -#jni/ui_atlas.h diff --git a/android/assets/ppge_atlas.meta b/android/assets/ppge_atlas.meta new file mode 100644 index 0000000000..fe26c5199c Binary files /dev/null and b/android/assets/ppge_atlas.meta differ diff --git a/android/assets/ui_atlas.meta b/android/assets/ui_atlas.meta new file mode 100644 index 0000000000..e6b9cf53a2 Binary files /dev/null and b/android/assets/ui_atlas.meta differ diff --git a/android/jni/Android.mk b/android/jni/Android.mk index da3f9312bb..2021abeeda 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -183,7 +183,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/MIPS/IR/IRInterpreter.cpp \ $(SRC)/Core/MIPS/IR/IRPassSimplify.cpp \ $(SRC)/Core/MIPS/IR/IRRegCache.cpp \ - $(SRC)/UI/ui_atlas.cpp \ $(SRC)/ext/libkirk/AES.c \ $(SRC)/ext/libkirk/amctrl.c \ $(SRC)/ext/libkirk/SHA1.c \ @@ -417,7 +416,6 @@ EXEC_AND_LIB_FILES := \ $(SRC)/Core/Util/AudioFormat.cpp \ $(SRC)/Core/Util/GameManager.cpp \ $(SRC)/Core/Util/BlockAllocator.cpp \ - $(SRC)/Core/Util/ppge_atlas.cpp \ $(SRC)/Core/Util/PPGeDraw.cpp \ $(SRC)/git-version.cpp diff --git a/assets/ppge_atlas.meta b/assets/ppge_atlas.meta index 7650d69de6..fe26c5199c 100644 Binary files a/assets/ppge_atlas.meta and b/assets/ppge_atlas.meta differ diff --git a/assets/ui_atlas.meta b/assets/ui_atlas.meta index 1ebc7dc265..e6b9cf53a2 100644 Binary files a/assets/ui_atlas.meta and b/assets/ui_atlas.meta differ diff --git a/build_ppgeatlas.sh b/build_ppgeatlas.sh index 46a25a9987..bee2e6c56d 100755 --- a/build_ppgeatlas.sh +++ b/build_ppgeatlas.sh @@ -1 +1 @@ -./ext/native/tools/build/atlastool ppge_atlasscript.txt ppge && mv ppge_atlas.cpp ppge_atlas.h Core/Util && cp ppge_atlas.zim assets && mv ppge_atlas.zim ppge_atlas.meta android/assets +./ext/native/tools/build/atlastool ppge_atlasscript.txt ppge && rm ppge_atlas.cpp ppge_atlas.h && cp ppge_atlas.zim assets && cp ppge_atlas.meta assets && mv ppge_atlas.zim ppge_atlas.meta android/assets diff --git a/buildatlas.sh b/buildatlas.sh index c503115f1a..6034748179 100755 --- a/buildatlas.sh +++ b/buildatlas.sh @@ -1,2 +1,3 @@ -./ext/native/tools/build/atlastool atlasscript.txt ui 8888 && cp ui_atlas.zim ui_atlas.meta assets && cp ui_atlas.zim ui_atlas.meta android/assets && mv ui_atlas.cpp ui_atlas.h UI +./ext/native/tools/build/atlastool atlasscript.txt ui 8888 && cp ui_atlas.zim ui_atlas.meta assets && cp ui_atlas.zim ui_atlas.meta android/assets && rm ui_atlas.cpp ui_atlas.h + rm ui_atlas.zim ui_atlas.meta diff --git a/ext/native/gfx/texture_atlas.cpp b/ext/native/gfx/texture_atlas.cpp index 275d17f0cb..14f779a3e3 100644 --- a/ext/native/gfx/texture_atlas.cpp +++ b/ext/native/gfx/texture_atlas.cpp @@ -1,22 +1,100 @@ -#include +#include +#include +#include "base/logging.h" #include "gfx/texture_atlas.h" -const AtlasFont *Atlas::getFontByName(const char *name) const -{ - for (int i = 0; i < num_fonts; i++) { - if (!strcmp(name, fonts[i]->name)) - return fonts[i]; +class ByteReader { +public: + ByteReader(const uint8_t *data, size_t size) : data_(data), offset_(0), size_(size) {} + + template + T Read() { + T x; + memcpy(&x, data_ + offset_, sizeof(T)); + offset_ += sizeof(T); + return x; } - return 0; + + template + void ReadInto(T *t) { + memcpy(t, data_ + offset_, sizeof(T)); + offset_ += sizeof(T); + } + + template + T *ReadMultipleAlloc(size_t count) { + T *t = new T[count]; + memcpy(t, data_ + offset_, sizeof(T) * count); + offset_ += sizeof(T) * count; + return t; + } + +private: + const uint8_t *data_; + size_t offset_; + size_t size_; +}; + +bool Atlas::Load(const uint8_t *data, size_t data_size) { + ByteReader reader(data, data_size); + + AtlasHeader header = reader.Read(); + num_images = header.numImages; + num_fonts = header.numFonts; + if (header.magic != ATLAS_MAGIC) { + return false; + } + + images = reader.ReadMultipleAlloc(num_images); + fonts = new AtlasFont[num_fonts]; + for (int i = 0; i < num_fonts; i++) { + AtlasFontHeader font_header = reader.Read(); + fonts[i].padding = font_header.padding; + fonts[i].height = font_header.height; + fonts[i].ascend = font_header.ascend; + fonts[i].distslope = font_header.distslope; + fonts[i].numRanges = font_header.numRanges; + fonts[i].numChars = font_header.numChars; + fonts[i].ranges = reader.ReadMultipleAlloc(font_header.numRanges); + fonts[i].charData = reader.ReadMultipleAlloc(font_header.numChars); + memcpy(fonts[i].name, font_header.name, sizeof(font_header.name)); + } + return true; } -const AtlasImage *Atlas::getImageByName(const char *name) const -{ +const AtlasFont *Atlas::getFont(FontID id) const { + if (id.isInvalid()) + return nullptr; + + for (int i = 0; i < num_fonts; i++) { + if (!strcmp(id.id, fonts[i].name)) + return &fonts[i]; + } + return nullptr; +} + +const AtlasImage *Atlas::getImage(ImageID name) const { + if (name.isInvalid()) + return nullptr; + for (int i = 0; i < num_images; i++) { - if (!strcmp(name, images[i].name)) + if (!strcmp(name.id, images[i].name)) return &images[i]; } - return 0; + return nullptr; +} + +bool Atlas::measureImage(ImageID id, float *w, float *h) const { + const AtlasImage *image = getImage(id); + if (image) { + *w = (float)image->w; + *h = (float)image->h; + return true; + } else { + *w = 0.0f; + *h = 0.0f; + return false; + } } const AtlasChar *AtlasFont::getChar(int utf32) const { @@ -31,3 +109,13 @@ const AtlasChar *AtlasFont::getChar(int utf32) const { } return 0; } + +Atlas::~Atlas() { + delete[] images; + delete[] fonts; +} + +AtlasFont::~AtlasFont() { + delete[] ranges; + delete[] charData; +} diff --git a/ext/native/gfx/texture_atlas.h b/ext/native/gfx/texture_atlas.h index 250fea42b3..dfcf734dae 100644 --- a/ext/native/gfx/texture_atlas.h +++ b/ext/native/gfx/texture_atlas.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + #define ATLAS_MAGIC ('A' + ('T' << 8) + ('L' << 16) | ('A' << 24)) // Metadata file structure v0: @@ -14,7 +17,57 @@ // For each char: // AtlasChar -typedef int ImageID; +struct Atlas; + +struct ImageID { +public: + ImageID() : id(nullptr) {} + explicit ImageID(const char *_id) : id(_id) {} + + static inline ImageID invalid() { + return ImageID{ nullptr }; + } + + bool isValid() const { + return id != nullptr; + } + + bool isInvalid() const { + return id == nullptr; + } + + bool operator ==(const ImageID &other) { + return (id == other.id) || !strcmp(id, other.id); + } + + bool operator !=(const ImageID &other) { + if (id == other.id) { + return false; + } + return strcmp(id, other.id) != 0; + } + +private: + const char *id; + friend struct Atlas; +}; + +struct FontID { +public: + explicit FontID(const char *_id) : id(_id) {} + + static inline FontID invalid() { + return FontID{ nullptr }; + } + + bool isInvalid() const { + return id == nullptr; + } + +private: + const char *id; + friend struct Atlas; +}; struct AtlasChar { // texcoords @@ -40,9 +93,12 @@ struct AtlasFontHeader { float distslope; int numRanges; int numChars; + char name[32]; }; struct AtlasFont { + ~AtlasFont(); + float padding; float height; float ascend; @@ -50,19 +106,14 @@ struct AtlasFont { const AtlasChar *charData; const AtlasCharRange *ranges; int numRanges; - const char *name; + int numChars; + char name[32]; // Returns 0 on no match. const AtlasChar *getChar(int utf32) const ; }; struct AtlasImage { - float u1, v1, u2, v2; - int w, h; - const char *name; -}; - -struct AtlasImage2 { float u1, v1, u2, v2; int w, h; char name[32]; @@ -76,13 +127,20 @@ struct AtlasHeader { }; struct Atlas { - const char *filename; - const AtlasFont **fonts; - int num_fonts; - const AtlasImage *images; - int num_images; + ~Atlas(); + bool Load(const uint8_t *data, size_t data_size); + bool IsMetadataLoaded() { + return images != nullptr; + } + + AtlasFont *fonts = nullptr; + int num_fonts = 0; + AtlasImage *images = nullptr; + int num_images = 0; // These are inefficient linear searches, try not to call every frame. - const AtlasFont *getFontByName(const char *name) const; - const AtlasImage *getImageByName(const char *name) const; + const AtlasFont *getFont(FontID id) const; + const AtlasImage *getImage(ImageID id) const; + + bool measureImage(ImageID id, float *w, float *h) const; }; diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index b329534a93..e9ff42c8db 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -173,8 +173,10 @@ void DrawBuffer::Rect(float x, float y, float w, float h, V(x, y + h, 0, color, u, v + uh); } -void DrawBuffer::Line(int atlas_image, float x1, float y1, float x2, float y2, float thickness, uint32_t color) { - const AtlasImage &image = atlas->images[atlas_image]; +void DrawBuffer::Line(ImageID atlas_image, float x1, float y1, float x2, float y2, float thickness, uint32_t color) { + const AtlasImage *image = atlas->getImage(atlas_image); + if (!image) + return; // No caps yet! // Pre-rotated - we are making a thick line here @@ -190,24 +192,34 @@ void DrawBuffer::Line(int atlas_image, float x1, float y1, float x2, float y2, f float x[4] = { x1 - dx, x2 - dx, x1 + dx, x2 + dx }; float y[4] = { y1 - dy, y2 - dy, y1 + dy, y2 + dy }; - V(x[0], y[0], color, image.u1, image.v1); - V(x[1], y[1], color, image.u2, image.v1); - V(x[2], y[2], color, image.u1, image.v2); - V(x[2], y[2], color, image.u1, image.v2); - V(x[1], y[1], color, image.u2, image.v1); - V(x[3], y[3], color, image.u2, image.v2); + V(x[0], y[0], color, image->u1, image->v1); + V(x[1], y[1], color, image->u2, image->v1); + V(x[2], y[2], color, image->u1, image->v2); + V(x[2], y[2], color, image->u1, image->v2); + V(x[1], y[1], color, image->u2, image->v1); + V(x[3], y[3], color, image->u2, image->v2); } -void DrawBuffer::MeasureImage(ImageID atlas_image, float *w, float *h) { - const AtlasImage &image = atlas->images[atlas_image]; - *w = (float)image.w; - *h = (float)image.h; +bool DrawBuffer::MeasureImage(ImageID atlas_image, float *w, float *h) { + const AtlasImage *image = atlas->getImage(atlas_image); + if (image) { + *w = (float)image->w; + *h = (float)image->h; + return true; + } else { + *w = 0; + *h = 0; + return false; + } } void DrawBuffer::DrawImage(ImageID atlas_image, float x, float y, float scale, Color color, int align) { - const AtlasImage &image = atlas->images[atlas_image]; - float w = (float)image.w * scale; - float h = (float)image.h * scale; + const AtlasImage *image = atlas->getImage(atlas_image); + if (!image) + return; + + float w = (float)image->w * scale; + float h = (float)image->h * scale; if (align & ALIGN_HCENTER) x -= w / 2; if (align & ALIGN_RIGHT) x -= w; if (align & ALIGN_VCENTER) y -= h / 2; @@ -216,13 +228,15 @@ void DrawBuffer::DrawImage(ImageID atlas_image, float x, float y, float scale, C } void DrawBuffer::DrawImageStretch(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color) { - const AtlasImage &image = atlas->images[atlas_image]; - V(x1, y1, color, image.u1, image.v1); - V(x2, y1, color, image.u2, image.v1); - V(x2, y2, color, image.u2, image.v2); - V(x1, y1, color, image.u1, image.v1); - V(x2, y2, color, image.u2, image.v2); - V(x1, y2, color, image.u1, image.v2); + const AtlasImage *image = atlas->getImage(atlas_image); + if (!image) + return; + V(x1, y1, color, image->u1, image->v1); + V(x2, y1, color, image->u2, image->v1); + V(x2, y2, color, image->u2, image->v2); + V(x1, y1, color, image->u1, image->v1); + V(x2, y2, color, image->u2, image->v2); + V(x1, y2, color, image->u1, image->v2); } inline void rot(float *v, float angle, float xc, float yc) { @@ -235,9 +249,9 @@ inline void rot(float *v, float angle, float xc, float yc) { } void DrawBuffer::DrawImageRotated(ImageID atlas_image, float x, float y, float scale, float angle, Color color, bool mirror_h) { - const AtlasImage &image = atlas->images[atlas_image]; - float w = (float)image.w * scale; - float h = (float)image.h * scale; + const AtlasImage *image = atlas->getImage(atlas_image); + float w = (float)image->w * scale; + float h = (float)image->h * scale; float x1 = x - w / 2; float x2 = x + w / 2; float y1 = y - h / 2; @@ -250,20 +264,20 @@ void DrawBuffer::DrawImageRotated(ImageID atlas_image, float x, float y, float s {x2, y2}, {x1, y2}, }; - float u1 = image.u1; - float u2 = image.u2; + float u1 = image->u1; + float u2 = image->u2; if (mirror_h) { float temp = u1; u1 = u2; u2 = temp; } const float uv[6][2] = { - {u1, image.v1}, - {u2, image.v1}, - {u2, image.v2}, - {u1, image.v1}, - {u2, image.v2}, - {u1, image.v2}, + {u1, image->v1}, + {u2, image->v1}, + {u2, image->v2}, + {u1, image->v1}, + {u2, image->v2}, + {u1, image->v2}, }; for (int i = 0; i < 6; i++) { rot(v[i], angle, x, y); @@ -306,13 +320,17 @@ void DrawBuffer::DrawTexRect(float x1, float y1, float x2, float y2, float u1, f } void DrawBuffer::DrawImage4Grid(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color, float corner_scale) { - const AtlasImage &image = atlas->images[atlas_image]; + const AtlasImage *image = atlas->getImage(atlas_image); - float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2; + if (!image) { + return; + } + + float u1 = image->u1, v1 = image->v1, u2 = image->u2, v2 = image->v2; float um = (u2 + u1) * 0.5f; float vm = (v2 + v1) * 0.5f; - float iw2 = (image.w * 0.5f) * corner_scale; - float ih2 = (image.h * 0.5f) * corner_scale; + float iw2 = (image->w * 0.5f) * corner_scale; + float ih2 = (image->h * 0.5f) * corner_scale; float xa = x1 + iw2; float xb = x2 - iw2; float ya = y1 + ih2; @@ -332,13 +350,13 @@ void DrawBuffer::DrawImage4Grid(ImageID atlas_image, float x1, float y1, float x } void DrawBuffer::DrawImage2GridH(ImageID atlas_image, float x1, float y1, float x2, Color color, float corner_scale) { - const AtlasImage &image = atlas->images[atlas_image]; - float um = (image.u1 + image.u2) * 0.5f; - float iw2 = (image.w * 0.5f) * corner_scale; + const AtlasImage *image = atlas->getImage(atlas_image); + float um = (image->u1 + image->u2) * 0.5f; + float iw2 = (image->w * 0.5f) * corner_scale; float xa = x1 + iw2; float xb = x2 - iw2; - float u1 = image.u1, v1 = image.v1, u2 = image.u2, v2 = image.v2; - float y2 = y1 + image.h; + float u1 = image->u1, v1 = image->v1, u2 = image->u2, v2 = image->v2; + float y2 = y1 + image->h; DrawTexRect(x1, y1, xa, y2, u1, v1, um, v2, color); DrawTexRect(xa, y1, xb, y2, um, v1, um, v2, color); DrawTexRect(xb, y1, x2, y2, um, v1, u2, v2, color); @@ -374,8 +392,13 @@ float AtlasWordWrapper::MeasureWidth(const char *str, size_t bytes) { return w; } -void DrawBuffer::MeasureTextCount(int font, const char *text, int count, float *w, float *h) { - const AtlasFont &atlasfont = *atlas->fonts[font]; +void DrawBuffer::MeasureTextCount(FontID font, const char *text, int count, float *w, float *h) { + const AtlasFont *atlasfont = atlas->getFont(font); + if (!atlasfont) { + *w = 0.0f; + *h = 0.0f; + return; + } unsigned int cval; float wacc = 0; @@ -402,17 +425,17 @@ void DrawBuffer::MeasureTextCount(int font, const char *text, int count, float * // Ignore lone ampersands continue; } - const AtlasChar *c = atlasfont.getChar(cval); + const AtlasChar *c = atlasfont->getChar(cval); if (c) { wacc += c->wx * fontscalex; } } if (w) *w = std::max(wacc, maxX); - if (h) *h = atlasfont.height * fontscaley * lines; + if (h) *h = atlasfont->height * fontscaley * lines; } -void DrawBuffer::MeasureTextRect(int font, const char *text, int count, const Bounds &bounds, float *w, float *h, int align) { - if (!text || (uint32_t)font >= (uint32_t)atlas->num_fonts) { +void DrawBuffer::MeasureTextRect(FontID font_id, const char *text, int count, const Bounds &bounds, float *w, float *h, int align) { + if (!text || font_id.isInvalid()) { *w = 0; *h = 0; return; @@ -420,17 +443,20 @@ void DrawBuffer::MeasureTextRect(int font, const char *text, int count, const Bo std::string toMeasure = std::string(text, count); if (align & FLAG_WRAP_TEXT) { - AtlasWordWrapper wrapper(*atlas->fonts[font], fontscalex, toMeasure.c_str(), bounds.w); + const AtlasFont *font = atlas->getFont(font_id); + if (!font) + return; + AtlasWordWrapper wrapper(*font, fontscalex, toMeasure.c_str(), bounds.w); toMeasure = wrapper.Wrapped(); } - MeasureTextCount(font, toMeasure.c_str(), (int)toMeasure.length(), w, h); + MeasureTextCount(font_id, toMeasure.c_str(), (int)toMeasure.length(), w, h); } -void DrawBuffer::MeasureText(int font, const char *text, float *w, float *h) { +void DrawBuffer::MeasureText(FontID font, const char *text, float *w, float *h) { return MeasureTextCount(font, text, (int)strlen(text), w, h); } -void DrawBuffer::DrawTextShadow(int font, const char *text, float x, float y, Color color, int flags) { +void DrawBuffer::DrawTextShadow(FontID font, const char *text, float x, float y, Color color, int flags) { uint32_t alpha = (color >> 1) & 0xFF000000; DrawText(font, text, x + 2, y + 2, alpha, flags); DrawText(font, text, x, y, color, flags); @@ -449,7 +475,7 @@ void DrawBuffer::DoAlign(int flags, float *x, float *y, float *w, float *h) { // TODO: Actually use the rect properly, take bounds. -void DrawBuffer::DrawTextRect(int font, const char *text, float x, float y, float w, float h, Color color, int align) { +void DrawBuffer::DrawTextRect(FontID font, const char *text, float x, float y, float w, float h, Color color, int align) { if (align & ALIGN_HCENTER) { x += w / 2; } else if (align & ALIGN_RIGHT) { @@ -463,7 +489,7 @@ void DrawBuffer::DrawTextRect(int font, const char *text, float x, float y, floa std::string toDraw = text; if (align & FLAG_WRAP_TEXT) { - AtlasWordWrapper wrapper(*atlas->fonts[font], fontscalex, toDraw.c_str(), w); + AtlasWordWrapper wrapper(*atlas->getFont(font), fontscalex, toDraw.c_str(), w); toDraw = wrapper.Wrapped(); } @@ -493,7 +519,7 @@ void DrawBuffer::DrawTextRect(int font, const char *text, float x, float y, floa } // ROTATE_* doesn't yet work right. -void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color color, int align) { +void DrawBuffer::DrawText(FontID font, const char *text, float x, float y, Color color, int align) { // rough estimate size_t textLen = strlen(text); if (count_ + textLen * 6 > MAX_VERTS) { @@ -503,7 +529,9 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co } } - const AtlasFont &atlasfont = *atlas->fonts[font]; + const AtlasFont *atlasfont = atlas->getFont(font); + if (!atlasfont) + return; unsigned int cval; float w, h; MeasureText(font, text, &w, &h); @@ -512,10 +540,10 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co } if (align & ROTATE_90DEG_LEFT) { - x -= atlasfont.ascend * fontscaley; + x -= atlasfont->ascend * fontscaley; // y += h; } else { - y += atlasfont.ascend * fontscaley; + y += atlasfont->ascend * fontscaley; } float sx = x; UTF8 utf(text); @@ -527,7 +555,7 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co if (cval == 0xA0) { cval = ' '; } else if (cval == '\n') { - y += atlasfont.height * fontscaley; + y += atlasfont->height * fontscaley; x = sx; continue; } else if (cval == '\t') { @@ -536,9 +564,9 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co // Ignore lone ampersands continue; } - const AtlasChar *ch = atlasfont.getChar(cval); + const AtlasChar *ch = atlasfont->getChar(cval); if (!ch) - ch = atlasfont.getChar('?'); + ch = atlasfont->getChar('?'); if (ch) { const AtlasChar &c = *ch; float cx1, cy1, cx2, cy2; diff --git a/ext/native/gfx_es2/draw_buffer.h b/ext/native/gfx_es2/draw_buffer.h index d90f8ae774..211fc4fb95 100644 --- a/ext/native/gfx_es2/draw_buffer.h +++ b/ext/native/gfx_es2/draw_buffer.h @@ -79,7 +79,7 @@ public: void vLine(float x, float y1, float y2, uint32_t color); void vLineAlpha50(float x, float y1, float y2, uint32_t color); - void Line(int atlas_image, float x1, float y1, float x2, float y2, float thickness, uint32_t color); + void Line(ImageID atlas_image, float x1, float y1, float x2, float y2, float thickness, uint32_t color); void RectOutline(float x, float y, float w, float h, uint32_t color, int align = ALIGN_TOPLEFT); @@ -109,7 +109,7 @@ public: atlas = _atlas; } const Atlas *GetAtlas() const { return atlas; } - void MeasureImage(ImageID atlas_image, float *w, float *h); + bool MeasureImage(ImageID atlas_image, float *w, float *h); void DrawImage(ImageID atlas_image, float x, float y, float scale, Color color = COLOR(0xFFFFFF), int align = ALIGN_TOPLEFT); void DrawImageStretch(ImageID atlas_image, float x1, float y1, float x2, float y2, Color color = COLOR(0xFFFFFF)); void DrawImageStretch(ImageID atlas_image, const Bounds &bounds, Color color = COLOR(0xFFFFFF)) { @@ -125,15 +125,15 @@ public: // This is only 6 triangles, much cheaper. void DrawImage2GridH(ImageID atlas_image, float x1, float y1, float x2, Color color = COLOR(0xFFFFFF), float scale = 1.0); - void MeasureText(int font, const char *text, float *w, float *h); + void MeasureText(FontID font, const char *text, float *w, float *h); // NOTE: Count is in plain chars not utf-8 chars! - void MeasureTextCount(int font, const char *text, int count, float *w, float *h); - void MeasureTextRect(int font, const char *text, int count, const Bounds &bounds, float *w, float *h, int align = 0); + void MeasureTextCount(FontID font, const char *text, int count, float *w, float *h); + void MeasureTextRect(FontID font, const char *text, int count, const Bounds &bounds, float *w, float *h, int align = 0); - void DrawTextRect(int font, const char *text, float x, float y, float w, float h, Color color = 0xFFFFFFFF, int align = 0); - void DrawText(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0); - void DrawTextShadow(int font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0); + void DrawTextRect(FontID font, const char *text, float x, float y, float w, float h, Color color = 0xFFFFFFFF, int align = 0); + void DrawText(FontID font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0); + void DrawTextShadow(FontID font, const char *text, float x, float y, Color color = 0xFFFFFFFF, int align = 0); void SetFontScale(float xs, float ys) { fontscalex = xs; diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index 336b677e92..c0fac7431d 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -631,6 +631,8 @@ struct FontDesc { header.height = ascend + descend; header.ascend = ascend; header.distslope = distmult / 256.0; + strncpy(header.name, name.c_str(), sizeof(header.name)); + header.name[sizeof(header.name) - 1] = '\0'; header.numChars = numChars; header.numRanges = (int)ranges.size(); return header; @@ -642,11 +644,11 @@ struct FontDesc { for (size_t r = 0; r < ranges.size(); r++) { int first_char_id = ranges[r].start; int last_char_id = ranges[r].end; - start_index += last_char_id - first_char_id; AtlasCharRange range; range.start = first_char_id; range.end = last_char_id; range.start_index = start_index; + start_index += last_char_id - first_char_id; out_ranges.push_back(range); } return out_ranges; @@ -679,8 +681,8 @@ struct ImageDesc { Effect effect; int result_index; - AtlasImage2 ToAtlasImage2(float tw, float th, const vector &results) { - AtlasImage2 img; + AtlasImage ToAtlasImage(float tw, float th, const vector &results) { + AtlasImage img; int i = result_index; float toffx = 0.5f / tw; float toffy = 0.5f / th; @@ -965,6 +967,14 @@ int main(int argc, char **argv) { dest.SaveZIM(image_name.c_str(), ZIM_RGBA4444 | ZIM_ZLIB_COMPRESSED); } + // Also save PNG for debugging. + printf("Writing .PNG %s\n", (image_name + ".png").c_str()); + dest.SavePNG((image_name + ".png").c_str()); + + printf("Done. Outputting source and meta files %s_atlas.cpp/h/meta.\n", out_prefix.c_str()); + // Sort items by ID. + sort(results.begin(), results.end()); + // Save all the metadata. { FILE *meta = fopen(meta_name.c_str(), "wb"); @@ -976,8 +986,7 @@ int main(int argc, char **argv) { fwrite(&header, 1, sizeof(header), meta); // For each image for (int i = 0; i < (int)images.size(); i++) { - auto &image = images[i]; - AtlasImage2 atlas_image = image.ToAtlasImage2(dest.width(), dest.height(), results); + AtlasImage atlas_image = images[i].ToAtlasImage(dest.width(), dest.height(), results); fwrite(&atlas_image, 1, sizeof(atlas_image), meta); } // For each font @@ -994,14 +1003,6 @@ int main(int argc, char **argv) { fclose(meta); } - // Also save PNG for debugging. - printf("Writing .PNG %s\n", (image_name + ".png").c_str()); - dest.SavePNG((image_name + ".png").c_str()); - - printf("Done. Outputting source files %s_atlas.cpp/h.\n", out_prefix.c_str()); - // Sort items by ID. - sort(results.begin(), results.end()); - FILE *cpp_file = fopen((out_prefix + "_atlas.cpp").c_str(), "wb"); fprintf(cpp_file, "// C++ generated by atlastool from %s (hrydgard@gmail.com)\n\n", argv[1]); fprintf(cpp_file, "#include \"%s\"\n\n", (out_prefix + "_atlas.h").c_str()); diff --git a/ext/native/tools/atlastool/atlastool.vcxproj b/ext/native/tools/atlastool/atlastool.vcxproj index 592c7dac88..20c96b3f1a 100644 --- a/ext/native/tools/atlastool/atlastool.vcxproj +++ b/ext/native/tools/atlastool/atlastool.vcxproj @@ -60,6 +60,7 @@ true + ../build/ false diff --git a/ext/native/ui/view.cpp b/ext/native/ui/view.cpp index 965a8aacb8..01376c4c09 100644 --- a/ext/native/ui/view.cpp +++ b/ext/native/ui/view.cpp @@ -513,10 +513,8 @@ void ClickableItem::Draw(UIContext &dc) { } void Choice::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { - if (atlasImage_ != -1) { - const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_]; - w = img.w; - h = img.h; + if (atlasImage_.isValid()) { + dc.Draw()->GetAtlas()->measureImage(atlasImage_, &w, &h); } else { const int paddingX = 12; float availWidth = horiz.size - paddingX * 2 - textPadding_.horiz(); @@ -570,7 +568,7 @@ void Choice::Draw(UIContext &dc) { style = dc.theme->itemDisabledStyle; } - if (atlasImage_ != -1) { + if (atlasImage_.isValid()) { dc.Draw()->DrawImage(atlasImage_, bounds_.centerX(), bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER); } else { dc.SetFontStyle(dc.theme->uiFont); @@ -583,7 +581,7 @@ void Choice::Draw(UIContext &dc) { if (centered_) { dc.DrawTextRect(text_.c_str(), bounds_, style.fgColor, ALIGN_CENTER | FLAG_WRAP_TEXT); } else { - if (iconImage_ != -1) { + if (iconImage_.isValid()) { dc.Draw()->DrawImage(iconImage_, bounds_.x2() - 32 - paddingX, bounds_.centerY(), 0.5f, style.fgColor, ALIGN_CENTER); } @@ -634,8 +632,8 @@ void InfoItem::Draw(UIContext &dc) { ItemHeader::ItemHeader(const std::string &text, LayoutParams *layoutParams) : Item(layoutParams), text_(text) { - layoutParams_->width = FILL_PARENT; - layoutParams_->height = 40; + layoutParams_->width = FILL_PARENT; + layoutParams_->height = 40; } void ItemHeader::Draw(UIContext &dc) { @@ -709,7 +707,7 @@ void CheckBox::Draw(UIContext &dc) { ClickableItem::Draw(dc); - int image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff; + ImageID image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff; float imageW, imageH; dc.Draw()->MeasureImage(image, &imageW, &imageH); @@ -736,7 +734,7 @@ float CheckBox::CalculateTextScale(const UIContext &dc, float availWidth) const } void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - int image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff; + ImageID image = Toggled() ? dc.theme->checkOn : dc.theme->checkOff; float imageW, imageH; dc.Draw()->MeasureImage(image, &imageW, &imageH); @@ -769,10 +767,8 @@ bool BitCheckBox::Toggled() const { } void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - if (imageID_ != -1) { - const AtlasImage *img = &dc.Draw()->GetAtlas()->images[imageID_]; - w = img->w; - h = img->h; + if (imageID_.isValid()) { + dc.Draw()->GetAtlas()->measureImage(imageID_, &w, &h); } else { dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.c_str(), &w, &h); } @@ -792,36 +788,38 @@ void Button::Draw(UIContext &dc) { DrawBG(dc, style); float tw, th; dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, text_.c_str(), &tw, &th); - if (tw > bounds_.w || imageID_ != -1) { + if (tw > bounds_.w || imageID_.isValid()) { dc.PushScissor(bounds_); } dc.SetFontStyle(dc.theme->uiFont); - if (imageID_ != -1 && text_.empty()) { + if (imageID_.isValid() && text_.empty()) { dc.Draw()->DrawImage(imageID_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); } else if (!text_.empty()) { dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER); - if (imageID_ != -1) { - const AtlasImage &img = dc.Draw()->GetAtlas()->images[imageID_]; - dc.Draw()->DrawImage(imageID_, bounds_.centerX() - tw / 2 - 5 - img.w/2, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); + if (imageID_.isValid()) { + const AtlasImage *img = dc.Draw()->GetAtlas()->getImage(imageID_); + if (img) { + dc.Draw()->DrawImage(imageID_, bounds_.centerX() - tw / 2 - 5 - img->w / 2, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER); + } } } - if (tw > bounds_.w || imageID_ != -1) { + if (tw > bounds_.w || imageID_.isValid()) { dc.PopScissor(); } } void ImageView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_]; + dc.Draw()->GetAtlas()->measureImage(atlasImage_, &w, &h); // TODO: involve sizemode - w = img.w; - h = img.h; } void ImageView::Draw(UIContext &dc) { - const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_]; - // TODO: involve sizemode - float scale = bounds_.w / img.w; - dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT); + const AtlasImage *img = dc.Draw()->GetAtlas()->getImage(atlasImage_); + if (img) { + // TODO: involve sizemode + float scale = bounds_.w / img->w; + dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT); + } } void TextView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { @@ -1146,9 +1144,7 @@ void TriggerButton::Draw(UIContext &dc) { } void TriggerButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const { - const AtlasImage &image = dc.Draw()->GetAtlas()->images[imageBackground_]; - w = image.w; - h = image.h; + dc.Draw()->GetAtlas()->measureImage(imageBackground_, &w, &h); } bool Slider::Key(const KeyInput &input) { diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 32be22ec86..8bcbbe7a0d 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -28,6 +28,8 @@ struct KeyInput; struct TouchInput; struct AxisInput; +struct ImageID; + class DrawBuffer; class Texture; class UIContext; @@ -64,29 +66,29 @@ enum Visibility { }; struct Drawable { - Drawable() : type(DRAW_NOTHING), image(-1), color(0xFFFFFFFF) {} - explicit Drawable(uint32_t col) : type(DRAW_SOLID_COLOR), image(-1), color(col) {} - Drawable(DrawableType t, int img, uint32_t col = 0xFFFFFFFF) : type(t), image(img), color(col) {} + Drawable() : type(DRAW_NOTHING), image(ImageID::invalid()), color(0xFFFFFFFF) {} + explicit Drawable(uint32_t col) : type(DRAW_SOLID_COLOR), image(ImageID::invalid()), color(col) {} + Drawable(DrawableType t, ImageID img, uint32_t col = 0xFFFFFFFF) : type(t), image(img), color(col) {} DrawableType type; - uint32_t image; + ImageID image; uint32_t color; }; struct Style { - Style() : fgColor(0xFFFFFFFF), background(0xFF303030), image(-1) {} + Style() : fgColor(0xFFFFFFFF), background(0xFF303030), image(ImageID::invalid()) {} uint32_t fgColor; Drawable background; - int image; // where applicable. + ImageID image; // where applicable. }; struct FontStyle { FontStyle() : atlasFont(0), sizePts(0), flags(0) {} FontStyle(const char *name, int size) : atlasFont(0), fontName(name), sizePts(size), flags(0) {} - FontStyle(int atlasFnt, const char *name, int size) : atlasFont(atlasFnt), fontName(name), sizePts(size), flags(0) {} + FontStyle(FontID atlasFnt, const char *name, int size) : atlasFont(atlasFnt), fontName(name), sizePts(size), flags(0) {} - int atlasFont; + FontID atlasFont; // For native fonts: std::string fontName; int sizePts; @@ -99,11 +101,12 @@ struct Theme { FontStyle uiFont; FontStyle uiFontSmall; FontStyle uiFontSmaller; - int checkOn; - int checkOff; - int sliderKnob; - int whiteImage; - int dropShadow4Grid; + + ImageID checkOn; + ImageID checkOff; + ImageID sliderKnob; + ImageID whiteImage; + ImageID dropShadow4Grid; Style buttonStyle; Style buttonFocusedStyle; @@ -497,7 +500,7 @@ protected: class Button : public Clickable { public: Button(const std::string &text, LayoutParams *layoutParams = 0) - : Clickable(layoutParams), text_(text), imageID_(-1) {} + : Clickable(layoutParams), text_(text), imageID_(ImageID::invalid()) {} Button(ImageID imageID, LayoutParams *layoutParams = 0) : Clickable(layoutParams), imageID_(imageID) {} Button(const std::string &text, ImageID imageID, LayoutParams *layoutParams = 0) @@ -585,7 +588,7 @@ private: // Suitable for controller simulation (ABXY etc). class TriggerButton : public View { public: - TriggerButton(uint32_t *bitField, uint32_t bit, int imageBackground, int imageForeground, LayoutParams *layoutParams) + TriggerButton(uint32_t *bitField, uint32_t bit, ImageID imageBackground, ImageID imageForeground, LayoutParams *layoutParams) : View(layoutParams), down_(0.0), bitField_(bitField), bit_(bit), imageBackground_(imageBackground), imageForeground_(imageForeground) {} void Touch(const TouchInput &input) override; @@ -598,8 +601,8 @@ private: uint32_t *bitField_; uint32_t bit_; - int imageBackground_; - int imageForeground_; + ImageID imageBackground_; + ImageID imageForeground_; }; @@ -627,9 +630,9 @@ public: Choice(const std::string &text, LayoutParams *layoutParams = nullptr) : Choice(text, std::string(), false, layoutParams) {} Choice(const std::string &text, const std::string &smallText, bool selected = false, LayoutParams *layoutParams = nullptr) - : ClickableItem(layoutParams), text_(text), smallText_(smallText), atlasImage_(-1), iconImage_(-1), centered_(false), highlighted_(false), selected_(selected) {} + : ClickableItem(layoutParams), text_(text), smallText_(smallText), atlasImage_(ImageID::invalid()), iconImage_(ImageID::invalid()), centered_(false), highlighted_(false), selected_(selected) {} Choice(ImageID image, LayoutParams *layoutParams = nullptr) - : ClickableItem(layoutParams), atlasImage_(image), iconImage_(-1), centered_(false), highlighted_(false), selected_(false) {} + : ClickableItem(layoutParams), atlasImage_(image), iconImage_(ImageID::invalid()), centered_(false), highlighted_(false), selected_(false) {} virtual void HighlightChanged(bool highlighted); void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; @@ -853,14 +856,14 @@ enum ImageSizeMode { class ImageView : public InertView { public: - ImageView(int atlasImage, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) + ImageView(ImageID atlasImage, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) : InertView(layoutParams), atlasImage_(atlasImage), sizeMode_(sizeMode) {} void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; private: - int atlasImage_; + ImageID atlasImage_; ImageSizeMode sizeMode_; }; @@ -889,7 +892,7 @@ private: class Spinner : public InertView { public: - Spinner(const int *images, int numImages, LayoutParams *layoutParams = 0) + Spinner(const ImageID *images, int numImages, LayoutParams *layoutParams = 0) : InertView(layoutParams), images_(images), numImages_(numImages) { } @@ -898,7 +901,7 @@ public: void SetColor(uint32_t color) { color_ = color; } private: - const int *images_; + const ImageID *images_; int numImages_; uint32_t color_ = 0xFFFFFFFF; };