Merge branch 'ppge-scroll' of https://github.com/unknownbrackets/ppsspp into unknownbrackets-ppge-scroll

This commit is contained in:
Henrik Rydgård 2020-07-19 14:09:24 +02:00
commit 79b3352b67
10 changed files with 338 additions and 166 deletions

View File

@ -198,6 +198,16 @@ bool PSPDialog::IsButtonHeld(int checkButton, int &framesHeld, int framesHeldThr
return false;
}
PPGeStyle PSPDialog::FadedStyle(PPGeAlign align, float scale) {
PPGeStyle textStyle;
textStyle.align = align;
textStyle.scale = scale;
textStyle.color = CalcFadedColor(textStyle.color);
textStyle.hasShadow = true;
textStyle.shadowColor = CalcFadedColor(textStyle.shadowColor);
return textStyle;
}
void PSPDialog::DisplayButtons(int flags, const char *caption)
{
bool useCaption = false;
@ -207,6 +217,8 @@ void PSPDialog::DisplayButtons(int flags, const char *caption)
truncate_cpy(safeCaption, caption);
}
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, FONT_SCALE);
auto di = GetI18NCategory("Dialog");
float x1 = 183.5f, x2 = 261.5f;
if (GetCommonParam()->buttonSwap == 1) {
@ -215,16 +227,12 @@ void PSPDialog::DisplayButtons(int flags, const char *caption)
}
if (flags & DS_BUTTON_OK) {
const char *text = useCaption ? safeCaption : di->T("Enter");
PPGeDrawImage(okButtonImg, x2, 258, 11.5f, 11.5f, 0, CalcFadedColor(0x80000000));
PPGeDrawImage(okButtonImg, x2, 256, 11.5f, 11.5f, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(text, x2 + 15.5f, 254, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(text, x2 + 14.5f, 252, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(okButtonImg, x2, 256, 11.5f, 11.5f, textStyle);
PPGeDrawText(text, x2 + 14.5f, 252, textStyle);
}
if (flags & DS_BUTTON_CANCEL) {
const char *text = useCaption ? safeCaption : di->T("Back");
PPGeDrawText(text, x1 + 15.5f, 254, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(text, x1 + 14.5f, 252, PPGeAlign::BOX_LEFT, FONT_SCALE, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(cancelButtonImg, x1, 258, 11.5f, 11.5f, 0, CalcFadedColor(0x80000000));
PPGeDrawImage(cancelButtonImg, x1, 256, 11.5f, 11.5f, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(cancelButtonImg, x1, 256, 11.5f, 11.5f, textStyle);
PPGeDrawText(text, x1 + 14.5f, 252, textStyle);
}
}

View File

@ -22,6 +22,7 @@
#include "Common/Common.h"
#include "Common/CommonTypes.h"
#include "Common/Swap.h"
#include "Core/Util/PPGeDraw.h"
class PointerWrap;
@ -83,6 +84,7 @@ public:
void StartDraw();
void EndDraw();
protected:
PPGeStyle FadedStyle(PPGeAlign align, float scale);
void UpdateButtons();
bool IsButtonPressed(int checkButton);
bool IsButtonHeld(int checkButton, int &framesHeld, int framesHeldThreshold = 30, int framesHeldRepeatRate = 10);

View File

@ -15,7 +15,9 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include <algorithm>
#include "Core/Dialog/PSPMsgDialog.h"
#include "Core/Dialog/PSPSaveDialog.h"
#include "Core/Util/PPGeDraw.h"
#include "Core/HLE/sceCtrl.h"
#include "Core/MemMapHelpers.h"
@ -66,6 +68,9 @@ int PSPMsgDialog::Init(unsigned int paramAddr) {
}
flag = 0;
scrollPos_ = 0.0f;
framesUpHeld_ = 0;
framesDownHeld_ = 0;
// Check request invalidity
if(messageDialog.type == 0 && !(messageDialog.errorNum & 0x80000000))
@ -129,7 +134,7 @@ int PSPMsgDialog::Init(unsigned int paramAddr) {
}
if (flag & DS_ERRORMSG) {
snprintf(msgText, 512, "Error code: %08x", messageDialog.errorNum);
FormatErrorCode(messageDialog.errorNum);
} else {
truncate_cpy(msgText, messageDialog.string);
}
@ -141,74 +146,131 @@ int PSPMsgDialog::Init(unsigned int paramAddr) {
return 0;
}
void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK)
{
float WRAP_WIDTH = 300.0f;
if (UTF8StringNonASCIICount(text.c_str()) > 3)
WRAP_WIDTH = 372.0f;
float y = 140.0f;
float h, sy, ey;
PPGeMeasureText(nullptr, &h, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
float h2 = h / 2.0f;
ey = y + h2 + 20.0f;
void PSPMsgDialog::FormatErrorCode(uint32_t code) {
auto di = GetI18NCategory("Dialog");
if (hasYesNo)
{
auto di = GetI18NCategory("Dialog");
const char *choiceText;
u32 yesColor, noColor;
float x, w;
switch (code) {
case SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataDataBroken", "Save data was corrupt."), code);
break;
case SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_MS:
case SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK:
case SCE_UTILITY_SAVEDATA_ERROR_SAVE_NO_MS:
case SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_MS:
case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_MS:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataNoMS", "Memory stick not inserted."), code);
break;
case SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA:
case SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA:
case SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA:
case SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataNoData", "Warning: no save data was found."), code);
break;
case SCE_UTILITY_SAVEDATA_ERROR_RW_MEMSTICK_FULL:
case SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE:
snprintf(msgText, 512, "%s (%08x)", di->T("MsgErrorSavedataMSFull", "Memory stick full. Check your storage space."), code);
break;
default:
snprintf(msgText, 512, "%s %08x", di->T("MsgErrorCode", "Error code:"), code);
}
}
void PSPMsgDialog::DisplayMessage(std::string text, bool hasYesNo, bool hasOK) {
auto di = GetI18NCategory("Dialog");
PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE);
PPGeStyle messageStyle = FadedStyle(PPGeAlign::BOX_HCENTER, FONT_SCALE);
// Without the scrollbar, we have 390 total pixels.
float WRAP_WIDTH = 340.0f;
if (UTF8StringNonASCIICount(text.c_str()) >= text.size() / 4) {
WRAP_WIDTH = 376.0f;
if (text.size() > 12) {
messageStyle.scale = 0.6f;
}
}
float totalHeight = 0.0f;
PPGeMeasureText(nullptr, &totalHeight, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
// The PSP normally only shows about 8 lines at a time.
// For improved UX, we intentionally show part of the next line.
float visibleHeight = std::min(totalHeight, 175.0f);
float h2 = visibleHeight / 2.0f;
float centerY = 135.0f;
float sy = centerY - h2 - 15.0f;
float ey = centerY + h2 + 20.0f;
float buttonY = centerY + h2 + 5.0f;
auto drawSelectionBoxAndAdjust = [&](float x) {
// Box has a fixed size.
float w = 15.0f;
float h = 8.0f;
PPGeDrawRect(x - w, buttonY - h, x + w, buttonY + h, CalcFadedColor(0x6DCFCFCF));
centerY -= h + 5.0f;
sy -= h + 5.0f;
ey = buttonY + h * 2.0f + 5.0f;
};
if (hasYesNo) {
if (yesnoChoice == 1) {
choiceText = di->T("Yes");
x = 204.0f;
yesColor = 0xFFFFFFFF;
noColor = 0xFFFFFFFF;
drawSelectionBoxAndAdjust(204.0f);
} else {
drawSelectionBoxAndAdjust(273.0f);
}
else {
choiceText = di->T("No");
x = 273.0f;
yesColor = 0xFFFFFFFF;
noColor = 0xFFFFFFFF;
}
PPGeMeasureText(&w, &h, choiceText, FONT_SCALE);
w = 15.0f;
h = 8.0f;
float y2 = y + h2 + 8.0f;
h2 += h + 5.0f;
y = 135.0f - h;
PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF));
PPGeDrawText(di->T("Yes"), 204.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(di->T("Yes"), 203.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(yesColor));
PPGeDrawText(di->T("No"), 273.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(di->T("No"), 272.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(noColor));
PPGeDrawText(di->T("Yes"), 203.0f, buttonY - 1.0f, buttonStyle);
PPGeDrawText(di->T("No"), 272.0f, buttonY - 1.0f, buttonStyle);
if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) {
yesnoChoice = 1;
}
else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) {
} else if (IsButtonPressed(CTRL_RIGHT) && yesnoChoice == 1) {
yesnoChoice = 0;
}
ey = y2 + 25.0f;
buttonY += 8.0f + 5.0f;
}
if (hasOK) {
auto di = GetI18NCategory("Dialog");
float x, w;
x = 240.0f;
w = 15.0f;
h = 8.0f;
float y2 = y + h2 + 8.0f;
h2 += h + 5.0f;
y = 135.0f - h;
PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x6DCFCFCF));
PPGeDrawText(di->T("OK"), 240.0f, y2 + 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(di->T("OK"), 239.0f, y2 - 1.0f, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF));
ey = y2 + 25.0f;
drawSelectionBoxAndAdjust(240.0f);
PPGeDrawText(di->T("OK"), 239.0f, buttonY - 1.0f, buttonStyle);
buttonY += 8.0f + 5.0f;
}
PPGeScissor(0, (int)(centerY - h2 - 2), 480, (int)(centerY + h2 + 2));
PPGeDrawTextWrapped(text.c_str(), 240.0f, centerY - h2 - scrollPos_, WRAP_WIDTH, 0, messageStyle);
PPGeScissorReset();
// Do we need a scrollbar?
if (visibleHeight < totalHeight) {
float scrollSpeed = 5.0f;
float scrollMax = totalHeight - visibleHeight;
float bobHeight = (visibleHeight / totalHeight) * visibleHeight;
float bobOffset = (scrollPos_ / scrollMax) * (visibleHeight - bobHeight);
float bobY1 = centerY - h2 + bobOffset;
PPGeDrawRect(435.0f, bobY1, 440.0f, bobY1 + bobHeight, CalcFadedColor(0xFFCCCCCC));
auto buttonDown = [this](int btn, int &held) {
if (IsButtonPressed(btn)) {
held = 0;
return true;
}
return IsButtonHeld(btn, held, 1, 1);
};
if (buttonDown(CTRL_DOWN, framesDownHeld_) && scrollPos_ < scrollMax) {
scrollPos_ = std::min(scrollMax, scrollPos_ + scrollSpeed);
}
if (buttonDown(CTRL_UP, framesUpHeld_) && scrollPos_ > 0.0f) {
scrollPos_ = std::max(0.0f, scrollPos_ - scrollSpeed);
}
}
PPGeDrawTextWrapped(text.c_str(), 241.0f, y+2, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawTextWrapped(text.c_str(), 240.0f, y, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF));
sy = 125.0f - h2;
PPGeDrawRect(40.0f, sy, 440.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawRect(40.0f, ey, 440.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF));
}
@ -321,6 +383,13 @@ void PSPMsgDialog::DoState(PointerWrap &p)
p.Do(messageDialogAddr);
p.DoArray(msgText, sizeof(msgText));
p.Do(yesnoChoice);
// We don't save state this, you'll just have to scroll down again.
if (p.mode == p.MODE_READ) {
scrollPos_ = 0.0f;
framesUpHeld_ = 0;
framesDownHeld_ = 0;
}
}
pspUtilityDialogCommon *PSPMsgDialog::GetCommonParam()

View File

@ -74,7 +74,8 @@ protected:
return false;
}
private :
private:
void FormatErrorCode(uint32_t code);
void DisplayMessage(std::string text, bool hasYesNo = false, bool hasOK = false);
enum Flags
@ -98,5 +99,8 @@ private :
char msgText[512];
int yesnoChoice;
float scrollPos_ = 0.0f;
int framesUpHeld_ = 0;
int framesDownHeld_ = 0;
};

