Switch all images to dynamic lookup in the atlas by string ID.

SLN fix

It works, but with the wrong images and the wrong characters!

Fix another bug in atlastool's binary output

Get Android building again.

Oops, didn't mean to disable this permanently.

Error checking

Minor cleanup

Gotta tweak my git ignores...

Regenerate metadata
This commit is contained in:
Henrik Rydgård 2020-02-29 21:51:14 +01:00
parent 7e9578e49d
commit 45d94c4877
51 changed files with 676 additions and 476 deletions

4
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -71,7 +71,6 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\Windows\fix_2017.props" />
</ImportGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@ -834,7 +833,6 @@
<ClCompile Include="Util\DisArm64.cpp" />
<ClCompile Include="Util\GameManager.cpp" />
<ClCompile Include="Util\PPGeDraw.cpp" />
<ClCompile Include="Util\ppge_atlas.cpp" />
<ClCompile Include="..\ext\xxhash.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IntrinsicFunctions>
@ -1166,7 +1164,6 @@
<ClInclude Include="Util\DisArm64.h" />
<ClInclude Include="Util\GameManager.h" />
<ClInclude Include="Util\PPGeDraw.h" />
<ClInclude Include="Util\ppge_atlas.h" />
<ClInclude Include="..\ext\xxhash.h" />
<ClInclude Include="WaveFile.h" />
<ClInclude Include="WebServer.h" />

View File

@ -336,9 +336,6 @@
<ClCompile Include="Util\PPGeDraw.cpp">
<Filter>Util</Filter>
</ClCompile>
<ClCompile Include="Util\ppge_atlas.cpp">
<Filter>Util</Filter>
</ClCompile>
<ClCompile Include="HLE\sceFont.cpp">
<Filter>HLE\Libraries</Filter>
</ClCompile>
@ -1000,9 +997,6 @@
<ClInclude Include="Util\PPGeDraw.h">
<Filter>Util</Filter>
</ClInclude>
<ClInclude Include="Util\ppge_atlas.h">
<Filter>Util</Filter>
</ClInclude>
<ClInclude Include="HLE\sceFont.h">
<Filter>HLE\Libraries</Filter>
</ClInclude>

View File

@ -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);

View File

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

View File

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

View File

@ -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) {

View File

@ -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));

View File

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

View File

@ -18,6 +18,8 @@
#include <algorithm>
#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);
}

View File

@ -19,7 +19,9 @@
#include <vector>
#include <string>
#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 {

View File

@ -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<std::string, int> 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<std::string, ImageID> 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<std::string, int>::iterator imageFinder;
std::map<std::string, ImageID>::iterator imageFinder;
auto mc = GetI18NCategory("MappableControls");

View File

@ -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<std::string, int> 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<std::string, ImageID> 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();

View File

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <deque>
#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())

View File

@ -17,13 +17,17 @@
#include <algorithm>
#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) {

View File

@ -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) {
}
};

View File

@ -18,11 +18,11 @@
#include <vector>
#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;

View File

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

View File

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

View File

@ -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:

View File

@ -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"

View File

@ -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)

View File

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

View File

@ -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();

View File

@ -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"

View File

@ -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"

View File

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

View File

@ -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));

View File

@ -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 {

View File

@ -65,7 +65,6 @@
<ClCompile Include="TouchControlLayoutScreen.cpp" />
<ClCompile Include="TouchControlVisibilityScreen.cpp" />
<ClCompile Include="InstallZipScreen.cpp" />
<ClCompile Include="ui_atlas.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BackgroundAudio.h" />
@ -98,7 +97,6 @@
<ClInclude Include="TouchControlLayoutScreen.h" />
<ClInclude Include="TouchControlVisibilityScreen.h" />
<ClInclude Include="InstallZipScreen.h" />
<ClInclude Include="ui_atlas.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ext\discord-rpc-build\discord-rpc.vcxproj">
@ -426,4 +424,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -4,7 +4,6 @@
<ClCompile Include="GameInfoCache.cpp" />
<ClCompile Include="GamepadEmu.cpp" />
<ClCompile Include="NativeApp.cpp" />
<ClCompile Include="ui_atlas.cpp" />
<ClCompile Include="OnScreenDisplay.cpp" />
<ClCompile Include="EmuScreen.cpp">
<Filter>Screens</Filter>
@ -78,7 +77,6 @@
<ItemGroup>
<ClInclude Include="GameInfoCache.h" />
<ClInclude Include="GamepadEmu.h" />
<ClInclude Include="ui_atlas.h" />
<ClInclude Include="OnScreenDisplay.h" />
<ClInclude Include="EmuScreen.h">
<Filter>Screens</Filter>
@ -155,4 +153,4 @@
<UniqueIdentifier>{faee5dce-633b-4ba6-b19d-ea70ee3c1c38}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
</Project>

View File

@ -409,7 +409,6 @@
<ClInclude Include="..\..\UI\TiltEventProcessor.h" />
<ClInclude Include="..\..\UI\TouchControlLayoutScreen.h" />
<ClInclude Include="..\..\UI\TouchControlVisibilityScreen.h" />
<ClInclude Include="..\..\UI\ui_atlas.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
@ -444,7 +443,6 @@
<ClCompile Include="..\..\UI\TiltEventProcessor.cpp" />
<ClCompile Include="..\..\UI\TouchControlLayoutScreen.cpp" />
<ClCompile Include="..\..\UI\TouchControlVisibilityScreen.cpp" />
<ClCompile Include="..\..\UI\ui_atlas.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

View File

@ -32,7 +32,6 @@
<ClCompile Include="..\..\UI\TiltEventProcessor.cpp" />
<ClCompile Include="..\..\UI\TouchControlLayoutScreen.cpp" />
<ClCompile Include="..\..\UI\TouchControlVisibilityScreen.cpp" />
<ClCompile Include="..\..\UI\ui_atlas.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
@ -67,6 +66,5 @@
<ClInclude Include="..\..\UI\TiltEventProcessor.h" />
<ClInclude Include="..\..\UI\TouchControlLayoutScreen.h" />
<ClInclude Include="..\..\UI\TouchControlVisibilityScreen.h" />
<ClInclude Include="..\..\UI\ui_atlas.h" />
</ItemGroup>
</Project>

View File

@ -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

5
android/.gitignore vendored
View File

@ -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

Binary file not shown.

Binary file not shown.

View File

@ -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

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -1,22 +1,100 @@
#include <string.h>
#include <cstring>
#include <cstdint>
#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<class T>
T Read() {
T x;
memcpy(&x, data_ + offset_, sizeof(T));
offset_ += sizeof(T);
return x;
}
return 0;
template<class T>
void ReadInto(T *t) {
memcpy(t, data_ + offset_, sizeof(T));
offset_ += sizeof(T);
}
template<class T>
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<AtlasHeader>();
num_images = header.numImages;
num_fonts = header.numFonts;
if (header.magic != ATLAS_MAGIC) {
return false;
}
images = reader.ReadMultipleAlloc<AtlasImage>(num_images);
fonts = new AtlasFont[num_fonts];
for (int i = 0; i < num_fonts; i++) {
AtlasFontHeader font_header = reader.Read<AtlasFontHeader>();
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<AtlasCharRange>(font_header.numRanges);
fonts[i].charData = reader.ReadMultipleAlloc<AtlasChar>(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;
}

View File

@ -1,5 +1,8 @@
#pragma once
#include <cstdint>
#include <cstring>
#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;
};

View File

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

View File

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

View File

@ -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<Data> &results) {
AtlasImage2 img;
AtlasImage ToAtlasImage(float tw, float th, const vector<Data> &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());

View File

@ -60,6 +60,7 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>../build/</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>

View File

@ -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) {

View File

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