azahar/src/citra_qt/notification_led.cpp
Cobalt d4b5633cf0
Some checks failed
citra-build / source (push) Has been cancelled
citra-build / linux-x86_64 (appimage) (push) Has been cancelled
citra-build / linux-x86_64 (appimage-wayland) (push) Has been cancelled
citra-build / linux-x86_64 (gcc-nopch) (push) Has been cancelled
citra-build / linux-arm64 (clang) (push) Has been cancelled
citra-build / linux-arm64 (gcc-nopch) (push) Has been cancelled
citra-build / macos (push) Has been cancelled
citra-build / windows (msvc) (push) Has been cancelled
citra-build / windows (msys2) (push) Has been cancelled
citra-build / android (googleplay) (push) Has been cancelled
citra-build / android (vanilla) (push) Has been cancelled
citra-build / docker (push) Has been cancelled
citra-format / clang-format (push) Has been cancelled
citra-libretro / android (push) Has been cancelled
citra-libretro / linux (push) Has been cancelled
citra-libretro / windows (push) Has been cancelled
citra-libretro / macos (arm64) (push) Has been cancelled
citra-libretro / macos (x86_64) (push) Has been cancelled
citra-libretro / ios (push) Has been cancelled
citra-libretro / tvos (push) Has been cancelled
citra-transifex / transifex (push) Has been cancelled
qt Fix compilation issues in status LED code (#2045)
solves a build issue a ***lot*** of [L4T Megascript](https://github.com/cobalt2727/L4T-Megascript) users were reporting to me on Linux. C++ is definitely not my strong suit, but per https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/pow-powf-powl?view=msvc-170#remarks `pow` has identical behavior in C++ projects. no clue why `powf` worked fine on your environment when developing this but not other people's.

```cmake
[ 98%] Building CXX object src/citra_qt/CMakeFiles/citra_qt.dir/qt_image_interface.cpp.o
/home/runner/azahar/src/citra_qt/notification_led.cpp:56:15: error: no member named 'powf' in namespace 'std'; did you mean simply 'powf'?
   56 |     float t = std::powf(pwm, 1.f / gamma);
      |               ^~~~~~~~~
      |               powf
/usr/include/aarch64-linux-gnu/bits/mathcalls.h:140:1: note: 'powf' declared here
  140 | __MATHCALL_VEC (pow,, (_Mdouble_ __x, _Mdouble_ __y));
      | ^
/usr/include/math.h:280:3: note: expanded from macro '__MATHCALL_VEC'
  280 |   __MATHCALL (function, suffix, args)
      |   ^
/usr/include/math.h:287:3: note: expanded from macro '__MATHCALL'
  287 |   __MATHDECL (_Mdouble_,function,suffix, args)
      |   ^
/usr/include/math.h:289:3: note: expanded from macro '__MATHDECL'
  289 |   __MATHDECL_1(type, function,suffix, args); \
      |   ^
note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
/usr/include/math.h:297:15: note: expanded from macro '__MATHDECL_1_IMPL'
  297 |   extern type __MATH_PRECNAME(function,suffix) args __THROW
      |               ^
/usr/include/math.h:326:34: note: expanded from macro '__MATH_PRECNAME'
  326 | # define __MATH_PRECNAME(name,r) name##f##r
      |                                  ^
<scratch space>:97:1: note: expanded from here
   97 | powf
      | ^
1 error generated.
make[2]: *** [src/citra_qt/CMakeFiles/citra_qt.dir/build.make:1573: src/citra_qt/CMakeFiles/citra_qt.dir/notification_led.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/Makefile2:3481: src/citra_qt/CMakeFiles/citra_qt.dir/all] Error 2
make: *** [Makefile:166: all] Error 2
```
2026-04-16 09:53:08 +02:00

87 lines
2.4 KiB
C++

// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cmath>
#include <QPainter>
#include <QRadialGradient>
#include "citra_qt/notification_led.h"
LedWidget::LedWidget(QWidget* parent) : QWidget(parent), color(0, 0, 0) {
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}
QSize LedWidget::sizeHint() const {
return QSize(16, 16);
}
QSize LedWidget::minimumSizeHint() const {
return QSize(16, 16);
}
void LedWidget::setColor(const QColor& _color) {
if (color == _color)
return;
color = _color;
update();
}
QColor LedWidget::lerpColor(const QColor& a, const QColor& b, float t) {
t = std::clamp(t, 0.0f, 1.0f);
return QColor(int(a.red() + (b.red() - a.red()) * t),
int(a.green() + (b.green() - a.green()) * t),
int(a.blue() + (b.blue() - a.blue()) * t));
}
QColor LedWidget::blendLedColor(int r, int g, int b) const {
// Default "off" color
const QColor off_color(64, 64, 64);
// If completely off, just show gray and skip further calculations
if (r == 0 && g == 0 && b == 0)
return off_color;
// Normalize lit color so hue stays pure
int max_c = std::max({r, g, b});
QColor lit_color((r * 255) / max_c, (g * 255) / max_c, (b * 255) / max_c);
// Convert PWM duty to perceived brightness.
// This gives better results as LED RGB values
// are not linear.
constexpr float gamma = 2.4f;
float pwm = max_c / 255.0;
float t = std::pow(pwm, 1.f / gamma);
return lerpColor(off_color, lit_color, t * 0.8f);
}
void LedWidget::paintEvent(QPaintEvent*) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
QRectF rect = this->rect().adjusted(0, 2, 0, -2);
qreal size = std::min(rect.width(), rect.height());
QRectF circle((rect.center().x() - size / 2.f) - 2, rect.center().y() - size / 2.f, size, size);
QPointF center = circle.center();
qreal radius = circle.width() / 2.f;
QColor base = blendLedColor(color.red(), color.green(), color.blue());
QRadialGradient g(center, radius);
QColor inner = base.lighter(135);
QColor outer = base.darker(125);
g.setColorAt(0.f, inner);
g.setColorAt(0.7f, base);
g.setColorAt(1.f, outer);
p.setPen(Qt::NoPen);
p.setBrush(g);
p.drawEllipse(circle);
}