View File

@ -65,10 +65,13 @@ void PSPNetconfDialog::DrawBanner() {
PPGeDrawRect(0, 0, 480, 23, CalcFadedColor(0x65636358));
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f);
textStyle.hasShadow = false;
// TODO: Draw a hexagon icon
PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, textStyle.color);
auto di = GetI18NCategory("Dialog");
PPGeDrawText(di->T("Network Connection"), 30, 11, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Network Connection"), 30, 11, textStyle);
}
int PSPNetconfDialog::Update(int animSpeed) {
@ -83,14 +86,17 @@ int PSPNetconfDialog::Update(int animSpeed) {
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;
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f);
PPGeStyle buttonStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f);
if (request.netAction == NETCONF_CONNECT_APNET || request.netAction == NETCONF_STATUS_APNET || request.netAction == NETCONF_CONNECT_APNET_LAST) {
UpdateFade(animSpeed);
StartDraw();
DrawBanner();
PPGeDrawRect(0, 0, 480, 272, CalcFadedColor(0x63636363));
PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("OK"), 225, 252, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawTextWrapped(err->T("PPSSPPDoesNotSupportInternet", "PPSSPP currently does not support connecting to the Internet for DLC, PSN, or game updates."), 241, 132, WRAP_WIDTH, 0, textStyle);
PPGeDrawImage(confirmBtnImage, 195, 250, 20, 20, buttonStyle);
PPGeDrawText(di->T("OK"), 225, 252, buttonStyle);
if (IsButtonPressed(confirmBtn)) {
StartFade(false);

View File

@ -766,7 +766,14 @@ void PSPOskDialog::RenderKeyboard()
float previewLeftSide = (480.0f - (12.0f * drawLimit)) / 2.0f;
float title = (480.0f - (0.5f * drawLimit)) / 2.0f;
PPGeDrawText(oskDesc.c_str(), title , 20, PPGeAlign::BOX_CENTER, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeStyle descStyle = FadedStyle(PPGeAlign::BOX_CENTER, 0.5f);
PPGeDrawText(oskDesc.c_str(), title, 20, descStyle);
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.5f);
PPGeStyle keyStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.6f);
PPGeStyle selectedKeyStyle = FadedStyle(PPGeAlign::BOX_HCENTER, 0.6f);
selectedKeyStyle.color = CalcFadedColor(0xFF3060FF);
std::u16string result;
@ -776,12 +783,11 @@ void PSPOskDialog::RenderKeyboard()
drawIndex = result.size() == limit + 1 ? drawIndex - 1 : drawIndex; // When the length reached limit, the last character don't fade in and out.
for (u32 i = 0; i < drawLimit; ++i, ++drawIndex)
{
u32 color = CalcFadedColor(0xFFFFFFFF);
if (drawIndex + 1 < result.size())
{
temp[0] = result[drawIndex];
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, textStyle);
}
else
{
@ -794,25 +800,25 @@ void PSPOskDialog::RenderKeyboard()
float animStep = (float)(__DisplayGetNumVblanks() % 40) / 20.0f;
// Fade in and out the next character so they know it's not part of the string yet.
u32 alpha = (0.5f - (cosf(animStep * M_PI) / 2.0f)) * 128 + 127;
color = CalcFadedColor((alpha << 24) | 0xFFFFFF);
PPGeStyle animStyle = textStyle;
animStyle.color = CalcFadedColor((alpha << 24) | 0x00FFFFFF);
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, animStyle);
// Also draw the underline for the same reason.
color = CalcFadedColor(0xFFFFFFFF);
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color);
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, textStyle);
}
else
{
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color);
PPGeDrawText(buffer.c_str(), previewLeftSide + (i * characterWidth), 40.0f, textStyle);
}
}
else
{
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, PPGeAlign::BOX_HCENTER, 0.5f, color);
PPGeDrawText("_", previewLeftSide + (i * characterWidth), 40.0f, textStyle);
}
}
}
@ -821,17 +827,16 @@ void PSPOskDialog::RenderKeyboard()
{
for (int col = 0; col < numKeyCols[currentKeyboard]; ++col)
{
u32 color = CalcFadedColor(0xFFFFFFFF);
if (selectedRow == row && col == selectedCol)
color = CalcFadedColor(0xFF3060FF);
temp[0] = oskKeys[currentKeyboard][row][col];
ConvertUCS2ToUTF8(buffer, temp);
PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGeAlign::BOX_HCENTER, 0.6f, color);
if (selectedRow == row && col == selectedCol)
PPGeDrawText("_", keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), PPGeAlign::BOX_HCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF));
if (selectedRow == row && col == selectedCol) {
PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), selectedKeyStyle);
PPGeDrawText("_", keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), keyStyle);
} else {
PPGeDrawText(buffer.c_str(), keyboardLeftSide + (25.0f * col) + characterWidth / 2.0, 70.0f + (25.0f * row), keyStyle);
}
}
}
}
@ -944,22 +949,25 @@ int PSPOskDialog::Update(int animSpeed) {
auto di = GetI18NCategory("Dialog");
PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Space"), 390, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeStyle actionStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f);
PPGeStyle guideStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.6f);
PPGeDrawImage(ImageID("I_SQUARE"), 365, 222, 16, 16, guideStyle);
PPGeDrawText(di->T("Space"), 390, 222, actionStyle);
if (g_Config.iButtonPreference != PSP_SYSTEMPARAM_BUTTON_CIRCLE) {
PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CIRCLE"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CROSS"), 45, 222, 16, 16, guideStyle);
PPGeDrawImage(ImageID("I_CIRCLE"), 45, 247, 16, 16, guideStyle);
} else {
PPGeDrawImage(ImageID("I_CIRCLE"), 45, 222, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, 0, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(ImageID("I_CIRCLE"), 45, 222, 16, 16, guideStyle);
PPGeDrawImage(ImageID("I_CROSS"), 45, 247, 16, 16, guideStyle);
}
PPGeDrawText(di->T("Select"), 75, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Delete"), 75, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Select"), 75, 222, actionStyle);
PPGeDrawText(di->T("Delete"), 75, 247, actionStyle);
PPGeDrawText("Start", 135, 220, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Finish"), 185, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText("Start", 135, 220, guideStyle);
PPGeDrawText(di->T("Finish"), 185, 222, actionStyle);
auto lookupLangName = [&](int direction) {
// First, find the valid one...
@ -983,20 +991,20 @@ int PSPOskDialog::Update(int animSpeed) {
};
if (OskKeyboardNames[currentKeyboardLanguage] != "ko_KR" && IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) {
PPGeDrawText("Select", 135, 245, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(di->T("Shift"), 185, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText("Select", 135, 245, guideStyle);
PPGeDrawText(di->T("Shift"), 185, 247, actionStyle);
}
const char *prevLang = lookupLangName(-1);
if (prevLang) {
PPGeDrawText("L", 235, 220, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(prevLang, 255, 222, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText("L", 235, 220, guideStyle);
PPGeDrawText(prevLang, 255, 222, actionStyle);
}
const char *nextLang = lookupLangName(1);
if (nextLang) {
PPGeDrawText("R", 235, 245, PPGeAlign::BOX_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(nextLang, 255, 247, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText("R", 235, 245, guideStyle);
PPGeDrawText(nextLang, 255, 247, actionStyle);
}
if (IsButtonPressed(CTRL_UP) || IsButtonHeld(CTRL_UP, upBtnFramesHeld, framesHeldThreshold, framesHeldRepeatRate)) {

View File

@ -283,6 +283,10 @@ void PSPSaveDialog::DisplayBanner(int which)
{
auto di = GetI18NCategory("Dialog");
PPGeDrawRect(0, 0, 480, 23, CalcFadedColor(0x65636358));
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f);
textStyle.hasShadow = false;
const char *title;
switch (which)
{
@ -300,8 +304,8 @@ void PSPSaveDialog::DisplayBanner(int which)
break;
}
// TODO: Draw a hexagon icon
PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(title, 30, 11, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawImage(10, 6, 12.0f, 12.0f, 1, 10, 1, 10, 10, 10, textStyle.color);
PPGeDrawText(title, 30, 11, textStyle);
}
void PSPSaveDialog::DisplaySaveList(bool canMove) {
@ -436,7 +440,8 @@ void PSPSaveDialog::DisplaySaveDataInfo1() {
if (saveInfo.size == 0) {
auto di = GetI18NCategory("Dialog");
PPGeDrawText(di->T("NEW DATA"), 180, 136, PPGeAlign::BOX_VCENTER, 0.6f, CalcFadedColor(0xFFFFFFFF));
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_VCENTER, 0.6f);
PPGeDrawText(di->T("NEW DATA"), 180, 136, textStyle);
} else {
char hour_time[32];
FormatSaveHourMin(hour_time, sizeof(hour_time), saveInfo.modif_time);
@ -452,14 +457,15 @@ void PSPSaveDialog::DisplaySaveDataInfo1() {
std::string saveTitleTxt = saveInfo.saveTitle;
std::string saveDetailTxt = saveInfo.saveDetail;
PPGeDrawText(titleTxt.c_str(), 181, 138, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0x80000000));
PPGeDrawText(titleTxt.c_str(), 180, 136, PPGeAlign::BOX_BOTTOM, 0.6f, CalcFadedColor(0xFFC0C0C0));
PPGeDrawText(timeTxt.c_str(), 181, 139, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000));
PPGeDrawText(timeTxt.c_str(), 180, 137, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(saveTitleTxt.c_str(), 176, 162, PPGeAlign::BOX_LEFT, 0.55f, CalcFadedColor(0x80000000));
PPGeDrawText(saveTitleTxt.c_str(), 175, 159, PPGeAlign::BOX_LEFT, 0.55f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawTextWrapped(saveDetailTxt.c_str(), 176, 183, 480 - 175, 250 - 183, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000));
PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeStyle titleStyle = FadedStyle(PPGeAlign::BOX_BOTTOM, 0.6f);
PPGeStyle saveTitleStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.55f);
titleStyle.color = CalcFadedColor(0xFFC0C0C0);
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f);
PPGeDrawText(titleTxt.c_str(), 180, 136, titleStyle);
PPGeDrawText(timeTxt.c_str(), 180, 137, textStyle);
PPGeDrawText(saveTitleTxt.c_str(), 175, 159, saveTitleStyle);
PPGeDrawTextWrapped(saveDetailTxt.c_str(), 175, 181, 480 - 175, 250 - 181, textStyle);
}
}
@ -491,13 +497,15 @@ void PSPSaveDialog::DisplaySaveDataInfo2(bool showNewData) {
s64 sizeK = data_size / 1024;
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_LEFT, 0.5f);
std::string saveinfoTxt = StringFromFormat("%.128s\n%s %s\n%lld KB", save_title, date_year, hour_time, sizeK);
PPGeDrawText(saveinfoTxt.c_str(), 9, 202, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0x80000000));
PPGeDrawText(saveinfoTxt.c_str(), 8, 200, PPGeAlign::BOX_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawText(saveinfoTxt.c_str(), 8, 200, textStyle);
}
void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo)
{
PPGeStyle textStyle = FadedStyle(PPGeAlign::BOX_CENTER, FONT_SCALE);
const float WRAP_WIDTH = 254.0f;
float y = 136.0f, h;
PPGeMeasureText(nullptr, &h, text.c_str(), FONT_SCALE, PPGE_LINE_WRAP_WORD, WRAP_WIDTH);
@ -506,19 +514,14 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo)
{
auto di = GetI18NCategory("Dialog");
const char *choiceText;
u32 yesColor, noColor;
float x, w;
if (yesnoChoice == 1) {
choiceText = di->T("Yes");
x = 302.0f;
yesColor = 0xFFFFFFFF;
noColor = 0xFFFFFFFF;
}
else {
choiceText = di->T("No");
x = 366.0f;
yesColor = 0xFFFFFFFF;
noColor = 0xFFFFFFFF;
}
PPGeMeasureText(&w, &h, choiceText, FONT_SCALE);
w = w / 2.0f + 5.5f;
@ -527,10 +530,8 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo)
h2 += h + 4.0f;
y = 132.0f - h;
PPGeDrawRect(x - w, y2 - h, x + w, y2 + h, CalcFadedColor(0x40C0C0C0));
PPGeDrawText(di->T("Yes"), 303.0f, y2+2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(di->T("Yes"), 302.0f, y2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(yesColor));
PPGeDrawText(di->T("No"), 367.0f, y2+2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawText(di->T("No"), 366.0f, y2, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(noColor));
PPGeDrawText(di->T("Yes"), 302.0f, y2, textStyle);
PPGeDrawText(di->T("No"), 366.0f, y2, textStyle);
if (IsButtonPressed(CTRL_LEFT) && yesnoChoice == 0) {
yesnoChoice = 1;
}
@ -538,8 +539,7 @@ void PSPSaveDialog::DisplayMessage(std::string text, bool hasYesNo)
yesnoChoice = 0;
}
}
PPGeDrawTextWrapped(text.c_str(), 335.0f, y+2, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0x80000000));
PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, PPGeAlign::BOX_CENTER, FONT_SCALE, CalcFadedColor(0xFFFFFFFF));
PPGeDrawTextWrapped(text.c_str(), 334.0f, y, WRAP_WIDTH, 0, textStyle);
float sy = 122.0f - h2, ey = 150.0f + h2;
PPGeDrawRect(202.0f, sy, 466.0f, sy + 1.0f, CalcFadedColor(0xFFFFFFFF));
PPGeDrawRect(202.0f, ey, 466.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF));

View File

@ -17,6 +17,7 @@
#pragma once
#include <set>
#include "Common/CommonTypes.h"
#include "Core/MemMap.h"
#include "Core/HLE/sceRtc.h"

View File

@ -17,6 +17,7 @@
#include <algorithm>
#include "base/colorutil.h"
#include "base/stringutil.h"
#include "file/vfs.h"
#include "gfx/texture_atlas.h"
@ -140,6 +141,7 @@ void PPGeSetTexture(u32 dataAddr, int width, int height);
static void WriteCmd(u8 cmd, u32 data) {
Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr);
dlWritePtr += 4;
assert(dlWritePtr <= dlPtr + dlSize);
}
static void WriteCmdAddrWithBase(u8 cmd, u32 addr) {
@ -178,6 +180,7 @@ static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color
Memory::WriteStruct(dataWritePtr, &vtx);
dataWritePtr += sizeof(vtx);
}
assert(dataWritePtr <= dataPtr + dataSize);
vertexCount++;
}
@ -384,8 +387,7 @@ void PPGeBegin()
PPGeSetDefaultTexture();
WriteCmd(GE_CMD_SCISSOR1, (0 << 10) | 0);
WriteCmd(GE_CMD_SCISSOR2, (271 << 10) | 479);
PPGeScissor(0, 0, 480, 272);
WriteCmd(GE_CMD_MINZ, 0);
WriteCmd(GE_CMD_MAXZ, 0xFFFF);
@ -417,6 +419,17 @@ void PPGeEnd()
}
}
void PPGeScissor(int x1, int y1, int x2, int y2) {
assert(x1 >= 0 && x1 <= 480 && x2 >= 0 && x2 <= 480);
assert(y1 >= 0 && y1 <= 272 && y2 >= 0 && y2 <= 272);
WriteCmd(GE_CMD_SCISSOR1, (y1 << 10) | x1);
WriteCmd(GE_CMD_SCISSOR2, ((y2 - 1) << 10) | (x2 - 1));
}
void PPGeScissorReset() {
PPGeScissor(0, 0, 480, 272);
}
static const AtlasChar *PPGeGetChar(const AtlasFont &atlasfont, unsigned int cval)
{
const AtlasChar *c = atlasfont.getChar(cval);
@ -789,14 +802,14 @@ int GetPow2(int x) {
return ret;
}
static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, float scale, float maxWidth, bool wrap) {
static PPGeTextDrawerImage PPGeGetTextImage(const char *text, const PPGeStyle &style, float maxWidth, bool wrap) {
int tdalign = 0;
tdalign |= FLAG_ELLIPSIZE_TEXT;
if (wrap) {
tdalign |= FLAG_WRAP_TEXT;
}
PPGeTextDrawerCacheKey key{ text, tdalign, maxWidth / scale };
PPGeTextDrawerCacheKey key{ text, tdalign, maxWidth / style.scale };
PPGeTextDrawerImage im{};
auto cacheItem = textDrawerImages.find(key);
@ -805,7 +818,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, f
cacheItem->second.entry.lastUsedFrame = gpuStats.numFlips;
} else {
std::vector<uint8_t> bitmapData;
textDrawer->SetFontScale(scale, scale);
textDrawer->SetFontScale(style.scale, style.scale);
Bounds b(0, 0, maxWidth, 272.0f);
std::string cleaned = ReplaceAll(text, "\r", "");
textDrawer->DrawStringBitmapRect(bitmapData, im.entry, Draw::DataFormat::R8_UNORM, cleaned.c_str(), b, tdalign);
@ -842,7 +855,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, PPGeAlign align, f
return im;
}
static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlign align, float scale, u32 color) {
static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, const PPGeStyle &style) {
if (!im.ptr) {
return;
}
@ -855,41 +868,58 @@ static void PPGeDrawTextImage(PPGeTextDrawerImage im, float x, float y, PPGeAlig
WriteCmd(GE_CMD_TEXSIZE0, wp2 | (hp2 << 8));
WriteCmd(GE_CMD_TEXFLUSH, 0);
float w = im.entry.width * scale;
float h = im.entry.height * scale;
float w = im.entry.width * style.scale;
float h = im.entry.height * style.scale;
if (align & PPGeAlign::BOX_HCENTER)
if (style.align & PPGeAlign::BOX_HCENTER)
x -= w / 2.0f;
else if (align & PPGeAlign::BOX_RIGHT)
else if (style.align & PPGeAlign::BOX_RIGHT)
x -= w;
if (align & PPGeAlign::BOX_VCENTER)
if (style.align & PPGeAlign::BOX_VCENTER)
y -= h / 2.0f;
else if (align & PPGeAlign::BOX_BOTTOM)
else if (style.align & PPGeAlign::BOX_BOTTOM)
y -= h;
BeginVertexData();
float u1 = (float)im.entry.width / (1 << wp2);
float v1 = (float)im.entry.height / (1 << hp2);
Vertex(x, y, 0, 0, 1 << wp2, 1 << hp2, color);
Vertex(x + w, y + h, u1, v1, 1 << wp2, 1 << hp2, color);
if (style.hasShadow) {
// Draw more shadows for a blurrier shadow.
for (float dy = 0.0f; dy <= 2.0f; dy += 1.0f) {
for (float dx = 0.0f; dx <= 1.0f; dx += 0.5f) {
if (dx == 0.0f && dy == 0.0f)
continue;
Vertex(x + dx, y + dy, 0, 0, 1 << wp2, 1 << hp2, alphaMul(style.shadowColor, 0.35f));
Vertex(x + dx + w, y + dy + h, u1, v1, 1 << wp2, 1 << hp2, alphaMul(style.shadowColor, 0.35f));
}
}
}
Vertex(x, y, 0, 0, 1 << wp2, 1 << hp2, style.color);
Vertex(x + w, y + h, u1, v1, 1 << wp2, 1 << hp2, style.color);
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
PPGeSetDefaultTexture();
}
void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale, u32 color) {
void PPGeDrawText(const char *text, float x, float y, const PPGeStyle &style) {
if (!text || !strlen(text)) {
return;
}
if (HasTextDrawer()) {
PPGeTextDrawerImage im = PPGeGetTextImage(text, align, scale, 480.0f - x, false);
PPGeDrawTextImage(im, x, y, align, scale, color);
PPGeTextDrawerImage im = PPGeGetTextImage(text, style, 480.0f - x, false);
PPGeDrawTextImage(im, x, y, style);
return;
}
PPGePrepareText(text, x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS);
PPGeDrawCurrentText(color);
if (style.hasShadow) {
// This doesn't have the nicer shadow because it's so many verts.
PPGePrepareText(text, x + 1, y + 2, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS);
PPGeDrawCurrentText(style.shadowColor);
}
PPGePrepareText(text, x, y, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS);
PPGeDrawCurrentText(style.color);
}
static std::string StripTrailingWhite(const std::string &s) {
@ -915,7 +945,7 @@ static std::string CropLinesToCount(const std::string &s, int numLines) {
return s.substr(0, len);
}
void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, PPGeAlign align, float scale, u32 color) {
void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, const PPGeStyle &style) {
std::string s = text;
if (wrapHeight != 0.0f) {
s = StripTrailingWhite(s);
@ -928,8 +958,11 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl
float actualWidth, actualHeight;
Bounds b(0, 0, wrapWidth <= 0 ? 480.0f - x : wrapWidth, wrapHeight);
int tdalign = 0;
textDrawer->SetFontScale(scale, scale);
textDrawer->SetFontScale(style.scale, style.scale);
textDrawer->MeasureStringRect(s.c_str(), s.size(), b, &actualWidth, &actualHeight, tdalign | FLAG_WRAP_TEXT);
// Check if we need to scale the text down to fit better.
PPGeStyle adjustedStyle = style;
if (wrapHeight != 0.0f && actualHeight > wrapHeight) {
// Cheap way to get the line height.
float oneLine, twoLines;
@ -945,16 +978,20 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl
s = StripTrailingWhite(CropLinesToCount(s, (int)maxLines)) + "\n...";
}
scale *= wrapHeight / actualHeight;
adjustedStyle.scale *= wrapHeight / actualHeight;
}
PPGeTextDrawerImage im = PPGeGetTextImage(s.c_str(), align, scale, wrapWidth <= 0 ? 480.0f - x : wrapWidth, true);
PPGeDrawTextImage(im, x, y, align, scale, color);
PPGeTextDrawerImage im = PPGeGetTextImage(s.c_str(), adjustedStyle, wrapWidth <= 0 ? 480.0f - x : wrapWidth, true);
PPGeDrawTextImage(im, x, y, adjustedStyle);
return;
}
PPGePrepareText(s.c_str(), x, y, align, scale, scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
int sx = style.hasShadow ? 1 : 0;
int sy = style.hasShadow ? 2 : 0;
PPGePrepareText(s.c_str(), x + sx, y + sy, style.align, style.scale, style.scale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
float scale = style.scale;
float lineHeightScale = style.scale;
float actualHeight = char_lines_metrics.lineHeight * char_lines_metrics.numLines;
if (wrapHeight != 0.0f && actualHeight > wrapHeight) {
if (actualHeight > wrapHeight * maxScaleDown) {
@ -967,11 +1004,18 @@ void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, fl
// Measure the text again after scaling down.
PPGeResetCurrentText();
float reduced = scale * wrapHeight / actualHeight;
float reduced = style.scale * wrapHeight / actualHeight;
// Try to keep the font as large as possible, so reduce the line height some.
PPGePrepareText(s.c_str(), x, y, align, reduced * 1.15, reduced, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
scale = reduced * 1.15f;
lineHeightScale = reduced;
PPGePrepareText(s.c_str(), x + sx, y + sy, style.align, scale, lineHeightScale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
}
PPGeDrawCurrentText(color);
if (style.hasShadow) {
// This doesn't have the nicer shadow because it's so many verts.
PPGeDrawCurrentText(style.shadowColor);
PPGePrepareText(s.c_str(), x, y, style.align, scale, lineHeightScale, PPGE_LINE_USE_ELLIPSIS | PPGE_LINE_WRAP_WORD, wrapWidth);
}
PPGeDrawCurrentText(style.color);
}
// Draws a "4-patch" for button-like things that can be resized
@ -1031,8 +1075,7 @@ 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(ImageID atlasImage, float x, float y, int align, u32 color)
{
void PPGeDrawImage(ImageID atlasImage, float x, float y, const PPGeStyle &style) {
if (!dlPtr)
return;
@ -1043,13 +1086,22 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, int align, u32 color)
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);
if (style.hasShadow) {
for (float dy = 0.0f; dy <= 2.0f; dy += 1.0f) {
for (float dx = 0.0f; dx <= 1.0f; dx += 0.5f) {
if (dx == 0.0f && dy == 0.0f)
continue;
Vertex(x + dx, y + dy, img->u1, img->v1, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f));
Vertex(x + dx + w, y + dy + h, img->u2, img->v2, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f));
}
}
}
Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, style.color);
Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, style.color);
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}
void PPGeDrawImage(ImageID 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, const PPGeStyle &style) {
if (!dlPtr)
return;
@ -1058,8 +1110,18 @@ void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, int a
return;
}
BeginVertexData();
Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, color);
Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, color);
if (style.hasShadow) {
for (float dy = 0.0f; dy <= 2.0f; dy += 1.0f) {
for (float dx = 0.0f; dx <= 1.0f; dx += 0.5f) {
if (dx == 0.0f && dy == 0.0f)
continue;
Vertex(x + dx, y + dy, img->u1, img->v1, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f));
Vertex(x + dx + w, y + dy + h, img->u2, img->v2, atlasWidth, atlasHeight, alphaMul(style.shadowColor, 0.35f));
}
}
}
Vertex(x, y, img->u1, img->v1, atlasWidth, atlasHeight, style.color);
Vertex(x + w, y + h, img->u2, img->v2, atlasWidth, atlasHeight, style.color);
EndVertexDataAndDraw(GE_PRIM_RECTANGLES);
}

