Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIRECTOR: Fixes for The Dark Eye #5404

Merged
merged 2 commits into from Nov 11, 2023
Merged

Conversation

moralrecordings
Copy link
Contributor

No description provided.

Previously, BITD bitmaps were pre-converted to match the ScummVM colour
depth. This caused issues in 32-bit mode; you are allowed to change the
palette of an 8-bit image at any time, so pre-converting all 8-bit
images to 32-bit leaves you frozen to whatever palette was in use when
the image was loaded.

The correct way to deal with this is to keep the original bitmap
pixel format, and perform the conversion at widget creation time.
@neuromancer
Copy link
Contributor

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Nov 10, 2023

Walkthrough

Walkthrough

The changes primarily focus on enhancing the handling of bitmap images in the Director engine. This includes modifications to the BitmapCastMember class for handling 1bpp and non-1bpp cases, and the addition of a new function for dithering indexed images. The BITDDecoder class has also been updated to handle pixel color conversion based on the pixel format. Additionally, a new Windows game "lingoexpo" has been added to the detection tables.

Changes

File(s) Summary
.../castmember/bitmap.cpp, .../castmember/bitmap.h Added a new function for dithering indexed images and modified the BitmapCastMember::createWidget function to handle 1bpp and non-1bpp cases.
.../director/detection_tables.h Added a new Windows game "lingoexpo" with corresponding checksum, size, and version.
.../director/graphics.cpp Added a comment emphasizing the need for surfaces passed to inkBlitSurface to match the format of the window manager for blit efficiency.
.../director/images.cpp, .../director/images.h Updated the BITDDecoder class to handle pixel color conversion based on the pixel format and removed the convertPixelIntoSurface function.

Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai help to get help.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

Comment on lines +216 to +217
// ScummVM using 8-bit video

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here is a bit confusing. It's not clear what "early directors" refers to. Consider revising for clarity.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOL

Comment on lines +263 to +352
Graphics::Surface *BitmapCastMember::getDitherImg() {
Graphics::Surface *dither = nullptr;

// Convert indexed image to indexed palette
Movie *movie = g_director->getCurrentMovie();
Cast *cast = movie->getCast();
Score *score = movie->getScore();
// Get the current score palette. Note that this is the ID of the palette in the list, not the cast member!
CastMemberID currentPaletteId = score->getCurrentPalette();
if (currentPaletteId.isNull())
currentPaletteId = cast->_defaultPalette;
PaletteV4 *currentPalette = g_director->getPalette(currentPaletteId);
if (!currentPalette) {
currentPaletteId = CastMemberID(kClutSystemMac, -1);
currentPalette = g_director->getPalette(currentPaletteId);
}
CastMemberID castPaletteId = _clut;
// It is possible for Director to have saved an invalid ID in _clut;
// if this is the case, do no dithering.
if (castPaletteId.isNull())
castPaletteId = currentPaletteId;

// Check if the palette is in the middle of a color fade event
bool isColorCycling = score->isPaletteColorCycling();

// First, check if the palettes are different
switch (_bitsPerPixel) {
// 1bpp - this is preconverted to 0x00 and 0xff, change nothing.
case 1:
break;
// 2bpp - convert to nearest using the standard 2-bit palette.
case 2:
{
const PaletteV4 &srcPal = g_director->getLoaded4Palette();
dither = _picture->_surface.convertTo(g_director->_wm->_pixelformat, srcPal.palette, srcPal.length, currentPalette->palette, currentPalette->length, Graphics::kDitherNaive);
}
break;
// 4bpp - if using a builtin palette, use one of the corresponding 4-bit ones.
case 4:
{
const auto pals = g_director->getLoaded16Palettes();
// in D4 you aren't allowed to use custom palettes for 4-bit images, so uh...
// I guess default to the mac palette?
CastMemberID palIndex = pals.contains(castPaletteId) ? castPaletteId : CastMemberID(kClutSystemMac, -1);
const PaletteV4 &srcPal = pals.getVal(palIndex);
dither = _picture->_surface.convertTo(g_director->_wm->_pixelformat, srcPal.palette, srcPal.length, currentPalette->palette, currentPalette->length, Graphics::kDitherNaive);
}
break;
// 8bpp - if using a different palette, and we're not doing a color cycling operation, convert using nearest colour matching
case 8:
// Only redither 8-bit images if we have the flag set, or it is external
if (!movie->_remapPalettesWhenNeeded && !_external)
break;
if (_external || (castPaletteId != currentPaletteId && !isColorCycling)) {
const auto pals = g_director->getLoadedPalettes();
CastMemberID palIndex = pals.contains(castPaletteId) ? castPaletteId : CastMemberID(kClutSystemMac, -1);
const PaletteV4 &srcPal = pals.getVal(palIndex);

// If it is an external image, use the included palette.
// For BMP images especially, they'll often have the right colors
// but in the wrong palette order.
const byte *palPtr = _external ? _picture->_palette : srcPal.palette;
int palLength = _external ? _picture->getPaletteSize() : srcPal.length;
dither = _picture->_surface.convertTo(g_director->_wm->_pixelformat, palPtr, palLength, currentPalette->palette, currentPalette->length, Graphics::kDitherNaive);
}
break;
default:
break;
}

if (dither) {
// Save the palette ID so we can check if a redraw is required
_ditheredTargetClut = currentPaletteId;

if (!_external) {
// Finally, the first and last colours in the palette are special. No matter what the palette remap
// does, we need to scrub those to be the same.
const Graphics::Surface *src = &_picture->_surface;
for (int y = 0; y < src->h; y++) {
for (int x = 0; x < src->w; x++) {
const int test = *(const byte *)src->getBasePtr(x, y);
if (test == 0 || test == (1 << _bitsPerPixel) - 1) {
*(byte *)dither->getBasePtr(x, y) = test == 0 ? 0x00 : 0xff;
}
}
}
}
}
return dither;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getDitherImg() function is quite long and complex. Consider breaking it down into smaller, more manageable functions. This will improve readability and maintainability.

@sev-
Copy link
Member

sev- commented Nov 11, 2023

Thank you!

@sev- sev- merged commit ccff1f8 into scummvm:master Nov 11, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants