nice dithering

This commit is contained in:
2025-10-09 23:41:51 +02:00
parent c3295b9b01
commit 54d5f85538

View File

@@ -542,10 +542,11 @@ private:
const uint8_t* romDataView = nullptr;
std::size_t romDataViewSize = 0;
std::vector<uint8_t> cartRam;
bool frameDirty = false;
uint32_t fpsLastSampleMs = 0;
uint32_t fpsFrameCounter = 0;
uint32_t fpsCurrent = 0;
bool frameDirty = false;
uint32_t fpsLastSampleMs = 0;
uint32_t fpsFrameCounter = 0;
uint32_t totalFrameCounter = 0;
uint32_t fpsCurrent = 0;
std::string activeRomName;
std::string activeRomSavePath;
@@ -1042,6 +1043,7 @@ private:
ensureRenderGeometry();
++fpsFrameCounter;
++totalFrameCounter;
const uint32_t nowMs = context.clock.millis();
if (fpsLastSampleMs == 0)
fpsLastSampleMs = nowMs;
@@ -1223,6 +1225,19 @@ private:
return static_cast<GameboyApp*>(gb->direct.priv);
}
static bool shouldPixelBeOn(int value, int dstX, int dstY, bool useDither) {
value &= 0x03;
if (!useDither)
return value >= 2;
if (value >= 3)
return true;
if (value <= 0)
return false;
constexpr uint8_t pattern[2][2] = {{0, 2}, {3, 1}};
const uint8_t threshold = pattern[dstY & 0x01][dstX & 0x01];
return value > threshold;
}
static uint8_t romRead(struct gb_s* gb, const uint_fast32_t addr) {
auto* self = fromGb(gb);
if (!self)
@@ -1291,11 +1306,15 @@ private:
DispTools::draw_to_display_async_wait();
GB_PERF_ONLY(self->perf.waitUs = esp_timer_get_time() - waitStartUs;)
const bool useDither = (self->scaleMode == ScaleMode::FullHeight) &&
(geom.scaledWidth != LCD_WIDTH || geom.scaledHeight != LCD_HEIGHT);
if (geom.scaledWidth == LCD_WIDTH && geom.scaledHeight == LCD_HEIGHT) {
const int dstY = yStart;
const int dstXBase = geom.offsetX;
for (int x = 0; x < LCD_WIDTH; ++x) {
const bool on = (pixels[x] & 0x03u) >= 2;
const int val = (pixels[x] & 0x03u);
const bool on = shouldPixelBeOn(val, dstXBase + x, dstY, useDither);
fb.drawPixel(dstXBase + x, dstY, on);
}
return;
@@ -1308,10 +1327,11 @@ private:
const int drawEnd = colEnd[x];
if (drawStart >= drawEnd)
continue;
const bool on = (pixels[x] & 0x03u) >= 2;
for (int dstY = yStart; dstY < yEnd; ++dstY)
for (int dstX = drawStart; dstX < drawEnd; ++dstX)
for (int dstX = drawStart; dstX < drawEnd; ++dstX) {
const bool on = shouldPixelBeOn(pixels[x], dstX, dstY, useDither);
fb.drawPixel(dstX, dstY, on);
}
}
}