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;
};