Skip to content

Commit

Permalink
Go back to 16-bit for blitting with mask
Browse files Browse the repository at this point in the history
  • Loading branch information
andrews05 committed Oct 13, 2024
1 parent 3f79e16 commit 581bbb8
Showing 1 changed file with 43 additions and 25 deletions.
68 changes: 43 additions & 25 deletions src/blitters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern "C" {
Bitmap dBitmap(dest->raw.width, dest->raw.height, dest->raw.bytesPerRow, pixelFormat, dest->raw.buffer);
Graphics graphics(&dBitmap);
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality);
graphics.DrawImage(
source,
Rect(
Expand All @@ -53,13 +54,14 @@ extern "C" {
);
}

// SETDWORD(0x00575B58, _blit16); // 16 to 16 - existing implementation is fine here
SETDWORD(0x00575B60, _blit16); // 16 to 32
SETDWORD(0x00575BBC, _blit16); // 16 to 16 stretch
SETDWORD(0x00575BC4, _blit16); // 16 to 32 stretch
void blit16(NVBitmap *source, NVBitmap *dest, QDRect *srcRect, QDRect *destRect) {
// SETDWORD(0x00575B58, _blit16noAlpha); // 16 to 16 - existing implementation is fine here
SETDWORD(0x00575B60, _blit16noAlpha); // 16 to 32
SETDWORD(0x00575BBC, _blit16noAlpha); // 16 to 16 stretch
SETDWORD(0x00575BC4, _blit16noAlpha); // 16 to 32 stretch
void blit16(NVBitmap *source, NVBitmap *dest, QDRect *srcRect, QDRect *destRect, bool alpha) {
startupGdiplus();

PixelFormat pixelFormat = alpha ? PixelFormat16bppARGB1555 : PixelFormat16bppRGB555;
int stride = source->raw.bytesPerRow;
if (stride % 4) {
// Stride must be a multiple of 4 but the source isn't.
Expand All @@ -73,13 +75,16 @@ extern "C" {
output += stride;
input += source->raw.bytesPerRow;
}
Bitmap sBitmap(source->raw.width, source->raw.height, stride, PixelFormat16bppRGB555, buffer);
Bitmap sBitmap(source->raw.width, source->raw.height, stride, pixelFormat, buffer);
blit(&sBitmap, dest, srcRect, destRect);
} else {
Bitmap sBitmap(source->raw.width, source->raw.height, stride, PixelFormat16bppRGB555, source->raw.buffer);
Bitmap sBitmap(source->raw.width, source->raw.height, stride, pixelFormat, source->raw.buffer);
blit(&sBitmap, dest, srcRect, destRect);
}
}
void blit16noAlpha(NVBitmap *source, NVBitmap *dest, QDRect *srcRect, QDRect *destRect) {
blit16(source, dest, srcRect, destRect, false);
}

SETDWORD(0x00575B6C, _blit24); // 24 to 16
SETDWORD(0x00575B74, _blit24); // 24 to 32
Expand Down Expand Up @@ -121,30 +126,43 @@ extern "C" {
blit(&sBitmap, dest, srcRect, destRect);
}

// Set button construction bitmaps to 32-bit to make masking easier
SETINST(0x004A3111, "PUSH 32"); // Button parts
CLEAR_NOP(0x004A3111 + 2, 0x004A3111 + 8);
SETINST(0x004A312D, "PUSH 32"); // Button masks

SETDWORD(0x00575D10, _blit32withMask); // 32 to 16
SETDWORD(0x00575D18, _blit32withMask); // 32 to 32
SETDWORD(0x00575D74, _blit32withMask); // 32 to 16 stretch
SETDWORD(0x00575D7C, _blit32withMask); // 32 to 32 stretch
void blit32withMask(NVBitmap *source, NVBitmap *mask, NVBitmap *dest, QDRect *srcRect, QDRect *maskRect, QDRect *destRect) {
startupGdiplus();

// SETDWORD(0x00575CE8, _blit16withMask); // 16 to 16 - existing implementation is fine here
SETDWORD(0x00575CF0, _blit16withMask); // 16 to 32
SETDWORD(0x00575D4C, _blit16withMask); // 16 to 16 stretch
SETDWORD(0x00575D54, _blit16withMask); // 16 to 32 stretch
void blit16withMask(NVBitmap *source, NVBitmap *mask, NVBitmap *dest, QDRect *srcRect, QDRect *maskRect, QDRect *destRect) {
for (int y = 0; y < source->raw.height; y++) {
for (int x = 0; x < source->raw.width; x++) {
int sourceIndex = y * source->raw.bytesPerRow + x * 4;
int maskIndex = y * mask->raw.bytesPerRow + x * 4;
// Use the first channel of the mask as the alpha channel of the source
source->raw.buffer[sourceIndex + 3] = ~mask->raw.buffer[maskIndex];
int sourceIndex = y * source->raw.bytesPerRow + x * 2;
int maskIndex = y * mask->raw.bytesPerRow + x * 2;
// When mask is black, set the high bit to make the pixel opaque
if (mask->raw.buffer[maskIndex] == 0) {
source->raw.buffer[sourceIndex + 1] |= 0x80;
}
}
}
Bitmap sBitmap(source->raw.width, source->raw.height, source->raw.bytesPerRow, PixelFormat32bppARGB, source->raw.buffer);
blit(&sBitmap, dest, srcRect, destRect);
blit16(source, dest, srcRect, destRect, true);
}

// SETDWORD(0x00575D10, _blit32withMask); // 32 to 16
// SETDWORD(0x00575D18, _blit32withMask); // 32 to 32
// SETDWORD(0x00575D74, _blit32withMask); // 32 to 16 stretch
// SETDWORD(0x00575D7C, _blit32withMask); // 32 to 32 stretch
// void blit32withMask(NVBitmap *source, NVBitmap *mask, NVBitmap *dest, QDRect *srcRect, QDRect *maskRect, QDRect *destRect) {
// startupGdiplus();

// for (int y = 0; y < source->raw.height; y++) {
// for (int x = 0; x < source->raw.width; x++) {
// int sourceIndex = y * source->raw.bytesPerRow + x * 4;
// int maskIndex = y * mask->raw.bytesPerRow + x * 4;
// // Use the first channel of the mask as the alpha channel of the source
// source->raw.buffer[sourceIndex + 3] = ~mask->raw.buffer[maskIndex];
// }
// }
// Bitmap sBitmap(source->raw.width, source->raw.height, source->raw.bytesPerRow, PixelFormat32bppARGB, source->raw.buffer);
// blit(&sBitmap, dest, srcRect, destRect);
// }

// Disable brightness adjustment when loading picts.
// This prevents a forced loss of bits which would preclude dithering of 24-bit sources.
SETBYTE(0x004B9050 + 1, 0);
Expand Down

0 comments on commit 581bbb8

Please sign in to comment.