[Scummvm-tracker] [ScummVM] #9857: SCI: GK2: Character Graphic Glitches in Opera basement

Colin Snover trac at scummvm.org
Mon Jun 26 07:20:27 CEST 2017


#9857: SCI: GK2: Character Graphic Glitches in Opera basement
-------------------------------+-------------------------
  Reporter:  dafioram          |      Owner:  csnover
      Type:  defect            |     Status:  new
  Priority:  low               |  Component:  Engine: SCI
Resolution:                    |   Keywords:  sci32
      Game:  Gabriel Knight 2  |
-------------------------------+-------------------------

Comment (by csnover):

 So, here is a write-up of things so far:

 SCI engine uses versioning to manage palette updates. This is generally an
 optimisation to avoid unnecessary palette updates when a palette has
 already been merged into the main (source) palette.

 There are two ways that palettes make it into GfxPalette32. The first way
 is by an explicit call by a game script to `kPalette` to load a specific
 palette resource. The second way is implicit: during rendering, when a
 screen item ends up in the draw list, its cel’s baked-in palette is
 submitted by `GfxFrameout::frameOut` or `palMorphFrameOut` to the palette
 manager.

 In both cases, the palette data contains a version field that is updated
 by GfxPalette32 to record the last version that the given palette was
 submitted. If the current version in GfxPalette32 is the same as the
 version in the palette data, the palette manager skips applying the
 palette.

 If the version in the palette data does ''not'' match the version of
 GfxPalette32, the palette is merged into the source palette, and if this
 causes a change to the colours in the source palette, the
 `GfxPalette32::_needsUpdate` flag is set, and the GfxPalette32 version is
 incremented. Once the `_needsUpdate` flag is set, all palettes with a
 different version are merged, but the GfxPalette32 version is not updated
 again until the `_needsUpdate` flag is cleared (by a call to
 `GfxPalette32::updateForFrame` or `updateFFrame`).

 What seems to be happening here is complicated and seems to revolve around
 explicit calls to submit palette 252.

 When loading the attached save 86 and walking up the stairs, the order of
 operation is:

 * The game plays the VMD of walking up the stairs. This submits palettes
 for the VMD + view 126 (the background for the bar at the top of the
 screen with the room name & score), and both are applied successfully.
 (version is now 6)
 * After the VMD ends, palette 252 is submitted by a game script, and is
 also applied successfully. (version is now 7)
 * The game plays the VMD of the man talking about the show starting. This
 submits palettes for the VMD + view 126, again applied successfully, but
 version remains 7 because nothing has cleared the `_needsUpdate` flag.
 * After the VMD, palette 252 is submitted again, but since GfxPalette32
 says we are still at version 7, it is not applied. This breaks Grace's
 palette, which comes from palette 252.

 If we mess with GfxPalette32 by calling `updateForFrame` to clear the
 `_needsUpdate` flag before calling `frameOut` in `VMDPlayer::renderFrame`,
 when `frameOut` submits all the draw list palettes, this will
 coincidentally trigger a version update when view 126’s palette is
 submitted, and then when palette 252 is submitted again later, it will be
 updated to the new version. But this seems to rely entirely on the
 coincidence that there is a cel waiting to render when `frameOut` is
 called that causes a change to the colours in the source palette.

 I am not sure yet what is the correct way to ensure this all works
 properly. It is possible that SSCI relied on this coincidental situation
 with the draw list but I am still looking to figure it out. I have tried
 changing the ScummVM implementation to put the palette from the VMD
 decoder into the SciBitmap that is used to render the video (so it is
 processed by the call to `submitPalette` in `frameOut`, instead of being
 submitted directly), but this does not seem to change the situation when
 it comes times to resubmit palette 252.

 As I write this description, I realise that it does, however, seem to
 provide a basis for guaranteeing that at least one palette will be
 submitted through the draw list to cause a version update: the VMD’s own
 screen item. So it may actually just be the case that the implementation
 has to be updated to do this, but also with a call to `updateForFrame`
 before `frameOut` in `VMDPlayer::renderFrame` so that the VMD’s palette
 update does not get batched up with any earlier set of palette changes.

--
Ticket URL: <https://bugs.scummvm.org/ticket/9857#comment:3>
ScummVM <https://bugs.scummvm.org>
ScummVM


More information about the Scummvm-tracker mailing list