View File

@ -69,22 +69,34 @@ enum {
PPGE_LINE_WRAP_CHAR = 4,
};
struct PPGeStyle {
PPGeAlign align = PPGeAlign::BOX_LEFT;
float scale = 1.0f;
uint32_t color = 0xFFFFFFFF;
bool hasShadow = false;
uint32_t shadowColor = 0x80000000;
};
// Get the metrics of the bounding box of the text without changing the buffer or state.
void PPGeMeasureText(float *w, float *h, const char *text, float scale, int WrapType = PPGE_LINE_NONE, int wrapWidth = 0);
// Draws some text using the one font we have.
// Clears the text buffer when done.
void PPGeDrawText(const char *text, float x, float y, PPGeAlign align, float scale = 1.0f, u32 color = 0xFFFFFFFF);
void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, PPGeAlign align, float scale = 1.0f, u32 color = 0xFFFFFFFF);
void PPGeDrawText(const char *text, float x, float y, const PPGeStyle &style);
void PPGeDrawTextWrapped(const char *text, float x, float y, float wrapWidth, float wrapHeight, const PPGeStyle &style);
// Draws a "4-patch" for button-like things that can be resized.
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(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(ImageID atlasImage, float x, float y, const PPGeStyle &style);
void PPGeDrawImage(ImageID atlasImage, float x, float y, float w, float h, const PPGeStyle &style);
void PPGeDrawImage(float x, float y, float w, float h, float u1, float v1, float u2, float v2, int tw, int th, u32 color);
// Note: x2/y2 are exclusive.
void PPGeScissor(int x1, int y1, int x2, int y2);
void PPGeScissorReset();
void PPGeNotifyFrame();
class PPGeImage {