[Scummvm-git-logs] scummvm master -> 9903913859120b0d0595ad82a093b87fc6e400d5

sev- sev at scummvm.org
Sun Mar 21 23:16:26 UTC 2021


This automated email contains information about 396 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
f00ee606d3 ENGINES: Add stub Buried in Time engine
4cbcd29a94 COMMON: Fix out-of-bounds write in SZDD EXE decompression
c3c188f4b6 COMMON: Add an NE version resource parser
639a1e0120 COMMON: Add a function to read NE strings
5f86d48b42 BURIED: Begin adding the windowing/messaging system
51cb5d1672 BURIED: Add some more functions for detection
dd36ffea1f BURIED: Add a wrapper around the EXE parser
a16c3ae442 BURIED: Begin loading from the EXE/DLL
db090027b6 BURIED: Begin to load the Arial font
8c130031eb BURIED: Initiate the graphics system
2e534155ee BURIED: Add a function to read file paths from strings
0c925bb641 BURIED: Move all graphics stuff to its own class
06a1bcc9ee BURIED: Add support for the cursors
ccabf0621c IMAGE: Add support for headerless bitmaps
2874046e52 BURIED: Add the sound manager code
faca37064b AUDIO: Mark the wave code as being used by buried
27b938d47f BURIED: Add the CP-1252 charset mapping
3c158972b3 GRAPHICS: Add the Windows busy cursor
9b21d8e83d BURIED: Allow using the Windows busy cursor
e51ef54d6d BURIED: Add a wrapper method to get an EXE string
7bff632e1c BURIED: Add some more GraphicsManager functions
d5b6f36676 IMAGE: Mark BitmapDecoder as being used by buried
0e9ba8f256 BURIED: Add the GlobalFlags table
c7bcfed6a7 BURIED: Add navigation data structs
c2d9988b2c BURIED: Add a bunch of resource data structs/constants
6f9178dcd0 BURIED: Add wrappers for retrieving buried-specific data
e97c2f47a8 BURIED: Update the Window code a bit
33444e800d BURIED: Implement window enabling
8773a54785 BURIED: Add simple blit function
657b35f04c BURIED: Make some private Window members protected
75ddf08271 BURIED: Add first stab at the LiveText window
c7c2077f76 BURIED: Actually use the palette now in non-truecolor mode
48f1fae34e BURIED: Add uncompressed detection
5e25d91bd6 BURIED: Fix white palette entry setting
a30f0d6bbc BURIED: Add color matching for paletted mode
6f2eb23ff8 BURIED: Remove unneeded OnQueryNewPalette window stuff
b77e31af10 BURIED: Add the new AVI frames cache system
fe7a58df3c BURIED: Make sure AVI frames are converted to the screen format
77b996462e BURIED: Add a wrapper to invalidate a whole window
b3419fadc3 BURIED: Add window class for videos
e9bc4bc1c0 BURIED: Add way to initialize a Window with a parent in the constructor
b9e1ddfbd7 BURIED: Add a function to decode a bitmap from a file
ae488a3e0b BURIED: Also add parent parameter to videos
eb3f5a20c9 BURIED: Add some basic Timer code
a2c4bd3204 BURIED: Hook up video windows into the engine
d4ee5b07f1 BURIED: Ensure videos are in the correct format
de5d0b4350 BURIED: Make the video window resize to the video size
9db1bff262 BURIED: Have windows maintain order and position
fdf7982f32 BURIED: Add wrapper to fill a rect on the screen
4e630357a7 BURIED: Make dispatchAllMessages also dispatch the children's messages
470879c98b BURIED: Add the title sequence window
229db8dd21 BURIED: Show the title sequence in the full game
bb7bd2ff4e BURIED: Add basic keyboard input support
bd1d0d7796 BURIED: Add initial mouse support
ca54be6b1f BURIED: Switch to a single message queue
a3d4eb646b BURIED: Use the extra as a hint for detection
27a64d7d8e BURIED: Fix freeing of sound streams when looping
890b2620d5 BURIED: Make sure surfaces are converted upon loading
070a58fef7 BURIED: Add the main menu
c53ee0b6bf BURIED: Add the overview sequence
d1ab45529a BURIED: Add a more advanced blit function
f48978e88c BURIED: Make sure 8bpp images are using the right palette
343f8afbee BURIED: Add the credits window
bdf5c27b10 BURIED: Some updates to the messaging system to allow for inner loops
3a69ae8033 BURIED: Strip "BITDATA" from demo file names
a4cb03264e BURIED: Add the demo main menu
54254d997a BURIED: Default to empty string on setAmbientSound
595503890b BURIED: Add the frame window class
a2db33cf92 BURIED: Make sure we invalidate the focused window if we delete that window
535d29a869 BURIED: Hook up the main menus to the frame window and related windows
a08d14bcca BURIED: Make sure the main window gets deleted before everything else
83ea799cac BURIED: Fix semi-broken dirty rectangles
afecd69ec2 BURIED: Ensure a window's rect is invalidated upon deletion
34f50804ba BURIED: Add the demo trailer movies
2e335fd740 BURIED: Add the demo features screens
558736180c BURIED: Allow for updating the screen without updating the main window
f9273c13f5 BURIED: Implement the demo title sequence
f0cb54504b BURIED: Fix some memory leaks
4d104c12e2 COMMON: Fix some memory leaks
c2de52df05 BURIED: Make mouse messages relative to the window
da2d275859 BURIED: Fix resource struct types
406bbb19cf BURIED: Children get pushed to the bottom of the z-order on creation
e4560d5291 BURIED: Invalidate the rect on a window that changes visibility
4b5960b4b7 BURIED: Allow for creating a font for Arial Bold too
4ea076bde0 BURIED: Fix erase background behavior
3c13de6ee1 BURIED: Fix some visiblility issues
55c470ad10 BURIED: Begin adding the UI code
a07fed3493 BURIED: Implement set cursor messages
d830e849c1 BURIED: Some minor video fixes
4da91fb632 BURIED: Add the right BioChip display window
f9cd1b65ff BURIED: Add some transparency functions
5a8260815c BURIED: Add the navigation arrows window
bf3ba824c4 BURIED: Add the biochip view window
a49e249813 BURIED: Add some functions to get/set the transition speed
43e49fd1c1 BURIED: Add the interface biochip window
6058158772 BURIED: Add the files biochip window
cc3d4b18aa BURIED: Remove unneeded double-click message
13f48076bf BURIED: Fix font sizes
76f5c3d2f5 COMMON: Add a wrapper to read PE strings
6b72a97670 BURIED: Add support for the Win95 binaries
7d19e450bb BURIED: Hook the demo into the interface
78c866efec BURIED: Add inventory window
04328b98fd BURIED: Font-related cleanup
d86096574b BURIED: Add a wrapper for drawing multi-line text
7487adfd93 BURIED: Add the death screens
10ac40bda0 BURIED: Add support for setting capture mode on a window
7924396125 BURIED: Add the completion window
4726a69d49 BURIED: Default to arrow cursors in onSetCursor()
0853ba7ac6 BURIED: Make setWindowPos take a const pointer for the insertion point
31acc825bf BURIED: Add some more resource values
7d0ad60ba9 BURIED: Add missing live text code
09827199da BURIED: Fix a typo
2d38b79e0f BURIED: Hook death/completion windows into FrameWindow
503645f379 BURIED: Add a method of querying the EXE version
579d6540cc BURIED: Add death/completion window scoring strings
4bba4a34b3 BURIED: Fixed global flags for the louvre research flag
a966f157af BURIED: Add detection for the Japanese version
1aebefdebb BURIED: Update Japanese font code
9f12e36917 BURIED: Add detection for the German v1.05 version
9c0da1c36b BURIED: Add the scene view class
b460830309 BURIED: Add the old apartment scene
16a1a67a20 BURIED: Fix drawing the scene view window
201495903f BURIED: Allow the game to go beyond the second part of the intro
ea4b3c6a2d BURIED: Fix some uninitialized variables
fde36a0d77 BURIED: Fix up live text redrawing
8866f3b1ca BURIED: Don't draw the date or warning light in the demo
773f42174d BURIED: Fix the demo's interface biochip view images
9f759260f6 BURIED: Fix destroying the biochip view window
33add4b517 BURIED: Fix checking for a transparent point
6aa06fd538 BURIED: Add sanity check on constructSceneObject return value
c8b3013d24 BURIED: Add a basic debugger
d2505042db BURIED: Actually turn on the walk movie
946b7c8f5f BURIED: Begin initializing the castle time zone
b12cd67b6b BURIED: Don't forget to set _tempFrame to 0
0a1e694ef2 BURIED: Treat hidden windows as disabled
d809429d9a BURIED: Add the basic door class
9114b2025f BURIED: Add a stub for the future apartment
817a6ac6de BURIED: Fix sound volume clipping
6b87aee941 COMMON: Ensure stddef.h is included in scummsys.h
ad39786203 BURIED: Add the future apartment stingers
aaa3274b45 BURIED: Fix the demo transition slider
23da2a6761 BURIED: Add one shot videos
b96691c27a BURIED: Fill in other castle doors
22989c40a5 BURIED: Add the two sentry castle video
60b8942e75 BURIED: Implement toy shelf zooming
5171e5022f BURIED: Add the future apartment figurines
18df139af3 BURIED: Add the ClickPlayVideo scene base
518f292aba BURIED: Add the TurnDepthPreChange scene base
47a464b6b6 BURIED: Implement entering/exiting the environ room
abd3a671da BURIED: Fix capturing windows
751ce57bd4 BURIED: Implement item dragging
cc4fd1abe2 BURIED: Add the GenericAcquireItem scene base
21f2d33cd9 BURIED: Fix double-free on the drag icon image
6d8fed8dd7 BURIED: Implement the keep climb
345b8924f7 BURIED: Fix the inventory info screen file name in the demo
3479260449 BURIED: Fix demo inventory info timings
9d81867146 BURIED: Fix destroy order for the inventory window
2d04529ec9 BURIED: Implement the time jump menu
73be4ce2e8 BURIED: Add stub for the AI lab
4a2d15aacd BURIED: Add ambient sounds to the castle time zone
2affb8163b BURIED: Add stub for mayan
cade2e076f BURIED: Add a Da Vinci stub
109212e2dc BURIED: Add a bunch of Da Vinci scenes
911ac215fa BURIED: Fix navigation arrows after decloaking
89f903d301 BURIED: Implement the castle exploding wall
43b63cca28 BURIED: Implement the king's chamber guards encounter
49bd829ec1 BURIED: Fix frame cycling
85ce38ceed BURIED: Fix drop inventory item icons
c34d32e468 BURIED: Fix arrow status check when clicking
db0d4be62a BURIED: Fix sound fading
e825892922 BURIED: Fix the warning light
7d5dc1877c BURIED: Implement the remaining two parts of the initial castle tower
cafba7cd6b BURIED: Implement some common Mayan scenes
428295621b BURIED: Implement the painting tower door
dd0e6469db BURIED: Fix adding evidence to the global flag table
3bc843f72e BURIED: Implement the Agent 3 evidence in Da Vinci
9d0e6550f9 BURIED: Implement the castle storage room door
234e3f67f3 BURIED: Implement placing the ceramic bowl
8668c6287b BURIED: Fix missing Mayan ambient fade
4a1f123f48 BURIED: Add the sound exiting from scene common scene
c2e9401da0 BURIED: Implement the ClickPlaySound common scene
5df033e4b9 BURIED: Add the castle wall slide death
dab0e11433 BURIED: Implement the background catapult sounds
af847ff0d0 BURIED: Fix async video behavior
9c3c87564d BURIED: Allow for right-aligned text
853f9a8e96 BURIED: Implement the kitchen unit
50e0db86f3 BURIED: Begin implementing the AI lab
6c81ce5589 BURIED: Make the synchronous sound functions use yield()
7b487f22eb BURIED: Implement the basic space door
cb5ff6cc7b BURIED: Fix the scene view OnSetCursor implementation
dae2d4d6cb BURIED: Implement the habitat wing locked doors
020989eefe BURIED: Improve the text positioning a bit
09c1f91c42 BURIED: Be sure to take a copy of the global flags when dying
894c488341 BURIED: Implement the arthur scary voices
88abb972ef BURIED: Start implementing the painting tower elevator
961a93ba80 BURIED: Fix evidence locate cursor logic
c1f9f93b9b BURIED: Implement the Da Vinci footprint evidence
a3f2bef3f3 BURIED: Implement the evidence review screen
aceeeb9a9c BURIED: Implement a bunch of Mayan translation stuff
882c7597a7 BURIED: Implement the Mayan calendar puzzle
e593a6a3bb BURIED: Implement basic save/load support through the GMM
912c673e34 BURIED: Implement the smithy bench
01afc91cf4 BURIED: Implement some more common scenes
89a6bd8000 BURIED: Implement the ClickChangeScene base scene
2175070672 BURIED: Implement ClickPlayVideoSwitch scene base
6a9a93b260 BURIED: Implement the king's study guard
588b4ccba9 BURIED: Add remaining king's study specific scenes
b883626caa BURIED: Implement browsing books
0732557f6f BURIED: Implement opening the castle storage room chest
f0c37500a4 BURIED: Fix some invalid reads with the storage room door
38ed1a93cf BURIED: Add the PlaySoundEnteringFromScene common scene
b79655ab1c BURIED: Don't reset the environment upon loading a saved game
1d14a528f9 BURIED: Implement scenes for the first node of the castle hidden room
d7e045a7ee BURIED: Implement the ClickZoom scene base
2528ab9fd8 BURIED: Implement the sword evidence
be3f65324c BURIED: Implement the painting tower elevator
b6ee7ca56f BURIED: Implement the capacitance array to habitat door
225f45da15 BURIED: Implement the capacitance array scenes
03b2be8c14 BURIED: Stop ambient sounds when playing synchronous animations with audio
4d4f7ad8f6 BURIED: Implement the docking bay
cbf96064b6 BURIED: Implement the scanner room
ceb175329f BURIED: Implement the AI Nexus puzzle
f986fc85fe BURIED: Fix Arthur's commenting
57ddbd0890 BURIED: Implement the Iceteroid door
b1d44240b2 BURIED: Implement the Iceteroid pods
f4a8254087 BURIED: Implement the Iceteroid elevator
5e146eaffb BURIED: Implement the science wing stingers
b6f398a922 BURIED: Implement picking up the water canister
283913da63 BURIED: Implement the iceteroid mining controls
2b1a427212 BURIED: Implement the iceteroid dispenser
9ce7c71303 BURIED: Implement the PlaySoundExitingForward scene
d09e01aace BURIED: Implement the science wing panel
f6ec605697 BURIED: Fix dying while in a timer
f024f5631e BURIED: Implement entering the biomass processing room
6528929f8e BURIED: Implement the biomass processing room
35bcf1d216 BURIED: Implement Chateau Gaillard custom AI dependencies
00ef60aa1f BURIED: Implement Farnstein Lab custom AI comment dependencies
85fa17a732 BURIED: Implement the Da Vinci AI comment dependencies
67a38919a3 BURIED: Add the Future Apartment AI comment dependency
5f3160c984 BURIED: Implement picking up the wheel assembly
74aff808a4 BURIED: Implement assembling the siege cycle
456c08003c BURIED: Implement some courtyard and workshop random scenes
7c86219b99 BURIED: Fix keyboard focus
f11771b2e6 BURIED: Fix backspace in shop net
c80c5590c6 BURIED: Fix drag sprites in 8bpp
f95d9be8a1 BURIED: Implement turning the ballista
5a4a5bcf5e BURIED: Implement clipping animations
3081fd6d01 BURIED: Implement firing the ballista
377c4c8664 BURIED: Implement placing the siege cycle
daa42fea2d BURIED: Implement getting into the codex tower
0fe51571db BURIED: Implement the lens filter evidence
0e148ce14a BURIED: Implement a couple random codex tower scenes
be0204f26e BURIED: Fix bad reads when going through AI comments
6ac35b1c34 BURIED: Implement pauseEngineIntern()
d8226496e0 BURIED: Prevent saving during a synchronous sequence
d37f680e0f BURIED: Implement picking up the preserved heart
c2cce6687d BURIED: Implement the codex tower elevator controls
f8e573c43c BURIED: Implement the codexes
0a3b06d996 BURIED: Make sure syncSoundSettings() is called from run()
384d8f2c95 BURIED: Add some commands to add/remove inventory items
661738d36f BURIED: Implement the oven door
0478b7778a BURIED: Implement some custom videos with AI comments
f3e92d1333 BURIED: Implement changing the background based on whether the remote is there
358c706fce BURIED: Implement the apartment bookshelf
80567b391f BURIED: Don't clear the video rect when closing a video
8bbfe49d8e BURIED: Implement the apartment desk
ae5de7b230 BURIED: Implement the coffee table area scenes
13a5d36632 BURIED: Implement the cavern door views
22440cf87d BURIED: Implement the glass pyramid evidence
d4df81743a BURIED: Implement some parts of the environ system
ca9fedb6c1 BURIED: Add base for Agent 3's lair
b81a6c949a BURIED: Implement the Agent 3 lair entry scene
a3dc50a6a2 BURIED: Fix jump biochip display
13fb5c21d4 BURIED: Implement the cavern offering heads
debf417c4e BURIED: Implement the WalkVolumeChange scene
b547647234 BURIED: Implement the Mayan AI comment dependencies
f55d5b3e2f BURIED: Add the SetVolumeAndFlag scene base
bb3623cbca BURIED: Implement the wealth god puzzle
c4ea3070b0 BURIED: Make sure the async movie is deleted
f507a66533 BURIED: Implement the water god puzzle
27c82b7174 BURIED: Fix some gcc warnings when compiling with optimization
902a9f6dc3 BURIED: Implement the arrow god heads
423c702c9b BURIED: Implement the spear room puzzle
069b6d7b10 BURIED: Implement the death god door
ed0e8368f5 BURIED: Implement the death god altar
071d870a9e BURIED: Implement the Mayan puzzle box... puzzle
4f563aff73 BURIED: Fix frame cycling in the Agent 3 lair entry segment
270b776887 BURIED: Implement replacing the generator core
7879a8c810 BURIED: Implement the replicator
a2c2042a12 BURIED: Implement the environ system nature scenes
2333f6f12c BURIED: Implement Geno's music video
2d0d6e8227 BURIED: Implement the interactive news network
b7e30acb63 BURIED: Implement INN for Agent 3's lair
d8feab64f4 BURIED: Implement the Agent 3 transporter
8887e2dc03 BURIED: Add the alien time zone
e66faa92b8 BURIED: Implement the alien transporter
8153960b2b BURIED: Implement entering the alien ship without the lens filter
5bcf46ce9e BURIED: Implement the transport pod descriptions
3ad17ea057 BURIED: Implement the inorganic matter transporters
131ca518df BURIED: Implement the arm controls
329513c37a BURIED: Implement alien door A
ecfc52c7bb BURIED: Implement alien door B
3513bb1a64 BURIED: Implement krynn ship nerve movement
5ad6ad3a42 BURIED: Implement the alien artifact pods
cbeba842f1 BURIED: Implement the first part of the final sequence
46bbc3d63a BURIED: Implement the final sequence
e9ec786111 BURIED: Fix missing puzzle score flag
05ee6ecf06 BURIED: Implement internal load/save dialog boxes
3273594eac BURIED: Implement returning to the main menu
4687e061ca BURIED: Remove some obsolete TODOs
80db452ed4 BURIED: Have the frame window keep focus instead of one of its child windows
8de136a125 BURIED: Implement escape-to-quit
e9542e6e67 BURIED: Use runLoadDialog/runSaveDialog instead of the old save/load code
948a6a55ae BURIED: Implement control down
43ea41678b BURIED: Implement the pause button
9739542b73 CREDITS: Add credits for buried
bdd386f883 BURIED: Implement switching video audio tracks
13e09b1e73 BURIED: Add support for the ms core fonts path for arial
eb30d39e9a BURIED: Silence some gcc warnings
97692662f4 BURIED: Fix death god door open animation
1fe81654a7 BURIED: Properly clip rects to their parent's rect
b8f51e9f2f BURIED: Implement continue game from the death screen
542b8e6b10 BURIED: Fix demo ambient when returning to the courtyard
385948933c BURIED: Fix onSetCursor behavior
360c7b2293 BURIED: Fix the demo door open/close sound
91e21dd39e BURIED: Stop sending messages if we're quitting
3eaa2774bb BURIED: Ensure timers get removed upon window destruction
73ea211632 BURIED: Start fixing the burned letter
52180e87bc BURIED: Fix push transitions
3fdd4080d3 BURIED: Fix the burned letter transition
8f82da6e07 BURIED: Make the burned letter not use the scene background
810f006e9a BURIED: Use separate pause sound functions for pausing the game
85d64a510f BURIED: Fix TurnDepthPreChange
5583f97ebd BURIED: Clean up searching for fonts
facf690f29 BURIED: Add TODO for MS Gothic bold
f1ff0f59cf BURIED: Fix size of the font used by the Japanese inventory
18db1475a3 BURIED: Force the monochrome version of MS Gothic since we need the bitmaps
75760fa054 BURIED: Use the render text function for the inventory window
7e57ba728e BURIED: Add support for displaying Japanese text
4270ea8fdd BURIED: Fix the date not showing in the intro
8ff163af29 BURIED: Don't bother loading the drag frame video in the full version
98ef56ed53 BURIED: Fix guard not being shot by the arrow when jumping from castle to castle
1cc30236a5 BURIED: Add detection for the French version
be2de373ae BURIED: Add detection for the trial version
e05089621a BURIED: Push the default scene view down to each environ
18a7b010be BURIED: Implement the trial version's auto-recall
57920ae92d BURIED: Display a message when trying to load non-apartment saves in the trial
0d04d75a3c BURIED: Add support for the Italian version
c1c5ba7bb4 BURIED: Switch to timer messages generated on-the-fly
d3f68fe216 BURIED: Squash timers down to one if multiple are set to fire
67333fcc06 BURIED: Fix the wait cursor not appearing in synchronous scene movies
e484ec4f5d BURIED: Use a ScopedPtr for temporary VideoWindows
14d9738021 BURIED: Use an RAII class to handle temporary cursor changes
85ae8a95ca BURIED: Use TempCursorChange in a few more places
ceb1e3c359 BURIED: Add debug location utilities to the console
7574c843a0 BURIED: Fix re-enabling cycling
ef983ee568 BURIED: Fix the lair scene affecting the flicker option
564598c0f5 BURIED: Force frame cycling to be enabled for the two knight scenes as well
936cdc998a BURIED: Add the path required by the Trilogy release
615247b5f8 BURIED: Add support for the Spanish version
45ff8fb04e BURIED: Moved detection table to a separate file
b44bc8fdb4 BURIED: Fixes gor modern API
8e660ca581 BURIED: More API fixes
3784b21a0c BURIED: Fix warning
88e5b10e33 BURIED: Fix overridden method
7725f0ceed COMMON: Make WinResource::getVersionInfo more universal
c529636463 BURIED: Converted detection.cpp to the new plugin structure
4ad07cd5f4 BURIED: Removed hacky loading of the system font and switch fallback to Liberation
279acfd6bc BURIED: Fix metaengine.cpp compilation
1af920e3cf BURIED: Use conventional methods of SaveLoadChooser instead of direct calls
26fe61bfb8 BURIED: Re-add accidentally removed method
622528796d BURIED: Added support for GOG.com release
7c47e67c49 GUI: Added VL Gothic regular font to fonts.dat
2c9cce70b2 BURIED: Simplified font handling and added reliable font fallbacks
6dbb8d9134 BURIED: Added detection entries for 1.04 release
97a2408677 CREDITS: Fix file after merge
5dfb0c592c COMMON: Remove duplicate include
6e49bfd0ae BURIED: Fix warnings
077fe677a5 BURIED: Fix warnings
7fac27c728 BURIED: Fix some CppCheck warnings
6e7e2f8be9 BURIED: Remove some useless includes
1a0b3ce309 BURIED: Add some missing 'override' keywords
0b49d9d43d BURIED: Review includes
d9d0205aff BURIED: Remove or reword passive-aggressive or insulting comments
5f3f279f77 BURIED: Added POTFILES
5c7cc7aee8 BURIED: Remove accidentally removed commented out unused class variable
d1373e8691 BURIED: Use more consistently SIC_REJECT in inventory item related functions
e798795cee BURIED: Make more consistent use of nullptr
0acfe12ca3 BURIED: Remove another aggressive comment
fd3856d4dd BURIED: Set pointers to nullptr where applicable
5aab3da1bf BURIED: Added missing override keywords
9c68ab2f43 BURIED: const'ness
c2d4a39c98 JANITORIAL: Whitespace fixes
78c7324f92 BURIED: Marked engine as highres
048950f73b BURIED: Remove unneeded includes
9903913859 BURIED: Remove obsolete comment


Commit: f00ee606d313ecbd03b61978361363683fb8d8b3
    https://github.com/scummvm/scummvm/commit/f00ee606d313ecbd03b61978361363683fb8d8b3
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
ENGINES: Add stub Buried in Time engine

Changed paths:
  A engines/buried/buried.cpp
  A engines/buried/buried.h
  A engines/buried/configure.engine
  A engines/buried/detection.cpp
  A engines/buried/module.mk


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
new file mode 100644
index 0000000000..c86a799500
--- /dev/null
+++ b/engines/buried/buried.cpp
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/error.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
+#include "buried/buried.h"
+
+namespace Buried {
+
+BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+}
+
+BuriedEngine::~BuriedEngine() {
+}
+
+Common::Error BuriedEngine::run() {
+	return Common::kNoError;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
new file mode 100644
index 0000000000..349e63915c
--- /dev/null
+++ b/engines/buried/buried.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_BURIED_H
+#define BURIED_BURIED_H
+
+#include "common/scummsys.h"
+#include "common/array.h"
+
+#include "engines/engine.h"
+
+class OSystem;
+
+namespace Buried {
+
+struct BuriedGameDescription;
+
+class BuriedEngine : public ::Engine {
+protected:
+	Common::Error run();
+
+public:
+	BuriedEngine(OSystem *syst, const BuriedGameDescription *gamedesc);
+	virtual ~BuriedEngine();
+
+	// Detection related functions
+	const BuriedGameDescription *_gameDescription;
+	bool isDemo() const;
+
+	bool hasFeature(EngineFeature f) const;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/configure.engine b/engines/buried/configure.engine
new file mode 100644
index 0000000000..1cf7cbdad0
--- /dev/null
+++ b/engines/buried/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine buried "The Journeyman Project 2: Buried in Time" no "" "" "freetype2"
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
new file mode 100644
index 0000000000..45aa5dbab3
--- /dev/null
+++ b/engines/buried/detection.cpp
@@ -0,0 +1,147 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "engines/advancedDetector.h"
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/savefile.h"
+
+#include "buried/buried.h"
+
+namespace Buried {
+
+struct BuriedGameDescription {
+	ADGameDescription desc;
+};
+
+bool BuriedEngine::hasFeature(EngineFeature f) const {
+	return
+		(f == kSupportsRTL);
+}
+
+bool BuriedEngine::isDemo() const {
+	return (_gameDescription->desc.flags & ADGF_DEMO) != 0;
+}
+
+} // End of namespace Buried
+
+static const PlainGameDescriptor buriedGames[] = {
+	{"buried", "The Journeyman Project 2: Buried in Time"},
+	{0, 0}
+};
+
+
+namespace Buried {
+
+static const BuriedGameDescription gameDescriptions[] = {
+	// Windows 3.11 8BPP
+	{
+		{
+			"buried",
+			"8BPP",
+			AD_ENTRY1("BIT816.EX_", "166b44e53350c19bb25ef93d2c2b8f79"),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Windows 3.11 24BPP
+	{
+		{
+			"buried",
+			"24BPP",
+			AD_ENTRY1("BIT2416.EX_", "a9ac76610ba614b59235a7d5e00e4a62"),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Demo 8BPP
+	{
+		{
+			"buried",
+			"Demo 8BPP",
+			AD_ENTRY1("BIT816.EXE", "a5bca831dac0903a304c29c320f881c5"),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Demo 24BPP
+	{
+		{
+			"buried",
+			"Demo 24BPP",
+			AD_ENTRY1("BIT2416.EXE", "9857e2d2b7a63b1304058dabc5098249"),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	{ AD_TABLE_END_MARKER }
+};
+
+} // End of namespace Buried
+
+
+class BuriedMetaEngine : public AdvancedMetaEngine {
+public:
+	BuriedMetaEngine() : AdvancedMetaEngine(Buried::gameDescriptions, sizeof(Buried::BuriedGameDescription), buriedGames) {
+		_singleid = "buried";
+	}
+
+	virtual const char *getName() const {
+		return "The Journeyman Project 2: Buried in Time";
+	}
+
+	virtual const char *getOriginalCopyright() const {
+		return "The Journeyman Project 2: Buried in Time (C) Presto Studios";
+	}
+
+	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+};
+
+bool BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	const Buried::BuriedGameDescription *gd = (const Buried::BuriedGameDescription *)desc;
+
+	if (gd)
+		*engine = new Buried::BuriedEngine(syst, gd);
+
+	return (gd != 0);
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(BURIED)
+	REGISTER_PLUGIN_DYNAMIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
+#else
+	REGISTER_PLUGIN_STATIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
+#endif
+
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
new file mode 100644
index 0000000000..8edf8d7d8a
--- /dev/null
+++ b/engines/buried/module.mk
@@ -0,0 +1,14 @@
+MODULE := engines/buried
+
+MODULE_OBJS = \
+	buried.o \
+	detection.o
+
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_BURIED), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk


Commit: 4cbcd29a94d27e514346187b2c72d5f8eef0b2af
    https://github.com/scummvm/scummvm/commit/4cbcd29a94d27e514346187b2c72d5f8eef0b2af
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
COMMON: Fix out-of-bounds write in SZDD EXE decompression

Changed paths:
    common/winexe_ne.cpp


diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index 66b5e0911a..bed7d9810a 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -64,6 +64,82 @@ bool NEResources::loadFromEXE(SeekableReadStream *stream) {
 	return true;
 }
 
+<<<<<<< HEAD
+=======
+bool NEResources::loadFromCompressedEXE(const String &fileName) {
+	// Based on http://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html
+
+	// TODO: Merge this with with loadFromEXE() so the handling of the compressed
+	// EXE's is transparent
+
+	File file;
+
+	if (!file.open(fileName))
+		return false;
+
+	// First part of the signature
+	if (file.readUint32BE() != MKTAG('S','Z','D','D'))
+		return false;
+
+	// Second part of the signature
+	if (file.readUint32BE() != 0x88F02733)
+		return false;
+
+	// Compression mode must be 'A'
+	if (file.readByte() != 'A')
+		return false;
+
+	file.readByte(); // file name character change
+	uint32 unpackedLength = file.readUint32LE();
+
+	byte *window = new byte[0x1000];
+	int pos = 0x1000 - 16;
+	memset(window, 0x20, 0x1000); // Initialize to all spaces
+
+	byte *unpackedData = (byte *)malloc(unpackedLength);
+	if (!unpackedData)
+		error("Failed to allocate uncompressed EXE");
+
+	byte *dataPos = unpackedData;
+	byte *endPos = unpackedData + unpackedLength;
+
+	// Apply simple LZSS decompression
+	while (dataPos < endPos) {
+		byte controlByte = file.readByte();
+
+		if (file.eos())
+			break;
+
+		for (byte i = 0; i < 8 && dataPos < endPos; i++) {
+			if (controlByte & (1 << i)) {
+				*dataPos++ = window[pos++] = file.readByte();
+				pos &= 0xFFF;
+			} else {
+				int matchPos = file.readByte();
+				int matchLen = file.readByte();
+				matchPos |= (matchLen & 0xF0) << 4;
+				matchLen = (matchLen & 0xF) + 3;
+
+				// Clip the length to the remaining size
+				matchLen = MIN<int>(matchLen, endPos - dataPos);
+
+				while (matchLen--) {
+					*dataPos++ = window[pos++] = window[matchPos++];
+					pos &= 0xFFF;
+					matchPos &= 0xFFF;
+				}
+			}
+
+		}
+	}
+
+	delete[] window;
+	SeekableReadStream *stream = new MemoryReadStream(unpackedData, unpackedLength);
+
+	return loadFromEXE(stream);
+}
+
+>>>>>>> 50fe418ac0 (COMMON: Fix out-of-bounds write in SZDD EXE decompression)
 uint32 NEResources::getResourceTableOffset() {
 	if (!_exe)
 		return 0xFFFFFFFF;


Commit: c3c188f4b6cb3ea83313e3a4e7bd220280a9b05c
    https://github.com/scummvm/scummvm/commit/c3c188f4b6cb3ea83313e3a4e7bd220280a9b05c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
COMMON: Add an NE version resource parser

Changed paths:
    common/winexe_ne.cpp
    common/winexe_ne.h


diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index bed7d9810a..4b75c58621 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -287,4 +287,67 @@ const Array<WinResourceID> NEResources::getIDList(const WinResourceID &type) con
 	return idArray;
 }
 
+NEResources::VersionInfo NEResources::getVersionInfo() {
+	VersionInfo info;
+	Common::ScopedPtr<Common::SeekableReadStream> stream(getResource(kNEVersion, 1));
+
+	if (!stream)
+		return info;
+
+	stream->readUint16LE(); // resource size
+
+	// Value size check
+	if (stream->readUint16LE() != 0x34)
+		return info;
+
+	char versionInfoString[16];
+	stream->read(versionInfoString, sizeof(versionInfoString));
+
+	if (memcmp(versionInfoString, "VS_VERSION_INFO", sizeof(versionInfoString) - 1) != 0)
+		return info;
+
+	// Signature check
+	if (stream->readUint32LE() != 0xFEEF04BD)
+		return info;
+
+	stream->readUint32LE(); // struct version
+
+	// The versions are stored a bit weird
+	info.fileVersion[1] = stream->readUint16LE();
+	info.fileVersion[0] = stream->readUint16LE();
+	info.fileVersion[3] = stream->readUint16LE();
+	info.fileVersion[2] = stream->readUint16LE();
+	info.productVersion[1] = stream->readUint16LE();
+	info.productVersion[0] = stream->readUint16LE();
+	info.productVersion[3] = stream->readUint16LE();
+	info.productVersion[2] = stream->readUint16LE();
+	
+	info.fileFlagsMask = stream->readUint32LE();
+	info.fileFlags = stream->readUint32LE();
+	info.fileOS = stream->readUint32LE();
+	info.fileType = stream->readUint32LE();
+	info.fileSubtype = stream->readUint32LE();
+	info.fileDate[0] = stream->readUint32LE();
+	info.fileDate[1] = stream->readUint32LE();
+
+	// TODO: Think about reading StringFileInfo and Translation parts
+
+	return info;
+}
+
+NEResources::VersionInfo::VersionInfo() {
+	fileVersion[0] = fileVersion[1] = fileVersion[2] = fileVersion[3] = 0;
+	productVersion[0] = productVersion[1] = productVersion[2] = productVersion[3] = 0;
+	fileFlagsMask = 0;
+	fileFlags = 0;
+	fileOS = 0;
+	fileType = 0;
+	fileSubtype = 0;
+	fileDate[0] = fileDate[1] = 0;
+}
+
+bool NEResources::VersionInfo::isValid() const {
+	return fileOS != 0;
+}
+
 } // End of namespace Common
diff --git a/common/winexe_ne.h b/common/winexe_ne.h
index 85b42489c2..7dbb6c55c8 100644
--- a/common/winexe_ne.h
+++ b/common/winexe_ne.h
@@ -67,6 +67,26 @@ public:
 	/** Return a stream to the specified resource (or 0 if non-existent). */
 	SeekableReadStream *getResource(const WinResourceID &type, const WinResourceID &id);
 
+	/** The structure of the version resource inside an NE EXE */
+	struct VersionInfo {
+		VersionInfo();
+
+		/** Is the version field valid? */
+		bool isValid() const;
+
+		uint16 fileVersion[4];
+		uint16 productVersion[4];
+		uint32 fileFlagsMask;
+		uint32 fileFlags;
+		uint32 fileOS;
+		uint32 fileType;
+		uint32 fileSubtype;
+		uint32 fileDate[2];		
+	};
+
+	/** Return the version of the EXE */
+	VersionInfo getVersionInfo();
+
 private:
 	/** A resource. */
 	struct Resource {


Commit: 639a1e01206102ca737d7942f6390f7949de38bb
    https://github.com/scummvm/scummvm/commit/639a1e01206102ca737d7942f6390f7949de38bb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
COMMON: Add a function to read NE strings

Changed paths:
    common/winexe_ne.cpp
    common/winexe_ne.h


diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index 4b75c58621..30652c0d02 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -335,6 +335,27 @@ NEResources::VersionInfo NEResources::getVersionInfo() {
 	return info;
 }
 
+String NEResources::loadString(uint32 stringID) {
+	// This is how the resource ID is calculated
+	String string;
+	SeekableReadStream *stream = getResource(kNEString, (stringID >> 4) + 1);
+
+	if (!stream)
+		return string;
+
+	// Skip over strings we don't care about
+	uint32 startString = stringID & ~0xF;
+
+	for (uint32 i = startString; i < stringID; i++)
+		stream->skip(stream->readByte());
+
+	byte size = stream->readByte();
+	while (size--)
+		string += (char)stream->readByte();
+
+	return string;
+}
+
 NEResources::VersionInfo::VersionInfo() {
 	fileVersion[0] = fileVersion[1] = fileVersion[2] = fileVersion[3] = 0;
 	productVersion[0] = productVersion[1] = productVersion[2] = productVersion[3] = 0;
diff --git a/common/winexe_ne.h b/common/winexe_ne.h
index 7dbb6c55c8..169dced837 100644
--- a/common/winexe_ne.h
+++ b/common/winexe_ne.h
@@ -87,6 +87,9 @@ public:
 	/** Return the version of the EXE */
 	VersionInfo getVersionInfo();
 
+	/** Get a string from a string resource. */
+	String loadString(uint32 stringID);
+
 private:
 	/** A resource. */
 	struct Resource {


Commit: 5f86d48b428d3790db630a400bf3df16f01a0803
    https://github.com/scummvm/scummvm/commit/5f86d48b428d3790db630a400bf3df16f01a0803
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Begin adding the windowing/messaging system

Changed paths:
  A engines/buried/message.h
  A engines/buried/window.cpp
  A engines/buried/window.h
    engines/buried/module.mk


diff --git a/engines/buried/message.h b/engines/buried/message.h
new file mode 100644
index 0000000000..a154d095ca
--- /dev/null
+++ b/engines/buried/message.h
@@ -0,0 +1,159 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_MESSAGE_H
+#define BURIED_MESSAGE_H
+
+#include "common/keyboard.h"
+#include "common/rect.h"
+
+namespace Buried {
+
+// This is all based on the Windows messaging system
+// ...but less stupid
+
+class Window;
+
+enum MessageType {
+	kMessageTypeEraseBackground,
+	kMessageTypeKeyUp,
+	kMessageTypeKeyDown,
+	kMessageTypeTimer,
+	kMessageTypeSetFocus,
+	kMessageTypeKillFocus,
+	kMessageTypeQueryNewPalette,
+	kMessageTypePaint,
+	kMessageTypeMouseMove,
+	kMessageTypeLButtonUp,
+	kMessageTypeLButtonDown,
+	kMessageTypeLButtonDoubleClick,
+	kMessageTypeMButtonUp,
+	kMessageTypeRButtonUp,
+	kMessageTypeRButtonDown,
+	kMessageTypeSetCursor,
+	kMessageTypeEnable
+};
+
+
+class Message {
+public:
+	virtual ~Message() {}
+
+	virtual MessageType getMessageType() const = 0;
+};
+
+// Templated version to make stuff a bit neater
+template <MessageType type>
+class MessageTypeIntern : public Message {
+public:
+	MessageType getMessageType() const { return type; }
+};
+
+// Some common template classes
+template <MessageType type>
+class MouseMessage : public MessageTypeIntern<type> {
+public:
+	MouseMessage(const Common::Point &point, uint flags) : _point(point), _flags(flags) {}
+
+	Common::Point getPoint() const { return _point; }
+	uint getFlags() const { return _flags; }
+
+private:
+	Common::Point _point;
+	uint _flags;
+};
+
+template <MessageType type>
+class KeyMessage : public MessageTypeIntern<type> {
+public:
+	KeyMessage(const Common::KeyState &keyState, uint flags) : _keyState(keyState), _flags(flags) {}
+
+	Common::KeyState getKeyState() const { return _keyState; }
+	uint getFlags() const { return _flags; }
+
+private:
+	Common::KeyState _keyState;
+	uint _flags;
+};
+
+template <MessageType type>
+class WindowMessage : public MessageTypeIntern<type> {
+public:
+	WindowMessage(Window *window) : _window(window) {}
+
+	Window *getWindow() const { return _window; }
+
+private:
+	Window *_window;
+};
+
+// Types for everything that falls under one of the above categories
+typedef MessageTypeIntern<kMessageTypeEraseBackground> EraseBackgroundMessage;
+typedef MessageTypeIntern<kMessageTypeQueryNewPalette> QueryNewPaletteMessage;
+typedef MessageTypeIntern<kMessageTypePaint>           PaintMessage;
+typedef KeyMessage<kMessageTypeKeyUp>                  KeyUpMessage;
+typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
+typedef WindowMessage<kMessageTypeSetFocus>            SetFocusMessage;
+typedef WindowMessage<kMessageTypeKillFocus>           KillFocusMessage;
+typedef MouseMessage<kMessageTypeMouseMove>            MouseMoveMessage;
+typedef MouseMessage<kMessageTypeLButtonUp>            LButtonUpMessage;
+typedef MouseMessage<kMessageTypeLButtonDown>          LButtonDownMessage;
+typedef MouseMessage<kMessageTypeLButtonDoubleClick>   LButtonDoubleClickMessage;
+typedef MouseMessage<kMessageTypeMButtonUp>            MButtonUpMessage;
+typedef MouseMessage<kMessageTypeRButtonUp>            RButtonUpMessage;
+typedef MouseMessage<kMessageTypeRButtonDown>          RButtonDownMessage;
+
+// ...and the rest
+class SetCursorMessage : public WindowMessage<kMessageTypeSetCursor> {
+public:
+	SetCursorMessage(Window *window, uint cursor)
+			: WindowMessage<kMessageTypeSetCursor>(window), _cursor(cursor) {}
+
+	uint getCursor() const { return _cursor; }
+
+private:
+	uint _cursor;
+};
+
+class TimerMessage : public MessageTypeIntern<kMessageTypeTimer> {
+public:
+	TimerMessage(uint timer) : _timer(timer) {}
+
+	uint getTimer() const { return _timer; }
+
+private:
+	uint _timer;
+};
+
+class EnableMessage : public MessageTypeIntern<kMessageTypeEnable> {
+public:
+	EnableMessage(bool enable) : _enable(enable) {}
+
+	bool getEnable() const { return _enable; }
+
+private:
+	bool _enable;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 8edf8d7d8a..209b079a09 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -2,7 +2,8 @@ MODULE := engines/buried
 
 MODULE_OBJS = \
 	buried.o \
-	detection.o
+	detection.o \
+	window.o
 
 
 # This module can be built as a plugin
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
new file mode 100644
index 0000000000..2dcf185662
--- /dev/null
+++ b/engines/buried/window.cpp
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/textconsole.h"
+
+#include "buried/message.h"
+#include "buried/window.h"
+
+namespace Buried {
+
+void Window::dispatchMessage() {
+	if (_queue.empty())
+		return;
+
+	Message *message = _queue.pop();
+
+	switch (message->getMessageType()) {
+	case kMessageTypeEraseBackground:
+		onEraseBackground();
+		break;
+	case kMessageTypeKeyUp:
+		onKeyUp(((KeyUpMessage *)message)->getKeyState(), ((KeyUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeKeyDown:
+		onKeyDown(((KeyDownMessage *)message)->getKeyState(), ((KeyDownMessage *)message)->getFlags());
+		break;
+	case kMessageTypeTimer:
+		onTimer(((TimerMessage *)message)->getTimer());
+		break;
+	case kMessageTypeSetFocus:
+		onSetFocus(((SetFocusMessage *)message)->getWindow());
+		break;
+	case kMessageTypeKillFocus:
+		onKillFocus(((KillFocusMessage *)message)->getWindow());
+		break;
+	case kMessageTypeQueryNewPalette:
+		onQueryNewPalette();
+		break;
+	case kMessageTypePaint:
+		onPaint();
+		break;
+	case kMessageTypeLButtonUp:
+		onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeLButtonDown:
+		onLButtonDown(((LButtonDownMessage *)message)->getPoint(), ((LButtonDownMessage *)message)->getFlags());
+		break;
+	case kMessageTypeLButtonDoubleClick:
+		onLButtonDoubleClick(((LButtonDoubleClickMessage *)message)->getPoint(), ((LButtonDoubleClickMessage *)message)->getFlags());
+		break;
+	case kMessageTypeMButtonUp:
+		onMButtonUp(((MButtonUpMessage *)message)->getPoint(), ((MButtonUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeRButtonUp:
+		onRButtonUp(((RButtonUpMessage *)message)->getPoint(), ((RButtonUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeRButtonDown:
+		onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
+		break;
+	case kMessageTypeSetCursor:
+		onSetCursor(((SetCursorMessage *)message)->getWindow(), ((SetCursorMessage *)message)->getCursor());
+		break;
+	case kMessageTypeEnable:
+		onEnable(((EnableMessage *)message)->getEnable());
+		break;
+	default:
+		error("Unknown message type %d", message->getMessageType());
+	}
+
+	delete message;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
new file mode 100644
index 0000000000..dd099d0756
--- /dev/null
+++ b/engines/buried/window.h
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_WINDOW_H
+#define BURIED_WINDOW_H
+
+#include "common/queue.h"
+
+namespace Common {
+struct KeyState;
+struct Point;
+}
+
+namespace Buried {
+
+struct Message;
+
+class Window {
+public:
+	virtual ~Window() {}
+
+	// The message types used by Buried in Time's windows
+	virtual bool onEraseBackground() { return false; }
+	virtual void onKeyDown(const Common::KeyState &key, uint flags) {}
+	virtual void onKeyUp(const Common::KeyState &key, uint flags) {}
+	virtual void onTimer(uint timer) {}
+	virtual void onKillFocus(Window *newWindow) {}
+	virtual void onSetFocus(Window *oldWindow) {}
+	virtual bool onQueryNewPalette() { return false; }
+	virtual void onPaint() {}
+	virtual void onLButtonUp(const Common::Point &point, uint flags) {}
+	virtual void onLButtonDown(const Common::Point &point, uint flags) {}
+	virtual void onLButtonDoubleClick(const Common::Point &point, uint flags) {}
+	virtual void onMouseMove(const Common::Point &point, uint flags) {}
+	virtual void onMButtonUp(const Common::Point &point, uint flags) {}
+	virtual void onRButtonUp(const Common::Point &point, uint flags) {}
+	virtual void onRButtonDown(const Common::Point &point, uint flags) {}
+	virtual bool onSetCursor(Window *window, uint cursor) { return false; }
+	virtual void onEnable(bool enable) {}
+
+	// TODO:
+	// SetTimer
+	// ShowWindow
+	// UpdateWindow
+	// GetClientRect
+	// KillTimer
+	// InvalidateRect
+	// BeginPaint (?)
+	// EndPaint (?)
+	// Create
+	// GetParent
+	// ...
+
+	void sendMessage(Message *message) { _queue.push(message); }
+	void dispatchMessage();
+
+private:
+	Common::Queue<Message *> _queue;
+
+	// TODO: Something about children? Parents?
+};
+
+} // End of namespace Buried
+
+#endif


Commit: 51cb5d1672aa1b308ae36d8baaf2bb47493490f0
    https://github.com/scummvm/scummvm/commit/51cb5d1672aa1b308ae36d8baaf2bb47493490f0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Add some more functions for detection

Changed paths:
    engines/buried/buried.h
    engines/buried/detection.cpp


diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 349e63915c..82637bc558 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -45,6 +45,11 @@ public:
 	// Detection related functions
 	const BuriedGameDescription *_gameDescription;
 	bool isDemo() const;
+	bool isTrueColor() const;
+	bool isWin95() const;
+	bool isCompressed() const;
+	Common::String getEXEName() const;
+	Common::String getLibraryName() const;
 
 	bool hasFeature(EngineFeature f) const;
 };
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 45aa5dbab3..0f8d8f2781 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -35,6 +35,12 @@ struct BuriedGameDescription {
 	ADGameDescription desc;
 };
 
+enum {
+	GF_TRUECOLOR  = (1 << 1),
+	GF_WIN95      = (1 << 2),
+	GF_COMPRESSED = (1 << 3)
+};
+
 bool BuriedEngine::hasFeature(EngineFeature f) const {
 	return
 		(f == kSupportsRTL);
@@ -44,6 +50,26 @@ bool BuriedEngine::isDemo() const {
 	return (_gameDescription->desc.flags & ADGF_DEMO) != 0;
 }
 
+bool BuriedEngine::isTrueColor() const {
+	return (_gameDescription->desc.flags & GF_TRUECOLOR) != 0;
+}
+
+bool BuriedEngine::isWin95() const {
+	return (_gameDescription->desc.flags & GF_WIN95) != 0;
+}
+
+bool BuriedEngine::isCompressed() const {
+	return (_gameDescription->desc.flags & GF_COMPRESSED) != 0;
+}
+
+Common::String BuriedEngine::getEXEName() const {
+	return _gameDescription->desc.filesDescriptions[0].fileName;
+}
+
+Common::String BuriedEngine::getLibraryName() const {
+	return _gameDescription->desc.filesDescriptions[1].fileName;
+}
+
 } // End of namespace Buried
 
 static const PlainGameDescriptor buriedGames[] = {
@@ -60,10 +86,14 @@ static const BuriedGameDescription gameDescriptions[] = {
 		{
 			"buried",
 			"8BPP",
-			AD_ENTRY1("BIT816.EX_", "166b44e53350c19bb25ef93d2c2b8f79"),
+			{
+				{ "BIT816.EX_",  0, "166b44e53350c19bb25ef93d2c2b8f79", 364490 },
+				{ "BIT8LIB.DL_", 0, "8a345993f60f6bed7c17fa9e7f2bc37d", 908854 },
+				{ 0, 0, 0, 0 },
+			},
 			Common::EN_ANY,
 			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
+			GF_COMPRESSED,
 			GUIO0()
 		},
 	},
@@ -73,10 +103,14 @@ static const BuriedGameDescription gameDescriptions[] = {
 		{
 			"buried",
 			"24BPP",
-			AD_ENTRY1("BIT2416.EX_", "a9ac76610ba614b59235a7d5e00e4a62"),
+			{
+				{ "BIT2416.EX_",  0, "a9ac76610ba614b59235a7d5e00e4a62", 361816 },
+				{ "BIT24LIB.DL_", 0, "00e6eedbcef824988fbb01a87ca8f7fd", 2269314 },
+				{ 0, 0, 0, 0 },
+			},
 			Common::EN_ANY,
 			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
+			GF_COMPRESSED | GF_TRUECOLOR,
 			GUIO0()
 		},
 	},
@@ -89,7 +123,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 			AD_ENTRY1("BIT816.EXE", "a5bca831dac0903a304c29c320f881c5"),
 			Common::EN_ANY,
 			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
+			ADGF_DEMO,
 			GUIO0()
 		},
 	},
@@ -102,7 +136,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 			AD_ENTRY1("BIT2416.EXE", "9857e2d2b7a63b1304058dabc5098249"),
 			Common::EN_ANY,
 			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
+			ADGF_DEMO | GF_TRUECOLOR,
 			GUIO0()
 		},
 	},


Commit: dd36ffea1fe2c9e973e73a88f3bc78ba35462389
    https://github.com/scummvm/scummvm/commit/dd36ffea1fe2c9e973e73a88f3bc78ba35462389
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Add a wrapper around the EXE parser

Changed paths:
  A engines/buried/database.cpp
  A engines/buried/database.h
    engines/buried/module.mk


diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
new file mode 100644
index 0000000000..7a3d865995
--- /dev/null
+++ b/engines/buried/database.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/winexe_ne.h"
+
+#include "buried/database.h"
+
+namespace Buried {
+
+DatabaseNE::DatabaseNE() {
+	_exe = new Common::NEResources();
+}
+
+DatabaseNE::~DatabaseNE() {
+	delete _exe;
+}
+
+bool DatabaseNE::load(const Common::String &fileName) {
+	return _exe->loadFromEXE(fileName);
+}
+
+void DatabaseNE::close() {
+	_exe->clear();
+}
+
+Common::String DatabaseNE::loadString(uint32 stringID) {
+	bool continueReading = true;
+	Common::String result;
+
+	while (continueReading) {
+		Common::String string = _exe->loadString(stringID);
+
+		if (string.empty())
+			return "";
+
+		if (string[0] == '!') {
+			string.deleteChar(0);
+			stringID++;
+		} else {
+			continueReading = false;
+		}
+
+		result += string;
+	}
+
+	// Change any \r to \n
+	for (uint32 i = 0; i < result.size(); i++)
+		if (result[i] == '\r')
+			result.setChar('\n', i);
+
+	return result;
+}
+
+bool DatabaseNECompressed::load(const Common::String &fileName) {
+	return _exe->loadFromCompressedEXE(fileName);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/database.h b/engines/buried/database.h
new file mode 100644
index 0000000000..18576a36c9
--- /dev/null
+++ b/engines/buried/database.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_DATABASE_H
+#define BURIED_DATABASE_H
+
+namespace Common {
+	class NEResources;
+	class String;
+}
+
+namespace Buried {
+
+/**
+ * Simple wrapper class around the game's binaries to load
+ * data between them (without needing too much code different
+ * between Win16 and Win32 versions).
+ */
+class Database {
+public:
+	virtual ~Database() {}
+
+	virtual bool load(const Common::String &fileName) = 0;
+	virtual void close() = 0;
+
+	virtual Common::String loadString(uint32 stringID) = 0;
+};
+
+/**
+ * A database loaded from an NE executable/library
+ */
+class DatabaseNE : public Database {
+public:
+	DatabaseNE();
+	virtual ~DatabaseNE();
+
+	virtual bool load(const Common::String &fileName);
+	void close();
+
+	Common::String loadString(uint32 stringID);
+
+protected:
+	Common::NEResources *_exe;
+};
+
+/**
+ * A database loaded from a compressed NE executable/library
+ */
+class DatabaseNECompressed : public DatabaseNE {
+public:
+	bool load(const Common::String &fileName);
+};
+
+// TODO: PE stuff
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 209b079a09..e5e5bed5c7 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/buried
 
 MODULE_OBJS = \
 	buried.o \
+	database.o \
 	detection.o \
 	window.o
 


Commit: a16c3ae442395ed6a91ea8427fcd5edc49f65be4
    https://github.com/scummvm/scummvm/commit/a16c3ae442395ed6a91ea8427fcd5edc49f65be4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Begin loading from the EXE/DLL

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index c86a799500..a8ba42fa41 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -26,16 +26,40 @@
 #include "common/textconsole.h"
 
 #include "buried/buried.h"
+#include "buried/database.h"
 
 namespace Buried {
 
 BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+	_mainEXE = 0;
+	_library = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
+	delete _mainEXE;
+	delete _library;
 }
 
 Common::Error BuriedEngine::run() {
+	if (isWin95()) {
+		error("TODO: Win95 version");
+	} else if (isCompressed()) {
+		_mainEXE = new DatabaseNECompressed();
+		_library = new DatabaseNECompressed();
+	} else {
+		_mainEXE = new DatabaseNE();
+
+		// Demo only uses the main EXE
+		if (!isDemo())
+			_library = new DatabaseNE();
+	}
+
+	if (!_mainEXE->load(getEXEName()))
+		error("Failed to load main EXE '%s'", getEXEName().c_str());
+
+	if (_library && !_library->load(getLibraryName()))
+		error("Failed to load library DLL '%s'", getLibraryName().c_str());
+
 	return Common::kNoError;
 }
 
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 82637bc558..de16b4cbec 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -33,6 +33,7 @@ class OSystem;
 namespace Buried {
 
 struct BuriedGameDescription;
+class Database;
 
 class BuriedEngine : public ::Engine {
 protected:
@@ -52,6 +53,9 @@ public:
 	Common::String getLibraryName() const;
 
 	bool hasFeature(EngineFeature f) const;
+
+private:
+	Database *_mainEXE, *_library;
 };
 
 } // End of namespace Buried


Commit: db090027b6f0d8a84d08de9f99b16cb93370d162
    https://github.com/scummvm/scummvm/commit/db090027b6f0d8a84d08de9f99b16cb93370d162
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Begin to load the Arial font

TrueType2 is now required for the engine

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index a8ba42fa41..46fe04d448 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -22,8 +22,14 @@
 
 #include "common/scummsys.h"
 #include "common/error.h"
+#include "common/fs.h"
+#ifdef MACOSX
+#include "common/macresman.h"
+#endif
 #include "common/system.h"
 #include "common/textconsole.h"
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
 
 #include "buried/buried.h"
 #include "buried/database.h"
@@ -63,4 +69,64 @@ Common::Error BuriedEngine::run() {
 	return Common::kNoError;
 }
 
+Graphics::Font *BuriedEngine::createFont(int size) const {
+	Common::SeekableReadStream *stream = 0;
+
+	// HACK: Try to load the system font
+	// TODO: MS Gothic for the Japanese version (please buy for clone2727)
+	// Arial for everything else (???)
+#if defined(WIN32)
+	Common::FSNode fontPath("C:/WINDOWS/Fonts/arial.ttf");
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		Common::FSNode win2kFontPath("C:/WINNT/Fonts/arial.ttf");
+
+		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
+			stream = win2kFontPath.createReadStream();
+	}
+#elif defined(MACOSX)
+	// Attempt to load the font from the Arial.ttf font first
+	Common::FSNode fontPath("/Library/Fonts/Arial.ttf");
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		// Try the suitcase on the system
+		Common::FSNode fontDirectory("/Library/Fonts");
+		Common::MacResManager resFork;
+
+		// DOUBLE HACK WARNING: Just assume it's 0x1000
+		// (it should always be this, the first font, but parsing the FOND would be better)
+		if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
+			stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
+
+		// ...and one last try
+		if (!stream) {
+			Common::FSNode msFontDirectory("/Library/Fonts/Microsoft");
+			if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
+				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
+		}
+	}
+#endif
+
+	if (!stream) {
+		// TODO: Try to load an equivalent font from the theme
+		return 0;
+	}
+
+	// TODO: Make the monochrome mode optional
+	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
+	// with the TrueType font on Win7/Win8 (at least)
+	// TODO: The mapping is code page 1252, but it should be 1:1 to Unicode
+	// for the characters we need.
+	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, Graphics::kTTFRenderModeMonochrome, 0);
+	delete stream;
+	return font;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index de16b4cbec..279d80f30f 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -30,6 +30,10 @@
 
 class OSystem;
 
+namespace Graphics {
+class Font;
+}
+
 namespace Buried {
 
 struct BuriedGameDescription;
@@ -54,6 +58,8 @@ public:
 
 	bool hasFeature(EngineFeature f) const;
 
+	Graphics::Font *createFont(int size) const;
+
 private:
 	Database *_mainEXE, *_library;
 };


Commit: 8c130031eb4af4e7dfdac9b0b84af2cf7116686f
    https://github.com/scummvm/scummvm/commit/8c130031eb4af4e7dfdac9b0b84af2cf7116686f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Initiate the graphics system

Yes, this is going to be piecemeal

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 46fe04d448..5c8c9e6a1b 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -28,6 +28,7 @@
 #endif
 #include "common/system.h"
 #include "common/textconsole.h"
+#include "engines/util.h"
 #include "graphics/font.h"
 #include "graphics/fonts/ttf.h"
 
@@ -47,6 +48,20 @@ BuriedEngine::~BuriedEngine() {
 }
 
 Common::Error BuriedEngine::run() {
+	if (isTrueColor()) {
+#ifndef USE_RGB_COLOR
+		// Can't play 24bpp version without support
+		return Common::kUnsupportedColorMode;
+#else
+		initGraphics(640, 480, true, 0);
+
+		if (_system->getScreenFormat().bytesPerPixel == 1)
+			return Common::kUnsupportedColorMode;
+#endif
+	} else {
+		initGraphics(640, 480, true);
+	}
+
 	if (isWin95()) {
 		error("TODO: Win95 version");
 	} else if (isCompressed()) {


Commit: 2e534155ee905cf182739d74233480a2c4eac074
    https://github.com/scummvm/scummvm/commit/2e534155ee905cf182739d74233480a2c4eac074
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Add a function to read file paths from strings

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 5c8c9e6a1b..682bdd5d8a 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -144,4 +144,28 @@ Graphics::Font *BuriedEngine::createFont(int size) const {
 	return font;
 }
 
+Common::String BuriedEngine::getFilePath(uint32 stringID) {
+	Common::String path = _mainEXE->loadString(stringID);
+	Common::String output;
+
+	if (path.empty())
+		return output;
+
+	uint i = 0;
+
+	// The non-demo paths have CD info followed by a backspace
+	// We ignore this
+	if (!isDemo())
+		i += 2;
+
+	for (; i < path.size(); i++) {
+		if (path[i] == '\\')
+			output += '/';
+		else
+			output += path[i];
+	}
+
+	return output;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 279d80f30f..463ce46d08 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -60,6 +60,8 @@ public:
 
 	Graphics::Font *createFont(int size) const;
 
+	Common::String getFilePath(uint32 stringID);
+
 private:
 	Database *_mainEXE, *_library;
 };


Commit: 0c925bb64158b2ec312040a3fd0bbef318313683
    https://github.com/scummvm/scummvm/commit/0c925bb64158b2ec312040a3fd0bbef318313683
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Move all graphics stuff to its own class

Also added the 8bpp default palette function

Changed paths:
  A engines/buried/graphics.cpp
  A engines/buried/graphics.h
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/database.cpp
    engines/buried/database.h
    engines/buried/module.mk


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 682bdd5d8a..cede1ccf87 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -4,6 +4,9 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -22,27 +25,24 @@
 
 #include "common/scummsys.h"
 #include "common/error.h"
-#include "common/fs.h"
-#ifdef MACOSX
-#include "common/macresman.h"
-#endif
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "engines/util.h"
-#include "graphics/font.h"
-#include "graphics/fonts/ttf.h"
 
 #include "buried/buried.h"
 #include "buried/database.h"
+#include "buried/graphics.h"
 
 namespace Buried {
 
 BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+	_gfx = 0;
 	_mainEXE = 0;
 	_library = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
+	delete _gfx;
 	delete _mainEXE;
 	delete _library;
 }
@@ -81,67 +81,9 @@ Common::Error BuriedEngine::run() {
 	if (_library && !_library->load(getLibraryName()))
 		error("Failed to load library DLL '%s'", getLibraryName().c_str());
 
-	return Common::kNoError;
-}
-
-Graphics::Font *BuriedEngine::createFont(int size) const {
-	Common::SeekableReadStream *stream = 0;
-
-	// HACK: Try to load the system font
-	// TODO: MS Gothic for the Japanese version (please buy for clone2727)
-	// Arial for everything else (???)
-#if defined(WIN32)
-	Common::FSNode fontPath("C:/WINDOWS/Fonts/arial.ttf");
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-
-	if (!stream) {
-		Common::FSNode win2kFontPath("C:/WINNT/Fonts/arial.ttf");
-
-		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
-			stream = win2kFontPath.createReadStream();
-	}
-#elif defined(MACOSX)
-	// Attempt to load the font from the Arial.ttf font first
-	Common::FSNode fontPath("/Library/Fonts/Arial.ttf");
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-
-	if (!stream) {
-		// Try the suitcase on the system
-		Common::FSNode fontDirectory("/Library/Fonts");
-		Common::MacResManager resFork;
-
-		// DOUBLE HACK WARNING: Just assume it's 0x1000
-		// (it should always be this, the first font, but parsing the FOND would be better)
-		if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
-			stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
-
-		// ...and one last try
-		if (!stream) {
-			Common::FSNode msFontDirectory("/Library/Fonts/Microsoft");
-			if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
-				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
-		}
-	}
-#endif
-
-	if (!stream) {
-		// TODO: Try to load an equivalent font from the theme
-		return 0;
-	}
+	_gfx = new GraphicsManager(this);
 
-	// TODO: Make the monochrome mode optional
-	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
-	// with the TrueType font on Win7/Win8 (at least)
-	// TODO: The mapping is code page 1252, but it should be 1:1 to Unicode
-	// for the characters we need.
-	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, Graphics::kTTFRenderModeMonochrome, 0);
-	delete stream;
-	return font;
+	return Common::kNoError;
 }
 
 Common::String BuriedEngine::getFilePath(uint32 stringID) {
@@ -168,4 +110,13 @@ Common::String BuriedEngine::getFilePath(uint32 stringID) {
 	return output;
 }
 
+Common::SeekableReadStream *BuriedEngine::getBitmapStream(uint32 bitmapID) {
+	// The demo's bitmaps are in the main EXE
+	if (isDemo())
+		return _mainEXE->getBitmapStream(bitmapID);
+
+	// The rest in the database library
+	return _library->getBitmapStream(bitmapID);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 463ce46d08..ba9d51971c 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -30,14 +30,11 @@
 
 class OSystem;
 
-namespace Graphics {
-class Font;
-}
-
 namespace Buried {
 
 struct BuriedGameDescription;
 class Database;
+class GraphicsManager;
 
 class BuriedEngine : public ::Engine {
 protected:
@@ -58,9 +55,10 @@ public:
 
 	bool hasFeature(EngineFeature f) const;
 
-	Graphics::Font *createFont(int size) const;
-
 	Common::String getFilePath(uint32 stringID);
+	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
+
+	GraphicsManager *_gfx;
 
 private:
 	Database *_mainEXE, *_library;
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index 7a3d865995..104e095a5e 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -73,6 +73,10 @@ Common::String DatabaseNE::loadString(uint32 stringID) {
 	return result;
 }
 
+Common::SeekableReadStream *DatabaseNE::getBitmapStream(uint32 bitmapID) {
+	return _exe->getResource(Common::kNEBitmap, bitmapID);
+}
+
 bool DatabaseNECompressed::load(const Common::String &fileName) {
 	return _exe->loadFromCompressedEXE(fileName);
 }
diff --git a/engines/buried/database.h b/engines/buried/database.h
index 18576a36c9..3a64c221c2 100644
--- a/engines/buried/database.h
+++ b/engines/buried/database.h
@@ -43,6 +43,7 @@ public:
 	virtual void close() = 0;
 
 	virtual Common::String loadString(uint32 stringID) = 0;
+	virtual Common::SeekableReadStream *getBitmapStream(uint32 bitmapID) = 0;
 };
 
 /**
@@ -57,6 +58,7 @@ public:
 	void close();
 
 	Common::String loadString(uint32 stringID);
+	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 
 protected:
 	Common::NEResources *_exe;
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
new file mode 100644
index 0000000000..717f199096
--- /dev/null
+++ b/engines/buried/graphics.cpp
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/fs.h"
+#ifdef MACOSX
+#include "common/macresman.h"
+#endif
+#include "graphics/font.h"
+#include "graphics/fonts/ttf.h"
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+
+namespace Buried {
+
+GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
+}
+
+GraphicsManager::~GraphicsManager() {
+}
+
+byte *GraphicsManager::getDefaultPalette() const {
+	Common::SeekableReadStream *stream = _vm->getBitmapStream(700);
+
+	if (!stream)
+		error("Couldn't find bitmap 700");
+
+	stream->skip(14);
+
+	if (stream->readUint16LE() != 8)
+		error("Trying to load palette from non-8bpp image 700");
+
+	stream->skip(16);
+
+	uint32 colorsUsed = stream->readUint32LE();
+
+	if (colorsUsed != 0 && colorsUsed != 256)
+		error("Bitmap 700 is missing a full palette");
+
+	stream->skip(4);
+	byte *palette = new byte[256 * 3];
+	byte *ptr = palette;
+
+	for (uint32 i = 0; i < 256; i++) {
+		ptr[2] = stream->readByte();
+		ptr[1] = stream->readByte();
+		ptr[0] = stream->readByte();
+		stream->readByte();
+		ptr += 3;
+	}
+
+	delete stream;
+
+	// Make sure the first entry is black and the last is white
+	palette[0]   = palette[1]   = palette[2]   = 0x00;
+	palette[253] = palette[254] = palette[255] = 0xFF;
+
+	return palette;
+}
+
+Graphics::Font *GraphicsManager::createFont(int size) const {
+	Common::SeekableReadStream *stream = 0;
+
+	// HACK: Try to load the system font
+	// TODO: MS Gothic for the Japanese version (please buy for clone2727)
+	// Arial for everything else (???)
+#if defined(WIN32)
+	Common::FSNode fontPath("C:/WINDOWS/Fonts/arial.ttf");
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		Common::FSNode win2kFontPath("C:/WINNT/Fonts/arial.ttf");
+
+		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
+			stream = win2kFontPath.createReadStream();
+	}
+#elif defined(MACOSX)
+	// Attempt to load the font from the Arial.ttf font first
+	Common::FSNode fontPath("/Library/Fonts/Arial.ttf");
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		// Try the suitcase on the system
+		Common::FSNode fontDirectory("/Library/Fonts");
+		Common::MacResManager resFork;
+
+		// DOUBLE HACK WARNING: Just assume it's 0x1000
+		// (it should always be this, the first font, but parsing the FOND would be better)
+		if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
+			stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
+
+		// ...and one last try
+		if (!stream) {
+			Common::FSNode msFontDirectory("/Library/Fonts/Microsoft");
+			if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
+				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
+		}
+	}
+#endif
+
+	if (!stream) {
+		// TODO: Try to load an equivalent font from the theme
+		return 0;
+	}
+
+	// TODO: Make the monochrome mode optional
+	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
+	// with the TrueType font on Win7/Win8 (at least)
+	// TODO: The mapping is code page 1252, but it should be 1:1 to Unicode
+	// for the characters we need.
+	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, Graphics::kTTFRenderModeMonochrome, 0);
+	delete stream;
+	return font;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
new file mode 100644
index 0000000000..f18297d108
--- /dev/null
+++ b/engines/buried/graphics.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_GRAPHICS_H
+#define BURIED_GRAPHICS_H
+
+#include "common/scummsys.h"
+
+namespace Graphics {
+class Font;
+}
+
+namespace Buried {
+
+class BuriedEngine;
+
+class GraphicsManager {
+public:
+	GraphicsManager(BuriedEngine *vm);
+	~GraphicsManager();
+
+	byte *getDefaultPalette() const;
+	Graphics::Font *createFont(int size) const;
+
+private:
+	BuriedEngine *_vm;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index e5e5bed5c7..8ecea5ddf5 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS = \
 	buried.o \
 	database.o \
 	detection.o \
+	graphics.o \
 	window.o
 
 


Commit: 06a1bcc9ee200e6b205b0a7cff6ab85bf8fc710c
    https://github.com/scummvm/scummvm/commit/06a1bcc9ee200e6b205b0a7cff6ab85bf8fc710c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Add support for the cursors

Changed paths:
    engines/buried/buried.h
    engines/buried/database.cpp
    engines/buried/database.h
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index ba9d51971c..2eb2e4e6a3 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -59,9 +59,10 @@ public:
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 
 	GraphicsManager *_gfx;
+	Database *_mainEXE;
 
 private:
-	Database *_mainEXE, *_library;
+	Database *_library;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index 104e095a5e..76b42c6c30 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "common/winexe_ne.h"
+#include "graphics/wincursor.h"
 
 #include "buried/database.h"
 
@@ -77,6 +78,10 @@ Common::SeekableReadStream *DatabaseNE::getBitmapStream(uint32 bitmapID) {
 	return _exe->getResource(Common::kNEBitmap, bitmapID);
 }
 
+Graphics::WinCursorGroup *DatabaseNE::getCursorGroup(uint32 cursorGroupID) {
+	return Graphics::WinCursorGroup::createCursorGroup(*_exe, cursorGroupID);
+}
+
 bool DatabaseNECompressed::load(const Common::String &fileName) {
 	return _exe->loadFromCompressedEXE(fileName);
 }
diff --git a/engines/buried/database.h b/engines/buried/database.h
index 3a64c221c2..0dcae2b8ab 100644
--- a/engines/buried/database.h
+++ b/engines/buried/database.h
@@ -24,8 +24,12 @@
 #define BURIED_DATABASE_H
 
 namespace Common {
-	class NEResources;
-	class String;
+class NEResources;
+class String;
+}
+
+namespace Graphics {
+class WinCursorGroup;
 }
 
 namespace Buried {
@@ -44,6 +48,7 @@ public:
 
 	virtual Common::String loadString(uint32 stringID) = 0;
 	virtual Common::SeekableReadStream *getBitmapStream(uint32 bitmapID) = 0;
+	virtual Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID) = 0;
 };
 
 /**
@@ -59,6 +64,7 @@ public:
 
 	Common::String loadString(uint32 stringID);
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
+	Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID);
 
 protected:
 	Common::NEResources *_exe;
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 717f199096..baf0a49d79 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -24,15 +24,22 @@
 #ifdef MACOSX
 #include "common/macresman.h"
 #endif
+#include "graphics/cursorman.h"
+#include "graphics/wincursor.h"
 #include "graphics/font.h"
 #include "graphics/fonts/ttf.h"
 
 #include "buried/buried.h"
+#include "buried/database.h"
 #include "buried/graphics.h"
 
 namespace Buried {
 
 GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
+	_curCursor = kCursorNone;
+
+	setCursor(kCursorArrow);
+	CursorMan.showMouse(true);
 }
 
 GraphicsManager::~GraphicsManager() {
@@ -137,4 +144,41 @@ Graphics::Font *GraphicsManager::createFont(int size) const {
 	return font;
 }
 
+Cursor GraphicsManager::setCursor(Cursor newCursor) {
+	Cursor oldCursor = _curCursor;
+	Graphics::Cursor *cursor = 0;
+	Graphics::WinCursorGroup *cursorGroup = 0;
+
+	if (newCursor == kCursorArrow) {
+		cursor = Graphics::makeDefaultWinCursor();
+	} else if (newCursor == kCursorWait) {
+		warning("STUB: setCursor(kCursorWait)");
+		return kCursorNone;
+	} else {
+		cursorGroup = _vm->_mainEXE->getCursorGroup(newCursor);
+
+		if (!cursorGroup)
+			return kCursorNone;
+
+		cursor = cursorGroup->cursors[0].cursor;
+	}
+
+	if (!cursor)
+		error("Failed to find cursor %d", newCursor);
+
+	// TODO: Fallback mode for platforms without cursor palettes in 8bpp mode?
+
+	CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(),
+			cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
+	CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());
+
+	if (cursorGroup)
+		delete cursorGroup;
+	else
+		delete cursor;
+
+	_curCursor = newCursor;
+	return oldCursor;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index f18297d108..f70da40e8b 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -33,6 +33,32 @@ namespace Buried {
 
 class BuriedEngine;
 
+enum Cursor {
+	kCursorNone            =     0,
+
+	// Windows cursors
+	kCursorArrow           = 32512,
+	kCursorWait            = 32514,
+
+	// Buried in Time Cursors
+	kCursorEmptyArrow      =   100,
+	kCursorFinger          =   101,
+	kCursorMagnifyingGlass =   102,
+	kCursorOpenHand        =   103,
+	kCursorClosedHand      =   104,
+	kCursorPutDown         =   105,
+	kCursorNextPage        =   106,
+	kCursorPrevPage        =   107,
+	kCursorMoveUp          =   108,
+	kCursorMoveDown        =   109,
+	kCursorLocateCursorA   =   110,
+	kCursorLocateCursorB   =   111,
+	kCursorArrowUp         =   112,
+	kCursorArrowLeft       =   113,
+	kCursorArrowDown       =   114,
+	kCursorArrowRight      =   115
+};
+
 class GraphicsManager {
 public:
 	GraphicsManager(BuriedEngine *vm);
@@ -40,9 +66,11 @@ public:
 
 	byte *getDefaultPalette() const;
 	Graphics::Font *createFont(int size) const;
+	Cursor setCursor(Cursor newCursor);
 
 private:
 	BuriedEngine *_vm;
+	Cursor _curCursor;
 };
 
 } // End of namespace Buried


Commit: ccabf0621cea4caf4acc5d98adde34f9f97b942a
    https://github.com/scummvm/scummvm/commit/ccabf0621cea4caf4acc5d98adde34f9f97b942a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
IMAGE: Add support for headerless bitmaps

These ones are found inside of executables as resources

Changed paths:
    image/bmp.cpp


diff --git a/image/bmp.cpp b/image/bmp.cpp
index 2a00cbc9d6..9396d05fd9 100644
--- a/image/bmp.cpp
+++ b/image/bmp.cpp
@@ -57,16 +57,19 @@ void BitmapDecoder::destroy() {
 bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) {
 	destroy();
 
-	if (stream.readByte() != 'B')
-		return false;
-
-	if (stream.readByte() != 'M')
-		return false;
-
-	/* uint32 fileSize = */ stream.readUint32LE();
-	/* uint16 res1 = */ stream.readUint16LE();
-	/* uint16 res2 = */ stream.readUint16LE();
-	uint32 imageOffset = stream.readUint32LE();
+	uint16 fileType = stream.readUint16BE();
+	uint32 imageOffset = 0;
+
+	if (fileType == MKTAG16('B', 'M')) {
+		// The bitmap file header is present
+		/* uint32 fileSize = */ stream.readUint32LE();
+		/* uint16 res1 = */ stream.readUint16LE();
+		/* uint16 res2 = */ stream.readUint16LE();
+		imageOffset = stream.readUint32LE();
+	} else {
+		// Not present, let's try to parse as a headerless one
+		stream.seek(-2, SEEK_CUR);
+	}
 
 	uint32 infoSize = stream.readUint32LE();
 	if (infoSize != 40 && infoSize != 108) {
@@ -119,6 +122,11 @@ bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) {
 	if (!_codec)
 		return false;
 
+	// If the image offset is zero (like in headerless ones), set it to the current
+	// position.
+	if (imageOffset == 0)
+		imageOffset = stream.pos();
+
 	// If the image size is zero, set it to the rest of the stream.
 	if (imageSize == 0)
 		imageSize = stream.size() - imageOffset;


Commit: 2874046e52e377d240e433a0f49d936497710bb1
    https://github.com/scummvm/scummvm/commit/2874046e52e377d240e433a0f49d936497710bb1
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:36+01:00

Commit Message:
BURIED: Add the sound manager code

Changed paths:
  A engines/buried/resources.h
  A engines/buried/sound.cpp
  A engines/buried/sound.h
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/module.mk


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index cede1ccf87..a55e97355f 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -32,6 +32,7 @@
 #include "buried/buried.h"
 #include "buried/database.h"
 #include "buried/graphics.h"
+#include "buried/sound.h"
 
 namespace Buried {
 
@@ -39,12 +40,14 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_gfx = 0;
 	_mainEXE = 0;
 	_library = 0;
+	_sound = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
 	delete _gfx;
 	delete _mainEXE;
 	delete _library;
+	delete _sound;
 }
 
 Common::Error BuriedEngine::run() {
@@ -82,6 +85,7 @@ Common::Error BuriedEngine::run() {
 		error("Failed to load library DLL '%s'", getLibraryName().c_str());
 
 	_gfx = new GraphicsManager(this);
+	_sound = new SoundManager(this);
 
 	return Common::kNoError;
 }
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 2eb2e4e6a3..c2d2a85f69 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -35,6 +35,7 @@ namespace Buried {
 struct BuriedGameDescription;
 class Database;
 class GraphicsManager;
+class SoundManager;
 
 class BuriedEngine : public ::Engine {
 protected:
@@ -60,6 +61,7 @@ public:
 
 	GraphicsManager *_gfx;
 	Database *_mainEXE;
+	SoundManager *_sound;
 
 private:
 	Database *_library;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 8ecea5ddf5..af3be70a38 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS = \
 	database.o \
 	detection.o \
 	graphics.o \
+	sound.o \
 	window.o
 
 
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
new file mode 100644
index 0000000000..3eaffed257
--- /dev/null
+++ b/engines/buried/resources.h
@@ -0,0 +1,341 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_RESOURCES_H
+#define BURIED_RESOURCES_H
+
+namespace Buried {
+
+#define IDS_MOVEMENT_DATA_BASE_ID		800
+
+#define IDBD_DIARY1						900
+#define IDBD_DIARY2						901
+
+#define IDBD_BC_VIEW_DATA				902
+
+#define IDBD_LETTERS_BOOK_DATA			903
+
+#define IDBD_DIARY1_TRANS_TEXT_BASE		1000
+#define IDBD_DIARY2_TRANS_TEXT_BASE		1100
+#define IDBD_DIARY3_TRANS_TEXT_BASE		1250
+
+#define IDBD_BLETTER_NUM_LINES_TEXT		1300
+#define IDBD_BLETTER_TRANS_TEXT_BASE	1301
+
+#define IDMYTP_WHEELS_LEFT_TRANS_TEXT_BASE		1400
+#define IDMYTP_WHEELS_RIGHT_TRANS_TEXT_BASE		1450
+#define IDMYTP_WALLS_COMBO_TRANS_TEXT_BASE		1500
+
+#define IDMYTP_INNER_DOOR_TRANS_TEXT			1550
+#define IDMYTP_INNER_LEFT_TRANS_TEXT			1551
+#define IDMYTP_INNER_MIDDLE_TRANS_TEXT			1552
+
+#define IDMYTP_OUTER_SOUTHLEFT_TRANS_TEXT		1553
+#define IDMYTP_OUTER_WEST_TRANS_TEXT			1554
+#define IDMYTP_OUTER_NORTH_TRANS_TEXT			1555
+
+#define IDMYMC_WG_DOOR_TOP_TRANS_TEXT			1556
+#define IDMYMC_WG_DOOR_RIGHT_TRANS_TEXT			1557
+
+#define IDMYMC_WATERGOD_DOOR_TOP_TRANS_TEXT		1558
+#define IDMYMC_WATERGOD_DOOR_RIGHT_TRANS_TEXT	1559
+
+#define IDMYMC_AG_DOOR_TOP_TRANS_TEXT			1560
+#define IDMYMC_AG_DOOR_RIGHT_TRANS_TEXT			1561
+
+#define IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT		1562
+#define IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT	1563
+
+#define IDDS_ELEVATOR_CONTROLS_TEXT_A			1570
+#define IDDS_ELEVATOR_CONTROLS_TEXT_B			1571
+#define IDDS_ELEVATOR_CONTROLS_TEXT_C			1572
+#define IDDS_ELEVATOR_CONTROLS_TEXT_D			1573
+#define IDDS_WORKSHOP_TOOLS_TEXT				1574
+
+#define IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE		1600
+
+
+#define IDFAKI_SN_CHEESE_GIRL_CODE_TEXT			1650
+#define IDFAKI_SN_CHEESE_GIRL_CODE_TITLE		1651
+#define IDFAKI_SN_CHEESE_GIRL_ORDER_TEXT		1652
+
+#define IDFAKI_SN_TRANSLATE_CHIP_CODE_TEXT		1653
+#define IDFAKI_SN_TRANSLATE_CHIP_CODE_TITLE		1654
+#define IDFAKI_SN_TRANSLATE_CHIP_ORDER_TEXT		1655
+
+#define IDFAKI_SN_GENO_SINGLE_CODE_TEXT			1656
+#define IDFAKI_SN_GENO_SINGLE_CODE_TITLE		1657
+#define IDFAKI_SN_GENO_SINGLE_ORDER_TEXT		1658
+
+#define IDFAKI_SN_SUCCESSFUL_ORDER_TEXT			1659
+#define IDFAKI_SN_UNSUCCESSFUL_ORDER_TEXT		1660
+
+#define IDFAKI_AC_ORDER_FOOD_TEXT				1670
+
+#define IDS_MBT_EVIDENCE_PRESENT				1700
+#define IDS_MBT_EVIDENCE_ACQUIRED				1701
+#define IDS_MBT_EVIDENCE_ALREADY_ACQUIRED		1702
+#define IDS_MBT_EVIDENCE_MUST_BE_REVEALED		1703
+#define IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED		1704
+#define IDS_MBT_EVIDENCE_NONE_ACQUIRED			1705
+
+#define IDS_MBT_JUMP_LOCKOUT_TEXT               1706
+
+#define IDS_SAVE_GAME_MESSAGE					1710
+#define IDS_SEE_DOLL_MESSAGE_A					1711
+#define IDS_SEE_DOLL_MESSAGE_B					1712
+#define IDS_SEE_DOLL_MESSAGE_C					1713
+#define IDS_WM_AI_LAB_TEXT						1714
+
+#define IDS_LENS_FILTER_ACTIVATED				1720
+#define IDS_LENS_FILTER_DEACTIVATED				1721
+
+#define IDS_JUMP_BC_REVIEW_MISSION_TEXT_A		1722
+#define IDS_JUMP_BC_REVIEW_MISSION_TEXT_B		1723
+#define IDS_JUMP_BC_REVIEW_MISSION_TEXT_C		1724
+#define IDS_JUMP_BC_REVIEW_MISSION_TEXT_D		1725
+
+#define IDS_LENS_FILTER_ATTACHED				1730
+#define IDS_LENS_FILTER_REMOVED                 1731
+#define IDS_LENS_FILTER_DENY_REMOVAL            1732
+
+#define IDS_CLOAK_BIOCHIP_ACTIVATE              1733
+#define IDS_CLOAK_BIOCHIP_AUTO_ACTIVATE         1734
+#define IDS_CLOAK_BIOCHIP_DEACTIVATE            1735
+
+#define IDS_JUMPSUIT_LIGHT_TURN_ON_MESSAGE      1736
+
+#define IDS_HUMAN_PRESENCE_3METERS				1737
+
+#define IDS_DS_WS_UNSTABLE_CYCLE_MESSAGE        1738
+
+#define IDS_DS_WS_CYCLE_PLANS_TEXT_A            1739
+#define IDS_DS_WS_CYCLE_PLANS_TEXT_B            1740
+#define IDS_DS_WS_CYCLE_PLANS_TEXT_C            1741
+
+#define IDS_AI_ENTERING_PRES_ENV_TEXT           1742
+
+#define IDS_HUMAN_PRESENCE_10METERS             1743
+#define IDS_HUMAN_PRESENCE_500METERS            1744
+
+#define IDS_AI_IC_REFILL_OXYGEN_RESERVE         1745
+
+#define IDS_MY_AG_ALTAR_TEXT                    1746
+#define IDS_MY_WT_ALTAR_TEXT                    1747
+#define IDS_MY_WG_ALTAR_TEXT                    1748
+
+#define IDS_AI_ENTERING_NON_PRES_ENV_TEXT       1749
+
+#define IDS_AS_RA_BEINGS_DETECTED_20_METERS     1750
+#define IDS_AS_RA_BEINGS_DETECTED_5_METERS      1751
+
+#define IDS_AS_RA_POD_A_STATUS_TEXT             1752
+#define IDS_AS_RA_POD_B_STATUS_TEXT             1753
+#define IDS_AS_RA_POD_C_STATUS_TEXT             1754
+
+#define IDS_AI_IS_JUMP_IN_TEXT                  1755
+
+
+#define IDS_DEATH_SCENE_MESSAGE_TEXT_BASE		1800
+#define IDS_DEATH_SCENE_CAUSE_TEXT_BASE			1801
+
+
+#define IDS_AI_PRES_PANEL_DESC_BASE				5000
+
+#define IDS_AI_PRES_PANEL_ENV_PRES_TEXT			5020
+#define IDS_AI_PRES_PANEL_PRES_ENV_TEXT			5021
+#define IDS_AI_PRES_PANEL_ZERO_PRES_ENV			5022
+#define IDS_AI_PRES_PANEL_ENV_DEPRES			5023
+#define IDS_AI_PRES_PANEL_INSUF_OXYGEN			5024
+#define IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH		5025
+#define IDS_AI_PRES_PANEL_ENV_DEPRES_OBST		5026
+
+#define IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM		5027
+#define IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW		5028
+
+#define IDS_UNABLE_TO_TRANSLATE_TEXT            5029
+
+#define IDS_EC_DESC_TEXT_A                      5050
+#define IDS_EC_DESC_TEXT_B                      5051
+#define IDS_EC_DESC_TEXT_C                      5052
+#define IDS_EC_DESC_TEXT_D                      5053
+#define IDS_EC_DESC_TEXT_E                      5054
+#define IDS_EC_DESC_TEXT_F                      5055
+#define IDS_EC_DESC_TEXT_G                      5056
+#define IDS_EC_DESC_TEXT_H                      5057
+#define IDS_EC_DESC_TEXT_I                      5058
+#define IDS_EC_DESC_TEXT_J                      5059
+#define IDS_EC_DESC_TEXT_K                      5060
+
+
+
+#define IDB_UI_TOP                      12288
+#define IDB_UI_LEFT                     12289
+#define IDB_UI_RIGHT                    12290
+#define IDB_UI_BOTTOM                   12291
+#define IDB_INVENTORY_BACKGROUND        12292
+#define IDB_INVENTORY_ARROWS            12293
+#define IDB_INVENTORY_INFO_BACKGROUND   12294
+#define IDB_LIVE_TEXT_BACKGROUND        12295
+#define IDB_ARROW_BACKGROUND            12296
+#define IDB_ARROW_UP_CLEAR              12297
+#define IDB_ARROW_UP_LIT                12298
+#define IDB_ARROW_UP_HIGHLIGHTED        12299
+#define IDB_ARROW_LEFT_CLEAR            12300
+#define IDB_ARROW_LEFT_LIT              12301
+#define IDB_ARROW_LEFT_HIGHLIGHTED      12302
+#define IDB_ARROW_DOWN_CLEAR            12303
+#define IDB_ARROW_DOWN_LIT              12304
+#define IDB_ARROW_DOWN_HIGHLIGHTED      12305
+#define IDB_ARROW_RIGHT_CLEAR           12306
+#define IDB_ARROW_RIGHT_LIT             12307
+#define IDB_ARROW_RIGHT_HIGHLIGHTED     12308
+#define IDB_ARROW_FORWARD_CLEAR         12309
+#define IDB_ARROW_FORWARD_LIT           12310
+#define IDB_ARROW_FORWARD_HIGHLIGHTED   12311
+
+#define IDB_UI_WARNING_LIGHT			12315
+
+#define IDB_UI_DATE_BASE				12320
+
+#define IDB_MAINMENU_NORMAL				12348
+#define IDB_MAINMENU_DEPRESSED_OVERVIEW			12349
+#define IDB_MAINMENU_DEPRESSED_NEW_GAME			12350
+#define IDB_MAINMENU_DEPRESSED_PLAY_MODE		12351
+#define IDB_MAINMENU_DEPRESSED_PLAY_INRO		12352
+#define IDB_MAINMENU_DEPRESSED_RESTORE_GAME		12353
+#define IDB_MAINMENU_DEPRESSED_CREDITS			12354
+#define IDB_MAINMENU_DEPRESSED_QUIT			12355
+
+#define IDB_DISK_SWAP_DIB_BASE			12360
+
+#define IDB_DEATH_UI_TOP				12400
+#define IDB_DEATH_UI_LEFT				12401
+#define IDB_DEATH_UI_RIGHT				12402
+#define IDB_DEATH_UI_BOTTOM				12403
+
+#define IDB_DEATH_ELIGHT_ON				12404
+#define IDB_DEATH_BUTTONS_NORMAL		12405
+#define IDB_DEATH_BUTTONS_DEPRESSED		12406
+
+#define IDB_BCV_INTERFACE_MAIN			12410
+#define IDB_BCV_INTERFACE_HANDLE		12411
+#define IDB_BCV_INTERFACE_CHECK         12412
+
+#define IDB_DEATH_WT_LOWER_LEFT         12413
+#define IDB_DEATH_WT_BUTTONS_NORMAL     12414
+#define IDB_DEATH_WT_BUTTONS_DEPRESSED  12415
+
+#define IDB_BCR_BITMAP_BASE				12450
+
+
+#define IDB_PICON_BITMAP_BASE			12800
+#define IDB_DRAG_BITMAP_BASE			12900
+#define IDER_NAV_DB_BASE                16384
+#define IDER_SOUND_DB_BASE              16640
+#define IDER_ANIM_DB_BASE               16896
+#define IDER_AI_DB_BASE					17152
+
+#define IDER_ITEM_DB					4096
+
+#define IDS_BC_RIGHT_FILENAME			6144
+#define IDS_BC_MISC_VIEW_FILENAME		6145
+#define IDS_BC_JUMP_VIEW_FILENAME		6146
+#define IDS_BC_FILES_VIEW_FILENAME		6147
+#define IDS_BC_EVIDENCE_VIEW_FILENAME	6148
+#define IDS_BC_EVIDENCE_ITEMS_FILENAME	6149
+#define IDS_BC_CLOAKING_MOVIE_FILENAME	6150
+#define IDS_BC_CLOAKING_SOUND_FILENAME  6151
+#define IDS_BC_JUMP_MOVIE_FILENAME		6152
+#define IDS_INVENTORY_SPIN_FILENAME		6153
+#define IDS_INVENTORY_DRAG_FILENAME		6154
+#define IDS_DEATH_CASTLE_FILENAME		6155
+#define IDS_DEATH_MAYAN_FILENAME		6156
+#define IDS_DEATH_AGENTLAIR_FILENAME	6157
+#define IDS_DEATH_DAVINCI_FILENAME		6158
+#define IDS_DEATH_AILAB_FILENAME		6159
+#define IDS_DEATH_ALIEN_FILENAME		6160
+#define IDS_DEATH_FINALE_FILENAME		6161
+
+#define IDS_BC_JUMP_VIEW_NAV_DATA		6162
+#define IDS_INVITEM_LETTER_FILENAME		6163
+
+#define IDS_TITLE_STARFIELD_FILENAME	6164
+#define IDS_TITLE_MOVIE_FILENAME		6165
+
+#define IDS_TITLE_PRESTO_LOGO_FILENAME	6166
+#define IDS_TITLE_SW_LOGO_FILENAME	    6167
+
+#define IDS_FUTAPT_BOOK_AUDIO_FILENAME	6170
+
+#define IDS_MAYAN_JUMP_MOVIE_FILENAME	6171
+#define IDS_CASTLE_JUMP_MOVIE_FILENAME	6172
+#define IDS_DAVINCI_JUMP_MOVIE_FILENAME 6173
+#define IDS_AILAB_JUMP_MOVIE_FILENAME	6174
+#define IDS_FUTAPT_JUMP_MOVIE_FILENAME	6175
+#define IDS_BC_JUMP_AUDIO_FILENAME		6176
+#define IDS_AGENT3_VIRUS_SOUND_BASE		6180
+
+#define IDS_AGENT3_VIRUS_TEXT_A			6190
+#define IDS_AGENT3_VIRUS_TEXT_B			6191
+#define IDS_AGENT3_VIRUS_TEXT_C			6192
+#define IDS_AGENT3_VIRUS_TEXT_D			6193
+#define IDS_AGENT3_VIRUS_PASSWORD		6194
+#define IDS_AGENT3_VIRUS_CURSOR			6195
+#define IDS_FUTAPT_ENVIRON_DOOR_CLOSE	6196
+#define IDS_AGENT3_VIRUS_PW_ACCEPTED    6197
+
+#define IDS_FOOTSTEPS_FILENAME_BASE		6200
+
+#define IDS_INN_STILL_FRAME_FILENAME	6300
+#define IDBD_INN_BINARY_DATA			6301
+#define IDBD_INN_MEDIA_BINARY_DATA		6302
+#define IDS_INN_AMBIENT_FILENAME		6309
+#define IDS_INN_MEDIA_FILENAME_BASE		6310
+
+#define IDS_IF_OV_FULL_SCREEN_DIB		6400
+#define IDS_IF_OV_BIOCHIPS_DIB			6401
+#define IDS_IF_OV_INVENTORY_DIB			6402
+#define IDS_IF_OV_MESSAGE_BOX_DIB		6403
+#define IDS_IF_OV_NAV_ARROWS_DIB		6404
+#define IDS_IF_OV_NAV_ARROWS_AUDIO		6410
+#define IDS_IF_OV_INVENTORY_AUDIO		6411
+#define IDS_IF_OV_BIOCHIPS_AUDIO		6412
+#define IDS_IF_OV_MESSAGE_BOX_AUDIO		6413
+#define IDS_IF_OV_FURTHER_INFO_AUDIO	6414
+
+#define IDS_CREDITS_MAIN_FILENAME		6420
+#define IDS_CREDITS_HIGHLIGHT_FILENAME	6421
+#define IDS_CREDITS_MOVIE_FILENAME		6422
+
+#define IDES_ITEM_TITLE_BASE			8192
+#define IDES_ITEM_DESC_BASE				8256
+
+#define IDES_FILENAME_BASE              17408
+#define IDES_STRING_BASE                21504
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
new file mode 100644
index 0000000000..fe97f109ab
--- /dev/null
+++ b/engines/buried/sound.cpp
@@ -0,0 +1,755 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "audio/audiostream.h"
+#include "audio/mixer.h"
+#include "audio/decoders/wave.h"
+#include "common/archive.h"
+#include "common/events.h"
+#include "common/system.h"
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+
+namespace Buried {
+
+#define TIMED_EFFECT_NONE   0x00
+#define TIMED_EFFECT_VOLUME 0x01
+
+#define SOUND_FLAG_DESTROY_AFTER_COMPLETION 0x01
+
+SoundManager::SoundManager(BuriedEngine *vm) : _vm(vm) {
+	_fileIDFootsteps = -1;
+	_lastAmbient = 1;
+	startup();
+}
+
+SoundManager::~SoundManager() {
+	for (int i = 0; i < kMaxSounds; i++)
+		delete _soundData[i];
+}
+
+bool SoundManager::startup() {
+	_paused = false;
+
+	for (int i = 0; i < kMaxSounds; i++)
+		_soundData[i] = new Sound();
+
+	return true;
+}
+
+void SoundManager::shutDown() {
+	if (_paused)
+		return;
+
+	for (int i = 0; i < kMaxSounds; i++) {
+		delete _soundData[i];
+		_soundData[i] = new Sound();
+	}
+}
+
+bool SoundManager::setAmbientSound(const Common::String &fileName, bool fade, byte finalVolumeLevel) {
+	// Determine which of the two ambient tracks to use
+	int newAmbientTrack = (_lastAmbient == 0) ? 1 : 0;
+
+	// If this ambient track is currently in use, stop and kill it now
+	if (_soundData[kAmbientIndexBase + newAmbientTrack]->isPlaying()) {
+		delete _soundData[kAmbientIndexBase + newAmbientTrack];
+		_soundData[kAmbientIndexBase + newAmbientTrack] = new Sound();
+	}
+
+	bool retVal = true;
+
+	if (fileName.empty()) {
+		if (fade) {
+			// Set parameters for the current ambient, if there is one
+			if (_soundData[kAmbientIndexBase + _lastAmbient]->isPlaying()) {
+				_soundData[kAmbientIndexBase + _lastAmbient]->_loop = true;
+				_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+				_soundData[kAmbientIndexBase + _lastAmbient]->_flags = SOUND_FLAG_DESTROY_AFTER_COMPLETION;
+				_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectSteps = 16;
+				_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectDelta = -(_soundData[kAmbientIndexBase + _lastAmbient]->_volume / 16);
+				_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectStart = g_system->getMillis();
+				_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectRemaining = 2000;
+
+				// Reset parameters for current ambient
+				g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle, _soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1);
+				// clone2727: The original resets the loop count, but I don't think that's necessary
+			}
+		} else {
+			// Stop the current ambient
+			delete _soundData[kAmbientIndexBase + _lastAmbient];
+			_soundData[kAmbientIndexBase + _lastAmbient] = new Sound();
+		}
+		return true;
+	}
+
+	if (fade) {
+		// Set parameters for the current ambient, if there is one
+		if (_soundData[kAmbientIndexBase + _lastAmbient]->_handle) {
+			_soundData[kAmbientIndexBase + _lastAmbient]->_loop = true;
+			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+			_soundData[kAmbientIndexBase + _lastAmbient]->_flags = SOUND_FLAG_DESTROY_AFTER_COMPLETION;
+			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectSteps = 16;
+			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectDelta = -(_soundData[kAmbientIndexBase + _lastAmbient]->_volume / 16);
+			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectStart = g_system->getMillis();
+			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectRemaining = 2000;
+	
+			// Reset parameters for the current ambient
+			g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle,
+					_soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1);
+		}
+
+		// Load the new ambient
+		if (_soundData[kAmbientIndexBase + _lastAmbient]->load(fileName)) {
+			// Set the parameters of the new ambient
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_volume = 0;
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_loop = true;
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_flags = 0;
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectSteps = 16;
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectDelta = finalVolumeLevel / 16;
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectStart = g_system->getMillis();
+			_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectRemaining = 2000;
+
+			// Start the new ambient
+			retVal = _soundData[kAmbientIndexBase + newAmbientTrack]->start();
+		}
+	} else {
+		// Load the new ambient
+		if (!fileName.empty()) {
+			if (_soundData[kAmbientIndexBase + newAmbientTrack]->load(fileName)) {
+				// Set some parameters
+				_soundData[kAmbientIndexBase + newAmbientTrack]->_volume = finalVolumeLevel;
+				_soundData[kAmbientIndexBase + newAmbientTrack]->_loop = true;
+
+				// Stop the current ambient
+				delete _soundData[kAmbientIndexBase + _lastAmbient];
+				_soundData[kAmbientIndexBase + _lastAmbient] = new Sound();
+
+				// Start the new ambient
+				retVal = _soundData[kAmbientIndexBase + newAmbientTrack]->start();
+			}
+		} else {
+			// Stop the current ambient
+			delete _soundData[kAmbientIndexBase + _lastAmbient];
+			_soundData[kAmbientIndexBase + _lastAmbient] = new Sound();
+		}
+	}
+
+	// Reset the last ambient index
+	_lastAmbient = newAmbientTrack;
+
+	// Return success
+	return retVal;
+}
+
+bool SoundManager::adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength) {
+	// If we are not playing an ambient track, simply return false
+	if (!_soundData[kAmbientIndexBase + _lastAmbient]->_handle)
+		return false;
+
+	// Compare the new volume level to the current one, returning success if they are the same
+	if (_soundData[kAmbientIndexBase + _lastAmbient]->_volume == newVolumeLevel)
+		return true;
+
+	// If we already have any timed channels in the current ambient channel, kill them now
+	if (_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectIndex != TIMED_EFFECT_NONE) {
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectIndex = TIMED_EFFECT_NONE;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_flags = 0; // clone2727 says: is this right?
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectSteps = 0;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectDelta = 0;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectStart = 0;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectRemaining = 0;
+	}
+
+	// Switch on whether or not we are fading to the new volume level
+	if (fade) {
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectSteps = steps;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectDelta =
+				((int)newVolumeLevel - (int)_soundData[kAmbientIndexBase + _lastAmbient]->_volume) / (int)steps;
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectStart = g_system->getMillis();
+		_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectRemaining = fadeLength;
+	} else {
+		// We are not fading between the current and new volume levels, so simply change the level
+		// and reset the volume for the sample
+		_soundData[kAmbientIndexBase + _lastAmbient]->_volume = newVolumeLevel;
+		g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle,
+				newVolumeLevel << 1);
+	}
+
+	// Return success
+	return true;
+}
+
+bool SoundManager::setSecondaryAmbientSound(const Common::String &fileName, bool fade, byte finalVolumeLevel) {
+	if (fileName.empty())
+		return false;
+
+	// Determine which of the two ambient tracks to use
+	int newAmbientTrack = (_lastAmbient == 0) ? 1 : 0;
+
+	// If this ambient track is currently in use, stop and kill it now
+	if (_soundData[kAmbientIndexBase + newAmbientTrack]->_handle) {
+		delete _soundData[kAmbientIndexBase + newAmbientTrack];
+		_soundData[kAmbientIndexBase + newAmbientTrack] = new Sound();
+	}
+
+	// Are we flagged for fade?
+	if (fade) {
+		// Load the new ambient
+		if (!_soundData[kAmbientIndexBase + newAmbientTrack]->load(fileName))
+			return false;
+
+		// Set the parameters for the new ambient
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_volume = 0;
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_loop = true;
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_flags = 0;
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectSteps = 16;
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectDelta = finalVolumeLevel / 16;
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectStart = g_system->getMillis();
+		_soundData[kAmbientIndexBase + newAmbientTrack]->_timedEffectRemaining = 2000;
+
+		// Start the new ambient
+		return _soundData[kAmbientIndexBase + newAmbientTrack]->start();
+	}
+
+	// Load the new ambient
+	if (!_soundData[kAmbientIndexBase + newAmbientTrack]->load(fileName))
+		return false;
+
+	// Set some parameters
+	_soundData[kAmbientIndexBase + newAmbientTrack]->_volume = finalVolumeLevel;
+	_soundData[kAmbientIndexBase + newAmbientTrack]->_loop = true;
+
+	// Start the new ambient
+	return _soundData[kAmbientIndexBase + newAmbientTrack]->start();
+}
+
+bool SoundManager::adjustSecondaryAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength) {
+	// Determine which of the two ambient tracks to modify
+	int ambientTrack = (_lastAmbient == 0) ? 1 : 0;
+
+	// If we are not playing an ambient track, simply return false
+	if (!_soundData[kAmbientIndexBase + ambientTrack]->_handle)
+		return false;
+
+	// Compare the new volume level to the current one, returning success if they are the same
+	if (_soundData[kAmbientIndexBase + ambientTrack]->_volume == newVolumeLevel)
+		return true;
+
+	// If we already have any timed channels in the current ambient channel, kill them now
+	if (_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectIndex != TIMED_EFFECT_NONE) {
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectIndex = TIMED_EFFECT_NONE;
+		_soundData[kAmbientIndexBase + ambientTrack]->_flags = 0; // clone2727 says: is this right?
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectSteps = 0;
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectDelta = 0;
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectStart = 0;
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectRemaining = 0;
+	}
+
+	// Switch on whether or not we are fading to the new volume level
+	if (fade) {
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectSteps = steps;
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectDelta =
+				((int)newVolumeLevel - (int)_soundData[kAmbientIndexBase + ambientTrack]->_volume) / (int)steps;
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectStart = g_system->getMillis();
+		_soundData[kAmbientIndexBase + ambientTrack]->_timedEffectRemaining = fadeLength;
+	} else {
+		// We are not fading between the current and new volume levels, so simply change the level
+		// and reset the volume for the sample
+		_soundData[kAmbientIndexBase + ambientTrack]->_volume = newVolumeLevel;
+		g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + ambientTrack]->_handle,
+				newVolumeLevel << 1);
+	}
+
+	// Return success
+	return true;
+}
+
+uint32 SoundManager::getSecondaryAmbientPosition() {
+	int ambientTrack = (_lastAmbient == 0) ? 1 : 0;
+
+	if (!_soundData[kAmbientIndexBase + ambientTrack]->isPlaying())
+		return 0;
+
+	// We need to return the position in *bytes* in the buffer here
+	// So, let's work some magic with this
+	Audio::Timestamp time = g_system->getMixer()->getElapsedTime(*_soundData[kAmbientIndexBase + ambientTrack]->_handle);
+
+	// Convert to the sound rate before getting to the magic.
+	time = time.convertToFramerate(_soundData[kAmbientIndexBase + ambientTrack]->_soundData->getRate());
+
+	// Here's the magic. We're assuming everything is 8-bit, mono.
+	return time.totalNumberOfFrames();
+}
+		
+bool SoundManager::restartSecondaryAmbientSound() {
+	int ambientTrack = (_lastAmbient == 0) ? 1 : 0;
+
+	if (!_soundData[kAmbientIndexBase + ambientTrack]->isPlaying())
+		return 0;
+
+	_soundData[kAmbientIndexBase + ambientTrack]->start();
+	return true;
+}
+
+bool SoundManager::playSynchronousAIComment(const Common::String &fileName) {
+	if (_paused)
+		return false;
+
+	// Load the sound file
+	if (!_soundData[kAIVoiceIndex]->load(fileName))
+		return false;
+
+	// Play the file
+	bool retVal = _soundData[kAIVoiceIndex]->start();
+
+	while (retVal && !_vm->shouldQuit() && _soundData[kAIVoiceIndex]->isPlaying()) {
+		timerCallback();
+
+		Common::Event event;
+		while (g_system->getEventManager()->pollEvent(event))
+			if (event.type == Common::EVENT_MOUSEMOVE)
+				g_system->updateScreen();
+
+		g_system->delayMillis(10);
+	}
+
+	// Now that is has been played, kill it here and now
+	delete _soundData[kAIVoiceIndex];
+	_soundData[kAIVoiceIndex] = new Sound();
+
+	// Return success
+	return true;
+}
+
+bool SoundManager::playAsynchronousAIComment(const Common::String &fileName) {
+	if (_paused)
+		return false;
+
+	// Load the sound file
+	if (!_soundData[kAIVoiceIndex]->load(fileName))
+		return false;
+
+	// Set some parameters
+	_soundData[kAIVoiceIndex]->_flags = SOUND_FLAG_DESTROY_AFTER_COMPLETION;
+	_soundData[kAIVoiceIndex]->_volume = 127;
+
+	// Play the file
+	return _soundData[kAIVoiceIndex]->start();
+}
+
+bool SoundManager::isAsynchronousAICommentPlaying() {
+	if (_paused)
+		return false;
+
+	return _soundData[kAIVoiceIndex]->isPlaying();
+}
+
+int SoundManager::playSoundEffect(const Common::String &fileName, int volume, bool loop, bool oneShot) {
+	if (fileName.empty())
+		return -1;
+
+	if (_paused)
+		return -1;
+
+	// Make sure that we have a free sound effect channel
+	int effectChannel = -1;
+	if (!_soundData[kEffectsIndexB]->_handle)
+		effectChannel = 1;
+	if (!_soundData[kEffectsIndexA]->_handle)
+		effectChannel = 0;
+	if (effectChannel == -1)
+		return -1;
+
+	// Reinitialize the structure
+	delete _soundData[kEffectsIndexBase + effectChannel];
+	_soundData[kEffectsIndexBase + effectChannel] = new Sound();
+
+	// Load the sound file
+	if (!_soundData[kEffectsIndexBase + effectChannel]->load(fileName))
+		return -1;
+
+	// Set some parameters
+	_soundData[kEffectsIndexBase + effectChannel]->_volume = volume;
+	_soundData[kEffectsIndexBase + effectChannel]->_loop = loop;
+	if (oneShot)
+		_soundData[kEffectsIndexBase + effectChannel]->_flags = SOUND_FLAG_DESTROY_AFTER_COMPLETION;
+
+	// Play the file
+	_soundData[kEffectsIndexBase + effectChannel]->start();
+
+	// Return the index of the channel used
+	return effectChannel;
+}
+
+bool SoundManager::playSynchronousSoundEffect(const Common::String &fileName, int volume) {
+	// Reset the cursor
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	g_system->updateScreen();
+
+	// Attempt to start the sound playing using the standard sound effect playback function
+	int soundChannel = playSoundEffect(fileName, volume, false, true);
+
+	// If the sound channel passed to us was invalid, return false right now
+	if (soundChannel < 0)
+		return false;
+
+	// Otherwise, assume the sound has started playing and enter a wait and see loop until
+	// the sound finishes playing
+	do {
+		timerCallback();
+
+		Common::Event event;
+		while (g_system->getEventManager()->pollEvent(event))
+			if (event.type == Common::EVENT_MOUSEMOVE)
+				g_system->updateScreen();
+
+		g_system->delayMillis(10);
+	} while (!_vm->shouldQuit() && isSoundEffectPlaying(soundChannel));
+
+	// One last callback check
+	timerCallback();
+
+	// Reset the cursor
+	_vm->_gfx->setCursor(oldCursor);
+	g_system->updateScreen();
+
+	// Return success
+	return true;
+}
+
+bool SoundManager::stopSoundEffect(int effectID) {
+	if (_paused)
+		return false;
+
+	// Confirm that we have a valid sound effect channel
+	if (effectID < 0 || effectID > 1)
+		return false;
+
+	// Return the result
+	return _soundData[kEffectsIndexBase + effectID]->stop();
+}
+
+bool SoundManager::isSoundEffectPlaying(int effectID) {
+	if (_paused)
+		return false;
+
+	// Confirm that we have a valid sound effect channel
+	if (effectID < 0 || effectID > 1)
+		return false;
+
+	// Return the result
+	return _soundData[kEffectsIndexBase + effectID]->isPlaying();
+}
+
+bool SoundManager::adjustSoundEffectSoundVolume(int effectID, byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength) {
+	// Confirm that we have a valid sound effect channel
+	if (effectID < 0 || effectID > 1)
+		return false;
+
+	// If the effect is not playing, then stop it now
+	if (!_soundData[kEffectsIndexBase + effectID]->isPlaying())
+		return false;
+
+	// Compare the new volume level to the current one, returning success if they are the same
+	if (_soundData[kEffectsIndexBase + effectID]->_volume == newVolumeLevel)
+		return true;
+
+	// If we already have any timed channels in the current effect channel, kill them now
+	if (_soundData[kEffectsIndexBase + effectID]->_timedEffectIndex != TIMED_EFFECT_NONE) {
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectIndex = TIMED_EFFECT_NONE;
+		_soundData[kEffectsIndexBase + effectID]->_flags = 0; // clone2727 says: is this right?
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectSteps = 0;
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectDelta = 0;
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectStart = 0;
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectRemaining = 0;
+	}
+
+	// Switch on whether or not we are fading to the new volume level
+	if (fade) {
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectIndex = TIMED_EFFECT_VOLUME;
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectSteps = steps;
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectDelta =
+				((int)newVolumeLevel - (int)_soundData[kEffectsIndexBase + effectID]->_volume) / (int)steps;
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectStart = g_system->getMillis();
+		_soundData[kEffectsIndexBase + effectID]->_timedEffectRemaining = fadeLength;
+	} else {
+		// We are not fading between the current and new volume levels, so simply change the level
+		// and reset the volume for the sample
+		_soundData[kEffectsIndexBase + effectID]->_volume = newVolumeLevel;
+		g_system->getMixer()->setChannelVolume(*_soundData[kEffectsIndexBase + effectID]->_handle,
+				newVolumeLevel << 1);
+	}
+
+	// Return success
+	return true;
+}
+	
+bool SoundManager::playInterfaceSound(const Common::String &fileName) {
+	if (_paused)
+		return false;
+
+	// If we have a sound playing, stop and destroy it
+	if (_soundData[kInterfaceIndex]->_handle) {
+		delete _soundData[kInterfaceIndex];
+		_soundData[kInterfaceIndex] = new Sound();
+	}
+
+	// Load the sound file
+	if (!_soundData[kInterfaceIndex]->load(fileName))
+		return false;
+
+	_soundData[kInterfaceIndex]->_flags = SOUND_FLAG_DESTROY_AFTER_COMPLETION;
+
+	// Play the file
+	return _soundData[kInterfaceIndex]->start();
+}
+
+bool SoundManager::stopInterfaceSound() {
+	if (_paused)
+		return false;
+			
+	// Stop the sound
+	delete _soundData[kInterfaceIndex];
+	_soundData[kInterfaceIndex] = new Sound();
+	return true;
+}
+
+bool SoundManager::isInterfaceSoundPlaying() {
+	if (_paused)
+		return false;
+
+	return _soundData[kInterfaceIndex]->isPlaying();
+}
+
+bool SoundManager::startFootsteps(int footstepsID) {
+	if (_paused)
+		return false;
+
+	// Check the passed ID
+	if (footstepsID < 0)
+		return false;
+
+	// Compare the ID against the current ID
+	if (_fileIDFootsteps != footstepsID) {
+		// Swap the current footsteps ID
+		_fileIDFootsteps = footstepsID;
+
+		// Dispose and reinitialize the current footsteps sample
+		delete _soundData[kFootstepsIndex];
+		_soundData[kFootstepsIndex] = new Sound();
+
+		// Load the footsteps sample data and modify the internal flags
+		_soundData[kFootstepsIndex]->load(_vm->getFilePath(IDS_FOOTSTEPS_FILENAME_BASE + footstepsID));
+    	_soundData[kFootstepsIndex]->_loop = true;
+	}
+
+	// Play the footsteps
+	_soundData[kFootstepsIndex]->start();
+
+	// Return success
+	return true;
+}
+
+bool SoundManager::stopFootsteps() {
+	if (_paused)
+		return false;
+
+	// Make sure that if the footsteps are currently playing, they are stopped
+	_soundData[kFootstepsIndex]->stop();
+
+	// Return success
+	return true;
+}
+	
+bool SoundManager::stop() {
+	if (_paused)
+		return true;
+
+	// Stop any playing sounds, but keep them in memory
+	for (int i = 0; i < kMaxSounds; i++) {
+		if (_soundData[i]->stop()) {
+			if (i < 2) {
+				_soundData[i]->_wasPlaying = true;
+			} else {
+				delete _soundData[i];
+				_soundData[i] = new Sound();
+			}
+		}
+	}
+
+	_paused = true;
+	return true;
+}
+	
+bool SoundManager::restart() {
+	if (!_paused)
+		return true;
+
+	// Check all samples, and if they were playing, restart them now
+	for (int i = 0; i < kMaxSounds; i++) {
+		if (_soundData[i]->_wasPlaying) {
+			_soundData[i]->start();
+			_soundData[i]->_wasPlaying = false;
+		}
+	}
+
+	_paused = false;
+
+	// Return success
+	return true;
+}
+
+void SoundManager::timerCallback() {
+	if (_paused)
+		return;
+
+	// Check the playing sounds, and if they are playing, check for time-based effects
+	for (int i = 0; i < kMaxSounds; i++) {
+		if (_soundData[i]->_handle) {
+			if (_soundData[i]->_timedEffectIndex != TIMED_EFFECT_NONE) {
+				// Has the right amount of time passed for a change to be made?
+				if (g_system->getMillis() >= (_soundData[i]->_timedEffectStart + (_soundData[i]->_timedEffectRemaining / _soundData[i]->_timedEffectSteps))) {
+					// Change the specified member and notify the mixer of the change
+					if (_soundData[i]->_timedEffectIndex == TIMED_EFFECT_VOLUME) {
+						_soundData[i]->_volume += _soundData[i]->_timedEffectDelta;
+						g_system->getMixer()->setChannelVolume(*_soundData[i]->_handle, _soundData[i]->_volume << 1);
+					}
+
+					// Update the start time, step counter, and remaining time
+					_soundData[i]->_timedEffectRemaining -= (_soundData[i]->_timedEffectRemaining / _soundData[i]->_timedEffectSteps);
+	                _soundData[i]->_timedEffectStart = g_system->getMillis();
+	                _soundData[i]->_timedEffectSteps--;
+
+					// If the effect has finished, then remove the transition type
+					if (_soundData[i]->_timedEffectSteps == 0) {
+						// If we are flagged for destruction after completion, do it now
+						if (_soundData[i]->_flags & SOUND_FLAG_DESTROY_AFTER_COMPLETION) {
+							delete _soundData[i];
+							_soundData[i] = new Sound();
+						}
+	
+						// Reset effect data
+						_soundData[i]->_timedEffectIndex = TIMED_EFFECT_NONE;
+						_soundData[i]->_flags = 0;
+						_soundData[i]->_timedEffectSteps = 0;
+						_soundData[i]->_timedEffectDelta = 0;
+						_soundData[i]->_timedEffectStart = 0;
+						_soundData[i]->_timedEffectRemaining = 0;
+					}
+				}
+			} else {
+				// Even though we are not flagged for a timed effect, is this sound flagged for destruction?
+				if ((_soundData[i]->_flags & SOUND_FLAG_DESTROY_AFTER_COMPLETION) && !_soundData[i]->isPlaying()) {
+					delete _soundData[i];
+					_soundData[i] = new Sound();
+				}
+			}
+		}
+	}
+}
+
+SoundManager::Sound::Sound() {
+	_soundData = 0;
+	_handle = 0;
+
+	_volume = 127;
+	_loop = false;
+
+	_flags = 0;
+	_timedEffectIndex = TIMED_EFFECT_NONE;
+	_timedEffectSteps = 0;
+	_timedEffectDelta = 0;
+	_timedEffectStart = 0;
+	_timedEffectRemaining = 0;
+
+	_wasPlaying = false;
+}
+
+SoundManager::Sound::~Sound() {
+	stop();
+
+	delete _soundData;
+}
+
+bool SoundManager::Sound::load(const Common::String &fileName) {
+	if (fileName.empty())
+		return false;
+
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName);
+
+	if (!stream)
+		return false;
+
+	_soundData = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
+	return _soundData != 0;
+}
+
+bool SoundManager::Sound::start() {
+	if (!_soundData)
+		return false;
+
+	stop();
+
+	_handle = new Audio::SoundHandle();
+
+	Audio::AudioStream *audioStream = _soundData;
+	DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::NO;
+
+	_soundData->rewind();
+
+	if (_loop) {
+		audioStream = Audio::makeLoopingAudioStream(_soundData, 0);
+		disposeAfterUse = DisposeAfterUse::YES;
+	}
+
+	g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, audioStream,
+			-1, _volume << 1, 0, disposeAfterUse);
+
+	return true;
+}
+
+bool SoundManager::Sound::isPlaying() const {
+	return _soundData && _handle && g_system->getMixer()->isSoundHandleActive(*_handle);
+}
+
+bool SoundManager::Sound::stop() {
+	if (!isPlaying())
+		return false;
+
+	g_system->getMixer()->stopHandle(*_handle);
+	delete _handle;
+	_handle = 0;
+	return true;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/sound.h b/engines/buried/sound.h
new file mode 100644
index 0000000000..40f01e7c99
--- /dev/null
+++ b/engines/buried/sound.h
@@ -0,0 +1,148 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_SOUND_H
+#define BURIED_SOUND_H
+
+#include "common/str.h"
+
+namespace Audio {
+class RewindableAudioStream;
+class SoundHandle;
+}
+
+namespace Buried {
+
+class BuriedEngine;
+
+class SoundManager {
+public:
+	SoundManager(BuriedEngine *vm);
+	~SoundManager();
+
+	// STARTUP/SHUTDOWN FUNCTIONS
+	bool startup();
+	void shutDown();
+
+	// AMBIENT SOUND CHANNEL FUNCTIONS
+	bool setAmbientSound(const Common::String &fileName, bool fade = false, byte finalVolumeLevel = 64);
+	bool adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
+	uint32 getAmbientPosition();
+
+	bool setSecondaryAmbientSound(const Common::String &fileName, bool fade = false, byte finalVolumeLevel = 64);
+	bool adjustSecondaryAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
+	uint32 getSecondaryAmbientPosition();
+	bool restartSecondaryAmbientSound();
+
+	// AI SOUND CHANNEL FUNCTIONS
+	bool playSynchronousAIComment(const Common::String &fileName);
+	bool playAsynchronousAIComment(const Common::String &fileName);
+	bool isAsynchronousAICommentPlaying();
+
+	// SOUND EFFECTS FUNCTIONS
+	int playSoundEffect(const Common::String &fileName, int volume = 127, bool loop = false, bool oneShot = true);
+	bool playSynchronousSoundEffect(const Common::String &fileName, int volume = 127);
+	bool stopSoundEffect(int effectID);
+	bool isSoundEffectPlaying (int effectID);
+	bool adjustSoundEffectSoundVolume(int effectID, byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
+
+	// Interface sound functions
+	bool playInterfaceSound(const Common::String &fileName);
+	bool stopInterfaceSound();
+	bool isInterfaceSoundPlaying();
+
+	// START AND STOP SPECIFIED FOOTSTEPS SOUND
+	bool startFootsteps(int footstepsID);
+	bool stopFootsteps();
+
+	// PAUSE FUNCTIONS
+	bool stop();
+	bool restart();
+
+	// TIMER CALLBACK FUNCTION
+	void timerCallback();
+
+private:
+	enum {
+		kAmbientIndexBase = 0,
+		kAmbientIndexA = 0,
+		kAmbientIndexB = 1,
+
+		kEffectsIndexBase = 2,
+		kEffectsIndexA = 2,
+		kEffectsIndexB = 3,
+
+		kInterfaceIndex = 4,
+		kAIVoiceIndex = 5,
+		kFootstepsIndex = 6,
+
+		kMaxSounds = 7
+	};
+
+	class Sound {
+	friend class SoundManager;
+
+	public:
+		Sound();
+		~Sound();
+
+		bool load(const Common::String &fileName);
+		bool start();
+		bool isPlaying() const;
+		bool stop();
+
+	protected:
+		Audio::RewindableAudioStream *_soundData; // Stream to the data
+		Audio::SoundHandle *_handle;              // Handle
+
+		int32 _volume;                            // Volume of this sample
+		bool _loop;                               // Is this sample looping?
+		byte _flags;                              // Sound flags
+		byte _timedEffectIndex;                   // Timed effect index
+		int _timedEffectSteps;                    // Number of steps remaining in timed effect
+		int32 _timedEffectDelta;                  // Amount to change target value in each step
+		uint32 _timedEffectStart;                 // The last starting time for the timed effect
+		uint32 _timedEffectRemaining;             // The remaining amount of time for the effect
+
+		bool _wasPlaying;
+	};
+
+	BuriedEngine *_vm;
+
+	Sound *_soundData[kMaxSounds];
+
+	bool _paused;
+
+	int _fileIDFootsteps;
+	Common::String _ambientFileNames[2];
+	int _lastAmbient;
+	Common::String _effectsFileNames[2];
+	Common::String _interfaceFileName;
+	Common::String _arthurFileName;
+};
+
+} // End of namespace Buried
+
+#endif


Commit: faca37064b7c219f5badfc9948d5c2d4eb7e7a74
    https://github.com/scummvm/scummvm/commit/faca37064b7c219f5badfc9948d5c2d4eb7e7a74
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
AUDIO: Mark the wave code as being used by buried

Changed paths:
    audio/decoders/wave.h


diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h
index 75581f189b..2a73396e11 100644
--- a/audio/decoders/wave.h
+++ b/audio/decoders/wave.h
@@ -25,6 +25,7 @@
  * Sound decoder used in engines:
  *  - access
  *  - agos
+ *  - buried
  *  - cge
  *  - cge2
  *  - fullpipe


Commit: 27b938d47f34aea4b62e6899fde107a554aad176
    https://github.com/scummvm/scummvm/commit/27b938d47f34aea4b62e6899fde107a554aad176
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add the CP-1252 charset mapping

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index baf0a49d79..4caec93cf3 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -84,6 +84,79 @@ byte *GraphicsManager::getDefaultPalette() const {
 	return palette;
 }
 
+#define REQUIRED(x) (((uint32)(x)) | 0x80000000)
+#define NOT_REQUIRED(x) (x)
+
+static const uint32 s_codePage1252[256] = {
+	NOT_REQUIRED(0x0000), NOT_REQUIRED(0x0001), NOT_REQUIRED(0x0002), NOT_REQUIRED(0x0003),
+	NOT_REQUIRED(0x0004), NOT_REQUIRED(0x0005), NOT_REQUIRED(0x0006), NOT_REQUIRED(0x0007),
+	NOT_REQUIRED(0x0008), NOT_REQUIRED(0x0009), NOT_REQUIRED(0x000A), NOT_REQUIRED(0x000B),
+	NOT_REQUIRED(0x000C), NOT_REQUIRED(0x000D), NOT_REQUIRED(0x000E), NOT_REQUIRED(0x000F),
+	NOT_REQUIRED(0x0010), NOT_REQUIRED(0x0011), NOT_REQUIRED(0x0012), NOT_REQUIRED(0x0013),
+	NOT_REQUIRED(0x0014), NOT_REQUIRED(0x0015), NOT_REQUIRED(0x0016), NOT_REQUIRED(0x0017),
+	NOT_REQUIRED(0x0018), NOT_REQUIRED(0x0019), NOT_REQUIRED(0x001A), NOT_REQUIRED(0x001B),
+	NOT_REQUIRED(0x001C), NOT_REQUIRED(0x001D), NOT_REQUIRED(0x001E), NOT_REQUIRED(0x001F),
+	    REQUIRED(0x0020),     REQUIRED(0x0021),     REQUIRED(0x0022),     REQUIRED(0x0023),
+	    REQUIRED(0x0024),     REQUIRED(0x0025),     REQUIRED(0x0026),     REQUIRED(0x0027),
+	    REQUIRED(0x0028),     REQUIRED(0x0029),     REQUIRED(0x002A),     REQUIRED(0x002B),
+	    REQUIRED(0x002C),     REQUIRED(0x002D),     REQUIRED(0x002E),     REQUIRED(0x002F),
+	    REQUIRED(0x0030),     REQUIRED(0x0031),     REQUIRED(0x0032),     REQUIRED(0x0033),
+	    REQUIRED(0x0034),     REQUIRED(0x0035),     REQUIRED(0x0036),     REQUIRED(0x0037),
+	    REQUIRED(0x0038),     REQUIRED(0x0039),     REQUIRED(0x003A),     REQUIRED(0x003B),
+	    REQUIRED(0x003C),     REQUIRED(0x003D),     REQUIRED(0x003E),     REQUIRED(0x003F),
+	    REQUIRED(0x0040),     REQUIRED(0x0041),     REQUIRED(0x0042),     REQUIRED(0x0043),
+	    REQUIRED(0x0044),     REQUIRED(0x0045),     REQUIRED(0x0046),     REQUIRED(0x0047),
+	    REQUIRED(0x0048),     REQUIRED(0x0049),     REQUIRED(0x004A),     REQUIRED(0x004B),
+	    REQUIRED(0x004C),     REQUIRED(0x004D),     REQUIRED(0x004E),     REQUIRED(0x004F),
+	    REQUIRED(0x0050),     REQUIRED(0x0051),     REQUIRED(0x0052),     REQUIRED(0x0053),
+	    REQUIRED(0x0054),     REQUIRED(0x0055),     REQUIRED(0x0056),     REQUIRED(0x0057),
+	    REQUIRED(0x0058),     REQUIRED(0x0059),     REQUIRED(0x005A),     REQUIRED(0x005B),
+	    REQUIRED(0x005C),     REQUIRED(0x005D),     REQUIRED(0x005E),     REQUIRED(0x005F),
+	    REQUIRED(0x0060),     REQUIRED(0x0061),     REQUIRED(0x0062),     REQUIRED(0x0063),
+	    REQUIRED(0x0064),     REQUIRED(0x0065),     REQUIRED(0x0066),     REQUIRED(0x0067),
+	    REQUIRED(0x0068),     REQUIRED(0x0069),     REQUIRED(0x006A),     REQUIRED(0x006B),
+	    REQUIRED(0x006C),     REQUIRED(0x006D),     REQUIRED(0x006E),     REQUIRED(0x006F),
+	    REQUIRED(0x0070),     REQUIRED(0x0071),     REQUIRED(0x0072),     REQUIRED(0x0073),
+	    REQUIRED(0x0074),     REQUIRED(0x0075),     REQUIRED(0x0076),     REQUIRED(0x0077),
+	    REQUIRED(0x0078),     REQUIRED(0x0079),     REQUIRED(0x007A),     REQUIRED(0x007B),
+	    REQUIRED(0x007C),     REQUIRED(0x007D),     REQUIRED(0x007E), NOT_REQUIRED(0x007F),
+	NOT_REQUIRED(0xFFFE), NOT_REQUIRED(0xFFFE),     REQUIRED(0x201A),     REQUIRED(0x0192),
+	    REQUIRED(0x201E),     REQUIRED(0x2026),     REQUIRED(0x2020),     REQUIRED(0x2021),
+	    REQUIRED(0x02C6),     REQUIRED(0x2030),     REQUIRED(0x0160),     REQUIRED(0x2039),
+	    REQUIRED(0x0152), NOT_REQUIRED(0xFFFE), NOT_REQUIRED(0xFFFE), NOT_REQUIRED(0xFFFE),
+	NOT_REQUIRED(0xFFFE),     REQUIRED(0x2018),     REQUIRED(0x2019),     REQUIRED(0x201C),
+	    REQUIRED(0x201D),     REQUIRED(0x2022),     REQUIRED(0x2013),     REQUIRED(0x2014),
+	    REQUIRED(0x02DC),     REQUIRED(0x2122),     REQUIRED(0x0161),     REQUIRED(0x203A),
+	    REQUIRED(0x0153), NOT_REQUIRED(0xFFFE), NOT_REQUIRED(0xFFFE),     REQUIRED(0x0178),
+	    REQUIRED(0x00A0),     REQUIRED(0x00A1),     REQUIRED(0x00A2),     REQUIRED(0x00A3),
+	    REQUIRED(0x00A4),     REQUIRED(0x00A5),     REQUIRED(0x00A6),     REQUIRED(0x00A7),
+	    REQUIRED(0x00A8),     REQUIRED(0x00A9),     REQUIRED(0x00AA),     REQUIRED(0x00AB),
+	    REQUIRED(0x00AC),     REQUIRED(0x00AD),     REQUIRED(0x00AE),     REQUIRED(0x00AF),
+	    REQUIRED(0x00B0),     REQUIRED(0x00B1),     REQUIRED(0x00B2),     REQUIRED(0x00B3),
+	    REQUIRED(0x00B4),     REQUIRED(0x00B5),     REQUIRED(0x00B6),     REQUIRED(0x00B7),
+	    REQUIRED(0x00B8),     REQUIRED(0x00B9),     REQUIRED(0x00BA),     REQUIRED(0x00BB),
+	    REQUIRED(0x00BC),     REQUIRED(0x00BD),     REQUIRED(0x00BE),     REQUIRED(0x00BF),
+	    REQUIRED(0x00C0),     REQUIRED(0x00C1),     REQUIRED(0x00C2),     REQUIRED(0x00C3),
+	    REQUIRED(0x00C4),     REQUIRED(0x00C5),     REQUIRED(0x00C6),     REQUIRED(0x00C7),
+	    REQUIRED(0x00C8),     REQUIRED(0x00C9),     REQUIRED(0x00CA),     REQUIRED(0x00CB),
+	    REQUIRED(0x00CC),     REQUIRED(0x00CD),     REQUIRED(0x00CE),     REQUIRED(0x00CF),
+	    REQUIRED(0x00D0),     REQUIRED(0x00D1),     REQUIRED(0x00D2),     REQUIRED(0x00D3),
+	    REQUIRED(0x00D4),     REQUIRED(0x00D5),     REQUIRED(0x00D6),     REQUIRED(0x00D7),
+	    REQUIRED(0x00D8),     REQUIRED(0x00D9),     REQUIRED(0x00DA),     REQUIRED(0x00DB),
+	    REQUIRED(0x00DC),     REQUIRED(0x00DD),     REQUIRED(0x00DE),     REQUIRED(0x00DF),
+	    REQUIRED(0x00E0),     REQUIRED(0x00E1),     REQUIRED(0x00E2),     REQUIRED(0x00E3),
+	    REQUIRED(0x00E4),     REQUIRED(0x00E5),     REQUIRED(0x00E6),     REQUIRED(0x00E7),
+	    REQUIRED(0x00E8),     REQUIRED(0x00E9),     REQUIRED(0x00EA),     REQUIRED(0x00EB),
+	    REQUIRED(0x00EC),     REQUIRED(0x00ED),     REQUIRED(0x00EE),     REQUIRED(0x00EF),
+	    REQUIRED(0x00F0),     REQUIRED(0x00F1),     REQUIRED(0x00F2),     REQUIRED(0x00F3),
+	    REQUIRED(0x00F4),     REQUIRED(0x00F5),     REQUIRED(0x00F6),     REQUIRED(0x00F7),
+	    REQUIRED(0x00F8),     REQUIRED(0x00F9),     REQUIRED(0x00FA),     REQUIRED(0x00FB),
+	    REQUIRED(0x00FC),     REQUIRED(0x00FD),     REQUIRED(0x00FE),     REQUIRED(0x00FF)
+};
+
+#undef REQUIRED
+#undef NOT_REQUIRED
+
 Graphics::Font *GraphicsManager::createFont(int size) const {
 	Common::SeekableReadStream *stream = 0;
 
@@ -136,10 +209,8 @@ Graphics::Font *GraphicsManager::createFont(int size) const {
 	// TODO: Make the monochrome mode optional
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
-	// TODO: The mapping is code page 1252, but it should be 1:1 to Unicode
-	// for the characters we need.
 	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, Graphics::kTTFRenderModeMonochrome, 0);
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 	delete stream;
 	return font;
 }


Commit: 3c158972b36b2af87a113831fab9181bd13f25f9
    https://github.com/scummvm/scummvm/commit/3c158972b36b2af87a113831fab9181bd13f25f9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
GRAPHICS: Add the Windows busy cursor

Changed paths:
    graphics/wincursor.cpp
    graphics/wincursor.h


diff --git a/graphics/wincursor.cpp b/graphics/wincursor.cpp
index 8c3cf97ec6..9867e352f4 100644
--- a/graphics/wincursor.cpp
+++ b/graphics/wincursor.cpp
@@ -353,4 +353,68 @@ Cursor *makeDefaultWinCursor() {
 	return new DefaultWinCursor();
 }
 
+/**
+ * The Windows busy cursor
+ */
+class BusyWinCursor : public Cursor {
+public:
+	BusyWinCursor() {}
+	~BusyWinCursor() {}
+
+	uint16 getWidth() const { return 15; }
+	uint16 getHeight() const { return 27; }
+	uint16 getHotspotX() const { return 7; }
+	uint16 getHotspotY() const { return 13; }
+	byte getKeyColor() const { return 0; }
+
+	const byte *getSurface() const {
+		static const byte busyCursor[] = {
+			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+			1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+			0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+			0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 0,
+			0, 1, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 1, 0,
+			0, 0, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1, 1, 0, 0,
+			0, 0, 0, 1, 1, 2, 2, 1, 2, 2, 1, 1, 0, 0, 0,
+			0, 0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0, 0, 0,
+			0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0,
+			0, 0, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 0, 0,
+			0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 1, 0,
+			0, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 0,
+			0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+			1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+		};
+
+		return busyCursor;
+	}
+
+	const byte *getPalette() const {
+		static const byte bwPalette[] = {
+			0x00, 0x00, 0x00,	// Black
+			0xFF, 0xFF, 0xFF	// White
+		};
+
+		return bwPalette;
+	}
+	byte getPaletteStartIndex() const { return 1; }
+	uint16 getPaletteCount() const { return 2; }
+};
+
+Cursor *makeBusyWinCursor() {
+	return new BusyWinCursor();
+}
+
 } // End of namespace Graphics
diff --git a/graphics/wincursor.h b/graphics/wincursor.h
index 1431d4a894..5584ca281c 100644
--- a/graphics/wincursor.h
+++ b/graphics/wincursor.h
@@ -73,7 +73,16 @@ struct WinCursorGroup {
  * @note The calling code is responsible for deleting the returned pointer.
  */
 Cursor *makeDefaultWinCursor();
+
+/**
+ * Create a Cursor for the Windows busy cursor.
+ *
+ * @note The calling code is responsible for deleting the returned pointer.
+ */
+Cursor *makeBusyWinCursor();
+
 /** @} */
+
 } // End of namespace Graphics
 
 #endif


Commit: 9b21d8e83de0bec3577e8f11cdc48a4e9cd1e97c
    https://github.com/scummvm/scummvm/commit/9b21d8e83de0bec3577e8f11cdc48a4e9cd1e97c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Allow using the Windows busy cursor

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 4caec93cf3..bb26ade0df 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -223,8 +223,7 @@ Cursor GraphicsManager::setCursor(Cursor newCursor) {
 	if (newCursor == kCursorArrow) {
 		cursor = Graphics::makeDefaultWinCursor();
 	} else if (newCursor == kCursorWait) {
-		warning("STUB: setCursor(kCursorWait)");
-		return kCursorNone;
+		cursor = Graphics::makeBusyWinCursor();
 	} else {
 		cursorGroup = _vm->_mainEXE->getCursorGroup(newCursor);
 


Commit: e51ef54d6df37da4a34b931684ca5b7d449e1dad
    https://github.com/scummvm/scummvm/commit/e51ef54d6df37da4a34b931684ca5b7d449e1dad
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add a wrapper method to get an EXE string

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index a55e97355f..e075bb251b 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -90,8 +90,12 @@ Common::Error BuriedEngine::run() {
 	return Common::kNoError;
 }
 
+Common::String BuriedEngine::getString(uint32 stringID) {
+	return _mainEXE->loadString(stringID);
+}
+
 Common::String BuriedEngine::getFilePath(uint32 stringID) {
-	Common::String path = _mainEXE->loadString(stringID);
+	Common::String path = getString(stringID);
 	Common::String output;
 
 	if (path.empty())
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index c2d2a85f69..659ed02e19 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -56,6 +56,7 @@ public:
 
 	bool hasFeature(EngineFeature f) const;
 
+	Common::String getString(uint32 stringID);
 	Common::String getFilePath(uint32 stringID);
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 


Commit: 7bff632e1cdfe9b436d5e6b2f23e70c67a8bf4f0
    https://github.com/scummvm/scummvm/commit/7bff632e1cdfe9b436d5e6b2f23e70c67a8bf4f0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add some more GraphicsManager functions

Minor cleanup too

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index bb26ade0df..05cd35ee23 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -24,10 +24,13 @@
 #ifdef MACOSX
 #include "common/macresman.h"
 #endif
+#include "common/system.h"
 #include "graphics/cursorman.h"
-#include "graphics/wincursor.h"
 #include "graphics/font.h"
+#include "graphics/surface.h"
+#include "graphics/wincursor.h"
 #include "graphics/fonts/ttf.h"
+#include "image/bmp.h"
 
 #include "buried/buried.h"
 #include "buried/database.h"
@@ -210,7 +213,7 @@ Graphics::Font *GraphicsManager::createFont(int size) const {
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
 	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, Graphics::kTTFRenderModeMonochrome, s_codePage1252);
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 	delete stream;
 	return font;
 }
@@ -251,4 +254,29 @@ Cursor GraphicsManager::setCursor(Cursor newCursor) {
 	return oldCursor;
 }
 
+Graphics::Surface *GraphicsManager::getBitmap(uint32 bitmapID) {
+	Common::SeekableReadStream *stream = _vm->getBitmapStream(bitmapID);
+
+	if (!stream)
+		error("Could not find bitmap %d", bitmapID);
+
+	Image::BitmapDecoder decoder;
+	if (!decoder.loadStream(*stream))
+		error("Failed to decode bitmap %d", bitmapID);
+
+	delete stream;
+
+	Graphics::Surface *surface = new Graphics::Surface();
+	surface->copyFrom(*decoder.getSurface());
+	return surface;
+}
+
+uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
+	if (_vm->isTrueColor())
+		return g_system->getScreenFormat().RGBToColor(r, g, b);
+
+	// TODO
+	return 0;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index f70da40e8b..39bfbbd7a4 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -67,6 +67,8 @@ public:
 	byte *getDefaultPalette() const;
 	Graphics::Font *createFont(int size) const;
 	Cursor setCursor(Cursor newCursor);
+	Graphics::Surface *getBitmap(uint32 bitmapID);
+	uint32 getColor(byte r, byte g, byte b);
 
 private:
 	BuriedEngine *_vm;


Commit: d5b6f36676ee9200e4e269f39edb46b12185c06e
    https://github.com/scummvm/scummvm/commit/d5b6f36676ee9200e4e269f39edb46b12185c06e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
IMAGE: Mark BitmapDecoder as being used by buried

Changed paths:
    image/bmp.h


diff --git a/image/bmp.h b/image/bmp.h
index ae258c77e3..017c4ef4bc 100644
--- a/image/bmp.h
+++ b/image/bmp.h
@@ -20,6 +20,15 @@
  *
  */
 
+/**
+ * @file
+ * Image decoder used in engines:
+ *  - buried
+ *  - hugo
+ *  - mohawk
+ *  - wintermute
+ */
+
 #ifndef IMAGE_BMP_H
 #define IMAGE_BMP_H
 
@@ -37,7 +46,7 @@ struct Surface;
 }
 
 namespace Image {
-	
+
 /**
  * @defgroup image_bmp BMP decoder
  * @ingroup image
@@ -51,7 +60,7 @@ namespace Image {
  *  - Wintermute
  * @{
  */
- 
+
 class Codec;
 
 class BitmapDecoder : public ImageDecoder {


Commit: 0e9ba8f2565039148b189568f4ab229ede9b09cf
    https://github.com/scummvm/scummvm/commit/0e9ba8f2565039148b189568f4ab229ede9b09cf
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add the GlobalFlags table

Changed paths:
  A engines/buried/global_flags.h


diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
new file mode 100644
index 0000000000..22ed2e66d5
--- /dev/null
+++ b/engines/buried/global_flags.h
@@ -0,0 +1,319 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_GLOBAL_FLAGS_H
+#define BURIED_GLOBAL_FLAGS_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+// This is the struct that holds all the global variables for the game
+// Originally, it was just a 1024 byte block of data with offsets into it
+// (There clearly aren't enough variables)
+// For double-fun, they still need to be accessed by index for AI support
+// -> It therefore needs to be packed (Yes, this is totally evil)
+
+#include "common/pack-start.h"
+
+struct GlobalFlags {
+	byte cgWallExploded;                // 0
+	byte cgHookPresent;                 // 1
+	byte cgArrowPresent;                // 2
+	byte cgHammerPresent;               // 3
+	byte cgSmithyStatus;                // 4
+	byte cgSmithyGuard;                 // 5
+	byte cgBaileyOneWayGuard;           // 6
+	byte cgBaileyTwoWayGuards;          // 7
+	byte cgTapestryFlag;                // 8
+	byte cgBurnedLetterPresent;         // 9
+	byte cgGoldCoinsPresent;            // 10
+	byte cgStorageRoomVisit;            // 11
+	byte bcTranslateEnabled;            // 12
+	byte bcCloakingEnabled;             // 13
+	byte bcLocateEnabled;               // 14
+	byte myPickedUpCeramicBowl;         // 15
+	byte myTPCodeWheelStatus;           // 16
+	byte myTPCodeWheelLeftIndex;        // 17
+	byte myTPCodeWheelRightIndex;       // 18
+	byte myMCPickedUpSkull;             // 19
+	byte myMCDeathGodOfferings;         // 20
+	byte myWGPlacedRope;                // 21
+	byte myWGRetrivedJadeBlock;         // 22
+	byte myWTRetrievedLimestoneBlock;   // 23
+	byte myWTCurrentBridgeStatus;       // 24
+	byte myAGRetrievedEntrySkull;       // 25
+	byte myAGRetrievedSpearSkull;       // 26
+	byte myAGRetrievedCopperMedal;      // 27
+	byte myAGRetrievedObsidianBlock;    // 28
+	byte myAGHeadAStatus;               // 29
+	byte myAGHeadBStatus;               // 30
+	byte myAGHeadCStatus;               // 31
+	byte myAGHeadDStatus;               // 32
+	byte myAGHeadAStatusSkullID;        // 33
+	byte myAGHeadBStatusSkullID;        // 34
+	byte myAGHeadCStatusSkullID;        // 35
+	byte myAGHeadDStatusSkullID;        // 36
+	byte myAGTimerHeadID;               // 37
+	uint32 myAGTimerStartTime;          // 38-41
+	byte myDGOfferedHeart;              // 42
+	byte takenEnvironCart;              // 43
+	byte alRDTakenLiveCore;             // 44
+	byte alRDTakenDeadCore;             // 45
+	byte alNMWrongAlienPrefixCode;      // 46
+	byte faKIOvenStatus;                // 47
+	byte faKIPostBoxSlotA;              // 48
+	byte faKIPostBoxSlotB;              // 49
+	byte faKIPostBoxSlotC;              // 50
+	byte faERCurrentCartridge;          // 51
+	byte faERTakenRemoteControl;        // 52
+	byte myMCStingerID;                 // 53
+	byte myMCStingerChannelID;          // 54
+	byte myFAStingerID;                 // 55
+	byte myFAStingerChannelID;          // 56
+	byte unused0[3];                    // 57-59
+	uint32 cgMWCatapultData;            // 60-63
+	uint32 cgMWCatapultOffset;          // 64-67
+	byte cgTSTriedDoor;                 // 68
+	byte cgMBCrossedMoat;               // 69
+	byte cgKSSmithyEntryRead;           // 70
+	byte cgKSSmithyEntryTranslated;     // 71
+	byte cgBSFoundMold;                 // 72
+	byte readBurnedLetter;              // 73
+	byte evcapNumCaptured;              // 74
+	byte evcapBaseID[12];               // 75-86
+	byte unused1[3];                    // 87-89
+	byte faMNEnvironDoor;               // 90
+	byte faMNClockClicked;              // 91
+	byte faMNBooksClicked;              // 92
+	byte faMNTazClicked;                // 93
+	byte faMNPongClicked;               // 94
+	byte faKIBirdsBobbed;               // 95
+	byte faKICoffeeSpilled;             // 96
+	byte cgViewedKeepPlans;             // 97
+	byte cgFoundChestPanel;             // 98
+	byte cgTRFoundSword;                // 99
+	byte faHeardAgentFigure;            // 100
+	byte jumpBCNoInfoMessageCycle;      // 101
+	byte myTPCalendarTopTranslated;     // 102
+	byte myTPCalendarListTranslated;    // 103
+	byte myTPTextTranslated;            // 104
+	byte myMCTransDoor;                 // 105
+	byte myMCTransAGOffering;           // 106
+	byte myMCTransWGOffering;           // 107
+	byte myMCTransWTOffering;           // 108
+	byte myMCTransDGOffering;           // 109
+	byte myMCTransMadeAnOffering;       // 110
+	byte myWGTransDoorTop;              // 111
+	byte myWGSeenLowerPassage;          // 112
+	byte myWGCrossedRopeBridge;         // 113
+	byte myWMCViewedDeathGodDoor;       // 114
+	byte myTPTransBreathOfItzamna;      // 115
+	uint32 myAGHeadAOpenedTime;         // 116-119
+	uint32 myAGHeadBOpenedTime;         // 120-123
+	uint32 myAGHeadCOpenedTime;         // 124-127
+	uint32 myAGHeadDOpenedTime;         // 128-131
+	byte myAGHeadATouched;              // 132
+	byte myAGHeadBTouched;              // 133
+	byte myAGHeadCTouched;              // 134
+	byte myAGHeadDTouched;              // 135
+	byte lensFilterActivated;           // 136
+	byte dsPTElevatorPresent;           // 137
+	byte dsPTElevatorLeverA;            // 138
+	byte dsPTElevatorLeverB;            // 139
+	byte dsPTDoorLocked;                // 140
+	byte dsWSPickedUpWheelAssembly;     // 141
+	byte dsWSPickedUpGearAssembly;      // 142
+	byte dsWSPickedUpPegs;              // 143
+	byte dsWSSiegeCycleStatus;          // 144
+	byte dsWSGrabbedSiegeCycle;         // 145
+	byte dsPTUseElevatorControls;       // 146
+	byte dsPTTransElevatorControls;     // 147
+	byte dsGDTakenCoilOfRope;           // 148
+	byte dsCTUnlockedDoor;              // 149
+	byte dsCTViewedAgent3;              // 150
+	byte dsPTViewedAgent3;              // 151
+	byte dsCTRetrievedLens;             // 152
+	byte dsCTTakenHeart;                // 153
+	byte dsCYFiredCannon;               // 154
+	byte dsCYBallistaStatus;            // 155
+	byte dsCYPlacedSiegeCycle;          // 156
+	byte dsCYBallistaXPos;              // 157
+	byte dsCYBallistaYPos;              // 158
+	byte aiHWStingerID;                 // 159
+	byte aiHWStingerChannelID;          // 160
+	byte aiCRStingerID;                 // 161
+	byte aiCRStingerChannelID;          // 162
+	byte aiDBStingerID;                 // 163
+	byte aiDBStingerChannelID;          // 164
+	byte aiCRGrabbedMetalBar;           // 165
+	byte aiICGrabbedWaterCanister;      // 166
+	byte aiOxygenTimer;                 // 167
+	byte aiCRPressurized;               // 168
+	byte aiCRPressurizedAttempted;      // 169
+	byte aiMRPressurized;               // 170
+	byte aiIceMined;                    // 171
+	byte aiOxygenReserves;              // 172
+	byte aiSCHeardInitialSpeech;        // 173
+	byte aiSCInitialAudioChannel;       // 174
+	byte aiSCDBDoorWarning;             // 175
+	byte aiSCMoveCenterWarning;         // 176
+	byte aiSCConversationStatus;        // 177
+	byte aiHWIceDoorUnlocked;           // 178
+	byte aiICWaterInFillHandle;         // 179
+	byte aiICTakenWaterCanister;        // 180
+	byte aiSWStingerID;                 // 181
+	byte aiSWStingerChannelID;          // 182
+	byte aiMRCorrectFreqSet;            // 183
+	byte aiSCHeardNexusDoorComment;     // 184
+	byte aiSCHeardNexusDoorCode;        // 185
+	byte asInitialGuardsPass;           // 186
+	byte asRBPodAStatus;                // 187
+	byte asRBPodBStatus;                // 188
+	byte asRBPodCStatus;                // 189
+	byte asRBPodDStatus;                // 190
+	byte asRBPodEStatus;                // 191
+	byte asRBPodFStatus;                // 192
+	byte asRBPodATakenEnvironCart;      // 193
+	byte asRBPodBTakenPuzzleBox;        // 194
+	byte asRBPodCTakenCodex;            // 195
+	byte asRBPodDTakenSculpture;        // 196
+	byte asRBPodETakenSword;            // 197
+	byte asTakenEvidenceThisTrip;       // 198
+	byte asDangerDoorASealed;           // 199
+	byte asDoorBGuardsSeen;             // 200
+	byte asAmbassadorEncounter;         // 201
+	byte dsCTTriedLockedDoor;           // 202
+	byte dsCTCodexTranslateAttempted;   // 203
+	byte dsCTCodexFormulaeFound;        // 204
+	byte dsCTCodexAtlanticusPage2;      // 205
+	byte dsCTTriedElevatorControls;     // 206
+	byte aiDBPlayedMomComment;          // 207
+	byte aiDBPlayedFirstArthur;         // 208
+	byte aiDBPlayedSecondArthur;        // 209
+	byte aiDBPlayedThirdArthur;         // 210
+	byte aiDBPlayedFourthArthur;        // 211
+	byte aiSCPlayedNoStinger;           // 212
+	byte faKITakenPostboxItem;          // 213
+	byte cgMBVisited;                   // 214
+	byte cgKCVisited;                   // 215
+	byte cgTRVisited;                   // 216
+	byte cgKSReadJournal;               // 217
+	byte cgSRClickedOnLockedChest;      // 218
+	byte cgSROpenedChest;               // 219
+	byte dsVisitedCodexTower;           // 220
+	byte dsPTRaisedPlatform;            // 221
+	byte dsPTWalkedDownElevator;        // 222
+	byte dsPTBeenOnBalcony;             // 223
+	byte dsGDClickedOnCodexDoor;        // 224
+	byte dsWSSeenCycleSketch;           // 225
+	byte dsWSSeenBallistaSketch;        // 226
+	byte genHadSiegeCycle;              // 227
+	byte genHadDriveAssembly;           // 228
+	byte genHadWheelAssembly;           // 229
+	byte dsCYNeverConnectedHook;        // 230
+	byte dsCYNeverShotBallista;         // 231
+	byte dsCYNeverUsedCrank;            // 232
+	byte dsCYNeverOpenedBalconyDoor;    // 233
+	byte dsCYTranslatedCodex;           // 234
+	byte dsCYTriedOpeningDoor;          // 235
+	byte dsCYTriedElevator;             // 236
+	byte dsCYFoundCodexes;              // 237
+	byte myVisitedMainCavern;           // 238
+	byte myVisitedArrowGod;             // 239
+	byte myVisitedWaterGod;             // 240
+	byte myVisitedWealthGod;            // 241
+	byte myVisitedDeathGod;             // 242
+	byte myVisitedSpecRooms;            // 243
+	byte myWTSteppedOnSwings;           // 244
+	byte myWTSteppedOnFarLedge;         // 245
+	byte myDGOpenedPuzzleBox;           // 246
+	byte myAGVisitedAltar;              // 247
+	byte dsCTPlayedBallistaFalling;     // 248
+	byte cgTSTriedDoorA;                // 249
+	byte cgTSTriedDoorB;                // 250
+	byte aiHWLastCommentPlayed;         // 251
+	byte aiNXPlayedBrainComment;        // 252
+	byte asRBLastStingerID;             // 253
+	byte asRBStingerID;                 // 254
+	byte aiICProcessedOxygen;           // 255
+	byte dsCYWeeblieClicked;            // 256
+	byte aiICUsedMiningControls;        // 257
+	byte aiSWAttemptedPresMR;           // 258
+	byte aiICRefilledOxygen;            // 259
+	byte aiMRUsedHarmonicsInterface;    // 260
+	byte alRestoreSkipAgent3Initial;    // 261
+	byte unused2[38];                   // 262-299
+	byte scoreGotTranslateBioChip;      // 300
+	byte scoreEnteredSpaceStation;      // 301
+	byte scoreDownloadedArthur;         // 302
+	byte scoreFoundSculptureDiagram;    // 303
+	byte scoreEnteredKeep;              // 304
+	byte scoreGotKeyFromSmithy;         // 305
+	byte scoreEnteredTreasureRoom;      // 306
+	byte scoreFoundSwordDiamond;        // 307
+	byte scoreMadeSiegeCycle;           // 308
+	byte scoreEnteredCodexTower;        // 309
+	byte scoreLoggedCodexEvidence;      // 310
+	byte scoreEnteredMainCavern;        // 311
+	byte scoreGotWealthGodPiece;        // 312
+	byte scoreGotRainGodPiece;          // 313
+	byte scoreGotWarGodPiece;           // 314
+	byte scoreCompletedDeathGod;        // 315
+	byte scoreEliminatedAgent3;         // 316 (clone2727 refrains from commenting here)
+	byte scoreTransportToKrynn;         // 317
+	byte scoreGotKrynnArtifacts;        // 318
+	byte scoreDefeatedIcarus;           // 319
+	byte scoreResearchINNHighBidder;    // 320
+	byte scoreResearchINNAppeal;        // 321
+	byte scoreResearchINNUpdate;        // 322
+	byte scoreResearchINNJumpsuit;      // 323
+	byte scoreResearchBCJumpsuit;       // 324
+	byte scoreResearchMichelle;         // 325
+	byte scoreResearchMichelleBkg;      // 326
+	byte scoreResearchLensFilter;       // 327
+	byte scoreResearchCastleFootprint;  // 328
+	byte scoreResearchDaVinciFootprint; // 329
+	byte scoreResearchMorphSculpture;   // 330
+	byte scoreResearchEnvironCart;      // 331
+	byte scoreResearchAgent3Note;       // 332
+	byte scoreResearchAgent3DaVinci;    // 333
+	uint16 scoreHintsTotal;             // 334-335
+	byte unused3[54];                   // 336-389
+	byte genJumpCastleBriefing;         // 390
+	byte genJumpMayanBriefing;          // 391
+	byte genJumpDaVinciBriefing;        // 392
+	byte genJumpStationBriefing;        // 393
+	byte unused4[106];                  // 394-499
+	byte generalWalkthroughMode;        // 500
+	byte unused5[11];                   // 501-511
+	byte aiData[512];                   // 512-1023
+} PACKED_STRUCT;
+
+#include "common/pack-end.h"
+
+} // End of namespace Buried
+
+#endif


Commit: c7bcfed6a7c2840c17fe5856d2e7c9977cdacab4
    https://github.com/scummvm/scummvm/commit/c7bcfed6a7c2840c17fe5856d2e7c9977cdacab4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add navigation data structs

Changed paths:
  A engines/buried/navdata.h


diff --git a/engines/buried/navdata.h b/engines/buried/navdata.h
new file mode 100644
index 0000000000..a8a801c74f
--- /dev/null
+++ b/engines/buried/navdata.h
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_NAVDATA_H
+#define BURIED_NAVDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+struct Location {
+	uint16 timeZone;
+	uint16 environment;
+	uint16 node;
+	uint16 facing;
+	uint16 orientaton;
+	uint16 depth;
+};
+
+enum {
+	TRANSITION_NONE = 0,
+	TRANSITION_PUSH = 1,
+	TRANSITION_WALK = 2,
+	TRANSITION_VIDEO = 3,
+	TRANSITION_FADE = 4
+};
+
+enum {
+	TF_PUSH_UP = 0,
+	TF_PUSH_LEFT = 1,
+	TF_PUSH_RIGHT = 2,
+	TF_PUSH_DOWN = 3
+};
+
+struct DestinationScene {
+	Location destinationScene;
+	uint16 transitionType;
+
+	// Data specific to each type of transition:
+	// TRANSITION_VIDEO: video clip ID
+	// TRANSITION_PUSH: identifies direction
+	uint16 transitionData;
+
+	uint32 transitionStartFrame; // Unused for video
+	uint32 transitionLength;     // Unused for video
+};
+
+struct LocationStaticData {
+	Location location;
+	DestinationScene destUp;
+	DestinationScene destLeft;
+	DestinationScene destRight;
+	DestinationScene destDown;
+	DestinationScene destForward;
+	uint16 classID;
+	uint32 navFrameIndex;
+	uint32 miscFrameIndex;
+	uint32 miscFrameCount;
+	uint32 cycleStartFrame;
+	uint32 cycleFrameCount;
+};
+
+} // End of namespace Buried
+
+#endif


Commit: c2d9988b2c3528d46ea0decea1c00c594bb985a2
    https://github.com/scummvm/scummvm/commit/c2d9988b2c3528d46ea0decea1c00c594bb985a2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add a bunch of resource data structs/constants

Changed paths:
  A engines/buried/aidata.h
  A engines/buried/animdata.h
  A engines/buried/bookdata.h
  A engines/buried/fbcdata.h
  A engines/buried/inndata.h
  A engines/buried/invdata.h
  A engines/buried/snddata.h
  A engines/buried/sprtdata.h


diff --git a/engines/buried/aidata.h b/engines/buried/aidata.h
new file mode 100644
index 0000000000..a5067c42fc
--- /dev/null
+++ b/engines/buried/aidata.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_AIDATA_H
+#define BURIED_AIDATA_H
+
+#include "buried/navdata.h"
+
+namespace Buried {
+
+enum {
+	// Types
+	AI_COMMENT_TYPE_INFORMATION           = (1 << 0),
+	AI_COMMENT_TYPE_HELP                  = (1 << 1),
+	AI_COMMENT_TYPE_SPONTANEOUS           = (1 << 2),
+	AI_COMMENT_TYPE_OTHER                 = (1 << 3),
+
+	// Flags
+	AI_COMMENT_FLAG_SPECIAL_LOGIC         = (1 << 4),
+	AI_STATUS_FLAG_NON_BASE_DERIVED       = (1 << 5),
+	AI_DEPENDENCY_FLAG_NON_BASE_DERIVED_A = (1 << 6),
+	AI_DEPENDENCY_CHECK_FOR_MINIMUM_A     = (1 << 7),
+	AI_DEPENDENCY_FLAG_NON_BASE_DERIVED_B = (1 << 8),
+	AI_DEPENDENCY_CHECK_FOR_MINIMUM_B     = (1 << 9),
+	AI_COMMENT_DISABLE_IN_WALKTHROUGH     = (1 << 10)
+};
+
+// commentID - Environment relative comment ID number
+// commentFlags - Flags definit this comment. These include type and special logic.
+// dependencyFlagOffset - Offset to dependency flag
+// dependencyValue - Maximum value for dependency condition to be true
+// statusFlagOffset - Offset to status flag to be incremented when this comment is played
+struct AIComment {
+	Location location;
+	uint16 commentID;
+	uint16 commentFlags;
+	uint16 dependencyFlagOffsetA;
+	uint16 dependencyValueA;
+	uint16 dependencyFlagOffsetB;
+	uint16 dependencyValueB;
+	uint16 statusFlagOffset;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/animdata.h b/engines/buried/animdata.h
new file mode 100644
index 0000000000..9cd953ef3d
--- /dev/null
+++ b/engines/buried/animdata.h
@@ -0,0 +1,43 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_ANIMDATA_H
+#define BURIED_ANIMDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+struct AnimEvent {
+	uint16 animationID;
+	uint16 fileNameID;
+	uint16 audioStreamCount;
+	uint32 startFrame;
+	uint32 frameCount;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/bookdata.h b/engines/buried/bookdata.h
new file mode 100644
index 0000000000..4153dff2f4
--- /dev/null
+++ b/engines/buried/bookdata.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_BOOKDATA_H
+#define BURIED_BOOKDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+struct PageTurn {
+	uint32 typeOfTrans;
+	uint32 destPage;
+};
+
+struct BookPage {
+	uint16 pageID;
+	uint32 pageFrameIndex;
+	uint16 numLines;
+	PageTurn up;
+	PageTurn left;
+	PageTurn right;
+	PageTurn down;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/fbcdata.h b/engines/buried/fbcdata.h
new file mode 100644
index 0000000000..814d10dc61
--- /dev/null
+++ b/engines/buried/fbcdata.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_FBCDATA_H
+#define BURIED_FBCDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+struct FilesPageHotspot {
+	uint32 left;
+	uint32 top;
+	uint32 right;
+	uint32 bottom;
+	uint32 pageIndex;
+};
+
+struct FilesPage {
+	uint16 pageID;
+	uint16 returnPageIndex;
+	uint16 nextButtonPageIndex;
+	uint16 prevButtonPageIndex;
+	FilesPageHotspot hotspots[6];
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/inndata.h b/engines/buried/inndata.h
new file mode 100644
index 0000000000..11c2051324
--- /dev/null
+++ b/engines/buried/inndata.h
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_INNDATA_H
+#define BURIED_INNDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+struct INNHotspotData {
+	uint32 left;
+	uint32 top;
+	uint32 right;
+	uint32 bottom;
+	uint32 stillFrameOffset;
+};
+
+struct INNFrame {
+	uint16 topicID;
+	uint16 pageType;
+	uint32 stillFrameOffset;
+	INNHotspotData hotspots[8];
+};
+
+enum {
+	MEDIA_TYPE_VIDEO_FULL = 1,
+	MEDIA_TYPE_VIDEO_SMALL_A = 2,
+	MEDIA_TYPE_VIDEO_SMALL_B = 3,
+	MEDIA_TYPE_AUDIO = 4
+};
+
+struct INNMediaElement {
+	uint32 frameIndex;
+	uint16 mediaType;
+	uint16 fileIDOffset;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/invdata.h b/engines/buried/invdata.h
new file mode 100644
index 0000000000..507ecbf0c1
--- /dev/null
+++ b/engines/buried/invdata.h
@@ -0,0 +1,90 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_INVDATA_H
+#define BURIED_INVDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+enum {
+	kItemBalconyKey = 0,
+	kItemBioChipAI = 1,
+	kItemBioChipBlank = 2,
+	kItemBioChipCloak = 3,
+	kItemBioChipEvidence = 4,
+	kItemBioChipFiles = 5,
+	kItemBioChipInterface = 6,
+	kItemBioChipJump = 7,
+	kItemBioChipTranslate = 8,
+	kItemBloodyArrow = 9,
+	kItemBurnedLetter = 10,
+	kItemBurnedOutCore = 11,
+	kItemCeramicBowl = 12,
+	kItemCheeseGirl = 13,
+	kItemClassicGamesCart = 14, // Unused!
+	kItemCodexAtlanticus = 15,
+	kItemCoilOfRope = 15,
+	kItemCopperKey = 16,
+	kItemCopperMedallion = 18,
+	kItemCreditChip = 19, // Unused!
+	kItemEnvironCart = 20,
+	kItemExplosiveCharge = 21,
+	kItemDriveAssembly = 22,
+	kItemGeneratorCore = 23,
+	kItemGenoSingleCart = 24,
+	kItemGoldCoins = 25,
+	kItemGrapplingHook = 26,
+	kItemHammer = 27,
+	kItemInteractiveSculpture = 28,
+	kItemJadeBlock = 29,
+	kItemLensFilter = 30,
+	kItemLimestoneBlock = 31,
+	kItemMayanPuzzleBox = 32,
+	kItemMetalBar = 33,
+	kItemObsidianBlock = 34,
+	kItemPreservedHeart = 35,
+	kItemRemoteControl = 36,
+	kItemRichardsSword = 37,
+	kItemSiegeCycle = 38,
+	kItemCavernSkull = 39,
+	kItemEntrySkull = 40,
+	kItemSpearSkull = 41,
+	kItemWaterCanEmpty = 42,
+	kItemWaterCanFull = 43,
+	kItemWheelAssembly = 44,
+	kItemWoodenPegs = 45
+};
+
+struct InventoryElement {
+	uint16 itemID;
+	uint32 firstDragID;
+	uint32 dragIDCount;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/snddata.h b/engines/buried/snddata.h
new file mode 100644
index 0000000000..8d734ca9c5
--- /dev/null
+++ b/engines/buried/snddata.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_SNDDATA_H
+#define BURIED_SNDDATA_H
+
+#include "common/scummsys.h"
+
+namespace Buried {
+
+struct SoundEvent {
+	uint16 eventID;
+	uint16 fileNameID;
+	uint16 flags;
+	uint16 volumeLevel;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/sprtdata.h b/engines/buried/sprtdata.h
new file mode 100644
index 0000000000..d5faee601e
--- /dev/null
+++ b/engines/buried/sprtdata.h
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_SPRTDATA_H
+#define BURIED_SPRTDATA_H
+
+#include "common/scummsys.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+struct Sprite {
+	Graphics::Surface *image;
+	int32 xPos;
+	int32 yPos;
+	int32 width;
+	int32 height;
+	byte redTrans;
+	byte greenTrans;
+	byte blueTrans;
+};
+
+} // End of namespace Buried
+
+#endif


Commit: 6f9178dcd06952ff4f820071ae93d554b10a32cd
    https://github.com/scummvm/scummvm/commit/6f9178dcd06952ff4f820071ae93d554b10a32cd
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add wrappers for retrieving buried-specific data

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/database.cpp
    engines/buried/database.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index e075bb251b..7a0501cc9f 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -127,4 +127,36 @@ Common::SeekableReadStream *BuriedEngine::getBitmapStream(uint32 bitmapID) {
 	return _library->getBitmapStream(bitmapID);
 }
 
+Common::SeekableReadStream *BuriedEngine::getNavData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("NAVDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getSndData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("SNDDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getAnimData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("ANIMDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getAIData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("AIDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getItemData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("ITEMDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getBookData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("BOOKDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getFileBCData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("FILEBCDATA", resourceID);
+}
+
+Common::SeekableReadStream *BuriedEngine::getINNData(uint32 resourceID) {
+	return _mainEXE->getResourceStream("INNDATA", resourceID);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 659ed02e19..3af9d6dcf7 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -59,6 +59,14 @@ public:
 	Common::String getString(uint32 stringID);
 	Common::String getFilePath(uint32 stringID);
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
+	Common::SeekableReadStream *getNavData(uint32 resourceID);
+	Common::SeekableReadStream *getSndData(uint32 resourceID);
+	Common::SeekableReadStream *getAnimData(uint32 resourceID);
+	Common::SeekableReadStream *getAIData(uint32 resourceID);
+	Common::SeekableReadStream *getItemData(uint32 resourceID);
+	Common::SeekableReadStream *getBookData(uint32 resourceID);
+	Common::SeekableReadStream *getFileBCData(uint32 resourceID);
+	Common::SeekableReadStream *getINNData(uint32 resourceID);
 
 	GraphicsManager *_gfx;
 	Database *_mainEXE;
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index 76b42c6c30..d45de73214 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -82,6 +82,10 @@ Graphics::WinCursorGroup *DatabaseNE::getCursorGroup(uint32 cursorGroupID) {
 	return Graphics::WinCursorGroup::createCursorGroup(*_exe, cursorGroupID);
 }
 
+Common::SeekableReadStream *DatabaseNE::getResourceStream(const Common::String &resourceType, uint32 resourceID) {
+	return _exe->getResource(resourceType, resourceID);
+}
+
 bool DatabaseNECompressed::load(const Common::String &fileName) {
 	return _exe->loadFromCompressedEXE(fileName);
 }
diff --git a/engines/buried/database.h b/engines/buried/database.h
index 0dcae2b8ab..598158a68e 100644
--- a/engines/buried/database.h
+++ b/engines/buried/database.h
@@ -49,6 +49,7 @@ public:
 	virtual Common::String loadString(uint32 stringID) = 0;
 	virtual Common::SeekableReadStream *getBitmapStream(uint32 bitmapID) = 0;
 	virtual Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID) = 0;
+	virtual Common::SeekableReadStream *getResourceStream(const Common::String &resourceType, uint32 resourceID) = 0;
 };
 
 /**
@@ -65,6 +66,7 @@ public:
 	Common::String loadString(uint32 stringID);
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 	Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID);
+	Common::SeekableReadStream *getResourceStream(const Common::String &resourceType, uint32 resourceID);
 
 protected:
 	Common::NEResources *_exe;


Commit: e97c2f47a84c75d1919486c0d3bcc8ab6be176fc
    https://github.com/scummvm/scummvm/commit/e97c2f47a84c75d1919486c0d3bcc8ab6be176fc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Update the Window code a bit

Paint events will happen separately from the queue, since they're special anyway

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/message.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 7a0501cc9f..cb6907874d 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -87,6 +87,12 @@ Common::Error BuriedEngine::run() {
 	_gfx = new GraphicsManager(this);
 	_sound = new SoundManager(this);
 
+	// TODO: Event loop
+	// - Dispatch window events
+	// - Poll events
+	// - Call UpdateWindow for the windows
+	// - Update timers
+
 	return Common::kNoError;
 }
 
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 3af9d6dcf7..9db03de4be 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -30,6 +30,10 @@
 
 class OSystem;
 
+namespace Common {
+class SeekableReadStream;
+}
+
 namespace Buried {
 
 struct BuriedGameDescription;
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 05cd35ee23..1e04cae5b1 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -43,9 +43,14 @@ GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
 
 	setCursor(kCursorArrow);
 	CursorMan.showMouse(true);
+
+	_screen = new Graphics::Surface();
+	_screen->create(640, 480, g_system->getScreenFormat());
 }
 
 GraphicsManager::~GraphicsManager() {
+	_screen->free();
+	delete _screen;
 }
 
 byte *GraphicsManager::getDefaultPalette() const {
@@ -279,4 +284,9 @@ uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
 	return 0;
 }
 
+void GraphicsManager::invalidateRect(const Common::Rect &rect, bool erase) {
+	_dirtyRect.extend(rect);
+	// TODO: Erase?
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 39bfbbd7a4..01fefb6f6f 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -23,10 +23,12 @@
 #ifndef BURIED_GRAPHICS_H
 #define BURIED_GRAPHICS_H
 
+#include "common/rect.h"
 #include "common/scummsys.h"
 
 namespace Graphics {
 class Font;
+struct Surface;
 }
 
 namespace Buried {
@@ -70,9 +72,16 @@ public:
 	Graphics::Surface *getBitmap(uint32 bitmapID);
 	uint32 getColor(byte r, byte g, byte b);
 
+	void invalidateRect(const Common::Rect &rect, bool erase = true);
+
+	Graphics::Surface *getScreen() const { return _screen; }
+
 private:
 	BuriedEngine *_vm;
 	Cursor _curCursor;
+
+	Common::Rect _dirtyRect;
+	Graphics::Surface *_screen;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/message.h b/engines/buried/message.h
index a154d095ca..e5f2b83ebb 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -41,7 +41,6 @@ enum MessageType {
 	kMessageTypeSetFocus,
 	kMessageTypeKillFocus,
 	kMessageTypeQueryNewPalette,
-	kMessageTypePaint,
 	kMessageTypeMouseMove,
 	kMessageTypeLButtonUp,
 	kMessageTypeLButtonDown,
@@ -109,7 +108,6 @@ private:
 // Types for everything that falls under one of the above categories
 typedef MessageTypeIntern<kMessageTypeEraseBackground> EraseBackgroundMessage;
 typedef MessageTypeIntern<kMessageTypeQueryNewPalette> QueryNewPaletteMessage;
-typedef MessageTypeIntern<kMessageTypePaint>           PaintMessage;
 typedef KeyMessage<kMessageTypeKeyUp>                  KeyUpMessage;
 typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
 typedef WindowMessage<kMessageTypeSetFocus>            SetFocusMessage;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 2dcf185662..6b173d929e 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -22,71 +22,92 @@
 
 #include "common/textconsole.h"
 
+#include "buried/buried.h"
+#include "buried/graphics.h"
 #include "buried/message.h"
 #include "buried/window.h"
 
 namespace Buried {
 
-void Window::dispatchMessage() {
-	if (_queue.empty())
-		return;
+Window::Window(BuriedEngine *vm) : _vm(vm) {
+	_parent = 0;
+}
 
-	Message *message = _queue.pop();
+Window::~Window() {
+	// Make sure the queue is cleaned out
+	while (!_queue.empty())
+		delete _queue.pop();
+}
 
-	switch (message->getMessageType()) {
-	case kMessageTypeEraseBackground:
-		onEraseBackground();
-		break;
-	case kMessageTypeKeyUp:
-		onKeyUp(((KeyUpMessage *)message)->getKeyState(), ((KeyUpMessage *)message)->getFlags());
-		break;
-	case kMessageTypeKeyDown:
-		onKeyDown(((KeyDownMessage *)message)->getKeyState(), ((KeyDownMessage *)message)->getFlags());
-		break;
-	case kMessageTypeTimer:
-		onTimer(((TimerMessage *)message)->getTimer());
-		break;
-	case kMessageTypeSetFocus:
-		onSetFocus(((SetFocusMessage *)message)->getWindow());
-		break;
-	case kMessageTypeKillFocus:
-		onKillFocus(((KillFocusMessage *)message)->getWindow());
-		break;
-	case kMessageTypeQueryNewPalette:
-		onQueryNewPalette();
-		break;
-	case kMessageTypePaint:
-		onPaint();
-		break;
-	case kMessageTypeLButtonUp:
-		onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
-		break;
-	case kMessageTypeLButtonDown:
-		onLButtonDown(((LButtonDownMessage *)message)->getPoint(), ((LButtonDownMessage *)message)->getFlags());
-		break;
-	case kMessageTypeLButtonDoubleClick:
-		onLButtonDoubleClick(((LButtonDoubleClickMessage *)message)->getPoint(), ((LButtonDoubleClickMessage *)message)->getFlags());
-		break;
-	case kMessageTypeMButtonUp:
-		onMButtonUp(((MButtonUpMessage *)message)->getPoint(), ((MButtonUpMessage *)message)->getFlags());
-		break;
-	case kMessageTypeRButtonUp:
-		onRButtonUp(((RButtonUpMessage *)message)->getPoint(), ((RButtonUpMessage *)message)->getFlags());
-		break;
-	case kMessageTypeRButtonDown:
-		onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
-		break;
-	case kMessageTypeSetCursor:
-		onSetCursor(((SetCursorMessage *)message)->getWindow(), ((SetCursorMessage *)message)->getCursor());
-		break;
-	case kMessageTypeEnable:
-		onEnable(((EnableMessage *)message)->getEnable());
-		break;
-	default:
-		error("Unknown message type %d", message->getMessageType());
-	}
+void Window::invalidateRect(const Common::Rect &rect, bool erase) {
+	_vm->_gfx->invalidateRect(rect, erase);
+}
+
+void Window::createChild(const Common::Rect &rect, Window *parent) {
+	_rect = rect;
+	_parent = parent;
+}
 
-	delete message;
+Common::Rect Window::getClientRect() const {
+	return Common::Rect(_rect.width(), _rect.height());
+}
+
+void Window::dispatchAllMessages() {
+	while (!_queue.empty() && !_vm->shouldQuit()) {
+		Message *message = _queue.pop();
+
+		switch (message->getMessageType()) {
+		case kMessageTypeEraseBackground:
+			onEraseBackground();
+			break;
+		case kMessageTypeKeyUp:
+			onKeyUp(((KeyUpMessage *)message)->getKeyState(), ((KeyUpMessage *)message)->getFlags());
+			break;
+		case kMessageTypeKeyDown:
+			onKeyDown(((KeyDownMessage *)message)->getKeyState(), ((KeyDownMessage *)message)->getFlags());
+			break;
+		case kMessageTypeTimer:
+			onTimer(((TimerMessage *)message)->getTimer());
+			break;
+		case kMessageTypeSetFocus:
+			onSetFocus(((SetFocusMessage *)message)->getWindow());
+			break;
+		case kMessageTypeKillFocus:
+			onKillFocus(((KillFocusMessage *)message)->getWindow());
+			break;
+		case kMessageTypeQueryNewPalette:
+			onQueryNewPalette();
+			break;
+		case kMessageTypeLButtonUp:
+			onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
+			break;
+		case kMessageTypeLButtonDown:
+			onLButtonDown(((LButtonDownMessage *)message)->getPoint(), ((LButtonDownMessage *)message)->getFlags());
+			break;
+		case kMessageTypeLButtonDoubleClick:
+			onLButtonDoubleClick(((LButtonDoubleClickMessage *)message)->getPoint(), ((LButtonDoubleClickMessage *)message)->getFlags());
+			break;
+		case kMessageTypeMButtonUp:
+			onMButtonUp(((MButtonUpMessage *)message)->getPoint(), ((MButtonUpMessage *)message)->getFlags());
+			break;
+		case kMessageTypeRButtonUp:
+			onRButtonUp(((RButtonUpMessage *)message)->getPoint(), ((RButtonUpMessage *)message)->getFlags());
+			break;
+		case kMessageTypeRButtonDown:
+			onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
+			break;
+		case kMessageTypeSetCursor:
+			onSetCursor(((SetCursorMessage *)message)->getWindow(), ((SetCursorMessage *)message)->getCursor());
+			break;
+		case kMessageTypeEnable:
+			onEnable(((EnableMessage *)message)->getEnable());
+			break;
+		default:
+			error("Unknown message type %d", message->getMessageType());
+		}
+
+		delete message;
+	}
 }
 
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index dd099d0756..75d1cc421e 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -23,20 +23,22 @@
 #ifndef BURIED_WINDOW_H
 #define BURIED_WINDOW_H
 
+#include "common/rect.h"
 #include "common/queue.h"
 
 namespace Common {
 struct KeyState;
-struct Point;
 }
 
 namespace Buried {
 
+class BuriedEngine;
 struct Message;
 
 class Window {
 public:
-	virtual ~Window() {}
+	Window(BuriedEngine *vm);
+	virtual ~Window();
 
 	// The message types used by Buried in Time's windows
 	virtual bool onEraseBackground() { return false; }
@@ -57,26 +59,32 @@ public:
 	virtual bool onSetCursor(Window *window, uint cursor) { return false; }
 	virtual void onEnable(bool enable) {}
 
+	void invalidateRect(const Common::Rect &rect, bool erase = true);
+	void createChild(const Common::Rect &rect, Window *parent);
+	Window *getParent() const { return _parent; }
+	const Common::Rect &getRect() const { return _rect; }
+	Common::Rect getClientRect() const;
+	void updateWindow() { onPaint(); }
+
 	// TODO:
 	// SetTimer
 	// ShowWindow
-	// UpdateWindow
-	// GetClientRect
 	// KillTimer
-	// InvalidateRect
 	// BeginPaint (?)
 	// EndPaint (?)
 	// Create
-	// GetParent
 	// ...
 
 	void sendMessage(Message *message) { _queue.push(message); }
-	void dispatchMessage();
+	void dispatchAllMessages();
 
 private:
+	BuriedEngine *_vm;
 	Common::Queue<Message *> _queue;
 
-	// TODO: Something about children? Parents?
+	// TODO: Something about children?
+	Window *_parent;
+	Common::Rect _rect;
 };
 
 } // End of namespace Buried


Commit: 33444e800d097fc10dbc9a9bfa817a4ea2dd6d90
    https://github.com/scummvm/scummvm/commit/33444e800d097fc10dbc9a9bfa817a4ea2dd6d90
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Implement window enabling

Changed paths:
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 6b173d929e..d6a0b8606b 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -31,6 +31,7 @@ namespace Buried {
 
 Window::Window(BuriedEngine *vm) : _vm(vm) {
 	_parent = 0;
+	_enabled = true;
 }
 
 Window::~Window() {
@@ -110,4 +111,18 @@ void Window::dispatchAllMessages() {
 	}
 }
 
+void Window::enableWindow(bool enable) {
+	if (_enabled != enable) {
+		_enabled = enable;
+		sendMessage(new EnableMessage(enable));
+	}
+}
+
+bool Window::isWindowEnabled() const {
+	if (_parent && !_parent->isWindowEnabled())
+		return false;
+
+	return _enabled;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 75d1cc421e..61feb817a5 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -65,6 +65,8 @@ public:
 	const Common::Rect &getRect() const { return _rect; }
 	Common::Rect getClientRect() const;
 	void updateWindow() { onPaint(); }
+	void enableWindow(bool enable);
+	bool isWindowEnabled() const;
 
 	// TODO:
 	// SetTimer
@@ -82,9 +84,9 @@ private:
 	BuriedEngine *_vm;
 	Common::Queue<Message *> _queue;
 
-	// TODO: Something about children?
 	Window *_parent;
 	Common::Rect _rect;
+	bool _enabled;
 };
 
 } // End of namespace Buried


Commit: 8773a54785503cde981163a895247820aaf46885
    https://github.com/scummvm/scummvm/commit/8773a54785503cde981163a895247820aaf46885
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add simple blit function

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 1e04cae5b1..ad8595560a 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -289,4 +289,11 @@ void GraphicsManager::invalidateRect(const Common::Rect &rect, bool erase) {
 	// TODO: Erase?
 }
 
+void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
+	assert(surface->format.bytesPerPixel == _screen->format.bytesPerPixel);
+
+	for (int i = 0; i < surface->h; i++)
+		memcpy(_screen->getBasePtr(x, y + i), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 01fefb6f6f..709fa96805 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -76,6 +76,8 @@ public:
 
 	Graphics::Surface *getScreen() const { return _screen; }
 
+	void blit(const Graphics::Surface *surface, int x, int y);
+
 private:
 	BuriedEngine *_vm;
 	Cursor _curCursor;


Commit: 657b35f04c03c178b2b1741c8787260b062faf03
    https://github.com/scummvm/scummvm/commit/657b35f04c03c178b2b1741c8787260b062faf03
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Make some private Window members protected

Changed paths:
    engines/buried/window.h


diff --git a/engines/buried/window.h b/engines/buried/window.h
index 61feb817a5..be7417d438 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -80,12 +80,14 @@ public:
 	void sendMessage(Message *message) { _queue.push(message); }
 	void dispatchAllMessages();
 
-private:
+protected:
 	BuriedEngine *_vm;
-	Common::Queue<Message *> _queue;
 
 	Window *_parent;
 	Common::Rect _rect;
+
+private:
+	Common::Queue<Message *> _queue;
 	bool _enabled;
 };
 


Commit: 75ddf082711794ec72e61bc6d06150818eb9d21e
    https://github.com/scummvm/scummvm/commit/75ddf082711794ec72e61bc6d06150818eb9d21e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add first stab at the LiveText window

Changed paths:
  A engines/buried/livetext.cpp
  A engines/buried/livetext.h
    engines/buried/module.mk


diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
new file mode 100644
index 0000000000..56579c4e85
--- /dev/null
+++ b/engines/buried/livetext.cpp
@@ -0,0 +1,143 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/str-array.h"
+#include "graphics/font.h"
+#include "graphics/surface.h"
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/livetext.h"
+#include "buried/resources.h"
+
+namespace Buried {
+
+LiveTextWindow::LiveTextWindow(BuriedEngine *vm, Window *parent) : Window(vm) {
+	// Initialize member variables to empty
+	_textTranslation = false;
+
+	// Create font
+	_font = _vm->_gfx->createFont(14);
+
+	// Create window
+	createChild(Common::Rect(137, 21, 447, 87), parent);
+
+	// Update the text in the window
+	updateLiveText(_vm->getString(IDS_SAVE_GAME_MESSAGE), false);
+}
+
+LiveTextWindow::~LiveTextWindow() {
+	delete _font;
+}
+
+bool LiveTextWindow::updateLiveText(const Common::String &text, bool notifyUser) {
+	// Set translated text flag
+	_textTranslation = false;
+
+	if (text.empty()) {
+		_text.clear();
+
+		invalidateRect(Common::Rect(), false);
+		updateWindow();
+
+		// TODO: Set warning state to false
+		return true;
+	}
+
+	_text = text;
+
+	// Redraw the window
+	invalidateRect(Common::Rect(), false);
+	updateWindow();
+
+	if (notifyUser) {
+		// TODO: Flash the warning light
+	}
+
+	return true;
+}
+
+bool LiveTextWindow::updateTranslationText(const Common::String &text, bool notifyUser) {
+	if (text.empty()) {
+		_text.clear();
+
+		invalidateRect(Common::Rect(), false);
+		updateWindow();
+
+		// TODO: Set warning state to false
+		return true;
+	}
+
+	_text = text;
+
+	// Set translated text flag
+	_textTranslation = true;
+
+	// Redraw the window
+	invalidateRect(Common::Rect(), false);
+	updateWindow();
+
+	// TODO: Set warning state to false
+
+	return true;
+}
+
+void LiveTextWindow::translateBiochipClosing() {
+	// If the current text is translated text, then kill it now
+	if (_textTranslation)
+		updateLiveText();
+}
+
+void LiveTextWindow::onPaint() {
+	// Draw the background bitmap
+	Graphics::Surface *surface = _vm->_gfx->getBitmap(IDB_LIVE_TEXT_BACKGROUND);
+
+	// (This probably needs a look-through)
+	if (!_text.empty()) {
+		uint32 textColor = _vm->_gfx->getColor(212, 109, 0);
+
+		Common::StringArray lines;
+		_font->wordWrapText(_text, 270, lines);
+
+		uint32 y = 4;
+		for (uint32 i = 0; i < lines.size(); i++) {
+			_font->drawString(surface, lines[i], 30, y, 270, textColor);
+			y += _font->getFontHeight() + 1;
+		}
+	}
+
+	_vm->_gfx->blit(surface, _rect.left, _rect.top);
+
+	surface->free();
+	delete surface;
+}
+
+void LiveTextWindow::onEnable(bool enable) {
+	if (enable) {
+		// TODO: Clear out mouse messages (why???)
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/livetext.h b/engines/buried/livetext.h
new file mode 100644
index 0000000000..864d055cb1
--- /dev/null
+++ b/engines/buried/livetext.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_LIVETEXT_H
+#define BURIED_LIVETEXT_H
+
+#include "common/str.h"
+
+#include "buried/window.h"
+
+namespace Graphics {
+class Font;
+}
+
+namespace Buried {
+
+class LiveTextWindow : public Window {
+public:
+	LiveTextWindow(BuriedEngine *vm, Window *parent);
+	~LiveTextWindow();
+
+	bool updateLiveText(const Common::String &text = "", bool notifyUser = true);
+	bool updateTranslationText(const Common::String &text = "", bool notifyUser = true);
+
+	void translateBiochipClosing();
+
+	void onPaint();
+	void onEnable(bool enable);
+
+private:
+	Graphics::Font *_font;
+	bool _textTranslation;
+	Common::String _text;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index af3be70a38..e252904cde 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS = \
 	database.o \
 	detection.o \
 	graphics.o \
+	livetext.o \
 	sound.o \
 	window.o
 


Commit: c7c2077f766a6847a8b184057d502f85004f3926
    https://github.com/scummvm/scummvm/commit/c7c2077f766a6847a8b184057d502f85004f3926
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Actually use the palette now in non-truecolor mode

All one game palette.

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index ad8595560a..5889587bf4 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -27,6 +27,7 @@
 #include "common/system.h"
 #include "graphics/cursorman.h"
 #include "graphics/font.h"
+#include "graphics/palette.h"
 #include "graphics/surface.h"
 #include "graphics/wincursor.h"
 #include "graphics/fonts/ttf.h"
@@ -46,50 +47,24 @@ GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
 
 	_screen = new Graphics::Surface();
 	_screen->create(640, 480, g_system->getScreenFormat());
+
+	if (_vm->isTrueColor()) {
+		// No palette to deal with
+		_palette = 0;
+	} else {
+		// Grab the palette from our EXE bitmap
+		_palette = createDefaultPalette();
+
+		// Then apply it. The only time we'll use this call even.
+		g_system->getPaletteManager()->setPalette(_palette, 0, 256);
+	}
 }
 
 GraphicsManager::~GraphicsManager() {
 	_screen->free();
 	delete _screen;
-}
-
-byte *GraphicsManager::getDefaultPalette() const {
-	Common::SeekableReadStream *stream = _vm->getBitmapStream(700);
-
-	if (!stream)
-		error("Couldn't find bitmap 700");
-
-	stream->skip(14);
-
-	if (stream->readUint16LE() != 8)
-		error("Trying to load palette from non-8bpp image 700");
-
-	stream->skip(16);
-
-	uint32 colorsUsed = stream->readUint32LE();
-
-	if (colorsUsed != 0 && colorsUsed != 256)
-		error("Bitmap 700 is missing a full palette");
-
-	stream->skip(4);
-	byte *palette = new byte[256 * 3];
-	byte *ptr = palette;
-
-	for (uint32 i = 0; i < 256; i++) {
-		ptr[2] = stream->readByte();
-		ptr[1] = stream->readByte();
-		ptr[0] = stream->readByte();
-		stream->readByte();
-		ptr += 3;
-	}
-
-	delete stream;
-
-	// Make sure the first entry is black and the last is white
-	palette[0]   = palette[1]   = palette[2]   = 0x00;
-	palette[253] = palette[254] = palette[255] = 0xFF;
 
-	return palette;
+	delete[] _palette;
 }
 
 #define REQUIRED(x) (((uint32)(x)) | 0x80000000)
@@ -296,4 +271,43 @@ void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
 		memcpy(_screen->getBasePtr(x, y + i), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
 }
 
+byte *GraphicsManager::createDefaultPalette() const {
+	Common::SeekableReadStream *stream = _vm->getBitmapStream(700);
+
+	if (!stream)
+		error("Couldn't find bitmap 700");
+
+	stream->skip(14);
+
+	if (stream->readUint16LE() != 8)
+		error("Trying to load palette from non-8bpp image 700");
+
+	stream->skip(16);
+
+	uint32 colorsUsed = stream->readUint32LE();
+
+	if (colorsUsed != 0 && colorsUsed != 256)
+		error("Bitmap 700 is missing a full palette");
+
+	stream->skip(4);
+	byte *palette = new byte[256 * 3];
+	byte *ptr = palette;
+
+	for (uint32 i = 0; i < 256; i++) {
+		ptr[2] = stream->readByte();
+		ptr[1] = stream->readByte();
+		ptr[0] = stream->readByte();
+		stream->readByte();
+		ptr += 3;
+	}
+
+	delete stream;
+
+	// Make sure the first entry is black and the last is white
+	palette[0]   = palette[1]   = palette[2]   = 0x00;
+	palette[253] = palette[254] = palette[255] = 0xFF;
+
+	return palette;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 709fa96805..82e6bb95b9 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -66,7 +66,7 @@ public:
 	GraphicsManager(BuriedEngine *vm);
 	~GraphicsManager();
 
-	byte *getDefaultPalette() const;
+	byte *getDefaultPalette() const { return _palette; }
 	Graphics::Font *createFont(int size) const;
 	Cursor setCursor(Cursor newCursor);
 	Graphics::Surface *getBitmap(uint32 bitmapID);
@@ -84,6 +84,9 @@ private:
 
 	Common::Rect _dirtyRect;
 	Graphics::Surface *_screen;
+	byte *_palette;
+	
+	byte *createDefaultPalette() const;
 };
 
 } // End of namespace Buried


Commit: 48f1fae34e2f65701d97b815a6c5db1cf540aba8
    https://github.com/scummvm/scummvm/commit/48f1fae34e2f65701d97b815a6c5db1cf540aba8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add uncompressed detection

Changed paths:
    engines/buried/detection.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 0f8d8f2781..8e16bc29d1 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -82,6 +82,43 @@ namespace Buried {
 
 static const BuriedGameDescription gameDescriptions[] = {
 	// Windows 3.11 8BPP
+	// Installed
+	{
+		{
+			"buried",
+			"8BPP",
+			{
+				{ "BIT816.EXE",  0, "57a14461c77d9c77534bd418043db1ec", 1163776 },
+				{ "BIT8LIB.DLL", 0, "31bcd9e5cc32df00b09ce626e6d9106e", 2420480 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Windows 3.11 24BPP
+	// Installed
+	{
+		{
+			"buried",
+			"24BPP",
+			{
+				{ "BIT2416.EXE",  0, "dcbfb3f2916ad902043942fc00d2017f", 1159680 },
+				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// Windows 3.11 8BPP
+	// Not Installed
 	{
 		{
 			"buried",
@@ -99,6 +136,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 	},
 
 	// Windows 3.11 24BPP
+	// Not Installed
 	{
 		{
 			"buried",


Commit: 5e25d91bd66db6ffbb78cf50bb248fa92626f7b6
    https://github.com/scummvm/scummvm/commit/5e25d91bd66db6ffbb78cf50bb248fa92626f7b6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Fix white palette entry setting

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 5889587bf4..f8ba41b86d 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -304,8 +304,8 @@ byte *GraphicsManager::createDefaultPalette() const {
 	delete stream;
 
 	// Make sure the first entry is black and the last is white
-	palette[0]   = palette[1]   = palette[2]   = 0x00;
-	palette[253] = palette[254] = palette[255] = 0xFF;
+	palette[0 * 3]   = palette[0 * 3 + 1]   = palette[0 * 3 + 2]   = 0x00;
+	palette[255 * 3] = palette[255 * 3 + 1] = palette[255 * 3 + 2] = 0xFF;
 
 	return palette;
 }


Commit: a30f0d6bbc1c251b0d2667a4dff76f8ac9652836
    https://github.com/scummvm/scummvm/commit/a30f0d6bbc1c251b0d2667a4dff76f8ac9652836
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add color matching for paletted mode

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index f8ba41b86d..40e2cdc4b2 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -255,8 +255,24 @@ uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
 	if (_vm->isTrueColor())
 		return g_system->getScreenFormat().RGBToColor(r, g, b);
 
-	// TODO
-	return 0;
+	// Find the best match color
+	int diff = 0x7FFFFFFF;
+	byte best = 0;
+
+	for (uint i = 0; i < 256 && diff > 0; i++) {
+		int rDiff = (int)_palette[i * 3] - (int)r;
+		int gDiff = (int)_palette[i * 3 + 1] - (int)g;
+		int bDiff = (int)_palette[i * 3 + 2] - (int)b;
+
+		int curDiff = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
+
+		if (curDiff < diff) {
+			best = i;
+			diff = curDiff;
+		}
+	}
+
+	return best;
 }
 
 void GraphicsManager::invalidateRect(const Common::Rect &rect, bool erase) {


Commit: 6f2eb23ff8b45fe775b3d9c9c0c66d332ae9129b
    https://github.com/scummvm/scummvm/commit/6f2eb23ff8b45fe775b3d9c9c0c66d332ae9129b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Remove unneeded OnQueryNewPalette window stuff

Changed paths:
    engines/buried/message.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/message.h b/engines/buried/message.h
index e5f2b83ebb..50c659abbe 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -40,7 +40,6 @@ enum MessageType {
 	kMessageTypeTimer,
 	kMessageTypeSetFocus,
 	kMessageTypeKillFocus,
-	kMessageTypeQueryNewPalette,
 	kMessageTypeMouseMove,
 	kMessageTypeLButtonUp,
 	kMessageTypeLButtonDown,
@@ -107,7 +106,6 @@ private:
 
 // Types for everything that falls under one of the above categories
 typedef MessageTypeIntern<kMessageTypeEraseBackground> EraseBackgroundMessage;
-typedef MessageTypeIntern<kMessageTypeQueryNewPalette> QueryNewPaletteMessage;
 typedef KeyMessage<kMessageTypeKeyUp>                  KeyUpMessage;
 typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
 typedef WindowMessage<kMessageTypeSetFocus>            SetFocusMessage;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index d6a0b8606b..4e9d5bfa74 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -76,9 +76,6 @@ void Window::dispatchAllMessages() {
 		case kMessageTypeKillFocus:
 			onKillFocus(((KillFocusMessage *)message)->getWindow());
 			break;
-		case kMessageTypeQueryNewPalette:
-			onQueryNewPalette();
-			break;
 		case kMessageTypeLButtonUp:
 			onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
 			break;
diff --git a/engines/buried/window.h b/engines/buried/window.h
index be7417d438..c95924465c 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -47,7 +47,6 @@ public:
 	virtual void onTimer(uint timer) {}
 	virtual void onKillFocus(Window *newWindow) {}
 	virtual void onSetFocus(Window *oldWindow) {}
-	virtual bool onQueryNewPalette() { return false; }
 	virtual void onPaint() {}
 	virtual void onLButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onLButtonDown(const Common::Point &point, uint flags) {}


Commit: b77e31af1077b42c86b06d79ccfc85a0925fd1ca
    https://github.com/scummvm/scummvm/commit/b77e31af1077b42c86b06d79ccfc85a0925fd1ca
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add the new AVI frames cache system

Changed paths:
  A engines/buried/avi_frames.cpp
  A engines/buried/avi_frames.h
    engines/buried/module.mk


diff --git a/engines/buried/avi_frames.cpp b/engines/buried/avi_frames.cpp
new file mode 100644
index 0000000000..aacb4fcca3
--- /dev/null
+++ b/engines/buried/avi_frames.cpp
@@ -0,0 +1,178 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/avi_frames.h"
+#include "buried/buried.h"
+#include "buried/graphics.h"
+
+#include "graphics/surface.h"
+#include "video/avi_decoder.h"
+
+namespace Buried {
+
+AVIFrames::AVIFrames(const Common::String &fileName, uint cachedFrames) {
+	_maxCachedFrames = 0;
+	_video = 0;
+	_cacheEnabled = false;
+	_lastFrame = 0;
+	_lastFrameIndex = -1;
+
+	if (!fileName.empty())
+		open(fileName, cachedFrames);
+}
+
+AVIFrames::~AVIFrames() {
+	close();
+}
+
+bool AVIFrames::open(const Common::String &fileName, uint cachedFrames) {
+	if (fileName.empty())
+		return false;
+
+	if (_fileName == fileName)
+		return true;
+
+	close();
+
+	_video = new Video::AVIDecoder();
+
+	if (!_video->loadFile(fileName)) {
+		close();
+		return false;
+	}
+
+	_fileName = fileName;
+
+	// Put us into dither mode, for the 8bpp version
+	BuriedEngine *vm = (BuriedEngine *)g_engine;
+	if (!vm->isTrueColor())
+		_video->setDitheringPalette(vm->_gfx->getDefaultPalette());
+
+	if (cachedFrames == 0) {
+		_cacheEnabled = false;
+	} else {
+		_maxCachedFrames = cachedFrames;
+		_cacheEnabled = true;
+	}
+
+	_lastFrameIndex = -1;
+	return true;
+}
+
+void AVIFrames::close() {
+	delete _video;
+	_video = 0;
+
+	_fileName.clear();
+
+	flushFrameCache();
+
+	_lastFrameIndex = -1;
+	_lastFrame = 0;
+}
+
+const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
+	if (!_video)
+		return 0;
+
+	if (frameIndex < 0 || frameIndex == _lastFrameIndex)
+		return _lastFrame;
+
+	if (_cacheEnabled) {
+		const Graphics::Surface *cachedFrame = retrieveFrameFromCache(frameIndex);
+		if (cachedFrame)
+			return cachedFrame;
+	}
+
+	if (!_video->seekToFrame(frameIndex))
+		return 0;
+
+	const Graphics::Surface *frame = _video->decodeNextFrame();
+	if (!frame)
+		return 0;
+
+	Graphics::Surface *copy = new Graphics::Surface();
+	copy->copyFrom(*frame);
+
+	if (_cacheEnabled)
+		addFrameToCache(frameIndex, copy);
+
+	return copy;
+}
+
+Graphics::Surface *AVIFrames::getFrameCopy(int frameIndex) {
+	const Graphics::Surface *frame = getFrame(frameIndex);
+	if (!frame)
+		return 0;
+
+	Graphics::Surface *copy = new Graphics::Surface();
+	copy->copyFrom(*frame);
+	return copy;
+}
+
+int AVIFrames::getFrameCount() {
+	if (!_video)
+		return 0;
+
+	return _video->getFrameCount();
+}
+
+bool AVIFrames::flushFrameCache() {
+	if (_cachedFrames.empty())
+		return false;
+
+	for (FrameList::iterator it = _cachedFrames.begin(); it != _cachedFrames.end(); it++) {
+		if (it->frame) {
+			it->frame->free();
+			delete it->frame;
+		}
+	}
+
+	return true;
+}
+
+const Graphics::Surface *AVIFrames::retrieveFrameFromCache(int frameIndex) const {
+	for (FrameList::const_iterator it = _cachedFrames.begin(); it != _cachedFrames.end(); it++)
+		if (it->index == frameIndex)
+			return it->frame;
+
+	return 0;
+}
+
+void AVIFrames::addFrameToCache(int frameIndex, Graphics::Surface *frame) {
+	if (_cachedFrames.size() >= _maxCachedFrames) {
+		CachedFrame &cachedFrame = _cachedFrames.front();
+		if (cachedFrame.frame) {
+			cachedFrame.frame->free();
+			delete cachedFrame.frame;
+		}
+		
+		_cachedFrames.pop_front();
+	}
+
+	_cachedFrames.push_back(CachedFrame(frameIndex, frame));
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/avi_frames.h b/engines/buried/avi_frames.h
new file mode 100644
index 0000000000..6d1ffe8ac0
--- /dev/null
+++ b/engines/buried/avi_frames.h
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_AVI_FRAMES_H
+#define BURIED_AVI_FRAMES_H
+
+#include "common/list.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace Buried {
+
+class AVIFrames {
+public:
+	AVIFrames(const Common::String &fileName, uint cachedFrames = 0);
+	~AVIFrames();
+
+	bool open(const Common::String &fileName, uint cachedFrames = 0);
+	void close();
+
+	const Graphics::Surface *getFrame(int frameIndex);
+	Graphics::Surface *getFrameCopy(int frameIndex);
+
+	int getFrameCount();
+
+	void enableFrameCache(bool enable) { _cacheEnabled = enable; }
+	bool flushFrameCache();
+
+private:
+	const Graphics::Surface *retrieveFrameFromCache(int frameIndex) const;
+	void addFrameToCache(int frameIndex, Graphics::Surface *frame);
+
+	struct CachedFrame {
+		CachedFrame(int i, Graphics::Surface *f) : index(i), frame(f) {}
+
+		int index;
+		Graphics::Surface *frame;
+	};
+
+	typedef Common::List<CachedFrame> FrameList;
+
+	Common::String _fileName;
+	FrameList _cachedFrames;
+	uint _maxCachedFrames;
+	Video::VideoDecoder *_video;
+	bool _cacheEnabled;
+
+	Graphics::Surface *_lastFrame;
+	int _lastFrameIndex;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index e252904cde..2f2d680285 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -1,6 +1,7 @@
 MODULE := engines/buried
 
 MODULE_OBJS = \
+	avi_frames.o \
 	buried.o \
 	database.o \
 	detection.o \


Commit: fe7a58df3cdf1e412293bc3a6d70eff737d53a05
    https://github.com/scummvm/scummvm/commit/fe7a58df3cdf1e412293bc3a6d70eff737d53a05
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Make sure AVI frames are converted to the screen format

Changed paths:
    engines/buried/avi_frames.cpp


diff --git a/engines/buried/avi_frames.cpp b/engines/buried/avi_frames.cpp
index aacb4fcca3..98139c14bc 100644
--- a/engines/buried/avi_frames.cpp
+++ b/engines/buried/avi_frames.cpp
@@ -27,6 +27,7 @@
 #include "buried/buried.h"
 #include "buried/graphics.h"
 
+#include "common/system.h"
 #include "graphics/surface.h"
 #include "video/avi_decoder.h"
 
@@ -113,8 +114,13 @@ const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
 	if (!frame)
 		return 0;
 
-	Graphics::Surface *copy = new Graphics::Surface();
-	copy->copyFrom(*frame);
+	Graphics::Surface *copy;
+	if (frame->format == g_system->getScreenFormat()) {
+		copy = new Graphics::Surface();
+		copy->copyFrom(*frame);
+	} else {
+		copy = frame->convertTo(g_system->getScreenFormat());
+	}
 
 	if (_cacheEnabled)
 		addFrameToCache(frameIndex, copy);


Commit: 77b996462eda0dfac63b16fb834940c8870cc3d2
    https://github.com/scummvm/scummvm/commit/77b996462eda0dfac63b16fb834940c8870cc3d2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add a wrapper to invalidate a whole window

Changed paths:
    engines/buried/window.h


diff --git a/engines/buried/window.h b/engines/buried/window.h
index c95924465c..969013f48b 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -59,6 +59,7 @@ public:
 	virtual void onEnable(bool enable) {}
 
 	void invalidateRect(const Common::Rect &rect, bool erase = true);
+	void invalidateWindow(bool erase = true) { invalidateRect(_rect, erase); }
 	void createChild(const Common::Rect &rect, Window *parent);
 	Window *getParent() const { return _parent; }
 	const Common::Rect &getRect() const { return _rect; }


Commit: b3419fadc316cac4fab014aa2752459842df2336
    https://github.com/scummvm/scummvm/commit/b3419fadc316cac4fab014aa2752459842df2336
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add window class for videos

Changed paths:
  A engines/buried/video_window.cpp
  A engines/buried/video_window.h
    engines/buried/module.mk


diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 2f2d680285..4bc72aff7e 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS = \
 	graphics.o \
 	livetext.o \
 	sound.o \
+	video_window.o \
 	window.o
 
 
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
new file mode 100644
index 0000000000..800b9bd3c6
--- /dev/null
+++ b/engines/buried/video_window.cpp
@@ -0,0 +1,139 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/video_window.h"
+
+#include "video/avi_decoder.h"
+
+namespace Buried {
+
+VideoWindow::VideoWindow(BuriedEngine *vm) : Window(vm), _video(0), _mode(kModeClosed), _lastFrame(0) {
+}
+
+VideoWindow::~VideoWindow() {
+	closeVideo();
+}
+
+bool VideoWindow::playVideo() {
+	if (!_video)
+		return false;
+
+	if (_video->isPlaying())
+		return true;
+
+	_video->start();
+	_mode = kModePlaying;
+	return true;
+}
+
+bool VideoWindow::playToFrame(int frame) {
+	if (!_video)
+		return false;
+
+	_video->setEndFrame(frame);
+
+	if (_video->isPlaying())
+		return true;
+
+	_video->start();
+	_mode = kModePlaying;
+	return true;
+}
+
+bool VideoWindow::seekToFrame(int frame) {
+	if (!_video)
+		return false;
+
+	return _video->seekToFrame(frame);
+}
+
+void VideoWindow::stopVideo() {
+	if (_video) {
+		_video->stop();
+		_mode = kModeStopped;
+	}
+}
+
+int VideoWindow::getCurFrame() {
+	if (_video)
+		return _video->getCurFrame() + 1;
+
+	return -1;
+}
+
+int VideoWindow::getFrameCount() {
+	if (_video)
+		return _video->getFrameCount();
+
+	return 0;
+}
+
+bool VideoWindow::openVideo(const Common::String &fileName) {
+	closeVideo();
+
+	_video = new Video::AVIDecoder();
+
+	if (!_video->loadFile(fileName)) {
+		closeVideo();
+		return false;
+	}
+
+	_mode = kModeOpen;
+	return true;
+}
+
+void VideoWindow::closeVideo() {
+	if (_video) {
+		delete _video;
+		_video = 0;
+		_mode = kModeClosed;
+		_lastFrame = 0;
+	}
+}
+
+void VideoWindow::updateVideo() {
+	if (_video) {
+		if (_video->needsUpdate()) {
+			// Store the frame for later
+			const Graphics::Surface *frame = _video->decodeNextFrame();
+			if (frame)
+				_lastFrame = frame;
+
+			// Invalidate the window so it gets updated
+			invalidateWindow();
+		}
+
+		if (_video->isPlaying() && _video->endOfVideo()) {
+			_video->stop();
+			_mode = kModeStopped;
+		}
+	}
+}
+
+void VideoWindow::onPaint() {
+	if (_lastFrame)
+		_vm->_gfx->blit(_lastFrame, _rect.left, _rect.top);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
new file mode 100644
index 0000000000..c22a729159
--- /dev/null
+++ b/engines/buried/video_window.h
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_VIDEO_WINDOW_H
+#define BURIED_VIDEO_WINDOW_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Video {
+class VideoDecoder;
+}
+
+namespace Buried {
+
+class VideoWindow : public Window {
+public:
+	VideoWindow(BuriedEngine *vm);
+	~VideoWindow();
+
+	// ScummVM-specific interface
+	void updateVideo();
+
+	// VFW interface
+	bool playVideo(); // MCIWndPlay
+	bool playToFrame(int frame); // MCIWndPlayTo
+	bool seekToFrame(int frame); // MCIWndSeek
+	void stopVideo(); // MCIWndStop
+	int getCurFrame(); // MCIWndGetPosition
+	int getFrameCount(); // MCIWndGetLength
+
+	bool openVideo(const Common::String &fileName); // MCIWndOpen
+	void closeVideo(); // MCIWndClose
+
+	enum Mode {
+		kModeClosed, // "Not ready" is stupid
+		kModeOpen,
+		kModePaused,
+		kModePlaying,
+		kModeSeeking,
+		kModeStopped
+	};
+
+	Mode getMode() const { return _mode; } // MCIWndGetMode
+
+	// Window interface
+	void onPaint();
+
+private:
+	Video::VideoDecoder *_video;
+	const Graphics::Surface *_lastFrame;
+	Mode _mode;
+};
+
+} // End of namespace Buried
+
+#endif


Commit: e9bc4bc1c00b88b4cb1fd94c0e1de71bc4527bb9
    https://github.com/scummvm/scummvm/commit/e9bc4bc1c00b88b4cb1fd94c0e1de71bc4527bb9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add way to initialize a Window with a parent in the constructor

Changed paths:
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 4e9d5bfa74..ae3ad4f18e 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -29,8 +29,7 @@
 
 namespace Buried {
 
-Window::Window(BuriedEngine *vm) : _vm(vm) {
-	_parent = 0;
+Window::Window(BuriedEngine *vm, Window *parent) : _vm(vm), _parent(parent) {
 	_enabled = true;
 }
 
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 969013f48b..5d25296307 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -37,7 +37,7 @@ struct Message;
 
 class Window {
 public:
-	Window(BuriedEngine *vm);
+	Window(BuriedEngine *vm, Window *parent = 0);
 	virtual ~Window();
 
 	// The message types used by Buried in Time's windows


Commit: b9e1ddfbd78dcaee5186bc4d789ed73702150562
    https://github.com/scummvm/scummvm/commit/b9e1ddfbd78dcaee5186bc4d789ed73702150562
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add a function to decode a bitmap from a file

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 40e2cdc4b2..47ac08132f 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -251,6 +251,23 @@ Graphics::Surface *GraphicsManager::getBitmap(uint32 bitmapID) {
 	return surface;
 }
 
+Graphics::Surface *GraphicsManager::getBitmap(const Common::String &fileName) {
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(fileName);
+
+	if (!stream)
+		error("Could not find bitmap '%s'", fileName.c_str());
+
+	Image::BitmapDecoder decoder;
+	if (!decoder.loadStream(*stream))
+		error("Failed to decode bitmap '%s'", fileName.c_str());
+
+	delete stream;
+
+	Graphics::Surface *surface = new Graphics::Surface();
+	surface->copyFrom(*decoder.getSurface());
+	return surface;
+}
+
 uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
 	if (_vm->isTrueColor())
 		return g_system->getScreenFormat().RGBToColor(r, g, b);
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 82e6bb95b9..60995c52b1 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -70,6 +70,7 @@ public:
 	Graphics::Font *createFont(int size) const;
 	Cursor setCursor(Cursor newCursor);
 	Graphics::Surface *getBitmap(uint32 bitmapID);
+	Graphics::Surface *getBitmap(const Common::String &fileName);
 	uint32 getColor(byte r, byte g, byte b);
 
 	void invalidateRect(const Common::Rect &rect, bool erase = true);


Commit: ae488a3e0bfb44c3ef5d3e4bcf6cd9de9c726677
    https://github.com/scummvm/scummvm/commit/ae488a3e0bfb44c3ef5d3e4bcf6cd9de9c726677
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Also add parent parameter to videos

Changed paths:
    engines/buried/video_window.cpp
    engines/buried/video_window.h


diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 800b9bd3c6..d83b85ee33 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -28,7 +28,7 @@
 
 namespace Buried {
 
-VideoWindow::VideoWindow(BuriedEngine *vm) : Window(vm), _video(0), _mode(kModeClosed), _lastFrame(0) {
+VideoWindow::VideoWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent), _video(0), _mode(kModeClosed), _lastFrame(0) {
 }
 
 VideoWindow::~VideoWindow() {
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
index c22a729159..030485a679 100644
--- a/engines/buried/video_window.h
+++ b/engines/buried/video_window.h
@@ -37,7 +37,7 @@ namespace Buried {
 
 class VideoWindow : public Window {
 public:
-	VideoWindow(BuriedEngine *vm);
+	VideoWindow(BuriedEngine *vm, Window *parent = 0);
 	~VideoWindow();
 
 	// ScummVM-specific interface


Commit: eb3f5a20c91d8123391e2c36fb31ab810b33ca69
    https://github.com/scummvm/scummvm/commit/eb3f5a20c91d8123391e2c36fb31ab810b33ca69
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add some basic Timer code

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index cb6907874d..a26149291a 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -32,7 +32,9 @@
 #include "buried/buried.h"
 #include "buried/database.h"
 #include "buried/graphics.h"
+#include "buried/message.h"
 #include "buried/sound.h"
+#include "buried/window.h"
 
 namespace Buried {
 
@@ -41,6 +43,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_mainEXE = 0;
 	_library = 0;
 	_sound = 0;
+	_timerSeed = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
@@ -165,4 +168,35 @@ Common::SeekableReadStream *BuriedEngine::getINNData(uint32 resourceID) {
 	return _mainEXE->getResourceStream("INNDATA", resourceID);
 }
 
+uint BuriedEngine::createTimer(Window *window, uint period) {
+	uint timer = ++_timerSeed;
+
+	Timer timerInfo;
+	timerInfo.owner = window;
+	timerInfo.period = period;
+	timerInfo.nextTrigger = _system->getMillis() + period;
+
+	_timers[timer] = timerInfo;
+	return timer;
+}
+
+bool BuriedEngine::killTimer(uint timer) {
+	TimerMap::iterator it = _timers.find(timer);
+
+	if (it == _timers.end())
+		return false;
+
+	_timers.erase(it);
+	return true;
+}
+
+void BuriedEngine::updateTimers() {
+	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++) {
+		if (g_system->getMillis() >= it->_value.nextTrigger) {
+			it->_value.nextTrigger += it->_value.period;
+			it->_value.owner->sendMessage(new TimerMessage(it->_key));
+		}
+	}
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 9db03de4be..4e674e9c9c 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -25,6 +25,7 @@
 
 #include "common/scummsys.h"
 #include "common/array.h"
+#include "common/hashmap.h"
 
 #include "engines/engine.h"
 
@@ -40,6 +41,7 @@ struct BuriedGameDescription;
 class Database;
 class GraphicsManager;
 class SoundManager;
+class Window;
 
 class BuriedEngine : public ::Engine {
 protected:
@@ -76,8 +78,22 @@ public:
 	Database *_mainEXE;
 	SoundManager *_sound;
 
+	uint createTimer(Window *window, uint period);
+	bool killTimer(uint timer);
+	void updateTimers();
+
 private:
 	Database *_library;
+
+	struct Timer {
+		Window *owner;
+		uint32 period;
+		uint32 nextTrigger;
+	};
+
+	typedef Common::HashMap<uint, Timer> TimerMap;
+	TimerMap _timers;
+	uint _timerSeed;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index ae3ad4f18e..deae333d8d 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -121,4 +121,12 @@ bool Window::isWindowEnabled() const {
 	return _enabled;
 }
 
+uint Window::setTimer(uint elapse) {
+	return _vm->createTimer(this, elapse);
+}
+
+bool Window::killTimer(uint timer) {
+	return _vm->killTimer(timer);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 5d25296307..3332dc935c 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -69,9 +69,7 @@ public:
 	bool isWindowEnabled() const;
 
 	// TODO:
-	// SetTimer
 	// ShowWindow
-	// KillTimer
 	// BeginPaint (?)
 	// EndPaint (?)
 	// Create
@@ -86,6 +84,9 @@ protected:
 	Window *_parent;
 	Common::Rect _rect;
 
+	uint setTimer(uint elapse);
+	bool killTimer(uint timer);
+
 private:
 	Common::Queue<Message *> _queue;
 	bool _enabled;


Commit: a2c4bd3204331208f6920cf1c33ccdd0c075cb7f
    https://github.com/scummvm/scummvm/commit/a2c4bd3204331208f6920cf1c33ccdd0c075cb7f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Hook up video windows into the engine

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/video_window.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index a26149291a..15abfbf934 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -34,6 +34,7 @@
 #include "buried/graphics.h"
 #include "buried/message.h"
 #include "buried/sound.h"
+#include "buried/video_window.h"
 #include "buried/window.h"
 
 namespace Buried {
@@ -199,4 +200,17 @@ void BuriedEngine::updateTimers() {
 	}
 }
 
+void BuriedEngine::addVideo(VideoWindow *window) {
+	_videos.push_back(window);
+}
+
+void BuriedEngine::removeVideo(VideoWindow *window) {
+	_videos.remove(window);
+}
+
+void BuriedEngine::updateVideos() {
+	for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+		(*it)->updateVideo();
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 4e674e9c9c..9048397a6d 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -25,6 +25,7 @@
 
 #include "common/scummsys.h"
 #include "common/array.h"
+#include "common/list.h"
 #include "common/hashmap.h"
 
 #include "engines/engine.h"
@@ -42,6 +43,7 @@ class Database;
 class GraphicsManager;
 class SoundManager;
 class Window;
+class VideoWindow;
 
 class BuriedEngine : public ::Engine {
 protected:
@@ -82,6 +84,10 @@ public:
 	bool killTimer(uint timer);
 	void updateTimers();
 
+	void addVideo(VideoWindow *window);
+	void removeVideo(VideoWindow *window);
+	void updateVideos();
+
 private:
 	Database *_library;
 
@@ -94,6 +100,9 @@ private:
 	typedef Common::HashMap<uint, Timer> TimerMap;
 	TimerMap _timers;
 	uint _timerSeed;
+
+	typedef Common::List<VideoWindow *> VideoList;
+	VideoList _videos;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index d83b85ee33..eff1c1192b 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -29,10 +29,12 @@
 namespace Buried {
 
 VideoWindow::VideoWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent), _video(0), _mode(kModeClosed), _lastFrame(0) {
+	_vm->addVideo(this);
 }
 
 VideoWindow::~VideoWindow() {
 	closeVideo();
+	_vm->removeVideo(this);
 }
 
 bool VideoWindow::playVideo() {


Commit: d4ee5b07f10901be31a627bd708f2eda832730df
    https://github.com/scummvm/scummvm/commit/d4ee5b07f10901be31a627bd708f2eda832730df
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Ensure videos are in the correct format

Changed paths:
    engines/buried/video_window.cpp
    engines/buried/video_window.h


diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index eff1c1192b..6fe78236e1 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -24,12 +24,16 @@
 #include "buried/graphics.h"
 #include "buried/video_window.h"
 
+#include "common/system.h"
+#include "graphics/surface.h"
 #include "video/avi_decoder.h"
 
 namespace Buried {
 
 VideoWindow::VideoWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent), _video(0), _mode(kModeClosed), _lastFrame(0) {
 	_vm->addVideo(this);
+	_needsPalConversion = false;
+	_ownedFrame = 0;
 }
 
 VideoWindow::~VideoWindow() {
@@ -101,6 +105,17 @@ bool VideoWindow::openVideo(const Common::String &fileName) {
 		return false;
 	}
 
+	if (!_vm->isTrueColor()) {
+		Graphics::PixelFormat videoFormat = _video->getPixelFormat();
+
+		if (videoFormat.bytesPerPixel == 1) {
+			_needsPalConversion = true;
+		} else {
+			_video->setDitheringPalette(_vm->_gfx->getDefaultPalette());
+			_needsPalConversion = false;
+		}
+	}
+
 	_mode = kModeOpen;
 	return true;
 }
@@ -111,6 +126,12 @@ void VideoWindow::closeVideo() {
 		_video = 0;
 		_mode = kModeClosed;
 		_lastFrame = 0;
+
+		if (_ownedFrame) {
+			_ownedFrame->free();
+			delete _ownedFrame;
+			_ownedFrame = 0;
+		}
 	}
 }
 
@@ -119,8 +140,32 @@ void VideoWindow::updateVideo() {
 		if (_video->needsUpdate()) {
 			// Store the frame for later
 			const Graphics::Surface *frame = _video->decodeNextFrame();
-			if (frame)
-				_lastFrame = frame;
+			if (frame) {
+				if (_ownedFrame) {
+					_ownedFrame->free();
+					delete _ownedFrame;
+					_ownedFrame = 0;
+				}
+
+				if (_vm->isTrueColor()) {
+					// Convert to the screen format if necessary
+					if (frame->format == g_system->getScreenFormat()) {
+						_lastFrame = frame;
+					} else {
+						_ownedFrame = frame->convertTo(g_system->getScreenFormat(), _video->getPalette());
+						_lastFrame = _ownedFrame;
+					}
+				} else {
+					if (_needsPalConversion) {
+						// If it's a palette video, ensure it's using the screen palette
+						_ownedFrame = remapPalettedFrame(frame, _video->getPalette());
+						_lastFrame = _ownedFrame;
+					} else {
+						// Assume it's in the right format from dithering
+						_lastFrame = frame;
+					}
+				}
+			}
 
 			// Invalidate the window so it gets updated
 			invalidateWindow();
@@ -138,4 +183,55 @@ void VideoWindow::onPaint() {
 		_vm->_gfx->blit(_lastFrame, _rect.left, _rect.top);
 }
 
+Graphics::Surface *VideoWindow::remapPalettedFrame(const Graphics::Surface *frame, const byte *palette) {
+	// This is pretty much the same as the Cinepak one
+	// It seems to work for the one video I know that needs it (SWLOGO.BTV)
+
+	byte palMap[256];
+	const byte *screenPal = _vm->_gfx->getDefaultPalette();
+
+	for (int i = 0; i < 256; i++) {
+		int r = palette[i * 3];
+		int g = palette[i * 3 + 1];
+		int b = palette[i * 3 + 2];
+
+		int diff = 0x7FFFFFFF;
+		byte result = 0;
+
+		for (int j = 0; j < 256; j++) {
+			int bDiff = b - (int)screenPal[j * 3 + 2];
+			int curDiffB = diff - (bDiff * bDiff);
+
+			if (curDiffB > 0) {
+				int gDiff = g - (int)screenPal[j * 3 + 1];
+				int curDiffG = curDiffB - (gDiff * gDiff);
+
+				if (curDiffG > 0) {
+					int rDiff = r - (int)screenPal[j * 3];
+					int curDiffR = curDiffG - (rDiff * rDiff);
+
+					if (curDiffR > 0) {
+						diff -= curDiffR;
+						result = j;
+
+						if (diff == 0)
+							break;
+					}
+				}
+			}
+		}
+
+		palMap[i] = result;
+	}
+
+	Graphics::Surface *convertedSurface = new Graphics::Surface();
+	convertedSurface->create(frame->w, frame->h, frame->format);
+
+	for (int y = 0; y < frame->h; y++)
+		for (int x = 0; x < frame->w; x++)
+			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((byte *)frame->getBasePtr(x, y))];
+
+	return convertedSurface;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
index 030485a679..4a4103d86e 100644
--- a/engines/buried/video_window.h
+++ b/engines/buried/video_window.h
@@ -72,6 +72,10 @@ private:
 	Video::VideoDecoder *_video;
 	const Graphics::Surface *_lastFrame;
 	Mode _mode;
+	Graphics::Surface *_ownedFrame;
+	bool _needsPalConversion;
+
+	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 };
 
 } // End of namespace Buried


Commit: de5d0b4350054b2ced3a19ba542facb61d91da2a
    https://github.com/scummvm/scummvm/commit/de5d0b4350054b2ced3a19ba542facb61d91da2a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Make the video window resize to the video size

Changed paths:
    engines/buried/video_window.cpp


diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 6fe78236e1..837c733e16 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -117,6 +117,7 @@ bool VideoWindow::openVideo(const Common::String &fileName) {
 	}
 
 	_mode = kModeOpen;
+	_rect = Common::Rect(_video->getWidth(), _video->getHeight());
 	return true;
 }
 
@@ -126,6 +127,7 @@ void VideoWindow::closeVideo() {
 		_video = 0;
 		_mode = kModeClosed;
 		_lastFrame = 0;
+		_rect = Common::Rect();
 
 		if (_ownedFrame) {
 			_ownedFrame->free();


Commit: 9db1bff262efbe7cda33119b0b54d3ffe19cac90
    https://github.com/scummvm/scummvm/commit/9db1bff262efbe7cda33119b0b54d3ffe19cac90
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Have windows maintain order and position

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/livetext.cpp
    engines/buried/message.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 15abfbf934..e369b0c40d 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -45,6 +45,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_library = 0;
 	_sound = 0;
 	_timerSeed = 0;
+	_mainWindow = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
@@ -52,6 +53,7 @@ BuriedEngine::~BuriedEngine() {
 	delete _mainEXE;
 	delete _library;
 	delete _sound;
+	delete _mainWindow;
 }
 
 Common::Error BuriedEngine::run() {
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 9048397a6d..24caac1d66 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -79,6 +79,7 @@ public:
 	GraphicsManager *_gfx;
 	Database *_mainEXE;
 	SoundManager *_sound;
+	Window *_mainWindow; // Only one main window is supported.
 
 	uint createTimer(Window *window, uint period);
 	bool killTimer(uint timer);
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 47ac08132f..705c3e3294 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -36,11 +36,13 @@
 #include "buried/buried.h"
 #include "buried/database.h"
 #include "buried/graphics.h"
+#include "buried/window.h"
 
 namespace Buried {
 
 GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
 	_curCursor = kCursorNone;
+	_mouseMoved = false;
 
 	setCursor(kCursorArrow);
 	CursorMan.showMouse(true);
@@ -292,9 +294,30 @@ uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
 	return best;
 }
 
-void GraphicsManager::invalidateRect(const Common::Rect &rect, bool erase) {
+void GraphicsManager::invalidateRect(const Common::Rect &rect) {
 	_dirtyRect.extend(rect);
-	// TODO: Erase?
+}
+
+void GraphicsManager::updateScreen() {
+	bool shouldUpdateScreen = _mouseMoved;
+	_mouseMoved = false;
+
+	if (!_dirtyRect.isEmpty()) {
+		// Draw the main window, which will draw its children
+		_vm->_mainWindow->updateWindow();
+
+		// Copy just that rect
+		g_system->copyRectToScreen(_screen->getPixels(), _screen->pitch, _dirtyRect.left, _dirtyRect.top, _dirtyRect.width(), _dirtyRect.height());
+
+		// Empty out the dirty rect
+		_dirtyRect = Common::Rect();
+
+		// Definitely update
+		shouldUpdateScreen = true;
+	}
+
+	if (shouldUpdateScreen)
+		g_system->updateScreen();
 }
 
 void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 60995c52b1..bacedddd89 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -73,8 +73,11 @@ public:
 	Graphics::Surface *getBitmap(const Common::String &fileName);
 	uint32 getColor(byte r, byte g, byte b);
 
-	void invalidateRect(const Common::Rect &rect, bool erase = true);
+	void invalidateRect(const Common::Rect &rect);
+	const Common::Rect &getDirtyRect() const { return _dirtyRect; }
 
+	void markMouseMoved() { _mouseMoved = true; }
+	void updateScreen();
 	Graphics::Surface *getScreen() const { return _screen; }
 
 	void blit(const Graphics::Surface *surface, int x, int y);
@@ -84,6 +87,7 @@ private:
 	Cursor _curCursor;
 
 	Common::Rect _dirtyRect;
+	bool _mouseMoved;
 	Graphics::Surface *_screen;
 	byte *_palette;
 	
diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index 56579c4e85..01d6dbad8e 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -34,7 +34,7 @@
 
 namespace Buried {
 
-LiveTextWindow::LiveTextWindow(BuriedEngine *vm, Window *parent) : Window(vm) {
+LiveTextWindow::LiveTextWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
 	// Initialize member variables to empty
 	_textTranslation = false;
 
@@ -42,7 +42,7 @@ LiveTextWindow::LiveTextWindow(BuriedEngine *vm, Window *parent) : Window(vm) {
 	_font = _vm->_gfx->createFont(14);
 
 	// Create window
-	createChild(Common::Rect(137, 21, 447, 87), parent);
+	_rect = Common::Rect(137, 21, 447, 87);
 
 	// Update the text in the window
 	updateLiveText(_vm->getString(IDS_SAVE_GAME_MESSAGE), false);
diff --git a/engines/buried/message.h b/engines/buried/message.h
index 50c659abbe..fee2621413 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -34,7 +34,6 @@ namespace Buried {
 class Window;
 
 enum MessageType {
-	kMessageTypeEraseBackground,
 	kMessageTypeKeyUp,
 	kMessageTypeKeyDown,
 	kMessageTypeTimer,
@@ -105,7 +104,6 @@ private:
 };
 
 // Types for everything that falls under one of the above categories
-typedef MessageTypeIntern<kMessageTypeEraseBackground> EraseBackgroundMessage;
 typedef KeyMessage<kMessageTypeKeyUp>                  KeyUpMessage;
 typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
 typedef WindowMessage<kMessageTypeSetFocus>            SetFocusMessage;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index deae333d8d..5d44fbe388 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -20,6 +20,7 @@
  *
  */
 
+#include "common/algorithm.h"
 #include "common/textconsole.h"
 
 #include "buried/buried.h"
@@ -29,37 +30,48 @@
 
 namespace Buried {
 
-Window::Window(BuriedEngine *vm, Window *parent) : _vm(vm), _parent(parent) {
+const Window *kWindowPosTop = (const Window *)0;
+const Window *kWindowPosTopMost = (const Window *)-1;
+
+Window::Window(BuriedEngine *vm, Window *parent, bool visible) : _vm(vm), _parent(parent), _visible(visible) {
 	_enabled = true;
+	_needsErase = false;
+
+	// Add us to the top of the parent's window list
+	if (_parent)
+		_parent->_children.push_back(this);
 }
 
 Window::~Window() {
 	// Make sure the queue is cleaned out
 	while (!_queue.empty())
 		delete _queue.pop();
-}
 
-void Window::invalidateRect(const Common::Rect &rect, bool erase) {
-	_vm->_gfx->invalidateRect(rect, erase);
+	// Remove us from any of the parent's window lists
+	if (_parent) {
+		_parent->_children.remove(this);
+		_parent->_topMostChildren.remove(this);
+	}
 }
 
-void Window::createChild(const Common::Rect &rect, Window *parent) {
-	_rect = rect;
-	_parent = parent;
+void Window::invalidateRect(const Common::Rect &rect, bool erase) {
+	_vm->_gfx->invalidateRect(makeAbsoluteRect(rect));
+	_needsErase |= erase;
 }
 
 Common::Rect Window::getClientRect() const {
 	return Common::Rect(_rect.width(), _rect.height());
 }
 
+Common::Rect Window::getAbsoluteRect() const {
+	return makeAbsoluteRect(_rect);
+}
+
 void Window::dispatchAllMessages() {
 	while (!_queue.empty() && !_vm->shouldQuit()) {
 		Message *message = _queue.pop();
 
 		switch (message->getMessageType()) {
-		case kMessageTypeEraseBackground:
-			onEraseBackground();
-			break;
 		case kMessageTypeKeyUp:
 			onKeyUp(((KeyUpMessage *)message)->getKeyState(), ((KeyUpMessage *)message)->getFlags());
 			break;
@@ -107,6 +119,92 @@ void Window::dispatchAllMessages() {
 	}
 }
 
+void Window::updateWindow() {
+	// If we're not visible, ignore
+	if (!isWindowVisible())
+		return;
+
+	// If we're not in the dirty rect, ignore
+	if (!_vm->_gfx->getDirtyRect().intersects(getAbsoluteRect()))
+		return;
+
+	// If we need to erase, erase first
+	if (_needsErase) {
+		onEraseBackground();
+		_needsErase = false;
+	}
+
+	// Always draw this window first
+	onPaint();
+
+	// Draw children
+	for (WindowList::iterator it = _children.begin(); it != _children.end(); it++)
+		(*it)->updateWindow();
+
+	// Draw top-most children
+	for (WindowList::iterator it = _topMostChildren.begin(); it != _topMostChildren.end(); it++)
+		(*it)->updateWindow();
+}
+
+void Window::setWindowPos(Window *insertAfter, int x, int y, int width, int height, uint flags) {
+	if (!(flags & kWindowPosNoZOrder)) {
+		assert(insertAfter != this); // I don't even want to think about this case
+
+		_parent->_children.remove(this);
+		_parent->_topMostChildren.remove(this);
+
+		if (insertAfter == kWindowPosTop) {
+			// Reposition the window to the top
+			_parent->_children.push_back(this);
+		} else if (insertAfter == kWindowPosTopMost) {
+			// Reposition the window to the top of the top-most
+			_parent->_topMostChildren.push_back(this);
+		} else {
+			// Reposition the window to after insertAfter
+			WindowList::iterator it = Common::find(_parent->_children.begin(), _parent->_children.end(), insertAfter);
+
+			if (it == _parent->_children.end()) {
+				it = Common::find(_parent->_topMostChildren.begin(), _parent->_topMostChildren.end(), insertAfter);
+
+				// It has to be in one of the lists
+				assert(it != _parent->_topMostChildren.end());
+
+				_parent->_topMostChildren.insert(it, this);
+			} else {
+				_parent->_children.insert(it, this);
+			}
+		}
+	}
+
+	if (flags & kWindowPosShowWindow) {
+		assert(!(flags & kWindowPosHideWindow));
+		showWindow(kWindowShow);
+	} else if (flags & kWindowPosHideWindow) {
+		assert(!(flags & kWindowPosShowWindow));
+		showWindow(kWindowHide);
+	}
+
+	if (!(flags & kWindowPosNoActivate)) {
+		// TODO: Activate the window
+	}
+
+	if (!(flags & kWindowPosNoMove))
+		_rect.moveTo(x, y);
+
+	if (!(flags & kWindowPosNoSize)) {
+		_rect.right = _rect.left + width;
+		_rect.bottom = _rect.top + height;
+	}
+}
+
+void Window::showWindow(WindowShowMode showMode) {
+	_visible = (showMode != kWindowHide);
+
+	if (showMode == kWindowShowNormal) {
+		// TODO: Activate
+	}
+}
+
 void Window::enableWindow(bool enable) {
 	if (_enabled != enable) {
 		_enabled = enable;
@@ -129,4 +227,15 @@ bool Window::killTimer(uint timer) {
 	return _vm->killTimer(timer);
 }
 
+Common::Rect Window::makeAbsoluteRect(const Common::Rect &rect) const {
+	// No parent; it's already absolute
+	if (!_parent)
+		return rect;
+
+	Common::Rect parentRect = _parent->getAbsoluteRect();
+	Common::Rect absoluteRect = rect;
+	absoluteRect.translate(parentRect.left, parentRect.top);
+	return absoluteRect;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 3332dc935c..4df2acb529 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -37,7 +37,7 @@ struct Message;
 
 class Window {
 public:
-	Window(BuriedEngine *vm, Window *parent = 0);
+	Window(BuriedEngine *vm, Window *parent, bool visible = true);
 	virtual ~Window();
 
 	// The message types used by Buried in Time's windows
@@ -60,13 +60,36 @@ public:
 
 	void invalidateRect(const Common::Rect &rect, bool erase = true);
 	void invalidateWindow(bool erase = true) { invalidateRect(_rect, erase); }
-	void createChild(const Common::Rect &rect, Window *parent);
 	Window *getParent() const { return _parent; }
 	const Common::Rect &getRect() const { return _rect; }
 	Common::Rect getClientRect() const;
-	void updateWindow() { onPaint(); }
+	Common::Rect getAbsoluteRect() const;
+	void updateWindow();
 	void enableWindow(bool enable);
 	bool isWindowEnabled() const;
+	void setWindowPos(Window *insertAfter, int x, int y, int width, int height, uint flags);
+
+	// The subset of show modes we'll accept
+	enum WindowShowMode {
+		kWindowShow,
+		kWindowHide,
+		kWindowShowNormal
+	};
+
+	void showWindow(WindowShowMode showMode);
+	bool isWindowVisible() const { return _visible; }
+
+	// The subset of flags we'll accept
+	enum WindowPosFlags {
+		kWindowPosNoFlags = 0,
+
+		kWindowPosNoSize = (1 << 0),
+		kWindowPosNoZOrder = (1 << 1),
+		kWindowPosHideWindow = (1 << 2),
+		kWindowPosShowWindow = (1 << 3),
+		kWindowPosNoMove = (1 << 4),
+		kWindowPosNoActivate = (1 << 5)
+	};
 
 	// TODO:
 	// ShowWindow
@@ -87,11 +110,22 @@ protected:
 	uint setTimer(uint elapse);
 	bool killTimer(uint timer);
 
+	Common::Rect makeAbsoluteRect(const Common::Rect &rect) const;
+
 private:
 	Common::Queue<Message *> _queue;
-	bool _enabled;
+	bool _enabled, _visible;
+	bool _needsErase;
+
+	typedef Common::List<Window *> WindowList;
+	WindowList _children, _topMostChildren;
 };
 
+// A subset of the special insert after Window handles
+// (Values declared in window.cpp)
+extern const Window *kWindowPosTop;
+extern const Window *kWindowPosTopMost;
+
 } // End of namespace Buried
 
 #endif


Commit: fdf7982f320d02e77144cee828d31a09390a5777
    https://github.com/scummvm/scummvm/commit/fdf7982f320d02e77144cee828d31a09390a5777
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add wrapper to fill a rect on the screen

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 705c3e3294..bc7b184d7a 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -327,6 +327,10 @@ void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
 		memcpy(_screen->getBasePtr(x, y + i), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
 }
 
+void GraphicsManager::fillRect(const Common::Rect &rect, uint32 color) {
+	_screen->fillRect(rect, color);
+}
+
 byte *GraphicsManager::createDefaultPalette() const {
 	Common::SeekableReadStream *stream = _vm->getBitmapStream(700);
 
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index bacedddd89..dc2ca61049 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -81,6 +81,7 @@ public:
 	Graphics::Surface *getScreen() const { return _screen; }
 
 	void blit(const Graphics::Surface *surface, int x, int y);
+	void fillRect(const Common::Rect &rect, uint32 color);
 
 private:
 	BuriedEngine *_vm;


Commit: 4e630357a7ce15f9e8e8da6f1e9baa2cf1b0fb5c
    https://github.com/scummvm/scummvm/commit/4e630357a7ce15f9e8e8da6f1e9baa2cf1b0fb5c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Make dispatchAllMessages also dispatch the children's messages

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 5d44fbe388..e275e1f347 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -68,6 +68,7 @@ Common::Rect Window::getAbsoluteRect() const {
 }
 
 void Window::dispatchAllMessages() {
+	// Dispatch all of our messages
 	while (!_queue.empty() && !_vm->shouldQuit()) {
 		Message *message = _queue.pop();
 
@@ -117,6 +118,13 @@ void Window::dispatchAllMessages() {
 
 		delete message;
 	}
+
+	// Also dispatch any children's messages
+	for (WindowList::iterator it = _children.begin(); it != _children.end() && !_vm->shouldQuit(); it++)
+		(*it)->dispatchAllMessages();
+
+	for (WindowList::iterator it = _topMostChildren.begin(); it != _topMostChildren.end() && !_vm->shouldQuit(); it++)
+		(*it)->dispatchAllMessages();
 }
 
 void Window::updateWindow() {


Commit: 470879c98be832468fdc78e558fdcfd68ac69576
    https://github.com/scummvm/scummvm/commit/470879c98be832468fdc78e558fdcfd68ac69576
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add the title sequence window

Changed paths:
  A engines/buried/title_sequence.cpp
  A engines/buried/title_sequence.h
    engines/buried/module.mk


diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 4bc72aff7e..391d4d5450 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS = \
 	graphics.o \
 	livetext.o \
 	sound.o \
+	title_sequence.o \
 	video_window.o \
 	window.o
 
diff --git a/engines/buried/title_sequence.cpp b/engines/buried/title_sequence.cpp
new file mode 100644
index 0000000000..236f9ba231
--- /dev/null
+++ b/engines/buried/title_sequence.cpp
@@ -0,0 +1,173 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/title_sequence.h"
+#include "buried/resources.h"
+#include "buried/video_window.h"
+
+#include "graphics/surface.h"
+
+namespace Buried {
+
+TitleSequenceWindow::TitleSequenceWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	// Initialize member variables
+	_currentBackground = 0;
+	_currentMovie = 0;
+	_exitNow = false;
+	_currentAnimation = 0;
+
+	// Create a rect to use to place the window inside the parent
+	Common::Rect parentRect = parent->getRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = _rect.left + 640;
+	_rect.bottom = _rect.top + 480;
+
+	_timerID = setTimer(1000);
+}
+
+TitleSequenceWindow::~TitleSequenceWindow() {
+	if (_currentBackground) {
+		_currentBackground->free();
+		delete _currentBackground;
+	}
+
+	delete _currentMovie;
+
+	killTimer(_timerID);
+}
+
+bool TitleSequenceWindow::playTitleSequence() {
+	switch (_currentAnimation) {
+	case 0: // Display Sanctuary Woods Logo
+		// Clean the window
+		invalidateWindow();
+
+		_currentMovie = new VideoWindow(_vm, this);
+
+		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_SW_LOGO_FILENAME))) {
+			delete _currentMovie;
+			_currentMovie = 0;
+			// TODO: Return to main menu
+			return false;
+		}
+
+		_currentMovie->setWindowPos(0, 195, 115, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+		_currentMovie->enableWindow(false);
+		_currentMovie->playVideo();
+		_currentAnimation = 1;
+		return true;
+	case 1: // Display Presto Studios Logo
+		// Clean the window
+		invalidateWindow();
+
+		_currentMovie = new VideoWindow(_vm, this);
+
+		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_PRESTO_LOGO_FILENAME))) {
+			delete _currentMovie;
+			_currentMovie = 0;
+			// TODO: Return to main menu
+			return false;
+		}
+
+		_currentMovie->setWindowPos(0, 200, 60, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+		_currentMovie->enableWindow(false);
+		_currentMovie->playVideo();
+		_currentAnimation = 2;
+		return true;
+	case 2: // Display the intro credits movie
+		_currentBackground = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_TITLE_STARFIELD_FILENAME));
+
+		_currentMovie = new VideoWindow(_vm, this);
+
+		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_MOVIE_FILENAME))) {
+			delete _currentMovie;
+			_currentMovie = 0;
+			// TODO: Return to main menu
+			return false;
+		}
+
+		_currentMovie->setWindowPos(0, 60, 138, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+		_currentMovie->enableWindow(false);
+		invalidateWindow();
+		_currentMovie->playVideo();
+		_currentAnimation = 3;
+		return true;
+	case 3: // Exit the title sequence
+		// TODO: Return to main menu
+		return true;
+	}
+
+	return true;
+}
+
+void TitleSequenceWindow::onPaint() {
+	if (_currentBackground)
+		_vm->_gfx->blit(_currentBackground, 0, 0);
+}
+
+bool TitleSequenceWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void TitleSequenceWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	_exitNow = true;
+}
+
+void TitleSequenceWindow::onMButtonUp(const Common::Point &point, uint flags) {
+	_exitNow = true;
+}
+
+void TitleSequenceWindow::onRButtonUp(const Common::Point &point, uint flags) {
+	_exitNow = true;
+}
+
+void TitleSequenceWindow::onKeyUp(const Common::KeyState &key, uint flags) {
+	_exitNow = true;
+}
+
+void TitleSequenceWindow::onTimer(uint timer) {
+	if (_exitNow || (_currentMovie && _currentMovie->getMode() == VideoWindow::kModeStopped)) {
+		// Destroy all resources
+		if (_currentBackground) {
+			_currentBackground->free();
+			delete _currentBackground;
+			_currentBackground = 0;
+		}
+
+		delete _currentMovie;
+		_currentMovie = 0;
+
+		// Clean out the input queue
+		_exitNow = false;
+
+		playTitleSequence();
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/title_sequence.h b/engines/buried/title_sequence.h
new file mode 100644
index 0000000000..910289fc9b
--- /dev/null
+++ b/engines/buried/title_sequence.h
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_TITLE_SEQUENCE_H
+#define BURIED_TITLE_SEQUENCE_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class VideoWindow;
+
+class TitleSequenceWindow : public Window {
+public:
+	TitleSequenceWindow(BuriedEngine *vm, Window *parent);
+	~TitleSequenceWindow();
+
+	bool playTitleSequence();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onMButtonUp(const Common::Point &point, uint flags);
+	void onRButtonUp(const Common::Point &point, uint flags);
+	void onKeyUp(const Common::KeyState &key, uint flags);
+	void onTimer(uint timer);
+
+private:
+	Graphics::Surface *_currentBackground;
+	bool _exitNow;
+	int _currentAnimation;
+	uint _timerID;
+	VideoWindow *_currentMovie;
+};
+
+} // End of namespace Buried
+
+#endif


Commit: 229db8dd21b3f79ced0f24dda5ac4f92af5625cf
    https://github.com/scummvm/scummvm/commit/229db8dd21b3f79ced0f24dda5ac4f92af5625cf
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Show the title sequence in the full game

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index e369b0c40d..b78c03f115 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -37,6 +37,9 @@
 #include "buried/video_window.h"
 #include "buried/window.h"
 
+#include "buried/title_sequence.h"
+#include "common/events.h"
+
 namespace Buried {
 
 BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
@@ -92,12 +95,38 @@ Common::Error BuriedEngine::run() {
 
 	_gfx = new GraphicsManager(this);
 	_sound = new SoundManager(this);
+	
+	// HACK: Show the intro for now in the full game
+	if (isDemo())
+		return Common::kNoError;
+
+	_mainWindow = new Window(this, 0);
+	_mainWindow->setWindowPos(0, 0, 0, 640, 480, Window::kWindowPosNoZOrder);
+	TitleSequenceWindow *titleSeq = new TitleSequenceWindow(this, _mainWindow);
+	titleSeq->playTitleSequence();
+
+	while (!shouldQuit()) {
+		updateTimers();
+		updateVideos();
+
+		Common::Event event;
+		while (_eventMan->pollEvent(event)) {
+			switch (event.type) {
+			case Common::EVENT_MOUSEMOVE:
+				_gfx->markMouseMoved();
+				break;
+			default:
+				break;
+			}
+		}
+
+		_mainWindow->dispatchAllMessages();
+
+		_gfx->updateScreen();
+		_system->delayMillis(10);
+	}
 
-	// TODO: Event loop
-	// - Dispatch window events
-	// - Poll events
-	// - Call UpdateWindow for the windows
-	// - Update timers
+	delete titleSeq;
 
 	return Common::kNoError;
 }


Commit: bb7bd2ff4e51422d311008e1723e791faaff7f88
    https://github.com/scummvm/scummvm/commit/bb7bd2ff4e51422d311008e1723e791faaff7f88
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add basic keyboard input support

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/message.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b78c03f115..6d594df4b1 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -49,6 +49,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_sound = 0;
 	_timerSeed = 0;
 	_mainWindow = 0;
+	_focusedWindow = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
@@ -103,6 +104,7 @@ Common::Error BuriedEngine::run() {
 	_mainWindow = new Window(this, 0);
 	_mainWindow->setWindowPos(0, 0, 0, 640, 480, Window::kWindowPosNoZOrder);
 	TitleSequenceWindow *titleSeq = new TitleSequenceWindow(this, _mainWindow);
+	titleSeq->setFocus();
 	titleSeq->playTitleSequence();
 
 	while (!shouldQuit()) {
@@ -115,6 +117,16 @@ Common::Error BuriedEngine::run() {
 			case Common::EVENT_MOUSEMOVE:
 				_gfx->markMouseMoved();
 				break;
+			case Common::EVENT_KEYUP:
+				// TODO: Key flags
+				if (_focusedWindow)
+					_focusedWindow->sendMessage(new KeyUpMessage(event.kbd, 0));
+				break;
+			case Common::EVENT_KEYDOWN:
+				// TODO: Key flags
+				if (_focusedWindow)
+					_focusedWindow->sendMessage(new KeyDownMessage(event.kbd, 0));
+				break;
 			default:
 				break;
 			}
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 24caac1d66..4067384f96 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -80,6 +80,7 @@ public:
 	Database *_mainEXE;
 	SoundManager *_sound;
 	Window *_mainWindow; // Only one main window is supported.
+	Window *_focusedWindow;
 
 	uint createTimer(Window *window, uint period);
 	bool killTimer(uint timer);
diff --git a/engines/buried/message.h b/engines/buried/message.h
index fee2621413..8640842818 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -37,8 +37,6 @@ enum MessageType {
 	kMessageTypeKeyUp,
 	kMessageTypeKeyDown,
 	kMessageTypeTimer,
-	kMessageTypeSetFocus,
-	kMessageTypeKillFocus,
 	kMessageTypeMouseMove,
 	kMessageTypeLButtonUp,
 	kMessageTypeLButtonDown,
@@ -106,8 +104,6 @@ private:
 // Types for everything that falls under one of the above categories
 typedef KeyMessage<kMessageTypeKeyUp>                  KeyUpMessage;
 typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
-typedef WindowMessage<kMessageTypeSetFocus>            SetFocusMessage;
-typedef WindowMessage<kMessageTypeKillFocus>           KillFocusMessage;
 typedef MouseMessage<kMessageTypeMouseMove>            MouseMoveMessage;
 typedef MouseMessage<kMessageTypeLButtonUp>            LButtonUpMessage;
 typedef MouseMessage<kMessageTypeLButtonDown>          LButtonDownMessage;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index e275e1f347..f6ae7a6d10 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -82,12 +82,6 @@ void Window::dispatchAllMessages() {
 		case kMessageTypeTimer:
 			onTimer(((TimerMessage *)message)->getTimer());
 			break;
-		case kMessageTypeSetFocus:
-			onSetFocus(((SetFocusMessage *)message)->getWindow());
-			break;
-		case kMessageTypeKillFocus:
-			onKillFocus(((KillFocusMessage *)message)->getWindow());
-			break;
 		case kMessageTypeLButtonUp:
 			onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
 			break;
@@ -246,4 +240,22 @@ Common::Rect Window::makeAbsoluteRect(const Common::Rect &rect) const {
 	return absoluteRect;
 }
 
+Window *Window::setFocus() {
+	// Don't allow focus to be acquired if the window is disabled
+	if (!isWindowEnabled())
+		return 0;
+
+	Window *oldWindow = 0;
+
+	// Notify the old window we just took its focus
+	if (_vm->_focusedWindow) {
+		_vm->_focusedWindow->onKillFocus(this);
+		oldWindow = _vm->_focusedWindow;
+	}
+
+	_vm->_focusedWindow = this;
+	onSetFocus(oldWindow);
+	return oldWindow;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 4df2acb529..b6eea2c750 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -91,6 +91,8 @@ public:
 		kWindowPosNoActivate = (1 << 5)
 	};
 
+	Window *setFocus();
+
 	// TODO:
 	// ShowWindow
 	// BeginPaint (?)


Commit: bd1d0d7796c3d30f6e1ecd78085600d6cce4f676
    https://github.com/scummvm/scummvm/commit/bd1d0d7796c3d30f6e1ecd78085600d6cce4f676
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add initial mouse support

Changed paths:
    engines/buried/buried.cpp
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 6d594df4b1..5cb508bea6 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -111,22 +111,40 @@ Common::Error BuriedEngine::run() {
 		updateTimers();
 		updateVideos();
 
+		// TODO: Key flags
+		// TODO: Mouse flags
+
 		Common::Event event;
 		while (_eventMan->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_MOUSEMOVE:
 				_gfx->markMouseMoved();
+				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new MouseMoveMessage(event.mouse, 0));
 				break;
 			case Common::EVENT_KEYUP:
-				// TODO: Key flags
 				if (_focusedWindow)
 					_focusedWindow->sendMessage(new KeyUpMessage(event.kbd, 0));
 				break;
 			case Common::EVENT_KEYDOWN:
-				// TODO: Key flags
 				if (_focusedWindow)
 					_focusedWindow->sendMessage(new KeyDownMessage(event.kbd, 0));
 				break;
+			case Common::EVENT_LBUTTONDOWN:
+				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new LButtonDownMessage(event.mouse, 0));
+				break;
+			case Common::EVENT_LBUTTONUP:
+				// TODO: Double-click
+				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new LButtonUpMessage(event.mouse, 0));
+				break;
+			case Common::EVENT_MBUTTONUP:
+				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new MButtonUpMessage(event.mouse, 0));
+				break;
+			case Common::EVENT_RBUTTONDOWN:
+				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new RButtonDownMessage(event.mouse, 0));
+				break;
+			case Common::EVENT_RBUTTONUP:
+				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new RButtonUpMessage(event.mouse, 0));
+				break;
 			default:
 				break;
 			}
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index f6ae7a6d10..c03063dc71 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -82,6 +82,9 @@ void Window::dispatchAllMessages() {
 		case kMessageTypeTimer:
 			onTimer(((TimerMessage *)message)->getTimer());
 			break;
+		case kMessageTypeMouseMove:
+			onMouseMove(((MouseMoveMessage *)message)->getPoint(), ((MouseMoveMessage *)message)->getFlags());
+			break;
 		case kMessageTypeLButtonUp:
 			onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
 			break;
@@ -258,4 +261,16 @@ Window *Window::setFocus() {
 	return oldWindow;
 }
 
+Window *Window::findWindowAtPoint(const Common::Point &point) {
+	for (WindowList::iterator it = _topMostChildren.reverse_begin(); it != _topMostChildren.end(); it--)
+		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
+			return (*it)->findWindowAtPoint(point);
+
+	for (WindowList::iterator it = _children.reverse_begin(); it != _children.end(); it--)
+		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
+			return (*it)->findWindowAtPoint(point);
+
+	return this;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index b6eea2c750..c8378fe228 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -103,6 +103,8 @@ public:
 	void sendMessage(Message *message) { _queue.push(message); }
 	void dispatchAllMessages();
 
+	Window *findWindowAtPoint(const Common::Point &point);
+
 protected:
 	BuriedEngine *_vm;
 


Commit: ca54be6b1f29d9520736baa2da97d3855efd0b55
    https://github.com/scummvm/scummvm/commit/ca54be6b1f29d9520736baa2da97d3855efd0b55
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Switch to a single message queue

And other message-related cleanup

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 5cb508bea6..581e35fcf6 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -58,6 +58,8 @@ BuriedEngine::~BuriedEngine() {
 	delete _library;
 	delete _sound;
 	delete _mainWindow;
+
+	// The queue should be empty since all windows destroy their messages
 }
 
 Common::Error BuriedEngine::run() {
@@ -119,38 +121,38 @@ Common::Error BuriedEngine::run() {
 			switch (event.type) {
 			case Common::EVENT_MOUSEMOVE:
 				_gfx->markMouseMoved();
-				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new MouseMoveMessage(event.mouse, 0));
+				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MouseMoveMessage(event.mouse, 0));
 				break;
 			case Common::EVENT_KEYUP:
 				if (_focusedWindow)
-					_focusedWindow->sendMessage(new KeyUpMessage(event.kbd, 0));
+					_focusedWindow->postMessage(new KeyUpMessage(event.kbd, 0));
 				break;
 			case Common::EVENT_KEYDOWN:
 				if (_focusedWindow)
-					_focusedWindow->sendMessage(new KeyDownMessage(event.kbd, 0));
+					_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
 				break;
 			case Common::EVENT_LBUTTONDOWN:
-				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new LButtonDownMessage(event.mouse, 0));
+				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonDownMessage(event.mouse, 0));
 				break;
 			case Common::EVENT_LBUTTONUP:
 				// TODO: Double-click
-				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new LButtonUpMessage(event.mouse, 0));
+				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonUpMessage(event.mouse, 0));
 				break;
 			case Common::EVENT_MBUTTONUP:
-				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new MButtonUpMessage(event.mouse, 0));
+				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MButtonUpMessage(event.mouse, 0));
 				break;
 			case Common::EVENT_RBUTTONDOWN:
-				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new RButtonDownMessage(event.mouse, 0));
+				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonDownMessage(event.mouse, 0));
 				break;
 			case Common::EVENT_RBUTTONUP:
-				_mainWindow->findWindowAtPoint(event.mouse)->sendMessage(new RButtonUpMessage(event.mouse, 0));
+				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonUpMessage(event.mouse, 0));
 				break;
 			default:
 				break;
 			}
 		}
 
-		_mainWindow->dispatchAllMessages();
+		sendAllMessages();
 
 		_gfx->updateScreen();
 		_system->delayMillis(10);
@@ -256,7 +258,7 @@ void BuriedEngine::updateTimers() {
 	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++) {
 		if (g_system->getMillis() >= it->_value.nextTrigger) {
 			it->_value.nextTrigger += it->_value.period;
-			it->_value.owner->sendMessage(new TimerMessage(it->_key));
+			it->_value.owner->postMessage(new TimerMessage(it->_key));
 		}
 	}
 }
@@ -274,4 +276,54 @@ void BuriedEngine::updateVideos() {
 		(*it)->updateVideo();
 }
 
+void BuriedEngine::postMessageToWindow(Window *dest, Message *message) {
+	MessageInfo msg;
+	msg.dest = dest;
+	msg.message = message;
+	_messageQueue.push_back(msg);
+}
+
+void BuriedEngine::sendAllMessages() {
+	while (!_messageQueue.empty()) {
+		MessageInfo msg = _messageQueue.front();
+		_messageQueue.pop_front();
+
+		msg.dest->sendMessage(msg.message);
+		// Control of the pointer is passed to the destination
+	}
+}
+
+void BuriedEngine::removeKeyboardMessages(Window *window) {
+	for (MessageQueue::iterator it = _messageQueue.begin(); it != _messageQueue.end();) {
+		if (it->dest == window && it->message->getMessageType() >= kMessageTypeKeyUp && it->message->getMessageType() <= kMessageTypeKeyDown) {
+			delete it->message;
+			it = _messageQueue.erase(it);
+		} else {
+			it++;
+		}
+	}
+}
+
+void BuriedEngine::removeMouseMessages(Window *window) {
+	for (MessageQueue::iterator it = _messageQueue.begin(); it != _messageQueue.end();) {
+		if (it->dest == window && it->message->getMessageType() >= kMessageTypeMouseMove && it->message->getMessageType() <= kMessageTypeSetCursor) {
+			delete it->message;
+			it = _messageQueue.erase(it);
+		} else {
+			it++;
+		}
+	}
+}
+
+void BuriedEngine::removeAllMessages(Window *window) {
+	for (MessageQueue::iterator it = _messageQueue.begin(); it != _messageQueue.end();) {
+		if (it->dest == window) {
+			delete it->message;
+			it = _messageQueue.erase(it);
+		} else {
+			it++;
+		}
+	}
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 4067384f96..d91b48d3fb 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -41,6 +41,7 @@ namespace Buried {
 struct BuriedGameDescription;
 class Database;
 class GraphicsManager;
+class Message;
 class SoundManager;
 class Window;
 class VideoWindow;
@@ -64,6 +65,7 @@ public:
 
 	bool hasFeature(EngineFeature f) const;
 
+	// Resources
 	Common::String getString(uint32 stringID);
 	Common::String getFilePath(uint32 stringID);
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
@@ -82,14 +84,23 @@ public:
 	Window *_mainWindow; // Only one main window is supported.
 	Window *_focusedWindow;
 
+	// Timers
 	uint createTimer(Window *window, uint period);
 	bool killTimer(uint timer);
 	void updateTimers();
 
+	// Video
 	void addVideo(VideoWindow *window);
 	void removeVideo(VideoWindow *window);
 	void updateVideos();
 
+	// Messaging
+	void postMessageToWindow(Window *dest, Message *message);
+	void sendAllMessages();
+	void removeKeyboardMessages(Window *window);
+	void removeMouseMessages(Window *window);
+	void removeAllMessages(Window *window);
+
 private:
 	Database *_library;
 
@@ -105,6 +116,15 @@ private:
 
 	typedef Common::List<VideoWindow *> VideoList;
 	VideoList _videos;
+
+	struct MessageInfo { // I did think about calling this "Envelope"
+		Window *dest;
+		Message *message;
+	};
+
+	// LordHoto didn't want me to add an iterator to Common::Queue.
+	typedef Common::List<MessageInfo> MessageQueue;
+	MessageQueue _messageQueue;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index c03063dc71..81d1870158 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -43,15 +43,14 @@ Window::Window(BuriedEngine *vm, Window *parent, bool visible) : _vm(vm), _paren
 }
 
 Window::~Window() {
-	// Make sure the queue is cleaned out
-	while (!_queue.empty())
-		delete _queue.pop();
-
 	// Remove us from any of the parent's window lists
 	if (_parent) {
 		_parent->_children.remove(this);
 		_parent->_topMostChildren.remove(this);
 	}
+
+	// Remove any of our messages from the queue
+	_vm->removeAllMessages(this);
 }
 
 void Window::invalidateRect(const Common::Rect &rect, bool erase) {
@@ -67,61 +66,54 @@ Common::Rect Window::getAbsoluteRect() const {
 	return makeAbsoluteRect(_rect);
 }
 
-void Window::dispatchAllMessages() {
-	// Dispatch all of our messages
-	while (!_queue.empty() && !_vm->shouldQuit()) {
-		Message *message = _queue.pop();
-
-		switch (message->getMessageType()) {
-		case kMessageTypeKeyUp:
-			onKeyUp(((KeyUpMessage *)message)->getKeyState(), ((KeyUpMessage *)message)->getFlags());
-			break;
-		case kMessageTypeKeyDown:
-			onKeyDown(((KeyDownMessage *)message)->getKeyState(), ((KeyDownMessage *)message)->getFlags());
-			break;
-		case kMessageTypeTimer:
-			onTimer(((TimerMessage *)message)->getTimer());
-			break;
-		case kMessageTypeMouseMove:
-			onMouseMove(((MouseMoveMessage *)message)->getPoint(), ((MouseMoveMessage *)message)->getFlags());
-			break;
-		case kMessageTypeLButtonUp:
-			onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
-			break;
-		case kMessageTypeLButtonDown:
-			onLButtonDown(((LButtonDownMessage *)message)->getPoint(), ((LButtonDownMessage *)message)->getFlags());
-			break;
-		case kMessageTypeLButtonDoubleClick:
-			onLButtonDoubleClick(((LButtonDoubleClickMessage *)message)->getPoint(), ((LButtonDoubleClickMessage *)message)->getFlags());
-			break;
-		case kMessageTypeMButtonUp:
-			onMButtonUp(((MButtonUpMessage *)message)->getPoint(), ((MButtonUpMessage *)message)->getFlags());
-			break;
-		case kMessageTypeRButtonUp:
-			onRButtonUp(((RButtonUpMessage *)message)->getPoint(), ((RButtonUpMessage *)message)->getFlags());
-			break;
-		case kMessageTypeRButtonDown:
-			onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
-			break;
-		case kMessageTypeSetCursor:
-			onSetCursor(((SetCursorMessage *)message)->getWindow(), ((SetCursorMessage *)message)->getCursor());
-			break;
-		case kMessageTypeEnable:
-			onEnable(((EnableMessage *)message)->getEnable());
-			break;
-		default:
-			error("Unknown message type %d", message->getMessageType());
-		}
-
-		delete message;
+void Window::sendMessage(Message *message) {
+	switch (message->getMessageType()) {
+	case kMessageTypeKeyUp:
+		onKeyUp(((KeyUpMessage *)message)->getKeyState(), ((KeyUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeKeyDown:
+		onKeyDown(((KeyDownMessage *)message)->getKeyState(), ((KeyDownMessage *)message)->getFlags());
+		break;
+	case kMessageTypeTimer:
+		onTimer(((TimerMessage *)message)->getTimer());
+		break;
+	case kMessageTypeMouseMove:
+		onMouseMove(((MouseMoveMessage *)message)->getPoint(), ((MouseMoveMessage *)message)->getFlags());
+		break;
+	case kMessageTypeLButtonUp:
+		onLButtonUp(((LButtonUpMessage *)message)->getPoint(), ((LButtonUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeLButtonDown:
+		onLButtonDown(((LButtonDownMessage *)message)->getPoint(), ((LButtonDownMessage *)message)->getFlags());
+		break;
+	case kMessageTypeLButtonDoubleClick:
+		onLButtonDoubleClick(((LButtonDoubleClickMessage *)message)->getPoint(), ((LButtonDoubleClickMessage *)message)->getFlags());
+		break;
+	case kMessageTypeMButtonUp:
+		onMButtonUp(((MButtonUpMessage *)message)->getPoint(), ((MButtonUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeRButtonUp:
+		onRButtonUp(((RButtonUpMessage *)message)->getPoint(), ((RButtonUpMessage *)message)->getFlags());
+		break;
+	case kMessageTypeRButtonDown:
+		onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
+		break;
+	case kMessageTypeSetCursor:
+		onSetCursor(((SetCursorMessage *)message)->getWindow(), ((SetCursorMessage *)message)->getCursor());
+		break;
+	case kMessageTypeEnable:
+		onEnable(((EnableMessage *)message)->getEnable());
+		break;
+	default:
+		error("Unknown message type %d", message->getMessageType());
 	}
 
-	// Also dispatch any children's messages
-	for (WindowList::iterator it = _children.begin(); it != _children.end() && !_vm->shouldQuit(); it++)
-		(*it)->dispatchAllMessages();
+	delete message;
+}
 
-	for (WindowList::iterator it = _topMostChildren.begin(); it != _topMostChildren.end() && !_vm->shouldQuit(); it++)
-		(*it)->dispatchAllMessages();
+void Window::postMessage(Message *message) {
+	// Simple wrapper
+	_vm->postMessageToWindow(this, message);
 }
 
 void Window::updateWindow() {
@@ -213,7 +205,7 @@ void Window::showWindow(WindowShowMode showMode) {
 void Window::enableWindow(bool enable) {
 	if (_enabled != enable) {
 		_enabled = enable;
-		sendMessage(new EnableMessage(enable));
+		postMessage(new EnableMessage(enable));
 	}
 }
 
diff --git a/engines/buried/window.h b/engines/buried/window.h
index c8378fe228..46ed982401 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -100,8 +100,8 @@ public:
 	// Create
 	// ...
 
-	void sendMessage(Message *message) { _queue.push(message); }
-	void dispatchAllMessages();
+	void sendMessage(Message *message);
+	void postMessage(Message *message);
 
 	Window *findWindowAtPoint(const Common::Point &point);
 
@@ -117,7 +117,6 @@ protected:
 	Common::Rect makeAbsoluteRect(const Common::Rect &rect) const;
 
 private:
-	Common::Queue<Message *> _queue;
 	bool _enabled, _visible;
 	bool _needsErase;
 


Commit: a3d4eb646b4b1094e20f78637a0da8e263b3d422
    https://github.com/scummvm/scummvm/commit/a3d4eb646b4b1094e20f78637a0da8e263b3d422
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Use the extra as a hint for detection

Changed paths:
    engines/buried/detection.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 8e16bc29d1..6493473673 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -189,6 +189,7 @@ class BuriedMetaEngine : public AdvancedMetaEngine {
 public:
 	BuriedMetaEngine() : AdvancedMetaEngine(Buried::gameDescriptions, sizeof(Buried::BuriedGameDescription), buriedGames) {
 		_singleid = "buried";
+		_flags = kADFlagUseExtraAsHint;
 	}
 
 	virtual const char *getName() const {


Commit: 27a64d7d8e76b25d81eee417b921701ef8cd58d7
    https://github.com/scummvm/scummvm/commit/27a64d7d8e76b25d81eee417b921701ef8cd58d7
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Fix freeing of sound streams when looping

Changed paths:
    engines/buried/sound.cpp


diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index fe97f109ab..b5d31b737d 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -728,7 +728,7 @@ bool SoundManager::Sound::start() {
 	_soundData->rewind();
 
 	if (_loop) {
-		audioStream = Audio::makeLoopingAudioStream(_soundData, 0);
+		audioStream = new Audio::LoopingAudioStream(_soundData, 0, DisposeAfterUse::NO);
 		disposeAfterUse = DisposeAfterUse::YES;
 	}
 


Commit: 890b2620d57bfd7864701039ba66a8677051dc9d
    https://github.com/scummvm/scummvm/commit/890b2620d57bfd7864701039ba66a8677051dc9d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Make sure surfaces are converted upon loading

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index bc7b184d7a..0972c03097 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -248,6 +248,11 @@ Graphics::Surface *GraphicsManager::getBitmap(uint32 bitmapID) {
 
 	delete stream;
 
+	if (decoder.getSurface()->format != g_system->getScreenFormat()) {
+		assert(_vm->isTrueColor());
+		return decoder.getSurface()->convertTo(g_system->getScreenFormat(), decoder.getPalette());
+	}
+
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->copyFrom(*decoder.getSurface());
 	return surface;
@@ -265,6 +270,11 @@ Graphics::Surface *GraphicsManager::getBitmap(const Common::String &fileName) {
 
 	delete stream;
 
+	if (decoder.getSurface()->format != g_system->getScreenFormat()) {
+		assert(_vm->isTrueColor());
+		return decoder.getSurface()->convertTo(g_system->getScreenFormat(), decoder.getPalette());
+	}
+
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->copyFrom(*decoder.getSurface());
 	return surface;


Commit: 070a58fef749e5c6f2a816570c62f13fac2cd806
    https://github.com/scummvm/scummvm/commit/070a58fef749e5c6f2a816570c62f13fac2cd806
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add the main menu

Only quit does anything at the moment

Changed paths:
  A engines/buried/main_menu.cpp
  A engines/buried/main_menu.h
    engines/buried/module.mk


diff --git a/engines/buried/main_menu.cpp b/engines/buried/main_menu.cpp
new file mode 100644
index 0000000000..e557e7b611
--- /dev/null
+++ b/engines/buried/main_menu.cpp
@@ -0,0 +1,223 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/main_menu.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+
+#include "graphics/surface.h"
+
+namespace Buried {
+
+enum {
+	BUTTON_INTERFACE_OVERVIEW = 1,
+	BUTTON_NEW_GAME = 2,
+	BUTTON_RESTORE_GAME = 3,
+	BUTTON_CREDITS = 4,
+	BUTTON_QUIT = 5
+};
+
+MainMenuWindow::MainMenuWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_curButton = 0;
+	_showIntro = true;
+	_walkthrough = false;
+	_buttonDrawnDown = false;
+	_disableDrawing = false;
+
+	Common::Rect parentRect = _parent->getClientRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = parentRect.left + 640;
+	_rect.bottom = parentRect.top + 480;
+
+	_buttons[0] = Common::Rect(335, 95, 610, 155);
+	_buttons[1] = Common::Rect(335, 168, 610, 228);
+	_buttons[2] = Common::Rect(335, 309, 610, 369);
+	_buttons[3] = Common::Rect(344, 375, 471, 407);
+	_buttons[4] = Common::Rect(471, 375, 598, 407);
+	
+	_playMode[0] = Common::Rect(345, 235, 465, 263);
+	_playMode[1] = Common::Rect(478, 235, 598, 263);
+	
+	_intro[0] = Common::Rect(345, 268, 465, 296);
+	_intro[1] = Common::Rect(478, 268, 598, 296);
+
+	_background = _vm->_gfx->getBitmap(IDB_MAINMENU_NORMAL);
+	_depressedPlayMode = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_PLAY_MODE);
+	_depressedPlayIntro = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_PLAY_INRO);
+	_depressedOverview = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_OVERVIEW);
+	_depressedNewGame = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_NEW_GAME);
+	_depressedRestoreGame = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_RESTORE_GAME);
+	_depressedCredits = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_CREDITS);
+	_depressedQuit = _vm->_gfx->getBitmap(IDB_MAINMENU_DEPRESSED_QUIT);
+}
+
+MainMenuWindow::~MainMenuWindow() {
+	_background->free();
+	delete _background;
+
+	_depressedPlayMode->free();
+	delete _depressedPlayMode;
+
+	_depressedPlayIntro->free();
+	delete _depressedPlayIntro;
+
+	_depressedOverview->free();
+	delete _depressedOverview;
+
+	_depressedNewGame->free();
+	delete _depressedNewGame;
+
+	_depressedRestoreGame->free();
+	delete _depressedRestoreGame;
+
+	_depressedCredits->free();
+	delete _depressedCredits;
+
+	_depressedQuit->free();
+	delete _depressedQuit;
+}
+
+bool MainMenuWindow::showMainMenu() {
+	_vm->_sound->restart();
+	_vm->_sound->setAmbientSound("BITDATA/COMMON/MAINMENU.BTA");
+
+	_vm->removeKeyboardMessages(this);
+	_vm->removeKeyboardMessages(_parent);
+
+	showWindow(kWindowShow);
+	invalidateWindow();
+	return true;
+}
+
+void MainMenuWindow::onPaint() {
+	if (!_disableDrawing) {
+		_vm->_gfx->blit(_background, 0, 0);
+
+		if (_walkthrough)
+			_vm->_gfx->blit(_depressedPlayMode, 343, 232);
+
+		if (!_showIntro)
+			_vm->_gfx->blit(_depressedPlayIntro, 343, 266);
+
+		switch (_curButton) {
+		case 1:
+			_vm->_gfx->blit(_depressedOverview, 334, 94);
+			break;
+		case 2:
+			_vm->_gfx->blit(_depressedNewGame, 334, 167);
+			break;
+		case 3:
+			_vm->_gfx->blit(_depressedRestoreGame, 334, 308);
+			break;
+		case 4:
+			_vm->_gfx->blit(_depressedCredits, 342, 374);
+			break;
+		case 5:
+			_vm->_gfx->blit(_depressedQuit, 471, 374);
+			break;
+		}
+	}
+}
+
+bool MainMenuWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void MainMenuWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_playMode[0].contains(point) && _walkthrough) {
+		_walkthrough = false;
+		invalidateRect(_playMode[0], false);
+		invalidateRect(_playMode[1], false);
+		return;
+	}
+
+	if (_playMode[1].contains(point) && !_walkthrough) {
+		_walkthrough = true;
+		invalidateRect(_playMode[0], false);
+		invalidateRect(_playMode[1], false);
+		return;
+	}
+
+	if (_intro[0].contains(point) && !_showIntro) {
+		_showIntro = true;
+		invalidateRect(_intro[0], false);
+		invalidateRect(_intro[1], false);
+		return;
+	}
+
+	if (_intro[1].contains(point) && _showIntro) {
+		_showIntro = false;
+		invalidateRect(_intro[0], false);
+		invalidateRect(_intro[1], false);
+		return;
+	}
+
+	for (int i = 0; i < 5; i++) {
+		if (_buttons[i].contains(point)) {
+			_curButton = i + 1;
+			invalidateRect(_buttons[i], false);
+			return;
+		}
+	}
+}
+
+void MainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_curButton > 0 && _buttons[_curButton - 1].contains(point)) {
+		switch (_curButton) {
+		case BUTTON_INTERFACE_OVERVIEW:
+			// TODO
+			break;
+		case BUTTON_NEW_GAME:
+			// TODO
+			break;
+		case BUTTON_RESTORE_GAME:
+			// TODO
+			break;
+		case BUTTON_CREDITS:
+			// TODO
+			break;
+		case BUTTON_QUIT:
+			_vm->quitGame();
+			return;
+		}
+
+		invalidateRect(_buttons[_curButton - 1], false);
+		_curButton = 0;
+	}
+}
+
+void MainMenuWindow::onMouseMove(const Common::Point &point, uint flags) {
+	// If we mouse-downed on a button, check to see if we moved outside of its bounds
+	if (_curButton > 0 && !_buttons[_curButton - 1].contains(point)) {
+		invalidateRect(_buttons[_curButton - 1], false);
+		_curButton = 0;
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/main_menu.h b/engines/buried/main_menu.h
new file mode 100644
index 0000000000..21e824307a
--- /dev/null
+++ b/engines/buried/main_menu.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_MAIN_MENU_H
+#define BURIED_MAIN_MENU_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class MainMenuWindow : public Window {
+public:
+	MainMenuWindow(BuriedEngine *vm, Window *parent);
+	~MainMenuWindow();
+
+	bool showMainMenu();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+
+private:
+	Common::Rect _buttons[5];
+	Common::Rect _playMode[2];
+	Common::Rect _intro[2];
+
+	int _curButton;
+	bool _showIntro;
+	bool _walkthrough;
+	bool _buttonDrawnDown;
+	bool _disableDrawing;
+
+	Graphics::Surface *_background;
+	Graphics::Surface *_depressedPlayMode;
+	Graphics::Surface *_depressedPlayIntro;
+	Graphics::Surface *_depressedOverview;
+	Graphics::Surface *_depressedNewGame;
+	Graphics::Surface *_depressedRestoreGame;
+	Graphics::Surface *_depressedCredits;
+	Graphics::Surface *_depressedQuit;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 391d4d5450..905824d6d5 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS = \
 	detection.o \
 	graphics.o \
 	livetext.o \
+	main_menu.o \
 	sound.o \
 	title_sequence.o \
 	video_window.o \


Commit: c53ee0b6bf6a76c803ab4ba3676047f60aa82fb5
    https://github.com/scummvm/scummvm/commit/c53ee0b6bf6a76c803ab4ba3676047f60aa82fb5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:37+01:00

Commit Message:
BURIED: Add the overview sequence

Changed paths:
  A engines/buried/overview.cpp
  A engines/buried/overview.h
    engines/buried/module.mk


diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 905824d6d5..0ea010fa4f 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS = \
 	graphics.o \
 	livetext.o \
 	main_menu.o \
+	overview.o \
 	sound.o \
 	title_sequence.o \
 	video_window.o \
diff --git a/engines/buried/overview.cpp b/engines/buried/overview.cpp
new file mode 100644
index 0000000000..82f87b3580
--- /dev/null
+++ b/engines/buried/overview.cpp
@@ -0,0 +1,179 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/overview.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+
+#include "graphics/surface.h"
+
+namespace Buried {
+
+OverviewWindow::OverviewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_currentImage = 0;
+	_currentStatus = -1;
+	_timer = 0xFFFFFFFF;
+
+	Common::Rect parentRect = _parent->getClientRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = parentRect.left + 640;
+	_rect.bottom = parentRect.top + 480;
+
+	_background = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_IF_OV_FULL_SCREEN_DIB));
+}
+
+OverviewWindow::~OverviewWindow() {
+	_vm->_sound->stopInterfaceSound();
+
+	_background->free();
+	delete _background;
+
+	if (_currentImage) {
+		_currentImage->free();
+		delete _currentImage;
+	}
+
+	if (_timer != 0xFFFFFFFF)
+		_vm->killTimer(_timer);
+}
+
+bool OverviewWindow::startOverview() {
+	_vm->_sound->setAmbientSound("");
+
+	showWindow(kWindowShow);
+	invalidateWindow();
+
+	_timer = setTimer(1000);
+	return true;
+}
+
+void OverviewWindow::onPaint() {
+	_vm->_gfx->blit(_background, 0, 0);
+
+	if (_currentImage) {
+		switch (_currentStatus) {
+		case 0: // Navigational buttons
+			_vm->_gfx->blit(_currentImage, 498, 274);
+			break;
+		case 1: // Inventory buttons
+			_vm->_gfx->blit(_currentImage, 163, 352);
+			break;
+		case 2: // BioChip buttons
+			_vm->_gfx->blit(_currentImage, 509, 89);
+			break;
+		case 3: // Message buttons
+			_vm->_gfx->blit(_currentImage, 93, 0);
+			break;
+		case 4: // Final info - no image to render to the screen
+			break;
+		}
+	}
+}
+
+bool OverviewWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void OverviewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	_vm->_sound->stopInterfaceSound();
+}
+
+void OverviewWindow::onKeyUp(const Common::KeyState &key, uint flags) {
+	_vm->_sound->stopInterfaceSound();
+}
+
+void OverviewWindow::onTimer(uint timer) {
+	_vm->_sound->timerCallback();
+
+	if (_currentStatus >= 0 && _vm->_sound->isInterfaceSoundPlaying())
+		return;
+
+	if (_currentImage) {
+		_currentImage->free();
+		delete _currentImage;
+		_currentImage = 0;
+	}
+
+	// Switch on the current status in order to determine which action to take next
+	switch (_currentStatus) {
+	case -1: // Starting value - kick things off
+		_currentStatus = 0;
+		_currentImage = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_IF_OV_NAV_ARROWS_DIB));
+		invalidateRect(Common::Rect(498, 274, 640, 433), false);
+
+		_vm->_sound->stopInterfaceSound();
+		_vm->_sound->timerCallback();
+		_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_IF_OV_NAV_ARROWS_AUDIO));
+		break;
+	case 0: // Played initial stuff
+		_currentStatus = 1;
+		_currentImage = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_IF_OV_INVENTORY_DIB));
+		invalidateRect(Common::Rect(498, 274, 640, 433), false);
+		invalidateRect(Common::Rect(163, 352, 472, 472), false);
+
+		_vm->_sound->stopInterfaceSound();
+		_vm->_sound->timerCallback();
+		_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_IF_OV_INVENTORY_AUDIO));
+		break;
+	case 1:
+		_currentStatus = 2;
+		_currentImage = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_IF_OV_BIOCHIPS_DIB));
+		invalidateRect(Common::Rect(163, 352, 472, 472), false);
+		invalidateRect(Common::Rect(509, 89, 640, 275), false);
+
+		_vm->_sound->stopInterfaceSound();
+		_vm->_sound->timerCallback();
+		_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_IF_OV_BIOCHIPS_AUDIO));
+		break;
+	case 2:
+		_currentStatus = 3;
+		_currentImage = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_IF_OV_MESSAGE_BOX_DIB));
+		invalidateRect(Common::Rect(509, 89, 640, 275), false);
+		invalidateRect(Common::Rect(93, 0, 482, 108), false);
+
+		_vm->_sound->stopInterfaceSound();
+		_vm->_sound->timerCallback();
+		_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_IF_OV_MESSAGE_BOX_AUDIO));
+		break;
+	case 3:
+		_currentStatus = 4;
+		invalidateRect(Common::Rect(93, 0, 482, 108), false);
+
+		_vm->_sound->stopInterfaceSound();
+		_vm->_sound->timerCallback();
+		_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_IF_OV_FURTHER_INFO_AUDIO));
+		break;
+	case 4:
+		_currentStatus = 5;
+		// TODO: Return to the main menu
+		break;
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/overview.h b/engines/buried/overview.h
new file mode 100644
index 0000000000..83b958a897
--- /dev/null
+++ b/engines/buried/overview.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_OVERVIEW_H
+#define BURIED_OVERVIEW_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class OverviewWindow : public Window {
+public:
+	OverviewWindow(BuriedEngine *vm, Window *parent);
+	~OverviewWindow();
+
+	bool startOverview();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onKeyUp(const Common::KeyState &key, uint flags);
+	void onTimer(uint timer);
+
+private:
+	Graphics::Surface *_background;
+	Graphics::Surface *_currentImage;
+	int _currentStatus;
+	uint _timer;
+};
+
+} // End of namespace Buried
+
+#endif


Commit: d1ab45529a9ebef602d4198b72e26faf981ff061
    https://github.com/scummvm/scummvm/commit/d1ab45529a9ebef602d4198b72e26faf981ff061
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add a more advanced blit function

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 0972c03097..3fa5717da8 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -337,6 +337,16 @@ void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
 		memcpy(_screen->getBasePtr(x, y + i), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
 }
 
+void GraphicsManager::blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect) {
+	assert(surface->format.bytesPerPixel == _screen->format.bytesPerPixel);
+
+	int width = MIN(srcRect.width(), dstRect.width());
+	int height = MIN(srcRect.height(), dstRect.height());
+
+	for (int i = 0; i < height; i++)
+		memcpy(_screen->getBasePtr(dstRect.left, dstRect.top + i), surface->getBasePtr(srcRect.left, srcRect.top + i), width * surface->format.bytesPerPixel);
+}
+
 void GraphicsManager::fillRect(const Common::Rect &rect, uint32 color) {
 	_screen->fillRect(rect, color);
 }
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index dc2ca61049..3ddbad85ac 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -81,6 +81,7 @@ public:
 	Graphics::Surface *getScreen() const { return _screen; }
 
 	void blit(const Graphics::Surface *surface, int x, int y);
+	void blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect);
 	void fillRect(const Common::Rect &rect, uint32 color);
 
 private:


Commit: f48978e88ca96d7e7a1d094d8b281cdcc8e2107a
    https://github.com/scummvm/scummvm/commit/f48978e88ca96d7e7a1d094d8b281cdcc8e2107a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Make sure 8bpp images are using the right palette

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/video_window.cpp
    engines/buried/video_window.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 3fa5717da8..0136be44d7 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -242,19 +242,10 @@ Graphics::Surface *GraphicsManager::getBitmap(uint32 bitmapID) {
 	if (!stream)
 		error("Could not find bitmap %d", bitmapID);
 
-	Image::BitmapDecoder decoder;
-	if (!decoder.loadStream(*stream))
+	Graphics::Surface *surface = getBitmap(stream);
+	if (!surface)
 		error("Failed to decode bitmap %d", bitmapID);
 
-	delete stream;
-
-	if (decoder.getSurface()->format != g_system->getScreenFormat()) {
-		assert(_vm->isTrueColor());
-		return decoder.getSurface()->convertTo(g_system->getScreenFormat(), decoder.getPalette());
-	}
-
-	Graphics::Surface *surface = new Graphics::Surface();
-	surface->copyFrom(*decoder.getSurface());
 	return surface;
 }
 
@@ -264,17 +255,33 @@ Graphics::Surface *GraphicsManager::getBitmap(const Common::String &fileName) {
 	if (!stream)
 		error("Could not find bitmap '%s'", fileName.c_str());
 
-	Image::BitmapDecoder decoder;
-	if (!decoder.loadStream(*stream))
+	Graphics::Surface *surface = getBitmap(stream);
+	if (!surface)
 		error("Failed to decode bitmap '%s'", fileName.c_str());
 
+	return surface;
+}
+
+Graphics::Surface *GraphicsManager::getBitmap(Common::SeekableReadStream *stream) {
+	Image::BitmapDecoder decoder;
+	if (!decoder.loadStream(*stream)) {
+		delete stream;
+		return 0;
+	}
+
 	delete stream;
 
+	// Convert to the screen format, if required
 	if (decoder.getSurface()->format != g_system->getScreenFormat()) {
 		assert(_vm->isTrueColor());
 		return decoder.getSurface()->convertTo(g_system->getScreenFormat(), decoder.getPalette());
 	}
 
+	// Remap the palette, if required
+	if (!_vm->isTrueColor() && memcmp(decoder.getPalette() + 3, getDefaultPalette() + 3, 256 - 6) != 0)
+		return remapPalettedFrame(decoder.getSurface(), decoder.getPalette());
+
+	// Just copy the frame
 	Graphics::Surface *surface = new Graphics::Surface();
 	surface->copyFrom(*decoder.getSurface());
 	return surface;
@@ -390,4 +397,56 @@ byte *GraphicsManager::createDefaultPalette() const {
 	return palette;
 }
 
+Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *frame, const byte *palette) {
+	// This is pretty much the same as the Cinepak one
+	// It seems to work for the one video I know that needs it (SWLOGO.BTV)
+	// TODO: Merge some of this with getColor()
+
+	byte palMap[256];
+	const byte *screenPal = getDefaultPalette();
+
+	for (int i = 0; i < 256; i++) {
+		int r = palette[i * 3];
+		int g = palette[i * 3 + 1];
+		int b = palette[i * 3 + 2];
+
+		int diff = 0x7FFFFFFF;
+		byte result = 0;
+
+		for (int j = 0; j < 256; j++) {
+			int bDiff = b - (int)screenPal[j * 3 + 2];
+			int curDiffB = diff - (bDiff * bDiff);
+
+			if (curDiffB > 0) {
+				int gDiff = g - (int)screenPal[j * 3 + 1];
+				int curDiffG = curDiffB - (gDiff * gDiff);
+
+				if (curDiffG > 0) {
+					int rDiff = r - (int)screenPal[j * 3];
+					int curDiffR = curDiffG - (rDiff * rDiff);
+
+					if (curDiffR > 0) {
+						diff -= curDiffR;
+						result = j;
+
+						if (diff == 0)
+							break;
+					}
+				}
+			}
+		}
+
+		palMap[i] = result;
+	}
+
+	Graphics::Surface *convertedSurface = new Graphics::Surface();
+	convertedSurface->create(frame->w, frame->h, frame->format);
+
+	for (int y = 0; y < frame->h; y++)
+		for (int x = 0; x < frame->w; x++)
+			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((byte *)frame->getBasePtr(x, y))];
+
+	return convertedSurface;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 3ddbad85ac..26d6a03442 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -26,6 +26,10 @@
 #include "common/rect.h"
 #include "common/scummsys.h"
 
+namespace Common {
+class SeekableReadStream;
+}
+
 namespace Graphics {
 class Font;
 struct Surface;
@@ -84,6 +88,8 @@ public:
 	void blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect);
 	void fillRect(const Common::Rect &rect, uint32 color);
 
+	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
+
 private:
 	BuriedEngine *_vm;
 	Cursor _curCursor;
@@ -94,6 +100,7 @@ private:
 	byte *_palette;
 	
 	byte *createDefaultPalette() const;
+	Graphics::Surface *getBitmap(Common::SeekableReadStream *stream);
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 837c733e16..d51514eb0b 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -160,7 +160,7 @@ void VideoWindow::updateVideo() {
 				} else {
 					if (_needsPalConversion) {
 						// If it's a palette video, ensure it's using the screen palette
-						_ownedFrame = remapPalettedFrame(frame, _video->getPalette());
+						_ownedFrame = _vm->_gfx->remapPalettedFrame(frame, _video->getPalette());
 						_lastFrame = _ownedFrame;
 					} else {
 						// Assume it's in the right format from dithering
@@ -185,55 +185,4 @@ void VideoWindow::onPaint() {
 		_vm->_gfx->blit(_lastFrame, _rect.left, _rect.top);
 }
 
-Graphics::Surface *VideoWindow::remapPalettedFrame(const Graphics::Surface *frame, const byte *palette) {
-	// This is pretty much the same as the Cinepak one
-	// It seems to work for the one video I know that needs it (SWLOGO.BTV)
-
-	byte palMap[256];
-	const byte *screenPal = _vm->_gfx->getDefaultPalette();
-
-	for (int i = 0; i < 256; i++) {
-		int r = palette[i * 3];
-		int g = palette[i * 3 + 1];
-		int b = palette[i * 3 + 2];
-
-		int diff = 0x7FFFFFFF;
-		byte result = 0;
-
-		for (int j = 0; j < 256; j++) {
-			int bDiff = b - (int)screenPal[j * 3 + 2];
-			int curDiffB = diff - (bDiff * bDiff);
-
-			if (curDiffB > 0) {
-				int gDiff = g - (int)screenPal[j * 3 + 1];
-				int curDiffG = curDiffB - (gDiff * gDiff);
-
-				if (curDiffG > 0) {
-					int rDiff = r - (int)screenPal[j * 3];
-					int curDiffR = curDiffG - (rDiff * rDiff);
-
-					if (curDiffR > 0) {
-						diff -= curDiffR;
-						result = j;
-
-						if (diff == 0)
-							break;
-					}
-				}
-			}
-		}
-
-		palMap[i] = result;
-	}
-
-	Graphics::Surface *convertedSurface = new Graphics::Surface();
-	convertedSurface->create(frame->w, frame->h, frame->format);
-
-	for (int y = 0; y < frame->h; y++)
-		for (int x = 0; x < frame->w; x++)
-			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((byte *)frame->getBasePtr(x, y))];
-
-	return convertedSurface;
-}
-
 } // End of namespace Buried
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
index 4a4103d86e..740153940d 100644
--- a/engines/buried/video_window.h
+++ b/engines/buried/video_window.h
@@ -74,8 +74,6 @@ private:
 	Mode _mode;
 	Graphics::Surface *_ownedFrame;
 	bool _needsPalConversion;
-
-	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 };
 
 } // End of namespace Buried


Commit: 343f8afbeef9843996ccb710c44578bc120ddca4
    https://github.com/scummvm/scummvm/commit/343f8afbeef9843996ccb710c44578bc120ddca4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the credits window

Changed paths:
  A engines/buried/credits.cpp
  A engines/buried/credits.h
    engines/buried/module.mk


diff --git a/engines/buried/credits.cpp b/engines/buried/credits.cpp
new file mode 100644
index 0000000000..98f5217ea8
--- /dev/null
+++ b/engines/buried/credits.cpp
@@ -0,0 +1,149 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/avi_frames.h"
+#include "buried/buried.h"
+#include "buried/credits.h"
+#include "buried/graphics.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+
+#include "graphics/surface.h"
+
+namespace Buried {
+
+CreditsWindow::CreditsWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_curButton = 1;
+	_curPage = 0;
+
+	_buttons[0] = Common::Rect(18, 92, 294, 152);
+	_buttons[1] = Common::Rect(18, 164, 294, 224);
+	_buttons[2] = Common::Rect(18, 236, 294, 296);
+	_buttons[3] = Common::Rect(18, 308, 294, 368);
+	_buttons[4] = Common::Rect(18, 380, 294, 440);
+	_returnButton = Common::Rect(572, 459, 639, 479);
+
+	Common::Rect parentRect = _parent->getClientRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = parentRect.left + 640;
+	_rect.bottom = parentRect.top + 480;
+
+	_normalImage = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_CREDITS_MAIN_FILENAME));
+	_highlightedImage = _vm->_gfx->getBitmap(_vm->getFilePath(IDS_CREDITS_HIGHLIGHT_FILENAME));
+
+	_stillFrames = new AVIFrames(_vm->getFilePath(IDS_CREDITS_MOVIE_FILENAME));
+}
+
+CreditsWindow::~CreditsWindow() {
+	delete _stillFrames;
+
+	_normalImage->free();
+	delete _normalImage;
+
+	_highlightedImage->free();
+	delete _highlightedImage;
+}
+
+bool CreditsWindow::showCredits() {
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_parent);
+
+	showWindow(kWindowShow);
+	invalidateWindow(false);
+
+	return true;
+}
+
+void CreditsWindow::onPaint() {
+	_vm->_gfx->blit(_normalImage, 0, 0);
+	_vm->_gfx->blit(_highlightedImage, Common::Rect(0, (_curButton - 1) * 60, 276, _curButton * 60), Common::Rect(18, (_curButton - 1) * 72 + 92, 294, (_curButton - 1) * 72 + 152));
+
+	const Graphics::Surface *frame = _stillFrames->getFrame(_curPage);
+	if (frame)
+		_vm->_gfx->blit(frame, 304, 0);
+}
+
+bool CreditsWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void CreditsWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_returnButton.contains(point)) {
+		// TODO: Show main menu
+		return;
+	}
+
+	if (_curButton == 1) {
+		// Displaying the main menu for the Presto people
+		if (_curPage == 0) {
+			// Check against the list of people
+			for (int i = 0; i < 17; i++) {
+				if (Common::Rect(319, i * 16 + 181, 619, i * 16 + 193).contains(point)) {
+					_curPage = i + 1;
+					invalidateRect(Common::Rect(304, 0, 640, 480), false);
+					return;
+				}
+			}
+		} else {
+			// Check for a return click
+			if (Common::Rect(312, 24, 625, 454).contains(point)) {
+				_curButton = 1;
+				_curPage = 0;
+				invalidateRect(Common::Rect(304, 0, 640, 480), false);
+			}
+		}
+	}
+
+	// Check normal buttons
+	for (int i = 0; i < 5; i++) {
+		if (_buttons[i].contains(point) && _curButton != i + 1) {
+			_curButton = i + 1;
+
+			switch (_curButton) {
+			case 1:
+				_curPage = 0;
+				break;
+			case 2:
+				_curPage = 18;
+				break;
+			case 3:
+				_curPage = 19;
+				break;
+			case 4:
+				_curPage = 20;
+				break;
+			case 5:
+				_curPage = 21;
+				break;
+			}
+
+			invalidateWindow(false);
+		}
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/credits.h b/engines/buried/credits.h
new file mode 100644
index 0000000000..d0e5de79ce
--- /dev/null
+++ b/engines/buried/credits.h
@@ -0,0 +1,65 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_CREDITS_H
+#define BURIED_CREDITS_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class AVIFrames;
+
+class CreditsWindow : public Window {
+public:
+	CreditsWindow(BuriedEngine *vm, Window *parent);
+	~CreditsWindow();
+
+	bool showCredits();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonDown(const Common::Point &point, uint flags);
+
+private:
+	Graphics::Surface *_normalImage;
+	Graphics::Surface *_highlightedImage;
+
+	Common::Rect _buttons[5];
+	Common::Rect _returnButton;
+
+	int _curButton;
+	int _curPage;
+
+	AVIFrames *_stillFrames;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 0ea010fa4f..cf4113649f 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/buried
 MODULE_OBJS = \
 	avi_frames.o \
 	buried.o \
+	credits.o \
 	database.o \
 	detection.o \
 	graphics.o \


Commit: bdf5c27b1064209a2c6262bebbe7d41258b5bd34
    https://github.com/scummvm/scummvm/commit/bdf5c27b1064209a2c6262bebbe7d41258b5bd34
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Some updates to the messaging system to allow for inner loops

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/message.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 581e35fcf6..5c49f8b5dc 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -113,44 +113,7 @@ Common::Error BuriedEngine::run() {
 		updateTimers();
 		updateVideos();
 
-		// TODO: Key flags
-		// TODO: Mouse flags
-
-		Common::Event event;
-		while (_eventMan->pollEvent(event)) {
-			switch (event.type) {
-			case Common::EVENT_MOUSEMOVE:
-				_gfx->markMouseMoved();
-				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MouseMoveMessage(event.mouse, 0));
-				break;
-			case Common::EVENT_KEYUP:
-				if (_focusedWindow)
-					_focusedWindow->postMessage(new KeyUpMessage(event.kbd, 0));
-				break;
-			case Common::EVENT_KEYDOWN:
-				if (_focusedWindow)
-					_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
-				break;
-			case Common::EVENT_LBUTTONDOWN:
-				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonDownMessage(event.mouse, 0));
-				break;
-			case Common::EVENT_LBUTTONUP:
-				// TODO: Double-click
-				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonUpMessage(event.mouse, 0));
-				break;
-			case Common::EVENT_MBUTTONUP:
-				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MButtonUpMessage(event.mouse, 0));
-				break;
-			case Common::EVENT_RBUTTONDOWN:
-				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonDownMessage(event.mouse, 0));
-				break;
-			case Common::EVENT_RBUTTONUP:
-				_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonUpMessage(event.mouse, 0));
-				break;
-			default:
-				break;
-			}
-		}
+		pollForEvents();
 
 		sendAllMessages();
 
@@ -293,9 +256,9 @@ void BuriedEngine::sendAllMessages() {
 	}
 }
 
-void BuriedEngine::removeKeyboardMessages(Window *window) {
+void BuriedEngine::removeMessages(Window *window, int messageBegin, int messageEnd) {
 	for (MessageQueue::iterator it = _messageQueue.begin(); it != _messageQueue.end();) {
-		if (it->dest == window && it->message->getMessageType() >= kMessageTypeKeyUp && it->message->getMessageType() <= kMessageTypeKeyDown) {
+		if (it->dest == window && it->message->getMessageType() >= messageBegin && it->message->getMessageType() <= messageEnd) {
 			delete it->message;
 			it = _messageQueue.erase(it);
 		} else {
@@ -304,15 +267,12 @@ void BuriedEngine::removeKeyboardMessages(Window *window) {
 	}
 }
 
+void BuriedEngine::removeKeyboardMessages(Window *window) {
+	removeMessages(window, kMessageTypeKeyBegin, kMessageTypeKeyEnd);
+}
+
 void BuriedEngine::removeMouseMessages(Window *window) {
-	for (MessageQueue::iterator it = _messageQueue.begin(); it != _messageQueue.end();) {
-		if (it->dest == window && it->message->getMessageType() >= kMessageTypeMouseMove && it->message->getMessageType() <= kMessageTypeSetCursor) {
-			delete it->message;
-			it = _messageQueue.erase(it);
-		} else {
-			it++;
-		}
-	}
+	removeMessages(window, kMessageTypeMouseBegin, kMessageTypeMouseEnd);
 }
 
 void BuriedEngine::removeAllMessages(Window *window) {
@@ -326,4 +286,68 @@ void BuriedEngine::removeAllMessages(Window *window) {
 	}
 }
 
+bool BuriedEngine::hasMessage(Window *window, int messageBegin, int messageEnd) const {
+	for (MessageQueue::const_iterator it = _messageQueue.begin(); it != _messageQueue.end(); it++)
+		if ((!window || it->dest == window) && it->message->getMessageType() >= messageBegin && it->message->getMessageType() <= messageEnd)
+			return true;
+
+	return false;
+}
+
+void BuriedEngine::yield() {
+	// A cut down version of the Win16 yield function. Win32 handles this
+	// asynchronously, which we don't want. Only needed for internal event loops.
+	updateTimers();
+	updateVideos();
+
+	pollForEvents();
+
+	// We don't send messages any messages from here. Otherwise, this is the same
+	// as our main loop.
+
+	_gfx->updateScreen();
+	_system->delayMillis(10);
+}
+
+void BuriedEngine::pollForEvents() {
+	// TODO: Key flags
+	// TODO: Mouse flags
+
+	Common::Event event;
+	while (_eventMan->pollEvent(event)) {
+		switch (event.type) {
+		case Common::EVENT_MOUSEMOVE:
+			_gfx->markMouseMoved();
+			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MouseMoveMessage(event.mouse, 0));
+			break;
+		case Common::EVENT_KEYUP:
+			if (_focusedWindow)
+				_focusedWindow->postMessage(new KeyUpMessage(event.kbd, 0));
+			break;
+		case Common::EVENT_KEYDOWN:
+			if (_focusedWindow)
+				_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
+			break;
+		case Common::EVENT_LBUTTONDOWN:
+			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonDownMessage(event.mouse, 0));
+			break;
+		case Common::EVENT_LBUTTONUP:
+			// TODO: Double-click
+			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonUpMessage(event.mouse, 0));
+			break;
+		case Common::EVENT_MBUTTONUP:
+			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MButtonUpMessage(event.mouse, 0));
+			break;
+		case Common::EVENT_RBUTTONDOWN:
+			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonDownMessage(event.mouse, 0));
+			break;
+		case Common::EVENT_RBUTTONUP:
+			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonUpMessage(event.mouse, 0));
+			break;
+		default:
+			break;
+		}
+	}
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index d91b48d3fb..6911b56188 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -100,6 +100,11 @@ public:
 	void removeKeyboardMessages(Window *window);
 	void removeMouseMessages(Window *window);
 	void removeAllMessages(Window *window);
+	void removeMessages(Window *window, int messageBegin, int messageEnd);
+	bool hasMessage(Window *window, int messageBegin, int messageEnd) const;
+
+	// Miscellaneous
+	void yield();
 
 private:
 	Database *_library;
@@ -125,6 +130,7 @@ private:
 	// LordHoto didn't want me to add an iterator to Common::Queue.
 	typedef Common::List<MessageInfo> MessageQueue;
 	MessageQueue _messageQueue;
+	void pollForEvents();
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/message.h b/engines/buried/message.h
index 8640842818..1309d2f9d3 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -34,6 +34,7 @@ namespace Buried {
 class Window;
 
 enum MessageType {
+	// Actual message types
 	kMessageTypeKeyUp,
 	kMessageTypeKeyDown,
 	kMessageTypeTimer,
@@ -45,7 +46,13 @@ enum MessageType {
 	kMessageTypeRButtonUp,
 	kMessageTypeRButtonDown,
 	kMessageTypeSetCursor,
-	kMessageTypeEnable
+	kMessageTypeEnable,
+
+	// Ranges of messages
+	kMessageTypeMouseBegin = kMessageTypeMouseMove,
+	kMessageTypeMouseEnd = kMessageTypeRButtonDown,
+	kMessageTypeKeyBegin = kMessageTypeKeyUp,
+	kMessageTypeKeyEnd = kMessageTypeKeyDown
 };
 
 


Commit: 3a69ae803300019cdac7d6d0030503925d9065ce
    https://github.com/scummvm/scummvm/commit/3a69ae803300019cdac7d6d0030503925d9065ce
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Strip "BITDATA" from demo file names

The demo has its binaries in that directory already

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 5c49f8b5dc..b75443cce3 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -139,9 +139,13 @@ Common::String BuriedEngine::getFilePath(uint32 stringID) {
 
 	uint i = 0;
 
-	// The non-demo paths have CD info followed by a backspace
-	// We ignore this
-	if (!isDemo())
+	// The non-demo paths have CD info followed by a backslash.
+	// We ignore this.
+	// In the demo, we remove the "BITDATA" prefix because the
+	// binaries are in the same directory.
+	if (isDemo())
+		i += 8;
+	else
 		i += 2;
 
 	for (; i < path.size(); i++) {


Commit: a4cb03264e8242e1707550ebf196dd9f6274d101
    https://github.com/scummvm/scummvm/commit/a4cb03264e8242e1707550ebf196dd9f6274d101
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the demo main menu

Changed paths:
  A engines/buried/demo/demo_menu.cpp
  A engines/buried/demo/demo_menu.h
    engines/buried/buried.cpp
    engines/buried/module.mk


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b75443cce3..d4c900f948 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -38,6 +38,7 @@
 #include "buried/window.h"
 
 #include "buried/title_sequence.h"
+#include "buried/demo/demo_menu.h"
 #include "common/events.h"
 
 namespace Buried {
@@ -98,16 +99,23 @@ Common::Error BuriedEngine::run() {
 
 	_gfx = new GraphicsManager(this);
 	_sound = new SoundManager(this);
-	
-	// HACK: Show the intro for now in the full game
-	if (isDemo())
-		return Common::kNoError;
 
+	// HACK: Create a dummy main window
 	_mainWindow = new Window(this, 0);
 	_mainWindow->setWindowPos(0, 0, 0, 640, 480, Window::kWindowPosNoZOrder);
-	TitleSequenceWindow *titleSeq = new TitleSequenceWindow(this, _mainWindow);
-	titleSeq->setFocus();
-	titleSeq->playTitleSequence();
+
+	// HACK: Show a window
+	Window *tempWindow = 0;
+	if (isDemo()) {
+		DemoMainMenuWindow *demoMenu = new DemoMainMenuWindow(this, _mainWindow);
+		demoMenu->showWithSplash();
+		tempWindow = demoMenu;
+	} else {
+		TitleSequenceWindow *titleSeq = new TitleSequenceWindow(this, _mainWindow);
+		titleSeq->setFocus();
+		titleSeq->playTitleSequence();
+		tempWindow = titleSeq;
+	}
 
 	while (!shouldQuit()) {
 		updateTimers();
@@ -121,7 +129,7 @@ Common::Error BuriedEngine::run() {
 		_system->delayMillis(10);
 	}
 
-	delete titleSeq;
+	delete tempWindow;
 
 	return Common::kNoError;
 }
diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
new file mode 100644
index 0000000000..ce3d2ecede
--- /dev/null
+++ b/engines/buried/demo/demo_menu.cpp
@@ -0,0 +1,162 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/message.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+#include "buried/demo/demo_menu.h"
+
+#include "common/events.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+enum {
+	BUTTON_OVERVIEW = 1,
+	BUTTON_TRAILER = 2,
+	BUTTON_INTERACTIVE = 3,
+	BUTTON_GALLERY = 4,
+	BUTTON_QUIT = 5
+};
+
+DemoMainMenuWindow::DemoMainMenuWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_curButton = 0;
+
+	Common::Rect parentRect = _parent->getClientRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = parentRect.left + 640;
+	_rect.bottom = parentRect.top + 480;
+
+	_overview = Common::Rect(29, 155, 168, 325);
+	_trailer = Common::Rect(177, 155, 316, 325);
+	_interactive = Common::Rect(324, 155, 463, 325);
+	_gallery = Common::Rect(471, 155, 610, 325);
+	_quit = Common::Rect(552, 439, 640, 480);
+	
+	if (_vm->isTrueColor())
+		_background = _vm->_gfx->getBitmap("MISC/24BPP/MAINMENU.BMP");
+	else
+		_background = _vm->_gfx->getBitmap("MISC/8BPP/MAINMENU.BMP");
+
+	_vm->_sound->setAmbientSound("MISC/MENULOOP.WAV");
+}
+
+DemoMainMenuWindow::~DemoMainMenuWindow() {
+	_background->free();
+	delete _background;
+}
+
+void DemoMainMenuWindow::showWithSplash() {
+	Graphics::Surface *temp = _background;
+
+	if (_vm->isTrueColor())
+		_background = _vm->_gfx->getBitmap("MISC/24BPP/SPLASH.BMP");
+	else
+		_background = _vm->_gfx->getBitmap("MISC/8BPP/SPLASH.BMP");
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_parent);
+
+	showWindow(kWindowShow);
+	invalidateWindow(false);
+	_vm->_gfx->updateScreen();
+
+	uint32 startTime = g_system->getMillis();
+	while (g_system->getMillis() < (startTime + 6000) && !_vm->hasMessage(this, kMessageTypeLButtonUp, kMessageTypeLButtonUp) && !_vm->shouldQuit())
+		_vm->yield();
+
+	delete _background;
+	_background = temp;
+	invalidateWindow(false);
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_parent);
+}
+
+void DemoMainMenuWindow::onPaint() {
+	_vm->_gfx->blit(_background, 0, 0);
+}
+
+bool DemoMainMenuWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void DemoMainMenuWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_overview.contains(point)) {
+		_curButton = BUTTON_OVERVIEW;
+		return;
+	}
+
+	if (_trailer.contains(point)) {
+		_curButton = BUTTON_TRAILER;
+		return;
+	}
+
+	if (_interactive.contains(point)) {
+		_curButton = BUTTON_INTERACTIVE;
+		return;
+	}
+
+	if (_gallery.contains(point)) {
+		_curButton = BUTTON_GALLERY;
+		return;
+	}
+
+	if (_quit.contains(point))
+		_curButton = BUTTON_QUIT;
+}
+
+void DemoMainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_curButton == 0)
+		return;
+
+	switch (_curButton) {
+	case BUTTON_OVERVIEW:
+		// TODO
+		break;
+	case BUTTON_TRAILER:
+		// TODO
+		break;
+	case BUTTON_INTERACTIVE:
+		// TODO
+		break;
+	case BUTTON_GALLERY:
+		// TODO
+		break;
+	case BUTTON_QUIT:
+		// TODO
+		return;
+	}
+
+	_curButton = 0;
+	invalidateWindow(false);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/demo/demo_menu.h b/engines/buried/demo/demo_menu.h
new file mode 100644
index 0000000000..e04bfb0113
--- /dev/null
+++ b/engines/buried/demo/demo_menu.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_DEMO_MENU_H
+#define BURIED_DEMO_MENU_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class DemoMainMenuWindow : public Window {
+public:
+	DemoMainMenuWindow(BuriedEngine *vm, Window *parent);
+	~DemoMainMenuWindow();
+
+	void showWithSplash();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onLButtonDown(const Common::Point &point, uint flags);
+
+private:
+	Common::Rect _overview;
+	Common::Rect _trailer;
+	Common::Rect _interactive;
+	Common::Rect _gallery;
+	Common::Rect _quit;
+	int _curButton;
+	bool _buttonDrawnDown;
+	Graphics::Surface *_background;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index cf4113649f..455d138a08 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -13,7 +13,8 @@ MODULE_OBJS = \
 	sound.o \
 	title_sequence.o \
 	video_window.o \
-	window.o
+	window.o \
+	demo/demo_menu.o
 
 
 # This module can be built as a plugin


Commit: 54254d997a261c06ac604a4afdb83a2b59d69eb3
    https://github.com/scummvm/scummvm/commit/54254d997a261c06ac604a4afdb83a2b59d69eb3
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Default to empty string on setAmbientSound

Changed paths:
    engines/buried/sound.h


diff --git a/engines/buried/sound.h b/engines/buried/sound.h
index 40f01e7c99..d7661f6fac 100644
--- a/engines/buried/sound.h
+++ b/engines/buried/sound.h
@@ -47,7 +47,7 @@ public:
 	void shutDown();
 
 	// AMBIENT SOUND CHANNEL FUNCTIONS
-	bool setAmbientSound(const Common::String &fileName, bool fade = false, byte finalVolumeLevel = 64);
+	bool setAmbientSound(const Common::String &fileName = "", bool fade = false, byte finalVolumeLevel = 64);
 	bool adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
 	uint32 getAmbientPosition();
 


Commit: 595503890b88d395fb0f7ef186acbab52e2de9f0
    https://github.com/scummvm/scummvm/commit/595503890b88d395fb0f7ef186acbab52e2de9f0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the frame window class

Changed paths:
  A engines/buried/frame_window.cpp
  A engines/buried/frame_window.h
    engines/buried/buried.cpp
    engines/buried/module.mk
    engines/buried/resources.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index d4c900f948..09412078c4 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -25,12 +25,14 @@
 
 #include "common/scummsys.h"
 #include "common/error.h"
+#include "common/events.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "engines/util.h"
 
 #include "buried/buried.h"
 #include "buried/database.h"
+#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/message.h"
 #include "buried/sound.h"
@@ -39,7 +41,6 @@
 
 #include "buried/title_sequence.h"
 #include "buried/demo/demo_menu.h"
-#include "common/events.h"
 
 namespace Buried {
 
@@ -99,10 +100,7 @@ Common::Error BuriedEngine::run() {
 
 	_gfx = new GraphicsManager(this);
 	_sound = new SoundManager(this);
-
-	// HACK: Create a dummy main window
-	_mainWindow = new Window(this, 0);
-	_mainWindow->setWindowPos(0, 0, 0, 640, 480, Window::kWindowPosNoZOrder);
+	_mainWindow = new FrameWindow(this);
 
 	// HACK: Show a window
 	Window *tempWindow = 0;
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
new file mode 100644
index 0000000000..ecaa8cb7bb
--- /dev/null
+++ b/engines/buried/frame_window.cpp
@@ -0,0 +1,263 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "common/events.h"
+
+#include "buried/buried.h"
+#include "buried/credits.h"
+#include "buried/frame_window.h"
+#include "buried/graphics.h"
+#include "buried/main_menu.h"
+#include "buried/message.h"
+#include "buried/overview.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+#include "buried/title_sequence.h"
+#include "buried/demo/demo_menu.h"
+
+namespace Buried {
+
+FrameWindow::FrameWindow(BuriedEngine *vm) : Window(vm, 0) {
+	// Initialize member variables
+	_mainChildWindow = 0;
+	_controlDown = false;
+	_cacheFrames = false;
+	_cycleDefault = false;
+	_transitionSpeed = 2;
+	_gameInProgress = false;
+	_atMainMenu = true;
+
+	// Retrieve the transition speed from the INI file
+	Common::String transitionConfigName = _vm->isDemo() ? "TransitionSpeed" : _vm->getString(IDS_INI_KEY_TRANS_SPEED);
+	if (ConfMan.hasKey(transitionConfigName))
+		_transitionSpeed = ConfMan.getInt(transitionConfigName);
+
+	// Get the INI file key for frame caching
+	Common::String cacheFramesConfigName = _vm->isDemo() ? "CycleCaching" : _vm->getString(IDS_INI_KEY_CYCLE_CACHING);
+	if (ConfMan.hasKey(cacheFramesConfigName))
+		_cacheFrames = ConfMan.getInt(cacheFramesConfigName) != 0;
+
+	_rect = Common::Rect(0, 0, 640, 480);
+}
+
+FrameWindow::~FrameWindow() {
+	delete _mainChildWindow;
+}
+
+bool FrameWindow::showMainMenu() {
+	_gameInProgress = false;
+	_atMainMenu = true;
+
+	// If we still have a child window, delete it now
+	delete _mainChildWindow;
+	_mainChildWindow = 0;
+
+	_vm->_sound->restart();
+
+	// Create and show the main menu window
+	if (_vm->isDemo()) {
+		_mainChildWindow = new DemoMainMenuWindow(_vm, this);
+		((DemoMainMenuWindow *)_mainChildWindow)->showWithSplash();
+	} else {
+		_mainChildWindow = new MainMenuWindow(_vm, this);
+		((MainMenuWindow *)_mainChildWindow)->showMainMenu();
+	}
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+	return true;
+}
+
+bool FrameWindow::returnToMainMenu() {
+	_gameInProgress = false;
+	_atMainMenu = true;
+
+	// Kill the ambient and restart it
+	_vm->_sound->restart();
+	_vm->_sound->setAmbientSound();
+
+	// If we still have a child window, delete it now
+	delete _mainChildWindow;
+	_mainChildWindow = 0;
+
+	// Create and show the main menu window
+	if (_vm->isDemo()) {
+		_mainChildWindow = new DemoMainMenuWindow(_vm, this);
+		_mainChildWindow->showWindow(kWindowShow);
+	} else {
+		_mainChildWindow = new MainMenuWindow(_vm, this);
+		((MainMenuWindow *)_mainChildWindow)->showMainMenu();
+	}
+
+	// Empty input queue
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+
+	return true;
+}
+
+bool FrameWindow::showClosingScreen() {
+	_gameInProgress = false;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// If we still have a child window, delete it now
+	delete _mainChildWindow;
+	_mainChildWindow = 0;
+
+	// Create the window
+	_mainChildWindow = new TitleSequenceWindow(_vm, this);
+
+	// Show the window
+	_mainChildWindow->showWindow(kWindowShow);
+	_mainChildWindow->setFocus();
+
+	// Start the the title sequence
+	((TitleSequenceWindow *)_mainChildWindow)->playTitleSequence();
+
+	// Empty the input queue
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+	_vm->removeKeyboardMessages(_mainChildWindow);
+
+	return true;
+}
+
+bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
+	_gameInProgress = true;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+
+	delete _mainChildWindow;
+	_mainChildWindow = 0;
+
+	// TODO: Create and show UI, then begin the game
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+	return true;
+}
+
+bool FrameWindow::startNewGame(const Common::String &fileName) {
+	_gameInProgress = true;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+
+	delete _mainChildWindow;
+	_mainChildWindow = 0;
+
+	// TODO: Create and show UI, then begin the game
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+	return true;
+}
+
+bool FrameWindow::showCredits() {
+	_gameInProgress = false;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+
+	// If we still have a child window, delete it now
+	delete _mainChildWindow;
+
+	_mainChildWindow = new CreditsWindow(_vm, this);
+	_mainChildWindow->showWindow(kWindowShow);
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+
+	return true;
+}
+
+bool FrameWindow::showOverview() {
+	_gameInProgress = false;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+
+	// If we still have a child window, delete it now
+	delete _mainChildWindow;
+
+	_mainChildWindow = new OverviewWindow(_vm, this);
+	((OverviewWindow *)_mainChildWindow)->startOverview();
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+
+	return true;
+}
+
+bool FrameWindow::setTimerPause(bool pause) {
+	if (_gameInProgress) {
+		// TODO
+		return true;
+	}
+
+	return false;
+}
+
+
+bool FrameWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void FrameWindow::onKeyDown(const Common::KeyState &key, uint flags) {
+	_controlDown = (key.flags & Common::KBD_CTRL) != 0;
+
+	if (key.keycode == Common::KEYCODE_ESCAPE) {
+		// TODO: Possibly quit
+	}
+}
+
+void FrameWindow::onKeyUp(const Common::KeyState &key, uint flags) {
+	_controlDown = (key.flags & Common::KBD_CTRL) != 0;
+
+	if (_mainChildWindow)
+		_mainChildWindow->sendMessage(new KeyUpMessage(key, flags));
+}
+
+void FrameWindow::onTimer(uint timer) {
+	// Call the sound manager maintence callback function to refresh the buffers
+	_vm->_sound->timerCallback();
+}
+
+void FrameWindow::onSetFocus(Window *oldWindow) {
+	_controlDown = false;
+}
+
+void FrameWindow::onKillFocus(Window *newWindow) {
+	_controlDown = false;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
new file mode 100644
index 0000000000..62816a5d3d
--- /dev/null
+++ b/engines/buried/frame_window.h
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_FRAME_WINDOW_H
+#define BURIED_FRAME_WINDOW_H
+
+#include "buried/window.h"
+
+namespace Buried {
+
+class BuriedEngine;
+
+class FrameWindow : public Window {
+public:
+	FrameWindow(BuriedEngine *vm);
+	~FrameWindow();
+
+	bool showMainMenu();
+	bool returnToMainMenu();
+	// TODO: playMovie
+	bool showClosingScreen();
+	bool showFeaturesScreen();
+	bool startNewGame(bool walkthrough = false, bool introMovie = false);
+	bool startNewGame(const Common::String &fileName);
+	// TODO: startNewGame with continue data
+	// TODO: showDeathScene
+	// TODO: showCompletionScene
+	bool showCredits();
+	bool showOverview();
+	bool notifyUserOfFrameCycling();
+	bool setTimerPause(bool pause);
+
+	bool onEraseBackground();
+	void onKeyDown(const Common::KeyState &key, uint flags);
+	void onKeyUp(const Common::KeyState &key, uint flags);
+	void onTimer(uint timer);
+	void onKillFocus(Window *newWindow);
+	void onSetFocus(Window *oldWindow);
+
+private:
+	Window *_mainChildWindow;
+	bool _controlDown;
+
+	bool _cacheFrames;
+	bool _cycleDefault;
+	int _transitionSpeed;
+	bool _gameInProgress;
+	bool _atMainMenu;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 455d138a08..35eb64db8c 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
 	credits.o \
 	database.o \
 	detection.o \
+	frame_window.o \
 	graphics.o \
 	livetext.o \
 	main_menu.o \
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 3eaffed257..b49f30a024 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -28,6 +28,9 @@
 
 namespace Buried {
 
+#define IDS_INI_KEY_TRANS_SPEED         868
+#define IDS_INI_KEY_CYCLE_CACHING		870
+
 #define IDS_MOVEMENT_DATA_BASE_ID		800
 
 #define IDBD_DIARY1						900


Commit: a2db33cf92ca93cfb0e3788d5f62afdfe97ddd9d
    https://github.com/scummvm/scummvm/commit/a2db33cf92ca93cfb0e3788d5f62afdfe97ddd9d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Make sure we invalidate the focused window if we delete that window

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 81d1870158..96e27de052 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -51,6 +51,10 @@ Window::~Window() {
 
 	// Remove any of our messages from the queue
 	_vm->removeAllMessages(this);
+
+	// Make sure we're not the focused window
+	if (_vm->_focusedWindow == this)
+		_vm->_focusedWindow = 0;
 }
 
 void Window::invalidateRect(const Common::Rect &rect, bool erase) {


Commit: 535d29a869d5b2d1a1f5562c2fe6835d00b8ff05
    https://github.com/scummvm/scummvm/commit/535d29a869d5b2d1a1f5562c2fe6835d00b8ff05
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Hook up the main menus to the frame window and related windows

Changed paths:
    engines/buried/buried.cpp
    engines/buried/credits.cpp
    engines/buried/frame_window.cpp
    engines/buried/main_menu.cpp
    engines/buried/overview.cpp
    engines/buried/title_sequence.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 09412078c4..85843a1012 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -39,9 +39,6 @@
 #include "buried/video_window.h"
 #include "buried/window.h"
 
-#include "buried/title_sequence.h"
-#include "buried/demo/demo_menu.h"
-
 namespace Buried {
 
 BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
@@ -102,17 +99,11 @@ Common::Error BuriedEngine::run() {
 	_sound = new SoundManager(this);
 	_mainWindow = new FrameWindow(this);
 
-	// HACK: Show a window
-	Window *tempWindow = 0;
 	if (isDemo()) {
-		DemoMainMenuWindow *demoMenu = new DemoMainMenuWindow(this, _mainWindow);
-		demoMenu->showWithSplash();
-		tempWindow = demoMenu;
+		// TODO: Title sequence
+		((FrameWindow *)_mainWindow)->showMainMenu();
 	} else {
-		TitleSequenceWindow *titleSeq = new TitleSequenceWindow(this, _mainWindow);
-		titleSeq->setFocus();
-		titleSeq->playTitleSequence();
-		tempWindow = titleSeq;
+		((FrameWindow *)_mainWindow)->showClosingScreen();
 	}
 
 	while (!shouldQuit()) {
@@ -127,8 +118,6 @@ Common::Error BuriedEngine::run() {
 		_system->delayMillis(10);
 	}
 
-	delete tempWindow;
-
 	return Common::kNoError;
 }
 
diff --git a/engines/buried/credits.cpp b/engines/buried/credits.cpp
index 98f5217ea8..2bdc739428 100644
--- a/engines/buried/credits.cpp
+++ b/engines/buried/credits.cpp
@@ -26,6 +26,7 @@
 #include "buried/avi_frames.h"
 #include "buried/buried.h"
 #include "buried/credits.h"
+#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
@@ -93,7 +94,7 @@ bool CreditsWindow::onEraseBackground() {
 
 void CreditsWindow::onLButtonDown(const Common::Point &point, uint flags) {
 	if (_returnButton.contains(point)) {
-		// TODO: Show main menu
+		((FrameWindow *)_parent)->showMainMenu();
 		return;
 	}
 
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index ecaa8cb7bb..c320644203 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -192,6 +192,7 @@ bool FrameWindow::showCredits() {
 
 	_mainChildWindow = new CreditsWindow(_vm, this);
 	_mainChildWindow->showWindow(kWindowShow);
+	_mainChildWindow->invalidateWindow(false);
 
 	_vm->removeMouseMessages(this);
 	_vm->removeMouseMessages(_mainChildWindow);
diff --git a/engines/buried/main_menu.cpp b/engines/buried/main_menu.cpp
index e557e7b611..4fd8cf0a73 100644
--- a/engines/buried/main_menu.cpp
+++ b/engines/buried/main_menu.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/main_menu.h"
 #include "buried/resources.h"
@@ -191,8 +192,9 @@ void MainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	if (_curButton > 0 && _buttons[_curButton - 1].contains(point)) {
 		switch (_curButton) {
 		case BUTTON_INTERFACE_OVERVIEW:
-			// TODO
-			break;
+			_vm->_sound->setAmbientSound();
+			((FrameWindow *)_parent)->showOverview();
+			return;
 		case BUTTON_NEW_GAME:
 			// TODO
 			break;
@@ -200,8 +202,8 @@ void MainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			// TODO
 			break;
 		case BUTTON_CREDITS:
-			// TODO
-			break;
+			((FrameWindow *)_parent)->showCredits();
+			return;
 		case BUTTON_QUIT:
 			_vm->quitGame();
 			return;
diff --git a/engines/buried/overview.cpp b/engines/buried/overview.cpp
index 82f87b3580..63e4de223d 100644
--- a/engines/buried/overview.cpp
+++ b/engines/buried/overview.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/overview.h"
 #include "buried/resources.h"
@@ -171,7 +172,7 @@ void OverviewWindow::onTimer(uint timer) {
 		break;
 	case 4:
 		_currentStatus = 5;
-		// TODO: Return to the main menu
+		((FrameWindow *)_parent)->returnToMainMenu();
 		break;
 	}
 }
diff --git a/engines/buried/title_sequence.cpp b/engines/buried/title_sequence.cpp
index 236f9ba231..9b329bc6ef 100644
--- a/engines/buried/title_sequence.cpp
+++ b/engines/buried/title_sequence.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/title_sequence.h"
 #include "buried/resources.h"
@@ -72,7 +73,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_SW_LOGO_FILENAME))) {
 			delete _currentMovie;
 			_currentMovie = 0;
-			// TODO: Return to main menu
+			((FrameWindow *)_parent)->returnToMainMenu();
 			return false;
 		}
 
@@ -90,7 +91,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_PRESTO_LOGO_FILENAME))) {
 			delete _currentMovie;
 			_currentMovie = 0;
-			// TODO: Return to main menu
+			((FrameWindow *)_parent)->returnToMainMenu();
 			return false;
 		}
 
@@ -107,7 +108,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_MOVIE_FILENAME))) {
 			delete _currentMovie;
 			_currentMovie = 0;
-			// TODO: Return to main menu
+			((FrameWindow *)_parent)->returnToMainMenu();
 			return false;
 		}
 
@@ -118,7 +119,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 		_currentAnimation = 3;
 		return true;
 	case 3: // Exit the title sequence
-		// TODO: Return to main menu
+		((FrameWindow *)_parent)->showMainMenu();
 		return true;
 	}
 


Commit: a08d14bccab3079d86532f2f8efca6fe5b9c202a
    https://github.com/scummvm/scummvm/commit/a08d14bccab3079d86532f2f8efca6fe5b9c202a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Make sure the main window gets deleted before everything else

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 85843a1012..508dd760c8 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -52,11 +52,11 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 }
 
 BuriedEngine::~BuriedEngine() {
+	delete _mainWindow;
 	delete _gfx;
 	delete _mainEXE;
 	delete _library;
 	delete _sound;
-	delete _mainWindow;
 
 	// The queue should be empty since all windows destroy their messages
 }


Commit: 83ea799cac97ab42b5a4d451e91f64555bc03667
    https://github.com/scummvm/scummvm/commit/83ea799cac97ab42b5a4d451e91f64555bc03667
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Fix semi-broken dirty rectangles

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 0136be44d7..ac976b402b 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -312,7 +312,10 @@ uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
 }
 
 void GraphicsManager::invalidateRect(const Common::Rect &rect) {
-	_dirtyRect.extend(rect);
+	if (_dirtyRect.isEmpty())
+		_dirtyRect = rect;
+	else
+		_dirtyRect.extend(rect);
 }
 
 void GraphicsManager::updateScreen() {
@@ -324,7 +327,7 @@ void GraphicsManager::updateScreen() {
 		_vm->_mainWindow->updateWindow();
 
 		// Copy just that rect
-		g_system->copyRectToScreen(_screen->getPixels(), _screen->pitch, _dirtyRect.left, _dirtyRect.top, _dirtyRect.width(), _dirtyRect.height());
+		g_system->copyRectToScreen(_screen->getBasePtr(_dirtyRect.left, _dirtyRect.top), _screen->pitch, _dirtyRect.left, _dirtyRect.top, _dirtyRect.width(), _dirtyRect.height());
 
 		// Empty out the dirty rect
 		_dirtyRect = Common::Rect();


Commit: afecd69ec248c45035174877c30840f46f7bd18d
    https://github.com/scummvm/scummvm/commit/afecd69ec248c45035174877c30840f46f7bd18d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Ensure a window's rect is invalidated upon deletion

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 96e27de052..5f4206fe7c 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -55,6 +55,9 @@ Window::~Window() {
 	// Make sure we're not the focused window
 	if (_vm->_focusedWindow == this)
 		_vm->_focusedWindow = 0;
+
+	// Invalidate this window's rect as well
+	_vm->_gfx->invalidateRect(getAbsoluteRect());
 }
 
 void Window::invalidateRect(const Common::Rect &rect, bool erase) {


Commit: 34f50804bab057d537766c886082f476a2e06d50
    https://github.com/scummvm/scummvm/commit/34f50804bab057d537766c886082f476a2e06d50
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the demo trailer movies

Changed paths:
  A engines/buried/demo/movie_scene.cpp
  A engines/buried/demo/movie_scene.h
    engines/buried/demo/demo_menu.cpp
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h
    engines/buried/module.mk


diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
index ce3d2ecede..4c9da8b3e6 100644
--- a/engines/buried/demo/demo_menu.cpp
+++ b/engines/buried/demo/demo_menu.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/message.h"
 #include "buried/resources.h"
@@ -70,6 +71,8 @@ DemoMainMenuWindow::DemoMainMenuWindow(BuriedEngine *vm, Window *parent) : Windo
 DemoMainMenuWindow::~DemoMainMenuWindow() {
 	_background->free();
 	delete _background;
+
+	_vm->_sound->setAmbientSound();
 }
 
 void DemoMainMenuWindow::showWithSplash() {
@@ -139,17 +142,20 @@ void DemoMainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 
 	switch (_curButton) {
 	case BUTTON_OVERVIEW:
-		// TODO
-		break;
+		if (_overview.contains(point))
+			((FrameWindow *)_parent)->playMovie(_vm->isTrueColor() ? "MISC/24BPP/OVERVIEW.BMP" : "MISC/8BPP/OVERVIEW.BMP", "MISC/OVERVIEW.AVI", 160, 112);
+		return;
 	case BUTTON_TRAILER:
-		// TODO
-		break;
+		if (_trailer.contains(point))
+			((FrameWindow *)_parent)->playMovie(_vm->isTrueColor() ? "MISC/24BPP/TRAILER.BMP" : "MISC/8BPP/TRAILER.BMP", "MISC/TRAILER.AVI", 104, 136);
+		return;
 	case BUTTON_INTERACTIVE:
 		// TODO
 		break;
 	case BUTTON_GALLERY:
-		// TODO
-		break;
+		if (_gallery.contains(point))
+			((FrameWindow *)_parent)->playMovie(_vm->isTrueColor() ? "MISC/24BPP/GALLERY.BMP" : "MISC/8BPP/GALLERY.BMP", "MISC/GALLERY.AVI", 104, 136);
+		return;
 	case BUTTON_QUIT:
 		// TODO
 		return;
diff --git a/engines/buried/demo/movie_scene.cpp b/engines/buried/demo/movie_scene.cpp
new file mode 100644
index 0000000000..e6e60a90f6
--- /dev/null
+++ b/engines/buried/demo/movie_scene.cpp
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/frame_window.h"
+#include "buried/graphics.h"
+#include "buried/video_window.h"
+#include "buried/demo/movie_scene.h"
+
+#include "graphics/surface.h"
+
+namespace Buried {
+
+MovieDisplayWindow::MovieDisplayWindow(BuriedEngine *vm, Window *parent, const Common::String &background, const Common::String &movie, int movieLeft, int movieTop)
+		: Window(vm, parent) {
+	_background = _vm->_gfx->getBitmap(background);
+
+	// Create a rect to use to place the window inside the parent
+	Common::Rect parentRect = parent->getRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = _rect.left + 640;
+	_rect.bottom = _rect.top + 480;
+
+	// Create and position the movie
+	_movie = new VideoWindow(_vm, this);
+
+	if (!_movie->openVideo(movie))
+		error("Failed to open movie '%s'", movie.c_str());
+
+	_movie->setWindowPos(0, movieLeft, movieTop, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+	_movie->enableWindow(false);
+
+	_timer = 0;
+}
+
+MovieDisplayWindow::~MovieDisplayWindow() {
+	if (_timer != 0)
+		killTimer(_timer);
+
+	delete _movie;
+
+	_background->free();
+	delete _background;
+}
+
+bool MovieDisplayWindow::showMovieInWindow() {
+	showWindow(kWindowShow);
+
+	_movie->enableWindow(false);
+	_movie->showWindow(kWindowShow);
+	_movie->playVideo();
+
+	_timer = setTimer(5000);
+	return true;
+}
+
+void MovieDisplayWindow::onPaint() {
+	_vm->_gfx->blit(_background, 0, 0);
+}
+
+bool MovieDisplayWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void MovieDisplayWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	((FrameWindow *)_parent)->returnToMainMenu();
+}
+
+void MovieDisplayWindow::onTimer(uint timer) {
+	if (_movie->getMode() == VideoWindow::kModeStopped)
+		((FrameWindow *)_parent)->returnToMainMenu();
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/demo/movie_scene.h b/engines/buried/demo/movie_scene.h
new file mode 100644
index 0000000000..73daf83348
--- /dev/null
+++ b/engines/buried/demo/movie_scene.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_DEMO_MOVIE_SCENE_H
+#define BURIED_DEMO_MOVIE_SCENE_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class MovieDisplayWindow : public Window {
+public:
+	MovieDisplayWindow(BuriedEngine *vm, Window *parent, const Common::String &background, const Common::String &movie, int movieLeft, int movieTop);
+	~MovieDisplayWindow();
+
+	bool showMovieInWindow();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onTimer(uint timer);
+
+private:
+	Graphics::Surface *_background;
+	VideoWindow *_movie;
+	uint _timer;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index c320644203..a0a7ba948d 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -37,6 +37,7 @@
 #include "buried/sound.h"
 #include "buried/title_sequence.h"
 #include "buried/demo/demo_menu.h"
+#include "buried/demo/movie_scene.h"
 
 namespace Buried {
 
@@ -119,6 +120,21 @@ bool FrameWindow::returnToMainMenu() {
 	return true;
 }
 
+bool FrameWindow::playMovie(const Common::String &background, const Common::String &movie, int movieLeft, int movieTop) {
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+
+	delete _mainChildWindow;
+	_mainChildWindow = new MovieDisplayWindow(_vm, this, background, movie, movieLeft, movieTop);
+
+	((MovieDisplayWindow *)_mainChildWindow)->showMovieInWindow();
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+
+	return true;
+}
+
 bool FrameWindow::showClosingScreen() {
 	_gameInProgress = false;
 	_atMainMenu = false;
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index 62816a5d3d..c3d65e19f1 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -39,7 +39,7 @@ public:
 
 	bool showMainMenu();
 	bool returnToMainMenu();
-	// TODO: playMovie
+	bool playMovie(const Common::String &background, const Common::String &movie, int movieLeft, int movieTop);
 	bool showClosingScreen();
 	bool showFeaturesScreen();
 	bool startNewGame(bool walkthrough = false, bool introMovie = false);
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 35eb64db8c..5caef81995 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -15,7 +15,8 @@ MODULE_OBJS = \
 	title_sequence.o \
 	video_window.o \
 	window.o \
-	demo/demo_menu.o
+	demo/demo_menu.o \
+	demo/movie_scene.o
 
 
 # This module can be built as a plugin


Commit: 2e335fd74036de269a20849328458e023ed0f9d8
    https://github.com/scummvm/scummvm/commit/2e335fd74036de269a20849328458e023ed0f9d8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the demo features screens

Changed paths:
  A engines/buried/demo/features.cpp
  A engines/buried/demo/features.h
    engines/buried/demo/demo_menu.cpp
    engines/buried/frame_window.cpp
    engines/buried/module.mk


diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
index 4c9da8b3e6..6d541d05a0 100644
--- a/engines/buried/demo/demo_menu.cpp
+++ b/engines/buried/demo/demo_menu.cpp
@@ -71,8 +71,6 @@ DemoMainMenuWindow::DemoMainMenuWindow(BuriedEngine *vm, Window *parent) : Windo
 DemoMainMenuWindow::~DemoMainMenuWindow() {
 	_background->free();
 	delete _background;
-
-	_vm->_sound->setAmbientSound();
 }
 
 void DemoMainMenuWindow::showWithSplash() {
@@ -142,22 +140,29 @@ void DemoMainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 
 	switch (_curButton) {
 	case BUTTON_OVERVIEW:
-		if (_overview.contains(point))
+		if (_overview.contains(point)) {
+			_vm->_sound->setAmbientSound();
 			((FrameWindow *)_parent)->playMovie(_vm->isTrueColor() ? "MISC/24BPP/OVERVIEW.BMP" : "MISC/8BPP/OVERVIEW.BMP", "MISC/OVERVIEW.AVI", 160, 112);
+		}
 		return;
 	case BUTTON_TRAILER:
-		if (_trailer.contains(point))
+		if (_trailer.contains(point)) {
+			_vm->_sound->setAmbientSound();
 			((FrameWindow *)_parent)->playMovie(_vm->isTrueColor() ? "MISC/24BPP/TRAILER.BMP" : "MISC/8BPP/TRAILER.BMP", "MISC/TRAILER.AVI", 104, 136);
+		}
 		return;
 	case BUTTON_INTERACTIVE:
 		// TODO
 		break;
 	case BUTTON_GALLERY:
-		if (_gallery.contains(point))
+		if (_gallery.contains(point)) {
+			_vm->_sound->setAmbientSound();
 			((FrameWindow *)_parent)->playMovie(_vm->isTrueColor() ? "MISC/24BPP/GALLERY.BMP" : "MISC/8BPP/GALLERY.BMP", "MISC/GALLERY.AVI", 104, 136);
+		}
 		return;
 	case BUTTON_QUIT:
-		// TODO
+		if (_quit.contains(point))
+			((FrameWindow *)_parent)->showFeaturesScreen();
 		return;
 	}
 
diff --git a/engines/buried/demo/features.cpp b/engines/buried/demo/features.cpp
new file mode 100644
index 0000000000..35273ee91e
--- /dev/null
+++ b/engines/buried/demo/features.cpp
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/frame_window.h"
+#include "buried/graphics.h"
+#include "buried/message.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+#include "buried/demo/features.h"
+
+#include "common/events.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+FeaturesDisplayWindow::FeaturesDisplayWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	Common::Rect parentRect = _parent->getClientRect();
+	_rect.left = (parentRect.right - 640) / 2;
+	_rect.top = (parentRect.bottom - 480) / 2;
+	_rect.right = parentRect.left + 640;
+	_rect.bottom = parentRect.top + 480;
+
+	_curBackground = 0;
+	_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "MISC/24BPP/FEATURE1.BMP" : "MISC/8BPP/FEATURE1.BMP");
+}
+
+FeaturesDisplayWindow::~FeaturesDisplayWindow() {
+	if (_background) {
+		_background->free();
+		delete _background;
+	}
+}
+
+void FeaturesDisplayWindow::onPaint() {
+	_vm->_gfx->blit(_background, 0, 0);
+}
+
+bool FeaturesDisplayWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void FeaturesDisplayWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_parent);
+
+	_curBackground++;
+	if (_background) {
+		_background->free();
+		delete _background;
+		_background = 0;
+	}
+
+	switch (_curBackground) {
+	case 1:
+		_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "MISC/24BPP/FEATURE2.BMP" : "MISC/8BPP/FEATURE2.BMP");
+		break;
+	case 2:
+		_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "MISC/24BPP/FEATURE3.BMP" : "MISC/8BPP/FEATURE3.BMP");
+		break;
+	case 3:
+		_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "MISC/24BPP/CLOSING.BMP" : "MISC/8BPP/CLOSING.BMP");
+		break;
+	case 4:
+		_vm->quitGame();
+		return;
+	}
+
+	invalidateWindow(false);
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_parent);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/demo/features.h b/engines/buried/demo/features.h
new file mode 100644
index 0000000000..38980a4f61
--- /dev/null
+++ b/engines/buried/demo/features.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_DEMO_FEATURES_H
+#define BURIED_DEMO_FEATURES_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class FeaturesDisplayWindow : public Window {
+public:
+	FeaturesDisplayWindow(BuriedEngine *vm, Window *parent);
+	~FeaturesDisplayWindow();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+
+private:
+	Graphics::Surface *_background;
+	int _curBackground;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index a0a7ba948d..45a9346a60 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -37,6 +37,7 @@
 #include "buried/sound.h"
 #include "buried/title_sequence.h"
 #include "buried/demo/demo_menu.h"
+#include "buried/demo/features.h"
 #include "buried/demo/movie_scene.h"
 
 namespace Buried {
@@ -165,6 +166,20 @@ bool FrameWindow::showClosingScreen() {
 	return true;
 }
 
+bool FrameWindow::showFeaturesScreen() {
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+
+	delete _mainChildWindow;
+	_mainChildWindow = new FeaturesDisplayWindow(_vm, this);
+
+	_mainChildWindow->showWindow(kWindowShow);
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(_mainChildWindow);
+	return true;
+}
+
 bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
 	_gameInProgress = true;
 	_atMainMenu = false;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 5caef81995..de8f8da77b 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS = \
 	video_window.o \
 	window.o \
 	demo/demo_menu.o \
+	demo/features.o \
 	demo/movie_scene.o
 
 


Commit: 558736180c72660a8718987c64ebe4ffa3e85dba
    https://github.com/scummvm/scummvm/commit/558736180c72660a8718987c64ebe4ffa3e85dba
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Allow for updating the screen without updating the main window

Used for temporary things drawn to the screen

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index ac976b402b..9c93bf2d47 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -318,13 +318,14 @@ void GraphicsManager::invalidateRect(const Common::Rect &rect) {
 		_dirtyRect.extend(rect);
 }
 
-void GraphicsManager::updateScreen() {
+void GraphicsManager::updateScreen(bool drawWindows) {
 	bool shouldUpdateScreen = _mouseMoved;
 	_mouseMoved = false;
 
 	if (!_dirtyRect.isEmpty()) {
 		// Draw the main window, which will draw its children
-		_vm->_mainWindow->updateWindow();
+		if (drawWindows)
+			_vm->_mainWindow->updateWindow();
 
 		// Copy just that rect
 		g_system->copyRectToScreen(_screen->getBasePtr(_dirtyRect.left, _dirtyRect.top), _screen->pitch, _dirtyRect.left, _dirtyRect.top, _dirtyRect.width(), _dirtyRect.height());
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 26d6a03442..a7cb9e610a 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -81,7 +81,7 @@ public:
 	const Common::Rect &getDirtyRect() const { return _dirtyRect; }
 
 	void markMouseMoved() { _mouseMoved = true; }
-	void updateScreen();
+	void updateScreen(bool drawWindows = true);
 	Graphics::Surface *getScreen() const { return _screen; }
 
 	void blit(const Graphics::Surface *surface, int x, int y);


Commit: f9273c13f5a815217a64353a578ad56517788fcc
    https://github.com/scummvm/scummvm/commit/f9273c13f5a815217a64353a578ad56517788fcc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Implement the demo title sequence

Changed paths:
    engines/buried/buried.cpp
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 508dd760c8..5585541498 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -100,7 +100,7 @@ Common::Error BuriedEngine::run() {
 	_mainWindow = new FrameWindow(this);
 
 	if (isDemo()) {
-		// TODO: Title sequence
+		((FrameWindow *)_mainWindow)->showTitleSequence();
 		((FrameWindow *)_mainWindow)->showMainMenu();
 	} else {
 		((FrameWindow *)_mainWindow)->showClosingScreen();
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 45a9346a60..ff3156384c 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -25,6 +25,8 @@
 
 #include "common/config-manager.h"
 #include "common/events.h"
+#include "common/system.h"
+#include "graphics/surface.h"
 
 #include "buried/buried.h"
 #include "buried/credits.h"
@@ -36,6 +38,7 @@
 #include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/title_sequence.h"
+#include "buried/video_window.h"
 #include "buried/demo/demo_menu.h"
 #include "buried/demo/features.h"
 #include "buried/demo/movie_scene.h"
@@ -69,6 +72,54 @@ FrameWindow::~FrameWindow() {
 	delete _mainChildWindow;
 }
 
+bool FrameWindow::showTitleSequence() {
+	invalidateWindow();
+	updateWindow();
+
+	Graphics::Surface *swLogo = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "MISC/24BPP/SWLOGO.BMP" : "MISC/8BPP/SWLOGO.BMP");
+	uint32 x = (640 - swLogo->w) / 2;
+	uint32 y = (480 - swLogo->h) / 2;
+	_vm->_gfx->blit(swLogo, x, y);
+	_vm->_gfx->updateScreen(false);
+	swLogo->free();
+	delete swLogo;
+
+	_vm->_sound->playInterfaceSound("MISC/SWSTING.WAV");
+
+	_vm->removeMouseMessages(this);
+
+	uint32 startTime = g_system->getMillis();
+	while (g_system->getMillis() < (startTime + 7000) && !_vm->hasMessage(this, kMessageTypeLButtonDown, kMessageTypeLButtonDown) && !_vm->shouldQuit())
+		_vm->yield();
+
+	_vm->_sound->stopInterfaceSound();
+	invalidateWindow();
+
+	VideoWindow *video = new VideoWindow(_vm, this);
+
+	if (!video->openVideo("MISC/PRESTO.AVI"))
+		error("Failed to open MISC/PRESTO.AVI");
+
+	video->enableWindow(false);
+	x = (_rect.right - video->getRect().right) / 2;
+	y = (_rect.bottom - video->getRect().bottom) / 2;
+
+	video->setWindowPos(0, x, y, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosShowWindow);
+	video->playVideo();
+	enableWindow(true);
+
+	_vm->removeMouseMessages(this);
+	_vm->removeMouseMessages(video);
+
+	while (!_vm->shouldQuit() && video->getMode() != VideoWindow::kModeStopped && !_vm->hasMessage(this, kMessageTypeLButtonDown, kMessageTypeLButtonDown))
+		_vm->yield();
+
+	delete video;
+
+	invalidateWindow();
+	return true;
+}
+
 bool FrameWindow::showMainMenu() {
 	_gameInProgress = false;
 	_atMainMenu = true;
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index c3d65e19f1..ceba583e54 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -37,6 +37,7 @@ public:
 	FrameWindow(BuriedEngine *vm);
 	~FrameWindow();
 
+	bool showTitleSequence();
 	bool showMainMenu();
 	bool returnToMainMenu();
 	bool playMovie(const Common::String &background, const Common::String &movie, int movieLeft, int movieTop);


Commit: f0cb54504bbb08f2042f2064e7c8a8f4c7e0379d
    https://github.com/scummvm/scummvm/commit/f0cb54504bbb08f2042f2064e7c8a8f4c7e0379d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Fix some memory leaks

Changed paths:
    engines/buried/avi_frames.cpp
    engines/buried/avi_frames.h
    engines/buried/demo/demo_menu.cpp


diff --git a/engines/buried/avi_frames.cpp b/engines/buried/avi_frames.cpp
index 98139c14bc..561c589ae4 100644
--- a/engines/buried/avi_frames.cpp
+++ b/engines/buried/avi_frames.cpp
@@ -39,6 +39,7 @@ AVIFrames::AVIFrames(const Common::String &fileName, uint cachedFrames) {
 	_cacheEnabled = false;
 	_lastFrame = 0;
 	_lastFrameIndex = -1;
+	_tempFrame = 0;
 
 	if (!fileName.empty())
 		open(fileName, cachedFrames);
@@ -92,6 +93,11 @@ void AVIFrames::close() {
 
 	_lastFrameIndex = -1;
 	_lastFrame = 0;
+
+	if (_tempFrame) {
+		_tempFrame->free();
+		delete _tempFrame;
+	}
 }
 
 const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
@@ -122,8 +128,16 @@ const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
 		copy = frame->convertTo(g_system->getScreenFormat());
 	}
 
-	if (_cacheEnabled)
+	if (_cacheEnabled) {
 		addFrameToCache(frameIndex, copy);
+	} else {
+		if (_tempFrame) {
+			_tempFrame->free();
+			delete _tempFrame;
+		}
+
+		_tempFrame = copy;
+	}
 
 	return copy;
 }
diff --git a/engines/buried/avi_frames.h b/engines/buried/avi_frames.h
index 6d1ffe8ac0..ab266d9ed9 100644
--- a/engines/buried/avi_frames.h
+++ b/engines/buried/avi_frames.h
@@ -76,6 +76,7 @@ private:
 	bool _cacheEnabled;
 
 	Graphics::Surface *_lastFrame;
+	Graphics::Surface *_tempFrame;
 	int _lastFrameIndex;
 };
 
diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
index 6d541d05a0..c03a4ba903 100644
--- a/engines/buried/demo/demo_menu.cpp
+++ b/engines/buried/demo/demo_menu.cpp
@@ -92,6 +92,7 @@ void DemoMainMenuWindow::showWithSplash() {
 	while (g_system->getMillis() < (startTime + 6000) && !_vm->hasMessage(this, kMessageTypeLButtonUp, kMessageTypeLButtonUp) && !_vm->shouldQuit())
 		_vm->yield();
 
+	_background->free();
 	delete _background;
 	_background = temp;
 	invalidateWindow(false);


Commit: 4d104c12e2d9c871da0d2bf4ca2111234829d81d
    https://github.com/scummvm/scummvm/commit/4d104c12e2d9c871da0d2bf4ca2111234829d81d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
COMMON: Fix some memory leaks

Changed paths:
    common/winexe_ne.cpp


diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index 30652c0d02..90dd090f81 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -134,7 +134,7 @@ bool NEResources::loadFromCompressedEXE(const String &fileName) {
 	}
 
 	delete[] window;
-	SeekableReadStream *stream = new MemoryReadStream(unpackedData, unpackedLength);
+	SeekableReadStream *stream = new MemoryReadStream(unpackedData, unpackedLength, DisposeAfterUse::YES);
 
 	return loadFromEXE(stream);
 }
@@ -353,6 +353,7 @@ String NEResources::loadString(uint32 stringID) {
 	while (size--)
 		string += (char)stream->readByte();
 
+	delete stream;
 	return string;
 }
 


Commit: c2de52df05cf77ba622818166695b824dcdb2212
    https://github.com/scummvm/scummvm/commit/c2de52df05cf77ba622818166695b824dcdb2212
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Make mouse messages relative to the window

Changed paths:
    engines/buried/buried.cpp
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 5585541498..b3e20d2a35 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -315,10 +315,13 @@ void BuriedEngine::pollForEvents() {
 	Common::Event event;
 	while (_eventMan->pollEvent(event)) {
 		switch (event.type) {
-		case Common::EVENT_MOUSEMOVE:
+		case Common::EVENT_MOUSEMOVE: {
 			_gfx->markMouseMoved();
-			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MouseMoveMessage(event.mouse, 0));
+			Common::Point relativePos;
+			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
+			window->postMessage(new MouseMoveMessage(relativePos, 0));
 			break;
+		}
 		case Common::EVENT_KEYUP:
 			if (_focusedWindow)
 				_focusedWindow->postMessage(new KeyUpMessage(event.kbd, 0));
@@ -327,22 +330,37 @@ void BuriedEngine::pollForEvents() {
 			if (_focusedWindow)
 				_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
 			break;
-		case Common::EVENT_LBUTTONDOWN:
-			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonDownMessage(event.mouse, 0));
+		case Common::EVENT_LBUTTONDOWN: {
+			Common::Point relativePos;
+			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
+			window->postMessage(new LButtonDownMessage(relativePos, 0));
 			break;
-		case Common::EVENT_LBUTTONUP:
+		}
+		case Common::EVENT_LBUTTONUP: {
 			// TODO: Double-click
-			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new LButtonUpMessage(event.mouse, 0));
+			Common::Point relativePos;
+			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
+			window->postMessage(new LButtonUpMessage(relativePos, 0));
 			break;
-		case Common::EVENT_MBUTTONUP:
-			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new MButtonUpMessage(event.mouse, 0));
+		}
+		case Common::EVENT_MBUTTONUP: {
+			Common::Point relativePos;
+			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
+			window->postMessage(new MButtonUpMessage(relativePos, 0));
 			break;
-		case Common::EVENT_RBUTTONDOWN:
-			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonDownMessage(event.mouse, 0));
+		}
+		case Common::EVENT_RBUTTONDOWN: {
+			Common::Point relativePos;
+			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
+			window->postMessage(new RButtonDownMessage(relativePos, 0));
 			break;
-		case Common::EVENT_RBUTTONUP:
-			_mainWindow->findWindowAtPoint(event.mouse)->postMessage(new RButtonUpMessage(event.mouse, 0));
+		}
+		case Common::EVENT_RBUTTONUP: {
+			Common::Point relativePos;
+			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
+			window->postMessage(new RButtonUpMessage(relativePos, 0));
 			break;
+		}
 		default:
 			break;
 		}
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 5f4206fe7c..c0de8c2b99 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -260,14 +260,19 @@ Window *Window::setFocus() {
 	return oldWindow;
 }
 
-Window *Window::findWindowAtPoint(const Common::Point &point) {
+Window *Window::findWindowAtPoint(const Common::Point &point, Common::Point &relativePos) {
 	for (WindowList::iterator it = _topMostChildren.reverse_begin(); it != _topMostChildren.end(); it--)
 		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
-			return (*it)->findWindowAtPoint(point);
+			return (*it)->findWindowAtPoint(point, relativePos);
 
 	for (WindowList::iterator it = _children.reverse_begin(); it != _children.end(); it--)
 		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
-			return (*it)->findWindowAtPoint(point);
+			return (*it)->findWindowAtPoint(point, relativePos);
+
+	// Also calculate the relative position of the point within the window
+	Common::Rect absoluteRect = getAbsoluteRect();
+	relativePos.x = point.x - absoluteRect.left;
+	relativePos.y = point.y - absoluteRect.top;
 
 	return this;
 }
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 46ed982401..69dd0d87f3 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -103,7 +103,7 @@ public:
 	void sendMessage(Message *message);
 	void postMessage(Message *message);
 
-	Window *findWindowAtPoint(const Common::Point &point);
+	Window *findWindowAtPoint(const Common::Point &point, Common::Point &relativePoint);
 
 protected:
 	BuriedEngine *_vm;


Commit: da2d2758593cc16dda00972b5d0ff9a3a0dea747
    https://github.com/scummvm/scummvm/commit/da2d2758593cc16dda00972b5d0ff9a3a0dea747
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Fix resource struct types

Changed paths:
    engines/buried/animdata.h
    engines/buried/bookdata.h
    engines/buried/fbcdata.h
    engines/buried/inndata.h
    engines/buried/invdata.h
    engines/buried/navdata.h
    engines/buried/snddata.h
    engines/buried/sprtdata.h


diff --git a/engines/buried/animdata.h b/engines/buried/animdata.h
index 9cd953ef3d..8f6418d1a1 100644
--- a/engines/buried/animdata.h
+++ b/engines/buried/animdata.h
@@ -31,11 +31,11 @@
 namespace Buried {
 
 struct AnimEvent {
-	uint16 animationID;
-	uint16 fileNameID;
-	uint16 audioStreamCount;
-	uint32 startFrame;
-	uint32 frameCount;
+	int16 animationID;
+	int16 fileNameID;
+	int16 audioStreamCount;
+	int32 startFrame;
+	int32 frameCount;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/bookdata.h b/engines/buried/bookdata.h
index 4153dff2f4..43368809d1 100644
--- a/engines/buried/bookdata.h
+++ b/engines/buried/bookdata.h
@@ -31,14 +31,14 @@
 namespace Buried {
 
 struct PageTurn {
-	uint32 typeOfTrans;
-	uint32 destPage;
+	int16 typeOfTrans;
+	int16 destPage;
 };
 
 struct BookPage {
-	uint16 pageID;
-	uint32 pageFrameIndex;
-	uint16 numLines;
+	int16 pageID;
+	int32 pageFrameIndex;
+	int16 numLines;
 	PageTurn up;
 	PageTurn left;
 	PageTurn right;
diff --git a/engines/buried/fbcdata.h b/engines/buried/fbcdata.h
index 814d10dc61..b0c307237b 100644
--- a/engines/buried/fbcdata.h
+++ b/engines/buried/fbcdata.h
@@ -31,18 +31,18 @@
 namespace Buried {
 
 struct FilesPageHotspot {
-	uint32 left;
-	uint32 top;
-	uint32 right;
-	uint32 bottom;
-	uint32 pageIndex;
+	int16 left;
+	int16 top;
+	int16 right;
+	int16 bottom;
+	int16 pageIndex;
 };
 
 struct FilesPage {
-	uint16 pageID;
-	uint16 returnPageIndex;
-	uint16 nextButtonPageIndex;
-	uint16 prevButtonPageIndex;
+	int16 pageID;
+	int16 returnPageIndex;
+	int16 nextButtonPageIndex;
+	int16 prevButtonPageIndex;
 	FilesPageHotspot hotspots[6];
 };
 
diff --git a/engines/buried/inndata.h b/engines/buried/inndata.h
index 11c2051324..0262743d82 100644
--- a/engines/buried/inndata.h
+++ b/engines/buried/inndata.h
@@ -31,17 +31,17 @@
 namespace Buried {
 
 struct INNHotspotData {
-	uint32 left;
-	uint32 top;
-	uint32 right;
-	uint32 bottom;
-	uint32 stillFrameOffset;
+	int16 left;
+	int16 top;
+	int16 right;
+	int16 bottom;
+	int32 stillFrameOffset;
 };
 
 struct INNFrame {
-	uint16 topicID;
-	uint16 pageType;
-	uint32 stillFrameOffset;
+	int16 topicID;
+	int16 pageType;
+	int32 stillFrameOffset;
 	INNHotspotData hotspots[8];
 };
 
@@ -53,9 +53,9 @@ enum {
 };
 
 struct INNMediaElement {
-	uint32 frameIndex;
-	uint16 mediaType;
-	uint16 fileIDOffset;
+	int32 frameIndex;
+	int16 mediaType;
+	int16 fileIDOffset;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/invdata.h b/engines/buried/invdata.h
index 507ecbf0c1..87eff0d2ed 100644
--- a/engines/buried/invdata.h
+++ b/engines/buried/invdata.h
@@ -80,9 +80,9 @@ enum {
 };
 
 struct InventoryElement {
-	uint16 itemID;
-	uint32 firstDragID;
-	uint32 dragIDCount;
+	int16 itemID;
+	int32 firstDragID;
+	int32 dragIDCount;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/navdata.h b/engines/buried/navdata.h
index a8a801c74f..f3a390846c 100644
--- a/engines/buried/navdata.h
+++ b/engines/buried/navdata.h
@@ -31,12 +31,12 @@
 namespace Buried {
 
 struct Location {
-	uint16 timeZone;
-	uint16 environment;
-	uint16 node;
-	uint16 facing;
-	uint16 orientaton;
-	uint16 depth;
+	int16 timeZone;
+	int16 environment;
+	int16 node;
+	int16 facing;
+	int16 orientaton;
+	int16 depth;
 };
 
 enum {
@@ -56,15 +56,15 @@ enum {
 
 struct DestinationScene {
 	Location destinationScene;
-	uint16 transitionType;
+	int16 transitionType;
 
 	// Data specific to each type of transition:
 	// TRANSITION_VIDEO: video clip ID
 	// TRANSITION_PUSH: identifies direction
-	uint16 transitionData;
+	int16 transitionData;
 
-	uint32 transitionStartFrame; // Unused for video
-	uint32 transitionLength;     // Unused for video
+	int32 transitionStartFrame; // Unused for video
+	int32 transitionLength;     // Unused for video
 };
 
 struct LocationStaticData {
@@ -74,12 +74,12 @@ struct LocationStaticData {
 	DestinationScene destRight;
 	DestinationScene destDown;
 	DestinationScene destForward;
-	uint16 classID;
-	uint32 navFrameIndex;
-	uint32 miscFrameIndex;
-	uint32 miscFrameCount;
-	uint32 cycleStartFrame;
-	uint32 cycleFrameCount;
+	int16 classID;
+	int32 navFrameIndex;
+	int32 miscFrameIndex;
+	int32 miscFrameCount;
+	int32 cycleStartFrame;
+	int32 cycleFrameCount;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/snddata.h b/engines/buried/snddata.h
index 8d734ca9c5..ccc6e7cab3 100644
--- a/engines/buried/snddata.h
+++ b/engines/buried/snddata.h
@@ -31,10 +31,10 @@
 namespace Buried {
 
 struct SoundEvent {
-	uint16 eventID;
-	uint16 fileNameID;
-	uint16 flags;
-	uint16 volumeLevel;
+	int16 eventID;
+	int16 fileNameID;
+	int16 flags;
+	int16 volumeLevel;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/sprtdata.h b/engines/buried/sprtdata.h
index d5faee601e..2c7409d550 100644
--- a/engines/buried/sprtdata.h
+++ b/engines/buried/sprtdata.h
@@ -36,10 +36,10 @@ namespace Buried {
 
 struct Sprite {
 	Graphics::Surface *image;
-	int32 xPos;
-	int32 yPos;
-	int32 width;
-	int32 height;
+	int16 xPos;
+	int16 yPos;
+	int16 width;
+	int16 height;
 	byte redTrans;
 	byte greenTrans;
 	byte blueTrans;


Commit: 406bbb19cfc9bbe054393f7c2ffb58f529c2ca5a
    https://github.com/scummvm/scummvm/commit/406bbb19cfc9bbe054393f7c2ffb58f529c2ca5a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Children get pushed to the bottom of the z-order on creation

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index c0de8c2b99..36b7375a43 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -37,9 +37,9 @@ Window::Window(BuriedEngine *vm, Window *parent, bool visible) : _vm(vm), _paren
 	_enabled = true;
 	_needsErase = false;
 
-	// Add us to the top of the parent's window list
+	// Add us to the bottom of the parent's window list
 	if (_parent)
-		_parent->_children.push_back(this);
+		_parent->_children.push_front(this);
 }
 
 Window::~Window() {


Commit: e4560d529170a2380ca5741711427e20697ed32d
    https://github.com/scummvm/scummvm/commit/e4560d529170a2380ca5741711427e20697ed32d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Invalidate the rect on a window that changes visibility

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 36b7375a43..fdd8901474 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -202,7 +202,12 @@ void Window::setWindowPos(Window *insertAfter, int x, int y, int width, int heig
 }
 
 void Window::showWindow(WindowShowMode showMode) {
-	_visible = (showMode != kWindowHide);
+	bool newVisibility = (showMode != kWindowHide);
+
+	if (_visible != newVisibility) {
+		invalidateWindow();
+		_visible = newVisibility;
+	}
 
 	if (showMode == kWindowShowNormal) {
 		// TODO: Activate


Commit: 4b5960b4b701e1134752fb0249e0d2389682c0d1
    https://github.com/scummvm/scummvm/commit/4b5960b4b701e1134752fb0249e0d2389682c0d1
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Allow for creating a font for Arial Bold too

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 9c93bf2d47..3ef7c6d399 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -142,59 +142,21 @@ static const uint32 s_codePage1252[256] = {
 #undef REQUIRED
 #undef NOT_REQUIRED
 
-Graphics::Font *GraphicsManager::createFont(int size) const {
-	Common::SeekableReadStream *stream = 0;
-
-	// HACK: Try to load the system font
+Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
 	// TODO: MS Gothic for the Japanese version (please buy for clone2727)
-	// Arial for everything else (???)
-#if defined(WIN32)
-	Common::FSNode fontPath("C:/WINDOWS/Fonts/arial.ttf");
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-
-	if (!stream) {
-		Common::FSNode win2kFontPath("C:/WINNT/Fonts/arial.ttf");
-
-		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
-			stream = win2kFontPath.createReadStream();
-	}
-#elif defined(MACOSX)
-	// Attempt to load the font from the Arial.ttf font first
-	Common::FSNode fontPath("/Library/Fonts/Arial.ttf");
+	// Arial or Arial Bold for everything else (???)
 
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
+	Common::SeekableReadStream *stream = findArialStream(bold);
 
-	if (!stream) {
-		// Try the suitcase on the system
-		Common::FSNode fontDirectory("/Library/Fonts");
-		Common::MacResManager resFork;
-
-		// DOUBLE HACK WARNING: Just assume it's 0x1000
-		// (it should always be this, the first font, but parsing the FOND would be better)
-		if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
-			stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
-
-		// ...and one last try
-		if (!stream) {
-			Common::FSNode msFontDirectory("/Library/Fonts/Microsoft");
-			if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
-				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), 0x1000);
-		}
-	}
-#endif
-
-	if (!stream) {
-		// TODO: Try to load an equivalent font from the theme
+	if (!stream)
 		return 0;
-	}
 
 	// TODO: Make the monochrome mode optional
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
 	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
+	// FIXME: 'size' is really 'height', not point size.
+	// FIXME: DPI should be 96, not 0 (72)
 	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 	delete stream;
 	return font;
@@ -453,4 +415,55 @@ Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *
 	return convertedSurface;
 }
 
+Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
+	Common::SeekableReadStream *stream = 0;
+
+	// HACK: Try to load the system font
+#if defined(WIN32)
+	Common::String baseName = bold ? "arialbd.ttf" : "arial.ttf";
+	Common::FSNode fontPath("C:/WINDOWS/Fonts/" + baseName);
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		Common::FSNode win2kFontPath("C:/WINNT/Fonts/" + baseName);
+
+		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
+			stream = win2kFontPath.createReadStream();
+	}
+#elif defined(MACOSX)
+	// Attempt to load the font from the Arial.ttf font first
+	Common::String baseName = bold ? "Arial Bold" : "Arial";
+	Common::FSNode fontPath(Common::String::format("/Library/Fonts/%s.ttf", baseName.c_str()));
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		// Try the suitcase on the system
+		Common::FSNode fontDirectory("/Library/Fonts");
+		Common::MacResManager resFork;
+
+		// DOUBLE HACK WARNING: Just assume it's 0x1000
+		// (it should always be this, the first font, but parsing the FOND would be better)
+		if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
+			stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), baseName);
+
+		// ...and one last try
+		if (!stream) {
+			Common::FSNode msFontDirectory("/Library/Fonts/Microsoft");
+			if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
+				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), baseName);
+		}
+	}
+#endif
+
+	if (!stream) {
+		// TODO: Find the equivalent free font
+	}
+
+	return stream;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index a7cb9e610a..cf133aeba6 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -71,7 +71,7 @@ public:
 	~GraphicsManager();
 
 	byte *getDefaultPalette() const { return _palette; }
-	Graphics::Font *createFont(int size) const;
+	Graphics::Font *createFont(int size, bool bold = false) const;
 	Cursor setCursor(Cursor newCursor);
 	Graphics::Surface *getBitmap(uint32 bitmapID);
 	Graphics::Surface *getBitmap(const Common::String &fileName);
@@ -101,6 +101,8 @@ private:
 	
 	byte *createDefaultPalette() const;
 	Graphics::Surface *getBitmap(Common::SeekableReadStream *stream);
+
+	Common::SeekableReadStream *findArialStream(bool bold) const;
 };
 
 } // End of namespace Buried


Commit: 4ea076bde02edc68db0ec70f8ecb7e9279be6f9d
    https://github.com/scummvm/scummvm/commit/4ea076bde02edc68db0ec70f8ecb7e9279be6f9d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Fix erase background behavior

Erase should apply globally, not per-window

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 3ef7c6d399..485ea2631b 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -43,6 +43,7 @@ namespace Buried {
 GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
 	_curCursor = kCursorNone;
 	_mouseMoved = false;
+	_needsErase = false;
 
 	setCursor(kCursorArrow);
 	CursorMan.showMouse(true);
@@ -273,11 +274,13 @@ uint32 GraphicsManager::getColor(byte r, byte g, byte b) {
 	return best;
 }
 
-void GraphicsManager::invalidateRect(const Common::Rect &rect) {
+void GraphicsManager::invalidateRect(const Common::Rect &rect, bool erase) {
 	if (_dirtyRect.isEmpty())
 		_dirtyRect = rect;
 	else
 		_dirtyRect.extend(rect);
+
+	_needsErase |= erase;
 }
 
 void GraphicsManager::updateScreen(bool drawWindows) {
@@ -301,6 +304,8 @@ void GraphicsManager::updateScreen(bool drawWindows) {
 
 	if (shouldUpdateScreen)
 		g_system->updateScreen();
+
+	_needsErase = false;
 }
 
 void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index cf133aeba6..93cc3c2752 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -77,12 +77,13 @@ public:
 	Graphics::Surface *getBitmap(const Common::String &fileName);
 	uint32 getColor(byte r, byte g, byte b);
 
-	void invalidateRect(const Common::Rect &rect);
+	void invalidateRect(const Common::Rect &rect, bool erase = true);
 	const Common::Rect &getDirtyRect() const { return _dirtyRect; }
 
 	void markMouseMoved() { _mouseMoved = true; }
 	void updateScreen(bool drawWindows = true);
 	Graphics::Surface *getScreen() const { return _screen; }
+	bool needsErase() const { return _needsErase; }
 
 	void blit(const Graphics::Surface *surface, int x, int y);
 	void blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect);
@@ -98,6 +99,7 @@ private:
 	bool _mouseMoved;
 	Graphics::Surface *_screen;
 	byte *_palette;
+	bool _needsErase;
 	
 	byte *createDefaultPalette() const;
 	Graphics::Surface *getBitmap(Common::SeekableReadStream *stream);
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index fdd8901474..75100a9022 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -35,7 +35,6 @@ const Window *kWindowPosTopMost = (const Window *)-1;
 
 Window::Window(BuriedEngine *vm, Window *parent, bool visible) : _vm(vm), _parent(parent), _visible(visible) {
 	_enabled = true;
-	_needsErase = false;
 
 	// Add us to the bottom of the parent's window list
 	if (_parent)
@@ -61,8 +60,7 @@ Window::~Window() {
 }
 
 void Window::invalidateRect(const Common::Rect &rect, bool erase) {
-	_vm->_gfx->invalidateRect(makeAbsoluteRect(rect));
-	_needsErase |= erase;
+	_vm->_gfx->invalidateRect(makeAbsoluteRect(rect), erase);
 }
 
 Common::Rect Window::getClientRect() const {
@@ -133,10 +131,8 @@ void Window::updateWindow() {
 		return;
 
 	// If we need to erase, erase first
-	if (_needsErase) {
+	if (_vm->_gfx->needsErase())
 		onEraseBackground();
-		_needsErase = false;
-	}
 
 	// Always draw this window first
 	onPaint();
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 69dd0d87f3..9b4e42af09 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -118,7 +118,6 @@ protected:
 
 private:
 	bool _enabled, _visible;
-	bool _needsErase;
 
 	typedef Common::List<Window *> WindowList;
 	WindowList _children, _topMostChildren;


Commit: 3c13de6ee15d4635eada2557d3813ba4d03c62a1
    https://github.com/scummvm/scummvm/commit/3c13de6ee15d4635eada2557d3813ba4d03c62a1
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Fix some visiblility issues

Windows should be invisible by default. Add some missing ShowWindow calls.

Changed paths:
    engines/buried/buried.cpp
    engines/buried/title_sequence.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b3e20d2a35..94d45a72ff 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -98,6 +98,7 @@ Common::Error BuriedEngine::run() {
 	_gfx = new GraphicsManager(this);
 	_sound = new SoundManager(this);
 	_mainWindow = new FrameWindow(this);
+	_mainWindow->showWindow(Window::kWindowShow);
 
 	if (isDemo()) {
 		((FrameWindow *)_mainWindow)->showTitleSequence();
diff --git a/engines/buried/title_sequence.cpp b/engines/buried/title_sequence.cpp
index 9b329bc6ef..77d2fe43c4 100644
--- a/engines/buried/title_sequence.cpp
+++ b/engines/buried/title_sequence.cpp
@@ -79,6 +79,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 
 		_currentMovie->setWindowPos(0, 195, 115, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
 		_currentMovie->enableWindow(false);
+		_currentMovie->showWindow(kWindowShow);
 		_currentMovie->playVideo();
 		_currentAnimation = 1;
 		return true;
@@ -97,6 +98,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 
 		_currentMovie->setWindowPos(0, 200, 60, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
 		_currentMovie->enableWindow(false);
+		_currentMovie->showWindow(kWindowShow);
 		_currentMovie->playVideo();
 		_currentAnimation = 2;
 		return true;
@@ -114,6 +116,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 
 		_currentMovie->setWindowPos(0, 60, 138, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
 		_currentMovie->enableWindow(false);
+		_currentMovie->showWindow(kWindowShow);
 		invalidateWindow();
 		_currentMovie->playVideo();
 		_currentAnimation = 3;
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 9b4e42af09..5011e4331f 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -37,7 +37,7 @@ struct Message;
 
 class Window {
 public:
-	Window(BuriedEngine *vm, Window *parent, bool visible = true);
+	Window(BuriedEngine *vm, Window *parent, bool visible = false);
 	virtual ~Window();
 
 	// The message types used by Buried in Time's windows


Commit: 55c470ad10009e09127c3e379410003e5278d1c2
    https://github.com/scummvm/scummvm/commit/55c470ad10009e09127c3e379410003e5278d1c2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Begin adding the UI code

The first part of the intro now plays

Changed paths:
  A engines/buried/gameui.cpp
  A engines/buried/gameui.h
    engines/buried/frame_window.cpp
    engines/buried/main_menu.cpp
    engines/buried/module.mk


diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index ff3156384c..0f2f5fe976 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -31,6 +31,7 @@
 #include "buried/buried.h"
 #include "buried/credits.h"
 #include "buried/frame_window.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/main_menu.h"
 #include "buried/message.h"
@@ -238,9 +239,15 @@ bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
 	_vm->removeMouseMessages(this);
 
 	delete _mainChildWindow;
-	_mainChildWindow = 0;
 
-	// TODO: Create and show UI, then begin the game
+	// Create Game UI window to kick things off
+	_mainChildWindow = new GameUIWindow(_vm, this);
+	_mainChildWindow->showWindow(kWindowShow);
+
+	if (introMovie)
+		((GameUIWindow *)_mainChildWindow)->startNewGameIntro(walkthrough);
+	else
+		((GameUIWindow *)_mainChildWindow)->startNewGame(walkthrough);
 
 	_vm->removeMouseMessages(this);
 	_vm->removeMouseMessages(_mainChildWindow);
@@ -254,9 +261,11 @@ bool FrameWindow::startNewGame(const Common::String &fileName) {
 	_vm->removeMouseMessages(this);
 
 	delete _mainChildWindow;
-	_mainChildWindow = 0;
 
-	// TODO: Create and show UI, then begin the game
+	// Create Game UI window to kick things off
+	_mainChildWindow = new GameUIWindow(_vm, this);
+	_mainChildWindow->showWindow(kWindowShow);
+	((GameUIWindow *)_mainChildWindow)->startNewGame(fileName);
 
 	_vm->removeMouseMessages(this);
 	_vm->removeMouseMessages(_mainChildWindow);
diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
new file mode 100644
index 0000000000..f2f8c3d1a6
--- /dev/null
+++ b/engines/buried/gameui.cpp
@@ -0,0 +1,316 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/graphics.h"
+#include "buried/livetext.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+#include "buried/video_window.h"
+
+#include "common/keyboard.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_currentDateDisplay = -1;
+	_warningLightDisplayed = false;
+	_rect = Common::Rect(0, 0, 640, 480);
+	_doNotDraw = true;
+
+	_liveTextWindow = new LiveTextWindow(_vm, this);
+
+	// TODO: Other windows
+}
+
+GameUIWindow::~GameUIWindow() {
+	delete _liveTextWindow;
+
+	// TODO: Other windows
+}
+
+bool GameUIWindow::startNewGame(bool walkthrough) {
+	_doNotDraw = false;
+	invalidateWindow(false);
+
+	_liveTextWindow->showWindow(kWindowShow);
+
+	// TODO: Other windows
+
+	return true;
+}
+
+bool GameUIWindow::startNewGameIntro(bool walkthrough) {
+	_doNotDraw = true;
+	_vm->_sound->setAmbientSound();
+
+	VideoWindow *video = new VideoWindow(_vm, this);
+
+	if (!video->openVideo(_vm->getFilePath(19972))) // FIXME: Why is this not a constant?
+		error("Failed to load intro video");
+
+	video->setWindowPos(0, 104, 145, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+	video->enableWindow(false);
+	video->showWindow(kWindowShow);
+	_vm->_sound->stop();
+	video->playVideo();
+
+	while (!_vm->shouldQuit() && video->getMode() != VideoWindow::kModeStopped)
+		_vm->yield();
+
+	delete video;
+
+	if (_vm->shouldQuit())
+		return false;
+
+	_vm->_sound->restart();
+	_doNotDraw = false;
+	invalidateWindow(false);
+
+	_liveTextWindow->showWindow(kWindowShow);
+
+	// TODO: Other windows
+	return true;
+}
+
+bool GameUIWindow::startNewGame(const Common::String &fileName) {
+	_doNotDraw = false;
+	invalidateWindow(false);
+
+	_liveTextWindow->showWindow(kWindowShow);
+
+	// TODO: Other windows
+
+	return true;
+}
+
+bool GameUIWindow::loadGame() {
+	_doNotDraw = false;
+
+	// TODO;
+
+	return false;
+}
+
+bool GameUIWindow::loadGame(const Common::String &fileName) {
+	// TODO
+
+	return true;
+}
+
+bool GameUIWindow::saveGame() {
+	// TODO
+
+	return false;
+}
+
+bool GameUIWindow::changeCurrentDate(int timeZoneID) {
+	switch (timeZoneID) {
+	case 1:
+		_currentDateDisplay = 1;
+		break;
+	case 2:
+		_currentDateDisplay = 3;
+		break;
+	case 3:
+	case 4:
+	case 7:
+		_currentDateDisplay = 4;
+		break;
+	case 5:
+		_currentDateDisplay = 5;
+		break;
+	case 6:
+		_currentDateDisplay = 0;
+		break;
+	default:
+		_currentDateDisplay = -1;
+		break;
+	}
+
+	invalidateRect(Common::Rect(50, 330, 200, 360), false);
+	return true;
+}
+
+bool GameUIWindow::flashWarningLight() {
+	Common::Rect redrawRect(185, 318, 275, 359);
+
+	if (_warningLightDisplayed) {
+		_warningLightDisplayed = false;
+		invalidateRect(redrawRect, false);
+		_vm->_gfx->updateScreen(false);
+	}
+
+	uint32 startTime = g_system->getMillis();
+	while (!_vm->shouldQuit() && (startTime + 200) > g_system->getMillis()) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return false;
+
+	_warningLightDisplayed = true;
+	invalidateRect(redrawRect, false);
+	_vm->_gfx->updateScreen(false);
+
+	_vm->_sound->playInterfaceSound("BITDATA/COMMON/MSGBEEP.BTA");
+
+	startTime = g_system->getMillis();
+	while (!_vm->shouldQuit() && (startTime + 250) > g_system->getMillis()) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return false;
+
+	_warningLightDisplayed = false;
+	invalidateRect(redrawRect, false);
+	_vm->_gfx->updateScreen(false);
+
+	startTime = g_system->getMillis();
+	while (!_vm->shouldQuit() && (startTime + 250) > g_system->getMillis()) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return false;
+
+	_warningLightDisplayed = false;
+	invalidateRect(redrawRect, false);
+	_vm->_gfx->updateScreen(false);
+
+	_vm->_sound->playInterfaceSound("BITDATA/COMMON/MSGBEEP.BTA");
+	return true;
+}
+
+bool GameUIWindow::setWarningState(bool newState) {
+	if (newState != _warningLightDisplayed) {
+		Common::Rect redrawRect(185, 318, 275, 359);
+		_warningLightDisplayed = newState;
+		_vm->_sound->playInterfaceSound("BITDATA/COMMON/MSGBEEP.BTA");
+		invalidateRect(redrawRect, false);
+	}
+
+	return true;
+}
+
+void GameUIWindow::onPaint() {
+	Common::Rect topUI(0, 0, 639, 127);
+	Common::Rect leftUI(0, 128, 64, 316);
+	Common::Rect bottomUI(0, 317, 639, 479);
+	Common::Rect rightUI(495, 128, 639, 316);
+
+	if (topUI.intersects(_vm->_gfx->getDirtyRect()) && !_doNotDraw) {
+		Graphics::Surface *topBitmap = _vm->_gfx->getBitmap(IDB_UI_TOP);
+		_vm->_gfx->blit(topBitmap, 0, 0);
+		topBitmap->free();
+		delete topBitmap;
+	}
+
+	if (leftUI.intersects(_vm->_gfx->getDirtyRect()) && !_doNotDraw) {
+		Graphics::Surface *leftBitmap = _vm->_gfx->getBitmap(IDB_UI_LEFT);
+		_vm->_gfx->blit(leftBitmap, 0, 128);
+		leftBitmap->free();
+		delete leftBitmap;
+	}
+
+	if (rightUI.intersects(_vm->_gfx->getDirtyRect()) && !_doNotDraw) {
+		Graphics::Surface *rightBitmap = _vm->_gfx->getBitmap(IDB_UI_RIGHT);
+		_vm->_gfx->blit(rightBitmap, 496, 128);
+		rightBitmap->free();
+		delete rightBitmap;
+	}
+
+	if (bottomUI.intersects(_vm->_gfx->getDirtyRect()) && !_doNotDraw) {
+		Graphics::Surface *bottomBitmap = _vm->_gfx->getBitmap(IDB_UI_BOTTOM);
+		_vm->_gfx->blit(bottomBitmap, 0, 317);
+		bottomBitmap->free();
+		delete bottomBitmap;
+
+		if (_currentDateDisplay >= 0) {
+			Graphics::Surface *dateBitmap = _vm->_gfx->getBitmap(IDB_UI_DATE_BASE + _currentDateDisplay);
+			_vm->_gfx->blit(dateBitmap, 62, 332);
+			dateBitmap->free();
+			delete dateBitmap;
+		}
+
+		if (_warningLightDisplayed) {
+			Graphics::Surface *warningLight = _vm->_gfx->getBitmap(IDB_UI_WARNING_LIGHT);
+			_vm->_gfx->blit(warningLight, 189, 321);
+			warningLight->free();
+			delete warningLight;
+		}
+	}
+}
+
+void GameUIWindow::onEnable(bool enable) {
+	// Pass the enable message to all child windows
+	_liveTextWindow->enableWindow(enable);
+	// TODO: Other windows
+
+	// If we're re-enabling, clear out the message queue of any mouse messages
+	if (enable)
+		_vm->removeMouseMessages(this);
+}
+
+void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
+	switch (key.keycode) {
+	case Common::KEYCODE_KP4:
+	case Common::KEYCODE_LEFT:
+	case Common::KEYCODE_KP6:
+	case Common::KEYCODE_RIGHT:
+	case Common::KEYCODE_KP2:
+	case Common::KEYCODE_DOWN:
+	case Common::KEYCODE_KP8:
+	case Common::KEYCODE_UP:
+	case Common::KEYCODE_KP5:
+		// TODO: Send to the nav arrow window
+		break;
+	case Common::KEYCODE_s:
+		if (key.flags & Common::KBD_CTRL) {
+			// TODO: Save
+			return;
+		}
+		// Fall through
+	case Common::KEYCODE_o:
+	case Common::KEYCODE_l:
+		if (key.flags & Common::KBD_CTRL) {
+			// TODO: Save
+			return;
+		}
+		// Fall through
+	default:
+		// TODO: Send to the scene view window
+		break;
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/gameui.h b/engines/buried/gameui.h
new file mode 100644
index 0000000000..3aa6580c5b
--- /dev/null
+++ b/engines/buried/gameui.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_GAMEUI_H
+#define BURIED_GAMEUI_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class LiveTextWindow;
+
+class GameUIWindow : public Window {
+public:
+	GameUIWindow(BuriedEngine *vm, Window *parent);
+	~GameUIWindow();
+
+	bool startNewGame(bool walkthrough = false);
+	bool startNewGameIntro(bool walkthrough = false);
+	// startNewGame(location struct)
+	bool startNewGame(const Common::String &fileName);
+	// startNewGame(continue data, location struct);
+	bool loadGame();
+	bool loadGame(const Common::String &fileName);
+	bool saveGame();
+	bool changeCurrentDate(int timeZoneID);
+	bool flashWarningLight();
+	bool setWarningState(bool newState);
+
+	void onPaint();
+	void onEnable(bool enable);
+	void onKeyUp(const Common::KeyState &key, uint flags);
+
+	// TODO: NavArrowWindow
+	LiveTextWindow *_liveTextWindow;
+	// TODO: SceneViewWindow
+	// TODO: InventoryWindow
+	// TODO: BioChipRightWindow
+
+private:
+	int _currentDateDisplay;
+	bool _warningLightDisplayed;
+	bool _doNotDraw;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/main_menu.cpp b/engines/buried/main_menu.cpp
index 4fd8cf0a73..617a2d3c43 100644
--- a/engines/buried/main_menu.cpp
+++ b/engines/buried/main_menu.cpp
@@ -196,8 +196,9 @@ void MainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			((FrameWindow *)_parent)->showOverview();
 			return;
 		case BUTTON_NEW_GAME:
-			// TODO
-			break;
+			// TODO: Easter egg with control down
+			((FrameWindow *)_parent)->startNewGame(_walkthrough, _showIntro);
+			return;
 		case BUTTON_RESTORE_GAME:
 			// TODO
 			break;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index de8f8da77b..4f07e8c2cb 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS = \
 	database.o \
 	detection.o \
 	frame_window.o \
+	gameui.o \
 	graphics.o \
 	livetext.o \
 	main_menu.o \


Commit: a07fed34934bde96d6bfe732032c9968c750ec01
    https://github.com/scummvm/scummvm/commit/a07fed34934bde96d6bfe732032c9968c750ec01
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Implement set cursor messages

Changed paths:
    engines/buried/buried.cpp
    engines/buried/message.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 94d45a72ff..b03aef67f4 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -321,6 +321,7 @@ void BuriedEngine::pollForEvents() {
 			Common::Point relativePos;
 			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
 			window->postMessage(new MouseMoveMessage(relativePos, 0));
+			window->postMessage(new SetCursorMessage(kMessageTypeMouseMove));
 			break;
 		}
 		case Common::EVENT_KEYUP:
diff --git a/engines/buried/message.h b/engines/buried/message.h
index 1309d2f9d3..a421df4cca 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -97,17 +97,6 @@ private:
 	uint _flags;
 };
 
-template <MessageType type>
-class WindowMessage : public MessageTypeIntern<type> {
-public:
-	WindowMessage(Window *window) : _window(window) {}
-
-	Window *getWindow() const { return _window; }
-
-private:
-	Window *_window;
-};
-
 // Types for everything that falls under one of the above categories
 typedef KeyMessage<kMessageTypeKeyUp>                  KeyUpMessage;
 typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
@@ -120,15 +109,15 @@ typedef MouseMessage<kMessageTypeRButtonUp>            RButtonUpMessage;
 typedef MouseMessage<kMessageTypeRButtonDown>          RButtonDownMessage;
 
 // ...and the rest
-class SetCursorMessage : public WindowMessage<kMessageTypeSetCursor> {
+class SetCursorMessage : public MessageTypeIntern<kMessageTypeSetCursor> {
 public:
-	SetCursorMessage(Window *window, uint cursor)
-			: WindowMessage<kMessageTypeSetCursor>(window), _cursor(cursor) {}
+	// Hit-test is purposely skipped
+	SetCursorMessage(uint message) : _message(message) {}
 
-	uint getCursor() const { return _cursor; }
+	uint getMessage() const { return _message; }
 
 private:
-	uint _cursor;
+	uint _message;
 };
 
 class TimerMessage : public MessageTypeIntern<kMessageTypeTimer> {
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 75100a9022..d52e2fda53 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -104,7 +104,7 @@ void Window::sendMessage(Message *message) {
 		onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
 		break;
 	case kMessageTypeSetCursor:
-		onSetCursor(((SetCursorMessage *)message)->getWindow(), ((SetCursorMessage *)message)->getCursor());
+		handleSetCursorMessage(((SetCursorMessage *)message)->getMessage());
 		break;
 	case kMessageTypeEnable:
 		onEnable(((EnableMessage *)message)->getEnable());
@@ -278,4 +278,13 @@ Window *Window::findWindowAtPoint(const Common::Point &point, Common::Point &rel
 	return this;
 }
 
+bool Window::handleSetCursorMessage(uint message) {
+	// SetCursor messages need special handling
+	// The parent has a chance to set a cursor first
+	if (_parent && _parent->handleSetCursorMessage(message))
+		return true;
+
+	return onSetCursor(message);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 5011e4331f..063a530006 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -55,7 +55,7 @@ public:
 	virtual void onMButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onRButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onRButtonDown(const Common::Point &point, uint flags) {}
-	virtual bool onSetCursor(Window *window, uint cursor) { return false; }
+	virtual bool onSetCursor(uint message) { return false; }
 	virtual void onEnable(bool enable) {}
 
 	void invalidateRect(const Common::Rect &rect, bool erase = true);
@@ -121,6 +121,8 @@ private:
 
 	typedef Common::List<Window *> WindowList;
 	WindowList _children, _topMostChildren;
+
+	bool handleSetCursorMessage(uint message);
 };
 
 // A subset of the special insert after Window handles


Commit: d830e849c1eb3e485a26e2ca2419327ebb9b2a04
    https://github.com/scummvm/scummvm/commit/d830e849c1eb3e485a26e2ca2419327ebb9b2a04
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Some minor video fixes

Changed paths:
    engines/buried/video_window.cpp


diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index d51514eb0b..0a417518ed 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -117,7 +117,8 @@ bool VideoWindow::openVideo(const Common::String &fileName) {
 	}
 
 	_mode = kModeOpen;
-	_rect = Common::Rect(_video->getWidth(), _video->getHeight());
+	_rect.right = _rect.left + _video->getWidth();
+	_rect.bottom = _rect.top + _video->getHeight();
 	return true;
 }
 
@@ -170,7 +171,7 @@ void VideoWindow::updateVideo() {
 			}
 
 			// Invalidate the window so it gets updated
-			invalidateWindow();
+			invalidateWindow(false);
 		}
 
 		if (_video->isPlaying() && _video->endOfVideo()) {
@@ -181,8 +182,10 @@ void VideoWindow::updateVideo() {
 }
 
 void VideoWindow::onPaint() {
-	if (_lastFrame)
-		_vm->_gfx->blit(_lastFrame, _rect.left, _rect.top);
+	if (_lastFrame) {
+		Common::Rect absoluteRect = getAbsoluteRect();
+		_vm->_gfx->blit(_lastFrame, absoluteRect.left, absoluteRect.top);
+	}
 }
 
 } // End of namespace Buried


Commit: 4da91fb632aa19f5735f8f1a310014f834f3b092
    https://github.com/scummvm/scummvm/commit/4da91fb632aa19f5735f8f1a310014f834f3b092
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the right BioChip display window

Changed paths:
  A engines/buried/biochip_right.cpp
  A engines/buried/biochip_right.h
    engines/buried/gameui.cpp
    engines/buried/gameui.h
    engines/buried/module.mk


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
new file mode 100644
index 0000000000..544d847f84
--- /dev/null
+++ b/engines/buried/biochip_right.cpp
@@ -0,0 +1,361 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/biochip_right.h"
+#include "buried/gameui.h"
+#include "buried/graphics.h"
+#include "buried/invdata.h"
+#include "buried/livetext.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+#include "buried/video_window.h"
+
+#include "graphics/surface.h"
+
+namespace Buried {
+
+BioChipRightWindow::BioChipRightWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_curBioChip = kItemBioChipInterface;
+	_status = 0;
+	_bioChipViewWindow = 0;
+	_forceHelp = false;
+	_forceComment = false;
+	_jumpInProgress = false;
+
+	_rect = Common::Rect(520, 102, 638, 281);
+}
+
+BioChipRightWindow::~BioChipRightWindow() {
+	delete _bioChipViewWindow;
+}
+
+bool BioChipRightWindow::changeCurrentBioChip(int bioChipID) {
+	if (_curBioChip == bioChipID)
+		return true;
+
+	// Signal live text to reset if this isn't the translate BioChip
+	if (bioChipID != kItemBioChipTranslate)
+		((GameUIWindow *)_parent)->_liveTextWindow->translateBiochipClosing();
+
+	// TODO
+	//if (bioChipID != kItemBioChipEvidence)
+	//	;
+
+	if (_bioChipViewWindow)
+		destroyBioChipViewWindow();
+
+	// TODO: Set the translate enabled flag to false
+
+	invalidateWindow(false);
+	return true;
+}
+
+bool BioChipRightWindow::showBioChipMainView() {
+	if (_bioChipViewWindow)
+		return false;
+
+	// TODO: Notify the view of the change
+	_vm->_sound->timerCallback();
+
+	// TODO: Destroy info window
+	// TODO: Destroy burned letter window
+	_vm->_sound->timerCallback();
+
+	// TODO: BioChip main view window
+	_vm->_sound->timerCallback();
+
+	return true;
+}
+
+bool BioChipRightWindow::destroyBioChipViewWindow() {
+	if (_bioChipViewWindow)
+		return false;
+
+	_vm->_sound->timerCallback();
+	delete _bioChipViewWindow;
+	_bioChipViewWindow = 0;
+	_vm->_sound->timerCallback();
+
+	// TODO: Signal the change to the scene view window
+
+	if (_status == 1) {
+		_status = 0;
+		invalidateWindow(false);
+	}
+
+	return true;
+}
+
+void BioChipRightWindow::sceneChanged() {
+	if (_curBioChip == kItemBioChipAI)
+		invalidateWindow(false);
+}
+
+void BioChipRightWindow::disableEvidenceCapture() {
+	if (_curBioChip == kItemBioChipEvidence) {
+		_status = 0;
+		// TODO: Disable locate flag
+		invalidateWindow(false);
+	}
+}
+
+void BioChipRightWindow::jumpInitiated(bool redraw) {
+	_jumpInProgress = true;
+
+	if (redraw)
+		invalidateWindow(false);
+}
+
+void BioChipRightWindow::jumpEnded(bool redraw) {
+	_jumpInProgress = false;
+
+	if (redraw)
+		invalidateWindow(false);
+}
+
+void BioChipRightWindow::onPaint() {
+	int bitmapResID = -1;
+
+	switch (_curBioChip) {
+	case kItemBioChipAI: {
+		// TODO: Check scene view for help/information comment
+		bool helpComment = _forceHelp || false;
+		bool information = _forceComment || false;
+
+		if (helpComment) {
+			if (information)
+				bitmapResID = 0;
+			else
+				bitmapResID = 1;
+		} else {
+			if (information)
+				bitmapResID = 2;
+			else
+				bitmapResID = 3;
+		}
+		break;
+	}
+	case kItemBioChipBlank:
+		bitmapResID = 4;
+		break;
+	case kItemBioChipCloak:
+		bitmapResID = (_status == 0) ? 5 : 6;
+		break;
+	case kItemBioChipEvidence:
+		switch (_status) {
+		case 0:
+			bitmapResID = 7;
+			break;
+		case 1:
+			bitmapResID = 8;
+			break;
+		case 2:
+			bitmapResID = 9;
+			break;
+		}
+		break;
+	case kItemBioChipFiles:
+		bitmapResID = (_status == 0) ? 10 : 11;
+		break;
+	case kItemBioChipInterface:
+		bitmapResID = (_status == 0) ? 12 : 13;
+		break;
+	case kItemBioChipJump:
+		// TODO
+		bitmapResID = 14;
+		break;
+	case kItemBioChipTranslate:
+		bitmapResID = (_status == 0) ? 18 : 19;
+		break;
+	}
+
+	if (bitmapResID >= 0) {
+		Graphics::Surface *bitmap = _vm->_gfx->getBitmap(IDB_BCR_BITMAP_BASE + bitmapResID);
+		Common::Rect absoluteRect = getAbsoluteRect();
+		_vm->_gfx->blit(bitmap, absoluteRect.left, absoluteRect.top);
+		bitmap->free();
+		delete bitmap;
+	}
+}
+
+void BioChipRightWindow::onEnable(bool enable) {
+	if (enable)
+		_vm->removeMouseMessages(this);
+}
+
+void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	Common::Rect upperButton(12, 120, 102, 148);
+	Common::Rect lowerButton(12, 149, 102, 177);
+
+	switch (_curBioChip) {
+	case kItemBioChipAI:
+		// TODO
+		break;
+	case kItemBioChipCloak:
+		if (upperButton.contains(point)) {
+			if (_status == 0) {
+				_status = 1;
+
+				// TODO: Disable navigation
+
+				VideoWindow *video = new VideoWindow(_vm, this);
+				video->setWindowPos(0, 2, 22, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
+				video->openVideo(_vm->getFilePath(IDS_BC_CLOAKING_MOVIE_FILENAME));
+				video->enableWindow(false);
+				video->showWindow(kWindowShow);
+
+				_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_BC_CLOAKING_SOUND_FILENAME));
+				video->playToFrame(23);
+
+				while (!_vm->shouldQuit() && video->getMode() != VideoWindow::kModeStopped) {
+					_vm->yield();
+					_vm->_sound->timerCallback();
+				}
+
+				_vm->_sound->timerCallback();
+				delete video;
+
+				invalidateWindow(false);
+
+				// TODO: Set cloaking flag
+				// TODO: Disable some controls
+				// TODO: Change live text
+			} else {
+				_status = 0;
+
+				VideoWindow *video = new VideoWindow(_vm, this);
+				video->setWindowPos(0, 2, 22, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
+				video->openVideo(_vm->getFilePath(IDS_BC_CLOAKING_MOVIE_FILENAME));
+				video->seekToFrame(24);
+				video->enableWindow(false);
+				video->showWindow(kWindowShow);
+
+				_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_BC_CLOAKING_SOUND_FILENAME));
+				video->playToFrame(47);
+
+				while (!_vm->shouldQuit() && video->getMode() != VideoWindow::kModeStopped) {
+					_vm->yield();
+					_vm->_sound->timerCallback();
+				}
+
+				_vm->_sound->timerCallback();
+				delete video;
+
+				invalidateWindow(false);
+
+				// TODO: Set cloaking flag
+				// TODO: Enable navigation
+				// TODO: Enable inventory controls
+				// TODO: Change live text
+			}
+		}
+		break;
+	case kItemBioChipEvidence:
+		if (upperButton.contains(point)) {
+			if (_status == 1) {
+				_status = 0;
+				// TODO
+				invalidateWindow(false);
+			} else {
+				destroyBioChipViewWindow();
+				_status = 1;
+				// TODO
+				invalidateWindow(false);
+			}
+		} else if (lowerButton.contains(point)) {
+			if (_status == 2) {
+				destroyBioChipViewWindow();
+				_status = 0;
+				invalidateWindow(false);
+			} else {
+				showBioChipMainView();
+				_status = 2;
+				// TODO
+				invalidateWindow(false);
+			}
+		}
+		break;
+	case kItemBioChipFiles:
+		if (upperButton.contains(point)) {
+			if (_status == 0) {
+				_status = 1;
+				showBioChipMainView();
+				invalidateWindow(false);
+			} else {
+				_status = 0;
+				destroyBioChipViewWindow();
+				invalidateWindow(false);
+			}
+		}
+		break;
+	case kItemBioChipInterface:
+		if (upperButton.contains(point)) {
+			if (_status == 0) {
+				_status = 1;
+				showBioChipMainView();
+				invalidateWindow(false);
+			} else {
+				_status = 0;
+				destroyBioChipViewWindow();
+				invalidateWindow(false);
+			}
+		}
+		break;
+	case kItemBioChipJump:
+		if (upperButton.contains(point)) {
+			if (_status == 0) {
+				_status = 1;
+				showBioChipMainView();
+				invalidateWindow(false);
+			} else {
+				_status = 0;
+				destroyBioChipViewWindow();
+				invalidateWindow(false);
+			}
+		} else if (lowerButton.contains(point)) {
+			// TODO
+		}
+		break;
+	case kItemBioChipTranslate:
+		if (upperButton.contains(point)) {
+			if (_status == 0) {
+				_status = 1;
+				invalidateWindow(false);
+
+				// TODO: Reset global flag
+				// TODO: Redraw the scene window
+			} else {
+				_status = 0;
+
+				// TODO: Reset global flag
+				// TODO: Redraw the scene window
+			}
+		}
+		break;
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/biochip_right.h b/engines/buried/biochip_right.h
new file mode 100644
index 0000000000..0521588024
--- /dev/null
+++ b/engines/buried/biochip_right.h
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_BIOCHIP_RIGHT_H
+#define BURIED_BIOCHIP_RIGHT_H
+
+#include "buried/window.h"
+
+namespace Buried {
+
+class BioChipRightWindow : public Window {
+public:
+	BioChipRightWindow(BuriedEngine *vm, Window *parent);
+	~BioChipRightWindow();
+
+	bool changeCurrentBioChip(int bioChipID);
+	bool showBioChipMainView();
+	bool destroyBioChipViewWindow();
+	void sceneChanged();
+	void disableEvidenceCapture();
+	void jumpInitiated(bool redraw);
+	void jumpEnded(bool redraw);
+
+	void onPaint();
+	void onEnable(bool enable);
+	void onLButtonUp(const Common::Point &point, uint flags);
+
+	// clone2727 says: These are labeled as HACKS, so I assume they are.
+	bool _forceHelp;
+	bool _forceComment;
+
+private:
+	int _curBioChip;
+	int _status;
+	Window *_bioChipViewWindow;
+	bool _jumpInProgress;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index f2f8c3d1a6..2854c91988 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -23,10 +23,13 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
+#include "buried/invdata.h"
 #include "buried/livetext.h"
+#include "buried/message.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
@@ -44,12 +47,14 @@ GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent
 	_doNotDraw = true;
 
 	_liveTextWindow = new LiveTextWindow(_vm, this);
+	_bioChipRightWindow = new BioChipRightWindow(_vm, this);
 
 	// TODO: Other windows
 }
 
 GameUIWindow::~GameUIWindow() {
 	delete _liveTextWindow;
+	delete _bioChipRightWindow;
 
 	// TODO: Other windows
 }
@@ -59,6 +64,7 @@ bool GameUIWindow::startNewGame(bool walkthrough) {
 	invalidateWindow(false);
 
 	_liveTextWindow->showWindow(kWindowShow);
+	_bioChipRightWindow->showWindow(kWindowShow);
 
 	// TODO: Other windows
 
@@ -93,6 +99,7 @@ bool GameUIWindow::startNewGameIntro(bool walkthrough) {
 	invalidateWindow(false);
 
 	_liveTextWindow->showWindow(kWindowShow);
+	_bioChipRightWindow->showWindow(kWindowShow);
 
 	// TODO: Other windows
 	return true;
@@ -103,6 +110,7 @@ bool GameUIWindow::startNewGame(const Common::String &fileName) {
 	invalidateWindow(false);
 
 	_liveTextWindow->showWindow(kWindowShow);
+	_bioChipRightWindow->showWindow(kWindowShow);
 
 	// TODO: Other windows
 
@@ -274,6 +282,7 @@ void GameUIWindow::onPaint() {
 void GameUIWindow::onEnable(bool enable) {
 	// Pass the enable message to all child windows
 	_liveTextWindow->enableWindow(enable);
+	_bioChipRightWindow->showWindow(kWindowShow);
 	// TODO: Other windows
 
 	// If we're re-enabling, clear out the message queue of any mouse messages
@@ -296,14 +305,22 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 		break;
 	case Common::KEYCODE_s:
 		if (key.flags & Common::KBD_CTRL) {
-			// TODO: Save
+			// TODO: Check for cloaking enabled
+			_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
+			_bioChipRightWindow->invalidateWindow(false);
+			_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 130), 0));
+			saveGame();
 			return;
 		}
 		// Fall through
 	case Common::KEYCODE_o:
 	case Common::KEYCODE_l:
 		if (key.flags & Common::KBD_CTRL) {
-			// TODO: Save
+			// TODO: Check for cloaking enabled
+			_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
+			_bioChipRightWindow->invalidateWindow(false);
+			_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 130), 0));
+			loadGame();
 			return;
 		}
 		// Fall through
diff --git a/engines/buried/gameui.h b/engines/buried/gameui.h
index 3aa6580c5b..7aa8ee4575 100644
--- a/engines/buried/gameui.h
+++ b/engines/buried/gameui.h
@@ -34,6 +34,7 @@ struct Surface;
 
 namespace Buried {
 
+class BioChipRightWindow;
 class LiveTextWindow;
 
 class GameUIWindow : public Window {
@@ -61,7 +62,7 @@ public:
 	LiveTextWindow *_liveTextWindow;
 	// TODO: SceneViewWindow
 	// TODO: InventoryWindow
-	// TODO: BioChipRightWindow
+	BioChipRightWindow *_bioChipRightWindow;
 
 private:
 	int _currentDateDisplay;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 4f07e8c2cb..21fe0fda2d 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/buried
 
 MODULE_OBJS = \
 	avi_frames.o \
+	biochip_right.o \
 	buried.o \
 	credits.o \
 	database.o \


Commit: f9cd1b65fff96b84b34f18bdc94efbc375d8275b
    https://github.com/scummvm/scummvm/commit/f9cd1b65fff96b84b34f18bdc94efbc375d8275b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add some transparency functions

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 485ea2631b..95ee20de63 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -4,6 +4,9 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -329,6 +332,121 @@ void GraphicsManager::fillRect(const Common::Rect &rect, uint32 color) {
 	_screen->fillRect(rect, color);
 }
 
+void GraphicsManager::opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte rTrans, byte gTrans, byte bTrans) {
+	if (_vm->isTrueColor()) {
+		uint32 transColor = getColor(rTrans, gTrans, bTrans);
+
+		for (int y = 0; y < h; y++) {
+			if (y + yDst < dst->h && y + yDst >= 0) {
+				for (int x = 0; x < w; x++) {
+					if (x + xDst < dst->w && x + xDst >= 0) {
+						uint32 srcColor;
+
+						if (src->format.bytesPerPixel == 2)
+							srcColor = *((const uint16 *)src->getBasePtr(x + xSrc, y + ySrc));
+						else
+							srcColor = *((const uint32 *)src->getBasePtr(x + xSrc, y + ySrc));
+
+						if (srcColor == transColor)
+							continue;
+
+						int srcCycles, dstCycles;
+						switch (opacityValue) {
+						case 50:
+							srcCycles = 1;
+							dstCycles = 3;
+							break;
+						case 85:
+							srcCycles = 17;
+							dstCycles = 3;
+							break;
+						default:
+							srcCycles = 1;
+							dstCycles = 0;
+							break;
+						}
+
+						byte rSrc, gSrc, bSrc;
+						g_system->getScreenFormat().colorToRGB(srcColor, rSrc, gSrc, bSrc);
+
+						uint32 dstColor;
+						if (dst->format.bytesPerPixel == 2)
+							dstColor = *((uint16 *)dst->getBasePtr(x + xDst, y + yDst));
+						else
+							dstColor = *((uint32 *)dst->getBasePtr(x + xDst, y + yDst));
+
+						byte rDst, gDst, bDst;
+						g_system->getScreenFormat().colorToRGB(dstColor, rDst, gDst, bDst);
+
+						byte r = (((int)rSrc * srcCycles) + ((int)rDst * dstCycles)) / (srcCycles + dstCycles);
+						byte g = (((int)gSrc * srcCycles) + ((int)gDst * dstCycles)) / (srcCycles + dstCycles);
+						byte b = (((int)bSrc * srcCycles) + ((int)bDst * dstCycles)) / (srcCycles + dstCycles);
+						uint32 color = g_system->getScreenFormat().RGBToColor(r, g, b);
+
+						if (dst->format.bytesPerPixel == 2)
+							*((uint16 *)dst->getBasePtr(x + xDst, y + yDst)) = color;
+						else
+							*((uint32 *)dst->getBasePtr(x + xDst, y + yDst)) = color;
+					}
+				}
+			}
+		}
+	} else {
+		// Find the palette index of the color
+		int paletteIndex = -1;
+		for (int i = 0; i < 256; i++) {
+			if (_palette[i * 3] == rTrans && _palette[i * 3 + 1] == gTrans && _palette[i * 3 + 2] == bTrans) {
+				paletteIndex = i;
+				break;
+			}
+		}
+
+		assert(paletteIndex >= 0);
+
+		for (int y = 0; y < h; y++) {
+			if (y + yDst < dst->h && y + yDst >= 0) {
+				for (int x = 0; x < w; x++) {
+					if (x + xDst < dst->w && x + xDst >= 0) {
+						byte color = *((const byte *)src->getBasePtr(x + xSrc, y + ySrc));
+
+						if (color == paletteIndex)
+							continue;
+
+						*((byte *)dst->getBasePtr(x + xDst, y + yDst)) = color;
+					}
+				}
+			}
+		}
+	}
+}
+
+bool GraphicsManager::checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans) {
+	if (_vm->isTrueColor()) {
+		uint32 transColor = getColor(rTrans, gTrans, bTrans);
+		uint32 color;
+
+		if (bitmap->format.bytesPerPixel == 2)
+			color = *((uint16 *)bitmap->getBasePtr(point.x + x, point.y + y));
+		else
+			color = *((uint32 *)bitmap->getBasePtr(point.x + x, point.y + y));
+
+		return transColor != color;
+	} else {
+		// Find the palette index of the color
+		int paletteIndex = -1;
+		for (int i = 0; i < 256; i++) {
+			if (_palette[i * 3] == rTrans && _palette[i * 3 + 1] == gTrans && _palette[i * 3 + 2] == bTrans) {
+				paletteIndex = i;
+				break;
+			}
+		}
+
+		assert(paletteIndex >= 0);
+
+		return *((const byte *)bitmap->getBasePtr(point.x + x, point.y + y)) != paletteIndex;
+	}
+}
+
 byte *GraphicsManager::createDefaultPalette() const {
 	Common::SeekableReadStream *stream = _vm->getBitmapStream(700);
 
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 93cc3c2752..a48d643c72 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -4,6 +4,9 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -88,6 +91,8 @@ public:
 	void blit(const Graphics::Surface *surface, int x, int y);
 	void blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect);
 	void fillRect(const Common::Rect &rect, uint32 color);
+	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
+	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 


Commit: 5a8260815c0c5b3c0c24f65a851c2e98f110d2c8
    https://github.com/scummvm/scummvm/commit/5a8260815c0c5b3c0c24f65a851c2e98f110d2c8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the navigation arrows window

Changed paths:
  A engines/buried/navarrow.cpp
  A engines/buried/navarrow.h
    engines/buried/biochip_right.cpp
    engines/buried/gameui.cpp
    engines/buried/gameui.h
    engines/buried/module.mk


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index 544d847f84..d2b88d5345 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -29,6 +29,7 @@
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/livetext.h"
+#include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
@@ -219,7 +220,8 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			if (_status == 0) {
 				_status = 1;
 
-				// TODO: Disable navigation
+				// Disable navigation
+				((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(0, 0, 0, 0, 0);
 
 				VideoWindow *video = new VideoWindow(_vm, this);
 				video->setWindowPos(0, 2, 22, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
@@ -242,6 +244,7 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 
 				// TODO: Set cloaking flag
 				// TODO: Disable some controls
+				((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(false);
 				// TODO: Change live text
 			} else {
 				_status = 0;
@@ -269,6 +272,7 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 				// TODO: Set cloaking flag
 				// TODO: Enable navigation
 				// TODO: Enable inventory controls
+				((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
 				// TODO: Change live text
 			}
 		}
diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index 2854c91988..6f3d58a303 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -30,6 +30,7 @@
 #include "buried/invdata.h"
 #include "buried/livetext.h"
 #include "buried/message.h"
+#include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
@@ -46,6 +47,7 @@ GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent
 	_rect = Common::Rect(0, 0, 640, 480);
 	_doNotDraw = true;
 
+	_navArrowWindow = new NavArrowWindow(_vm, this);
 	_liveTextWindow = new LiveTextWindow(_vm, this);
 	_bioChipRightWindow = new BioChipRightWindow(_vm, this);
 
@@ -53,6 +55,7 @@ GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent
 }
 
 GameUIWindow::~GameUIWindow() {
+	delete _navArrowWindow;
 	delete _liveTextWindow;
 	delete _bioChipRightWindow;
 
@@ -63,6 +66,7 @@ bool GameUIWindow::startNewGame(bool walkthrough) {
 	_doNotDraw = false;
 	invalidateWindow(false);
 
+	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
 
@@ -98,6 +102,7 @@ bool GameUIWindow::startNewGameIntro(bool walkthrough) {
 	_doNotDraw = false;
 	invalidateWindow(false);
 
+	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
 
@@ -109,6 +114,7 @@ bool GameUIWindow::startNewGame(const Common::String &fileName) {
 	_doNotDraw = false;
 	invalidateWindow(false);
 
+	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
 
@@ -281,8 +287,9 @@ void GameUIWindow::onPaint() {
 
 void GameUIWindow::onEnable(bool enable) {
 	// Pass the enable message to all child windows
+	_navArrowWindow->enableWindow(enable);
 	_liveTextWindow->enableWindow(enable);
-	_bioChipRightWindow->showWindow(kWindowShow);
+	_bioChipRightWindow->enableWindow(enable);
 	// TODO: Other windows
 
 	// If we're re-enabling, clear out the message queue of any mouse messages
@@ -301,7 +308,8 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 	case Common::KEYCODE_KP8:
 	case Common::KEYCODE_UP:
 	case Common::KEYCODE_KP5:
-		// TODO: Send to the nav arrow window
+		if (_navArrowWindow->isWindowEnabled())
+			_navArrowWindow->sendMessage(new KeyUpMessage(key, flags));
 		break;
 	case Common::KEYCODE_s:
 		if (key.flags & Common::KBD_CTRL) {
diff --git a/engines/buried/gameui.h b/engines/buried/gameui.h
index 7aa8ee4575..e3c26c9e72 100644
--- a/engines/buried/gameui.h
+++ b/engines/buried/gameui.h
@@ -36,6 +36,7 @@ namespace Buried {
 
 class BioChipRightWindow;
 class LiveTextWindow;
+class NavArrowWindow;
 
 class GameUIWindow : public Window {
 public:
@@ -58,7 +59,7 @@ public:
 	void onEnable(bool enable);
 	void onKeyUp(const Common::KeyState &key, uint flags);
 
-	// TODO: NavArrowWindow
+	NavArrowWindow *_navArrowWindow;
 	LiveTextWindow *_liveTextWindow;
 	// TODO: SceneViewWindow
 	// TODO: InventoryWindow
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 21fe0fda2d..59ebab304a 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS = \
 	graphics.o \
 	livetext.o \
 	main_menu.o \
+	navarrow.o \
 	overview.o \
 	sound.o \
 	title_sequence.o \
diff --git a/engines/buried/navarrow.cpp b/engines/buried/navarrow.cpp
new file mode 100644
index 0000000000..4cb57a8410
--- /dev/null
+++ b/engines/buried/navarrow.cpp
@@ -0,0 +1,236 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/navarrow.h"
+#include "buried/navdata.h"
+#include "buried/resources.h"
+
+#include "common/keyboard.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+NavArrowWindow::NavArrowWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_background = _vm->_gfx->getBitmap(IDB_ARROW_BACKGROUND);
+
+	_arrowBitmaps[0][0] = IDB_ARROW_UP_CLEAR;
+	_arrowBitmaps[0][1] = IDB_ARROW_UP_LIT;
+	_arrowBitmaps[0][2] = IDB_ARROW_UP_HIGHLIGHTED;
+	_arrowBitmaps[1][0] = IDB_ARROW_LEFT_CLEAR;
+	_arrowBitmaps[1][1] = IDB_ARROW_LEFT_LIT;
+	_arrowBitmaps[1][2] = IDB_ARROW_LEFT_HIGHLIGHTED;
+	_arrowBitmaps[2][0] = IDB_ARROW_RIGHT_CLEAR;
+	_arrowBitmaps[2][1] = IDB_ARROW_RIGHT_LIT;
+	_arrowBitmaps[2][2] = IDB_ARROW_RIGHT_HIGHLIGHTED;
+	_arrowBitmaps[3][0] = IDB_ARROW_DOWN_CLEAR;
+	_arrowBitmaps[3][1] = IDB_ARROW_DOWN_LIT;
+	_arrowBitmaps[3][2] = IDB_ARROW_DOWN_HIGHLIGHTED;
+	_arrowBitmaps[4][0] = IDB_ARROW_FORWARD_CLEAR;
+	_arrowBitmaps[4][1] = IDB_ARROW_FORWARD_LIT;
+	_arrowBitmaps[4][2] = IDB_ARROW_FORWARD_HIGHLIGHTED;
+
+	for (int i = 0; i < NUM_ARROWS; i++)
+		_arrowStatus[i] = BUTTON_DISABLED;
+
+	rebuildArrows();
+
+	_rect = Common::Rect(510, 292, 640, 418);
+}
+
+NavArrowWindow::~NavArrowWindow() {
+	_background->free();
+	delete _background;
+}
+
+bool NavArrowWindow::updateArrow(int button, int newStatus) {
+	_arrowStatus[button] = newStatus;
+
+	rebuildArrows();
+	invalidateWindow(false);
+	return true;
+}
+
+bool NavArrowWindow::updateAllArrows(int left, int up, int right, int down, int forward) {
+	// clone2727 says: This is wrong. Left and up are swapped.
+	// I can only imagine what bugs this causes.
+	_arrowStatus[0] = left;
+	_arrowStatus[1] = up;
+	_arrowStatus[2] = right;
+	_arrowStatus[3] = down;
+	_arrowStatus[4] = forward;
+
+	rebuildArrows();
+	invalidateWindow(false);
+	return true;
+}
+
+bool NavArrowWindow::updateAllArrows(const LocationStaticData &locationStaticData) {
+	_arrowStatus[0] = (locationStaticData.destUp.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
+	_arrowStatus[1] = (locationStaticData.destLeft.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
+	_arrowStatus[2] = (locationStaticData.destRight.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
+	_arrowStatus[3] = (locationStaticData.destDown.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
+	_arrowStatus[4] = (locationStaticData.destForward.destinationScene.timeZone >= 0) ? BUTTON_ENABLED : BUTTON_DISABLED;
+
+	rebuildArrows();
+	invalidateWindow(false);
+	return true;
+}
+
+bool NavArrowWindow::drawArrow(int xDst, int yDst, int arrow) {
+	Graphics::Surface *arrowBitmap = _vm->_gfx->getBitmap(_arrowBitmaps[arrow][_arrowStatus[arrow]]);
+
+	for (int ySrc = 0; ySrc < arrowBitmap->h; ySrc++)
+		memcpy(_background->getBasePtr(xDst, yDst + ySrc), arrowBitmap->getBasePtr(0, ySrc), arrowBitmap->w * arrowBitmap->format.bytesPerPixel);
+
+	arrowBitmap->free();
+	delete arrowBitmap;
+	return true;
+}
+
+bool NavArrowWindow::rebuildArrows() {
+	_background->free();
+	delete _background;
+	_background = _vm->_gfx->getBitmap(IDB_ARROW_BACKGROUND);
+
+	drawArrow(37, 2, 0);
+	drawArrow(2, 39, 1);
+	drawArrow(64, 38, 2);
+	drawArrow(38, 68, 3);
+
+	Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
+	_vm->_gfx->opaqueTransparentBlit(_background, 39, 49, centerArrow->w, centerArrow->h, centerArrow, 0, 0, (_arrowStatus[4] == BUTTON_DISABLED) ? 50 : 85, 255, 255, 255);
+	centerArrow->free();
+	delete centerArrow;
+	return true;
+}
+
+void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	Common::Rect leftButton(1, 43, 40, 78);
+	Common::Rect upButton(40, 1, 76, 45);
+	Common::Rect rightButton(63, 45, 130, 71);
+	Common::Rect downButton(42, 71, 78, 124);
+	Common::Rect forwardButton(39, 49, 101, 91);
+
+	// TODO: Destroy info window
+	// TODO: Destroy burned letter window
+
+	// clone2727: This logic was broken in the original. retVal wasn't initialized.
+	bool retVal = false;
+
+	// Did we click anywhere near the forward button?
+	if (forwardButton.contains(point)) {
+		// If we only clicked on the forward arrow, then take care of it here
+		if (!rightButton.contains(point) && !downButton.contains(point)) {
+			// TODO
+		} else {
+			if (rightButton.contains(point)) {
+				Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
+
+				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
+					// TODO
+				} else {
+					// TODO
+				}
+
+				centerArrow->free();
+				delete centerArrow;
+			}
+
+			if (downButton.contains(point)) {
+				Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
+
+				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
+					// TODO
+				} else {
+					// TODO
+				}
+
+				centerArrow->free();
+				delete centerArrow;
+			}
+		}
+	} else {
+		if (upButton.contains(point)) {
+			// TODO
+		}
+
+		if (leftButton.contains(point)) {
+			// TODO
+		}
+
+		if (rightButton.contains(point)) {
+			// TODO
+		}
+
+		if (downButton.contains(point)) {
+			// TODO
+		}
+	}
+
+	if (retVal) {
+		rebuildArrows();
+		invalidateWindow(false);
+	}
+}
+
+void NavArrowWindow::onKeyUp(const Common::KeyState &key, uint flags) {
+	switch (key.keycode) {
+	case Common::KEYCODE_KP4:
+	case Common::KEYCODE_LEFT:
+		// TODO
+		break;
+	case Common::KEYCODE_KP6:
+	case Common::KEYCODE_RIGHT:
+		// TODO
+		break;
+	case Common::KEYCODE_KP2:
+	case Common::KEYCODE_DOWN:
+		// TODO
+		break;
+	case Common::KEYCODE_KP8:
+	case Common::KEYCODE_UP:
+		// TODO
+		break;
+	case Common::KEYCODE_KP5:
+		// TODO
+		break;
+	default:
+		break;
+	}
+}
+
+void NavArrowWindow::onPaint() {
+	Common::Rect absoluteRect = getAbsoluteRect();
+	_vm->_gfx->blit(_background, absoluteRect.left, absoluteRect.top);
+}
+
+void NavArrowWindow::onEnable(bool enable) {
+	if (enable)
+		_vm->removeMouseMessages(this);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/navarrow.h b/engines/buried/navarrow.h
new file mode 100644
index 0000000000..709519056b
--- /dev/null
+++ b/engines/buried/navarrow.h
@@ -0,0 +1,82 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_NAVARROW_H
+#define BURIED_NAVARROW_H
+
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+struct LocationStaticData;
+
+class NavArrowWindow : public Window {
+public:
+	NavArrowWindow(BuriedEngine *vm, Window *parent);
+	~NavArrowWindow();
+
+	bool updateArrow(int button, int newStatus);
+	bool updateAllArrows(int up, int left, int right, int down, int forward);
+	bool updateAllArrows(const LocationStaticData &locationStaticData);
+
+	void onPaint();
+	void onEnable(bool enable);
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onKeyUp(const Common::KeyState &key, uint flags);
+
+private:
+	enum {
+		BUTTON_DISABLED = 0,
+		BUTTON_ENABLED = 1,
+		BUTTON_SELECTED = 2
+	};
+
+	enum {
+		NAV_BUTTON_UP = 0,
+		NAV_BUTTON_LEFT = 1,
+		NAV_BUTTON_RIGHT = 2,
+		NAV_BUTTON_DOWN = 3,
+		NAV_BUTTON_FORWARD = 4
+	};
+
+	static const int NUM_ARROWS = 5;
+	static const int NUM_ARROW_BITMAPS = 3;
+
+	Graphics::Surface *_background;
+	int _arrowBitmaps[NUM_ARROWS][NUM_ARROW_BITMAPS];
+	byte _arrowStatus[NUM_ARROWS];
+
+	bool drawArrow(int xDst, int yDst, int arrow);
+	bool rebuildArrows();
+
+};
+
+} // End of namespace Buried
+
+#endif


Commit: bf3ba824c4e4f90154b2662bc99e9f40a090fd6e
    https://github.com/scummvm/scummvm/commit/bf3ba824c4e4f90154b2662bc99e9f40a090fd6e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the biochip view window

Changed paths:
  A engines/buried/biochip_view.cpp
  A engines/buried/biochip_view.h
    engines/buried/biochip_right.cpp
    engines/buried/module.mk


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index d2b88d5345..31229398f3 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -85,7 +85,7 @@ bool BioChipRightWindow::showBioChipMainView() {
 	// TODO: Destroy burned letter window
 	_vm->_sound->timerCallback();
 
-	// TODO: BioChip main view window
+	// TODO: BioChip main view window (child to scene view)
 	_vm->_sound->timerCallback();
 
 	return true;
diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
new file mode 100644
index 0000000000..a76e6cfe9e
--- /dev/null
+++ b/engines/buried/biochip_view.cpp
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/biochip_view.h"
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/invdata.h"
+
+namespace Buried {
+
+BioChipMainViewWindow::BioChipMainViewWindow(BuriedEngine *vm, Window *parent, int currentBioChipID) : Window(vm, parent) {
+	_currentBioChipID = -1;
+	_rect = Common::Rect(0, 0, 432, 189);
+	_bioChipDisplayWindow = createBioChipSpecificViewWindow(currentBioChipID);
+	_currentBioChipID = currentBioChipID;
+
+	if (_bioChipDisplayWindow)
+		_bioChipDisplayWindow->showWindow(kWindowShow);
+
+	_oldCursor = _vm->_gfx->setCursor(kCursorArrow);
+}
+
+BioChipMainViewWindow::~BioChipMainViewWindow() {
+	delete _bioChipDisplayWindow;
+}
+
+bool BioChipMainViewWindow::onSetCursor(uint message) {
+	_vm->_gfx->setCursor((Cursor)_oldCursor);
+	return true;
+}
+
+bool BioChipMainViewWindow::changeCurrentBioChip(int newBioChipID) {
+	delete _bioChipDisplayWindow;
+	_currentBioChipID = newBioChipID;
+	_bioChipDisplayWindow = createBioChipSpecificViewWindow(newBioChipID);
+
+	if (_bioChipDisplayWindow)
+		_bioChipDisplayWindow->showWindow(kWindowShow);
+
+	return true;
+}
+
+Window *BioChipMainViewWindow::createBioChipSpecificViewWindow(int bioChipID) {
+	switch (bioChipID) {
+	case kItemBioChipInterface:
+		// TODO
+		break;
+	case kItemBioChipJump:
+		// TODO
+		break;
+	case kItemBioChipEvidence:
+		// TODO
+		break;
+	case kItemBioChipFiles:
+		// TODO
+		break;
+	}
+
+	// No entry for this BioChip
+	return 0;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/biochip_view.h b/engines/buried/biochip_view.h
new file mode 100644
index 0000000000..37fe87a09d
--- /dev/null
+++ b/engines/buried/biochip_view.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_BIOCHIP_VIEW_H
+#define BURIED_BIOCHIP_VIEW_H
+
+#include "buried/window.h"
+
+namespace Buried {
+
+class BioChipMainViewWindow : public Window {
+public:
+	BioChipMainViewWindow(BuriedEngine *vm, Window *parent, int currentBioChipID = 0);
+	~BioChipMainViewWindow();
+
+	bool changeCurrentBioChip(int newBioChip);
+
+	bool onSetCursor(uint message);
+
+private:
+	int _currentBioChipID;
+	Window *_bioChipDisplayWindow;
+	uint _oldCursor;
+
+	Window *createBioChipSpecificViewWindow(int bioChipID);
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 59ebab304a..be0c2f8fbe 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/buried
 MODULE_OBJS = \
 	avi_frames.o \
 	biochip_right.o \
+	biochip_view.o \
 	buried.o \
 	credits.o \
 	database.o \


Commit: a49e2498133c17aa98a8e0b33fbd566edbe0c46a
    https://github.com/scummvm/scummvm/commit/a49e2498133c17aa98a8e0b33fbd566edbe0c46a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add some functions to get/set the transition speed

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b03aef67f4..f61e77a540 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -369,4 +369,14 @@ void BuriedEngine::pollForEvents() {
 	}
 }
 
+int BuriedEngine::getTransitionSpeed() {
+	assert(_mainWindow);
+	return ((FrameWindow *)_mainWindow)->getTransitionSpeed();
+}
+
+void BuriedEngine::setTransitionSpeed(int newSpeed) {
+	assert(_mainWindow);
+	((FrameWindow *)_mainWindow)->setTransitionSpeed(newSpeed);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 6911b56188..00fe0719c8 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -105,6 +105,8 @@ public:
 
 	// Miscellaneous
 	void yield();
+	int getTransitionSpeed();
+	void setTransitionSpeed(int newSpeed);
 
 private:
 	Database *_library;
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 0f2f5fe976..0904496656 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -352,4 +352,9 @@ void FrameWindow::onKillFocus(Window *newWindow) {
 	_controlDown = false;
 }
 
+void FrameWindow::setTransitionSpeed(int newSpeed) {
+	_transitionSpeed = newSpeed;
+	ConfMan.setInt(_vm->isDemo() ? "TransitionSpeed" : _vm->getString(IDS_INI_KEY_TRANS_SPEED), newSpeed);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index ceba583e54..ee0ef204f0 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -60,6 +60,9 @@ public:
 	void onKillFocus(Window *newWindow);
 	void onSetFocus(Window *oldWindow);
 
+	int getTransitionSpeed() const { return _transitionSpeed; }
+	void setTransitionSpeed(int newSpeed);
+
 private:
 	Window *_mainChildWindow;
 	bool _controlDown;


Commit: 43e49fd1c1d9430d1b664964d97997620566a9e0
    https://github.com/scummvm/scummvm/commit/43e49fd1c1d9430d1b664964d97997620566a9e0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the interface biochip window

Changed paths:
    engines/buried/biochip_view.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index a76e6cfe9e..b2bc829367 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -27,6 +27,9 @@
 #include "buried/buried.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
+#include "buried/resources.h"
+
+#include "graphics/surface.h"
 
 namespace Buried {
 
@@ -62,11 +65,157 @@ bool BioChipMainViewWindow::changeCurrentBioChip(int newBioChipID) {
 	return true;
 }
 
+enum {
+	REGION_NONE = 0
+};
+
+enum {
+	REGION_SAVE = 1,
+	REGION_RESTORE = 2,
+	REGION_PAUSE = 3,
+	REGION_QUIT = 4,
+	REGION_FLICKER = 5,
+	REGION_TRANSITION_SPEED = 6
+};
+
+class InterfaceBioChipViewWindow : public Window {
+public:
+	InterfaceBioChipViewWindow(BuriedEngine *vm, Window *parent);
+	~InterfaceBioChipViewWindow();
+
+	void onPaint();
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+
+private:
+	Common::Rect _save;
+	Common::Rect _pause;
+	Common::Rect _restore;
+	Common::Rect _quit;
+	Common::Rect _flicker;
+	Common::Rect _transitionSpeed;
+
+	int _curRegion;
+	int _transLocation;
+	int _soundLocation;
+
+	Graphics::Surface *_background;
+	Graphics::Surface *_cycleCheck;
+	Graphics::Surface *_caret;
+};
+
+InterfaceBioChipViewWindow::InterfaceBioChipViewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_save = Common::Rect(192, 37, 300, 74);
+	_pause = Common::Rect(192, 84, 300, 121);
+	_restore = Common::Rect(313, 37, 421, 74);
+	_quit = Common::Rect(313, 84, 421, 121);
+	_flicker = Common::Rect(14, 146, 164, 166);
+	_transitionSpeed = Common::Rect(14, 100, 125, 140);
+
+	_curRegion = REGION_NONE;
+	_soundLocation = 0;
+	_transLocation = _vm->getTransitionSpeed() * 50;
+
+	_rect = Common::Rect(0, 0, 432, 189);
+
+	_background = _vm->_gfx->getBitmap(IDB_BCV_INTERFACE_MAIN);
+	_cycleCheck = _vm->_gfx->getBitmap(IDB_BCV_INTERFACE_CHECK);
+	_caret = _vm->_gfx->getBitmap(IDB_BCV_INTERFACE_HANDLE);
+}
+
+InterfaceBioChipViewWindow::~InterfaceBioChipViewWindow() {
+	_background->free();
+	delete _background;
+
+	_cycleCheck->free();
+	delete _cycleCheck;
+
+	_caret->free();
+	delete _caret;
+}
+
+void InterfaceBioChipViewWindow::onPaint() {
+	Common::Rect absoluteRect = getAbsoluteRect();
+	_vm->_gfx->blit(_background, absoluteRect.left, absoluteRect.top);
+
+	// TODO
+	if (true)
+		_vm->_gfx->blit(_cycleCheck, absoluteRect.left + 13, absoluteRect.top + 144);
+
+	if (_caret)
+		_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 14, absoluteRect.top + 97, 15, 30, _caret, 0, 0, 0, 248, _vm->isTrueColor() ? 252 : 248, 248);
+}
+
+void InterfaceBioChipViewWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_save.contains(point))
+		_curRegion = REGION_SAVE;
+	else if (_restore.contains(point))
+		_curRegion = REGION_RESTORE;
+	else if (_pause.contains(point))
+		_curRegion = REGION_PAUSE;
+	else if (_quit.contains(point))
+		_curRegion = REGION_QUIT;
+	else if (_flicker.contains(point))
+		_curRegion = REGION_FLICKER;
+	else if (_transitionSpeed.contains(point))
+		_curRegion = REGION_TRANSITION_SPEED;
+}
+
+void InterfaceBioChipViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	switch (_curRegion) {
+	case REGION_SAVE:
+		// TODO
+		break;
+	case REGION_RESTORE:
+		// TODO
+		break;
+	case REGION_QUIT:
+		// TODO
+		break;
+	case REGION_PAUSE:
+		// TODO
+		break;
+	case REGION_FLICKER:
+		// TODO
+		break;
+	case REGION_TRANSITION_SPEED:
+		_transLocation = CLIP<int>(point.x - 14, 0, 150);
+
+		if ((_transLocation % 50) > 25)
+			_transLocation = (_transLocation / 50 + 1) * 50;
+		else
+			_transLocation = _transLocation / 50 * 50;
+
+		_vm->setTransitionSpeed(_transLocation / 50);
+
+		invalidateWindow(false);
+		break;
+	}
+
+	_curRegion = REGION_NONE;
+}
+
+void InterfaceBioChipViewWindow::onMouseMove(const Common::Point &point, uint flags) {
+	if (_curRegion == REGION_TRANSITION_SPEED) {
+		int newPos = CLIP<int>(point.x - 14, 0, 150);
+
+		if ((newPos % 50) > 25)
+			newPos = (newPos / 50 + 1) * 50;
+		else
+			newPos = newPos / 50 * 50;
+
+		if (_transLocation != newPos) {
+			_transLocation = newPos;
+			invalidateWindow(false);
+		}
+	}
+}
+
 Window *BioChipMainViewWindow::createBioChipSpecificViewWindow(int bioChipID) {
 	switch (bioChipID) {
 	case kItemBioChipInterface:
-		// TODO
-		break;
+		return new InterfaceBioChipViewWindow(_vm, this);
 	case kItemBioChipJump:
 		// TODO
 		break;


Commit: 605815877255f8c3c597c796a962fe8a5526249e
    https://github.com/scummvm/scummvm/commit/605815877255f8c3c597c796a962fe8a5526249e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the files biochip window

Changed paths:
    engines/buried/avi_frames.h
    engines/buried/biochip_view.cpp


diff --git a/engines/buried/avi_frames.h b/engines/buried/avi_frames.h
index ab266d9ed9..30835c122f 100644
--- a/engines/buried/avi_frames.h
+++ b/engines/buried/avi_frames.h
@@ -42,7 +42,7 @@ namespace Buried {
 
 class AVIFrames {
 public:
-	AVIFrames(const Common::String &fileName, uint cachedFrames = 0);
+	AVIFrames(const Common::String &fileName = "", uint cachedFrames = 0);
 	~AVIFrames();
 
 	bool open(const Common::String &fileName, uint cachedFrames = 0);
diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index b2bc829367..c00a9e1bbc 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -23,12 +23,15 @@
  *
  */
 
+#include "buried/avi_frames.h"
 #include "buried/biochip_view.h"
 #include "buried/buried.h"
+#include "buried/fbcdata.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/resources.h"
 
+#include "common/stream.h"
 #include "graphics/surface.h"
 
 namespace Buried {
@@ -212,6 +215,100 @@ void InterfaceBioChipViewWindow::onMouseMove(const Common::Point &point, uint fl
 	}
 }
 
+class FilesBioChipViewWindow : public Window {
+public:
+	FilesBioChipViewWindow(BuriedEngine *vm, Window *parent);
+	
+	void onPaint();
+	void onLButtonUp(const Common::Point &point, uint flags);
+
+private:
+	int _curPage;
+	AVIFrames _stillFrames;
+	Common::Array<FilesPage> _navData;
+};
+
+FilesBioChipViewWindow::FilesBioChipViewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_curPage = 0;
+	_rect = Common::Rect(0, 0, 432, 189);
+
+	Common::SeekableReadStream *fbcStream = _vm->getFileBCData(IDBD_BC_VIEW_DATA);
+	assert(fbcStream);
+
+	fbcStream->skip(2); // Page count
+
+	while (fbcStream->pos() < fbcStream->size()) {
+		FilesPage page;
+		page.pageID = fbcStream->readSint16LE();
+		page.returnPageIndex = fbcStream->readSint16LE();
+		page.nextButtonPageIndex = fbcStream->readSint16LE();
+		page.prevButtonPageIndex = fbcStream->readSint16LE();
+
+		for (int i = 0; i < 6; i++) {
+			page.hotspots[i].left = fbcStream->readSint16LE();
+			page.hotspots[i].top = fbcStream->readSint16LE();
+			page.hotspots[i].right = fbcStream->readSint16LE();
+			page.hotspots[i].bottom = fbcStream->readSint16LE();
+			page.hotspots[i].pageIndex = fbcStream->readSint16LE();
+		}
+
+		_navData.push_back(page);
+	}
+
+	delete fbcStream;
+
+	if (!_stillFrames.open(_vm->getFilePath(IDS_BC_FILES_VIEW_FILENAME)))
+		error("Failed to open files biochip video");
+}
+
+void FilesBioChipViewWindow::onPaint() {
+	const Graphics::Surface *frame = _stillFrames.getFrame(_curPage);
+	assert(frame);
+
+	Common::Rect absoluteRect = getAbsoluteRect();
+	_vm->_gfx->blit(frame, absoluteRect.left, absoluteRect.top);
+}
+
+void FilesBioChipViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_curPage < 0 || _curPage >= (int)_navData.size())
+		return;
+
+	const FilesPage &page = _navData[_curPage];
+
+	Common::Rect returnButton(343, 157, 427, 185);
+	Common::Rect next(193, 25, 241, 43);
+	Common::Rect previous(253, 25, 301, 43);
+
+	if (page.returnPageIndex >= 0 && returnButton.contains(point)) {
+		_curPage = page.returnPageIndex;
+		invalidateWindow(false);
+		return;
+	}
+
+	if (page.nextButtonPageIndex >= 0 && next.contains(point)) {
+		_curPage = page.nextButtonPageIndex;
+		invalidateWindow(false);
+
+		// TODO: Score check
+
+		return;
+	}
+
+	if (page.prevButtonPageIndex >= 0 && previous.contains(point)) {
+		_curPage = page.prevButtonPageIndex;
+		invalidateWindow(false);
+		return;
+	}
+
+	for (int i = 0; i < 6; i++) {
+		if (page.hotspots[i].pageIndex >= 0 && Common::Rect(page.hotspots[i].left, page.hotspots[i].top, page.hotspots[i].right, page.hotspots[i].bottom).contains(point)) {
+			_curPage = page.hotspots[i].pageIndex;
+			invalidateWindow(false);
+			return;
+		}
+	}
+}
+
 Window *BioChipMainViewWindow::createBioChipSpecificViewWindow(int bioChipID) {
 	switch (bioChipID) {
 	case kItemBioChipInterface:
@@ -223,8 +320,7 @@ Window *BioChipMainViewWindow::createBioChipSpecificViewWindow(int bioChipID) {
 		// TODO
 		break;
 	case kItemBioChipFiles:
-		// TODO
-		break;
+		return new FilesBioChipViewWindow(_vm, this);
 	}
 
 	// No entry for this BioChip


Commit: cc3d4b18aad0af36454f405e235c53fa1f5f6c29
    https://github.com/scummvm/scummvm/commit/cc3d4b18aad0af36454f405e235c53fa1f5f6c29
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Remove unneeded double-click message

Changed paths:
    engines/buried/buried.cpp
    engines/buried/message.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index f61e77a540..2878322fb2 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -339,7 +339,6 @@ void BuriedEngine::pollForEvents() {
 			break;
 		}
 		case Common::EVENT_LBUTTONUP: {
-			// TODO: Double-click
 			Common::Point relativePos;
 			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
 			window->postMessage(new LButtonUpMessage(relativePos, 0));
diff --git a/engines/buried/message.h b/engines/buried/message.h
index a421df4cca..d379a0d75e 100644
--- a/engines/buried/message.h
+++ b/engines/buried/message.h
@@ -41,7 +41,6 @@ enum MessageType {
 	kMessageTypeMouseMove,
 	kMessageTypeLButtonUp,
 	kMessageTypeLButtonDown,
-	kMessageTypeLButtonDoubleClick,
 	kMessageTypeMButtonUp,
 	kMessageTypeRButtonUp,
 	kMessageTypeRButtonDown,
@@ -103,7 +102,6 @@ typedef KeyMessage<kMessageTypeKeyDown>                KeyDownMessage;
 typedef MouseMessage<kMessageTypeMouseMove>            MouseMoveMessage;
 typedef MouseMessage<kMessageTypeLButtonUp>            LButtonUpMessage;
 typedef MouseMessage<kMessageTypeLButtonDown>          LButtonDownMessage;
-typedef MouseMessage<kMessageTypeLButtonDoubleClick>   LButtonDoubleClickMessage;
 typedef MouseMessage<kMessageTypeMButtonUp>            MButtonUpMessage;
 typedef MouseMessage<kMessageTypeRButtonUp>            RButtonUpMessage;
 typedef MouseMessage<kMessageTypeRButtonDown>          RButtonDownMessage;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index d52e2fda53..bf88410e76 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -91,9 +91,6 @@ void Window::sendMessage(Message *message) {
 	case kMessageTypeLButtonDown:
 		onLButtonDown(((LButtonDownMessage *)message)->getPoint(), ((LButtonDownMessage *)message)->getFlags());
 		break;
-	case kMessageTypeLButtonDoubleClick:
-		onLButtonDoubleClick(((LButtonDoubleClickMessage *)message)->getPoint(), ((LButtonDoubleClickMessage *)message)->getFlags());
-		break;
 	case kMessageTypeMButtonUp:
 		onMButtonUp(((MButtonUpMessage *)message)->getPoint(), ((MButtonUpMessage *)message)->getFlags());
 		break;
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 063a530006..eb04d8e876 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -50,7 +50,6 @@ public:
 	virtual void onPaint() {}
 	virtual void onLButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onLButtonDown(const Common::Point &point, uint flags) {}
-	virtual void onLButtonDoubleClick(const Common::Point &point, uint flags) {}
 	virtual void onMouseMove(const Common::Point &point, uint flags) {}
 	virtual void onMButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onRButtonUp(const Common::Point &point, uint flags) {}


Commit: 13f48076bfc6ecac850c891e898d0caa0dba223e
    https://github.com/scummvm/scummvm/commit/13f48076bfc6ecac850c891e898d0caa0dba223e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Fix font sizes

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/livetext.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 95ee20de63..680fdd0847 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -148,20 +148,43 @@ static const uint32 s_codePage1252[256] = {
 
 Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
 	// TODO: MS Gothic for the Japanese version (please buy for clone2727)
-	// Arial or Arial Bold for everything else (???)
+	// Arial or Arial Bold for everything else
 
 	Common::SeekableReadStream *stream = findArialStream(bold);
 
 	if (!stream)
-		return 0;
+		error("Failed to find Arial%s font", bold ? " Bold" : "");
+
+	// Map the heights needed to point sizes
+	if (bold) {
+		if (size != 20)
+			error("Unhandled Arial Bold height %d", size);
+
+		size = 12;
+	} else {
+		switch (size) {
+		case 12:
+		case 13:
+			size = 7;
+			break;
+		case 14:
+			size = 8;
+			break;
+		default:
+			error("Unhandled Arial height %d", size);
+		}
+	}
 
 	// TODO: Make the monochrome mode optional
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
 	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
-	// FIXME: 'size' is really 'height', not point size.
-	// FIXME: DPI should be 96, not 0 (72)
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 0, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
+	// FIXME: The font is slightly off from the original... need to check. Sizes are right though!
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
+
+	if (!font)
+		error("Failed to load Arial%s font", bold ? " Bold" : "");
+
 	delete stream;
 	return font;
 }
diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index 01d6dbad8e..f9fbf0a23d 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -124,20 +124,20 @@ void LiveTextWindow::onPaint() {
 		uint32 y = 4;
 		for (uint32 i = 0; i < lines.size(); i++) {
 			_font->drawString(surface, lines[i], 30, y, 270, textColor);
-			y += _font->getFontHeight() + 1;
+			y += 14;
 		}
 	}
 
-	_vm->_gfx->blit(surface, _rect.left, _rect.top);
+	Common::Rect absoluteRect = getAbsoluteRect();
+	_vm->_gfx->blit(surface, absoluteRect.left, absoluteRect.top);
 
 	surface->free();
 	delete surface;
 }
 
 void LiveTextWindow::onEnable(bool enable) {
-	if (enable) {
-		// TODO: Clear out mouse messages (why???)
-	}
+	if (enable)
+		_vm->removeMouseMessages(this);
 }
 
 } // End of namespace Buried


Commit: 76f5c3d2f5ae4f84abe1af651c2084c7076ab443
    https://github.com/scummvm/scummvm/commit/76f5c3d2f5ae4f84abe1af651c2084c7076ab443
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
COMMON: Add a wrapper to read PE strings

Changed paths:
    common/winexe_pe.cpp
    common/winexe_pe.h


diff --git a/common/winexe_pe.cpp b/common/winexe_pe.cpp
index 5e962dd139..2d53ade23d 100644
--- a/common/winexe_pe.cpp
+++ b/common/winexe_pe.cpp
@@ -235,4 +235,26 @@ SeekableReadStream *PEResources::getResource(const WinResourceID &type, const Wi
 	return _exe->readStream(resource.size);
 }
 
+String PEResources::loadString(uint32 stringID) {
+	String string;
+	SeekableReadStream *stream = getResource(kPEString, (stringID >> 4) + 1);
+
+	if (!stream)
+		return string;
+
+	// Skip over strings we don't care about
+	uint32 startString = stringID & ~0xF;
+
+	for (uint32 i = startString; i < stringID; i++)
+		stream->skip(stream->readUint16LE() * 2);
+
+	// HACK: Truncate UTF-16 down to ASCII
+	byte size = stream->readUint16LE();
+	while (size--)
+		string += (char)(stream->readUint16LE() & 0xFF);
+
+	delete stream;
+	return string;
+}
+
 } // End of namespace Common
diff --git a/common/winexe_pe.h b/common/winexe_pe.h
index 67a34a3c7d..0af52fb2e6 100644
--- a/common/winexe_pe.h
+++ b/common/winexe_pe.h
@@ -75,6 +75,9 @@ public:
 	/** Return a stream to the specified resource (or 0 if non-existent). */
 	SeekableReadStream *getResource(const WinResourceID &type, const WinResourceID &id, const WinResourceID &lang);
 
+	/** Get a string from a string resource. */
+	String loadString(uint32 stringID);
+
 private:
 	struct Section {
 		uint32 virtualAddress;


Commit: 6b72a9767003355e73def3b3390f79f4b0367aec
    https://github.com/scummvm/scummvm/commit/6b72a9767003355e73def3b3390f79f4b0367aec
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add support for the Win95 binaries

Changed paths:
    engines/buried/buried.cpp
    engines/buried/database.cpp
    engines/buried/database.h
    engines/buried/detection.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 2878322fb2..a8108c3c36 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -77,7 +77,8 @@ Common::Error BuriedEngine::run() {
 	}
 
 	if (isWin95()) {
-		error("TODO: Win95 version");
+		_mainEXE = new DatabasePE();
+		_library = new DatabasePE();
 	} else if (isCompressed()) {
 		_mainEXE = new DatabaseNECompressed();
 		_library = new DatabaseNECompressed();
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index d45de73214..e2d1644d98 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "common/winexe_ne.h"
+#include "common/winexe_pe.h"
 #include "graphics/wincursor.h"
 
 #include "buried/database.h"
@@ -90,4 +91,60 @@ bool DatabaseNECompressed::load(const Common::String &fileName) {
 	return _exe->loadFromCompressedEXE(fileName);
 }
 
+DatabasePE::DatabasePE() {
+	_exe = new Common::PEResources();
+}
+
+DatabasePE::~DatabasePE() {
+	delete _exe;
+}
+
+bool DatabasePE::load(const Common::String &fileName) {
+	return _exe->loadFromEXE(fileName);
+}
+
+void DatabasePE::close() {
+	_exe->clear();
+}
+
+Common::String DatabasePE::loadString(uint32 stringID) {
+	bool continueReading = true;
+	Common::String result;
+
+	while (continueReading) {
+		Common::String string = _exe->loadString(stringID);
+
+		if (string.empty())
+			return "";
+
+		if (string[0] == '!') {
+			string.deleteChar(0);
+			stringID++;
+		} else {
+			continueReading = false;
+		}
+
+		result += string;
+	}
+
+	// Change any \r to \n
+	for (uint32 i = 0; i < result.size(); i++)
+		if (result[i] == '\r')
+			result.setChar('\n', i);
+
+	return result;
+}
+
+Common::SeekableReadStream *DatabasePE::getBitmapStream(uint32 bitmapID) {
+	return _exe->getResource(Common::kPEBitmap, bitmapID);
+}
+
+Graphics::WinCursorGroup *DatabasePE::getCursorGroup(uint32 cursorGroupID) {
+	return Graphics::WinCursorGroup::createCursorGroup(*_exe, cursorGroupID);
+}
+
+Common::SeekableReadStream *DatabasePE::getResourceStream(const Common::String &resourceType, uint32 resourceID) {
+	return _exe->getResource(resourceType, resourceID);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/database.h b/engines/buried/database.h
index 598158a68e..42c4048703 100644
--- a/engines/buried/database.h
+++ b/engines/buried/database.h
@@ -25,6 +25,7 @@
 
 namespace Common {
 class NEResources;
+class PEResources;
 class String;
 }
 
@@ -80,7 +81,22 @@ public:
 	bool load(const Common::String &fileName);
 };
 
-// TODO: PE stuff
+class DatabasePE : public Database {
+public:
+	DatabasePE();
+	~DatabasePE();
+
+	bool load(const Common::String &fileName);
+	void close();
+
+	Common::String loadString(uint32 stringID);
+	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
+	Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID);
+	Common::SeekableReadStream *getResourceStream(const Common::String &resourceType, uint32 resourceID);
+
+private:
+	Common::PEResources *_exe;
+};
 
 } // End of namespace Buried
 
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 6493473673..88c97e6bfa 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -83,10 +83,11 @@ namespace Buried {
 static const BuriedGameDescription gameDescriptions[] = {
 	// Windows 3.11 8BPP
 	// Installed
+	// v1.01
 	{
 		{
 			"buried",
-			"8BPP",
+			"v1.01 8BPP",
 			{
 				{ "BIT816.EXE",  0, "57a14461c77d9c77534bd418043db1ec", 1163776 },
 				{ "BIT8LIB.DLL", 0, "31bcd9e5cc32df00b09ce626e6d9106e", 2420480 },
@@ -101,10 +102,11 @@ static const BuriedGameDescription gameDescriptions[] = {
 
 	// Windows 3.11 24BPP
 	// Installed
+	// v1.01
 	{
 		{
 			"buried",
-			"24BPP",
+			"v1.01 24BPP",
 			{
 				{ "BIT2416.EXE",  0, "dcbfb3f2916ad902043942fc00d2017f", 1159680 },
 				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
@@ -119,10 +121,11 @@ static const BuriedGameDescription gameDescriptions[] = {
 
 	// Windows 3.11 8BPP
 	// Not Installed
+	// v1.01
 	{
 		{
 			"buried",
-			"8BPP",
+			"v1.01 8BPP",
 			{
 				{ "BIT816.EX_",  0, "166b44e53350c19bb25ef93d2c2b8f79", 364490 },
 				{ "BIT8LIB.DL_", 0, "8a345993f60f6bed7c17fa9e7f2bc37d", 908854 },
@@ -137,10 +140,11 @@ static const BuriedGameDescription gameDescriptions[] = {
 
 	// Windows 3.11 24BPP
 	// Not Installed
+	// v1.01
 	{
 		{
 			"buried",
-			"24BPP",
+			"v1.01 24BPP",
 			{
 				{ "BIT2416.EX_",  0, "a9ac76610ba614b59235a7d5e00e4a62", 361816 },
 				{ "BIT24LIB.DL_", 0, "00e6eedbcef824988fbb01a87ca8f7fd", 2269314 },
@@ -153,6 +157,42 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
+	// Windows 95 8BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"v1.1 8BPP",
+			{
+				{ "BIT832.EXE",  0, "f4f8007f49197ba40ea633eb113c0b6d", 1262592 },
+				{ "BIT8L32.DLL", 0, "addfef0420e1f41a7766ecc6baa58553", 2424832 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_WIN95,
+			GUIO0()
+		},
+	},
+
+	// Windows 95 24BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"v1.1 24BPP",
+			{
+				{ "BIT2432.EXE",  0, "4086a8200938eac3e72d238a84f65618", 1257472 },
+				{ "BIT24L32.DLL", 0, "198bfd476d5228c4a7a63c029cffadfc", 5216256 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR | GF_WIN95,
+			GUIO0()
+		},
+	},
+
 	// Demo 8BPP
 	{
 		{


Commit: 7d19e450bb6d102182530ca7d966167056f35789
    https://github.com/scummvm/scummvm/commit/7d19e450bb6d102182530ca7d966167056f35789
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Hook the demo into the interface

Changed paths:
    engines/buried/biochip_right.cpp
    engines/buried/demo/demo_menu.cpp
    engines/buried/resources.h


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index 31229398f3..2a56803671 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -182,7 +182,10 @@ void BioChipRightWindow::onPaint() {
 		bitmapResID = (_status == 0) ? 10 : 11;
 		break;
 	case kItemBioChipInterface:
-		bitmapResID = (_status == 0) ? 12 : 13;
+		if (_vm->isDemo())
+			bitmapResID = (_status == 0) ? IDB_BCR_INTERFACE_MENU : IDB_BCR_INTERFACE_EXIT;
+		else
+			bitmapResID = (_status == 0) ? 12 : 13;
 		break;
 	case kItemBioChipJump:
 		// TODO
@@ -194,7 +197,10 @@ void BioChipRightWindow::onPaint() {
 	}
 
 	if (bitmapResID >= 0) {
-		Graphics::Surface *bitmap = _vm->_gfx->getBitmap(IDB_BCR_BITMAP_BASE + bitmapResID);
+		if (!_vm->isDemo())
+			bitmapResID += IDB_BCR_BITMAP_BASE;
+
+		Graphics::Surface *bitmap = _vm->_gfx->getBitmap(bitmapResID);
 		Common::Rect absoluteRect = getAbsoluteRect();
 		_vm->_gfx->blit(bitmap, absoluteRect.left, absoluteRect.top);
 		bitmap->free();
diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
index c03a4ba903..bbfc34cc37 100644
--- a/engines/buried/demo/demo_menu.cpp
+++ b/engines/buried/demo/demo_menu.cpp
@@ -153,8 +153,12 @@ void DemoMainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 		}
 		return;
 	case BUTTON_INTERACTIVE:
-		// TODO
-		break;
+		if (_interactive.contains(point)) {
+			_vm->_sound->setAmbientSound();
+			// TODO: Reviewer mode check (control)
+			((FrameWindow *)_parent)->startNewGame();
+		}
+		return;
 	case BUTTON_GALLERY:
 		if (_gallery.contains(point)) {
 			_vm->_sound->setAmbientSound();
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index b49f30a024..96929a607d 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -251,8 +251,14 @@ namespace Buried {
 #define IDB_DEATH_WT_BUTTONS_NORMAL     12414
 #define IDB_DEATH_WT_BUTTONS_DEPRESSED  12415
 
+// Full Game:
 #define IDB_BCR_BITMAP_BASE				12450
 
+// Demo:
+#define IDB_BCR_BLANK_BACKGROUND		12400
+#define IDB_BCR_INTERFACE_MENU			12401
+#define IDB_BCR_INTERFACE_EXIT			12402
+
 
 #define IDB_PICON_BITMAP_BASE			12800
 #define IDB_DRAG_BITMAP_BASE			12900


Commit: 78c866efec799c8bac9beb489eac5af2838c49d6
    https://github.com/scummvm/scummvm/commit/78c866efec799c8bac9beb489eac5af2838c49d6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add inventory window

Dragging not working yet

Changed paths:
  A engines/buried/inventory_info.cpp
  A engines/buried/inventory_info.h
  A engines/buried/inventory_window.cpp
  A engines/buried/inventory_window.h
    engines/buried/biochip_right.cpp
    engines/buried/gameui.cpp
    engines/buried/gameui.h
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/module.mk


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index 2a56803671..d2a859ac8b 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -68,6 +68,9 @@ bool BioChipRightWindow::changeCurrentBioChip(int bioChipID) {
 	if (_bioChipViewWindow)
 		destroyBioChipViewWindow();
 
+	_curBioChip = bioChipID;
+	_status = 0;
+
 	// TODO: Set the translate enabled flag to false
 
 	invalidateWindow(false);
diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index 6f3d58a303..feb11b9cd8 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -28,6 +28,7 @@
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
+#include "buried/inventory_window.h"
 #include "buried/livetext.h"
 #include "buried/message.h"
 #include "buried/navarrow.h"
@@ -49,6 +50,7 @@ GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent
 
 	_navArrowWindow = new NavArrowWindow(_vm, this);
 	_liveTextWindow = new LiveTextWindow(_vm, this);
+	_inventoryWindow = new InventoryWindow(_vm, this);
 	_bioChipRightWindow = new BioChipRightWindow(_vm, this);
 
 	// TODO: Other windows
@@ -57,6 +59,7 @@ GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent
 GameUIWindow::~GameUIWindow() {
 	delete _navArrowWindow;
 	delete _liveTextWindow;
+	delete _inventoryWindow;
 	delete _bioChipRightWindow;
 
 	// TODO: Other windows
@@ -68,6 +71,7 @@ bool GameUIWindow::startNewGame(bool walkthrough) {
 
 	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
+	_inventoryWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
 
 	// TODO: Other windows
@@ -104,6 +108,7 @@ bool GameUIWindow::startNewGameIntro(bool walkthrough) {
 
 	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
+	_inventoryWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
 
 	// TODO: Other windows
@@ -116,6 +121,7 @@ bool GameUIWindow::startNewGame(const Common::String &fileName) {
 
 	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
+	_inventoryWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
 
 	// TODO: Other windows
@@ -287,6 +293,7 @@ void GameUIWindow::onPaint() {
 
 void GameUIWindow::onEnable(bool enable) {
 	// Pass the enable message to all child windows
+	_inventoryWindow->enableWindow(enable);
 	_navArrowWindow->enableWindow(enable);
 	_liveTextWindow->enableWindow(enable);
 	_bioChipRightWindow->enableWindow(enable);
diff --git a/engines/buried/gameui.h b/engines/buried/gameui.h
index e3c26c9e72..dff36bc87c 100644
--- a/engines/buried/gameui.h
+++ b/engines/buried/gameui.h
@@ -35,6 +35,7 @@ struct Surface;
 namespace Buried {
 
 class BioChipRightWindow;
+class InventoryWindow;
 class LiveTextWindow;
 class NavArrowWindow;
 
@@ -62,7 +63,7 @@ public:
 	NavArrowWindow *_navArrowWindow;
 	LiveTextWindow *_liveTextWindow;
 	// TODO: SceneViewWindow
-	// TODO: InventoryWindow
+	InventoryWindow *_inventoryWindow;
 	BioChipRightWindow *_bioChipRightWindow;
 
 private:
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 680fdd0847..cd1f466441 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -612,4 +612,41 @@ Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
 	return stream;
 }
 
+int GraphicsManager::computeHPushOffset(int speed) {
+	switch (speed) {
+	case 3:
+		return 432;
+	case 2:
+		return 72;
+	case 1:
+		return 36;
+	case 0:
+		return 12;
+	}
+
+	return 432;
+}
+
+int GraphicsManager::computeVPushOffset(int speed) {
+	switch (speed) {
+	case 3:
+		return 189;
+	case 2:
+		return 63;
+	case 1:
+		return 21;
+	case 0:
+		return 7;
+	}
+
+	return 189;
+}
+
+void GraphicsManager::crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc) {
+	assert(dst->format.bytesPerPixel == src->format.bytesPerPixel);
+
+	for (int y = 0; y < h; y++)
+		memcpy(dst->getBasePtr(xDst, yDst + y), src->getBasePtr(xSrc, ySrc + y), w * src->format.bytesPerPixel);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index a48d643c72..a824522b43 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -93,9 +93,13 @@ public:
 	void fillRect(const Common::Rect &rect, uint32 color);
 	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
 	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
+	void crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 
+	int computeHPushOffset(int speed);
+	int computeVPushOffset(int speed);
+
 private:
 	BuriedEngine *_vm;
 	Cursor _curCursor;
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
new file mode 100644
index 0000000000..6a1006deb1
--- /dev/null
+++ b/engines/buried/inventory_info.cpp
@@ -0,0 +1,284 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/avi_frames.h"
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/invdata.h"
+#include "buried/inventory_info.h"
+#include "buried/resources.h"
+#include "buried/video_window.h"
+
+#include "common/str-array.h"
+#include "graphics/font.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+InventoryInfoWindow::InventoryInfoWindow(BuriedEngine *vm, Window *parent, int currentItemID) : Window(vm, parent) {
+	_currentItemID = 0;
+	_spinStart = 0;
+	_spinLength = 70;
+
+	_textFont = _vm->_gfx->createFont(14);
+	_rect = Common::Rect(0, 0, 432, 189);
+	_videoWindow = new VideoWindow(_vm, this);
+
+	if (!_videoWindow->openVideo(_vm->getFilePath(IDS_INVENTORY_SPIN_FILENAME)))
+		error("Failed to load inventory info file");
+
+	_videoWindow->setWindowPos(0, 268, 17, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosShowWindow);
+	_videoWindow->enableWindow(false);
+
+	_timer = setTimer(100);
+	changeCurrentItem(currentItemID);
+}
+
+InventoryInfoWindow::~InventoryInfoWindow() {
+	_vm->killTimer(_timer);
+	delete _videoWindow;
+	delete _textFont;
+}
+
+bool InventoryInfoWindow::changeCurrentItem(int newItemID) {
+	_currentItemID = newItemID;
+
+	_spinStart = newItemID * 71;
+	_spinLength = 70;
+	_videoWindow->stopVideo();
+
+	_videoWindow->seekToFrame(_spinStart);
+	invalidateWindow(false);
+
+	_videoWindow->playToFrame(_spinStart + _spinLength);
+
+	if (_currentItemID == kItemLensFilter) {
+		// TODO: Set scoring flag
+	}
+
+	return true;
+}
+
+void InventoryInfoWindow::onPaint() {
+	Graphics::Surface *background = _vm->_gfx->getBitmap(IDB_INVENTORY_INFO_BACKGROUND);
+
+	// Draw the title
+	uint32 textColor = _vm->_gfx->getColor(212, 109, 0);
+	Common::Rect titleRect(10, 56, 263, 71);
+	Common::String title = _vm->getString(IDES_ITEM_TITLE_BASE + _currentItemID);
+	assert(!title.empty());
+
+	Common::StringArray lines;
+	_textFont->wordWrapText(title, titleRect.width(), lines);
+
+	uint32 y = titleRect.top;
+	for (uint32 i = 0; i < lines.size(); i++) {
+		_textFont->drawString(background, lines[i], titleRect.left, titleRect.top, titleRect.width(), textColor);
+		y += 14;
+	}
+
+	// Draw the description
+	Common::Rect descRect(10, 89, 263, 186);
+	Common::String desc = _vm->getString(IDES_ITEM_DESC_BASE + _currentItemID * 5);
+	assert(!desc.empty());
+
+	lines.clear();
+	_textFont->wordWrapText(desc, descRect.width(), lines);
+
+	y = descRect.top;
+	for (uint32 i = 0; i < lines.size(); i++) {
+		_textFont->drawString(background, lines[i], descRect.left, descRect.top, descRect.width(), textColor);
+		y += 14;
+	}
+
+	Common::Rect absoluteRect = getAbsoluteRect();
+	_vm->_gfx->blit(background, absoluteRect.left, absoluteRect.top);
+
+	background->free();
+	delete background;
+}
+
+bool InventoryInfoWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void InventoryInfoWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	// TODO: Destroy window
+}
+
+void InventoryInfoWindow::onTimer(uint timer) {
+	if (_videoWindow->getMode() == VideoWindow::kModeStopped) {
+		_videoWindow->seekToFrame(_spinStart);
+		_videoWindow->playToFrame(_spinStart + _spinLength);
+	}
+}
+
+BurnedLetterViewWindow::BurnedLetterViewWindow(BuriedEngine *vm, Window *parent, const LocationStaticData &curSceneStaticData) : Window(vm, parent), _curSceneStaticData(curSceneStaticData) {
+	_curView = 0;
+	_translatedTextResourceID = IDBD_BLETTER_TRANS_TEXT_BASE;
+	_curLineIndex = -1;
+	_preBuffer = 0;
+
+	_rect = Common::Rect(0, 0, 432, 189);
+
+	_viewLineCount[0] = 8;
+	_viewLineCount[1] = 8;
+	_viewLineCount[2] = 7;
+
+	_stillFrames = new AVIFrames(_vm->getFilePath(IDS_INVITEM_LETTER_FILENAME));
+
+	_viewCount = 3;
+
+	_top = Common::Rect(0, 0, 432, 60);
+	_bottom = Common::Rect(0, 129, 432, 189);
+	_left = Common::Rect(0, 60, 60, 129);
+	_right = Common::Rect(372, 60, 432, 129);
+	_putDown = Common::Rect(60, 60, 372, 129);
+
+	_rebuildPage = true;
+
+	// TODO: Scoring for reading the letter
+}
+
+BurnedLetterViewWindow::~BurnedLetterViewWindow() {
+	if (_preBuffer) {
+		_preBuffer->free();
+		delete _preBuffer;
+	}
+
+	delete _stillFrames;
+}
+
+void BurnedLetterViewWindow::onPaint() {
+	if (_rebuildPage) {
+		if (_preBuffer) {
+			_preBuffer->free();
+			delete _preBuffer;
+		}
+
+		_preBuffer = _stillFrames->getFrameCopy(_curView);
+		_rebuildPage = false;
+	}
+
+	Common::Rect absoluteRect = getAbsoluteRect();
+	byte transValue = _vm->isDemo() ? 2 : 0;
+	_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height(), _preBuffer, 0, 0, 0, transValue, transValue, transValue);
+
+	if (_curLineIndex >= 0 && false) { // TODO: Translation
+		int numLines = _viewLineCount[_curView];
+		uint32 boxColor = _vm->_gfx->getColor(255, 0, 0);
+		Common::Rect box(1, (187 / numLines) * _curLineIndex, 430, (187 / numLines) * (_curLineIndex + 1) - 1);
+		_vm->_gfx->getScreen()->frameRect(box, boxColor);
+	}
+}
+
+void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_top.contains(point) && _curView > 0) {
+		_curView--;
+
+		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+		Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
+
+		int offset = _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed());
+		for (int i = 0; i < 189; i += offset) {
+			_preBuffer->move(0, offset, _preBuffer->h - offset);
+
+			for (int j = 0; j < offset; j++)
+				memcpy(_preBuffer->getBasePtr(0, j), newFrame->getBasePtr(0, i + j), newFrame->w * newFrame->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+
+		_curLineIndex = -1;
+		_rebuildPage = true;
+		invalidateWindow(false);
+
+		_vm->_gfx->setCursor(oldCursor);
+	}
+
+	if (_bottom.contains(point) && _curView < _viewCount - 1) {
+		_curView++;
+
+		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+		Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
+
+		int offset = _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed());
+		for (int i = 189 - offset; i >= 0; i -= offset) {
+			_preBuffer->move(0, -offset, _preBuffer->h - offset);
+
+			for (int j = 0; j < offset; j++)
+				memcpy(_preBuffer->getBasePtr(0, j), newFrame->getBasePtr(0, i + j), newFrame->w * newFrame->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+
+		_curLineIndex = -1;
+		_rebuildPage = true;
+		invalidateWindow(false);
+
+		_vm->_gfx->setCursor(oldCursor);
+	}
+
+	if (_putDown.contains(point)) {
+		// TODO: Destroy the window
+	}
+}
+
+void BurnedLetterViewWindow::onMouseMove(const Common::Point &point, uint flags) {
+	_curMousePos = point;
+
+	// TODO: Translation
+
+	// Since translation was not enabled, check the current line flag
+	if (_curLineIndex != -1) {
+		// If the flag was not set to -1, reset it and invalidate the window
+		_curLineIndex = -1;
+		invalidateWindow(false);
+	}
+}
+
+bool BurnedLetterViewWindow::onSetCursor(uint message) {
+	Cursor cursorID = kCursorArrow;
+
+	if (_top.contains(_curMousePos) && _curView > 0) 
+		cursorID = kCursorMoveUp;
+
+	if (_bottom.contains(_curMousePos) && _curView < (_viewCount - 1))
+		cursorID = kCursorMoveDown;
+
+	if (_putDown.contains(_curMousePos))
+		cursorID = kCursorPutDown;
+
+	_vm->_gfx->setCursor(cursorID);
+
+	return true;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/inventory_info.h b/engines/buried/inventory_info.h
new file mode 100644
index 0000000000..69677d15f4
--- /dev/null
+++ b/engines/buried/inventory_info.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_INVENTORY_INFO_H
+#define BURIED_INVENTORY_INFO_H
+
+#include "buried/navdata.h"
+#include "buried/window.h"
+
+namespace Graphics {
+class Font;
+struct Surface;
+}
+
+namespace Buried {
+
+class AVIFrames;
+
+class InventoryInfoWindow : public Window {
+public:
+	InventoryInfoWindow(BuriedEngine *vm, Window *parent, int currentItemID);
+	~InventoryInfoWindow();
+
+	bool changeCurrentItem(int newItemID);
+
+	void onPaint();
+	bool onEraseBackground();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onTimer(uint timer);
+
+private:
+	Graphics::Font *_textFont;
+	int _currentItemID;
+	VideoWindow *_videoWindow;
+	int32 _spinStart;
+	int32 _spinLength;
+	uint _timer;
+};
+
+class BurnedLetterViewWindow : public Window {
+public:
+	BurnedLetterViewWindow(BuriedEngine *vm, Window *parent, const LocationStaticData &curSceneStaticData);
+	~BurnedLetterViewWindow();
+
+	void onPaint();
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+	bool onSetCursor(uint message);
+
+private:
+	LocationStaticData _curSceneStaticData;
+	int _viewCount;
+	int _curView;
+	Common::Rect _top, _bottom, _left, _right, _putDown;
+	int _translatedTextResourceID;
+	int _curLineIndex;
+	Graphics::Surface *_preBuffer;
+	AVIFrames *_stillFrames;
+	Common::Point _curMousePos;
+	int _viewLineCount[3];
+	bool _rebuildPage;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
new file mode 100644
index 0000000000..65c78a1da8
--- /dev/null
+++ b/engines/buried/inventory_window.cpp
@@ -0,0 +1,568 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/avi_frames.h"
+#include "buried/biochip_right.h"
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/graphics.h"
+#include "buried/inventory_info.h"
+#include "buried/inventory_window.h"
+#include "buried/message.h"
+#include "buried/resources.h"
+
+#include "common/algorithm.h"
+#include "graphics/font.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_background = 0;
+	_magSelected = false;
+	_upSelected = false;
+	_downSelected = false;
+	_textSelected = -1;
+	_itemComesFromInventory = false;
+	_draggingObject = false;
+	_draggingItemID = -1;
+	_draggingItemSpriteData.image = 0;
+	_draggingIconIndex = 0;
+	_draggingItemInInventory = false;
+
+	if (_vm->isDemo()) {
+		// Demo gets its own items
+		_itemArray.push_back(kItemBioChipInterface);
+		_itemArray.push_back(kItemGrapplingHook);
+	} else {
+		// Default items
+		_itemArray.push_back(kItemBioChipBlank);
+		_itemArray.push_back(kItemBioChipCloak);
+		_itemArray.push_back(kItemBioChipEvidence);
+		_itemArray.push_back(kItemBioChipFiles);
+		_itemArray.push_back(kItemBioChipInterface);
+		_itemArray.push_back(kItemBioChipJump);
+	}
+
+	_curItem = 0;
+
+	_infoWindow = 0;
+	_letterViewWindow = 0;
+
+	_scrollTimer = 0;
+
+	rebuildPreBuffer();
+
+	_textFont = _vm->_gfx->createFont(14);
+
+	_rect = Common::Rect(182, 375, 450, 454);
+	_curCursor = (int)kCursorNone;
+
+	Common::String dragFramesFileName;
+
+	if (_vm->isDemo()) {
+		if (_vm->isTrueColor())
+			dragFramesFileName = "COMMON/INVDRAG.BTV";
+		else
+			dragFramesFileName = "COMMON/INVDRAG8.BTV";
+	} else {
+		dragFramesFileName = _vm->getFilePath(IDS_INVENTORY_DRAG_FILENAME);
+	}
+
+	_dragFrames = new AVIFrames(dragFramesFileName);
+}
+
+InventoryWindow::~InventoryWindow() {
+	if (_background) {
+		_background->free();
+		delete _background;
+	}
+
+	if (_draggingItemSpriteData.image) {
+		_draggingItemSpriteData.image->free();
+		delete _draggingItemSpriteData.image;
+	}
+
+	if (_scrollTimer != 0)
+		killTimer(_scrollTimer);
+
+	destroyInfoWindow();
+	destroyBurnedLetterWindow();
+
+	delete _textFont;
+	delete _dragFrames;
+}
+
+bool InventoryWindow::rebuildPreBuffer() {
+	if (_background) {
+		_background->free();
+		delete _background;
+	}
+
+	_background = _vm->_gfx->getBitmap(IDB_INVENTORY_BACKGROUND);
+	Graphics::Surface *arrows = _vm->_gfx->getBitmap(IDB_INVENTORY_ARROWS);
+
+	int leftOffset = 3;
+	if (_magSelected)
+		leftOffset += 69;
+	if (_upSelected)
+		leftOffset += 23;
+	if (_downSelected)
+		leftOffset += 46;
+
+	_vm->_gfx->crossBlit(_background, 96, 7, 18, 69, arrows, leftOffset, 0);
+	arrows->free();
+	delete arrows;
+
+	if (!_itemArray.empty()) {
+		// Draw the icon for the current item
+		Graphics::Surface *icon = _vm->_gfx->getBitmap(IDB_PICON_BITMAP_BASE + _itemArray[_curItem]);
+		_vm->_gfx->crossBlit(_background, 17, 8, icon->w, icon->h, icon, 0, 0);
+	}
+
+	return true;
+}
+
+bool InventoryWindow::addItem(int itemID) {
+	_itemArray.push_back(itemID);
+
+	// Sort the array
+	Common::sort(_itemArray.begin(), _itemArray.end());
+
+	// Find the new position, and set the current selection to that
+	for (int i = 0; i < (int)_itemArray.size(); i++) {
+		if (_itemArray[i] == itemID) {
+			_curItem = i;
+			break;
+		}
+	}
+
+	// Redraw
+	rebuildPreBuffer();
+	invalidateWindow(false);
+
+	// TODO: Scoring flags
+	return true;
+}
+
+bool InventoryWindow::removeItem(int itemID) {
+	bool found = false;
+
+	for (int i = 0; i < (int)_itemArray.size(); i++) {
+		if (_itemArray[i] == itemID) {
+			found = true;
+			_itemArray.remove_at(i);
+			break;
+		}
+	}
+
+	if (!found)
+		return false;
+
+	if (_curItem >= (int)_itemArray.size())
+		_curItem--;
+
+	rebuildPreBuffer();
+	invalidateWindow(false);
+
+	return true;
+}
+
+bool InventoryWindow::startDraggingNewItem(int itemID, const Common::Point &pointStart) {
+	_draggingItemInInventory = false;
+	_itemComesFromInventory = false;
+	_draggingObject = true;
+	_draggingItemID = itemID;
+	_draggingIconIndex = 0;
+
+	InventoryElement staticItemData = getItemStaticData(_draggingItemID);
+	_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
+	_draggingItemSpriteData.xPos = 0;
+	_draggingItemSpriteData.yPos = 0;
+	_draggingItemSpriteData.width = _draggingItemSpriteData.image->w;
+	_draggingItemSpriteData.height = _draggingItemSpriteData.image->h;
+
+	if (_vm->isTrueColor()) {
+		_draggingItemSpriteData.redTrans = 255;
+		_draggingItemSpriteData.greenTrans = 255;
+		_draggingItemSpriteData.blueTrans = 255;
+	} else {
+		_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[0];
+		_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[1];
+		_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[2];
+
+		if (!_vm->isDemo()) {
+			for (int y = 0; y < _draggingItemSpriteData.height; y++) {
+				for (int x = 0; x < _draggingItemSpriteData.width; x++) {
+					byte color = *((byte *)_draggingItemSpriteData.image->getBasePtr(x, y));
+
+					if (color != 0)
+						*((byte *)_draggingItemSpriteData.image->getBasePtr(x, y)) = color + 10;
+				}
+			}
+		}
+	}
+
+	// TODO: Set capture
+	onSetCursor(kMessageTypeLButtonDown);
+	onMouseMove(pointStart, 0);
+
+	return true;
+}
+
+bool InventoryWindow::displayBurnedLetterWindow() {
+	if (_letterViewWindow)
+		return true;
+
+	// TODO
+
+	return true;
+}
+
+bool InventoryWindow::destroyBurnedLetterWindow() {
+	if (!_letterViewWindow)
+		return false;
+
+	delete _letterViewWindow;
+	_letterViewWindow = 0;
+
+	// TODO: Notify the scene view window
+
+	return true;
+}
+
+void InventoryWindow::onPaint() {
+	// Draw the prebuffer
+	Common::Rect absoluteRect = getAbsoluteRect();
+	_vm->_gfx->blit(_background, absoluteRect.left, absoluteRect.top);
+
+	// Draw inventory item names
+	uint32 textColor = _vm->_gfx->getColor(212, 109, 0);
+	for (int i = -2; i < 3; i++) {
+		if ((i + _curItem) >= 0 && (i + _curItem) < (int)_itemArray.size()) {
+			Common::Rect textRect = Common::Rect(120, (i + 2) * 13 + 8, 254, (i + 3) * 13 + 8);
+			textRect.translate(absoluteRect.left, absoluteRect.top);
+			Common::String text = _vm->getString(IDES_ITEM_TITLE_BASE + _itemArray[_curItem + i]);
+			_textFont->drawString(_vm->_gfx->getScreen(), text, textRect.left, textRect.top, textRect.width(), textColor);
+		}
+	}
+}
+
+void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (!isWindowEnabled())
+		return;
+
+	Common::Rect up(95, 8, 114, 29);
+	Common::Rect down(95, 54, 114, 75);
+	Common::Rect magnify(95, 30, 114, 52);
+	Common::Rect picon(15, 8, 93, 72);
+
+	Common::Rect inventoryText[5];
+	for (int i = 0; i < 5; i++)
+		inventoryText[i] = Common::Rect(120, i * 13 + 8, 254, (i + 1) * 13 + 8);
+
+	bool redraw = false;
+	if (up.contains(point)) {
+		if (_curItem > 0) {
+			_upSelected = true;
+			redraw = true;
+			_scrollTimer = setTimer(250);
+		}
+	}
+
+	if (down.contains(point)) {
+		if (_curItem < ((int)_itemArray.size() - 1)) {
+			_downSelected = true;
+			redraw = true;
+			_scrollTimer = setTimer(250);
+		}
+	}
+
+	if (magnify.contains(point)) {
+		_magSelected = true;
+		redraw = true;
+	}
+
+	for (int i = 0; i < 5; i++) {
+		if (inventoryText[i].contains(point)) {
+			_textSelected = i;
+			break;
+		}
+	}
+
+	if (picon.contains(point) && !_itemArray.empty() && !_infoWindow) {
+		int itemID = _itemArray[_curItem];
+
+		switch (itemID) {
+		case kItemBioChipAI:
+		case kItemBioChipBlank:
+		case kItemBioChipCloak:
+		case kItemBioChipEvidence:
+		case kItemBioChipFiles:
+		case kItemBioChipInterface:
+		case kItemBioChipJump:
+		case kItemBioChipTranslate:
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(itemID);
+			return;
+		}
+
+		if (true) { // TODO: Check for auxilary window
+			if (itemID == kItemBurnedLetter) {
+				displayBurnedLetterWindow();
+				return;
+			}
+
+			if (itemID == kItemLensFilter) {
+				// TODO
+				return;
+			}
+
+			// TODO: Support dragging
+			return;
+
+			InventoryElement staticItemData = getItemStaticData(_draggingItemID);
+
+			if (staticItemData.firstDragID < 0)
+				return;
+
+			_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
+			_draggingItemInInventory = true;
+			_itemComesFromInventory = true;
+			_draggingObject = true;
+			_draggingItemID = itemID;
+			_draggingIconIndex = 0;
+
+			_draggingItemSpriteData.xPos = 0;
+			_draggingItemSpriteData.yPos = 0;
+			_draggingItemSpriteData.width = _draggingItemSpriteData.image->w;
+			_draggingItemSpriteData.height = _draggingItemSpriteData.image->h;
+
+			if (_vm->isTrueColor()) {
+				_draggingItemSpriteData.redTrans = 255;
+				_draggingItemSpriteData.greenTrans = 255;
+				_draggingItemSpriteData.blueTrans = 255;
+			} else {
+				_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[0];
+				_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[1];
+				_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[2];
+
+				if (!_vm->isDemo()) {
+					for (int y = 0; y < _draggingItemSpriteData.height; y++) {
+						for (int x = 0; x < _draggingItemSpriteData.width; x++) {
+							byte color = *((byte *)_draggingItemSpriteData.image->getBasePtr(x, y));
+
+							if (color != 0)
+								*((byte *)_draggingItemSpriteData.image->getBasePtr(x, y)) = color + 10;
+						}
+					}
+				}
+			}
+
+			// TODO: SetCapture();
+
+			onSetCursor(kMessageTypeLButtonDown);
+			// TODO: Change sprite status
+			onMouseMove(point, 0);
+		}
+	}
+
+	if (redraw) {
+		rebuildPreBuffer();
+		invalidateWindow(false);
+	}
+}
+
+void InventoryWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (!isWindowEnabled())
+		return;
+
+	Common::Rect up(95, 8, 114, 29);
+	Common::Rect down(95, 54, 114, 75);
+	Common::Rect magnify(95, 30, 114, 52);
+	Common::Rect picon(15, 8, 93, 72);
+
+	Common::Rect inventoryText[5];
+	for (int i = 0; i < 5; i++)
+		inventoryText[i] = Common::Rect(120, i * 13 + 8, 254, (i + 1) * 13 + 8);
+
+	bool redraw = _upSelected || _downSelected || _magSelected;
+
+	if (up.contains(point) && _upSelected) {
+		if (_curItem > 0)
+			_curItem--;
+
+		if (_infoWindow)
+			_infoWindow->changeCurrentItem(_itemArray[_curItem]);
+
+		if (_scrollTimer != 0) {
+			killTimer(_scrollTimer);
+			_scrollTimer = 0;
+		}
+	}
+
+	if (down.contains(point) && _downSelected) {
+		if (_curItem < ((int)_itemArray.size() - 1))
+			_curItem++;
+
+		if (_infoWindow)
+			_infoWindow->changeCurrentItem(_itemArray[_curItem]);
+
+		if (_scrollTimer != 0) {
+			killTimer(_scrollTimer);
+			_scrollTimer = 0;
+		}
+	}
+
+	if (magnify.contains(point)) {
+		destroyBurnedLetterWindow();
+
+		if (_infoWindow) {
+			destroyInfoWindow();
+		} else {
+			// TODO: Create window
+			_magSelected = true;
+			redraw = true;
+		}
+	}
+
+	if (_textSelected >= 0) {
+		for (int i = 0; i < 5; i++) {
+			if (inventoryText[i].contains(point) && (_curItem + i - 2) >= 0 && (_curItem + i - 2) < (int)_itemArray.size() && i == _textSelected) {
+				_curItem += i - 2;
+				redraw = true;
+
+				if (_infoWindow)
+					_infoWindow->changeCurrentItem(_itemArray[_curItem]);
+			}
+		}
+	}
+
+	_upSelected = false;
+	_downSelected = false;
+	_textSelected = -1;
+
+	if (_draggingObject) {
+		_draggingObject = false;
+
+		// TODO: Lots missing
+	}
+
+	if (redraw) {
+		rebuildPreBuffer();
+		invalidateWindow(false);
+	}
+}
+
+void InventoryWindow::onMouseMove(const Common::Point &point, uint flags) {
+	_curMousePos = point;
+
+	if (_draggingObject) {
+		// TODO
+	} else {
+		Common::Rect up(95, 8, 114, 29);
+		Common::Rect down(95, 54, 114, 75);
+		Common::Rect magnify(95, 30, 114, 52);
+
+		if (_upSelected && !up.contains(point)) {
+			_upSelected = false;
+			rebuildPreBuffer();
+			invalidateWindow(false);
+		}
+
+		if (_downSelected && !down.contains(point)) {
+			_downSelected = false;
+			rebuildPreBuffer();
+			invalidateWindow(false);
+		}
+
+		if (_magSelected && !magnify.contains(point)) {
+			_magSelected = false;
+			rebuildPreBuffer();
+			invalidateWindow(false);
+		}
+	}
+}
+
+bool InventoryWindow::onSetCursor(uint message) {
+	if (!isWindowEnabled())
+		return false;
+
+	if (_draggingObject) {
+		_vm->_gfx->setCursor(kCursorClosedHand);
+	} else if (Common::Rect(15, 8, 93, 72).contains(_curMousePos)) {
+		_vm->_gfx->setCursor(kCursorOpenHand);
+	} else {
+		_vm->_gfx->setCursor(kCursorArrow);
+	}
+
+	return true;
+}
+
+void InventoryWindow::onTimer(uint timer) {
+	if (_upSelected) {
+		if (_curItem > 0) {
+			_curItem--;
+			rebuildPreBuffer();
+			invalidateWindow(false);
+		}
+	} else if (_downSelected) {
+		if (_curItem < (int)_itemArray.size() - 1) {
+			_curItem++;
+			rebuildPreBuffer();
+			invalidateWindow(false);
+		}
+	}
+}
+
+bool InventoryWindow::isItemInInventory(int itemID) {
+	for (uint i = 0; i < _itemArray.size(); i++)
+		if (_itemArray[i] == itemID)
+			return true;
+
+	return false;
+}
+
+InventoryElement InventoryWindow::getItemStaticData(int itemID) {
+	// TODO
+	return InventoryElement();
+}
+
+bool InventoryWindow::destroyInfoWindow() {
+	if (!_infoWindow)
+		return false;
+
+	delete _infoWindow;
+	_infoWindow = 0;
+
+	// TODO: Notify the scene view
+
+	_magSelected = false;
+	rebuildPreBuffer();
+	invalidateWindow(false);
+
+	return true;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/inventory_window.h b/engines/buried/inventory_window.h
new file mode 100644
index 0000000000..12c6151f87
--- /dev/null
+++ b/engines/buried/inventory_window.h
@@ -0,0 +1,105 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_INVENTORY_WINDOW_H
+#define BURIED_INVENTORY_WINDOW_H
+
+#include "buried/invdata.h"
+#include "buried/sprtdata.h"
+#include "buried/window.h"
+
+namespace Buried {
+
+class AVIFrames;
+class InventoryInfoWindow;
+class BurnedLetterViewWindow;
+
+class InventoryWindow : public Window {
+public:
+	InventoryWindow(BuriedEngine *vm, Window *parent);
+	~InventoryWindow();
+
+	bool rebuildPreBuffer();
+
+	bool addItem(int itemID);
+	bool removeItem(int itemID);
+
+	bool startDraggingNewItem(int itemID, const Common::Point &pointStart);
+	int getCurrentItemID() { return _itemArray[_curItem]; }
+	bool isItemInInventory(int itemID);
+	InventoryElement getItemStaticData(int itemID);
+	int getItemCount() { return _itemArray.size(); }
+	int getItemID(int itemIndex) { return _itemArray[itemIndex]; }
+	// getItemArray
+	// setItemArray
+
+	bool destroyInfoWindow();
+	InventoryInfoWindow *getInfoWindow() { return _infoWindow; }
+
+	bool displayBurnedLetterWindow();
+	bool destroyBurnedLetterWindow();
+	BurnedLetterViewWindow *getBurnedLetterWindow() { return _letterViewWindow; }
+
+	void onPaint();
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+	bool onSetCursor(uint message);
+	void onTimer(uint timer);
+
+private:
+	Graphics::Font *_textFont;
+	Graphics::Surface *_background;
+	Common::Array<int> _itemArray;
+	int _curItem;
+
+	bool _magSelected;
+	bool _upSelected;
+	bool _downSelected;
+	int _textSelected;
+
+	bool _draggingObject;
+	bool _itemComesFromInventory;
+	int _draggingItemID;
+	Sprite _draggingItemSpriteData;
+	int _draggingIconIndex;
+	bool _draggingItemInInventory;
+
+	Common::Point _curMousePos;
+	int _curCursor;
+
+	InventoryInfoWindow *_infoWindow;
+	BurnedLetterViewWindow *_letterViewWindow;
+
+	AVIFrames *_dragFrames;
+
+	uint _scrollTimer;
+
+	// TODO: Item data
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index be0c2f8fbe..84756bc746 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -11,6 +11,8 @@ MODULE_OBJS = \
 	frame_window.o \
 	gameui.o \
 	graphics.o \
+	inventory_info.o \
+	inventory_window.o \
 	livetext.o \
 	main_menu.o \
 	navarrow.o \


Commit: 04328b98fd649866b03e4de98359c67c4d730806
    https://github.com/scummvm/scummvm/commit/04328b98fd649866b03e4de98359c67c4d730806
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Font-related cleanup

The Japanese font can now be loaded, if available. and FreeSans from the theme can be used as a fallback where Arial is not available.

Changed paths:
    engines/buried/buried.h
    engines/buried/detection.cpp
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 00fe0719c8..4a2f3b6779 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -62,6 +62,7 @@ public:
 	bool isCompressed() const;
 	Common::String getEXEName() const;
 	Common::String getLibraryName() const;
+	Common::Language getLanguage() const;
 
 	bool hasFeature(EngineFeature f) const;
 
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 88c97e6bfa..5755a5340b 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -70,6 +70,10 @@ Common::String BuriedEngine::getLibraryName() const {
 	return _gameDescription->desc.filesDescriptions[1].fileName;
 }
 
+Common::Language BuriedEngine::getLanguage() const {
+	return _gameDescription->desc.language;
+}
+
 } // End of namespace Buried
 
 static const PlainGameDescriptor buriedGames[] = {
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index cd1f466441..69c6ecf06a 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -23,11 +23,13 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "common/fs.h"
 #ifdef MACOSX
 #include "common/macresman.h"
 #endif
 #include "common/system.h"
+#include "common/unzip.h"
 #include "graphics/cursorman.h"
 #include "graphics/font.h"
 #include "graphics/palette.h"
@@ -147,9 +149,17 @@ static const uint32 s_codePage1252[256] = {
 #undef NOT_REQUIRED
 
 Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
-	// TODO: MS Gothic for the Japanese version (please buy for clone2727)
+	// MS Gothic for the Japanese version (please buy for clone2727)
 	// Arial or Arial Bold for everything else
+	if (_vm->getLanguage() == Common::JA_JPN) {
+		assert(!bold);
+		return createMSGothicFont(size);
+	}
+
+	return createArialFont(size, bold);
+}
 
+Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
 	Common::SeekableReadStream *stream = findArialStream(bold);
 
 	if (!stream)
@@ -178,7 +188,6 @@ Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
 	// TODO: Make the monochrome mode optional
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
-	// TODO: shift-jis (code page 932) for the Japanese version (again, buy for clone2727)
 	// FIXME: The font is slightly off from the original... need to check. Sizes are right though!
 	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 
@@ -606,7 +615,13 @@ Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
 #endif
 
 	if (!stream) {
-		// TODO: Find the equivalent free font
+		// TODO: It would really be nice to have "Liberation Sans", since it is metric
+		// compatible with Arial.
+
+		if (bold)
+			stream = getThemeFontStream("FreeSansBold.ttf");
+		else
+			stream = getThemeFontStream("FreeSans.ttf");
 	}
 
 	return stream;
@@ -649,4 +664,88 @@ void GraphicsManager::crossBlit(Graphics::Surface *dst, int xDst, int yDst, int
 		memcpy(dst->getBasePtr(xDst, yDst + y), src->getBasePtr(xSrc, ySrc + y), w * src->format.bytesPerPixel);
 }
 
+Graphics::Font *GraphicsManager::createMSGothicFont(int size) const {
+	Common::SeekableReadStream *stream = findMSGothicStream();
+
+	if (!stream)
+		error("Failed to find MS Gothic font");
+
+	// TODO: Map the heights needed to point sizes
+
+	// TODO: Make the monochrome mode optional
+	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
+	// with the TrueType font on Win7/Win8 (at least)
+	// TODO: shift-jis codepage (932) and mapping
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, !_vm->isTrueColor(), s_codePage1252);
+
+	if (!font)
+		error("Failed to load MS Gothic font");
+
+	delete stream;
+	return font;
+}
+
+Common::SeekableReadStream *GraphicsManager::findMSGothicStream() const {
+	Common::SeekableReadStream *stream = 0;
+
+	// HACK: Try to load the system font
+#if defined(WIN32)
+	Common::FSNode fontPath("C:/WINDOWS/Fonts/msgothic.ttc");
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+
+	if (!stream) {
+		Common::FSNode win2kFontPath("C:/WINNT/Fonts/msgothic.ttc");
+
+		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
+			stream = win2kFontPath.createReadStream();
+	}
+#elif defined(MACOSX)
+	// Attempt to load the font from MS Gothic.ttf
+	Common::FSNode fontPath(Common::String::format("/Library/Fonts/MS Gothic.ttf"));
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
+#endif
+
+	if (!stream) {
+		// TODO: Find the equivalent free font (probably "VL Gothic", which is what Wine uses)
+		// "Ume Gothic" might be another alternative
+	}
+
+	return stream;
+}
+
+Common::SeekableReadStream *GraphicsManager::getThemeFontStream(const Common::String &fileName) const {
+	// Without needing to actually come out and say it, this is all one huge hack.
+	// OK, I said it anyway.
+
+	Common::SeekableReadStream *stream = 0;
+
+	// Code loosely based on the similar Wintermute code, minus the C++11 nullptr nonsense
+	// Attempt to load it from the theme
+
+	if (ConfMan.hasKey("themepath")) {
+		Common::SeekableReadStream *archiveStream = 0;
+		Common::FSNode themeFile(ConfMan.get("themepath") + "/scummmodern.zip");
+
+		if (themeFile.exists() && !themeFile.isDirectory() && themeFile.isReadable())
+			archiveStream = themeFile.createReadStream();
+
+		if (!archiveStream)
+			archiveStream = SearchMan.createReadStreamForMember("scummmodern.zip");
+
+		if (archiveStream) {
+			Common::Archive *archive = Common::makeZipArchive(archiveStream);
+			if (archive)
+				stream = archive->createReadStreamForMember(fileName);
+
+			delete archive;
+		}
+	}
+
+	return stream;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index a824522b43..e6fe91cb6d 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -113,7 +113,12 @@ private:
 	byte *createDefaultPalette() const;
 	Graphics::Surface *getBitmap(Common::SeekableReadStream *stream);
 
+	Graphics::Font *createArialFont(int size, bool bold) const;
 	Common::SeekableReadStream *findArialStream(bool bold) const;
+	Common::SeekableReadStream *getThemeFontStream(const Common::String &fileName) const;
+
+	Graphics::Font *createMSGothicFont(int size) const;
+	Common::SeekableReadStream *findMSGothicStream() const;
 };
 
 } // End of namespace Buried


Commit: d86096574b2ebbb54a7d55a2a3941050b73c6944
    https://github.com/scummvm/scummvm/commit/d86096574b2ebbb54a7d55a2a3941050b73c6944
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add a wrapper for drawing multi-line text

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/inventory_info.cpp
    engines/buried/livetext.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 69c6ecf06a..35d5d210e0 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -28,6 +28,7 @@
 #ifdef MACOSX
 #include "common/macresman.h"
 #endif
+#include "common/str-array.h"
 #include "common/system.h"
 #include "common/unzip.h"
 #include "graphics/cursorman.h"
@@ -748,4 +749,17 @@ Common::SeekableReadStream *GraphicsManager::getThemeFontStream(const Common::St
 	return stream;
 }
 
+void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight) {
+	if (text.empty())
+		return;
+
+	Common::StringArray lines;
+	font->wordWrapText(text, w, lines);
+
+	for (uint32 i = 0; i < lines.size(); i++) {
+		font->drawString(dst, lines[i], x, y, w, color);
+		y += lineHeight;
+	}
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index e6fe91cb6d..9278e7fdb1 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -94,6 +94,7 @@ public:
 	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
 	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
 	void crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc);
+	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index 6a1006deb1..fde878c42a 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -31,7 +31,6 @@
 #include "buried/resources.h"
 #include "buried/video_window.h"
 
-#include "common/str-array.h"
 #include "graphics/font.h"
 #include "graphics/surface.h"
 
@@ -89,29 +88,13 @@ void InventoryInfoWindow::onPaint() {
 	Common::Rect titleRect(10, 56, 263, 71);
 	Common::String title = _vm->getString(IDES_ITEM_TITLE_BASE + _currentItemID);
 	assert(!title.empty());
-
-	Common::StringArray lines;
-	_textFont->wordWrapText(title, titleRect.width(), lines);
-
-	uint32 y = titleRect.top;
-	for (uint32 i = 0; i < lines.size(); i++) {
-		_textFont->drawString(background, lines[i], titleRect.left, titleRect.top, titleRect.width(), textColor);
-		y += 14;
-	}
+	_vm->_gfx->renderText(background, _textFont, title, titleRect.left, titleRect.top, titleRect.width(), textColor, 14);
 
 	// Draw the description
 	Common::Rect descRect(10, 89, 263, 186);
 	Common::String desc = _vm->getString(IDES_ITEM_DESC_BASE + _currentItemID * 5);
 	assert(!desc.empty());
-
-	lines.clear();
-	_textFont->wordWrapText(desc, descRect.width(), lines);
-
-	y = descRect.top;
-	for (uint32 i = 0; i < lines.size(); i++) {
-		_textFont->drawString(background, lines[i], descRect.left, descRect.top, descRect.width(), textColor);
-		y += 14;
-	}
+	_vm->_gfx->renderText(background, _textFont, desc, descRect.left, descRect.top, descRect.width(), textColor, 14);
 
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(background, absoluteRect.left, absoluteRect.top);
diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index f9fbf0a23d..f2619cd091 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -23,7 +23,6 @@
  *
  */
 
-#include "common/str-array.h"
 #include "graphics/font.h"
 #include "graphics/surface.h"
 
@@ -114,19 +113,9 @@ void LiveTextWindow::onPaint() {
 	// Draw the background bitmap
 	Graphics::Surface *surface = _vm->_gfx->getBitmap(IDB_LIVE_TEXT_BACKGROUND);
 
-	// (This probably needs a look-through)
-	if (!_text.empty()) {
-		uint32 textColor = _vm->_gfx->getColor(212, 109, 0);
-
-		Common::StringArray lines;
-		_font->wordWrapText(_text, 270, lines);
-
-		uint32 y = 4;
-		for (uint32 i = 0; i < lines.size(); i++) {
-			_font->drawString(surface, lines[i], 30, y, 270, textColor);
-			y += 14;
-		}
-	}
+	// Draw the text on top of that
+	if (!_text.empty())
+		_vm->_gfx->renderText(surface, _font, _text, 30, 4, 270, _vm->_gfx->getColor(212, 109, 0), 14);
 
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(surface, absoluteRect.left, absoluteRect.top);


Commit: 7487adfd930c0d7c145beea77798372938ce9590
    https://github.com/scummvm/scummvm/commit/7487adfd930c0d7c145beea77798372938ce9590
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:38+01:00

Commit Message:
BURIED: Add the death screens

Changed paths:
  A engines/buried/death.cpp
  A engines/buried/death.h
    engines/buried/biochip_right.h
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/module.mk


diff --git a/engines/buried/biochip_right.h b/engines/buried/biochip_right.h
index 0521588024..683e7a27e8 100644
--- a/engines/buried/biochip_right.h
+++ b/engines/buried/biochip_right.h
@@ -30,6 +30,21 @@
 
 namespace Buried {
 
+// FIXME: Why is this here?
+enum {
+	CASTLE_EVIDENCE_FOOTPRINT = 1,
+	CASTLE_EVIDENCE_SWORD = 2,
+	MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID = 3,
+	MAYAN_EVIDENCE_PHONY_BLOOD = 4,
+	MAYAN_EVIDENCE_ENVIRON_CART = 5,
+	CASTLE_EVIDENCE_AGENT3 = 6,
+	AI_EVIDENCE_SCULPTURE = 7,
+	DAVINCI_EVIDENCE_FOOTPRINT = 8,
+	DAVINCI_EVIDENCE_AGENT3 = 9,
+	DAVINCI_EVIDENCE_CODEX = 10,
+	DAVINCI_EVIDENCE_LENS_FILTER = 11
+};
+
 class BioChipRightWindow : public Window {
 public:
 	BioChipRightWindow(BuriedEngine *vm, Window *parent);
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
new file mode 100644
index 0000000000..b1cfe8baca
--- /dev/null
+++ b/engines/buried/death.cpp
@@ -0,0 +1,375 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/avi_frames.h"
+#include "buried/biochip_right.h"
+#include "buried/buried.h"
+#include "buried/death.h"
+#include "buried/frame_window.h"
+#include "buried/graphics.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+
+#include "graphics/font.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+enum {
+	BUTTON_QUIT = 1,
+	BUTTON_RESTORE_GAME = 2,
+	BUTTON_MAIN_MENU = 3
+};
+
+#define CHECK_PUZZLE_FLAG(flag) \
+	if (_globalFlags.flag != 0) \
+		puzzlesSolved++
+
+#define CHECK_RESEARCH_FLAG(flag) \
+	if (_globalFlags.flag != 0) \
+		researchBonusRaw++
+
+#define CHECK_CRITICAL_EVIDENCE(flag) \
+	if (_globalFlags.evcapBaseID[i] == flag) \
+		criticalEvidence++
+
+#define CHECK_SUPPORTING_EVIDENCE(flag) \
+	if (_globalFlags.evcapBaseID[i] == flag) \
+		supportingEvidence++
+
+DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, const GlobalFlags &globalFlags) : Window(vm, parent), _deathSceneIndex(deathSceneIndex), _globalFlags(globalFlags) {
+	_curButton = 0;
+	_deathFrameIndex = -1;
+	_lightOn = false;
+	_walkthroughMode = false;
+
+	_rect = Common::Rect(0, 0, 640, 480);
+	_quit = Common::Rect(27, 422, 100, 460);
+	_restoreGame = Common::Rect(112, 422, 185, 460);
+	_mainMenu = Common::Rect(198, 422, 271, 460);
+
+	_timer = setTimer(400);
+
+	if (deathSceneIndex < 10) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_CASTLE_FILENAME));
+	} else if (deathSceneIndex < 20) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_MAYAN_FILENAME));
+	} else if (deathSceneIndex < 30) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_AGENTLAIR_FILENAME));
+	} else if (deathSceneIndex < 40) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_DAVINCI_FILENAME));
+	} else if (deathSceneIndex < 50) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_AILAB_FILENAME));
+	} else if (deathSceneIndex < 60) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_ALIEN_FILENAME));
+	} else if (deathSceneIndex < 70) {
+		_deathSceneFrames = new AVIFrames(_vm->getFilePath(IDS_DEATH_FINALE_FILENAME));
+	} else {
+		error("Bad death scene index %d", deathSceneIndex);
+	}
+
+	// Set the frame index
+	switch (deathSceneIndex) {
+	case 15:
+		_deathFrameIndex = 4;
+		break;
+	case 52:
+	case 53:
+		_deathFrameIndex = 1;
+		break;
+	case 54:
+	case 55:
+		_deathFrameIndex = 0;
+		break;
+	default:
+		_deathFrameIndex = deathSceneIndex % 10;
+		break;
+	}
+
+	_textFontA = _vm->_gfx->createFont(14);
+	_textFontB = _vm->_gfx->createFont(20, true);
+
+	_walkthroughMode = _globalFlags.generalWalkthroughMode != 0;
+
+	int puzzlesSolved = 0;
+	CHECK_PUZZLE_FLAG(scoreGotTranslateBioChip);
+	CHECK_PUZZLE_FLAG(scoreEnteredSpaceStation);
+	CHECK_PUZZLE_FLAG(scoreDownloadedArthur);
+	CHECK_PUZZLE_FLAG(scoreFoundSculptureDiagram);
+	CHECK_PUZZLE_FLAG(scoreEnteredKeep);
+	CHECK_PUZZLE_FLAG(scoreGotKeyFromSmithy);
+	CHECK_PUZZLE_FLAG(scoreEnteredTreasureRoom);
+	CHECK_PUZZLE_FLAG(scoreFoundSwordDiamond);
+	CHECK_PUZZLE_FLAG(scoreMadeSiegeCycle);
+	CHECK_PUZZLE_FLAG(scoreEnteredCodexTower);
+	CHECK_PUZZLE_FLAG(scoreLoggedCodexEvidence);
+	CHECK_PUZZLE_FLAG(scoreEnteredMainCavern);
+	CHECK_PUZZLE_FLAG(scoreGotWealthGodPiece);
+	CHECK_PUZZLE_FLAG(scoreGotWarGodPiece);
+	CHECK_PUZZLE_FLAG(scoreCompletedDeathGod);
+	CHECK_PUZZLE_FLAG(scoreEliminatedAgent3);
+	CHECK_PUZZLE_FLAG(scoreTransportToKrynn);
+	CHECK_PUZZLE_FLAG(scoreGotKrynnArtifacts);
+	CHECK_PUZZLE_FLAG(scoreDefeatedIcarus);
+
+	int researchBonusRaw = 0;
+	CHECK_RESEARCH_FLAG(scoreResearchINNHighBidder);
+	CHECK_RESEARCH_FLAG(scoreResearchINNAppeal);
+	CHECK_RESEARCH_FLAG(scoreResearchINNUpdate);
+	CHECK_RESEARCH_FLAG(scoreResearchINNJumpsuit);
+	CHECK_RESEARCH_FLAG(scoreResearchBCJumpsuit);
+	CHECK_RESEARCH_FLAG(scoreResearchMichelle);
+	CHECK_RESEARCH_FLAG(scoreResearchMichelleBkg);
+	CHECK_RESEARCH_FLAG(scoreResearchLensFilter);
+	CHECK_RESEARCH_FLAG(scoreResearchCastleFootprint);
+	CHECK_RESEARCH_FLAG(scoreResearchDaVinciFootprint);
+	CHECK_RESEARCH_FLAG(scoreResearchMorphSculpture);
+	CHECK_RESEARCH_FLAG(scoreResearchEnvironCart);
+	CHECK_RESEARCH_FLAG(scoreResearchAgent3Note);
+	CHECK_RESEARCH_FLAG(scoreResearchAgent3DaVinci);
+
+	int criticalEvidence = 0;
+	int supportingEvidence = 0;
+	for (int i = 0; i < _globalFlags.evcapNumCaptured; i++) {
+		CHECK_CRITICAL_EVIDENCE(CASTLE_EVIDENCE_SWORD);
+		CHECK_CRITICAL_EVIDENCE(MAYAN_EVIDENCE_ENVIRON_CART);
+		CHECK_CRITICAL_EVIDENCE(DAVINCI_EVIDENCE_CODEX);
+		CHECK_CRITICAL_EVIDENCE(AI_EVIDENCE_SCULPTURE);
+
+		CHECK_SUPPORTING_EVIDENCE(CASTLE_EVIDENCE_FOOTPRINT);
+		CHECK_SUPPORTING_EVIDENCE(MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID);
+		CHECK_SUPPORTING_EVIDENCE(MAYAN_EVIDENCE_PHONY_BLOOD);
+		CHECK_SUPPORTING_EVIDENCE(CASTLE_EVIDENCE_AGENT3);
+		CHECK_SUPPORTING_EVIDENCE(DAVINCI_EVIDENCE_FOOTPRINT);
+		CHECK_SUPPORTING_EVIDENCE(DAVINCI_EVIDENCE_AGENT3);
+		CHECK_SUPPORTING_EVIDENCE(DAVINCI_EVIDENCE_LENS_FILTER);
+	}
+
+	int hints = _globalFlags.scoreHintsTotal;
+	int finalCriticalEvidenceScore = criticalEvidence * 1000;
+	int finalSupportingEvidenceScore = supportingEvidence * 500;
+	int finalPuzzleScore = puzzlesSolved * 200;
+	int finalResearchScore = researchBonusRaw * 100;
+	int hintsScore = hints * 50;
+	int completionScore = (deathSceneIndex == 60) ? 2000 : 0;
+	int totalScore = finalCriticalEvidenceScore + finalSupportingEvidenceScore + finalPuzzleScore + finalResearchScore + completionScore;
+
+	if (_walkthroughMode) {
+		// TODO: This is a fucking mess between versions
+	} else {
+		totalScore -= hintsScore;
+
+		// TODO: Another mess
+	}
+
+	// TODO: A third mess
+
+	_vm->_sound->setAmbientSound();
+}
+
+#undef CHECK_PUZZLE_FLAG
+#undef CHECK_RESEARCH_FLAG
+#undef CHECK_CRITICAL_EVIDENCE
+#undef CHECK_SUPPORTING_EVIDENCE
+
+DeathWindow::~DeathWindow() {
+	killTimer(_timer);
+
+	delete _deathSceneFrames;
+
+	delete _textFontA;
+	delete _textFontB;
+}
+
+void DeathWindow::onPaint() {
+	Graphics::Surface *topBitmap = _vm->_gfx->getBitmap(IDB_DEATH_UI_TOP);
+	_vm->_gfx->blit(topBitmap, 301, 0);
+	topBitmap->free();
+	delete topBitmap;
+
+	Graphics::Surface *leftBitmap = _vm->_gfx->getBitmap(IDB_DEATH_UI_LEFT);
+	_vm->_gfx->blit(leftBitmap, 0, 0);
+	leftBitmap->free();
+	delete leftBitmap;
+
+	if (_walkthroughMode) {
+		Graphics::Surface *lowerLeftBitmap = _vm->_gfx->getBitmap(IDB_DEATH_WT_LOWER_LEFT);
+		_vm->_gfx->blit(lowerLeftBitmap, 0, 416);
+		lowerLeftBitmap->free();
+		delete lowerLeftBitmap;
+	}
+
+	Graphics::Surface *rightBitmap = _vm->_gfx->getBitmap(IDB_DEATH_UI_RIGHT);
+	_vm->_gfx->blit(rightBitmap, 624, 0);
+	rightBitmap->free();
+	delete rightBitmap;
+
+	Graphics::Surface *bottomBitmap = _vm->_gfx->getBitmap(IDB_DEATH_UI_BOTTOM);
+	_vm->_gfx->blit(bottomBitmap, 301, 468);
+	bottomBitmap->free();
+	delete bottomBitmap;
+
+	const Graphics::Surface *deathSceneHeader = _deathSceneFrames->getFrame(_deathFrameIndex);
+	_vm->_gfx->blit(deathSceneHeader, 301, 10);
+
+	uint32 textColor = _vm->_gfx->getColor(153, 102, 204);
+	Common::String firstBlock = _vm->getString(IDS_DEATH_SCENE_MESSAGE_TEXT_BASE + _deathSceneIndex * 5);
+	Common::Rect firstBlockRect(10, 54, 283, 86);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlock, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, 14);
+
+	Common::String secondBlock = _vm->getString(IDS_DEATH_SCENE_MESSAGE_TEXT_BASE + _deathSceneIndex * 5 + 1);
+	Common::Rect secondBlockRect(10, 120, 283, 215);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlock, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, 14);
+
+	Common::Rect scoringDescRect(10, 248, 283, 378);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, 14);
+
+	textColor = _vm->_gfx->getColor(212, 109, 0);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, 14, true);
+
+	// CHECKME: This does center vertical alignment, so check the y coordinates
+	Common::Rect finalTextScoreRect(122, 386, 283, 401);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), textColor, 20, true);
+}
+
+bool DeathWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void DeathWindow::onTimer(uint timer) {
+	_vm->_sound->timerCallback(); // clone2727 says: Don't think this is necessary
+
+	// Flip the state of the light
+	_lightOn = !_lightOn;
+
+	Common::Rect destRect(137, 51);
+	destRect.moveTo(164, 0);
+
+	if (_lightOn) {
+		// Light is now on
+		Graphics::Surface *lightBitmap = _vm->_gfx->getBitmap(IDB_DEATH_ELIGHT_ON);
+		_vm->_gfx->blit(lightBitmap, 164, 0);
+		lightBitmap->free();
+		delete lightBitmap;
+	} else {
+		// Light is now off
+		Graphics::Surface *leftBitmap = _vm->_gfx->getBitmap(IDB_DEATH_UI_LEFT);
+		_vm->_gfx->blit(leftBitmap, Common::Rect(164, 0, 164 + 137, 51), destRect);
+		leftBitmap->free();
+		delete leftBitmap;
+	}
+
+	// Force just that section of the screen to update
+	invalidateRect(destRect, false);
+	_vm->_gfx->updateScreen(false);
+}
+
+void DeathWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_quit.contains(point)) {
+		Graphics::Surface *buttons = _vm->_gfx->getBitmap(_walkthroughMode ? IDB_DEATH_WT_BUTTONS_DEPRESSED : IDB_DEATH_BUTTONS_DEPRESSED);
+		Common::Rect destRect(29, 424, 29 + 76, 424 + 36);
+		_vm->_gfx->blit(buttons, Common::Rect(76, 36), destRect);
+		buttons->free();
+		delete buttons;
+		invalidateRect(destRect, false);
+		_vm->_gfx->updateScreen(false);
+		_curButton = BUTTON_QUIT;
+	} else if (_restoreGame.contains(point)) {
+		Graphics::Surface *buttons = _vm->_gfx->getBitmap(_walkthroughMode ? IDB_DEATH_WT_BUTTONS_DEPRESSED : IDB_DEATH_BUTTONS_DEPRESSED);
+		Common::Rect destRect(109, 424, 109 + 80, 424 + 36);
+		_vm->_gfx->blit(buttons, Common::Rect(80, 0, 80 + 80, 36), destRect);
+		buttons->free();
+		delete buttons;
+		invalidateRect(destRect, false);
+		_vm->_gfx->updateScreen(false);
+		_curButton = BUTTON_RESTORE_GAME;
+	} else if (_mainMenu.contains(point)) {
+		Graphics::Surface *buttons = _vm->_gfx->getBitmap(_walkthroughMode ? IDB_DEATH_WT_BUTTONS_DEPRESSED : IDB_DEATH_BUTTONS_DEPRESSED);
+		Common::Rect destRect(195, 424, 195 + 76, 424 + 36);
+		_vm->_gfx->blit(buttons, Common::Rect(166, 0, 166 + 76, 36), destRect);
+		buttons->free();
+		delete buttons;
+		invalidateRect(destRect, false);
+		_vm->_gfx->updateScreen(false);
+		_curButton = BUTTON_MAIN_MENU;
+	}
+}
+
+void DeathWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	switch (_curButton) {
+	case BUTTON_QUIT:
+		if (_quit.contains(point)) {
+			_vm->quitGame();
+			return;
+		}
+		break;
+	case BUTTON_RESTORE_GAME:
+		if (_restoreGame.contains(point)) {
+			if (_walkthroughMode) {
+				// TODO: Do fake continue
+			} else {
+				// TODO: Show restore game window
+			}
+		}
+		break;
+	case BUTTON_MAIN_MENU:
+		if (_mainMenu.contains(point)) {
+			((FrameWindow *)_parent)->showMainMenu();
+			return;
+		}
+		break;
+	default:
+		return;
+	}
+
+	_curButton = 0;
+	invalidateWindow(false);
+}
+
+void DeathWindow::onMouseMove(const Common::Point &point, uint flags) {
+	switch (_curButton) {
+	case BUTTON_QUIT:
+		if (!_quit.contains(point)) {
+			_curButton = 0;
+			invalidateRect(_quit, false);
+		}
+		break;
+	case BUTTON_RESTORE_GAME:
+		if (!_restoreGame.contains(point)) {
+			_curButton = 0;
+			invalidateRect(_restoreGame, false);
+		}
+		break;
+	case BUTTON_MAIN_MENU:
+		if (!_mainMenu.contains(point)) {
+			_curButton = 0;
+			invalidateRect(_mainMenu, false);
+		}
+		break;
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/death.h b/engines/buried/death.h
new file mode 100644
index 0000000000..adbb53419d
--- /dev/null
+++ b/engines/buried/death.h
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_DEATH_H
+#define BURIED_DEATH_H
+
+#include "buried/global_flags.h"
+#include "buried/window.h"
+
+namespace Graphics {
+class Font;
+struct Surface;
+}
+
+namespace Buried {
+
+class AVIFrames;
+
+class DeathWindow : public Window {
+public:
+	DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, const GlobalFlags &globalFlags);
+	~DeathWindow();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onTimer(uint timer);
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+
+private:
+	Common::Rect _quit;
+	Common::Rect _restoreGame;
+	Common::Rect _mainMenu;
+	int _curButton;
+	uint _timer;
+	AVIFrames *_deathSceneFrames;
+	int _deathSceneIndex;
+	GlobalFlags _globalFlags;
+	int32 _deathFrameIndex;
+	bool _lightOn;
+	Graphics::Font *_textFontA;
+	Graphics::Font *_textFontB;
+	bool _walkthroughMode;
+
+	Common::String _scoringTextDescriptions;
+	Common::String _scoringTextScores;
+	Common::String _scoringTextFinalScore;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 35d5d210e0..9e6ed72aa8 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -749,7 +749,7 @@ Common::SeekableReadStream *GraphicsManager::getThemeFontStream(const Common::St
 	return stream;
 }
 
-void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight) {
+void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, bool rightAligned) {
 	if (text.empty())
 		return;
 
@@ -757,7 +757,7 @@ void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, c
 	font->wordWrapText(text, w, lines);
 
 	for (uint32 i = 0; i < lines.size(); i++) {
-		font->drawString(dst, lines[i], x, y, w, color);
+		font->drawString(dst, lines[i], x, y, w, color, rightAligned ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft);
 		y += lineHeight;
 	}
 }
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 9278e7fdb1..c09107f34c 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -94,7 +94,7 @@ public:
 	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
 	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
 	void crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc);
-	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight);
+	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, bool rightAligned = false);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 84756bc746..389ef6d26f 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS = \
 	buried.o \
 	credits.o \
 	database.o \
+	death.o \
 	detection.o \
 	frame_window.o \
 	gameui.o \


Commit: 10ac40bda0069343a63ca9cac89c17a0aea6fa84
    https://github.com/scummvm/scummvm/commit/10ac40bda0069343a63ca9cac89c17a0aea6fa84
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add support for setting capture mode on a window

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index a8108c3c36..d38c65e446 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -49,6 +49,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_timerSeed = 0;
 	_mainWindow = 0;
 	_focusedWindow = 0;
+	_captureWindow = 0;
 }
 
 BuriedEngine::~BuriedEngine() {
@@ -319,9 +320,8 @@ void BuriedEngine::pollForEvents() {
 		switch (event.type) {
 		case Common::EVENT_MOUSEMOVE: {
 			_gfx->markMouseMoved();
-			Common::Point relativePos;
-			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
-			window->postMessage(new MouseMoveMessage(relativePos, 0));
+			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
+			window->postMessage(new MouseMoveMessage(window->convertPointToLocal(event.mouse), 0));
 			window->postMessage(new SetCursorMessage(kMessageTypeMouseMove));
 			break;
 		}
@@ -334,33 +334,28 @@ void BuriedEngine::pollForEvents() {
 				_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
 			break;
 		case Common::EVENT_LBUTTONDOWN: {
-			Common::Point relativePos;
-			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
-			window->postMessage(new LButtonDownMessage(relativePos, 0));
+			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
+			window->postMessage(new LButtonDownMessage(window->convertPointToLocal(event.mouse), 0));
 			break;
 		}
 		case Common::EVENT_LBUTTONUP: {
-			Common::Point relativePos;
-			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
-			window->postMessage(new LButtonUpMessage(relativePos, 0));
+			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
+			window->postMessage(new LButtonUpMessage(window->convertPointToLocal(event.mouse), 0));
 			break;
 		}
 		case Common::EVENT_MBUTTONUP: {
-			Common::Point relativePos;
-			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
-			window->postMessage(new MButtonUpMessage(relativePos, 0));
+			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
+			window->postMessage(new MButtonUpMessage(window->convertPointToLocal(event.mouse), 0));
 			break;
 		}
 		case Common::EVENT_RBUTTONDOWN: {
-			Common::Point relativePos;
-			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
-			window->postMessage(new RButtonDownMessage(relativePos, 0));
+			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
+			window->postMessage(new RButtonDownMessage(window->convertPointToLocal(event.mouse), 0));
 			break;
 		}
 		case Common::EVENT_RBUTTONUP: {
-			Common::Point relativePos;
-			Window *window = _mainWindow->findWindowAtPoint(event.mouse, relativePos);
-			window->postMessage(new RButtonUpMessage(relativePos, 0));
+			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
+			window->postMessage(new RButtonUpMessage(window->convertPointToLocal(event.mouse), 0));
 			break;
 		}
 		default:
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 4a2f3b6779..fefe06e771 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -84,6 +84,7 @@ public:
 	SoundManager *_sound;
 	Window *_mainWindow; // Only one main window is supported.
 	Window *_focusedWindow;
+	Window *_captureWindow;
 
 	// Timers
 	uint createTimer(Window *window, uint period);
@@ -108,6 +109,7 @@ public:
 	void yield();
 	int getTransitionSpeed();
 	void setTransitionSpeed(int newSpeed);
+	void releaseCapture() { _captureWindow = 0; }
 
 private:
 	Database *_library;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index bf88410e76..7e1dd46def 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -55,6 +55,10 @@ Window::~Window() {
 	if (_vm->_focusedWindow == this)
 		_vm->_focusedWindow = 0;
 
+	// And also not captured
+	if (_vm->_captureWindow == this)
+		_vm->_captureWindow = 0;
+
 	// Invalidate this window's rect as well
 	_vm->_gfx->invalidateRect(getAbsoluteRect());
 }
@@ -258,19 +262,14 @@ Window *Window::setFocus() {
 	return oldWindow;
 }
 
-Window *Window::findWindowAtPoint(const Common::Point &point, Common::Point &relativePos) {
+Window *Window::childWindowAtPoint(const Common::Point &point) {
 	for (WindowList::iterator it = _topMostChildren.reverse_begin(); it != _topMostChildren.end(); it--)
 		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
-			return (*it)->findWindowAtPoint(point, relativePos);
+			return (*it)->childWindowAtPoint(point);
 
 	for (WindowList::iterator it = _children.reverse_begin(); it != _children.end(); it--)
 		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
-			return (*it)->findWindowAtPoint(point, relativePos);
-
-	// Also calculate the relative position of the point within the window
-	Common::Rect absoluteRect = getAbsoluteRect();
-	relativePos.x = point.x - absoluteRect.left;
-	relativePos.y = point.y - absoluteRect.top;
+			return (*it)->childWindowAtPoint(point);
 
 	return this;
 }
@@ -284,4 +283,24 @@ bool Window::handleSetCursorMessage(uint message) {
 	return onSetCursor(message);
 }
 
+Window *Window::setCapture() {
+	Window *oldCapturedWindow = _vm->_focusedWindow;
+	_vm->_focusedWindow = this;
+	return oldCapturedWindow;
+}
+
+Common::Point Window::convertPointToGlobal(const Common::Point &point) {
+	Common::Rect absoluteRect = getAbsoluteRect();
+	return Common::Point(point.x + absoluteRect.left, point.y + absoluteRect.top);
+}
+
+Common::Point Window::convertPointToLocal(const Common::Point &point) {
+	Common::Rect absoluteRect = getAbsoluteRect();
+	return Common::Point(point.x - absoluteRect.left, point.y - absoluteRect.top);
+}
+
+Common::Point Window::convertPointToWindow(const Common::Point &point, Window *dest) {
+	return dest->convertPointToLocal(convertPointToGlobal(point));
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index eb04d8e876..924328c226 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -91,18 +91,17 @@ public:
 	};
 
 	Window *setFocus();
-
-	// TODO:
-	// ShowWindow
-	// BeginPaint (?)
-	// EndPaint (?)
-	// Create
-	// ...
+	Window *setCapture();
 
 	void sendMessage(Message *message);
 	void postMessage(Message *message);
 
-	Window *findWindowAtPoint(const Common::Point &point, Common::Point &relativePoint);
+	Window *childWindowAtPoint(const Common::Point &point);
+
+	// Helper functions
+	Common::Point convertPointToGlobal(const Common::Point &point);
+	Common::Point convertPointToLocal(const Common::Point &point);
+	Common::Point convertPointToWindow(const Common::Point &point, Window *dest);
 
 protected:
 	BuriedEngine *_vm;


Commit: 7924396125def0df9f6269cd6921fa073e105425
    https://github.com/scummvm/scummvm/commit/7924396125def0df9f6269cd6921fa073e105425
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the completion window

Changed paths:
  A engines/buried/complete.cpp
  A engines/buried/complete.h
    engines/buried/module.mk


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
new file mode 100644
index 0000000000..9ec83510be
--- /dev/null
+++ b/engines/buried/complete.cpp
@@ -0,0 +1,264 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/biochip_right.h"
+#include "buried/buried.h"
+#include "buried/complete.h"
+#include "buried/frame_window.h"
+#include "buried/graphics.h"
+#include "buried/sound.h"
+#include "buried/video_window.h"
+
+#include "graphics/font.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+#define CHECK_PUZZLE_FLAG(flag) \
+	if (_globalFlags.flag != 0) \
+		puzzlesSolved++
+
+#define CHECK_RESEARCH_FLAG(flag) \
+	if (_globalFlags.flag != 0) \
+		researchBonusRaw++
+
+#define CHECK_CRITICAL_EVIDENCE(flag) \
+	if (_globalFlags.evcapBaseID[i] == flag) \
+		criticalEvidence++
+
+#define CHECK_SUPPORTING_EVIDENCE(flag) \
+	if (_globalFlags.evcapBaseID[i] == flag) \
+		supportingEvidence++
+
+CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, const GlobalFlags &globalFlags) : Window(vm, parent), _globalFlags(globalFlags) {
+	_vm->_sound->setAmbientSound();
+
+	_status = 0;
+	_background = 0;
+	_currentSoundEffectID = -1;
+	_gageVideo = 0;
+
+	_rect = Common::Rect(0, 0, 640, 480);
+
+	_timer = setTimer(1000);
+
+	_textFontA = _vm->_gfx->createFont(14);
+	_textFontB = _vm->_gfx->createFont(20, true);
+
+	_walkthroughMode = _globalFlags.generalWalkthroughMode != 0;
+
+	int puzzlesSolved = 0;
+	CHECK_PUZZLE_FLAG(scoreGotTranslateBioChip);
+	CHECK_PUZZLE_FLAG(scoreEnteredSpaceStation);
+	CHECK_PUZZLE_FLAG(scoreDownloadedArthur);
+	CHECK_PUZZLE_FLAG(scoreFoundSculptureDiagram);
+	CHECK_PUZZLE_FLAG(scoreEnteredKeep);
+	CHECK_PUZZLE_FLAG(scoreGotKeyFromSmithy);
+	CHECK_PUZZLE_FLAG(scoreEnteredTreasureRoom);
+	CHECK_PUZZLE_FLAG(scoreFoundSwordDiamond);
+	CHECK_PUZZLE_FLAG(scoreMadeSiegeCycle);
+	CHECK_PUZZLE_FLAG(scoreEnteredCodexTower);
+	CHECK_PUZZLE_FLAG(scoreLoggedCodexEvidence);
+	CHECK_PUZZLE_FLAG(scoreEnteredMainCavern);
+	CHECK_PUZZLE_FLAG(scoreGotWealthGodPiece);
+	CHECK_PUZZLE_FLAG(scoreGotWarGodPiece);
+	CHECK_PUZZLE_FLAG(scoreCompletedDeathGod);
+	CHECK_PUZZLE_FLAG(scoreEliminatedAgent3);
+	CHECK_PUZZLE_FLAG(scoreTransportToKrynn);
+	CHECK_PUZZLE_FLAG(scoreGotKrynnArtifacts);
+	CHECK_PUZZLE_FLAG(scoreDefeatedIcarus);
+
+	int researchBonusRaw = 0;
+	CHECK_RESEARCH_FLAG(scoreResearchINNHighBidder);
+	CHECK_RESEARCH_FLAG(scoreResearchINNAppeal);
+	CHECK_RESEARCH_FLAG(scoreResearchINNUpdate);
+	CHECK_RESEARCH_FLAG(scoreResearchINNJumpsuit);
+	CHECK_RESEARCH_FLAG(scoreResearchBCJumpsuit);
+	CHECK_RESEARCH_FLAG(scoreResearchMichelle);
+	CHECK_RESEARCH_FLAG(scoreResearchMichelleBkg);
+	CHECK_RESEARCH_FLAG(scoreResearchLensFilter);
+	CHECK_RESEARCH_FLAG(scoreResearchCastleFootprint);
+	CHECK_RESEARCH_FLAG(scoreResearchDaVinciFootprint);
+	CHECK_RESEARCH_FLAG(scoreResearchMorphSculpture);
+	CHECK_RESEARCH_FLAG(scoreResearchEnvironCart);
+	CHECK_RESEARCH_FLAG(scoreResearchAgent3Note);
+	CHECK_RESEARCH_FLAG(scoreResearchAgent3DaVinci);
+
+	int criticalEvidence = 0;
+	int supportingEvidence = 0;
+	for (int i = 0; i < _globalFlags.evcapNumCaptured; i++) {
+		CHECK_CRITICAL_EVIDENCE(CASTLE_EVIDENCE_SWORD);
+		CHECK_CRITICAL_EVIDENCE(MAYAN_EVIDENCE_ENVIRON_CART);
+		CHECK_CRITICAL_EVIDENCE(DAVINCI_EVIDENCE_CODEX);
+		CHECK_CRITICAL_EVIDENCE(AI_EVIDENCE_SCULPTURE);
+
+		CHECK_SUPPORTING_EVIDENCE(CASTLE_EVIDENCE_FOOTPRINT);
+		CHECK_SUPPORTING_EVIDENCE(MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID);
+		CHECK_SUPPORTING_EVIDENCE(MAYAN_EVIDENCE_PHONY_BLOOD);
+		CHECK_SUPPORTING_EVIDENCE(CASTLE_EVIDENCE_AGENT3);
+		CHECK_SUPPORTING_EVIDENCE(DAVINCI_EVIDENCE_FOOTPRINT);
+		CHECK_SUPPORTING_EVIDENCE(DAVINCI_EVIDENCE_AGENT3);
+		CHECK_SUPPORTING_EVIDENCE(DAVINCI_EVIDENCE_LENS_FILTER);
+	}
+
+	int hints = _globalFlags.scoreHintsTotal;
+	int finalCriticalEvidenceScore = criticalEvidence * 1000;
+	int finalSupportingEvidenceScore = supportingEvidence * 500;
+	int finalPuzzleScore = puzzlesSolved * 200;
+	int finalResearchScore = researchBonusRaw * 100;
+	int hintsScore = hints * 50;
+	int completionScore = 2000;
+	int totalScore = finalCriticalEvidenceScore + finalSupportingEvidenceScore + finalPuzzleScore + finalResearchScore + completionScore;
+
+	if (_walkthroughMode) {
+		// TODO: This is a fucking mess between versions
+	} else {
+		totalScore -= hintsScore;
+
+		// TODO: Another mess
+	}
+
+	// TODO: A third mess
+
+	_vm->_sound->setAmbientSound();
+}
+
+#undef CHECK_PUZZLE_FLAG
+#undef CHECK_RESEARCH_FLAG
+#undef CHECK_CRITICAL_EVIDENCE
+#undef CHECK_SUPPORTING_EVIDENCE
+
+CompletionWindow::~CompletionWindow() {
+	delete _gageVideo;
+	killTimer(_timer);
+	
+	delete _textFontA;
+	delete _textFontB;
+
+	if (_background) {
+		_background->free();
+		delete _background;
+	}
+}
+
+void CompletionWindow::onPaint() {
+	if (_background)
+		_vm->_gfx->blit(_background, 0, 0);
+
+	if (_status == 3) {
+		// Draw the first line
+		uint32 textColor = _vm->_gfx->getColor(102, 204, 153);
+		Common::String firstBlockText = _vm->getString(2100);
+		Common::Rect firstBlockRect(10, 54, 283, 86);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlockText, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, 14);
+
+		// Draw the cause text
+		Common::String secondBlockText = _vm->getString(2102);
+		Common::Rect secondBlockRect(10, 120, 283, 215);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlockText, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, 14);
+
+		// Description text
+		Common::Rect scoringTextRect(10, 248, 283, 378);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, 14);
+
+		// Scores
+		textColor = _vm->_gfx->getColor(255, 255, 51);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, 14, true);
+
+		// Total score
+		Common::Rect finalScoreRect(122, 386, 283, 401);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), textColor, 20, true);
+	}
+}
+
+bool CompletionWindow::onEraseBackground() {
+	_vm->_gfx->fillRect(getAbsoluteRect(), _vm->_gfx->getColor(0, 0, 0));
+	return true;
+}
+
+void CompletionWindow::onTimer(uint timer) {
+	switch (_status) {
+	case 0:
+		_currentSoundEffectID = _vm->_sound->playSoundEffect("BITDATA/FUTAPT/FA_COURT.BTA");
+		_status = 1;
+		_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "BITDATA/FUTAPT/CONGRATS.BTS" : "BITDATA/FUTAPT/CONGRAT8.BTS");
+		invalidateWindow(false);
+		break;
+	case 2:
+		if (!_gageVideo || _gageVideo->getMode() == VideoWindow::kModeStopped) {
+			delete _gageVideo;
+			_gageVideo = 0;
+
+			_status = 3;
+			_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "BITDATA/FUTAPT/ENDING24.BTS" : "BITDATA/FUTAPT/ENDING8.BTS");
+			invalidateWindow(false);
+			_vm->_sound->setAmbientSound("BITDATA/FUTAPT/FA_FIN.BTA");
+		}
+		break;
+	}
+}
+
+void CompletionWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	switch (_status) {
+	case 1:
+		_vm->_sound->stopSoundEffect(_currentSoundEffectID);
+		_currentSoundEffectID = -1;
+		_status = 2;
+
+		if (_background) {
+			_background->free();
+			delete _background;
+			_background = 0;
+		}
+
+		invalidateWindow(false);
+
+		_gageVideo = new VideoWindow(_vm, this);
+
+		if (!_gageVideo->openVideo("BITDATA/FUTAPT/FA_FIN.BTV"))
+			error("Failed to load finale video");
+
+		_gageVideo->setWindowPos(0, 104, 145, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+		_gageVideo->enableWindow(false);
+		_gageVideo->showWindow(kWindowShow);
+		_gageVideo->playVideo();
+		break;
+	case 2:
+		if (!_gageVideo || _gageVideo->getMode() == VideoWindow::kModeStopped) {
+			delete _gageVideo;
+			_gageVideo = 0;
+
+			_status = 4;
+			_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "BITDATA/FUTAPT/ENDING24.BTS" : "BITDATA/FUTAPT/ENDING8.BTS");
+			invalidateWindow(false);
+		}
+		break;
+	case 3:
+		((FrameWindow *)_parent)->showCredits();
+		break;
+	}
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/complete.h b/engines/buried/complete.h
new file mode 100644
index 0000000000..d8023de5ca
--- /dev/null
+++ b/engines/buried/complete.h
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_COMPLETE_H
+#define BURIED_COMPLETE_H
+
+#include "buried/global_flags.h"
+#include "buried/window.h"
+
+namespace Graphics {
+class Font;
+struct Surface;
+}
+
+namespace Buried {
+
+class VideoWindow;
+
+class CompletionWindow : public Window {
+public:
+	CompletionWindow(BuriedEngine *vm, Window *parent, const GlobalFlags &globalFlags);
+	~CompletionWindow();
+
+	void onPaint();
+	bool onEraseBackground();
+	void onTimer(uint timer);
+	void onLButtonUp(const Common::Point &point, uint flags);
+
+private:
+	int _status;
+	uint _timer;
+	Graphics::Surface *_background;
+	int _currentSoundEffectID;
+
+	GlobalFlags _globalFlags;
+	Graphics::Font *_textFontA;
+	Graphics::Font *_textFontB;
+	bool _walkthroughMode;
+
+	Common::String _scoringTextDescriptions;
+	Common::String _scoringTextScores;
+	Common::String _scoringTextFinalScore;
+
+	VideoWindow *_gageVideo;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 389ef6d26f..8925fe8493 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS = \
 	biochip_right.o \
 	biochip_view.o \
 	buried.o \
+	complete.o \
 	credits.o \
 	database.o \
 	death.o \


Commit: 4726a69d49cb50a8bd6fbe838990f74938c945c8
    https://github.com/scummvm/scummvm/commit/4726a69d49cb50a8bd6fbe838990f74938c945c8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Default to arrow cursors in onSetCursor()

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 9e6ed72aa8..61ffa1ee9c 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -200,6 +200,10 @@ Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
 }
 
 Cursor GraphicsManager::setCursor(Cursor newCursor) {
+	// Don't set the cursor again
+	if (newCursor == _curCursor)
+		return _curCursor;
+
 	Cursor oldCursor = _curCursor;
 	Graphics::Cursor *cursor = 0;
 	Graphics::WinCursorGroup *cursorGroup = 0;
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 7e1dd46def..2ebfd03b14 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -303,4 +303,10 @@ Common::Point Window::convertPointToWindow(const Common::Point &point, Window *d
 	return dest->convertPointToLocal(convertPointToGlobal(point));
 }
 
+bool Window::onSetCursor(uint message) {
+	// Default to the arrow
+	_vm->_gfx->setCursor(kCursorArrow);
+	return false;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 924328c226..cdf46b79e2 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -54,7 +54,7 @@ public:
 	virtual void onMButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onRButtonUp(const Common::Point &point, uint flags) {}
 	virtual void onRButtonDown(const Common::Point &point, uint flags) {}
-	virtual bool onSetCursor(uint message) { return false; }
+	virtual bool onSetCursor(uint message);
 	virtual void onEnable(bool enable) {}
 
 	void invalidateRect(const Common::Rect &rect, bool erase = true);


Commit: 0853ba7ac6ac180f5e1f6226043421161a17f0ad
    https://github.com/scummvm/scummvm/commit/0853ba7ac6ac180f5e1f6226043421161a17f0ad
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Make setWindowPos take a const pointer for the insertion point

Changed paths:
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 2ebfd03b14..c42601c1dd 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -147,7 +147,7 @@ void Window::updateWindow() {
 		(*it)->updateWindow();
 }
 
-void Window::setWindowPos(Window *insertAfter, int x, int y, int width, int height, uint flags) {
+void Window::setWindowPos(const Window *insertAfter, int x, int y, int width, int height, uint flags) {
 	if (!(flags & kWindowPosNoZOrder)) {
 		assert(insertAfter != this); // I don't even want to think about this case
 
diff --git a/engines/buried/window.h b/engines/buried/window.h
index cdf46b79e2..3519fd8e23 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -66,7 +66,7 @@ public:
 	void updateWindow();
 	void enableWindow(bool enable);
 	bool isWindowEnabled() const;
-	void setWindowPos(Window *insertAfter, int x, int y, int width, int height, uint flags);
+	void setWindowPos(const Window *insertAfter, int x, int y, int width, int height, uint flags);
 
 	// The subset of show modes we'll accept
 	enum WindowShowMode {


Commit: 31acc825bf021ae6855497eeabbdf0f44e48056e
    https://github.com/scummvm/scummvm/commit/31acc825bf021ae6855497eeabbdf0f44e48056e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add some more resource values

Changed paths:
    engines/buried/resources.h


diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 96929a607d..57e06227b9 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -345,6 +345,34 @@ namespace Buried {
 #define IDES_FILENAME_BASE              17408
 #define IDES_STRING_BASE                21504
 
+#define RESID_NAVDB_BASE				16384
+#define RESID_SOUNDDB_BASE				16640
+#define RESID_ANIMDB_BASE				16896
+#define RESID_AI_DB_BASE				17152
+	
+#define RESID_FILENAMES_BASE			17408
+#define RESID_STRINGS_BASE				21504
+#define RESID_TRANSLATOR_TEXT_BASE		8192
+
+#define RESOFFSET_NAVDB_TIMEZONE		16
+#define RESOFFSET_SOUNDDB_TIMEZONE		16
+#define RESOFFSET_ANIMDB_TIMEZONE		16
+#define RESOFFSET_AI_DB_TIMEZONE		16
+
+#define RESOFFSET_FILENAME_TIMEZONE		256
+#define RESOFFSET_FILENAME_ENVIRON		16
+
+#define LOADSTRING_BUFFER_SIZE			512
+#define LOADSTRING_NUM_BUFFERS			6
+
+#define SF_STILLS		0
+#define SF_CYCLES		1
+#define SF_NAVIGATION	2
+#define SF_AMBIENT		15
+
+#define DIB_FRAME_WIDTH		432
+#define DIB_FRAME_HEIGHT	189
+
 } // End of namespace Buried
 
 #endif


Commit: 7d0ad60ba9046193f9a8fc3e42cc9adf46d59e0d
    https://github.com/scummvm/scummvm/commit/7d0ad60ba9046193f9a8fc3e42cc9adf46d59e0d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add missing live text code

Changed paths:
    engines/buried/livetext.cpp


diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index f2619cd091..b6138bb5d3 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -27,6 +27,7 @@
 #include "graphics/surface.h"
 
 #include "buried/buried.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/livetext.h"
 #include "buried/resources.h"
@@ -61,7 +62,7 @@ bool LiveTextWindow::updateLiveText(const Common::String &text, bool notifyUser)
 		invalidateRect(Common::Rect(), false);
 		updateWindow();
 
-		// TODO: Set warning state to false
+		((GameUIWindow *)_parent)->setWarningState(false);
 		return true;
 	}
 
@@ -71,9 +72,8 @@ bool LiveTextWindow::updateLiveText(const Common::String &text, bool notifyUser)
 	invalidateRect(Common::Rect(), false);
 	updateWindow();
 
-	if (notifyUser) {
-		// TODO: Flash the warning light
-	}
+	if (notifyUser)
+		((GameUIWindow *)_parent)->flashWarningLight();
 
 	return true;
 }
@@ -85,7 +85,7 @@ bool LiveTextWindow::updateTranslationText(const Common::String &text, bool noti
 		invalidateRect(Common::Rect(), false);
 		updateWindow();
 
-		// TODO: Set warning state to false
+		((GameUIWindow *)_parent)->setWarningState(false);
 		return true;
 	}
 
@@ -98,7 +98,7 @@ bool LiveTextWindow::updateTranslationText(const Common::String &text, bool noti
 	invalidateRect(Common::Rect(), false);
 	updateWindow();
 
-	// TODO: Set warning state to false
+	((GameUIWindow *)_parent)->setWarningState(false);
 
 	return true;
 }


Commit: 09827199dad442fa4222dd3fb8a1e7d04c527f15
    https://github.com/scummvm/scummvm/commit/09827199dad442fa4222dd3fb8a1e7d04c527f15
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix a typo

Changed paths:
    engines/buried/navdata.h


diff --git a/engines/buried/navdata.h b/engines/buried/navdata.h
index f3a390846c..29944a1a08 100644
--- a/engines/buried/navdata.h
+++ b/engines/buried/navdata.h
@@ -35,7 +35,7 @@ struct Location {
 	int16 environment;
 	int16 node;
 	int16 facing;
-	int16 orientaton;
+	int16 orientation;
 	int16 depth;
 };
 


Commit: 2d38b79e0f24c8387e7bc860b0100b2eadd0d52a
    https://github.com/scummvm/scummvm/commit/2d38b79e0f24c8387e7bc860b0100b2eadd0d52a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Hook death/completion windows into FrameWindow

Changed paths:
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h


diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 0904496656..cf09b59001 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -29,7 +29,9 @@
 #include "graphics/surface.h"
 
 #include "buried/buried.h"
+#include "buried/complete.h"
 #include "buried/credits.h"
+#include "buried/death.h"
 #include "buried/frame_window.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -272,6 +274,34 @@ bool FrameWindow::startNewGame(const Common::String &fileName) {
 	return true;
 }
 
+bool FrameWindow::showDeathScene(int deathSceneIndex, const GlobalFlags &globalFlags) {
+	_gameInProgress = false;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+
+	delete _mainChildWindow;
+	_mainChildWindow = new DeathWindow(_vm, this, deathSceneIndex, globalFlags);
+	_mainChildWindow->showWindow(kWindowShow);
+	_mainChildWindow->invalidateWindow(false);
+
+	return true;
+}
+
+bool FrameWindow::showCompletionScene(const GlobalFlags &globalFlags) {
+	_gameInProgress = false;
+	_atMainMenu = false;
+
+	_vm->removeMouseMessages(this);
+
+	delete _mainChildWindow;
+	_mainChildWindow = new CompletionWindow(_vm, this, globalFlags);
+	_mainChildWindow->showWindow(kWindowShow);
+	_mainChildWindow->invalidateWindow(false);
+
+	return true;
+}
+
 bool FrameWindow::showCredits() {
 	_gameInProgress = false;
 	_atMainMenu = false;
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index ee0ef204f0..9160f9f5ab 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -31,6 +31,7 @@
 namespace Buried {
 
 class BuriedEngine;
+struct GlobalFlags;
 
 class FrameWindow : public Window {
 public:
@@ -46,8 +47,8 @@ public:
 	bool startNewGame(bool walkthrough = false, bool introMovie = false);
 	bool startNewGame(const Common::String &fileName);
 	// TODO: startNewGame with continue data
-	// TODO: showDeathScene
-	// TODO: showCompletionScene
+	bool showDeathScene(int deathSceneIndex, const GlobalFlags &globalFlags);
+	bool showCompletionScene(const GlobalFlags &globalFlags);
 	bool showCredits();
 	bool showOverview();
 	bool notifyUserOfFrameCycling();


Commit: 503645f379b5e96edefe30676d97e2b2d3c764a7
    https://github.com/scummvm/scummvm/commit/503645f379b5e96edefe30676d97e2b2d3c764a7
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add a method of querying the EXE version

For a couple of string differences

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/database.cpp
    engines/buried/database.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index d38c65e446..1deb037815 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -374,4 +374,8 @@ void BuriedEngine::setTransitionSpeed(int newSpeed) {
 	((FrameWindow *)_mainWindow)->setTransitionSpeed(newSpeed);
 }
 
+uint32 BuriedEngine::getVersion() {
+	return _mainEXE->getVersion();
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index fefe06e771..95527bf175 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -78,6 +78,7 @@ public:
 	Common::SeekableReadStream *getBookData(uint32 resourceID);
 	Common::SeekableReadStream *getFileBCData(uint32 resourceID);
 	Common::SeekableReadStream *getINNData(uint32 resourceID);
+	uint32 getVersion();
 
 	GraphicsManager *_gfx;
 	Database *_mainEXE;
@@ -138,6 +139,10 @@ private:
 	void pollForEvents();
 };
 
+// Macro for creating a version field
+#define MAKEVERSION(a, b, c, d) \
+	(((uint32)((a) & 0xFF) << 24) | ((uint32)((b) & 0xFF) << 16) | ((uint32)((c) & 0xFF) << 8) | ((uint32)((d) & 0xFF)))
+
 } // End of namespace Buried
 
 #endif
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index e2d1644d98..e6a1f9b57c 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -27,6 +27,7 @@
 #include "common/winexe_pe.h"
 #include "graphics/wincursor.h"
 
+#include "buried/buried.h"
 #include "buried/database.h"
 
 namespace Buried {
@@ -87,6 +88,11 @@ Common::SeekableReadStream *DatabaseNE::getResourceStream(const Common::String &
 	return _exe->getResource(resourceType, resourceID);
 }
 
+uint32 DatabaseNE::getVersion() {
+	Common::NEResources::VersionInfo versionInfo = _exe->getVersionInfo();
+	return MAKEVERSION(versionInfo.fileVersion[0], versionInfo.fileVersion[1], versionInfo.fileVersion[2], versionInfo.fileVersion[3]);
+}
+
 bool DatabaseNECompressed::load(const Common::String &fileName) {
 	return _exe->loadFromCompressedEXE(fileName);
 }
@@ -147,4 +153,9 @@ Common::SeekableReadStream *DatabasePE::getResourceStream(const Common::String &
 	return _exe->getResource(resourceType, resourceID);
 }
 
+uint32 DatabasePE::getVersion() {
+	// Not really needed, it should only be 1.1
+	return MAKEVERSION(1, 1, 0, 0);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/database.h b/engines/buried/database.h
index 42c4048703..355253177c 100644
--- a/engines/buried/database.h
+++ b/engines/buried/database.h
@@ -51,6 +51,7 @@ public:
 	virtual Common::SeekableReadStream *getBitmapStream(uint32 bitmapID) = 0;
 	virtual Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID) = 0;
 	virtual Common::SeekableReadStream *getResourceStream(const Common::String &resourceType, uint32 resourceID) = 0;
+	virtual uint32 getVersion() = 0;
 };
 
 /**
@@ -68,6 +69,7 @@ public:
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 	Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID);
 	Common::SeekableReadStream *getResourceStream(const Common::String &resourceType, uint32 resourceID);
+	uint32 getVersion();
 
 protected:
 	Common::NEResources *_exe;
@@ -93,6 +95,7 @@ public:
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 	Graphics::WinCursorGroup *getCursorGroup(uint32 cursorGroupID);
 	Common::SeekableReadStream *getResourceStream(const Common::String &resourceType, uint32 resourceID);
+	uint32 getVersion();
 
 private:
 	Common::PEResources *_exe;


Commit: 579d6540cce1fc9a8fa2153bc21bcc0b106c91b2
    https://github.com/scummvm/scummvm/commit/579d6540cce1fc9a8fa2153bc21bcc0b106c91b2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add death/completion window scoring strings

Changed paths:
    engines/buried/complete.cpp
    engines/buried/death.cpp
    engines/buried/resources.h


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index 9ec83510be..d61edd2e07 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -28,6 +28,7 @@
 #include "buried/complete.h"
 #include "buried/frame_window.h"
 #include "buried/graphics.h"
+#include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
 
@@ -132,15 +133,38 @@ CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, const Globa
 	int completionScore = 2000;
 	int totalScore = finalCriticalEvidenceScore + finalSupportingEvidenceScore + finalPuzzleScore + finalResearchScore + completionScore;
 
+	// Build the string buffers
 	if (_walkthroughMode) {
-		// TODO: This is a fucking mess between versions
+		if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) {
+			// HACK HACK HACK: Oh god. This is horrid.
+			Common::String stringResource = _vm->getString(IDS_COMPL_WALK_SCORE_DESC_TEMPL);
+			_scoringTextDescriptions = Common::String::format(stringResource.c_str(), criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw);
+			stringResource = _vm->getString(IDS_COMPL_WALK_SCORE_AMT_TEMPL);
+			_scoringTextScores = Common::String::format(stringResource.c_str(), finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore);
+		} else {
+			_scoringTextDescriptions = Common::String::format("Critical Evidence: %d / 4 x 1000\nSupporting Evidence: %d / 7 x 500\nPuzzles Solved: %d / 19 x 200\nResearch Bonus: %d / 15 x 100\nCompletion Bonus:",
+					criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw);
+			_scoringTextScores = Common::String::format("%d\n%d\n%d\n%d\n%d", finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore);
+		}
 	} else {
 		totalScore -= hintsScore;
 
-		// TODO: Another mess
+		if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) {
+			// HACK HACK HACK: Again, horrid.
+			Common::String stringResource = _vm->getString(IDS_COMPL_SCORE_DESC_TEMPL);
+			_scoringTextDescriptions = Common::String::format(stringResource.c_str(), criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw, hints);
+			stringResource = _vm->getString(IDS_COMPL_SCORE_AMT_TEMPL);
+			_scoringTextScores = Common::String::format(stringResource.c_str(), finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore, -hintsScore);
+		} else {
+			_scoringTextDescriptions = Common::String::format("Critical Evidence: %d / 4 x 1000\nSupporting Evidence: %d / 7 x 500\nPuzzles Solved: %d / 20 x 200\nResearch Bonus: %d / 15 x 100\nCompletion Bonus:\n\nHints: %d @ -50 ea.",
+					criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw, hints);
+			_scoringTextScores = Common::String::format("%d\n%d\n%d\n%d\n%d\n\n%d", finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore, -hintsScore);
+		}
 	}
 
-	// TODO: A third mess
+	// This would be a hack, but since it's just printing one number, I'm not
+	// loading that damned string too.
+	_scoringTextFinalScore = Common::String::format("%d", totalScore);
 
 	_vm->_sound->setAmbientSound();
 }
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index b1cfe8baca..41f6a8eb2c 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -176,15 +176,50 @@ DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex,
 	int completionScore = (deathSceneIndex == 60) ? 2000 : 0;
 	int totalScore = finalCriticalEvidenceScore + finalSupportingEvidenceScore + finalPuzzleScore + finalResearchScore + completionScore;
 
+	// Build the string buffers
 	if (_walkthroughMode) {
-		// TODO: This is a fucking mess between versions
+		if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) {
+			// HACK HACK HACK: More horridness.
+			Common::String stringResource = _vm->getString(IDS_DEATH_WALK_SCORE_DESC_TEMPL);
+			_scoringTextDescriptions = Common::String::format(stringResource.c_str(), criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw);
+			stringResource = _vm->getString(IDS_DEATH_WALK_SCORE_AMT_TEMPL);
+			_scoringTextScores = Common::String::format(stringResource.c_str(), finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore);
+		} else {
+			if (deathSceneIndex == 60) {
+				_scoringTextDescriptions = Common::String::format("Critical Evidence: %d / 4 x 1000\nSupporting Evidence: %d / 7 x 500\nPuzzles Solved: %d / 19 x 200\nResearch Bonus: %d / 15 x 100\nCompletion Bonus:",
+						criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw);
+				_scoringTextScores = Common::String::format("%d\n%d\n%d\n%d\n%d", finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore);
+			} else {
+				_scoringTextDescriptions = Common::String::format("Critical Evidence: %d / 4 x 1000\nSupporting Evidence: %d / 7 x 500\nPuzzles Solved: %d / 19 x 200\nResearch Bonus: %d / 15 x 100",
+						criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw);
+				_scoringTextScores = Common::String::format("%d\n%d\n%d\n%d", finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore);
+			}
+		}
 	} else {
 		totalScore -= hintsScore;
 
-		// TODO: Another mess
+		if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) {
+			// HACK HACK HACK: Did I mention this was terrible?
+			Common::String stringResource = _vm->getString(IDS_DEATH_SCORE_DESC_TEMPL);
+			_scoringTextDescriptions = Common::String::format(stringResource.c_str(), criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw, hints);
+			stringResource = _vm->getString(IDS_DEATH_SCORE_AMT_TEMPL);
+			_scoringTextScores = Common::String::format(stringResource.c_str(), finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore, -hintsScore);
+		} else {
+			if (deathSceneIndex == 60) {
+				_scoringTextDescriptions = Common::String::format("Critical Evidence: %d / 4 x 1000\nSupporting Evidence: %d / 7 x 500\nPuzzles Solved: %d / 20 x 200\nResearch Bonus: %d / 15 x 100\nCompletion Bonus:\n\nHints: %d @ -50 ea.",
+						criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw, hints);
+				_scoringTextScores = Common::String::format("%d\n%d\n%d\n%d\n%d\n\n%d", finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, completionScore, -hintsScore);
+			} else {
+				_scoringTextDescriptions = Common::String::format("Critical Evidence: %d / 4 x 1000\nSupporting Evidence: %d / 7 x 500\nPuzzles Solved: %d / 20 x 200\nResearch Bonus: %d / 15 x 100\n\n\nHints: %d @ -50 ea.",
+						criticalEvidence, supportingEvidence, puzzlesSolved, researchBonusRaw, hints);
+				_scoringTextScores = Common::String::format("%d\n%d\n%d\n%d\n\n\n%d", finalCriticalEvidenceScore, finalSupportingEvidenceScore, finalPuzzleScore, finalResearchScore, -hintsScore);
+			}
+		}
 	}
 
-	// TODO: A third mess
+	// This would be a hack, but since it's just printing one number, I'm not
+	// loading that damned string too.
+	_scoringTextFinalScore = Common::String::format("%d", totalScore);
 
 	_vm->_sound->setAmbientSound();
 }
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 57e06227b9..99759ed537 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -342,6 +342,18 @@ namespace Buried {
 #define IDES_ITEM_TITLE_BASE			8192
 #define IDES_ITEM_DESC_BASE				8256
 
+// 1.04+:
+#define IDS_COMPL_WALK_SCORE_DESC_TEMPL 9031
+#define IDS_DEATH_WALK_SCORE_DESC_TEMPL 9031
+#define IDS_COMPL_WALK_SCORE_AMT_TEMPL  9032
+#define IDS_DEATH_WALK_SCORE_AMT_TEMPL  9032
+#define IDS_COMPL_SCORE_DESC_TEMPL      9033
+#define IDS_DEATH_SCORE_DESC_TEMPL      9033
+#define IDS_COMPL_SCORE_AMT_TEMPL       9034
+#define IDS_DEATH_SCORE_AMT_TEMPL       9034
+#define IDS_COMPL_FINAL_SCORE_TEMPL     9035
+#define IDS_DEATH_FINAL_SCORE_TEMPL     9035
+
 #define IDES_FILENAME_BASE              17408
 #define IDES_STRING_BASE                21504
 


Commit: 4bba4a34b308525abaf2635f347cb1822cbde433
    https://github.com/scummvm/scummvm/commit/4bba4a34b308525abaf2635f347cb1822cbde433
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fixed global flags for the louvre research flag

Ugh. Ugh. Double ugh.

Changed paths:
    engines/buried/complete.cpp
    engines/buried/death.cpp
    engines/buried/global_flags.h


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index d61edd2e07..04f892e12a 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -92,6 +92,7 @@ CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, const Globa
 	CHECK_PUZZLE_FLAG(scoreDefeatedIcarus);
 
 	int researchBonusRaw = 0;
+	CHECK_RESEARCH_FLAG(scoreResearchINNLouvreReport); // > v1.01
 	CHECK_RESEARCH_FLAG(scoreResearchINNHighBidder);
 	CHECK_RESEARCH_FLAG(scoreResearchINNAppeal);
 	CHECK_RESEARCH_FLAG(scoreResearchINNUpdate);
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index 41f6a8eb2c..4e4cedd452 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -135,6 +135,7 @@ DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex,
 	CHECK_PUZZLE_FLAG(scoreDefeatedIcarus);
 
 	int researchBonusRaw = 0;
+	CHECK_RESEARCH_FLAG(scoreResearchINNLouvreReport); // > v1.01
 	CHECK_RESEARCH_FLAG(scoreResearchINNHighBidder);
 	CHECK_RESEARCH_FLAG(scoreResearchINNAppeal);
 	CHECK_RESEARCH_FLAG(scoreResearchINNUpdate);
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index 22ed2e66d5..d4ea7803f3 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -35,6 +35,7 @@ namespace Buried {
 // (There clearly aren't enough variables)
 // For double-fun, they still need to be accessed by index for AI support
 // -> It therefore needs to be packed (Yes, this is totally evil)
+// This is all horrible, really. Avert your eyes.
 
 #include "common/pack-start.h"
 
@@ -286,22 +287,30 @@ struct GlobalFlags {
 	byte scoreTransportToKrynn;         // 317
 	byte scoreGotKrynnArtifacts;        // 318
 	byte scoreDefeatedIcarus;           // 319
-	byte scoreResearchINNHighBidder;    // 320
-	byte scoreResearchINNAppeal;        // 321
-	byte scoreResearchINNUpdate;        // 322
-	byte scoreResearchINNJumpsuit;      // 323
-	byte scoreResearchBCJumpsuit;       // 324
-	byte scoreResearchMichelle;         // 325
-	byte scoreResearchMichelleBkg;      // 326
-	byte scoreResearchLensFilter;       // 327
-	byte scoreResearchCastleFootprint;  // 328
-	byte scoreResearchDaVinciFootprint; // 329
-	byte scoreResearchMorphSculpture;   // 330
-	byte scoreResearchEnvironCart;      // 331
-	byte scoreResearchAgent3Note;       // 332
-	byte scoreResearchAgent3DaVinci;    // 333
-	uint16 scoreHintsTotal;             // 334-335
-	byte unused3[54];                   // 336-389
+
+	// clone2727 would like to take time away from his busy schedule
+	// to describe how broken this next section is. This data was modified
+	// between 1.01 and 1.03, without changing the saved game version
+	// field -- just to add the Louvre research boolean. That's really
+	// unacceptable. I'll have the 1.01 offsets in parentheses.
+	byte scoreResearchINNLouvreReport;  // 320 (---)
+	byte scoreResearchINNHighBidder;    // 321 (320)
+	byte scoreResearchINNAppeal;        // 322 (321)
+	byte scoreResearchINNUpdate;        // 323 (322)
+	byte scoreResearchINNJumpsuit;      // 324 (323)
+	byte scoreResearchBCJumpsuit;       // 325 (324)
+	byte scoreResearchMichelle;         // 326 (325)
+	byte scoreResearchMichelleBkg;      // 327 (326)
+	byte scoreResearchLensFilter;       // 328 (327)
+	byte scoreResearchCastleFootprint;  // 329 (328)
+	byte scoreResearchDaVinciFootprint; // 330 (329)
+	byte scoreResearchMorphSculpture;   // 331 (330)
+	byte scoreResearchEnvironCart;      // 332 (331)
+	byte scoreResearchAgent3Note;       // 333 (332)
+	byte scoreResearchAgent3DaVinci;    // 334 (333)
+	uint16 scoreHintsTotal;             // 335-336 (334-335)
+	byte unused3[53];                   // 337-389 (336-389)
+
 	byte genJumpCastleBriefing;         // 390
 	byte genJumpMayanBriefing;          // 391
 	byte genJumpDaVinciBriefing;        // 392


Commit: a966f157afc9596fb8e5164736038c2691c30714
    https://github.com/scummvm/scummvm/commit/a966f157afc9596fb8e5164736038c2691c30714
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add detection for the Japanese version

Changed paths:
    engines/buried/buried.cpp
    engines/buried/detection.cpp
    engines/buried/graphics.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 1deb037815..24650815a0 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -24,8 +24,10 @@
  */
 
 #include "common/scummsys.h"
+#include "common/config-manager.h"
 #include "common/error.h"
 #include "common/events.h"
+#include "common/fs.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "engines/util.h"
@@ -50,6 +52,9 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_mainWindow = 0;
 	_focusedWindow = 0;
 	_captureWindow = 0;
+
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2);
 }
 
 BuriedEngine::~BuriedEngine() {
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 5755a5340b..f7568cd67f 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -85,7 +85,7 @@ static const PlainGameDescriptor buriedGames[] = {
 namespace Buried {
 
 static const BuriedGameDescription gameDescriptions[] = {
-	// Windows 3.11 8BPP
+	// English Windows 3.11 8BPP
 	// Installed
 	// v1.01
 	{
@@ -104,7 +104,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Windows 3.11 24BPP
+	// English Windows 3.11 24BPP
 	// Installed
 	// v1.01
 	{
@@ -123,7 +123,45 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Windows 3.11 8BPP
+	// Japanese Windows 3.11 8BPP
+	// Installed
+	// v1.051
+	{
+		{
+			"buried",
+			"v1.051 8BPP",
+			{
+				{ "BIT816.EXE",  0, "decbf9a7d91803525137ffd980d16708", 1163264 },
+				{ "BIT8LIB.DLL", 0, "f5ccde0efccb95afe902627a35262568", 2418816 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::JA_JPN,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Japanese Windows 3.11 24BPP
+	// Installed
+	// v1.051
+	{
+		{
+			"buried",
+			"v1.051 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "9435b9a40e3ac83e6fa1e83caaf57792", 1157632 },
+				{ "BIT24LIB.DLL", 0, "4d55802259d9648b9aa396461bfd53a3", 6576896 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::JA_JPN,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// English Windows 3.11 8BPP
 	// Not Installed
 	// v1.01
 	{
@@ -142,7 +180,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Windows 3.11 24BPP
+	// English Windows 3.11 24BPP
 	// Not Installed
 	// v1.01
 	{
@@ -161,7 +199,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Windows 95 8BPP
+	// English Windows 95 8BPP
 	// v1.1
 	{
 		{
@@ -179,7 +217,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Windows 95 24BPP
+	// English Windows 95 24BPP
 	// v1.1
 	{
 		{
@@ -197,7 +235,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Demo 8BPP
+	// English Windows Demo 8BPP
 	{
 		{
 			"buried",
@@ -210,7 +248,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
-	// Demo 24BPP
+	// English Windows Demo 24BPP
 	{
 		{
 			"buried",
@@ -226,6 +264,12 @@ static const BuriedGameDescription gameDescriptions[] = {
 	{ AD_TABLE_END_MARKER }
 };
 
+static const char *directoryGlobs[] = {
+	"win31",
+	"manual",
+	0
+};
+
 } // End of namespace Buried
 
 
@@ -234,6 +278,8 @@ public:
 	BuriedMetaEngine() : AdvancedMetaEngine(Buried::gameDescriptions, sizeof(Buried::BuriedGameDescription), buriedGames) {
 		_singleid = "buried";
 		_flags = kADFlagUseExtraAsHint;
+		_maxScanDepth = 3;
+		_directoryGlobs = Buried::directoryGlobs;
 	}
 
 	virtual const char *getName() const {
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 61ffa1ee9c..6048b6b664 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -708,7 +708,7 @@ Common::SeekableReadStream *GraphicsManager::findMSGothicStream() const {
 	}
 #elif defined(MACOSX)
 	// Attempt to load the font from MS Gothic.ttf
-	Common::FSNode fontPath(Common::String::format("/Library/Fonts/MS Gothic.ttf"));
+	Common::FSNode fontPath(Common::String::format("/Library/Fonts/Microsoft/MS Gothic.ttf"));
 
 	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
 		stream = fontPath.createReadStream();


Commit: 1aebefdebbceea0757adb7abb8f6359e99398cfd
    https://github.com/scummvm/scummvm/commit/1aebefdebbceea0757adb7abb8f6359e99398cfd
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Update Japanese font code

Changed paths:
    engines/buried/complete.cpp
    engines/buried/complete.h
    engines/buried/death.cpp
    engines/buried/death.h
    engines/buried/graphics.cpp
    engines/buried/inventory_info.cpp
    engines/buried/inventory_info.h
    engines/buried/inventory_window.cpp
    engines/buried/inventory_window.h
    engines/buried/livetext.cpp
    engines/buried/livetext.h


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index 04f892e12a..566e9e304d 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -65,8 +65,11 @@ CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, const Globa
 
 	_timer = setTimer(1000);
 
-	_textFontA = _vm->_gfx->createFont(14);
-	_textFontB = _vm->_gfx->createFont(20, true);
+	_fontHeightA = (_vm->getLanguage() == Common::JA_JPN) ? 12 : 14;
+	_textFontA = _vm->_gfx->createFont(_fontHeightA);
+
+	_fontHeightB = 20;
+	_textFontB = _vm->_gfx->createFont(_fontHeightB, true);
 
 	_walkthroughMode = _globalFlags.generalWalkthroughMode != 0;
 
@@ -197,24 +200,24 @@ void CompletionWindow::onPaint() {
 		uint32 textColor = _vm->_gfx->getColor(102, 204, 153);
 		Common::String firstBlockText = _vm->getString(2100);
 		Common::Rect firstBlockRect(10, 54, 283, 86);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlockText, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, 14);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlockText, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, _fontHeightA);
 
 		// Draw the cause text
 		Common::String secondBlockText = _vm->getString(2102);
 		Common::Rect secondBlockRect(10, 120, 283, 215);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlockText, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, 14);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlockText, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, _fontHeightA);
 
 		// Description text
 		Common::Rect scoringTextRect(10, 248, 283, 378);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, 14);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, _fontHeightA);
 
 		// Scores
 		textColor = _vm->_gfx->getColor(255, 255, 51);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, 14, true);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, _fontHeightA, true);
 
 		// Total score
 		Common::Rect finalScoreRect(122, 386, 283, 401);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), textColor, 20, true);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), textColor, _fontHeightB, true);
 	}
 }
 
diff --git a/engines/buried/complete.h b/engines/buried/complete.h
index d8023de5ca..eb46c8b320 100644
--- a/engines/buried/complete.h
+++ b/engines/buried/complete.h
@@ -57,6 +57,7 @@ private:
 	GlobalFlags _globalFlags;
 	Graphics::Font *_textFontA;
 	Graphics::Font *_textFontB;
+	int _fontHeightA, _fontHeightB;
 	bool _walkthroughMode;
 
 	Common::String _scoringTextDescriptions;
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index 4e4cedd452..45f9c8b790 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -108,8 +108,11 @@ DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex,
 		break;
 	}
 
-	_textFontA = _vm->_gfx->createFont(14);
-	_textFontB = _vm->_gfx->createFont(20, true);
+	_fontHeightA = (_vm->getLanguage() == Common::JA_JPN) ? 12 : 14;
+	_textFontA = _vm->_gfx->createFont(_fontHeightA);
+
+	_fontHeightB = 20;
+	_textFontB = _vm->_gfx->createFont(_fontHeightB, true);
 
 	_walkthroughMode = _globalFlags.generalWalkthroughMode != 0;
 
@@ -273,21 +276,21 @@ void DeathWindow::onPaint() {
 	uint32 textColor = _vm->_gfx->getColor(153, 102, 204);
 	Common::String firstBlock = _vm->getString(IDS_DEATH_SCENE_MESSAGE_TEXT_BASE + _deathSceneIndex * 5);
 	Common::Rect firstBlockRect(10, 54, 283, 86);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlock, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, 14);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlock, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, _fontHeightA);
 
 	Common::String secondBlock = _vm->getString(IDS_DEATH_SCENE_MESSAGE_TEXT_BASE + _deathSceneIndex * 5 + 1);
 	Common::Rect secondBlockRect(10, 120, 283, 215);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlock, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, 14);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlock, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, _fontHeightA);
 
 	Common::Rect scoringDescRect(10, 248, 283, 378);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, 14);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA);
 
 	textColor = _vm->_gfx->getColor(212, 109, 0);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, 14, true);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA, true);
 
 	// CHECKME: This does center vertical alignment, so check the y coordinates
 	Common::Rect finalTextScoreRect(122, 386, 283, 401);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), textColor, 20, true);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), textColor, _fontHeightB, true);
 }
 
 bool DeathWindow::onEraseBackground() {
diff --git a/engines/buried/death.h b/engines/buried/death.h
index adbb53419d..471f276fed 100644
--- a/engines/buried/death.h
+++ b/engines/buried/death.h
@@ -63,6 +63,7 @@ private:
 	bool _lightOn;
 	Graphics::Font *_textFontA;
 	Graphics::Font *_textFontB;
+	int _fontHeightA, _fontHeightB;
 	bool _walkthroughMode;
 
 	Common::String _scoringTextDescriptions;
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 6048b6b664..5e50caeffb 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -150,12 +150,10 @@ static const uint32 s_codePage1252[256] = {
 #undef NOT_REQUIRED
 
 Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
-	// MS Gothic for the Japanese version (please buy for clone2727)
+	// MS Gothic for the Japanese version
 	// Arial or Arial Bold for everything else
-	if (_vm->getLanguage() == Common::JA_JPN) {
-		assert(!bold);
+	if (_vm->getLanguage() == Common::JA_JPN)
 		return createMSGothicFont(size);
-	}
 
 	return createArialFont(size, bold);
 }
@@ -675,13 +673,28 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size) const {
 	if (!stream)
 		error("Failed to find MS Gothic font");
 
-	// TODO: Map the heights needed to point sizes
+	switch (size) {
+	case 10:
+		size = 7;
+		break;		
+	case 11:
+		size = 8;
+		break;
+	case 12:
+		size = 9;
+		break;
+	case 20:
+		size = 16;
+		break;
+	default:
+		error("Unknown MS Gothic font size %d", size);
+	}
 
 	// TODO: Make the monochrome mode optional
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
 	// TODO: shift-jis codepage (932) and mapping
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, !_vm->isTrueColor(), s_codePage1252);
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 
 	if (!font)
 		error("Failed to load MS Gothic font");
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index fde878c42a..4e3cd90af7 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -41,7 +41,9 @@ InventoryInfoWindow::InventoryInfoWindow(BuriedEngine *vm, Window *parent, int c
 	_spinStart = 0;
 	_spinLength = 70;
 
-	_textFont = _vm->_gfx->createFont(14);
+	_fontHeight = (_vm->getLanguage() == Common::JA_JPN) ? 11 : 14;
+	_textFont = _vm->_gfx->createFont(_fontHeight);
+
 	_rect = Common::Rect(0, 0, 432, 189);
 	_videoWindow = new VideoWindow(_vm, this);
 
diff --git a/engines/buried/inventory_info.h b/engines/buried/inventory_info.h
index 69677d15f4..373626f356 100644
--- a/engines/buried/inventory_info.h
+++ b/engines/buried/inventory_info.h
@@ -52,6 +52,7 @@ public:
 
 private:
 	Graphics::Font *_textFont;
+	int _fontHeight;
 	int _currentItemID;
 	VideoWindow *_videoWindow;
 	int32 _spinStart;
diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index 65c78a1da8..11655c0fa4 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -75,7 +75,8 @@ InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 
 	rebuildPreBuffer();
 
-	_textFont = _vm->_gfx->createFont(14);
+	_fontHeight = (_vm->getLanguage() == Common::JA_JPN) ? 10 : 14;
+	_textFont = _vm->_gfx->createFont(_fontHeight);
 
 	_rect = Common::Rect(182, 375, 450, 454);
 	_curCursor = (int)kCursorNone;
@@ -263,6 +264,13 @@ void InventoryWindow::onPaint() {
 	for (int i = -2; i < 3; i++) {
 		if ((i + _curItem) >= 0 && (i + _curItem) < (int)_itemArray.size()) {
 			Common::Rect textRect = Common::Rect(120, (i + 2) * 13 + 8, 254, (i + 3) * 13 + 8);
+
+			if (_vm->getLanguage() == Common::JA_JPN) {
+				// Japanese version is shifted by one pixel
+				textRect.top++;
+				textRect.bottom++;
+			}
+
 			textRect.translate(absoluteRect.left, absoluteRect.top);
 			Common::String text = _vm->getString(IDES_ITEM_TITLE_BASE + _itemArray[_curItem + i]);
 			_textFont->drawString(_vm->_gfx->getScreen(), text, textRect.left, textRect.top, textRect.width(), textColor);
diff --git a/engines/buried/inventory_window.h b/engines/buried/inventory_window.h
index 12c6151f87..d305303b98 100644
--- a/engines/buried/inventory_window.h
+++ b/engines/buried/inventory_window.h
@@ -71,6 +71,7 @@ public:
 
 private:
 	Graphics::Font *_textFont;
+	int _fontHeight;
 	Graphics::Surface *_background;
 	Common::Array<int> _itemArray;
 	int _curItem;
diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index b6138bb5d3..6aa62dc7b2 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -39,7 +39,8 @@ LiveTextWindow::LiveTextWindow(BuriedEngine *vm, Window *parent) : Window(vm, pa
 	_textTranslation = false;
 
 	// Create font
-	_font = _vm->_gfx->createFont(14);
+	_fontHeight = (_vm->getLanguage() == Common::JA_JPN) ? 12 : 14;
+	_font = _vm->_gfx->createFont(_fontHeight);
 
 	// Create window
 	_rect = Common::Rect(137, 21, 447, 87);
@@ -115,7 +116,7 @@ void LiveTextWindow::onPaint() {
 
 	// Draw the text on top of that
 	if (!_text.empty())
-		_vm->_gfx->renderText(surface, _font, _text, 30, 4, 270, _vm->_gfx->getColor(212, 109, 0), 14);
+		_vm->_gfx->renderText(surface, _font, _text, 30, 4, 270, _vm->_gfx->getColor(212, 109, 0), _fontHeight);
 
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(surface, absoluteRect.left, absoluteRect.top);
diff --git a/engines/buried/livetext.h b/engines/buried/livetext.h
index 864d055cb1..73751419fa 100644
--- a/engines/buried/livetext.h
+++ b/engines/buried/livetext.h
@@ -51,6 +51,7 @@ public:
 
 private:
 	Graphics::Font *_font;
+	int _fontHeight;
 	bool _textTranslation;
 	Common::String _text;
 };


Commit: 9f12e369177c9a4a9d269f565cc456d4a1060468
    https://github.com/scummvm/scummvm/commit/9f12e369177c9a4a9d269f565cc456d4a1060468
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add detection for the German v1.05 version

Changed paths:
    engines/buried/detection.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index f7568cd67f..f92a721058 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -199,6 +199,44 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
+	// German Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "a039e9f1c569acc1cf80f6b549ce1e37", 1178112 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::DE_DEU,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// German Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "fbfd453cced2b14069fa32e3c8dd69e2", 1172480 },
+				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::DE_DEU,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
 	// English Windows 95 8BPP
 	// v1.1
 	{


Commit: 9c0da1c36b0d83b5a34d05f64356cd43e053d2e5
    https://github.com/scummvm/scummvm/commit/9c0da1c36b0d83b5a34d05f64356cd43e053d2e5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the scene view class

Changed paths:
  A engines/buried/environ/scene_base.cpp
  A engines/buried/environ/scene_base.h
  A engines/buried/scene_view.cpp
  A engines/buried/scene_view.h
    engines/buried/biochip_right.cpp
    engines/buried/biochip_view.cpp
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h
    engines/buried/gameui.cpp
    engines/buried/gameui.h
    engines/buried/graphics.h
    engines/buried/inventory_info.cpp
    engines/buried/inventory_window.cpp
    engines/buried/inventory_window.h
    engines/buried/module.mk
    engines/buried/navarrow.cpp
    engines/buried/navarrow.h
    engines/buried/navdata.h
    engines/buried/resources.h


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index d2a859ac8b..1e0a806954 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -25,12 +25,15 @@
 
 #include "buried/buried.h"
 #include "buried/biochip_right.h"
+#include "buried/biochip_view.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
+#include "buried/inventory_window.h"
 #include "buried/livetext.h"
 #include "buried/navarrow.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
 
@@ -61,9 +64,8 @@ bool BioChipRightWindow::changeCurrentBioChip(int bioChipID) {
 	if (bioChipID != kItemBioChipTranslate)
 		((GameUIWindow *)_parent)->_liveTextWindow->translateBiochipClosing();
 
-	// TODO
-	//if (bioChipID != kItemBioChipEvidence)
-	//	;
+	if (bioChipID != kItemBioChipEvidence)
+		((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcLocateEnabled = 0;
 
 	if (_bioChipViewWindow)
 		destroyBioChipViewWindow();
@@ -71,7 +73,7 @@ bool BioChipRightWindow::changeCurrentBioChip(int bioChipID) {
 	_curBioChip = bioChipID;
 	_status = 0;
 
-	// TODO: Set the translate enabled flag to false
+	((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcTranslateEnabled = 0;
 
 	invalidateWindow(false);
 	return true;
@@ -81,14 +83,15 @@ bool BioChipRightWindow::showBioChipMainView() {
 	if (_bioChipViewWindow)
 		return false;
 
-	// TODO: Notify the view of the change
+	((GameUIWindow *)_parent)->_sceneViewWindow->bioChipWindowDisplayed(true);
 	_vm->_sound->timerCallback();
 
-	// TODO: Destroy info window
-	// TODO: Destroy burned letter window
+	((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
+	((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
 	_vm->_sound->timerCallback();
 
-	// TODO: BioChip main view window (child to scene view)
+	_bioChipViewWindow = new BioChipMainViewWindow(_vm, ((GameUIWindow *)_parent)->_sceneViewWindow, _curBioChip);
+	_bioChipViewWindow->showWindow(kWindowShow);
 	_vm->_sound->timerCallback();
 
 	return true;
@@ -103,7 +106,7 @@ bool BioChipRightWindow::destroyBioChipViewWindow() {
 	_bioChipViewWindow = 0;
 	_vm->_sound->timerCallback();
 
-	// TODO: Signal the change to the scene view window
+	((GameUIWindow *)_parent)->_sceneViewWindow->bioChipWindowDisplayed(false);
 
 	if (_status == 1) {
 		_status = 0;
@@ -121,7 +124,7 @@ void BioChipRightWindow::sceneChanged() {
 void BioChipRightWindow::disableEvidenceCapture() {
 	if (_curBioChip == kItemBioChipEvidence) {
 		_status = 0;
-		// TODO: Disable locate flag
+		((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcLocateEnabled = 0;
 		invalidateWindow(false);
 	}
 }
@@ -145,9 +148,8 @@ void BioChipRightWindow::onPaint() {
 
 	switch (_curBioChip) {
 	case kItemBioChipAI: {
-		// TODO: Check scene view for help/information comment
-		bool helpComment = _forceHelp || false;
-		bool information = _forceComment || false;
+		bool helpComment = _forceHelp || ((GameUIWindow *)_parent)->_sceneViewWindow->checkForAIComment(AI_COMMENT_TYPE_HELP);
+		bool information = _forceComment || ((GameUIWindow *)_parent)->_sceneViewWindow->checkForAIComment(AI_COMMENT_TYPE_INFORMATION);
 
 		if (helpComment) {
 			if (information)
@@ -190,10 +192,19 @@ void BioChipRightWindow::onPaint() {
 		else
 			bitmapResID = (_status == 0) ? 12 : 13;
 		break;
-	case kItemBioChipJump:
-		// TODO
+	case kItemBioChipJump: {
+		Location currentLocation;
 		bitmapResID = 14;
+
+		if (_status != 0)
+			bitmapResID += 2;
+
+		if (((GameUIWindow *)_parent)->_sceneViewWindow->getCurrentSceneLocation(currentLocation))
+			if (currentLocation.timeZone == 4)
+				bitmapResID++;
+
 		break;
+	}
 	case kItemBioChipTranslate:
 		bitmapResID = (_status == 0) ? 18 : 19;
 		break;
@@ -222,7 +233,11 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 
 	switch (_curBioChip) {
 	case kItemBioChipAI:
-		// TODO
+		if (upperButton.contains(point) && ((GameUIWindow *)_parent)->_sceneViewWindow->playAIComment(AI_COMMENT_TYPE_HELP))
+			invalidateWindow(false);
+
+		if (lowerButton.contains(point) && ((GameUIWindow *)_parent)->_sceneViewWindow->playAIComment(AI_COMMENT_TYPE_INFORMATION))
+			invalidateWindow(false);
 		break;
 	case kItemBioChipCloak:
 		if (upperButton.contains(point)) {
@@ -251,10 +266,18 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 
 				invalidateWindow(false);
 
-				// TODO: Set cloaking flag
-				// TODO: Disable some controls
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcCloakingEnabled = 1;
+				((GameUIWindow *)_parent)->_inventoryWindow->enableWindow(false);
+				((GameUIWindow *)_parent)->_sceneViewWindow->enableWindow(false);
 				((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(false);
-				// TODO: Change live text
+
+				Location currentLocation;
+				((GameUIWindow *)_parent)->_sceneViewWindow->getCurrentSceneLocation(currentLocation);
+
+				if (currentLocation.timeZone == 10)
+					((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_CLOAK_BIOCHIP_AUTO_ACTIVATE));
+				else
+					((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_CLOAK_BIOCHIP_ACTIVATE));
 			} else {
 				_status = 0;
 
@@ -278,11 +301,11 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 
 				invalidateWindow(false);
 
-				// TODO: Set cloaking flag
-				// TODO: Enable navigation
-				// TODO: Enable inventory controls
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcCloakingEnabled = 0;
+				((GameUIWindow *)_parent)->_inventoryWindow->enableWindow(true);
+				((GameUIWindow *)_parent)->_sceneViewWindow->enableWindow(true);
 				((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
-				// TODO: Change live text
+				((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_CLOAK_BIOCHIP_DEACTIVATE));
 			}
 		}
 		break;
@@ -290,12 +313,12 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 		if (upperButton.contains(point)) {
 			if (_status == 1) {
 				_status = 0;
-				// TODO
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcLocateEnabled = 0;
 				invalidateWindow(false);
 			} else {
 				destroyBioChipViewWindow();
 				_status = 1;
-				// TODO
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcLocateEnabled = 1;
 				invalidateWindow(false);
 			}
 		} else if (lowerButton.contains(point)) {
@@ -306,7 +329,7 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			} else {
 				showBioChipMainView();
 				_status = 2;
-				// TODO
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcLocateEnabled = 0;
 				invalidateWindow(false);
 			}
 		}
@@ -349,7 +372,17 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 				invalidateWindow(false);
 			}
 		} else if (lowerButton.contains(point)) {
-			// TODO
+			Location currentLocation;
+			if (((GameUIWindow *)_parent)->_sceneViewWindow->getCurrentSceneLocation(currentLocation)) {
+				if (currentLocation.timeZone != 4) {
+					_status = 0;
+					destroyBioChipViewWindow();
+					((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
+					((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
+					invalidateWindow(false);
+					((GameUIWindow *)_parent)->_sceneViewWindow->timeSuitJump(4);
+				}
+			}
 		}
 		break;
 	case kItemBioChipTranslate:
@@ -358,13 +391,15 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 				_status = 1;
 				invalidateWindow(false);
 
-				// TODO: Reset global flag
-				// TODO: Redraw the scene window
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcTranslateEnabled = 1;
+				((GameUIWindow *)_parent)->_sceneViewWindow->invalidateWindow(false);
 			} else {
 				_status = 0;
+				invalidateWindow(false);
 
-				// TODO: Reset global flag
-				// TODO: Redraw the scene window
+				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcTranslateEnabled = 0;
+				((GameUIWindow *)_parent)->_liveTextWindow->translateBiochipClosing();
+				((GameUIWindow *)_parent)->_sceneViewWindow->invalidateWindow(false);
 			}
 		}
 		break;
diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index c00a9e1bbc..6e0782ca74 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -30,6 +30,7 @@
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 
 #include "common/stream.h"
 #include "graphics/surface.h"
@@ -142,8 +143,7 @@ void InterfaceBioChipViewWindow::onPaint() {
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(_background, absoluteRect.left, absoluteRect.top);
 
-	// TODO
-	if (true)
+	if (((SceneViewWindow *)_parent)->getCyclingStatus())
 		_vm->_gfx->blit(_cycleCheck, absoluteRect.left + 13, absoluteRect.top + 144);
 
 	if (_caret)
@@ -180,7 +180,15 @@ void InterfaceBioChipViewWindow::onLButtonUp(const Common::Point &point, uint fl
 		// TODO
 		break;
 	case REGION_FLICKER:
-		// TODO
+		if (_flicker.contains(point)) {
+			if (((SceneViewWindow *)(_parent->getParent()))->getCyclingStatus()) {
+				((SceneViewWindow *)(_parent->getParent()))->enableCycling(false);
+				invalidateRect(_flicker, false);
+			} else {
+				((SceneViewWindow *)(_parent->getParent()))->enableCycling(true);
+				invalidateRect(_flicker, false);
+			}
+		}
 		break;
 	case REGION_TRANSITION_SPEED:
 		_transLocation = CLIP<int>(point.x - 14, 0, 150);
@@ -289,7 +297,12 @@ void FilesBioChipViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 		_curPage = page.nextButtonPageIndex;
 		invalidateWindow(false);
 
-		// TODO: Score check
+		if (_curPage == 6)
+			((SceneViewWindow *)(_parent->getParent()))->getGlobalFlags().scoreResearchBCJumpsuit = 1;
+		else if (_curPage == 21)
+			((SceneViewWindow *)(_parent->getParent()))->getGlobalFlags().scoreResearchMichelle = 1;
+		else if (_curPage == 31)
+			((SceneViewWindow *)(_parent->getParent()))->getGlobalFlags().scoreResearchMichelleBkg = 1;
 
 		return;
 	}
diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 24650815a0..e8d6783f05 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -37,6 +37,7 @@
 #include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/message.h"
+#include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
 #include "buried/window.h"
@@ -383,4 +384,20 @@ uint32 BuriedEngine::getVersion() {
 	return _mainEXE->getVersion();
 }
 
+Common::String BuriedEngine::getFilePath(int timeZone, int environment, int fileOffset) {
+	return getFilePath(RESID_FILENAMES_BASE + RESOFFSET_FILENAME_TIMEZONE * timeZone + RESOFFSET_FILENAME_ENVIRON * environment + fileOffset);
+}
+
+uint32 BuriedEngine::computeNavDBResourceID(int timeZone, int environment) {
+	return RESID_NAVDB_BASE + RESOFFSET_NAVDB_TIMEZONE * timeZone + environment;
+}
+
+uint32 BuriedEngine::computeAnimDBResourceID(int timeZone, int environment) {
+	return RESID_ANIMDB_BASE + RESOFFSET_ANIMDB_TIMEZONE * timeZone + environment; 
+}
+
+uint32 BuriedEngine::computeAIDBResourceID(int timeZone, int environment) {
+	return RESID_AI_DB_BASE + RESOFFSET_AI_DB_TIMEZONE * timeZone + environment;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 95527bf175..fcc3015419 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -69,6 +69,7 @@ public:
 	// Resources
 	Common::String getString(uint32 stringID);
 	Common::String getFilePath(uint32 stringID);
+	Common::String getFilePath(int timeZone, int environment, int fileOffset);
 	Common::SeekableReadStream *getBitmapStream(uint32 bitmapID);
 	Common::SeekableReadStream *getNavData(uint32 resourceID);
 	Common::SeekableReadStream *getSndData(uint32 resourceID);
@@ -79,6 +80,9 @@ public:
 	Common::SeekableReadStream *getFileBCData(uint32 resourceID);
 	Common::SeekableReadStream *getINNData(uint32 resourceID);
 	uint32 getVersion();
+	uint32 computeNavDBResourceID(int timeZone, int environment);
+	uint32 computeAnimDBResourceID(int timeZone, int environment);
+	uint32 computeAIDBResourceID(int timeZone, int environment);
 
 	GraphicsManager *_gfx;
 	Database *_mainEXE;
diff --git a/engines/buried/environ/scene_base.cpp b/engines/buried/environ/scene_base.cpp
new file mode 100644
index 0000000000..917b896649
--- /dev/null
+++ b/engines/buried/environ/scene_base.cpp
@@ -0,0 +1,82 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+SceneBase::SceneBase(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) : _vm(vm), _staticData(sceneStaticData) {
+	_frameCycleCount = _staticData.cycleStartFrame;
+
+	((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
+
+	if (_staticData.cycleStartFrame >= 0)
+		((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
+}
+
+int SceneBase::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	const Graphics::Surface *newFrame = 0;
+
+	if (_frameCycleCount >= 0) {
+		newFrame = ((SceneViewWindow *)viewWindow)->getCycleFrame(_frameCycleCount);
+
+		if (!newFrame)
+			newFrame = ((SceneViewWindow *)viewWindow)->getStillFrame(_staticData.navFrameIndex);
+	} else if (_staticData.navFrameIndex >= 0) {
+		newFrame = ((SceneViewWindow *)viewWindow)->getStillFrame(_staticData.navFrameIndex);
+	}
+
+	if (newFrame) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		_vm->_gfx->crossBlit(preBuffer, 0, 0, 432, 189, newFrame, 0, 0);
+	}
+
+	return SC_REPAINT;
+}
+
+int SceneBase::timerCallback(Window *viewWindow) {
+	// Check if we're cycling
+	if (_frameCycleCount < 0)
+		return SC_FALSE;
+
+	// Increment and wrap cycle counter
+	_frameCycleCount++;
+	if (_frameCycleCount > (_staticData.cycleStartFrame + _staticData.cycleFrameCount - 1))
+		_frameCycleCount = _staticData.cycleStartFrame;
+
+	// Update the view window
+	viewWindow->invalidateWindow(false);
+	return SC_TRUE;
+}
+
+int SceneBase::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	return (int)kCursorArrow;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_base.h b/engines/buried/environ/scene_base.h
new file mode 100644
index 0000000000..14c32a8866
--- /dev/null
+++ b/engines/buried/environ/scene_base.h
@@ -0,0 +1,118 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_SCENE_BASE_H
+#define BURIED_SCENE_BASE_H
+
+#include "common/keyboard.h"
+#include "common/rect.h"
+
+#include "buried/navdata.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+// Generic result codes
+enum {
+	SC_FALSE = 0,          // Everything did not go well, error out
+	SC_TRUE = 1,           // Everything is kosher, continue as normal
+	SC_END_PROCESSING = 4  // Stop processing here
+};
+
+// Post-exit specific result codes
+enum {
+	SC_DEATH = 3           // We died, so do nothing further
+};
+
+// Paint-specific return values
+enum {
+	SC_REPAINT = 0,
+	SC_DO_NOT_REPAINT = 1
+};
+
+// Movie status codes
+enum {
+	MOVIE_START = 0,
+	MOVIE_STOPPED = 1,
+	MOVIE_PLAYING = 2,
+	MOVIE_ABORTED_BY_USER = 3,
+	MOVIE_LOOPING_RESTART = 4
+};
+
+// Inventory item related return codes
+enum {
+	SIC_REJECT = 0,
+	SIC_ACCEPT = 1
+};
+
+class BuriedEngine;
+class Window;
+class VideoWindow;
+
+class SceneBase { // Wow, it's not a window!
+public:
+	SceneBase(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	virtual ~SceneBase() {}
+
+	virtual void preDestructor() {}
+
+	virtual int preEnterRoom(Window *viewWindow, const Location &priorLocation) { return SC_TRUE; }
+	virtual int postEnterRoom(Window *viewWindow, const Location &priorLocation) { return SC_TRUE; }
+
+	virtual int preExitRoom(Window *viewWindow, const Location &priorLocation) { return SC_TRUE; }
+	virtual int postExitRoom(Window *viewWindow, const Location &priorLocation) { return SC_TRUE; }
+
+	virtual int mouseDown(Window *viewWindow, const Common::Point &pointLocation) { return SC_TRUE; }
+	virtual int mouseUp(Window *viewWindow, const Common::Point &pointLocation) { return SC_TRUE; }
+	virtual int mouseMove(Window *viewWindow, const Common::Point &pointLocation) { return SC_TRUE; }
+
+	virtual int onCharacter(Window *viewWindow, const Common::KeyState &character) { return SC_TRUE; }
+
+	virtual int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	virtual int gdiPaint(Window *viewWindow) { return SC_REPAINT; }
+
+	virtual int movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) { return SC_TRUE; }
+	virtual int timerCallback(Window *viewWindow);
+
+	virtual int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) { return 0; }
+	virtual int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) { return SIC_REJECT; }
+
+	virtual int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+	virtual int locateAttempted(Window *viewWindow, const Common::Point &pointLocation) { return 0; }
+
+	LocationStaticData _staticData;
+	int32 _frameCycleCount;
+
+protected:
+	BuriedEngine *_vm;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index cf09b59001..edd8a85775 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -39,6 +39,7 @@
 #include "buried/message.h"
 #include "buried/overview.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/title_sequence.h"
 #include "buried/video_window.h"
@@ -57,6 +58,7 @@ FrameWindow::FrameWindow(BuriedEngine *vm) : Window(vm, 0) {
 	_transitionSpeed = 2;
 	_gameInProgress = false;
 	_atMainMenu = true;
+	_reviewerMode = false;
 
 	// Retrieve the transition speed from the INI file
 	Common::String transitionConfigName = _vm->isDemo() ? "TransitionSpeed" : _vm->getString(IDS_INI_KEY_TRANS_SPEED);
@@ -341,7 +343,7 @@ bool FrameWindow::showOverview() {
 
 bool FrameWindow::setTimerPause(bool pause) {
 	if (_gameInProgress) {
-		// TODO
+		((GameUIWindow *)_mainChildWindow)->_sceneViewWindow->_paused = pause;
 		return true;
 	}
 
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index 9160f9f5ab..1fa5d06ede 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -63,6 +63,10 @@ public:
 
 	int getTransitionSpeed() const { return _transitionSpeed; }
 	void setTransitionSpeed(int newSpeed);
+	bool isFrameCyclingDefault() const { return _cycleDefault; }
+	bool isFrameCachingAllowed() const { return _cacheFrames; }
+
+	bool _reviewerMode;
 
 private:
 	Window *_mainChildWindow;
diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index feb11b9cd8..5d28f2efeb 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -33,6 +33,7 @@
 #include "buried/message.h"
 #include "buried/navarrow.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/video_window.h"
 
@@ -50,10 +51,9 @@ GameUIWindow::GameUIWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent
 
 	_navArrowWindow = new NavArrowWindow(_vm, this);
 	_liveTextWindow = new LiveTextWindow(_vm, this);
+	_sceneViewWindow = new SceneViewWindow(_vm, this);
 	_inventoryWindow = new InventoryWindow(_vm, this);
 	_bioChipRightWindow = new BioChipRightWindow(_vm, this);
-
-	// TODO: Other windows
 }
 
 GameUIWindow::~GameUIWindow() {
@@ -61,8 +61,7 @@ GameUIWindow::~GameUIWindow() {
 	delete _liveTextWindow;
 	delete _inventoryWindow;
 	delete _bioChipRightWindow;
-
-	// TODO: Other windows
+	delete _sceneViewWindow;
 }
 
 bool GameUIWindow::startNewGame(bool walkthrough) {
@@ -73,8 +72,8 @@ bool GameUIWindow::startNewGame(bool walkthrough) {
 	_liveTextWindow->showWindow(kWindowShow);
 	_inventoryWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
-
-	// TODO: Other windows
+	_sceneViewWindow->showWindow(kWindowShow);
+	_sceneViewWindow->startNewGame(walkthrough);
 
 	return true;
 }
@@ -110,21 +109,38 @@ bool GameUIWindow::startNewGameIntro(bool walkthrough) {
 	_liveTextWindow->showWindow(kWindowShow);
 	_inventoryWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
+	_sceneViewWindow->showWindow(kWindowShow);
+	_sceneViewWindow->startNewGameIntro(walkthrough);
+
+	return true;
+}
+
+bool GameUIWindow::startNewGame(const Location &startingLocation) {
+	_doNotDraw = false;
+
+	showWindow(kWindowShow);
+	_navArrowWindow->showWindow(kWindowShow);
+	_liveTextWindow->showWindow(kWindowShow);
+	_sceneViewWindow->showWindow(kWindowShow);
+	_inventoryWindow->showWindow(kWindowShow);
+	_bioChipRightWindow->showWindow(kWindowShow);
+	_sceneViewWindow->startNewGame(startingLocation);
+	invalidateWindow(false);
 
-	// TODO: Other windows
 	return true;
 }
 
 bool GameUIWindow::startNewGame(const Common::String &fileName) {
 	_doNotDraw = false;
+	showWindow(kWindowShow);
 	invalidateWindow(false);
 
 	_navArrowWindow->showWindow(kWindowShow);
 	_liveTextWindow->showWindow(kWindowShow);
+	_sceneViewWindow->showWindow(kWindowShow);
 	_inventoryWindow->showWindow(kWindowShow);
 	_bioChipRightWindow->showWindow(kWindowShow);
-
-	// TODO: Other windows
+	_sceneViewWindow->startNewGame(fileName);
 
 	return true;
 }
@@ -296,8 +312,8 @@ void GameUIWindow::onEnable(bool enable) {
 	_inventoryWindow->enableWindow(enable);
 	_navArrowWindow->enableWindow(enable);
 	_liveTextWindow->enableWindow(enable);
+	_sceneViewWindow->enableWindow(enable);
 	_bioChipRightWindow->enableWindow(enable);
-	// TODO: Other windows
 
 	// If we're re-enabling, clear out the message queue of any mouse messages
 	if (enable)
@@ -319,8 +335,7 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 			_navArrowWindow->sendMessage(new KeyUpMessage(key, flags));
 		break;
 	case Common::KEYCODE_s:
-		if (key.flags & Common::KBD_CTRL) {
-			// TODO: Check for cloaking enabled
+		if ((key.flags & Common::KBD_CTRL) && _sceneViewWindow->getGlobalFlags().bcCloakingEnabled != 1) {
 			_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
 			_bioChipRightWindow->invalidateWindow(false);
 			_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 130), 0));
@@ -330,8 +345,7 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 		// Fall through
 	case Common::KEYCODE_o:
 	case Common::KEYCODE_l:
-		if (key.flags & Common::KBD_CTRL) {
-			// TODO: Check for cloaking enabled
+		if ((key.flags & Common::KBD_CTRL) && _sceneViewWindow->getGlobalFlags().bcCloakingEnabled != 1) {
 			_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
 			_bioChipRightWindow->invalidateWindow(false);
 			_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 130), 0));
@@ -340,7 +354,8 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 		}
 		// Fall through
 	default:
-		// TODO: Send to the scene view window
+		if (_sceneViewWindow)
+			_sceneViewWindow->sendMessage(new KeyUpMessage(key, flags));
 		break;
 	}
 }
diff --git a/engines/buried/gameui.h b/engines/buried/gameui.h
index dff36bc87c..84c10b403d 100644
--- a/engines/buried/gameui.h
+++ b/engines/buried/gameui.h
@@ -26,6 +26,7 @@
 #ifndef BURIED_GAMEUI_H
 #define BURIED_GAMEUI_H
 
+#include "buried/navdata.h"
 #include "buried/window.h"
 
 namespace Graphics {
@@ -38,6 +39,7 @@ class BioChipRightWindow;
 class InventoryWindow;
 class LiveTextWindow;
 class NavArrowWindow;
+class SceneViewWindow;
 
 class GameUIWindow : public Window {
 public:
@@ -46,7 +48,7 @@ public:
 
 	bool startNewGame(bool walkthrough = false);
 	bool startNewGameIntro(bool walkthrough = false);
-	// startNewGame(location struct)
+	bool startNewGame(const Location &startingLocation);
 	bool startNewGame(const Common::String &fileName);
 	// startNewGame(continue data, location struct);
 	bool loadGame();
@@ -62,7 +64,7 @@ public:
 
 	NavArrowWindow *_navArrowWindow;
 	LiveTextWindow *_liveTextWindow;
-	// TODO: SceneViewWindow
+	SceneViewWindow *_sceneViewWindow;
 	InventoryWindow *_inventoryWindow;
 	BioChipRightWindow *_bioChipRightWindow;
 
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index c09107f34c..a219db2aac 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -60,8 +60,8 @@ enum Cursor {
 	kCursorPrevPage        =   107,
 	kCursorMoveUp          =   108,
 	kCursorMoveDown        =   109,
-	kCursorLocateCursorA   =   110,
-	kCursorLocateCursorB   =   111,
+	kCursorLocateA         =   110,
+	kCursorLocateB         =   111,
 	kCursorArrowUp         =   112,
 	kCursorArrowLeft       =   113,
 	kCursorArrowDown       =   114,
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index 4e3cd90af7..b15ef0f566 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -25,10 +25,13 @@
 
 #include "buried/avi_frames.h"
 #include "buried/buried.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_info.h"
+#include "buried/inventory_window.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 #include "buried/video_window.h"
 
 #include "graphics/font.h"
@@ -75,9 +78,8 @@ bool InventoryInfoWindow::changeCurrentItem(int newItemID) {
 
 	_videoWindow->playToFrame(_spinStart + _spinLength);
 
-	if (_currentItemID == kItemLensFilter) {
-		// TODO: Set scoring flag
-	}
+	if (_currentItemID == kItemLensFilter)
+		((GameUIWindow *)(_parent->getParent()))->_sceneViewWindow->getGlobalFlags().scoreResearchLensFilter = 1;
 
 	return true;
 }
@@ -111,7 +113,7 @@ bool InventoryInfoWindow::onEraseBackground() {
 }
 
 void InventoryInfoWindow::onLButtonUp(const Common::Point &point, uint flags) {
-	// TODO: Destroy window
+	((GameUIWindow *)(_parent->getParent()))->_inventoryWindow->destroyInfoWindow();
 }
 
 void InventoryInfoWindow::onTimer(uint timer) {
@@ -145,7 +147,7 @@ BurnedLetterViewWindow::BurnedLetterViewWindow(BuriedEngine *vm, Window *parent,
 
 	_rebuildPage = true;
 
-	// TODO: Scoring for reading the letter
+	((GameUIWindow *)(_parent->getParent()))->_sceneViewWindow->getGlobalFlags().readBurnedLetter = 1;
 }
 
 BurnedLetterViewWindow::~BurnedLetterViewWindow() {
@@ -172,7 +174,7 @@ void BurnedLetterViewWindow::onPaint() {
 	byte transValue = _vm->isDemo() ? 2 : 0;
 	_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height(), _preBuffer, 0, 0, 0, transValue, transValue, transValue);
 
-	if (_curLineIndex >= 0 && false) { // TODO: Translation
+	if (_curLineIndex >= 0 && ((SceneViewWindow *)_parent)->getGlobalFlags().bcTranslateEnabled == 1) {
 		int numLines = _viewLineCount[_curView];
 		uint32 boxColor = _vm->_gfx->getColor(255, 0, 0);
 		Common::Rect box(1, (187 / numLines) * _curLineIndex, 430, (187 / numLines) * (_curLineIndex + 1) - 1);
@@ -231,15 +233,32 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 		_vm->_gfx->setCursor(oldCursor);
 	}
 
-	if (_putDown.contains(point)) {
-		// TODO: Destroy the window
-	}
+	if (_putDown.contains(point))
+		((GameUIWindow *)(_parent->getParent()))->_inventoryWindow->destroyBurnedLetterWindow();
 }
 
 void BurnedLetterViewWindow::onMouseMove(const Common::Point &point, uint flags) {
 	_curMousePos = point;
 
-	// TODO: Translation
+	if (((SceneViewWindow *)_parent)->getGlobalFlags().bcTranslateEnabled == 1) {
+		int lineCount = _viewLineCount[_curView];
+		int textLineNumber = 0;
+		for (int i = 0; i < _curView; i++)
+			textLineNumber += _viewLineCount[i];
+
+		int lineIndex = ((point.y - 2) / (187 / lineCount));
+		if (lineIndex > (lineCount - 1))
+			lineIndex = lineCount - 1;
+
+		if (_curLineIndex != lineIndex) {
+			_curLineIndex = lineIndex;
+			invalidateWindow(false);
+
+			Common::String translatedText = _vm->getString(_translatedTextResourceID + textLineNumber + _curLineIndex);
+			((SceneViewWindow *)_parent)->displayTranslationText(translatedText);
+			return;
+		}
+	}
 
 	// Since translation was not enabled, check the current line flag
 	if (_curLineIndex != -1) {
diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index 11655c0fa4..d79a1a8418 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -32,6 +32,7 @@
 #include "buried/inventory_window.h"
 #include "buried/message.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 
 #include "common/algorithm.h"
 #include "graphics/font.h"
@@ -164,7 +165,40 @@ bool InventoryWindow::addItem(int itemID) {
 	rebuildPreBuffer();
 	invalidateWindow(false);
 
-	// TODO: Scoring flags
+	// Update scoring flags
+	GlobalFlags &globalFlags = ((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags();
+
+	switch (itemID) {
+	case kItemBioChipTranslate:
+		globalFlags.scoreGotTranslateBioChip = 1;
+		break;
+	case kItemBioChipAI:
+		globalFlags.scoreDownloadedArthur = 1;
+		break;
+	case kItemCopperKey:
+		globalFlags.scoreGotKeyFromSmithy = 1;
+		break;
+	case kItemSiegeCycle:
+		globalFlags.scoreMadeSiegeCycle = 1;
+		globalFlags.genHadSiegeCycle = 1;
+		break;
+	case kItemJadeBlock:
+		globalFlags.scoreGotWealthGodPiece = 1;
+		break;
+	case kItemLimestoneBlock:
+		globalFlags.scoreGotRainGodPiece = 1;
+		break;
+	case kItemObsidianBlock:
+		globalFlags.scoreGotWarGodPiece = 1;
+		break;
+	case kItemDriveAssembly:
+		globalFlags.genHadDriveAssembly = 1;
+		break;
+	case kItemWheelAssembly:
+		globalFlags.genHadWheelAssembly = 1;
+		break;
+	}
+
 	return true;
 }
 
@@ -237,7 +271,14 @@ bool InventoryWindow::displayBurnedLetterWindow() {
 	if (_letterViewWindow)
 		return true;
 
-	// TODO
+	Location currentLocation;
+	LocationStaticData currentSceneStaticData;
+	((GameUIWindow *)_parent)->_sceneViewWindow->getCurrentSceneLocation(currentLocation);
+	((GameUIWindow *)_parent)->_sceneViewWindow->getSceneStaticData(currentLocation, currentSceneStaticData);
+
+	_letterViewWindow = new BurnedLetterViewWindow(_vm, ((GameUIWindow *)_parent)->_sceneViewWindow, currentSceneStaticData);
+	((GameUIWindow *)_parent)->_sceneViewWindow->burnedLetterWindowDisplayed(true);
+	_letterViewWindow->setWindowPos(kWindowPosTop, 0, 0, 0, 0, kWindowPosShowWindow | kWindowPosNoMove | kWindowPosNoSize);
 
 	return true;
 }
@@ -249,7 +290,7 @@ bool InventoryWindow::destroyBurnedLetterWindow() {
 	delete _letterViewWindow;
 	_letterViewWindow = 0;
 
-	// TODO: Notify the scene view window
+	((GameUIWindow *)_parent)->_sceneViewWindow->burnedLetterWindowDisplayed(false);
 
 	return true;
 }
@@ -336,14 +377,35 @@ void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
 			return;
 		}
 
-		if (true) { // TODO: Check for auxilary window
+		if (!((GameUIWindow *)_parent)->_sceneViewWindow->isAuxWindowDisplayed()) {
 			if (itemID == kItemBurnedLetter) {
 				displayBurnedLetterWindow();
 				return;
 			}
 
 			if (itemID == kItemLensFilter) {
-				// TODO
+				if (((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().generalWalkthroughMode == 1) {
+					((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_LENS_FILTER_ATTACHED));
+					((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().lensFilterActivated = 1;
+					return;
+				}
+	
+				if (((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().lensFilterActivated == 0) {
+					((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().lensFilterActivated = 1;
+					((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_LENS_FILTER_ATTACHED));
+				} else {
+					// Deny removing the filter in the alien space ship
+					Location currentLocation;
+					((GameUIWindow *)_parent)->_sceneViewWindow->getCurrentSceneLocation(currentLocation);
+			
+					if (currentLocation.timeZone == 7) {
+						((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_LENS_FILTER_DENY_REMOVAL));
+					} else {
+						((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().lensFilterActivated = 0;
+						((GameUIWindow *)_parent)->_sceneViewWindow->displayLiveText(_vm->getString(IDS_LENS_FILTER_REMOVED));
+					}
+				}
+
 				return;
 			}
 
@@ -391,7 +453,7 @@ void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
 			// TODO: SetCapture();
 
 			onSetCursor(kMessageTypeLButtonDown);
-			// TODO: Change sprite status
+			((GameUIWindow *)_parent)->_sceneViewWindow->changeSpriteStatus(true);
 			onMouseMove(point, 0);
 		}
 	}
@@ -449,7 +511,9 @@ void InventoryWindow::onLButtonUp(const Common::Point &point, uint flags) {
 		if (_infoWindow) {
 			destroyInfoWindow();
 		} else {
-			// TODO: Create window
+			_infoWindow = new InventoryInfoWindow(_vm, ((GameUIWindow *)_parent)->_sceneViewWindow, _itemArray[_curItem]);
+			((GameUIWindow *)_parent)->_sceneViewWindow->infoWindowDisplayed(true);
+			_infoWindow->setWindowPos(kWindowPosTop, 0, 0, 0, 0, kWindowPosShowWindow | kWindowPosNoMove | kWindowPosNoSize);
 			_magSelected = true;
 			redraw = true;
 		}
@@ -564,7 +628,7 @@ bool InventoryWindow::destroyInfoWindow() {
 	delete _infoWindow;
 	_infoWindow = 0;
 
-	// TODO: Notify the scene view
+	((GameUIWindow *)_parent)->_sceneViewWindow->infoWindowDisplayed(false);
 
 	_magSelected = false;
 	rebuildPreBuffer();
diff --git a/engines/buried/inventory_window.h b/engines/buried/inventory_window.h
index d305303b98..43aae5d0f0 100644
--- a/engines/buried/inventory_window.h
+++ b/engines/buried/inventory_window.h
@@ -30,6 +30,10 @@
 #include "buried/sprtdata.h"
 #include "buried/window.h"
 
+namespace Graphics {
+class Font;
+}
+
 namespace Buried {
 
 class AVIFrames;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 8925fe8493..01c5bb3ca5 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -19,13 +19,15 @@ MODULE_OBJS = \
 	main_menu.o \
 	navarrow.o \
 	overview.o \
+	scene_view.o \
 	sound.o \
 	title_sequence.o \
 	video_window.o \
 	window.o \
 	demo/demo_menu.o \
 	demo/features.o \
-	demo/movie_scene.o
+	demo/movie_scene.o \
+	environ/scene_base.o
 
 
 # This module can be built as a plugin
diff --git a/engines/buried/navarrow.cpp b/engines/buried/navarrow.cpp
index 4cb57a8410..760094482c 100644
--- a/engines/buried/navarrow.cpp
+++ b/engines/buried/navarrow.cpp
@@ -24,10 +24,13 @@
  */
 
 #include "buried/buried.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
+#include "buried/inventory_window.h"
 #include "buried/navarrow.h"
 #include "buried/navdata.h"
 #include "buried/resources.h"
+#include "buried/scene_view.h"
 
 #include "common/keyboard.h"
 #include "graphics/surface.h"
@@ -135,8 +138,8 @@ void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
 	Common::Rect downButton(42, 71, 78, 124);
 	Common::Rect forwardButton(39, 49, 101, 91);
 
-	// TODO: Destroy info window
-	// TODO: Destroy burned letter window
+	((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
+	((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
 
 	// clone2727: This logic was broken in the original. retVal wasn't initialized.
 	bool retVal = false;
@@ -145,16 +148,16 @@ void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
 	if (forwardButton.contains(point)) {
 		// If we only clicked on the forward arrow, then take care of it here
 		if (!rightButton.contains(point) && !downButton.contains(point)) {
-			// TODO
+			if (_arrowStatus[4] == BUTTON_ENABLED)
+				((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
 		} else {
 			if (rightButton.contains(point)) {
 				Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
 
-				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
-					// TODO
-				} else {
-					// TODO
-				}
+				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255))
+					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
+				else
+					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(2);
 
 				centerArrow->free();
 				delete centerArrow;
@@ -163,32 +166,27 @@ void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
 			if (downButton.contains(point)) {
 				Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
 
-				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
-					// TODO
-				} else {
-					// TODO
-				}
+				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255))
+					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
+				else
+					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(3);
 
 				centerArrow->free();
 				delete centerArrow;
 			}
 		}
 	} else {
-		if (upButton.contains(point)) {
-			// TODO
-		}
+		if (upButton.contains(point) && _arrowStatus[0] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(0);
 
-		if (leftButton.contains(point)) {
-			// TODO
-		}
+		if (leftButton.contains(point) && _arrowStatus[1] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(1);
 
-		if (rightButton.contains(point)) {
-			// TODO
-		}
+		if (rightButton.contains(point) && _arrowStatus[2] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(2);
 
-		if (downButton.contains(point)) {
-			// TODO
-		}
+		if (downButton.contains(point) && _arrowStatus[3] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(3);
 	}
 
 	if (retVal) {
@@ -201,22 +199,27 @@ void NavArrowWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 	switch (key.keycode) {
 	case Common::KEYCODE_KP4:
 	case Common::KEYCODE_LEFT:
-		// TODO
+		if (_arrowStatus[1] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(1);
 		break;
 	case Common::KEYCODE_KP6:
 	case Common::KEYCODE_RIGHT:
-		// TODO
+		if (_arrowStatus[2] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(2);
 		break;
 	case Common::KEYCODE_KP2:
 	case Common::KEYCODE_DOWN:
-		// TODO
+		if (_arrowStatus[3] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(3);
 		break;
 	case Common::KEYCODE_KP8:
 	case Common::KEYCODE_UP:
-		// TODO
+		if (_arrowStatus[0] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(0);
 		break;
 	case Common::KEYCODE_KP5:
-		// TODO
+		if (_arrowStatus[4] == BUTTON_ENABLED)
+			((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
 		break;
 	default:
 		break;
diff --git a/engines/buried/navarrow.h b/engines/buried/navarrow.h
index 709519056b..a87a3cf7f7 100644
--- a/engines/buried/navarrow.h
+++ b/engines/buried/navarrow.h
@@ -50,7 +50,6 @@ public:
 	void onLButtonDown(const Common::Point &point, uint flags);
 	void onKeyUp(const Common::KeyState &key, uint flags);
 
-private:
 	enum {
 		BUTTON_DISABLED = 0,
 		BUTTON_ENABLED = 1,
@@ -65,6 +64,7 @@ private:
 		NAV_BUTTON_FORWARD = 4
 	};
 
+private:
 	static const int NUM_ARROWS = 5;
 	static const int NUM_ARROW_BITMAPS = 3;
 
diff --git a/engines/buried/navdata.h b/engines/buried/navdata.h
index 29944a1a08..0e4d648f2e 100644
--- a/engines/buried/navdata.h
+++ b/engines/buried/navdata.h
@@ -31,6 +31,9 @@
 namespace Buried {
 
 struct Location {
+	Location() : timeZone(-1), environment(-1), node(-1), facing(-1), orientation(-1), depth(-1) {}
+	Location(int16 tz, int16 e, int16 n, int16 f, int16 o, int16 d) : timeZone(tz), environment(e), node(n), facing(f), orientation(o), depth(d) {}
+
 	int16 timeZone;
 	int16 environment;
 	int16 node;
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 99759ed537..019d78b773 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -354,6 +354,10 @@ namespace Buried {
 #define IDS_COMPL_FINAL_SCORE_TEMPL     9035
 #define IDS_DEATH_FINAL_SCORE_TEMPL     9035
 
+// 1.04+:
+#define IDS_PLAY_MODE_WALKTHROUGH_TEXT  9085
+#define IDS_PLAY_MODE_NORMAL_TEXT       9086
+
 #define IDES_FILENAME_BASE              17408
 #define IDES_STRING_BASE                21504
 
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
new file mode 100644
index 0000000000..fc3e42bc81
--- /dev/null
+++ b/engines/buried/scene_view.cpp
@@ -0,0 +1,2489 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/avi_frames.h"
+#include "buried/biochip_right.h"
+#include "buried/buried.h"
+#include "buried/frame_window.h"
+#include "buried/gameui.h"
+#include "buried/graphics.h"
+#include "buried/inventory_window.h"
+#include "buried/livetext.h"
+#include "buried/navarrow.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/video_window.h"
+#include "buried/environ/scene_base.h"
+
+#include "common/stream.h"
+#include "common/system.h"
+#include "graphics/surface.h"
+
+namespace Buried {
+
+SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_currentScene = 0;
+	_preBuffer = 0;
+	_walkMovie = 0;
+	_useScenePaint = true;
+	_timer = 0;
+	_currentSprite.image = 0;
+	_useSprite = true;
+	_infoWindowDisplayed = false;
+	_bioChipWindowDisplayed = false;
+	_burnedLetterDisplayed = false;
+	_soundTimer = 0;
+	_asyncMovie = 0;
+	_asyncMovieStartFrame = 0;
+	_loopAsyncMovie = false;
+	_paused = false;
+	_useWaitCursor = false;
+	_cycleEnabled = ((FrameWindow *)(_parent->getParent()))->isFrameCyclingDefault();
+	_disableArthur = false;
+
+	_preBuffer = new Graphics::Surface();
+	_preBuffer->create(DIB_FRAME_WIDTH, DIB_FRAME_HEIGHT, g_system->getScreenFormat());
+
+	_rect = Common::Rect(64, 128, 496, 317);
+
+	_timer = setTimer(100);
+	_curCursor = kCursorArrow;
+	_stillFrames = new AVIFrames();
+	_cycleFrames = new AVIFrames();
+}
+
+SceneViewWindow::~SceneViewWindow() {
+	if (_currentScene) {
+		_currentScene->preDestructor();
+		delete _currentScene;
+	}
+
+	killTimer(_timer);
+
+	if (_preBuffer) {
+		_preBuffer->free();
+		delete _preBuffer;
+	}
+
+	delete _stillFrames;
+	delete _cycleFrames;
+	delete _walkMovie;
+}
+
+bool SceneViewWindow::startNewGame(bool walkthrough) {
+	Location newLocation;
+
+	if (_vm->isDemo()) {
+		newLocation.timeZone = 1;
+		newLocation.environment = 4;
+		newLocation.node = 0;
+		newLocation.facing = 0;
+		newLocation.orientation = 1;
+		newLocation.depth = 0;
+	} else {
+		newLocation.timeZone = 4;
+		newLocation.environment = 3;
+		newLocation.node = 3;
+		newLocation.facing = 0;
+		newLocation.orientation = 1;
+		newLocation.depth = 0;
+	}
+
+	jumpToScene(newLocation);
+
+	if (_vm->isDemo()) {
+		displayLiveText("To return to the main menu, click the 'Menu' button on the Interface Biochip Display to the right, then click Quit.");
+		_vm->_sound->setAmbientSound("CASTLE/CGMBSNG.WAV");
+
+		// This is unlabeled in the original source, but it looks like a hidden feature
+		// to access a bonus puzzle in the demo. (Complete with a typo, but who's counting?)
+		if (((FrameWindow *)(_parent->getParent()))->_reviewerMode)
+			((GameUIWindow *)_parent)->_inventoryWindow->addItem(kItemCopperMedallion);
+	} else if (walkthrough) {
+		// Set the mode flag
+		_globalFlags.generalWalkthroughMode = 1;
+
+		// Set specific state flags for walkthrough mode
+		_globalFlags.cgSmithyStatus = 6;
+		_globalFlags.cgTapestryFlag = 1;
+		_globalFlags.myTPCodeWheelLeftIndex = 8;
+		_globalFlags.myTPCodeWheelRightIndex = 12;
+		_globalFlags.myTPCodeWheelStatus = 1;
+		_globalFlags.myWGPlacedRope = 1;
+
+		// Add the translate biochip
+		((GameUIWindow *)_parent)->_inventoryWindow->addItem(kItemBioChipTranslate);
+	}
+
+	invalidateWindow(false);
+	return true;
+}
+
+bool SceneViewWindow::startNewGameIntro(bool walkthrough) {
+	Location newLocation;
+	newLocation.timeZone = 10;
+	newLocation.environment = 0;
+	newLocation.node = 0;
+	newLocation.facing = 0;
+	newLocation.orientation = 0;
+	newLocation.depth = 0;
+
+	jumpToScene(newLocation);
+	
+	if (walkthrough) {
+		// Set the mode flag
+		_globalFlags.generalWalkthroughMode = 1;
+
+		// Set specific state flags for walkthrough mode
+		_globalFlags.cgSmithyStatus = 6;
+		_globalFlags.cgTapestryFlag = 1;
+		_globalFlags.myTPCodeWheelLeftIndex = 8;
+		_globalFlags.myTPCodeWheelRightIndex = 12;
+		_globalFlags.myTPCodeWheelStatus = 1;
+		_globalFlags.myWGPlacedRope = 1;
+
+		// Add the translate biochip
+		((GameUIWindow *)_parent)->_inventoryWindow->addItem(kItemBioChipTranslate);
+	}
+
+	invalidateWindow(false);
+	return true;
+}
+
+bool SceneViewWindow::startNewGame(const Location &startingLocation) {
+	jumpToSceneRestore(startingLocation);
+
+	if (_globalFlags.generalWalkthroughMode == 1) {
+		if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+			displayLiveText(_vm->getString(IDS_PLAY_MODE_WALKTHROUGH_TEXT));
+		else
+			displayLiveText("You are playing in Walkthrough mode.");
+	} else {
+		if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+			displayLiveText(_vm->getString(IDS_PLAY_MODE_NORMAL_TEXT));
+		else
+			displayLiveText("You are playing in Adventure mode.");
+	}
+
+	return true;
+}
+
+bool SceneViewWindow::startNewGame(const Common::String &restoreFile) {
+	((GameUIWindow *)_parent)->loadGame(restoreFile);
+	invalidateWindow(false);
+	return true;
+}
+
+bool SceneViewWindow::showDeathScene(int deathSceneIndex) {
+	return ((FrameWindow *)(_parent->getParent()))->showDeathScene(deathSceneIndex, _globalFlags); // TODO: Inventory
+}
+
+bool SceneViewWindow::showCompletionScene() {
+	return ((FrameWindow *)(_parent->getParent()))->showCompletionScene(_globalFlags); // TODO: Inventory
+}
+
+bool SceneViewWindow::getSceneStaticData(const Location &location, LocationStaticData &sceneStaticData) {
+	int curTimeZone = -1;
+	int curEnvironment = -1;
+
+	if (!_currentNavigationDatabase.empty()) {
+		curTimeZone = _currentNavigationDatabase[0].location.timeZone;
+		curEnvironment = _currentNavigationDatabase[0].location.environment;
+	}
+
+	if (location.timeZone != curTimeZone || location.environment != curEnvironment) {
+		_currentNavigationDatabase.clear();
+
+		int resID = _vm->computeNavDBResourceID(location.timeZone, location.environment);
+		Common::SeekableReadStream *resource = _vm->getNavData(resID);
+		resource->skip(2);
+
+		while (resource->pos() < resource->size()) {
+			LocationStaticData locationStaticData;
+
+			locationStaticData.location.timeZone = resource->readSint16LE();
+			locationStaticData.location.environment = resource->readSint16LE();
+			locationStaticData.location.node = resource->readSint16LE();
+			locationStaticData.location.facing = resource->readSint16LE();
+			locationStaticData.location.orientation = resource->readSint16LE();
+			locationStaticData.location.depth = resource->readSint16LE();
+
+			locationStaticData.destUp.destinationScene.timeZone = resource->readSint16LE();
+			locationStaticData.destUp.destinationScene.environment = resource->readSint16LE();
+			locationStaticData.destUp.destinationScene.node = resource->readSint16LE();
+			locationStaticData.destUp.destinationScene.facing = resource->readSint16LE();
+			locationStaticData.destUp.destinationScene.orientation = resource->readSint16LE();
+			locationStaticData.destUp.destinationScene.depth = resource->readSint16LE();
+			locationStaticData.destUp.transitionType = resource->readSint16LE();
+			locationStaticData.destUp.transitionData = resource->readSint16LE();
+			locationStaticData.destUp.transitionStartFrame = resource->readSint32LE();
+			locationStaticData.destUp.transitionLength = resource->readSint32LE();
+			
+			locationStaticData.destLeft.destinationScene.timeZone = resource->readSint16LE();
+			locationStaticData.destLeft.destinationScene.environment = resource->readSint16LE();
+			locationStaticData.destLeft.destinationScene.node = resource->readSint16LE();
+			locationStaticData.destLeft.destinationScene.facing = resource->readSint16LE();
+			locationStaticData.destLeft.destinationScene.orientation = resource->readSint16LE();
+			locationStaticData.destLeft.destinationScene.depth = resource->readSint16LE();
+			locationStaticData.destLeft.transitionType = resource->readSint16LE();
+			locationStaticData.destLeft.transitionData = resource->readSint16LE();
+			locationStaticData.destLeft.transitionStartFrame = resource->readSint32LE();
+			locationStaticData.destLeft.transitionLength = resource->readSint32LE();
+			
+			locationStaticData.destRight.destinationScene.timeZone = resource->readSint16LE();
+			locationStaticData.destRight.destinationScene.environment = resource->readSint16LE();
+			locationStaticData.destRight.destinationScene.node = resource->readSint16LE();
+			locationStaticData.destRight.destinationScene.facing = resource->readSint16LE();
+			locationStaticData.destRight.destinationScene.orientation = resource->readSint16LE();
+			locationStaticData.destRight.destinationScene.depth = resource->readSint16LE();
+			locationStaticData.destRight.transitionType = resource->readSint16LE();
+			locationStaticData.destRight.transitionData = resource->readSint16LE();
+			locationStaticData.destRight.transitionStartFrame = resource->readSint32LE();
+			locationStaticData.destRight.transitionLength = resource->readSint32LE();
+			
+			locationStaticData.destDown.destinationScene.timeZone = resource->readSint16LE();
+			locationStaticData.destDown.destinationScene.environment = resource->readSint16LE();
+			locationStaticData.destDown.destinationScene.node = resource->readSint16LE();
+			locationStaticData.destDown.destinationScene.facing = resource->readSint16LE();
+			locationStaticData.destDown.destinationScene.orientation = resource->readSint16LE();
+			locationStaticData.destDown.destinationScene.depth = resource->readSint16LE();
+			locationStaticData.destDown.transitionType = resource->readSint16LE();
+			locationStaticData.destDown.transitionData = resource->readSint16LE();
+			locationStaticData.destDown.transitionStartFrame = resource->readSint32LE();
+			locationStaticData.destDown.transitionLength = resource->readSint32LE();
+			
+			locationStaticData.destForward.destinationScene.timeZone = resource->readSint16LE();
+			locationStaticData.destForward.destinationScene.environment = resource->readSint16LE();
+			locationStaticData.destForward.destinationScene.node = resource->readSint16LE();
+			locationStaticData.destForward.destinationScene.facing = resource->readSint16LE();
+			locationStaticData.destForward.destinationScene.orientation = resource->readSint16LE();
+			locationStaticData.destForward.destinationScene.depth = resource->readSint16LE();
+			locationStaticData.destForward.transitionType = resource->readSint16LE();
+			locationStaticData.destForward.transitionData = resource->readSint16LE();
+			locationStaticData.destForward.transitionStartFrame = resource->readSint32LE();
+			locationStaticData.destForward.transitionLength = resource->readSint32LE();
+
+			locationStaticData.classID = resource->readSint16LE();
+			locationStaticData.navFrameIndex = resource->readSint32LE();
+			locationStaticData.miscFrameIndex = resource->readSint32LE();
+			locationStaticData.miscFrameCount = resource->readSint32LE();
+			locationStaticData.cycleStartFrame = resource->readSint32LE();
+			locationStaticData.cycleFrameCount = resource->readSint32LE();
+
+			_currentNavigationDatabase.push_back(locationStaticData);
+		}
+
+		if (_currentNavigationDatabase.empty())
+			return false;
+	}
+
+	for (uint32 i = 0; i < _currentNavigationDatabase.size(); i++) {
+		if (location.timeZone == _currentNavigationDatabase[i].location.timeZone &&
+				location.environment == _currentNavigationDatabase[i].location.environment &&
+				location.node == _currentNavigationDatabase[i].location.node &&
+				location.facing == _currentNavigationDatabase[i].location.facing &&
+				location.orientation == _currentNavigationDatabase[i].location.orientation &&
+				location.depth == _currentNavigationDatabase[i].location.depth) {
+			sceneStaticData = _currentNavigationDatabase[i];
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool SceneViewWindow::jumpToScene(const Location &newLocation) {
+	Location oldLocation;
+	oldLocation.timeZone = -1;
+	oldLocation.environment = -1;
+	oldLocation.node = -1;
+	oldLocation.facing = -1;
+	oldLocation.orientation = -1;
+	oldLocation.depth = -1;
+
+	Location passedLocation;
+	passedLocation.timeZone = -1;
+	passedLocation.environment = -1;
+	passedLocation.node = -1;
+	passedLocation.facing = -1;
+	passedLocation.orientation = -1;
+	passedLocation.depth = -1;
+
+	// Destroy any window displayed
+	if (_infoWindowDisplayed)
+		((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
+	if (_bioChipWindowDisplayed)
+		((GameUIWindow *)_parent)->_bioChipRightWindow->destroyBioChipViewWindow();
+	if (_burnedLetterDisplayed)
+		((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
+
+	LocationStaticData  newSceneStaticData;
+	if (!getSceneStaticData(newLocation, newSceneStaticData))
+		return false;
+
+	if (_currentScene)
+		oldLocation = _currentScene->_staticData.location;
+
+	// Clear the live text window
+	if (newLocation.timeZone != oldLocation.timeZone || newLocation.environment != oldLocation.environment)
+		((GameUIWindow *)_parent)->_liveTextWindow->updateLiveText();
+
+	// Call the pre-transition function
+	if (_currentScene)
+		_currentScene->preExitRoom(this, passedLocation);
+
+	if (newLocation.timeZone != oldLocation.timeZone && newLocation.timeZone != -2)
+		initializeTimeZoneAndEnvironment(this, newLocation.timeZone, -1);
+	if (newLocation.environment != oldLocation.environment && newLocation.environment != -2)
+		initializeTimeZoneAndEnvironment(this, newLocation.timeZone, newLocation.environment);
+
+	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, passedLocation);
+
+	if (_currentScene && _currentScene->postExitRoom(this, passedLocation) == SC_DEATH)
+		return false;
+
+	if (!newScene)
+		error("Failed to create scene");
+
+	if (_currentScene) {
+		_currentScene->preDestructor();
+		delete _currentScene;
+		_currentScene = 0;
+	}
+
+	if (newLocation.timeZone != oldLocation.timeZone || newLocation.environment != oldLocation.environment || oldLocation.timeZone < 0)
+		startEnvironmentAmbient(passedLocation.timeZone, passedLocation.environment, newLocation.timeZone, newLocation.environment);
+
+	_currentScene = newScene;
+
+	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+		flushCycleFrameCache();
+
+	invalidateWindow(false);
+
+	if (_currentScene->preEnterRoom(this, passedLocation) == SC_END_PROCESSING)
+		return true;
+
+	if (_globalFlags.bcCloakingEnabled != 1)
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(newScene->_staticData);
+
+	if (newLocation.timeZone != oldLocation.timeZone)
+		((GameUIWindow *)_parent)->changeCurrentDate(newLocation.timeZone);
+
+	invalidateWindow(false);
+
+	_currentScene->postEnterRoom(this, passedLocation);
+
+	_parent->invalidateWindow(false);
+
+	if (((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+		playAIComment(newSceneStaticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+	((GameUIWindow *)_parent)->_bioChipRightWindow->sceneChanged();
+
+	return true;
+}
+
+bool SceneViewWindow::jumpToSceneRestore(const Location &newLocation) {
+	// TODO
+	return true;
+}
+
+bool SceneViewWindow::moveInDirection(int direction) {
+	if (!_currentScene)
+		return false;
+
+	((GameUIWindow *)_parent)->_navArrowWindow->updateArrow(direction, NavArrowWindow::BUTTON_SELECTED);
+
+	DestinationScene destinationData;
+
+	switch (direction) {
+	case 0: // Up
+		destinationData = _currentScene->_staticData.destUp;
+		break;
+	case 1: // Left
+		destinationData = _currentScene->_staticData.destLeft;
+		break;
+	case 2: // Right
+		destinationData = _currentScene->_staticData.destRight;
+		break;
+	case 3: // Down
+		destinationData = _currentScene->_staticData.destDown;
+		break;
+	case 4: // Forward
+		destinationData = _currentScene->_staticData.destForward;
+		break;
+	}
+
+	return moveToDestination(destinationData);
+}
+
+bool SceneViewWindow::moveToDestination(const DestinationScene &destinationData) {
+	// Close any information window
+	if (_infoWindowDisplayed)
+		((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
+	if (_bioChipWindowDisplayed)
+		((GameUIWindow *)_parent)->_bioChipRightWindow->destroyBioChipViewWindow();
+	if (_burnedLetterDisplayed)
+		((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
+
+	// Check to see if this is a valid move
+	if (destinationData.destinationScene.timeZone == -1) {
+		((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
+		return true;
+	}
+
+	assert(_currentScene); // clone2727: sanity check -- the original code was broken
+
+	LocationStaticData newSceneStaticData;
+	if (!getSceneStaticData(destinationData.destinationScene, newSceneStaticData)) {
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(_currentScene->_staticData);
+		((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
+		return true;
+	}
+
+	Location oldLocation = _currentScene->_staticData.location;
+
+	// Disable locate and clear the live text window
+	if (newSceneStaticData.location.timeZone != oldLocation.timeZone ||
+			newSceneStaticData.location.environment != oldLocation.environment ||
+			newSceneStaticData.location.node != oldLocation.node) {
+		((GameUIWindow *)_parent)->_bioChipRightWindow->disableEvidenceCapture();
+		((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(false);
+	}
+
+	// Disable the arrow window
+	((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(false);
+
+	// Get thr esults from the pre-exit room function
+	int retVal = _currentScene->preExitRoom(this, destinationData.destinationScene);
+
+	// If we died, return here
+	if (retVal == SC_DEATH)
+		return false;
+
+	// If we did not return success, the move is disallowed
+	if (retVal != SC_TRUE) {
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(_currentScene->_staticData);
+		((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
+		return true;
+	}
+
+	// Initialize the time zone and environment
+	if (newSceneStaticData.location.timeZone != oldLocation.timeZone && newSceneStaticData.location.timeZone != -2)
+		initializeTimeZoneAndEnvironment(this, newSceneStaticData.location.timeZone, -1);
+	if (newSceneStaticData.location.environment != oldLocation.environment && newSceneStaticData.location.environment != -2)
+		initializeTimeZoneAndEnvironment(this, newSceneStaticData.location.timeZone, newSceneStaticData.location.environment);
+
+	// If we are movinto a different node or time zone, reset the evidence flag
+	if (newSceneStaticData.location.timeZone != oldLocation.timeZone ||
+			newSceneStaticData.location.environment != oldLocation.environment ||
+			newSceneStaticData.location.node != oldLocation.node) {
+		if (_globalFlags.bcLocateEnabled == 1) {
+			_globalFlags.bcLocateEnabled = 0;
+			((GameUIWindow *)_parent)->_bioChipRightWindow->invalidateWindow(false);
+		}
+	}
+
+	// Create the new scene object
+	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, oldLocation);
+
+	// Switch on the type of transition
+	if (destinationData.transitionType == TRANSITION_VIDEO) {
+		// Play transition
+		playTransition(destinationData, newScene->_staticData.navFrameIndex);
+
+		// Change the ambient sound
+		if (newSceneStaticData.location.timeZone != oldLocation.timeZone || newSceneStaticData.location.environment != oldLocation.environment || oldLocation.timeZone < 0)
+			startEnvironmentAmbient(oldLocation.timeZone, oldLocation.environment, newSceneStaticData.location.timeZone, newSceneStaticData.location.environment, false);
+	} else {
+		// Change the ambient sound
+		if (newSceneStaticData.location.timeZone != oldLocation.timeZone || newSceneStaticData.location.environment != oldLocation.environment || oldLocation.timeZone < 0)
+			startEnvironmentAmbient(oldLocation.timeZone, oldLocation.environment, newSceneStaticData.location.timeZone, newSceneStaticData.location.environment);
+
+		// Play transition
+		playTransition(destinationData, newScene->_staticData.navFrameIndex);
+	}
+
+	// Call the post-exit function
+	retVal = _currentScene->postExitRoom(this, destinationData.destinationScene);
+
+	if (retVal == SC_DEATH)
+		return false;
+
+	if (retVal != SC_TRUE) {
+		newScene->preDestructor();
+		delete newScene;
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(_currentScene->_staticData);
+		((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
+		return true;
+	}
+
+	// Delete the current scene
+	_currentScene->preDestructor();
+	delete _currentScene;
+	_currentScene = newScene;
+
+	// If this scene has no cycle frames, flush the cycle frame cache
+	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+		flushCycleFrameCache();
+
+	// Call the pre-enter function, exiting this function if SC_END_PROCESSING is returned
+	if (_currentScene->preEnterRoom(this, oldLocation) == SC_END_PROCESSING)
+		return true;
+
+	// Send new navigation data to navigation buttons
+	if (_globalFlags.bcCloakingEnabled != 1)
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(newScene->_staticData);
+
+	// If this is a different time zone, then change the date
+	if (newSceneStaticData.location.timeZone != oldLocation.timeZone)
+		((GameUIWindow *)_parent)->changeCurrentDate(newSceneStaticData.location.timeZone);
+
+	// Call for a repaint
+	invalidateWindow(false);
+
+	// Call the post-enter function
+	_currentScene->postEnterRoom(this, oldLocation);
+
+	// Invalidate this too, for some reason
+	_parent->invalidateWindow(false);
+
+	// Check the AI database for this environment to see if there is a spontaneous comment for this scene
+	if (((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipAI) && !_disableArthur)
+		playAIComment(newSceneStaticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+	// Notify the right BioChip window of change
+	((GameUIWindow *)_parent)->_bioChipRightWindow->sceneChanged();
+
+	// Re-enable navigation arrows
+	((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
+
+	// Hardcoded demo ambient
+	if (_vm->isDemo() && newSceneStaticData.location.environment != oldLocation.environment)
+		_vm->_sound->setAmbientSound("CASTLE/CGBSSNG.WAV");
+
+	return true;
+}
+
+bool SceneViewWindow::timeSuitJump(int destination) {
+	// Determine if this is a valid jump
+	if (destination < 0 || destination > 4)
+		return false;
+
+	// Clear any live text
+	((GameUIWindow *)_parent)->_liveTextWindow->updateLiveText();
+
+	// Disable movement controls
+	((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(0, 0, 0, 0, 0);
+
+	Location newLocation, oldLocation;
+
+	switch (destination) {
+	case 0:
+		newLocation = Location(2, 1, 6, 1, 1, 0);
+		oldLocation = Location(-2, -2, -2, -2, -2, -2);
+		break;
+	case 1:
+		newLocation = Location(1, 1, 3, 3, 1, 0);
+		oldLocation = Location(-2, -2, -2, -2, -2, -2);
+		break;
+	case 2:
+		newLocation = Location(5, 1, 2, 4, 1, 0);
+		oldLocation = Location(-2, -2, -2, -2, -2, -2);
+		break;
+	case 3:
+		if (_globalFlags.generalWalkthroughMode == 0)
+			newLocation = Location(6, 10, 0, 0, 0, 0);
+		else
+			newLocation = Location(6, 1, 1, 1, 2, 0);
+		oldLocation = Location(-2, -2, -2, -2, -2, -2);
+		break;
+	case 4:
+		newLocation = Location(4, 3, 3, 0, 1, 0);
+		oldLocation = Location(-2, -2, -2, -2, -2, -2);
+		break;
+	}
+
+	// Save the old location to use for the scene we are leaving
+	Location specOldLocation = oldLocation;
+
+	// Call the pre-transition function
+	if (_currentScene)
+		_currentScene->preExitRoom(this, specOldLocation);
+
+	// Make sure the right BioChip is displayed
+	((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipJump);
+
+	// Play the movie
+	VideoWindow *jumpMovie = new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow);
+	if (!jumpMovie->openVideo(_vm->getString(IDS_BC_JUMP_MOVIE_FILENAME)))
+		error("Failed to play small jump movie");
+
+	// Reposition
+	jumpMovie->setWindowPos(0, 0, 28, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
+
+	// Notify the BioChip of the change
+	((GameUIWindow *)_parent)->_bioChipRightWindow->jumpInitiated(false);
+
+	// Show and disable the movie window
+	jumpMovie->enableWindow(false);
+	jumpMovie->showWindow(kWindowShow);
+
+	// Start fading down the current ambient and start the jump audio file
+	_vm->_sound->setAmbientSound();
+	_vm->_sound->playInterfaceSound(_vm->getString(IDS_BC_JUMP_AUDIO_FILENAME));
+
+	// Play the movie
+	jumpMovie->playToFrame(24);
+
+	while (!_vm->shouldQuit() && jumpMovie->getMode() != VideoWindow::kModeStopped && _vm->_sound->isInterfaceSoundPlaying()) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return true;
+
+	// Make sure the interface sound has stopped
+	_vm->_sound->stopInterfaceSound();
+
+	delete jumpMovie;
+	_vm->_sound->timerCallback();
+	jumpMovie = new VideoWindow(_vm, this);
+
+	Common::String fileName;
+	switch (destination) {
+	case 0:
+		fileName = _vm->getString(IDS_MAYAN_JUMP_MOVIE_FILENAME);
+		break;
+	case 1:
+		fileName = _vm->getString(IDS_CASTLE_JUMP_MOVIE_FILENAME);
+		break;
+	case 2:
+		fileName = _vm->getString(IDS_DAVINCI_JUMP_MOVIE_FILENAME);
+		break;
+	case 3:
+		fileName = _vm->getString(IDS_AILAB_JUMP_MOVIE_FILENAME);
+		break;
+	case 4:
+		fileName = _vm->getString(IDS_FUTAPT_JUMP_MOVIE_FILENAME);
+		break;
+	}
+
+	if (!jumpMovie->openVideo(fileName))
+		error("Failed to play movie '%s'", fileName.c_str());
+
+	jumpMovie->setWindowPos(0, 0, 0, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
+
+	// Show and disable the window
+	jumpMovie->enableWindow(false);
+	jumpMovie->showWindow(kWindowShow);
+
+	_vm->_sound->stop();
+
+	// Play the movie
+	jumpMovie->playVideo();
+
+	while (!_vm->shouldQuit() && jumpMovie->getMode() != VideoWindow::kModeStopped)
+		_vm->yield();
+
+	if (_vm->shouldQuit())
+		return true;
+
+	_vm->_sound->restart();
+	delete jumpMovie;
+
+	// Initialize the time zone and environment
+	initializeTimeZoneAndEnvironment(this, newLocation.timeZone, -1);
+	initializeTimeZoneAndEnvironment(this, newLocation.timeZone, newLocation.environment);
+
+	// Get the static scene data for this new location
+	LocationStaticData newSceneStaticData;
+	if (!getSceneStaticData(newLocation, newSceneStaticData))
+		return false;
+
+	// And the old location
+	if (_currentScene)
+		oldLocation = _currentScene->_staticData.location;
+
+	// Create the new scene object
+	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, oldLocation);
+
+	if (_currentScene) {
+		// Post-transition function
+		if (_currentScene->postExitRoom(this, specOldLocation) == SC_DEATH)
+			return false;
+
+		// Delete the old scene
+		_currentScene->preDestructor();
+		delete _currentScene;
+	}
+
+	// Set the new scene
+	_currentScene = newScene;
+
+	// If this scene has no cycle frames, flush the cycle frame cache
+	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+		flushCycleFrameCache();
+
+	// Update navigation buttons, if not cloaked
+	if (_globalFlags.bcCloakingEnabled != 1)
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(_currentScene->_staticData);
+
+	// Change the date if the time zone changed
+	if (newLocation.timeZone != oldLocation.timeZone)
+		((GameUIWindow *)_parent)->changeCurrentDate(newLocation.timeZone);
+
+	// Call for a repaint
+	invalidateWindow(false);
+	_vm->_sound->timerCallback();
+
+	// Time to show and play the right-hand small movie to the mid point, with proper sound
+	jumpMovie = new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow);
+
+	if (!jumpMovie->openVideo(_vm->getString(IDS_BC_JUMP_MOVIE_FILENAME)))
+		error("Failed to play small jump movie");
+
+	jumpMovie->setWindowPos(0, 0, 28, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
+
+	// Notify the BioChip of the change
+	((GameUIWindow *)_parent)->_bioChipRightWindow->jumpEnded(false);
+
+	jumpMovie->enableWindow(false);
+	jumpMovie->showWindow(kWindowShow);
+
+	// Start the ambient fading back up, and play the jump sound
+	startEnvironmentAmbient(oldLocation.timeZone, oldLocation.environment, newLocation.timeZone, newLocation.environment);
+	_vm->_sound->playInterfaceSound(_vm->getString(IDS_BC_JUMP_AUDIO_FILENAME));
+
+	// Play the movie
+	jumpMovie->seekToFrame(24);
+	jumpMovie->playToFrame(48);
+
+	while (!_vm->shouldQuit() && jumpMovie->getMode() != VideoWindow::kModeStopped && _vm->_sound->isInterfaceSoundPlaying()) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return true;
+
+	// Forceably stop the interface sound
+	_vm->_sound->stopInterfaceSound();
+
+	// Destroy the movie
+	delete jumpMovie;
+
+	// Repaint the BioChip view window
+	((GameUIWindow *)_parent)->_bioChipRightWindow->invalidateWindow(false);
+
+	// Repaint the window
+	invalidateWindow(false);
+	
+	// Call the post-enter function
+	_currentScene->postEnterRoom(this, oldLocation);
+	_parent->invalidateWindow(false);
+
+	if (((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+		playAIComment(newSceneStaticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+	// Notify the right BioChip window of the change
+	((GameUIWindow *)_parent)->_bioChipRightWindow->sceneChanged();
+
+	return true;
+}
+
+bool SceneViewWindow::playTransition(const DestinationScene &destinationData, int navFrame) {
+	// Call the appropriate function for the transition type
+	switch (destinationData.transitionType) {
+	case TRANSITION_PUSH:
+		if (false) { // TODO: control down check
+			if (navFrame >= 0) {
+				LocationStaticData destinationStaticData;
+				if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))
+					return false;
+
+				changeStillFrameMovie(_vm->getFilePath(destinationStaticData.location.timeZone, destinationStaticData.location.environment, SF_STILLS));
+
+				Graphics::Surface *newBackground = getStillFrameCopy(navFrame);
+				_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+				newBackground->free();
+				delete newBackground;
+			}
+			return true;
+		} else {
+			LocationStaticData destinationStaticData;
+			if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))
+				return false;
+
+			Graphics::Surface *newBackground = getStillFrameCopy(navFrame);
+			Graphics::Surface *curBackground = _preBuffer;
+
+			bool retVal = false;
+			if (destinationData.transitionData == 0 || destinationData.transitionData == 3)
+				retVal = pushTransition(curBackground, newBackground, destinationData.transitionData, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
+			else
+				retVal = pushTransition(curBackground, newBackground, destinationData.transitionData, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
+
+			newBackground->free();
+			delete newBackground;
+			return retVal;
+		}
+		break;
+	case TRANSITION_WALK:
+		if (false) { // TODO: control down check
+			if (navFrame >= 0) {
+				LocationStaticData destinationStaticData;
+				if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))
+					return false;
+
+				changeStillFrameMovie(_vm->getFilePath(destinationStaticData.location.timeZone, destinationStaticData.location.environment, SF_STILLS));
+
+				Graphics::Surface *newBackground = getStillFrameCopy(navFrame);
+				_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+				newBackground->free();
+				delete newBackground;
+			}
+			return true;
+		} else {
+			return walkTransition(_currentScene->_staticData.location, destinationData, navFrame);
+		}
+		break;
+	case TRANSITION_VIDEO:
+		if (false) { // TODO: control down check and debug mode check (maybe?)
+			if (navFrame >= 0) {
+				LocationStaticData destinationStaticData;
+				if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))
+					return false;
+
+				changeStillFrameMovie(_vm->getFilePath(destinationStaticData.location.timeZone, destinationStaticData.location.environment, SF_STILLS));
+
+				Graphics::Surface *newBackground = getStillFrameCopy(navFrame);
+				_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+				newBackground->free();
+				delete newBackground;
+			}
+			return true;
+		} else {
+			return videoTransition(_currentScene->_staticData.location, destinationData, navFrame);
+		}
+		break;
+	}
+
+	return false;
+}
+
+bool SceneViewWindow::videoTransition(const Location &location, DestinationScene destinationData, int navFrame) {
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	_paused = true;
+	bool audioStream = true;
+
+	// If the start frame is less than 0, open up the animation database and retrieve all of the info
+	if (destinationData.transitionStartFrame < 0) {
+		Common::Array<AnimEvent> animEvents = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+		bool found = false;
+		uint i = 0;
+		for (; i < animEvents.size(); i++) {
+			if (animEvents[i].animationID == destinationData.transitionData) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			_paused = false;
+			return false;
+		}
+
+		destinationData.transitionData = animEvents[i].fileNameID;
+		destinationData.transitionStartFrame = animEvents[i].startFrame;
+		destinationData.transitionLength = animEvents[i].frameCount;
+
+		if (animEvents[i].audioStreamCount < 1)
+			audioStream = false;
+	}
+
+	LocationStaticData destinationStaticData;
+	if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData)) {
+		_paused = false;
+		return false;
+	}
+	
+	changeStillFrameMovie(_vm->getFilePath(destinationStaticData.location.timeZone, destinationStaticData.location.environment, SF_STILLS));
+
+	Graphics::Surface *newBackground = 0;
+	if (destinationStaticData.navFrameIndex >= 0)
+		newBackground = getStillFrameCopy(navFrame);
+
+	// Open the movie
+	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+
+	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, destinationData.transitionData);
+	if (!animationMovie->openVideo(fileName))
+		error("Failed to open video transition movie '%s'", fileName.c_str());
+
+	if (audioStream)
+		_vm->_sound->stop();
+
+	animationMovie->seekToFrame(destinationData.transitionStartFrame);
+	animationMovie->showWindow(kWindowShow);
+	animationMovie->playToFrame(destinationData.transitionStartFrame + destinationData.transitionLength - 1);
+
+	while (!_vm->shouldQuit() && animationMovie->getMode() != VideoWindow::kModeStopped) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return true;
+
+	delete animationMovie;
+
+	if (audioStream)
+		_vm->_sound->restart();
+
+	if (newBackground) {
+		_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+		newBackground->free();
+		delete newBackground;
+	}
+
+	_vm->_gfx->setCursor(oldCursor);
+	_paused = false;
+
+	return true;
+}
+
+bool SceneViewWindow::walkTransition(const Location &location, const DestinationScene &destinationData, int navFrame) {
+	_paused = true;
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	Graphics::Surface *newBackground = 0;
+
+	if (navFrame >= 0) {
+		changeStillFrameMovie(_vm->getFilePath(destinationData.destinationScene.timeZone, destinationData.destinationScene.environment, SF_STILLS));
+		newBackground = getStillFrameCopy(navFrame);
+	}
+
+	Common::String walkFileName = _vm->getFilePath(location.timeZone, location.environment, SF_NAVIGATION);
+	if (_walkMovieFileName != walkFileName) {
+		delete _walkMovie;
+		_walkMovie = new VideoWindow(_vm, this);
+		_walkMovie->setWindowPos(kWindowPosTop, 0, 0, 0, 0, kWindowPosNoActivate | kWindowPosNoZOrder | kWindowPosNoSize);
+
+		if (!_walkMovie->openVideo(walkFileName))
+			error("Failed to open walk movie '%s'", walkFileName.c_str());
+
+		_walkMovieFileName = walkFileName;
+	}
+
+	_vm->_sound->timerCallback(); // necessary?
+
+	_walkMovie->seekToFrame(destinationData.transitionStartFrame);
+
+	if (navFrame < 0) {
+		// FIXME: Is this possible?
+		_paused = false;
+		return true;
+	}
+
+	_walkMovie->showWindow(kWindowShow);
+	_walkMovie->invalidateWindow(false);
+
+	// Start the footsteps
+	_vm->_sound->startFootsteps(destinationData.transitionData);
+
+	while (!_vm->shouldQuit() && _walkMovie->getMode() != VideoWindow::kModeStopped) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit())
+		return true;
+
+	_vm->_sound->stopFootsteps();
+
+	_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+	newBackground->free();
+	delete newBackground;
+
+	_walkMovie->showWindow(kWindowHide);
+	_vm->_gfx->setCursor(oldCursor);
+	_paused = false;
+
+	return true;
+}
+
+bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics::Surface *newBackground, int direction, int stripSize, int totalTime) {
+	// Check the validity of the parameters
+	if (!curBackground || !newBackground || direction < 0 | direction > 4 || stripSize <= 0 || totalTime < 0)
+		return false;
+
+	// Change the cursor to an hourglass
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	switch (direction) {
+	case 0: // Push down
+		for (int i = 0; i < DIB_FRAME_HEIGHT; i += stripSize) {
+			curBackground->move(0, stripSize, curBackground->h - stripSize);
+
+			for (int j = 0; j < stripSize; j++)
+				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(0, i + j), newBackground->w * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 1: // Push right
+		for (int i = 0; i < DIB_FRAME_WIDTH; i += stripSize) {
+			curBackground->move(stripSize, 0, curBackground->h);
+
+			for (int j = 0; j < curBackground->h; j++)
+				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(i, j), stripSize * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 2: // Push left
+		for (int i = 0; i < DIB_FRAME_WIDTH; i += stripSize) {
+			curBackground->move(-stripSize, 0, curBackground->h);
+
+			for (int j = 0; j < curBackground->h; j++)
+				memcpy(curBackground->getBasePtr(curBackground->w - stripSize, j), newBackground->getBasePtr(newBackground->w - i, j), stripSize * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 3: // Push up
+		for (int i = DIB_FRAME_HEIGHT - stripSize; i >= 0; i -= stripSize) {
+			curBackground->move(0, -stripSize, curBackground->h - stripSize);
+
+			for (int j = 0; j < stripSize; j++)
+				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(0, i + j), newBackground->w * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	}
+
+	_vm->_gfx->setCursor(oldCursor);
+	return true;
+}
+
+bool SceneViewWindow::pushNewTransition(Graphics::Surface *newBackground, int direction, int stripSize, int totalTime) {
+	// Check the validity of the parameters
+	if (!newBackground || direction < 0 || direction > 4 || stripSize <= 0 || totalTime < 0)
+		return false;
+
+	// Call the push transition function
+	if (direction == 0 || direction == 3)
+		return pushTransition(_preBuffer, newBackground, direction, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), totalTime);
+
+	return pushTransition(_preBuffer, newBackground, direction, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), totalTime);
+}
+
+bool SceneViewWindow::slideInTransition(Graphics::Surface *newBackground, int direction, int stripSize, int totalTime) {
+	// Check the validity of the parameters
+	if (!newBackground || direction < 0 || direction > 4 || stripSize <= 0 || totalTime < 0)
+		return false;
+
+	// Change the cursor to an hourglass
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	switch (direction) {
+	case 0: // Push down
+		for (int i = stripSize; i <= DIB_FRAME_HEIGHT; i += stripSize) {
+			for (int j = 0; j < i; j++)
+				memcpy(_preBuffer->getBasePtr(0, j), newBackground->getBasePtr(0, DIB_FRAME_HEIGHT - j), newBackground->w * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 1: // Push right
+		for (int i = stripSize; i <= DIB_FRAME_WIDTH; i += stripSize) {
+			for (int j = 0; j < DIB_FRAME_HEIGHT; j++)
+				memcpy(_preBuffer->getBasePtr(0, j), newBackground->getBasePtr(DIB_FRAME_WIDTH - i, j), i * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 2: // Push left
+		for (int i = stripSize; i <= DIB_FRAME_WIDTH; i += stripSize) {
+			for (int j = 0; j < DIB_FRAME_HEIGHT; j++)
+				memcpy(_preBuffer->getBasePtr(0, DIB_FRAME_WIDTH - i), newBackground->getBasePtr(0, j), i * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 3: // Push up
+		for (int i = stripSize; i <= DIB_FRAME_HEIGHT; i += stripSize) {
+			for (int j = 0; j < i; j++)
+				memcpy(_preBuffer->getBasePtr(0, DIB_FRAME_HEIGHT - j), newBackground->getBasePtr(0, j), newBackground->w * newBackground->format.bytesPerPixel);
+
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	}
+
+	_vm->_gfx->setCursor(oldCursor);
+	return true;
+}
+
+bool SceneViewWindow::slideOutTransition(Graphics::Surface *newBackground, int direction, int stripSize, int totalTime) {
+	// Check the validity of the parameters
+	if (!newBackground || direction < 0 || direction > 4 || stripSize <= 0 || totalTime < 0)
+		return false;
+
+	// Change the cursor to an hourglass
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	Graphics::Surface curBackground;
+	curBackground.copyFrom(*_preBuffer);
+	_useScenePaint = false;
+
+	switch (direction) {
+	case 0: // Push down
+		for (int i = stripSize; i <= DIB_FRAME_HEIGHT; i += stripSize) {
+			_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+			_vm->_gfx->crossBlit(_preBuffer, 0, i, 432, 189 - i, &curBackground, 0, 0);
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 1: // Push right
+		for (int i = DIB_FRAME_WIDTH; i >= 0; i -= stripSize) {
+			if (i < DIB_FRAME_WIDTH)
+				_vm->_gfx->crossBlit(_preBuffer, i, 0, DIB_FRAME_WIDTH - i, 189, newBackground, i, 0);
+			_vm->_gfx->crossBlit(_preBuffer, 0, 0, i, 189, &curBackground, DIB_FRAME_WIDTH - i, 0);
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 2: // Push left
+		for (int i = stripSize; i <= DIB_FRAME_WIDTH; i += stripSize) {
+			_vm->_gfx->crossBlit(_preBuffer, 0, 0, i, 189, newBackground, 0, 0);
+			_vm->_gfx->crossBlit(_preBuffer, i, 0, 432 - i, 189, &curBackground, 0, 0);
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	case 3: // Push up
+		for (int i = DIB_FRAME_HEIGHT; i >= 0; i -= stripSize) {
+			_vm->_gfx->crossBlit(_preBuffer, 0, 0, 432, 189, newBackground, 0, 0);
+			_vm->_gfx->crossBlit(_preBuffer, 0, 189 - i, 432, i, &curBackground, 0, 0);
+			invalidateWindow(false);
+			_vm->yield();
+		}
+		break;
+	}
+
+	curBackground.free();
+	_useScenePaint = true;
+	_vm->_gfx->setCursor(oldCursor);
+	return true;
+}
+
+bool SceneViewWindow::changeStillFrameMovie(const Common::String &fileName) {
+	return _stillFrames->open(fileName);
+}
+
+bool SceneViewWindow::changeCycleFrameMovie(const Common::String &fileName) {
+	// Only continue if cycling is enabled
+	if (!_cycleEnabled)
+		return false;
+
+	if (((FrameWindow *)(_parent->getParent()))->isFrameCachingAllowed())
+		return _cycleFrames->open(fileName, 5);
+
+	return _cycleFrames->open(fileName);
+}
+
+Graphics::Surface *SceneViewWindow::getStillFrameCopy(int frameIndex) {
+	return _stillFrames->getFrameCopy(frameIndex);
+}
+
+const Graphics::Surface *SceneViewWindow::getStillFrame(int frameIndex) {
+	return _stillFrames->getFrame(frameIndex);
+}
+
+Graphics::Surface *SceneViewWindow::getCycleFrameCopy(int frameIndex) {
+	if (!_cycleEnabled)
+		return 0;
+
+	return _cycleFrames->getFrameCopy(frameIndex);
+}
+
+const Graphics::Surface *SceneViewWindow::getCycleFrame(int frameIndex) {
+	if (!_cycleEnabled)
+		return 0;
+
+	return _cycleFrames->getFrame(frameIndex);
+}
+
+bool SceneViewWindow::enableCycleFrameCache(bool enable) {
+	if (!_cycleEnabled)
+		return false;
+
+	_cycleFrames->enableFrameCache(enable);
+	return true;
+}
+
+bool SceneViewWindow::flushCycleFrameCache() {
+	if (!_cycleEnabled)
+		return false;
+
+	return _cycleFrames->flushFrameCache();
+}
+
+bool SceneViewWindow::enableCycling(bool enable) {
+	_cycleEnabled = enable;
+
+	if (!enable) {
+		flushCycleFrameCache();
+		_cycleFrames->close();
+	}
+	
+	return true;
+}
+
+bool SceneViewWindow::closeCycleFrameMovie() {
+	_cycleFrames->close();
+	return true;
+}
+
+int SceneViewWindow::getGlobalFlag(int offset) {
+	// TODO: Verify the offset
+	const byte *data = (const byte *)&_globalFlags;
+	return READ_UINT16(data + offset);
+}
+
+byte SceneViewWindow::getGlobalFlagByte(int offset) {
+	// TODO: Verify the offset
+
+	if (offset < 0)
+		return 0;
+
+	const byte *data = (const byte *)&_globalFlags;
+	return data[offset];
+}
+
+bool SceneViewWindow::setGlobalFlag(int offset, int value) {
+	// TODO: Verify the offset
+
+	byte *data = (byte *)&_globalFlags;
+	WRITE_UINT16(data + offset, value);
+	return true;
+}
+
+bool SceneViewWindow::setGlobalFlagByte(int offset, byte value) {
+	// TODO: Verify the offset
+
+	byte *data = (byte *)&_globalFlags;
+	data[offset] = value;
+	return true;
+}
+
+uint32 SceneViewWindow::getGlobalFlagDWord(int offset) {
+	// TODO: Verify the offset
+	const byte *data = (const byte *)&_globalFlags;
+	return READ_UINT32(data + offset);
+}
+
+bool SceneViewWindow::setGlobalFlagDWord(int offset, uint32 value) {
+	// TODO: Verify the offset
+
+	byte *data = (byte *)&_globalFlags;
+	WRITE_UINT32(data + offset, value);
+	return true;
+}
+
+bool SceneViewWindow::addNumberToGlobalFlagTable(int tableOffset, int curItemCountOffset, int maxItems, byte numberToAdd) {
+	// TODO: Rewrite this
+	byte *data = (byte *)&_globalFlags;
+	int16 *itemCountPtr = (int16 *)(data + curItemCountOffset);
+	int itemCount = *itemCountPtr;
+
+	if (itemCount >= maxItems)
+		return false;
+
+	byte *tableEntries = data + tableOffset;
+	for (int i = 0; i < itemCount; i++)
+		if (tableEntries[i] == numberToAdd)
+			return false;
+
+	tableEntries[itemCount] = numberToAdd;
+	*itemCountPtr = itemCount + 1;
+	return true;
+}
+
+byte SceneViewWindow::getNumberFromGlobalFlagTable(int tableOffset, int tableIndex) {
+	const byte *data = (const byte *)&_globalFlags;
+	return data[tableOffset + tableIndex];
+}
+
+bool SceneViewWindow::isNumberInGlobalFlagTable(int tableOffset, int curItemCountOffset, byte numberToCheck) {
+	const byte *data = (const byte *)&_globalFlags;
+	int itemCount = *((const int16 *)(data + curItemCountOffset));
+
+	const byte *tableEntries = data + tableOffset;
+
+	for (int i = 0; i < itemCount; i++)
+		if (tableEntries[i] == numberToCheck)
+			return true;
+
+	return false;
+}
+
+bool SceneViewWindow::getCurrentSceneLocation(Location &location) {
+	if (!_currentScene)
+		return false;
+
+	location = _currentScene->_staticData.location;
+	return true;
+}
+
+bool SceneViewWindow::playSynchronousAnimation(int animationID) {
+	_useWaitCursor = true;
+
+	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+	bool found = false;
+	uint i = 0;
+	for (; i < animDatabase.size(); i++) {
+		if (animDatabase[i].animationID == animationID) {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+		return false;
+
+	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animDatabase[i].fileNameID);
+	if (!animationMovie->openVideo(fileName))
+		error("Failed to open video '%s'", fileName.c_str());
+
+	// TODO: Try switching to the second audio stream if translation is enabled
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
+		// FIXME: Nah, why bother to free the movie
+		// (Probably, this is never hit)
+		return false;
+	}
+
+	animationMovie->seekToFrame(animDatabase[i].startFrame);
+	animationMovie->enableWindow(false);
+	animationMovie->showWindow(kWindowShow);
+	_parent->invalidateWindow(false);
+
+	// Empty the input queue
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// TODO: Stop background sound if the video has sound (ugh!)
+
+	animationMovie->playToFrame(animDatabase[i].startFrame + animDatabase[i].frameCount - 1);
+
+	while (!_vm->shouldQuit() && animationMovie->getMode() != VideoWindow::kModeStopped) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit()) {
+		delete animationMovie;
+		return true;
+	}
+
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// TODO: Restart background sound if the video had sound (ugh!)
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+		return false;
+
+	delete animationMovie;
+	_useWaitCursor = false;
+	return true;
+}
+
+bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
+	_useWaitCursor = true;
+
+	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::String fileName = _vm->getFilePath(animationID);
+	if (!animationMovie->openVideo(fileName))
+		error("Failed to open video '%s'", fileName.c_str());
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
+		// FIXME: Nah, why bother to free the movie
+		// (Probably, this is never hit)
+		return false;
+	}
+
+	animationMovie->enableWindow(false);
+	animationMovie->showWindow(kWindowShow);
+	_parent->invalidateWindow(false);
+
+	// Empty the input queue
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	_vm->_sound->stop();
+	animationMovie->playVideo();
+
+	while (!_vm->shouldQuit() && animationMovie->getMode() != VideoWindow::kModeStopped) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit()) {
+		delete animationMovie;
+		return true;
+	}
+
+	_vm->_sound->restart();
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+		return false;
+
+	delete animationMovie;
+	_useWaitCursor = false;
+	return true;
+}
+
+bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left, int top) {
+	_useWaitCursor = true;
+
+	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+	bool found = false;
+	uint i = 0;
+	for (; i < animDatabase.size(); i++) {
+		if (animDatabase[i].animationID == animationID) {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+		return false;
+
+	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animDatabase[i].fileNameID);
+	if (!animationMovie->openVideo(fileName))
+		error("Failed to open video '%s'", fileName.c_str());
+
+	animationMovie->setWindowPos(kWindowPosTopMost, left, top, 0, 0, kWindowPosNoSize | kWindowPosNoActivate | kWindowPosNoZOrder);
+
+	// TODO: Try switching to the second audio stream if translation is enabled
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
+		// FIXME: Nah, why bother to free the movie
+		// (Probably, this is never hit)
+		return false;
+	}
+
+	animationMovie->seekToFrame(animDatabase[i].startFrame);
+	animationMovie->enableWindow(false);
+	animationMovie->showWindow(kWindowShow);
+	_parent->invalidateWindow(false);
+
+	// Empty the input queue
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// TODO: Stop background sound if the video has sound (ugh!)
+
+	animationMovie->playToFrame(animDatabase[i].startFrame + animDatabase[i].frameCount - 1);
+
+	while (!_vm->shouldQuit() && animationMovie->getMode() != VideoWindow::kModeStopped) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit()) {
+		delete animationMovie;
+		return true;
+	}
+
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// TODO: Restart background sound if the video had sound (ugh!)
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+		return false;
+
+	delete animationMovie;
+	_useWaitCursor = false;
+	return true;
+}
+
+bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left, int top, int right, int bottom) {
+	// TODO
+	return playPlacedSynchronousAnimation(animationID, left, top);
+}
+
+bool SceneViewWindow::startAsynchronousAnimation(int animationID, bool loopAnimation) {
+	return startPlacedAsynchronousAnimation(0, 0, 432, 189, animationID, loopAnimation);
+}
+
+bool SceneViewWindow::startAsynchronousAnimation(int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation) {
+	return startPlacedAsynchronousAnimation(0, 0, 432, 189, fileNameID, startPosition, playStartPosition, frameCount, loopAnimation);
+}
+
+bool SceneViewWindow::startAsynchronousAnimationExtern(int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation) {
+	return startPlacedAsynchronousAnimationExtern(0, 0, 432, 189, fileNameID, startPosition, playStartPosition, frameCount, loopAnimation);
+}
+
+bool SceneViewWindow::stopAsynchronousAnimation() {
+	if (!_currentScene)
+		return false;
+
+	if (!_asyncMovie)
+		return false;
+
+	_asyncMovie->stopVideo();
+
+	_currentScene->movieCallback(this, _asyncMovie, 0, MOVIE_STOPPED);
+
+	delete _asyncMovie;
+	_asyncMovie = 0;
+	_asyncMovieFileName.clear();
+	_asyncMovieStartFrame = 0;
+	_asyncMovieFrameCount = 0;
+	_loopAsyncMovie = false;
+
+	return true;
+}
+
+bool SceneViewWindow::isAsynchronousAnimationStillPlaying() {
+	if (!_asyncMovie)
+		return false;
+
+	return _asyncMovie->getMode() != VideoWindow::kModeStopped;
+}
+
+int SceneViewWindow::getAsynchronousAnimationCurrentPosition() {
+	if (!_asyncMovie)
+		return -1;
+
+	return _asyncMovie->getCurFrame();
+}
+
+bool SceneViewWindow::asynchronousAnimationTimerCallback() {
+	if (!_asyncMovie)
+		return false;
+
+	if (_asyncMovie->getMode() == VideoWindow::kModeStopped) {
+		if (_loopAsyncMovie) {
+			_asyncMovie->seekToFrame(_asyncMovieStartFrame);
+			_asyncMovie->playToFrame(_asyncMovieStartFrame + _asyncMovieFrameCount - 1);
+
+			if (_currentScene && _currentScene->movieCallback(this, _asyncMovie, -1, MOVIE_LOOPING_RESTART) == SC_FALSE)
+				return false;
+		} else {
+			if (_currentScene) {
+				if (_currentScene->movieCallback(this, _asyncMovie, -1, MOVIE_STOPPED) == SC_TRUE) {
+					stopAsynchronousAnimation();
+					return true;
+				}
+
+				return false;
+			} else {
+				stopAsynchronousAnimation();
+			}
+		}
+	}
+
+	return true;
+}
+
+bool SceneViewWindow::startPlacedAsynchronousAnimation(int left, int top, int width, int height, int animationID, bool loopAnimation) {
+	if (!_currentScene)
+		return false;
+
+	if (_walkMovie) {
+		delete _walkMovie;
+		_walkMovie = 0;
+		_walkMovieFileName.clear();
+	}
+
+	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+	if (animDatabase.empty())
+		return false;
+
+	const AnimEvent *animData = 0;
+
+	for (uint i = 0; i < animDatabase.size() && !animData; i++)
+		if (animDatabase[i].animationID == animationID)
+			animData = &animDatabase[i];
+
+	if (!animData)
+		return false;
+
+	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animData->fileNameID);
+
+	if (fileName != _asyncMovieFileName) {
+		_asyncMovieFileName.clear();
+
+		if (_asyncMovie) {
+			_asyncMovie->stopVideo();
+			_asyncMovie->closeVideo();
+		} else {
+			_asyncMovie = new VideoWindow(_vm, this);
+		}
+
+		if (!_asyncMovie->openVideo(fileName))
+			return false;
+
+		_asyncMovieFileName = fileName;
+	}
+
+	_asyncMovie->setWindowPos(0, left, top, width, height, kWindowPosNoZOrder);
+	_asyncMovie->enableWindow(false);
+
+	_asyncMovieStartFrame = animData->startFrame;
+	_asyncMovieFrameCount = animData->frameCount;
+	_loopAsyncMovie = loopAnimation;
+
+	if (_currentScene->movieCallback(this, _asyncMovie, animationID, MOVIE_START) == SC_FALSE)
+		return false;
+
+	_asyncMovie->seekToFrame(animData->startFrame);
+	_asyncMovie->showWindow(kWindowShow);
+	_asyncMovie->playToFrame(animData->startFrame + animData->frameCount - 1);
+
+	return true;
+}
+
+bool SceneViewWindow::startPlacedAsynchronousAnimation(int left, int top, int width, int height, int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation) {
+	if (!_currentScene)
+		return false;
+
+	if (_walkMovie) {
+		delete _walkMovie;
+		_walkMovie = 0;
+		_walkMovieFileName.clear();
+	}
+
+	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, fileNameID);
+
+	if (fileName != _asyncMovieFileName) {
+		_asyncMovieFileName.clear();
+
+		if (_asyncMovie) {
+			_asyncMovie->stopVideo();
+			_asyncMovie->closeVideo();
+		} else {
+			_asyncMovie = new VideoWindow(_vm, this);
+		}
+
+		if (!_asyncMovie->openVideo(fileName))
+			return false;
+
+		_asyncMovieFileName = fileName;
+	}
+
+	_asyncMovie->setWindowPos(0, left, top, width, height, kWindowPosNoZOrder);
+	_asyncMovie->enableWindow(false);
+
+	_asyncMovieStartFrame = (startPosition < 0) ? 0 : startPosition;
+	_asyncMovieFrameCount = (frameCount < 0) ? _asyncMovie->getFrameCount() : frameCount;
+	_loopAsyncMovie = loopAnimation;
+
+	if (_currentScene->movieCallback(this, _asyncMovie, 0, MOVIE_START) == SC_FALSE)
+		return false;
+
+	_asyncMovie->seekToFrame((playStartPosition < 0) ? 0 : playStartPosition);
+	_asyncMovie->showWindow(kWindowShow);
+	_asyncMovie->playToFrame(_asyncMovieStartFrame + _asyncMovieFrameCount - 1);
+
+	return true;
+}
+
+bool SceneViewWindow::startPlacedAsynchronousAnimationExtern(int left, int top, int width, int height, int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation) {
+	if (!_currentScene)
+		return false;
+
+	if (_walkMovie) {
+		delete _walkMovie;
+		_walkMovie = 0;
+		_walkMovieFileName.clear();
+	}
+
+	Common::String fileName = _vm->getFilePath(fileNameID);
+
+	if (fileName != _asyncMovieFileName) {
+		_asyncMovieFileName.clear();
+
+		if (_asyncMovie) {
+			_asyncMovie->stopVideo();
+			_asyncMovie->closeVideo();
+		} else {
+			_asyncMovie = new VideoWindow(_vm, this);
+		}
+
+		if (!_asyncMovie->openVideo(fileName))
+			return false;
+
+		_asyncMovieFileName = fileName;
+	}
+
+	_asyncMovie->setWindowPos(0, left, top, width, height, kWindowPosNoZOrder);
+	_asyncMovie->enableWindow(false);
+
+	_asyncMovieStartFrame = (startPosition < 0) ? 0 : startPosition;
+	_asyncMovieFrameCount = (frameCount < 0) ? _asyncMovie->getFrameCount() : frameCount;
+	_loopAsyncMovie = loopAnimation;
+
+	if (_currentScene->movieCallback(this, _asyncMovie, 0, MOVIE_START) == SC_FALSE)
+		return false;
+
+	_asyncMovie->seekToFrame((playStartPosition < 0) ? 0 : playStartPosition);
+	_asyncMovie->showWindow(kWindowShow);
+	_asyncMovie->playToFrame(_asyncMovieStartFrame + _asyncMovieFrameCount - 1);
+
+	return true;
+}
+
+bool SceneViewWindow::retrieveAICommentEntry(const Location &commentLocation, int commentType, const Common::Array<AIComment> &commentDatabase, int &lastFoundIndex, AIComment &currentCommentData) {
+	if (commentDatabase.empty())
+		return false;
+
+	const AIComment *commentData = &commentDatabase[lastFoundIndex];
+
+	bool entryFound = false;
+
+	if (_globalFlags.generalWalkthroughMode == 1 && commentType == AI_COMMENT_TYPE_SPONTANEOUS) {
+		// Look for any spontaneous comments
+		for (; lastFoundIndex < (int)commentDatabase.size() && !entryFound; lastFoundIndex++) {
+			if ((commentData->commentFlags & AI_COMMENT_TYPE_SPONTANEOUS || (commentData->commentFlags & AI_COMMENT_TYPE_HELP && commentData->dependencyValueA == 0))
+					&& (commentLocation.timeZone == commentData->location.timeZone || commentData->location.timeZone == -1)
+					&& (commentLocation.environment == commentData->location.environment || commentData->location.environment == -1)
+					&& (commentLocation.node == commentData->location.node || commentData->location.node == -1)
+					&& (commentLocation.facing == commentData->location.facing || commentData->location.facing == -1)
+					&& (commentLocation.orientation == commentData->location.orientation || commentData->location.orientation == -1)
+					&& (commentLocation.depth == commentData->location.depth || commentData->location.depth == -1)) {
+				entryFound = true;
+			} else {
+				commentData++;
+			}
+		}
+	} else {
+		for (; lastFoundIndex < (int)commentDatabase.size() && !entryFound; lastFoundIndex++) {
+			if ((commentData->commentFlags & commentType)
+					&& (commentLocation.timeZone == commentData->location.timeZone || commentData->location.timeZone == -1)
+					&& (commentLocation.environment == commentData->location.environment || commentData->location.environment == -1)
+					&& (commentLocation.node == commentData->location.node || commentData->location.node == -1)
+					&& (commentLocation.facing == commentData->location.facing || commentData->location.facing == -1)
+					&& (commentLocation.orientation == commentData->location.orientation || commentData->location.orientation == -1)
+					&& (commentLocation.depth == commentData->location.depth || commentData->location.depth == -1)) {
+				entryFound = true;
+			} else {
+				commentData++;
+			}
+		}
+	}
+
+	if (entryFound)
+		currentCommentData = *commentData;
+
+	currentCommentData.location = commentLocation;
+
+	return entryFound;
+}
+
+bool SceneViewWindow::checkAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	// Ignore comments designed for solely adventure mode in walkthrough mode
+	if (_globalFlags.generalWalkthroughMode == 1 && commentData.commentFlags & AI_COMMENT_DISABLE_IN_WALKTHROUGH)
+		return false;
+
+	byte flagValueA = 0;
+	if (commentData.commentFlags & AI_DEPENDENCY_FLAG_NON_BASE_DERIVED_A)
+		flagValueA = getGlobalFlagByte(commentData.dependencyFlagOffsetA);
+	else
+		flagValueA = _globalFlags.aiData[commentData.dependencyFlagOffsetA];
+
+	bool dependencyA;
+	if (commentData.commentFlags & AI_DEPENDENCY_CHECK_FOR_MINIMUM_A)
+		dependencyA = flagValueA >= commentData.dependencyValueA;
+	else
+		dependencyA = flagValueA <= commentData.dependencyValueA;
+
+	if (!dependencyA)
+		return false;
+
+	if (commentData.commentFlags & AI_COMMENT_FLAG_SPECIAL_LOGIC)
+		return checkCustomAICommentDependencies(commentLocation, commentData);
+
+	byte flagValueB = 0;
+	if (commentData.commentFlags & AI_DEPENDENCY_FLAG_NON_BASE_DERIVED_B)
+		flagValueB = getGlobalFlagByte(commentData.dependencyFlagOffsetB);
+	else
+		flagValueB = _globalFlags.aiData[commentData.dependencyFlagOffsetB];
+
+	bool dependencyB;
+	if (commentData.commentFlags & AI_DEPENDENCY_CHECK_FOR_MINIMUM_B)
+		dependencyB = flagValueB >= commentData.dependencyValueB;
+	else
+		dependencyB = flagValueB <= commentData.dependencyValueB;
+
+	return dependencyB;
+}
+
+bool SceneViewWindow::playAICommentFromData(const AIComment &commentData) {
+	if (_vm->_sound->isAsynchronousAICommentPlaying())
+		return false;
+
+	Common::String commentFileName = "BITDATA/";
+
+	switch (commentData.location.timeZone) {
+	case 1: // Castle
+		commentFileName += "CASTLE/";
+
+		switch (commentData.location.environment) {
+		case 1:
+			commentFileName += "CGTT";
+			break;
+		case 2:
+			commentFileName += "CGTS";
+			break;
+		case 3:
+			commentFileName += "CGMW";
+			break;
+		case 4:
+			commentFileName += "CGMB";
+			break;
+		case 5:
+			commentFileName += "CGBS";
+			break;
+		case 6:
+			commentFileName += "CGKC";
+			break;
+		case 7:
+			commentFileName += "CGST";
+			break;
+		case 8:
+			commentFileName += "CGKS";
+			break;
+		case 9:
+			commentFileName += "CGSR";
+			break;
+		case 10:
+			commentFileName += "CGTR";
+			break;
+		default:
+			return false;
+		}
+		break;
+	case 2: // Mayan
+		commentFileName += "MAYAN/";
+
+		switch (commentData.location.environment) {
+		case 1:
+			commentFileName += "MYTP";
+			break;
+		case 2:
+			commentFileName += "MYMC";
+			break;
+		case 3:
+			commentFileName += "MYWG";
+			break;
+		case 4:
+			commentFileName += "MYWT";
+			break;
+		case 5:
+			commentFileName += "MYAG";
+			break;
+		case 6:
+			commentFileName += "MYDG";
+			break;
+		default:
+			return false;
+		}
+		break;
+	case 3: // Future Apartment
+		commentFileName += "FUTAPT/";
+
+		switch (commentData.location.environment) {
+		case 1:
+			commentFileName += "FAKI";
+			break;
+		case 2:
+			commentFileName += "FAER";
+			break;
+		case 3:
+			commentFileName += "FAMN";
+			break;
+		default:
+			return false;
+		}
+		break;
+	case 4: // Da Vinci
+		commentFileName += "DAVINCI/";
+
+		switch (commentData.location.environment) {
+		case 1:
+			commentFileName += "DSPT";
+			break;
+		case 2:
+			commentFileName += "DSCT";
+			break;
+		case 3:
+			commentFileName += "DSGD";
+			break;
+		case 4:
+			commentFileName += "DSWS";
+			break;
+		case 5:
+			commentFileName += "DSCY";
+			break;
+		default:
+			return false;
+		}
+		break;
+	case 5: // Space Station
+		commentFileName += "AILAB/";
+
+		switch (commentData.location.environment) {
+		case 1:
+			commentFileName += "AIHW";
+			break;
+		case 2:
+			commentFileName += "AICR";
+			break;
+		case 3:
+			commentFileName += "AIDB";
+			break;
+		case 4:
+			commentFileName += "AISC";
+			break;
+		case 5:
+			commentFileName += "AINX";
+			break;
+		case 6:
+			commentFileName += "AIIC";
+			break;
+		case 7:
+			commentFileName += "AISW";
+			break;
+		case 8:
+			commentFileName += "AIMR";
+			break;
+		case 9:
+			// There is no 9.
+			return false;
+		case 10:
+			commentFileName += "AIHW";
+			break;
+		default:
+			return false;
+		}
+		break;
+	default:
+		return false;
+	}
+
+	commentFileName += "_";
+
+	if (commentData.commentFlags & AI_COMMENT_TYPE_INFORMATION)
+		commentFileName += "I";
+	if (commentData.commentFlags & AI_COMMENT_TYPE_HELP)
+		commentFileName += "H";
+	if (commentData.commentFlags & AI_COMMENT_TYPE_SPONTANEOUS)
+		commentFileName += "C";
+	if (commentData.commentFlags & AI_COMMENT_TYPE_OTHER)
+		commentFileName += "O";
+
+	commentFileName += Common::String::format("%02d.BTA", commentData.commentID);
+
+	Cursor currentCursor = _vm->_gfx->setCursor(kCursorWait);
+	bool playedSuccessfully = _vm->_sound->playAsynchronousAIComment(commentFileName);
+	_vm->_gfx->setCursor(currentCursor);
+
+	if (playedSuccessfully) {
+		_lastAICommentFileName = commentFileName;
+
+		// This is pure evil. Ugh.
+		// The [g|s]etGlobalFlagByte nonsense, anyway.
+
+		byte flagValue = 0;
+		if (commentData.commentFlags & AI_STATUS_FLAG_NON_BASE_DERIVED)
+			flagValue = getGlobalFlagByte(commentData.statusFlagOffset);
+		else
+			flagValue = _globalFlags.aiData[commentData.statusFlagOffset];
+
+		flagValue++;
+
+		if (commentData.commentFlags & AI_STATUS_FLAG_NON_BASE_DERIVED)
+			setGlobalFlagByte(commentData.statusFlagOffset, flagValue);
+		else
+			_globalFlags.aiData[commentData.statusFlagOffset] = flagValue;
+
+		return true;
+	}
+
+	return false;
+}
+
+bool SceneViewWindow::playAIComment(int commentType) {
+	if (!_currentScene)
+		return false;
+
+	if (_vm->_sound->isAsynchronousAICommentPlaying())
+		return false;
+
+	return playAIComment(_currentScene->_staticData.location, commentType);
+}
+
+bool SceneViewWindow::playAIComment(const Location &commentLocation, int commentType) {
+	// Make sure no other comments are playing
+	if (_vm->_sound->isAsynchronousAICommentPlaying())
+		return false;
+
+	Common::Array<AIComment> commentDatabase = getAICommentDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+	if (commentDatabase.empty())
+		return false;
+
+	AIComment currentCommentData;
+	int lastFoundEntry = 0;
+	bool playedSuccessfully = false;
+
+	while (retrieveAICommentEntry(commentLocation, commentType, commentDatabase, lastFoundEntry, currentCommentData) && !playedSuccessfully)
+		if (checkAICommentDependencies(commentLocation, currentCommentData))
+			playedSuccessfully = playAICommentFromData(currentCommentData);
+
+	if (playedSuccessfully) {
+		if (commentType == AI_COMMENT_TYPE_HELP && _globalFlags.generalWalkthroughMode == 0)
+			_globalFlags.scoreHintsTotal++;
+
+		return true;
+	}
+
+	return false;
+}
+
+bool SceneViewWindow::checkForAIComment(int commentType) {
+	if (!_currentScene)
+		return false;
+
+	return checkForAIComment(_currentScene->_staticData.location, commentType);
+}
+
+bool SceneViewWindow::checkForAIComment(const Location &commentLocation, int commentType) {
+	Common::Array<AIComment> commentDatabase = getAICommentDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+	if (commentDatabase.empty())
+		return false;
+
+	AIComment currentCommentData;
+	int lastFoundEntry = 0;
+
+	while (retrieveAICommentEntry(commentLocation, commentType, commentDatabase, lastFoundEntry, currentCommentData))
+		if (checkAICommentDependencies(commentLocation, currentCommentData))
+			return true;
+
+	return false;
+}
+
+bool SceneViewWindow::infoWindowDisplayed(bool flag) {
+	if (flag && !_walkMovie) {
+		delete _walkMovie;
+		_walkMovie = 0;
+		_walkMovieFileName.clear();
+		changeCycleFrameMovie();
+	}
+
+	if (_asyncMovie) {
+		if (flag)
+			_asyncMovie->showWindow(kWindowHide);
+		else
+			_asyncMovie->showWindow(kWindowShow);
+	}
+
+	if (_bioChipWindowDisplayed && flag)
+		((GameUIWindow *)_parent)->_bioChipRightWindow->destroyBioChipViewWindow();
+
+	_infoWindowDisplayed = flag;
+	return true;
+}
+
+bool SceneViewWindow::bioChipWindowDisplayed(bool flag) {
+	if (flag && !_walkMovie) {
+		delete _walkMovie;
+		_walkMovie = 0;
+		_walkMovieFileName.clear();
+		changeCycleFrameMovie();
+	}
+
+	if (_asyncMovie) {
+		if (flag)
+			_asyncMovie->showWindow(kWindowHide);
+		else
+			_asyncMovie->showWindow(kWindowShow);
+	}
+
+	if (_infoWindowDisplayed && flag)
+		((GameUIWindow *)_parent)->_inventoryWindow->destroyInfoWindow();
+
+	_bioChipWindowDisplayed = flag;
+	return true;
+}
+
+bool SceneViewWindow::burnedLetterWindowDisplayed(bool flag) {
+	if (flag && !_walkMovie) {
+		delete _walkMovie;
+		_walkMovie = 0;
+		_walkMovieFileName.clear();
+		changeCycleFrameMovie();
+	}
+
+	if (_asyncMovie) {
+		if (flag)
+			_asyncMovie->showWindow(kWindowHide);
+		else
+			_asyncMovie->showWindow(kWindowShow);
+	}
+
+	if (_burnedLetterDisplayed)
+		((GameUIWindow *)_parent)->_inventoryWindow->destroyBurnedLetterWindow();
+
+	_burnedLetterDisplayed = flag;
+	return true;
+}
+
+bool SceneViewWindow::isAuxWindowDisplayed() {
+	return _burnedLetterDisplayed || _infoWindowDisplayed || _bioChipWindowDisplayed;
+}
+
+void SceneViewWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_currentScene && _globalFlags.bcLocateEnabled == 0)
+		_currentScene->mouseDown(this, point);
+}
+
+void SceneViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_currentScene) {
+		if (_globalFlags.bcLocateEnabled == 0)
+			_currentScene->mouseUp(this, point);
+		else
+			_currentScene->locateAttempted(this, point);
+	}
+}
+
+void SceneViewWindow::onMouseMove(const Common::Point &point, uint flags) {
+	_curMousePos = point;
+	if (_currentScene)
+		_currentScene->mouseMove(this, point);
+}
+
+void SceneViewWindow::onKeyUp(const Common::KeyState &key, uint flags) {
+	switch (key.keycode) {
+	case Common::KEYCODE_a:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipAI);
+			return;
+		}
+		break;
+	case Common::KEYCODE_b:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipBlank)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipBlank);
+			return;
+		}
+		break;
+	case Common::KEYCODE_c:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipCloak)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipCloak);
+			return;
+		}
+		break;
+	case Common::KEYCODE_e:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipEvidence)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipEvidence);
+			return;
+		}
+		break;
+	case Common::KEYCODE_f:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipFiles)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipFiles);
+			return;
+		}
+		break;
+	case Common::KEYCODE_i:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipInterface)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
+			return;
+		}
+		break;
+	case Common::KEYCODE_j:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipJump)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipJump);
+			return;
+		}
+		break;
+	case Common::KEYCODE_t:
+		if ((key.flags & Common::KBD_CTRL) && ((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipTranslate)) {
+			((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipTranslate);
+			return;
+		}
+		break;
+	case Common::KEYCODE_p:
+		if (key.flags & Common::KBD_CTRL) {
+			// TODO: Pause game
+			return;
+		}
+		break;
+	case Common::KEYCODE_q:
+		if (key.flags & Common::KBD_CTRL) {
+			// TODO: Return to main menu
+			return;
+		}
+		break;
+	case Common::KEYCODE_SPACE:
+		if (((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipAI) && _globalFlags.bcCloakingEnabled != 1) {
+			if (!_lastAICommentFileName.empty() && !_vm->_sound->isAsynchronousAICommentPlaying()) {
+				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+				_vm->_sound->playAsynchronousAIComment(_lastAICommentFileName);
+				_vm->_gfx->setCursor(oldCursor);
+			}
+			return;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (_currentScene)
+		_currentScene->onCharacter(this, key);
+}
+
+void SceneViewWindow::onPaint() {
+	// TODO: I think this should draw when the burned letter is displayed, since I modified that code
+	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed && !_burnedLetterDisplayed && !_asyncMovie) {
+		if (_currentScene->_staticData.navFrameIndex >= -1) {
+			if (_useScenePaint)
+				_currentScene->paint(this, _preBuffer);
+		} else {
+			return;
+		}
+
+		// If we have a sprite, update the prebuffer with it now
+		_vm->_gfx->opaqueTransparentBlit(_preBuffer, _currentSprite.xPos, _currentSprite.yPos, _currentSprite.width, _currentSprite.height, _currentSprite.image, 0, 0, 0, _currentSprite.redTrans, _currentSprite.greenTrans, _currentSprite.blueTrans);
+
+		// Update the screen
+		_vm->_gfx->blit(_preBuffer, 0, 0);
+
+		if (_useScenePaint)
+			_currentScene->gdiPaint(this);
+	}
+}
+
+void SceneViewWindow::onTimer(uint timer) {
+	_vm->_sound->timerCallback();
+
+	if (_paused)
+		return;
+
+	if (_asyncMovie)
+		asynchronousAnimationTimerCallback();
+
+	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed && !_burnedLetterDisplayed)
+		_currentScene->timerCallback(this);
+
+	_vm->_sound->timerCallback();
+}
+
+bool SceneViewWindow::onSetCursor(uint message) {
+	if (_useWaitCursor) {
+		_vm->_gfx->setCursor(kCursorWait);
+		return true;
+	}
+
+	// Check the scene cursor callback function to see if we need to change the cursor
+	int newCursor = (int)kCursorArrow;
+	if (_currentScene)
+		newCursor = _currentScene->specifyCursor(this, _curMousePos);
+
+	// If the locate button is enabled, follow different logic
+	if (_globalFlags.bcLocateEnabled == 1) {
+		if (_curCursor >= 0 || (newCursor > 65530 && newCursor != _curCursor)) {
+			// If the new cursor is less than zero, use it, otherwise use the default locate cursor
+			if (newCursor > 65533) {
+				if (newCursor == 65534)
+					_curCursor = (int)kCursorLocateB;
+				else
+					_curCursor = (int)kCursorLocateA;
+			} else {
+				_curCursor = (int)kCursorLocateA;
+			}
+		}
+	}
+
+	_vm->_gfx->setCursor((Cursor)_curCursor);
+	return true;
+}
+
+void SceneViewWindow::onEnable(bool enable) {
+	// If we're enabling, clear out the message queue of mouse messages
+	_vm->removeMouseMessages(this);
+}
+
+int SceneViewWindow::draggingItem(int itemID, const Common::Point &location, int itemFlags) {
+	if (!_currentScene)
+		return 0;
+
+	return _currentScene->draggingItem(this, itemID, location, itemFlags);
+}
+
+int SceneViewWindow::droppedItem(int itemID, const Common::Point &location, int itemFlags) {
+	if (!_currentScene)
+		return 0;
+
+	return _currentScene->droppedItem(this, itemID, location, itemFlags);
+}
+
+bool SceneViewWindow::updatePrebufferWithSprite(Sprite &spriteData) {
+	if (_currentSprite.image != spriteData.image && _currentSprite.image != 0) {
+		_currentSprite.image->free();
+		delete _currentSprite.image;
+	}
+
+	_currentSprite = spriteData;
+	invalidateWindow(false);
+	return true;
+}
+
+bool SceneViewWindow::changeSpriteStatus(bool status) {
+	bool prevStatus = _useSprite;
+	_useSprite = status;
+	return prevStatus;
+}
+
+bool SceneViewWindow::resetCursor() {
+	_vm->_gfx->setCursor((Cursor)_curCursor);
+	return true;
+}
+
+bool SceneViewWindow::displayLiveText(const Common::String &text, bool notifyUser) {
+	if (((GameUIWindow *)_parent)->_liveTextWindow)
+		return ((GameUIWindow *)_parent)->_liveTextWindow->updateLiveText(text, notifyUser);
+
+	return false;
+}
+
+bool SceneViewWindow::displayTranslationText(const Common::String &text) {
+	if (((GameUIWindow *)_parent)->_liveTextWindow)
+		return ((GameUIWindow *)_parent)->_liveTextWindow->updateTranslationText(text);
+	
+	return false;
+}
+
+Common::Array<AnimEvent> SceneViewWindow::getAnimationDatabase(int timeZone, int environment) {
+	Common::SeekableReadStream *stream = _vm->getAnimData(_vm->computeAnimDBResourceID(timeZone, environment));
+	stream->readUint16LE();
+
+	Common::Array<AnimEvent> animEvents;
+	while (stream->pos() < stream->size()) {
+		AnimEvent animEvent;
+		animEvent.animationID = stream->readSint16LE();
+		animEvent.fileNameID = stream->readSint16LE();
+		animEvent.audioStreamCount = stream->readSint16LE();
+		animEvent.startFrame = stream->readSint32LE();
+		animEvent.frameCount = stream->readSint32LE();
+		animEvents.push_back(animEvent);
+	}
+
+	delete stream;
+	return animEvents;
+}
+
+Common::Array<AIComment> SceneViewWindow::getAICommentDatabase(int timeZone, int environment) {
+	Common::SeekableReadStream *stream = _vm->getAnimData(_vm->computeAIDBResourceID(timeZone, environment));
+	Common::Array<AIComment> comments;
+
+	if (!stream)
+		return comments;
+
+	stream->readUint16LE();
+	
+	while (stream->pos() < stream->size()) {
+		AIComment comment;
+		comment.location.timeZone = stream->readSint16LE();
+		comment.location.environment = stream->readSint16LE();
+		comment.location.node = stream->readSint16LE();
+		comment.location.facing = stream->readSint16LE();
+		comment.location.orientation = stream->readSint16LE();
+		comment.location.depth = stream->readSint16LE();
+		comment.commentID = stream->readUint16LE();
+		comment.commentFlags = stream->readUint16LE();
+		comment.dependencyFlagOffsetA = stream->readUint16LE();
+		comment.dependencyValueA = stream->readUint16LE();
+		comment.dependencyFlagOffsetB = stream->readUint16LE();
+		comment.dependencyValueB = stream->readUint16LE();
+		comment.statusFlagOffset = stream->readUint16LE();
+		comments.push_back(comment);
+	}
+
+	delete stream;
+	return comments;
+}
+
+bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	// TODO
+	return false;
+}
+
+bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironment, int timeZone, int environment, bool fade) {
+	// TODO
+	return false;
+}
+
+SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+	return 0;
+}
+
+bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment) {
+	// TODO
+	return false;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
new file mode 100644
index 0000000000..0d1b7a9d04
--- /dev/null
+++ b/engines/buried/scene_view.h
@@ -0,0 +1,202 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_SCENE_VIEW_H
+#define BURIED_SCENE_VIEW_H
+
+#include "buried/aidata.h"
+#include "buried/animdata.h"
+#include "buried/global_flags.h"
+#include "buried/sprtdata.h"
+#include "buried/window.h"
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Buried {
+
+class AVIFrames;
+class SceneBase;
+class VideoWindow;
+
+class SceneViewWindow : public Window {
+public:
+	SceneViewWindow(BuriedEngine *vm, Window *parent);
+	~SceneViewWindow();
+
+	bool _paused;
+	bool _disableArthur;
+
+	bool startNewGame(bool walkthrough = false);
+	bool startNewGameIntro(bool walkthrough = false);
+	bool startNewGame(const Location &startingLocation);
+	bool startNewGame(const Common::String &restoreFile);
+	bool showDeathScene(int deathSceneIndex);
+	bool showCompletionScene();
+
+	bool getSceneStaticData(const Location &location, LocationStaticData &sceneStaticData);
+	GlobalFlags &getGlobalFlags() { return _globalFlags; }
+	bool getCurrentSceneLocation(Location &curLocation);
+
+	bool jumpToScene(const Location &newLocation);
+	bool jumpToSceneRestore(const Location &newLocation);
+	bool moveInDirection(int direction);
+	bool moveToDestination(const DestinationScene &destinationData);
+	bool timeSuitJump(int destination);
+
+	bool playTransition(const DestinationScene &destinationData, int navFrame);
+	bool videoTransition(const Location &location, DestinationScene destinationData, int navFrame);
+	bool walkTransition(const Location &location, const DestinationScene &destinationData, int navFrame);
+	bool pushTransition(Graphics::Surface *curBackground, Graphics::Surface *newBackground, int direction, int stripSize, int totalTime);
+	bool pushNewTransition(Graphics::Surface *newBackground, int direction, int stripSize, int totalTime);
+	bool slideInTransition(Graphics::Surface *newBackground, int direction, int stripSize, int totalTime);
+	bool slideOutTransition(Graphics::Surface *newBackground, int direction, int stripSize, int totalTime);
+
+	bool changeStillFrameMovie(const Common::String &fileName = "");
+	bool changeCycleFrameMovie(const Common::String &fileName = "");
+
+	Graphics::Surface *getStillFrameCopy(int frameIndex);
+	const Graphics::Surface *getStillFrame(int frameIndex);
+	Graphics::Surface *getCycleFrameCopy(int frameIndex);
+	const Graphics::Surface *getCycleFrame(int frameIndex);
+	bool enableCycleFrameCache(bool enable);
+	bool flushCycleFrameCache();
+	bool enableCycling(bool enable);
+	bool getCyclingStatus() { return _cycleEnabled; }
+	bool closeCycleFrameMovie();
+
+	int getGlobalFlag(int offset);
+	byte getGlobalFlagByte(int offset);
+	bool setGlobalFlag(int offset, int value);
+	bool setGlobalFlagByte(int offset, byte value);
+	bool setGlobalFlagDWord(int offset, uint32 value);
+	uint32 getGlobalFlagDWord(int offset);
+	bool addNumberToGlobalFlagTable(int offset, int curItemCountOffset, int maxItems, byte numberToAdd);
+	byte getNumberFromGlobalFlagTable(int offset, int tableIndex);
+	bool isNumberInGlobalFlagTable(int offset, int curItemCountOffset, byte numberToCheck);
+
+	bool playSynchronousAnimation(int animationID);
+	bool playSynchronousAnimationExtern(int animationID);
+	bool playPlacedSynchronousAnimation(int animationID, int left, int top);
+	bool playClippedSynchronousAnimation(int animationID, int left, int top, int right, int bottom);
+
+	bool startAsynchronousAnimation(int animationID, bool loopAnimation);
+	bool startAsynchronousAnimation(int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation);
+	bool startAsynchronousAnimationExtern(int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation);
+	bool stopAsynchronousAnimation();
+	bool isAsynchronousAnimationStillPlaying();
+	int getAsynchronousAnimationCurrentPosition();
+	bool asynchronousAnimationTimerCallback();
+	bool startPlacedAsynchronousAnimation(int left, int top, int width, int height, int animationID, bool loopAnimation);
+	bool startPlacedAsynchronousAnimation(int left, int top, int width, int height, int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation);
+	bool startPlacedAsynchronousAnimationExtern(int left, int top, int width, int height, int fileNameID, int startPosition, int playStartPosition, int frameCount, bool loopAnimation);
+
+	bool retrieveAICommentEntry(const Location &commentLocation, int commentType, const Common::Array<AIComment> &commentDatabase, int &lastFoundEntry, AIComment &currentCommentData);
+	bool checkAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
+	bool playAICommentFromData(const AIComment &commentData);
+	bool playAIComment(int commentType);
+	bool playAIComment(const Location &commentLocation, int commentType);
+	bool checkForAIComment(int commentType);
+	bool checkForAIComment(const Location &commentLocation, int commentType);
+
+	bool infoWindowDisplayed(bool flag);
+	bool bioChipWindowDisplayed(bool flag);
+	bool burnedLetterWindowDisplayed(bool flag);
+	bool isAuxWindowDisplayed();
+
+	void onPaint();
+	void onTimer(uint timer);
+	bool onSetCursor(uint message);
+	void onEnable(bool enable);
+
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+
+	void onKeyUp(const Common::KeyState &key, uint flags);
+	
+	bool isScenePresent() { return _currentScene != 0; }
+	int draggingItem(int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(int itemID, const Common::Point &pointLocation, int itemFlags);
+
+	bool updatePrebufferWithSprite(Sprite &spriteData);
+	bool changeSpriteStatus(bool status);
+	bool resetCursor();
+
+	bool displayLiveText(const Common::String &text = "", bool notifyUser = true);
+	bool displayTranslationText(const Common::String &text);
+
+	bool resetNavigationArrows();
+
+	bool startEnvironmentAmbient(int oldTimeZone = -1, int oldEnvironment = -1, int timeZone = -1, int environment = -1, bool fade = true);
+	bool checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
+
+private:
+	Graphics::Surface *_preBuffer;
+	SceneBase *_currentScene;
+	Common::Array<LocationStaticData> _currentNavigationDatabase;
+	GlobalFlags _globalFlags;
+	VideoWindow *_walkMovie;
+
+	Common::String _walkMovieFileName;
+
+	AVIFrames *_stillFrames;
+	AVIFrames *_cycleFrames;
+	Common::Point _curMousePos;
+	int _curCursor;
+	Sprite _currentSprite;
+	int _currentAmbient;
+	bool _useScenePaint;
+	bool _useSprite;
+	bool _cycleEnabled;
+	uint _timer;
+	uint _soundTimer;
+
+	bool _infoWindowDisplayed;
+	bool _bioChipWindowDisplayed;
+	bool _burnedLetterDisplayed;
+
+	VideoWindow *_asyncMovie;
+	Common::String _asyncMovieFileName;
+	int _asyncMovieStartFrame;
+	int _asyncMovieFrameCount;
+	bool _loopAsyncMovie;
+
+	Common::String _lastAICommentFileName;
+
+	bool _useWaitCursor;
+	int _oldCursorForWait;
+
+	bool initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment);
+	SceneBase *constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
+	Common::Array<AnimEvent> getAnimationDatabase(int timeZone, int environment);
+	Common::Array<AIComment> getAICommentDatabase(int timeZone, int environment);
+};
+
+} // End of namespace Buried
+
+#endif


Commit: b460830309496a9b20cecc8845fbe3642e55ae52
    https://github.com/scummvm/scummvm/commit/b460830309496a9b20cecc8845fbe3642e55ae52
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the old apartment scene

The second part of the intro partially plays correctly now!

Changed paths:
  A engines/buried/environ/scene_factory.cpp
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/module.mk
    engines/buried/resources.h
    engines/buried/scene_view.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index e8d6783f05..b9e3a87f3a 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -385,7 +385,7 @@ uint32 BuriedEngine::getVersion() {
 }
 
 Common::String BuriedEngine::getFilePath(int timeZone, int environment, int fileOffset) {
-	return getFilePath(RESID_FILENAMES_BASE + RESOFFSET_FILENAME_TIMEZONE * timeZone + RESOFFSET_FILENAME_ENVIRON * environment + fileOffset);
+	return getFilePath(computeFileNameResourceID(timeZone, environment, fileOffset));
 }
 
 uint32 BuriedEngine::computeNavDBResourceID(int timeZone, int environment) {
@@ -400,4 +400,8 @@ uint32 BuriedEngine::computeAIDBResourceID(int timeZone, int environment) {
 	return RESID_AI_DB_BASE + RESOFFSET_AI_DB_TIMEZONE * timeZone + environment;
 }
 
+uint32 BuriedEngine::computeFileNameResourceID(int timeZone, int environment, int fileOffset) {
+	return RESID_FILENAMES_BASE + RESOFFSET_FILENAME_TIMEZONE * timeZone + RESOFFSET_FILENAME_ENVIRON * environment + fileOffset;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index fcc3015419..ab7fee6b93 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -83,6 +83,7 @@ public:
 	uint32 computeNavDBResourceID(int timeZone, int environment);
 	uint32 computeAnimDBResourceID(int timeZone, int environment);
 	uint32 computeAIDBResourceID(int timeZone, int environment);
+	uint32 computeFileNameResourceID(int timeZone, int environment, int fileOffset);
 
 	GraphicsManager *_gfx;
 	Database *_mainEXE;
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
new file mode 100644
index 0000000000..698b55667b
--- /dev/null
+++ b/engines/buried/environ/scene_factory.cpp
@@ -0,0 +1,111 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/biochip_right.h"
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/invdata.h"
+#include "buried/inventory_window.h"
+#include "buried/message.h"
+#include "buried/navarrow.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+class OldApartmentSuitCap : public SceneBase {
+public:
+	OldApartmentSuitCap(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation)
+			: SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {}
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+int OldApartmentSuitCap::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Cloak before continuing
+	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipCloak);
+	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(18, 130), 0));
+
+	// Play the second piece of the intro movie
+	((SceneViewWindow *)viewWindow)->playSynchronousAnimationExtern(_vm->computeFileNameResourceID(_staticData.location.timeZone, _staticData.location.environment, 3));
+
+	// Disable cloak before continuing
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled = 0;
+	((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->enableWindow(true);
+	((GameUIWindow *)viewWindow->getParent())->_sceneViewWindow->enableWindow(true);
+	((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->enableWindow(true);
+
+	Common::String liveText;
+	if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+		liveText = _vm->getString(IDS_OLD_APT_RECALL_MESSAGE);
+	else
+		liveText = "Auto-recall Engaged";
+
+	((SceneViewWindow *)viewWindow)->displayLiveText(liveText, false);
+
+	// Jump to the future apartment
+	((SceneViewWindow *)viewWindow)->timeSuitJump(4);
+
+	return SC_TRUE;
+}
+
+bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	// TODO
+	return false;
+}
+
+bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironment, int timeZone, int environment, bool fade) {
+	// TODO
+
+	switch (timeZone) {
+	case 10:
+		return _vm->_sound->setAmbientSound();
+	}
+
+	return false;
+}
+
+SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	// If the class ID is zero, return the default base class
+	if (sceneStaticData.classID == 0)
+		return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+
+	switch (sceneStaticData.location.timeZone) {
+	case 10: // Old Apartment
+		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
+	}
+
+	return 0;
+}
+
+bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment) {
+	// TODO
+	return false;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 01c5bb3ca5..8a7dea6c02 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -27,7 +27,8 @@ MODULE_OBJS = \
 	demo/demo_menu.o \
 	demo/features.o \
 	demo/movie_scene.o \
-	environ/scene_base.o
+	environ/scene_base.o \
+	environ/scene_factory.o
 
 
 # This module can be built as a plugin
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 019d78b773..006606fb28 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -357,6 +357,8 @@ namespace Buried {
 // 1.04+:
 #define IDS_PLAY_MODE_WALKTHROUGH_TEXT  9085
 #define IDS_PLAY_MODE_NORMAL_TEXT       9086
+#define IDS_OLD_APT_RECALL_MESSAGE      9088
+
 
 #define IDES_FILENAME_BASE              17408
 #define IDES_STRING_BASE                21504
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index fc3e42bc81..508884521e 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2466,24 +2466,4 @@ Common::Array<AIComment> SceneViewWindow::getAICommentDatabase(int timeZone, int
 	return comments;
 }
 
-bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
-	// TODO
-	return false;
-}
-
-bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironment, int timeZone, int environment, bool fade) {
-	// TODO
-	return false;
-}
-
-SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-	return 0;
-}
-
-bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment) {
-	// TODO
-	return false;
-}
-
 } // End of namespace Buried
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 0d1b7a9d04..5eeb086b59 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -32,6 +32,8 @@
 #include "buried/sprtdata.h"
 #include "buried/window.h"
 
+#include "common/array.h"
+
 namespace Graphics {
 struct Surface;
 }


Commit: 16a1a67a2050f339509c375da93a40dd1efb08f9
    https://github.com/scummvm/scummvm/commit/16a1a67a2050f339509c375da93a40dd1efb08f9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix drawing the scene view window

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 508884521e..a12bc7dbdf 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2309,7 +2309,7 @@ void SceneViewWindow::onPaint() {
 		_vm->_gfx->opaqueTransparentBlit(_preBuffer, _currentSprite.xPos, _currentSprite.yPos, _currentSprite.width, _currentSprite.height, _currentSprite.image, 0, 0, 0, _currentSprite.redTrans, _currentSprite.greenTrans, _currentSprite.blueTrans);
 
 		// Update the screen
-		_vm->_gfx->blit(_preBuffer, 0, 0);
+		_vm->_gfx->blit(_preBuffer, _rect.left, _rect.top);
 
 		if (_useScenePaint)
 			_currentScene->gdiPaint(this);


Commit: 201495903fc9db61b441fdc9198627dc6c6137f1
    https://github.com/scummvm/scummvm/commit/201495903fc9db61b441fdc9198627dc6c6137f1
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Allow the game to go beyond the second part of the intro

Now it just needs the apartment!

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index a12bc7dbdf..8cbdfc021e 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -640,7 +640,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 
 	// Play the movie
 	VideoWindow *jumpMovie = new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow);
-	if (!jumpMovie->openVideo(_vm->getString(IDS_BC_JUMP_MOVIE_FILENAME)))
+	if (!jumpMovie->openVideo(_vm->getFilePath(IDS_BC_JUMP_MOVIE_FILENAME)))
 		error("Failed to play small jump movie");
 
 	// Reposition
@@ -655,7 +655,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 
 	// Start fading down the current ambient and start the jump audio file
 	_vm->_sound->setAmbientSound();
-	_vm->_sound->playInterfaceSound(_vm->getString(IDS_BC_JUMP_AUDIO_FILENAME));
+	_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_BC_JUMP_AUDIO_FILENAME));
 
 	// Play the movie
 	jumpMovie->playToFrame(24);
@@ -678,19 +678,19 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	Common::String fileName;
 	switch (destination) {
 	case 0:
-		fileName = _vm->getString(IDS_MAYAN_JUMP_MOVIE_FILENAME);
+		fileName = _vm->getFilePath(IDS_MAYAN_JUMP_MOVIE_FILENAME);
 		break;
 	case 1:
-		fileName = _vm->getString(IDS_CASTLE_JUMP_MOVIE_FILENAME);
+		fileName = _vm->getFilePath(IDS_CASTLE_JUMP_MOVIE_FILENAME);
 		break;
 	case 2:
-		fileName = _vm->getString(IDS_DAVINCI_JUMP_MOVIE_FILENAME);
+		fileName = _vm->getFilePath(IDS_DAVINCI_JUMP_MOVIE_FILENAME);
 		break;
 	case 3:
-		fileName = _vm->getString(IDS_AILAB_JUMP_MOVIE_FILENAME);
+		fileName = _vm->getFilePath(IDS_AILAB_JUMP_MOVIE_FILENAME);
 		break;
 	case 4:
-		fileName = _vm->getString(IDS_FUTAPT_JUMP_MOVIE_FILENAME);
+		fileName = _vm->getFilePath(IDS_FUTAPT_JUMP_MOVIE_FILENAME);
 		break;
 	}
 
@@ -743,6 +743,9 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 		delete _currentScene;
 	}
 
+	if (!newScene)
+		error("Failed to create scene object for time zone %d", destination);
+
 	// Set the new scene
 	_currentScene = newScene;
 
@@ -765,7 +768,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	// Time to show and play the right-hand small movie to the mid point, with proper sound
 	jumpMovie = new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow);
 
-	if (!jumpMovie->openVideo(_vm->getString(IDS_BC_JUMP_MOVIE_FILENAME)))
+	if (!jumpMovie->openVideo(_vm->getFilePath(IDS_BC_JUMP_MOVIE_FILENAME)))
 		error("Failed to play small jump movie");
 
 	jumpMovie->setWindowPos(0, 0, 28, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosHideWindow);
@@ -778,7 +781,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 
 	// Start the ambient fading back up, and play the jump sound
 	startEnvironmentAmbient(oldLocation.timeZone, oldLocation.environment, newLocation.timeZone, newLocation.environment);
-	_vm->_sound->playInterfaceSound(_vm->getString(IDS_BC_JUMP_AUDIO_FILENAME));
+	_vm->_sound->playInterfaceSound(_vm->getFilePath(IDS_BC_JUMP_AUDIO_FILENAME));
 
 	// Play the movie
 	jumpMovie->seekToFrame(24);


Commit: ea4b3c6a2dfd567eb6f5634f6c739bd22d59202a
    https://github.com/scummvm/scummvm/commit/ea4b3c6a2dfd567eb6f5634f6c739bd22d59202a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix some uninitialized variables

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 8cbdfc021e..cc851b4e06 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -73,6 +73,8 @@ SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_curCursor = kCursorArrow;
 	_stillFrames = new AVIFrames();
 	_cycleFrames = new AVIFrames();
+
+	memset(&_globalFlags, 0, sizeof(_globalFlags));
 }
 
 SceneViewWindow::~SceneViewWindow() {
@@ -2309,7 +2311,8 @@ void SceneViewWindow::onPaint() {
 		}
 
 		// If we have a sprite, update the prebuffer with it now
-		_vm->_gfx->opaqueTransparentBlit(_preBuffer, _currentSprite.xPos, _currentSprite.yPos, _currentSprite.width, _currentSprite.height, _currentSprite.image, 0, 0, 0, _currentSprite.redTrans, _currentSprite.greenTrans, _currentSprite.blueTrans);
+		if (_currentSprite.image && _useSprite)
+			_vm->_gfx->opaqueTransparentBlit(_preBuffer, _currentSprite.xPos, _currentSprite.yPos, _currentSprite.width, _currentSprite.height, _currentSprite.image, 0, 0, 0, _currentSprite.redTrans, _currentSprite.greenTrans, _currentSprite.blueTrans);
 
 		// Update the screen
 		_vm->_gfx->blit(_preBuffer, _rect.left, _rect.top);


Commit: fde36a0d773152b952608af2d92a6aa2735d0383
    https://github.com/scummvm/scummvm/commit/fde36a0d773152b952608af2d92a6aa2735d0383
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix up live text redrawing

Changed paths:
    engines/buried/livetext.cpp


diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index 6aa62dc7b2..0b5de602c2 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -60,8 +60,7 @@ bool LiveTextWindow::updateLiveText(const Common::String &text, bool notifyUser)
 	if (text.empty()) {
 		_text.clear();
 
-		invalidateRect(Common::Rect(), false);
-		updateWindow();
+		invalidateWindow(false);
 
 		((GameUIWindow *)_parent)->setWarningState(false);
 		return true;
@@ -70,8 +69,7 @@ bool LiveTextWindow::updateLiveText(const Common::String &text, bool notifyUser)
 	_text = text;
 
 	// Redraw the window
-	invalidateRect(Common::Rect(), false);
-	updateWindow();
+	invalidateWindow(false);
 
 	if (notifyUser)
 		((GameUIWindow *)_parent)->flashWarningLight();
@@ -83,8 +81,7 @@ bool LiveTextWindow::updateTranslationText(const Common::String &text, bool noti
 	if (text.empty()) {
 		_text.clear();
 
-		invalidateRect(Common::Rect(), false);
-		updateWindow();
+		invalidateWindow(false);
 
 		((GameUIWindow *)_parent)->setWarningState(false);
 		return true;
@@ -96,8 +93,7 @@ bool LiveTextWindow::updateTranslationText(const Common::String &text, bool noti
 	_textTranslation = true;
 
 	// Redraw the window
-	invalidateRect(Common::Rect(), false);
-	updateWindow();
+	invalidateWindow(false);
 
 	((GameUIWindow *)_parent)->setWarningState(false);
 


Commit: 8866f3b1ca94f09f4f81ecc2af691c67312e6294
    https://github.com/scummvm/scummvm/commit/8866f3b1ca94f09f4f81ecc2af691c67312e6294
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Don't draw the date or warning light in the demo

Changed paths:
    engines/buried/gameui.cpp


diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index 5d28f2efeb..6214ac525d 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -291,18 +291,20 @@ void GameUIWindow::onPaint() {
 		bottomBitmap->free();
 		delete bottomBitmap;
 
-		if (_currentDateDisplay >= 0) {
-			Graphics::Surface *dateBitmap = _vm->_gfx->getBitmap(IDB_UI_DATE_BASE + _currentDateDisplay);
-			_vm->_gfx->blit(dateBitmap, 62, 332);
-			dateBitmap->free();
-			delete dateBitmap;
-		}
-
-		if (_warningLightDisplayed) {
-			Graphics::Surface *warningLight = _vm->_gfx->getBitmap(IDB_UI_WARNING_LIGHT);
-			_vm->_gfx->blit(warningLight, 189, 321);
-			warningLight->free();
-			delete warningLight;
+		if (!_vm->isDemo()) {
+			if (_currentDateDisplay >= 0) {
+				Graphics::Surface *dateBitmap = _vm->_gfx->getBitmap(IDB_UI_DATE_BASE + _currentDateDisplay);
+				_vm->_gfx->blit(dateBitmap, 62, 332);
+				dateBitmap->free();
+				delete dateBitmap;
+			}
+
+			if (_warningLightDisplayed) {
+				Graphics::Surface *warningLight = _vm->_gfx->getBitmap(IDB_UI_WARNING_LIGHT);
+				_vm->_gfx->blit(warningLight, 189, 321);
+				warningLight->free();
+				delete warningLight;
+			}
 		}
 	}
 }


Commit: 773f42174d370b12858a3a0311e1d3adc9423956
    https://github.com/scummvm/scummvm/commit/773f42174d370b12858a3a0311e1d3adc9423956
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix the demo's interface biochip view images

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/resources.h


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 6e0782ca74..0cc8a9dbd1 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -123,9 +123,9 @@ InterfaceBioChipViewWindow::InterfaceBioChipViewWindow(BuriedEngine *vm, Window
 
 	_rect = Common::Rect(0, 0, 432, 189);
 
-	_background = _vm->_gfx->getBitmap(IDB_BCV_INTERFACE_MAIN);
-	_cycleCheck = _vm->_gfx->getBitmap(IDB_BCV_INTERFACE_CHECK);
-	_caret = _vm->_gfx->getBitmap(IDB_BCV_INTERFACE_HANDLE);
+	_background = _vm->_gfx->getBitmap(_vm->isDemo() ? IDB_BCM_INTERFACE_NORMAL : IDB_BCV_INTERFACE_MAIN);
+	_cycleCheck = _vm->_gfx->getBitmap(_vm->isDemo() ? IDB_BCM_INTERFACE_SELECTED : IDB_BCV_INTERFACE_CHECK);
+	_caret = _vm->_gfx->getBitmap(_vm->isDemo() ? IDB_BCM_INTERFACE_SLIDER : IDB_BCV_INTERFACE_HANDLE);
 }
 
 InterfaceBioChipViewWindow::~InterfaceBioChipViewWindow() {
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 006606fb28..1b334db38c 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -243,6 +243,7 @@ namespace Buried {
 #define IDB_DEATH_BUTTONS_NORMAL		12405
 #define IDB_DEATH_BUTTONS_DEPRESSED		12406
 
+// Full Game:
 #define IDB_BCV_INTERFACE_MAIN			12410
 #define IDB_BCV_INTERFACE_HANDLE		12411
 #define IDB_BCV_INTERFACE_CHECK         12412
@@ -259,6 +260,10 @@ namespace Buried {
 #define IDB_BCR_INTERFACE_MENU			12401
 #define IDB_BCR_INTERFACE_EXIT			12402
 
+// Demo:
+#define IDB_BCM_INTERFACE_NORMAL		12500
+#define IDB_BCM_INTERFACE_SELECTED		12501
+#define IDB_BCM_INTERFACE_SLIDER		12502
 
 #define IDB_PICON_BITMAP_BASE			12800
 #define IDB_DRAG_BITMAP_BASE			12900


Commit: 9f759260f6d4fde9e33591381c434e880563fcca
    https://github.com/scummvm/scummvm/commit/9f759260f6d4fde9e33591381c434e880563fcca
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix destroying the biochip view window

Changed paths:
    engines/buried/biochip_right.cpp


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index 1e0a806954..9467df08c9 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -98,7 +98,7 @@ bool BioChipRightWindow::showBioChipMainView() {
 }
 
 bool BioChipRightWindow::destroyBioChipViewWindow() {
-	if (_bioChipViewWindow)
+	if (!_bioChipViewWindow)
 		return false;
 
 	_vm->_sound->timerCallback();


Commit: 33add4b517772279b8cf017e479077f2137f3573
    https://github.com/scummvm/scummvm/commit/33add4b517772279b8cf017e479077f2137f3573
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix checking for a transparent point

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 5e50caeffb..3ad7d1c4b0 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -461,9 +461,9 @@ bool GraphicsManager::checkPointAgainstMaskedBitmap(const Graphics::Surface *bit
 		uint32 color;
 
 		if (bitmap->format.bytesPerPixel == 2)
-			color = *((uint16 *)bitmap->getBasePtr(point.x + x, point.y + y));
+			color = *((uint16 *)bitmap->getBasePtr(point.x - x, point.y - y));
 		else
-			color = *((uint32 *)bitmap->getBasePtr(point.x + x, point.y + y));
+			color = *((uint32 *)bitmap->getBasePtr(point.x - x, point.y - y));
 
 		return transColor != color;
 	} else {
@@ -478,7 +478,7 @@ bool GraphicsManager::checkPointAgainstMaskedBitmap(const Graphics::Surface *bit
 
 		assert(paletteIndex >= 0);
 
-		return *((const byte *)bitmap->getBasePtr(point.x + x, point.y + y)) != paletteIndex;
+		return *((const byte *)bitmap->getBasePtr(point.x - x, point.y - y)) != paletteIndex;
 	}
 }
 


Commit: 6aa06fd538df0def931ae60e93e3409af379ea1a
    https://github.com/scummvm/scummvm/commit/6aa06fd538df0def931ae60e93e3409af379ea1a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add sanity check on constructSceneObject return value

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index cc851b4e06..21964213d7 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -513,6 +513,9 @@ bool SceneViewWindow::moveToDestination(const DestinationScene &destinationData)
 	// Create the new scene object
 	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, oldLocation);
 
+	if (!newScene)
+		error("Failed to create new scene");
+
 	// Switch on the type of transition
 	if (destinationData.transitionType == TRANSITION_VIDEO) {
 		// Play transition


Commit: c8b3013d2482783cc25e61229a34e127d7c750a5
    https://github.com/scummvm/scummvm/commit/c8b3013d2482783cc25e61229a34e127d7c750a5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add a basic debugger

Changed paths:
  A engines/buried/console.cpp
  A engines/buried/console.h
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/module.mk


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b9e3a87f3a..18941d19f2 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -33,6 +33,7 @@
 #include "engines/util.h"
 
 #include "buried/buried.h"
+#include "buried/console.h"
 #include "buried/database.h"
 #include "buried/frame_window.h"
 #include "buried/graphics.h"
@@ -53,6 +54,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_mainWindow = 0;
 	_focusedWindow = 0;
 	_captureWindow = 0;
+	_console = 0;
 
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2);
@@ -64,11 +66,14 @@ BuriedEngine::~BuriedEngine() {
 	delete _mainEXE;
 	delete _library;
 	delete _sound;
+	delete _console;
 
 	// The queue should be empty since all windows destroy their messages
 }
 
 Common::Error BuriedEngine::run() {
+	_console = new BuriedConsole(this);
+
 	if (isTrueColor()) {
 #ifndef USE_RGB_COLOR
 		// Can't play 24bpp version without support
@@ -130,6 +135,10 @@ Common::Error BuriedEngine::run() {
 	return Common::kNoError;
 }
 
+GUI::Debugger *BuriedEngine::getDebugger() {
+	return _console;
+}
+
 Common::String BuriedEngine::getString(uint32 stringID) {
 	return _mainEXE->loadString(stringID);
 }
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index ab7fee6b93..6a9dffb27f 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -38,6 +38,7 @@ class SeekableReadStream;
 
 namespace Buried {
 
+class BuriedConsole;
 struct BuriedGameDescription;
 class Database;
 class GraphicsManager;
@@ -65,6 +66,7 @@ public:
 	Common::Language getLanguage() const;
 
 	bool hasFeature(EngineFeature f) const;
+	GUI::Debugger *getDebugger();
 
 	// Resources
 	Common::String getString(uint32 stringID);
@@ -91,6 +93,7 @@ public:
 	Window *_mainWindow; // Only one main window is supported.
 	Window *_focusedWindow;
 	Window *_captureWindow;
+	BuriedConsole *_console;
 
 	// Timers
 	uint createTimer(Window *window, uint period);
diff --git a/engines/buried/console.cpp b/engines/buried/console.cpp
new file mode 100644
index 0000000000..d911754df2
--- /dev/null
+++ b/engines/buried/console.cpp
@@ -0,0 +1,34 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/console.h"
+
+namespace Buried {
+
+BuriedConsole::BuriedConsole(BuriedEngine *vm) : _vm(vm) {
+}
+
+BuriedConsole::~BuriedConsole() {
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/console.h b/engines/buried/console.h
new file mode 100644
index 0000000000..1e8a728eeb
--- /dev/null
+++ b/engines/buried/console.h
@@ -0,0 +1,43 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_CONSOLE_H
+#define BURIED_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Buried {
+
+class BuriedEngine;
+
+class BuriedConsole : public GUI::Debugger {
+public:
+	BuriedConsole(BuriedEngine *vm);
+	~BuriedConsole();
+
+private:
+	BuriedEngine *_vm;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 8a7dea6c02..f0a5931c33 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
 	biochip_view.o \
 	buried.o \
 	complete.o \
+	console.o \
 	credits.o \
 	database.o \
 	death.o \


Commit: d2505042db66fc1a8b5bd18ea34ece225a9c4689
    https://github.com/scummvm/scummvm/commit/d2505042db66fc1a8b5bd18ea34ece225a9c4689
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Actually turn on the walk movie

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 21964213d7..981cbcc427 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1026,6 +1026,7 @@ bool SceneViewWindow::walkTransition(const Location &location, const Destination
 	// Start the footsteps
 	_vm->_sound->startFootsteps(destinationData.transitionData);
 
+	_walkMovie->playToFrame(destinationData.transitionStartFrame + destinationData.transitionLength - 1);
 	while (!_vm->shouldQuit() && _walkMovie->getMode() != VideoWindow::kModeStopped) {
 		_vm->yield();
 		_vm->_sound->timerCallback();


Commit: 946b7c8f5f67681a2ca30847e8ae6851ca99282f
    https://github.com/scummvm/scummvm/commit/946b7c8f5f67681a2ca30847e8ae6851ca99282f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Begin initializing the castle time zone

Changed paths:
  A engines/buried/environ/castle.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/inventory_window.h
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
new file mode 100644
index 0000000000..f56402017a
--- /dev/null
+++ b/engines/buried/environ/castle.cpp
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/gameui.h"
+#include "buried/invdata.h"
+#include "buried/inventory_window.h"
+#include "buried/scene_view.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+bool SceneViewWindow::initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment) {
+	// If we passed -1, initialize time zone, otherwise the environment
+	if (environment == -1) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgWallExploded = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgHookPresent = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemGrapplingHook) ? 1 : 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgArrowPresent = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBloodyArrow) ? 1 : 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgHammerPresent = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemHammer) ? 1 : 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyGuard = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgBaileyOneWayGuard = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgBaileyTwoWayGuards = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgTapestryFlag = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgStorageRoomVisit = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgBurnedLetterPresent = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBurnedLetter) ? 1 : 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgGoldCoinsPresent = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemGoldCoins) ? 1 : 0;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = 6;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgTapestryFlag = 1;
+		}
+	}
+
+	// Environment-specific
+	if (environment == 4) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredKeep = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMBVisited = 1;
+	} else if (environment == 6) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKCVisited = 1;
+	} else if (environment == 10) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredTreasureRoom = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgTRVisited = 1;
+	}
+
+	return true;
+}
+
+SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 698b55667b..963c308f19 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -96,6 +96,17 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 
 	switch (sceneStaticData.location.timeZone) {
+	case 0: // Miscellaneous scenes
+	case 2: // Mayan
+	case 3: // Agent 3's Lair
+	case 4: // Future Apartment
+	case 5: // Da Vinci
+	case 6: // AI Lab
+	case 7: // Alien
+		warning("Could not create scene object for time zone %d", sceneStaticData.location.timeZone);
+		break;
+	case 1: // Castle
+		return constructCastleSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 10: // Old Apartment
 		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
@@ -105,6 +116,11 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 
 bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment) {
 	// TODO
+	switch (timeZone) {
+	case 1:
+		return initializeCastleTimeZoneAndEnvironment(viewWindow, environment);
+	}
+
 	return false;
 }
 
diff --git a/engines/buried/inventory_window.h b/engines/buried/inventory_window.h
index 43aae5d0f0..2b708402a7 100644
--- a/engines/buried/inventory_window.h
+++ b/engines/buried/inventory_window.h
@@ -30,6 +30,8 @@
 #include "buried/sprtdata.h"
 #include "buried/window.h"
 
+#include "common/array.h"
+
 namespace Graphics {
 class Font;
 }
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index f0a5931c33..df194fbd6a 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -28,6 +28,7 @@ MODULE_OBJS = \
 	demo/demo_menu.o \
 	demo/features.o \
 	demo/movie_scene.o \
+	environ/castle.o \
 	environ/scene_base.o \
 	environ/scene_factory.o
 
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 5eeb086b59..6ebe20b2f4 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -197,6 +197,10 @@ private:
 
 	Common::Array<AnimEvent> getAnimationDatabase(int timeZone, int environment);
 	Common::Array<AIComment> getAICommentDatabase(int timeZone, int environment);
+
+	// Castle
+	bool initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	SceneBase *constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 };
 
 } // End of namespace Buried


Commit: b12cd67b6b97f03187eca831663ba19b6b2ea12e
    https://github.com/scummvm/scummvm/commit/b12cd67b6b97f03187eca831663ba19b6b2ea12e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Don't forget to set _tempFrame to 0

Changed paths:
    engines/buried/avi_frames.cpp


diff --git a/engines/buried/avi_frames.cpp b/engines/buried/avi_frames.cpp
index 561c589ae4..11eb26b9d4 100644
--- a/engines/buried/avi_frames.cpp
+++ b/engines/buried/avi_frames.cpp
@@ -97,6 +97,7 @@ void AVIFrames::close() {
 	if (_tempFrame) {
 		_tempFrame->free();
 		delete _tempFrame;
+		_tempFrame = 0;
 	}
 }
 


Commit: 0a1e694ef27519147c1b314af00017277a40e64b
    https://github.com/scummvm/scummvm/commit/0a1e694ef27519147c1b314af00017277a40e64b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Treat hidden windows as disabled

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index c42601c1dd..996fd1837f 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -222,7 +222,7 @@ bool Window::isWindowEnabled() const {
 	if (_parent && !_parent->isWindowEnabled())
 		return false;
 
-	return _enabled;
+	return _enabled && _visible;
 }
 
 uint Window::setTimer(uint elapse) {


Commit: d809429d9a55eaa7fd6d57f60202502d1d12818a
    https://github.com/scummvm/scummvm/commit/d809429d9a55eaa7fd6d57f60202502d1d12818a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the basic door class

You can now enter the smithy!

Changed paths:
  A engines/buried/environ/scene_common.cpp
  A engines/buried/environ/scene_common.h
    engines/buried/environ/castle.cpp
    engines/buried/module.mk


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index f56402017a..c1b393a361 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -28,6 +28,7 @@
 #include "buried/inventory_window.h"
 #include "buried/scene_view.h"
 #include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
 
 namespace Buried {
 
@@ -70,6 +71,13 @@ bool SceneViewWindow::initializeCastleTimeZoneAndEnvironment(Window *viewWindow,
 SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
+	switch (sceneStaticData.classID) {
+	case 9:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 81, 25, 360, 189, 1, 4, 2, 1, 1, 1, 2, 11, 413, 25);
+	}
+
+	warning("TODO: Castle scene object %d", sceneStaticData.classID);
+
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
new file mode 100644
index 0000000000..2b22a08069
--- /dev/null
+++ b/engines/buried/environ/scene_common.cpp
@@ -0,0 +1,96 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/graphics.h"
+#include "buried/resources.h"
+#include "buried/sound.h"
+#include "buried/scene_view.h"
+#include "buried/environ/scene_common.h"
+
+namespace Buried {
+
+BasicDoor::BasicDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int timeZone, int environment, int node, int facing,
+		int orientation, int depth, int transitionType, int transitionData,
+		int transitionStartFrame, int transitionLength, int openingSoundID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clicked = false;
+
+	_clickable = Common::Rect(left, top, right, bottom);
+
+	_destData.destinationScene.timeZone = timeZone;
+	_destData.destinationScene.environment = environment;
+	_destData.destinationScene.node = node;
+	_destData.destinationScene.facing = facing;
+	_destData.destinationScene.orientation = orientation;
+	_destData.destinationScene.depth = depth;
+
+	_destData.transitionType = transitionType;
+	_destData.transitionData = transitionData;
+	_destData.transitionStartFrame = transitionStartFrame;
+	_destData.transitionLength = transitionLength;
+
+	_openingSoundID = openingSoundID;
+
+	if (viewWindow) {
+		((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
+
+		if (_staticData.cycleStartFrame >= 0)
+			((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
+	}
+}
+
+int BasicDoor::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		_clicked = true;
+
+	return SC_TRUE;
+}
+
+int BasicDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clicked) {
+		_clicked = false;
+
+		if (_openingSoundID >= 0)
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _openingSoundID));
+
+		if (_clickable.contains(pointLocation))
+			((SceneViewWindow *)viewWindow)->moveToDestination(_destData);		
+	}
+
+	return SC_TRUE;
+}
+
+int BasicDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	//debug("(%d, %d) in (%d, %d, %d, %d)", pointLocation.x, pointLocation.y, _clickable.left, _clickable.top, _clickable.right, _clickable.bottom);
+
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
new file mode 100644
index 0000000000..99483da4d4
--- /dev/null
+++ b/engines/buried/environ/scene_common.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BURIED_SCENE_COMMON_H
+#define BURIED_SCENE_COMMON_H
+
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+class BasicDoor : public SceneBase {
+public:
+	BasicDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int timeZone = -1, int environment = -1,
+			int node = -1, int facing = -1, int orientation = -1, int depth = -1, int transitionType = -1, int transitionData = -1,
+			int transitionStartFrame = -1, int transitionLength = -1, int openingSoundID = -1);
+
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+	bool _clicked;
+	Common::Rect _clickable;
+	DestinationScene _destData;
+	int _openingSoundID;
+};
+
+} // End of namespace Buried
+
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index df194fbd6a..b82ac5bbf2 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -30,6 +30,7 @@ MODULE_OBJS = \
 	demo/movie_scene.o \
 	environ/castle.o \
 	environ/scene_base.o \
+	environ/scene_common.o \
 	environ/scene_factory.o
 
 


Commit: 9114b2025f2658e0b5914e3828a185cde9a1708b
    https://github.com/scummvm/scummvm/commit/9114b2025f2658e0b5914e3828a185cde9a1708b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add a stub for the future apartment

The full game is now very slightly playable!

Changed paths:
  A engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
new file mode 100644
index 0000000000..2da6e025db
--- /dev/null
+++ b/engines/buried/environ/future_apartment.cpp
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	_vm->_sound->setAmbientSound(_vm->getFilePath(4, environment, SF_AMBIENT));
+	return true;
+}
+
+SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);
+
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 963c308f19..51a5d14b1b 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -81,6 +81,8 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 	// TODO
 
 	switch (timeZone) {
+	case 4:
+		return startFutureApartmentAmbient(oldTimeZone, environment, environment, fade);
 	case 10:
 		return _vm->_sound->setAmbientSound();
 	}
@@ -89,8 +91,6 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 }
 
 SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	// If the class ID is zero, return the default base class
 	if (sceneStaticData.classID == 0)
 		return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
@@ -99,14 +99,16 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 	case 0: // Miscellaneous scenes
 	case 2: // Mayan
 	case 3: // Agent 3's Lair
-	case 4: // Future Apartment
 	case 5: // Da Vinci
 	case 6: // AI Lab
 	case 7: // Alien
+		// TODO
 		warning("Could not create scene object for time zone %d", sceneStaticData.location.timeZone);
 		break;
 	case 1: // Castle
 		return constructCastleSceneObject(viewWindow, sceneStaticData, priorLocation);
+	case 4:
+		return constructFutureApartmentSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 10: // Old Apartment
 		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
@@ -119,6 +121,9 @@ bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int t
 	switch (timeZone) {
 	case 1:
 		return initializeCastleTimeZoneAndEnvironment(viewWindow, environment);
+	case 4:
+		// Nothing to do
+		return true;
 	}
 
 	return false;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index b82ac5bbf2..134dc2ee81 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -29,6 +29,7 @@ MODULE_OBJS = \
 	demo/features.o \
 	demo/movie_scene.o \
 	environ/castle.o \
+	environ/future_apartment.o \
 	environ/scene_base.o \
 	environ/scene_common.o \
 	environ/scene_factory.o
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 6ebe20b2f4..94f855565a 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -201,6 +201,10 @@ private:
 	// Castle
 	bool initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	SceneBase *constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
+	// Future Apartment
+	bool startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
+	SceneBase *constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 };
 
 } // End of namespace Buried


Commit: 817a6ac6de5d9a34f05b4381d487cc71069a2e90
    https://github.com/scummvm/scummvm/commit/817a6ac6de5d9a34f05b4381d487cc71069a2e90
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix sound volume clipping

Changed paths:
    engines/buried/sound.cpp


diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index b5d31b737d..82214601eb 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -42,6 +42,10 @@ namespace Buried {
 
 #define SOUND_FLAG_DESTROY_AFTER_COMPLETION 0x01
 
+static inline int clipVolume(int volume) {
+	return CLIP<int>(volume, 0, Audio::Mixer::kMaxChannelVolume);
+}
+
 SoundManager::SoundManager(BuriedEngine *vm) : _vm(vm) {
 	_fileIDFootsteps = -1;
 	_lastAmbient = 1;
@@ -97,7 +101,7 @@ bool SoundManager::setAmbientSound(const Common::String &fileName, bool fade, by
 				_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectRemaining = 2000;
 
 				// Reset parameters for current ambient
-				g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle, _soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1);
+				g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle, clipVolume(_soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1));
 				// clone2727: The original resets the loop count, but I don't think that's necessary
 			}
 		} else {
@@ -121,7 +125,7 @@ bool SoundManager::setAmbientSound(const Common::String &fileName, bool fade, by
 	
 			// Reset parameters for the current ambient
 			g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle,
-					_soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1);
+					clipVolume(_soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1));
 		}
 
 		// Load the new ambient
@@ -200,7 +204,7 @@ bool SoundManager::adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte
 		// and reset the volume for the sample
 		_soundData[kAmbientIndexBase + _lastAmbient]->_volume = newVolumeLevel;
 		g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle,
-				newVolumeLevel << 1);
+				clipVolume(newVolumeLevel << 1));
 	}
 
 	// Return success
@@ -287,7 +291,7 @@ bool SoundManager::adjustSecondaryAmbientSoundVolume(byte newVolumeLevel, bool f
 		// and reset the volume for the sample
 		_soundData[kAmbientIndexBase + ambientTrack]->_volume = newVolumeLevel;
 		g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + ambientTrack]->_handle,
-				newVolumeLevel << 1);
+				clipVolume(newVolumeLevel << 1));
 	}
 
 	// Return success
@@ -507,7 +511,7 @@ bool SoundManager::adjustSoundEffectSoundVolume(int effectID, byte newVolumeLeve
 		// and reset the volume for the sample
 		_soundData[kEffectsIndexBase + effectID]->_volume = newVolumeLevel;
 		g_system->getMixer()->setChannelVolume(*_soundData[kEffectsIndexBase + effectID]->_handle,
-				newVolumeLevel << 1);
+				clipVolume(newVolumeLevel << 1));
 	}
 
 	// Return success
@@ -642,7 +646,7 @@ void SoundManager::timerCallback() {
 					// Change the specified member and notify the mixer of the change
 					if (_soundData[i]->_timedEffectIndex == TIMED_EFFECT_VOLUME) {
 						_soundData[i]->_volume += _soundData[i]->_timedEffectDelta;
-						g_system->getMixer()->setChannelVolume(*_soundData[i]->_handle, _soundData[i]->_volume << 1);
+						g_system->getMixer()->setChannelVolume(*_soundData[i]->_handle, clipVolume(_soundData[i]->_volume << 1));
 					}
 
 					// Update the start time, step counter, and remaining time
@@ -733,7 +737,7 @@ bool SoundManager::Sound::start() {
 	}
 
 	g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, audioStream,
-			-1, _volume << 1, 0, disposeAfterUse);
+			-1, clipVolume(_volume << 1), 0, disposeAfterUse);
 
 	return true;
 }


Commit: 6b87aee941531379fc5feeaecf17d415ca861b46
    https://github.com/scummvm/scummvm/commit/6b87aee941531379fc5feeaecf17d415ca861b46
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
COMMON: Ensure stddef.h is included in scummsys.h

Changed paths:
    common/scummsys.h


diff --git a/common/scummsys.h b/common/scummsys.h
index 19550a5930..ec900fb5c9 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -123,6 +123,7 @@
 	#include <stddef.h>
 	#include <assert.h>
 	#include <ctype.h>
+	#include <stddef.h>
 	// MSVC does not define M_PI, M_SQRT2 and other math defines by default.
 	// _USE_MATH_DEFINES must be defined in order to have these defined, thus
 	// we enable it here. For more information, check:


Commit: ad39786203d4687af729e28ff13daa1b9abab83f
    https://github.com/scummvm/scummvm/commit/ad39786203d4687af729e28ff13daa1b9abab83f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the future apartment stingers

Because ambience is everything

Changed paths:
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h
    engines/buried/global_flags.h


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 2da6e025db..2a36cfb967 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -28,6 +28,7 @@
 #include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
 
 namespace Buried {
 
@@ -39,6 +40,11 @@ bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnviro
 SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
+	switch (sceneStaticData.classID) {
+	case 30:
+		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14); 
+	}
+
 	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);
 
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 2b22a08069..1a11671431 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -55,6 +55,7 @@ BasicDoor::BasicDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticD
 
 	_openingSoundID = openingSoundID;
 
+	// FIXME: Why is this here?
 	if (viewWindow) {
 		((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
 
@@ -85,12 +86,51 @@ int BasicDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
 }
 
 int BasicDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
-	//debug("(%d, %d) in (%d, %d, %d, %d)", pointLocation.x, pointLocation.y, _clickable.left, _clickable.top, _clickable.right, _clickable.bottom);
-
 	if (_clickable.contains(pointLocation))
 		return kCursorFinger;
 
 	return kCursorArrow;
 }
 
+PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID, int lastStingerFileID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_stingerVolume = stingerVolume;
+	_lastStingerFlagOffset = lastStingerFlagOffset;
+	_effectIDFlagOffset = effectIDFlagOffset;
+	_firstStingerFileID = firstStingerFileID;
+	_lastStingerFileID = lastStingerFileID;
+
+	// FIXME: Why is this here?
+	if (viewWindow) {
+		((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
+
+		if (_staticData.cycleStartFrame >= 0)
+			((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
+	}
+}
+
+int PlayStingers::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_effectIDFlagOffset >= 0) {
+		// More evil.
+		byte effectID = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_effectIDFlagOffset);
+
+		if (!_vm->_sound->isSoundEffectPlaying(effectID - 1)) {
+			byte lastStinger = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_lastStingerFlagOffset);
+			lastStinger++;
+
+			uint32 fileNameIndex = _vm->computeFileNameResourceID(_staticData.location.timeZone, _staticData.location.environment, _firstStingerFileID + lastStinger - 1);
+			byte newStingerID = _vm->_sound->playSoundEffect(_vm->getFilePath(fileNameIndex), _stingerVolume, false, true) + 1;
+
+			if (lastStinger > _lastStingerFileID - _firstStingerFileID)
+				lastStinger = 0;
+
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_effectIDFlagOffset, newStingerID);
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
+		}
+	}
+
+	return SC_TRUE;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 99483da4d4..453c01cc92 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -47,6 +47,20 @@ public:
 	int _openingSoundID;
 };
 
+class PlayStingers : public SceneBase {
+public:
+	PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int stingerVolume = 127, int lastStingerFlagOffset = -1, int effectIDFlagOffset = -1, int firstStingerFileID = -1, int lastStingerFileID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _stingerVolume;
+	int _lastStingerFlagOffset;
+	int _effectIDFlagOffset;
+	int _firstStingerFileID;
+	int _lastStingerFileID;
+};
+
 } // End of namespace Buried
 
 #endif
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index d4ea7803f3..1826243136 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -92,8 +92,8 @@ struct GlobalFlags {
 	byte faERTakenRemoteControl;        // 52
 	byte myMCStingerID;                 // 53
 	byte myMCStingerChannelID;          // 54
-	byte myFAStingerID;                 // 55
-	byte myFAStingerChannelID;          // 56
+	byte faStingerID;                   // 55
+	byte faStingerChannelID;            // 56
 	byte unused0[3];                    // 57-59
 	uint32 cgMWCatapultData;            // 60-63
 	uint32 cgMWCatapultOffset;          // 64-67


Commit: aaa3274b453e5bac6fa38669bf4a230c7372a24e
    https://github.com/scummvm/scummvm/commit/aaa3274b453e5bac6fa38669bf4a230c7372a24e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix the demo transition slider

Changed paths:
    engines/buried/biochip_view.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 0cc8a9dbd1..fb8c47b41c 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -115,7 +115,7 @@ InterfaceBioChipViewWindow::InterfaceBioChipViewWindow(BuriedEngine *vm, Window
 	_restore = Common::Rect(313, 37, 421, 74);
 	_quit = Common::Rect(313, 84, 421, 121);
 	_flicker = Common::Rect(14, 146, 164, 166);
-	_transitionSpeed = Common::Rect(14, 100, 125, 140);
+	_transitionSpeed = _vm->isDemo() ? Common::Rect(14, 117, 179, 140) : Common::Rect(14, 100, 125, 140);
 
 	_curRegion = REGION_NONE;
 	_soundLocation = 0;
@@ -146,8 +146,12 @@ void InterfaceBioChipViewWindow::onPaint() {
 	if (((SceneViewWindow *)_parent)->getCyclingStatus())
 		_vm->_gfx->blit(_cycleCheck, absoluteRect.left + 13, absoluteRect.top + 144);
 
-	if (_caret)
-		_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 14, absoluteRect.top + 97, 15, 30, _caret, 0, 0, 0, 248, _vm->isTrueColor() ? 252 : 248, 248);
+	if (_caret) {
+		if (_vm->isDemo())
+			_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 12, absoluteRect.top + 112, 20, 35, _caret, 0, 0, 0, 255, 255, 255);
+		else
+			_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 14, absoluteRect.top + 97, 15, 30, _caret, 0, 0, 0, 248, _vm->isTrueColor() ? 252 : 248, 248);
+	}
 }
 
 void InterfaceBioChipViewWindow::onLButtonDown(const Common::Point &point, uint flags) {


Commit: 23da2a676187be139eec466b14ac92a1365aef19
    https://github.com/scummvm/scummvm/commit/23da2a676187be139eec466b14ac92a1365aef19
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add one shot videos

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index c1b393a361..30373a318e 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -23,9 +23,11 @@
  *
  */
 
+#include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
+#include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
@@ -74,6 +76,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 	switch (sceneStaticData.classID) {
 	case 9:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 81, 25, 360, 189, 1, 4, 2, 1, 1, 1, 2, 11, 413, 25);
+	case 32:
+		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, 0, offsetof(GlobalFlags, cgSmithyGuard), IDS_HUMAN_PRESENCE_10METERS);
+	case 33:
+		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 2 : 6, offsetof(GlobalFlags, cgBaileyOneWayGuard), IDS_HUMAN_PRESENCE_10METERS);
 	}
 
 	warning("TODO: Castle scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 1a11671431..cbc9c28d6d 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -54,14 +54,6 @@ BasicDoor::BasicDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticD
 	_destData.transitionLength = transitionLength;
 
 	_openingSoundID = openingSoundID;
-
-	// FIXME: Why is this here?
-	if (viewWindow) {
-		((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
-
-		if (_staticData.cycleStartFrame >= 0)
-			((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
-	}
 }
 
 int BasicDoor::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
@@ -100,14 +92,6 @@ PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationS
 	_effectIDFlagOffset = effectIDFlagOffset;
 	_firstStingerFileID = firstStingerFileID;
 	_lastStingerFileID = lastStingerFileID;
-
-	// FIXME: Why is this here?
-	if (viewWindow) {
-		((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
-
-		if (_staticData.cycleStartFrame >= 0)
-			((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
-	}
 }
 
 int PlayStingers::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
@@ -133,4 +117,23 @@ int PlayStingers::postEnterRoom(Window *viewWindow, const Location &priorLocatio
 	return SC_TRUE;
 }
 
+OneShotEntryVideoWarning::OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int animID, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_animID = animID;
+	_flagOffset = flagOffset;
+	_warningMessageID = warningMessageID;
+}
+
+int OneShotEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
+		if (_warningMessageID >= 0)
+			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_warningMessageID));
+
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+	}
+
+	return SC_TRUE;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 453c01cc92..48f835248f 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -61,6 +61,18 @@ private:
 	int _lastStingerFileID;
 };
 
+class OneShotEntryVideoWarning : public SceneBase {
+public:
+	OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int animID = 0, int flagOffset = 0, int warningMessageID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _animID;
+	int _flagOffset;
+	int _warningMessageID;
+};
+
 } // End of namespace Buried
 
 #endif


Commit: b96691c27ad1218e808790337b30cf328334b1fd
    https://github.com/scummvm/scummvm/commit/b96691c27ad1218e808790337b30cf328334b1fd
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fill in other castle doors

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 30373a318e..93445f4904 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -74,8 +74,20 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 4:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 114, 0, 324, 189, 1, 2, 5, 3, 1, 1, 2, 11, 395, 9);
+	case 5:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 103, 0, 355, 189, 1, 3, 5, 1, 1, 1, 2, 11, 641, 8);
 	case 9:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 81, 25, 360, 189, 1, 4, 2, 1, 1, 1, 2, 11, 413, 25);
+	case 10:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 24, 5, 415, 189, 1, 5, 0, 2, 1, 1, 2, 11, 72, 22);
+	case 16:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 131, 18, 322, 189, 1, 8, 10, 1, 1, 1, 2, 11, 307, 7);
+	case 17:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 42, 0, 357, 189, 1, 8, 11, 3, 1, 1, 2, 11, 314, 7);
+	case 18:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 26, 0, 432, 189, 1, 8, 6, 3, 1, 1, 2, 11, 288, 8);
 	case 32:
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, 0, offsetof(GlobalFlags, cgSmithyGuard), IDS_HUMAN_PRESENCE_10METERS);
 	case 33:


Commit: 22989c40a58f85fe4c7fbedf0abb9d3ec76de233
    https://github.com/scummvm/scummvm/commit/22989c40a58f85fe4c7fbedf0abb9d3ec76de233
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the two sentry castle video

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 93445f4904..428e26a59d 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -92,6 +92,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, 0, offsetof(GlobalFlags, cgSmithyGuard), IDS_HUMAN_PRESENCE_10METERS);
 	case 33:
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 2 : 6, offsetof(GlobalFlags, cgBaileyOneWayGuard), IDS_HUMAN_PRESENCE_10METERS);
+	case 34:
+		return new CycleEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 5 : 7, _vm->isDemo() ? 6 : 8, offsetof(GlobalFlags, cgBaileyTwoWayGuards), IDS_HUMAN_PRESENCE_10METERS);
 	}
 
 	warning("TODO: Castle scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index cbc9c28d6d..9f7f15385e 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -136,4 +136,27 @@ int OneShotEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &
 	return SC_TRUE;
 }
 
+CycleEntryVideoWarning::CycleEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int animIDA, int animIDB, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_animIDA = animIDA;
+	_animIDB = animIDB;
+	_flagOffset = flagOffset;
+	_warningMessageID = warningMessageID;
+}
+
+int CycleEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_warningMessageID >= 0)
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_warningMessageID));
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animIDA);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+	} else {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animIDB);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 0);
+	}
+
+	return SC_TRUE;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 48f835248f..c22dab1c92 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -73,6 +73,19 @@ private:
 	int _warningMessageID;
 };
 
+class CycleEntryVideoWarning : public SceneBase {
+public:
+	CycleEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int animIDA = 0, int animIDB = 0, int flagOffset = 0, int warningMessageID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _animIDA;
+	int _animIDB;
+	int _flagOffset;
+	int _warningMessageID;
+};
+
 } // End of namespace Buried
 
 #endif


Commit: 60b8942e7551162ff3f9945f314553aff625aa01
    https://github.com/scummvm/scummvm/commit/60b8942e7551162ff3f9945f314553aff625aa01
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Implement toy shelf zooming

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 2a36cfb967..d0af3eba59 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/graphics.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -32,6 +33,54 @@
 
 namespace Buried {
 
+class ClickZoomToyShelf : public SceneBase {
+public:
+	ClickZoomToyShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _toyZooms[4];
+};
+
+ClickZoomToyShelf::ClickZoomToyShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_toyZooms[0] = Common::Rect(102, 8, 170, 108);
+	_toyZooms[1] = Common::Rect(188, 24, 228, 108);
+	_toyZooms[2] = Common::Rect(282, 24, 330, 108);
+	_toyZooms[3] = Common::Rect(330, 28, 366, 108);
+}
+
+int ClickZoomToyShelf::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 4; i++) {
+		if (_toyZooms[i].contains(pointLocation)) {
+			DestinationScene newScene;
+			newScene.destinationScene = _staticData.location;
+			newScene.destinationScene.depth = i + 1;
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+
+			static const int transitionData[4] = { 13, 16, 19, 22 };
+			newScene.transitionData = transitionData[i];
+
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ClickZoomToyShelf::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 4; i++)
+		if (_toyZooms[i].contains(pointLocation))
+			return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
 	_vm->_sound->setAmbientSound(_vm->getFilePath(4, environment, SF_AMBIENT));
 	return true;
@@ -42,7 +91,9 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 
 	switch (sceneStaticData.classID) {
 	case 30:
-		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14); 
+		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14);
+	case 37:
+		return new ClickZoomToyShelf(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
 	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);


Commit: 5171e5022f4050b76cfd2cd188652263cae79e98
    https://github.com/scummvm/scummvm/commit/5171e5022f4050b76cfd2cd188652263cae79e98
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the future apartment figurines

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index d0af3eba59..9ee6e5a69d 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -24,7 +24,9 @@
  */
 
 #include "buried/buried.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
+#include "buried/inventory_window.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -81,6 +83,63 @@ int ClickZoomToyShelf::specifyCursor(Window *viewWindow, const Common::Point &po
 	return kCursorArrow;
 }
 
+class ToyClick : public SceneBase {
+public:
+	ToyClick(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int returnDepth = -1, int clickAnimation = -1, int returnAnimation = -1); 
+
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickRect;
+	int _returnDepth;
+	int _clickAnimation;
+	int _returnAnimation;
+};
+
+ToyClick::ToyClick(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int returnDepth, int clickAnimation, int returnAnimation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRect = Common::Rect(left, top, right, bottom);
+	_returnDepth = returnDepth;
+	_clickAnimation = clickAnimation;
+	_returnAnimation = returnAnimation;
+}
+
+int ToyClick::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRect.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_clickAnimation);
+
+		if (_clickAnimation == 17) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().faHeardAgentFigure = 1;
+
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && !((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_WM_AI_LAB_TEXT));
+		}
+
+		return SC_TRUE;
+	}
+
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = _returnDepth;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = _returnAnimation;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+
+	return SC_TRUE;
+}
+
+int ToyClick::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRect.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
 	_vm->_sound->setAmbientSound(_vm->getFilePath(4, environment, SF_AMBIENT));
 	return true;
@@ -94,6 +153,14 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14);
 	case 37:
 		return new ClickZoomToyShelf(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 38:
+		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 82, 0, 358, 189, 0, 14, 15);
+	case 39:
+		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 104, 0, 320, 189, 0, 17, 18);
+	case 40:
+		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 104, 10, 270, 189, 0, 20, 21);
+	case 41:
+		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 128, 0, 332, 189, 0, 23, 24);
 	}
 
 	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);


Commit: 18df139af321f6fccb922af63da17710a0d1ec4c
    https://github.com/scummvm/scummvm/commit/18df139af321f6fccb922af63da17710a0d1ec4c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the ClickPlayVideo scene base

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 428e26a59d..cfb7d149e1 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -25,6 +25,7 @@
 
 #include "buried/buried.h"
 #include "buried/gameui.h"
+#include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
 #include "buried/resources.h"
@@ -88,12 +89,16 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 42, 0, 357, 189, 1, 8, 11, 3, 1, 1, 2, 11, 314, 7);
 	case 18:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 26, 0, 432, 189, 1, 8, 6, 3, 1, 1, 2, 11, 288, 8);
+	case 31:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, 51, 25, 149, 149);
 	case 32:
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, 0, offsetof(GlobalFlags, cgSmithyGuard), IDS_HUMAN_PRESENCE_10METERS);
 	case 33:
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 2 : 6, offsetof(GlobalFlags, cgBaileyOneWayGuard), IDS_HUMAN_PRESENCE_10METERS);
 	case 34:
 		return new CycleEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 5 : 7, _vm->isDemo() ? 6 : 8, offsetof(GlobalFlags, cgBaileyTwoWayGuards), IDS_HUMAN_PRESENCE_10METERS);
+	case 47:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	}
 
 	warning("TODO: Castle scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 9ee6e5a69d..cb1747b2fb 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -161,6 +161,8 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 104, 10, 270, 189, 0, 20, 21);
 	case 41:
 		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 128, 0, 332, 189, 0, 23, 24);
+	case 54:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 36, kCursorFinger, 0, 0, 432, 189);
 	}
 
 	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 9f7f15385e..67124d6f0d 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -159,4 +159,29 @@ int CycleEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &pr
 	return SC_TRUE;
 }
 
+ClickPlayVideo::ClickPlayVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int animID, int cursorID, int left, int top, int right, int bottom)
+		: SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	
+	_cursorID = cursorID;
+	_animID = animID;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+}
+
+int ClickPlayVideo::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickPlayVideo::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index c22dab1c92..20d4c2a0ca 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -86,6 +86,20 @@ private:
 	int _warningMessageID;
 };
 
+class ClickPlayVideo : public SceneBase {
+public:
+	ClickPlayVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int animID = 0, int cursorID = -1, int left = 0, int top = 0, int right = 0, int bottom = 0); 
+
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	int _animID;
+	Common::Rect _clickRegion;
+};
+
 } // End of namespace Buried
 
 #endif


Commit: 518f292aba564c2796f8bb8fd43408817a95ff6e
    https://github.com/scummvm/scummvm/commit/518f292aba564c2796f8bb8fd43408817a95ff6e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Add the TurnDepthPreChange scene base

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index cfb7d149e1..1b1d48b9a9 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -79,6 +79,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 114, 0, 324, 189, 1, 2, 5, 3, 1, 1, 2, 11, 395, 9);
 	case 5:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 103, 0, 355, 189, 1, 3, 5, 1, 1, 1, 2, 11, 641, 8);
+	case 7:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgWallExploded), 0, 0, 1, 0, 0);
+	case 8:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgWallExploded), 0, 1, 0, 0, 0);
 	case 9:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 81, 25, 360, 189, 1, 4, 2, 1, 1, 1, 2, 11, 413, 25);
 	case 10:
@@ -89,6 +93,28 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 42, 0, 357, 189, 1, 8, 11, 3, 1, 1, 2, 11, 314, 7);
 	case 18:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 26, 0, 432, 189, 1, 8, 6, 3, 1, 1, 2, 11, 288, 8);
+	case 20:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHookPresent), 0, 0, 1, 0, 0);
+	case 21:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHookPresent), 0, 1, 0, 0, 0);
+	case 23:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgArrowPresent), 0, 0, 1, 0, 0);
+	case 24:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgArrowPresent), 0, 1, 0, 0, 0);
+	case 26:
+		if (_vm->isDemo())
+			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 0, 1, 0, 0);
+		break;
+	case 27:
+		if (_vm->isDemo())
+			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 1, 0, 0, 0);
+		break;
+	case 29:
+		if (_vm->isDemo())
+			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 0, 0, 1, 0);
+		break;
+	case 30:
+		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHookPresent), 0, 0, 0, 1, 0);
 	case 31:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, 51, 25, 149, 149);
 	case 32:
@@ -99,10 +125,11 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new CycleEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 5 : 7, _vm->isDemo() ? 6 : 8, offsetof(GlobalFlags, cgBaileyTwoWayGuards), IDS_HUMAN_PRESENCE_10METERS);
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
+	default:
+		warning("TODO: Castle scene object %d", sceneStaticData.classID);
+		break;
 	}
 
-	warning("TODO: Castle scene object %d", sceneStaticData.classID);
-
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 67124d6f0d..ebb3ee033d 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -84,6 +84,27 @@ int BasicDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocat
 	return kCursorArrow;
 }
 
+TurnDepthPreChange::TurnDepthPreChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, int upDepth, int leftDepth, int rightDepth, int downDepth, int forwardDepth) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset)) {
+		if (upDepth >= 0)
+			_staticData.destUp.destinationScene.depth = upDepth;
+
+		if (leftDepth >= 0)
+			_staticData.destUp.destinationScene.depth = leftDepth;
+
+		if (rightDepth >= 0)
+			_staticData.destUp.destinationScene.depth = rightDepth;
+
+		if (downDepth >= 0)
+			_staticData.destUp.destinationScene.depth = downDepth;
+
+		if (forwardDepth >= 0)
+			_staticData.destUp.destinationScene.depth = forwardDepth;
+	}
+}
+
 PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID, int lastStingerFileID) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 20d4c2a0ca..4896950daa 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -47,6 +47,12 @@ public:
 	int _openingSoundID;
 };
 
+class TurnDepthPreChange : public SceneBase {
+public:
+	TurnDepthPreChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, int upDepth = -1, int leftDepth = -1, int rightDepth = -1, int downDepth = -1, int forwardDepth = -1);
+};
+
 class PlayStingers : public SceneBase {
 public:
 	PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 47a464b6b67e09149e423ecfbf2ddc3e6c8444a9
    https://github.com/scummvm/scummvm/commit/47a464b6b67e09149e423ecfbf2ddc3e6c8444a9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Implement entering/exiting the environ room

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index cb1747b2fb..037cd957f7 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -140,6 +140,120 @@ int ToyClick::specifyCursor(Window *viewWindow, const Common::Point &pointLocati
 	return kCursorPutDown;
 }
 
+class MainEnvironDoorDown : public SceneBase {
+public:
+	MainEnvironDoorDown(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _doorOpen;
+	Common::Rect _doorRect;
+};
+
+MainEnvironDoorDown::MainEnvironDoorDown(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_doorOpen = false;
+
+	if (priorLocation.timeZone == _staticData.location.timeZone &&
+			priorLocation.environment == _staticData.location.environment &&
+			priorLocation.node == _staticData.location.node &&
+			priorLocation.facing == _staticData.location.facing &&
+			priorLocation.orientation == 1) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().faMNEnvironDoor == 1) {
+			_doorOpen = true;
+			_staticData.navFrameIndex = 220;
+		}
+	} else {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faMNEnvironDoor = 0;
+	}
+
+	_doorRect = Common::Rect(0, 0, 432, 189);
+}
+
+int MainEnvironDoorDown::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Play the door open movie
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 1;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 0;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_FALSE;
+}
+
+int MainEnvironDoorDown::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorRect.contains(pointLocation)) {
+		_staticData.navFrameIndex = 220;
+		_doorOpen = true;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faMNEnvironDoor = 1;
+
+		// Play the door open movie
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 0;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MainEnvironDoorDown::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorRect.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+class MainEnvironDoorExit : public SceneBase {
+public:
+	MainEnvironDoorExit(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+MainEnvironDoorExit::MainEnvironDoorExit(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int MainEnvironDoorExit::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Play the door open movie
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 1;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 14;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_FALSE;
+}
+
+class EnvironDoorExitSound : public SceneBase {
+public:
+	EnvironDoorExitSound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+};
+
+EnvironDoorExitSound::EnvironDoorExitSound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int EnvironDoorExitSound::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(IDS_FUTAPT_ENVIRON_DOOR_CLOSE));
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
 	_vm->_sound->setAmbientSound(_vm->getFilePath(4, environment, SF_AMBIENT));
 	return true;
@@ -163,6 +277,12 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 128, 0, 332, 189, 0, 23, 24);
 	case 54:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 36, kCursorFinger, 0, 0, 432, 189);
+	case 56:
+		return new MainEnvironDoorDown(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 57:
+		return new MainEnvironDoorExit(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 59:
+		return new EnvironDoorExitSound(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
 	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);


Commit: abd3a671daa046b1c4289f35b99aeae35e318c19
    https://github.com/scummvm/scummvm/commit/abd3a671daa046b1c4289f35b99aeae35e318c19
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:39+01:00

Commit Message:
BURIED: Fix capturing windows

Changed paths:
    engines/buried/window.cpp


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 996fd1837f..4706b1d07c 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -284,8 +284,8 @@ bool Window::handleSetCursorMessage(uint message) {
 }
 
 Window *Window::setCapture() {
-	Window *oldCapturedWindow = _vm->_focusedWindow;
-	_vm->_focusedWindow = this;
+	Window *oldCapturedWindow = _vm->_captureWindow;
+	_vm->_captureWindow = this;
 	return oldCapturedWindow;
 }
 


Commit: 751ce57bd4b0e2f49bc2f0272110848c813d7453
    https://github.com/scummvm/scummvm/commit/751ce57bd4b0e2f49bc2f0272110848c813d7453
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement item dragging

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index d79a1a8418..048d2cabfa 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -33,8 +33,10 @@
 #include "buried/message.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
+#include "buried/environ/scene_base.h"
 
 #include "common/algorithm.h"
+#include "common/stream.h"
 #include "graphics/font.h"
 #include "graphics/surface.h"
 
@@ -233,7 +235,11 @@ bool InventoryWindow::startDraggingNewItem(int itemID, const Common::Point &poin
 	_draggingIconIndex = 0;
 
 	InventoryElement staticItemData = getItemStaticData(_draggingItemID);
-	_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
+
+	if (_vm->isDemo())
+		_draggingItemSpriteData.image = _dragFrames->getFrameCopy(staticItemData.firstDragID + _draggingIconIndex);
+	else
+		_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
 	_draggingItemSpriteData.xPos = 0;
 	_draggingItemSpriteData.yPos = 0;
 	_draggingItemSpriteData.width = _draggingItemSpriteData.image->w;
@@ -244,9 +250,10 @@ bool InventoryWindow::startDraggingNewItem(int itemID, const Common::Point &poin
 		_draggingItemSpriteData.greenTrans = 255;
 		_draggingItemSpriteData.blueTrans = 255;
 	} else {
-		_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[0];
-		_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[1];
-		_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[2];
+		byte firstPixel = *((byte *)_draggingItemSpriteData.image->getBasePtr(0, 0));
+		_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3];
+		_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 1];
+		_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 2];
 
 		if (!_vm->isDemo()) {
 			for (int y = 0; y < _draggingItemSpriteData.height; y++) {
@@ -260,7 +267,7 @@ bool InventoryWindow::startDraggingNewItem(int itemID, const Common::Point &poin
 		}
 	}
 
-	// TODO: Set capture
+	setCapture();
 	onSetCursor(kMessageTypeLButtonDown);
 	onMouseMove(pointStart, 0);
 
@@ -409,15 +416,15 @@ void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
 				return;
 			}
 
-			// TODO: Support dragging
-			return;
-
-			InventoryElement staticItemData = getItemStaticData(_draggingItemID);
+			InventoryElement staticItemData = getItemStaticData(_itemArray[_curItem]);
 
 			if (staticItemData.firstDragID < 0)
 				return;
 
-			_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
+			if (_vm->isDemo())
+				_draggingItemSpriteData.image = _dragFrames->getFrameCopy(staticItemData.firstDragID);
+			else
+				_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
 			_draggingItemInInventory = true;
 			_itemComesFromInventory = true;
 			_draggingObject = true;
@@ -434,9 +441,10 @@ void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
 				_draggingItemSpriteData.greenTrans = 255;
 				_draggingItemSpriteData.blueTrans = 255;
 			} else {
-				_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[0];
-				_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[1];
-				_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[2];
+				byte firstPixel = *((byte *)_draggingItemSpriteData.image->getBasePtr(0, 0));
+				_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3];
+				_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 1];
+				_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 2];
 
 				if (!_vm->isDemo()) {
 					for (int y = 0; y < _draggingItemSpriteData.height; y++) {
@@ -450,7 +458,7 @@ void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
 				}
 			}
 
-			// TODO: SetCapture();
+			setCapture();
 
 			onSetCursor(kMessageTypeLButtonDown);
 			((GameUIWindow *)_parent)->_sceneViewWindow->changeSpriteStatus(true);
@@ -538,7 +546,75 @@ void InventoryWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	if (_draggingObject) {
 		_draggingObject = false;
 
-		// TODO: Lots missing
+		_vm->releaseCapture();
+
+		// Reset the cursor
+		((GameUIWindow *)getParent())->_sceneViewWindow->resetCursor();
+
+		// Did we drop on the scene or on the inventory window?
+		Common::Point ptScene = convertPointToWindow(point, ((GameUIWindow *)getParent())->_sceneViewWindow);
+		Common::Point ptGameUI = convertPointToWindow(point, getParent());
+		Window *droppedChild = getParent()->childWindowAtPoint(ptGameUI);
+		((GameUIWindow *)getParent())->_sceneViewWindow->changeSpriteStatus(false);
+
+		bool returnToInventory = true;
+		if (droppedChild == ((GameUIWindow *)getParent())->_sceneViewWindow) {
+			if (((GameUIWindow *)getParent())->_sceneViewWindow->droppedItem(_draggingItemID, ptScene, 0) == SIC_ACCEPT)
+				returnToInventory = false;
+
+			if (_draggingItemInInventory)
+				removeItem(_draggingItemID);
+		}
+
+		((GameUIWindow *)getParent())->_sceneViewWindow->changeSpriteStatus(true);
+
+		if (droppedChild == this) {
+			returnToInventory = false;
+
+			if (!_draggingItemInInventory) {
+				if (_draggingItemID == kItemCheeseGirl || _draggingItemID == kItemBioChipTranslate || _draggingItemID == kItemGenoSingleCart) {
+					if (!isItemInInventory(_draggingItemID))
+						addItem(_draggingItemID);
+				} else {
+					addItem(_draggingItemID);
+				}
+			}
+		}
+
+		if (!_itemComesFromInventory)
+			((GameUIWindow *)getParent())->_sceneViewWindow->droppedItem(_draggingItemID, Common::Point(-1, -1), 0);
+
+		if (returnToInventory) {
+			// If we dropped within the scene, then perform a graduated fall to the inventory window
+			if (ptScene.y < 190) {
+				// Loop and move the object into the inventory
+				int xDelta = 180 - ptScene.x;
+				int yDelta = 210 - ptScene.y;
+
+				for (int i = 0; i < 8; i++) {
+					xDelta /= 2;
+					yDelta /= 2;
+
+					ptScene.x += xDelta;
+					ptScene.y += yDelta;
+					_draggingItemSpriteData.xPos = ptScene.x - _draggingItemSpriteData.width / 2;
+					_draggingItemSpriteData.yPos = ptScene.y - _draggingItemSpriteData.height / 2;
+
+					((GameUIWindow *)getParent())->_sceneViewWindow->updatePrebufferWithSprite(_draggingItemSpriteData);
+
+					// TODO: Update screen? This seems to be missing *something*
+				}
+			}
+
+			if (!_draggingItemInInventory)
+				addItem(_draggingItemID);
+		}
+
+		_draggingItemSpriteData.image = 0;
+		((GameUIWindow *)getParent())->_sceneViewWindow->updatePrebufferWithSprite(_draggingItemSpriteData);
+		_itemComesFromInventory = false;
+
+		((GameUIWindow *)getParent())->_bioChipRightWindow->sceneChanged();
 	}
 
 	if (redraw) {
@@ -551,7 +627,89 @@ void InventoryWindow::onMouseMove(const Common::Point &point, uint flags) {
 	_curMousePos = point;
 
 	if (_draggingObject) {
-		// TODO
+		Common::Point ptScene = convertPointToWindow(point, ((GameUIWindow *)getParent())->_sceneViewWindow);
+		Common::Point ptView(ptScene);
+
+		if (ptScene.y > 189) {
+			if (!_draggingItemInInventory) {
+				if (_draggingItemID == kItemCheeseGirl || _draggingItemID == kItemBioChipTranslate || _draggingItemID == kItemGenoSingleCart) {
+					if (!isItemInInventory(_draggingItemID))
+						addItem(_draggingItemID);
+				} else {
+					addItem(_draggingItemID);
+				}
+
+				_draggingItemInInventory = true;
+				rebuildPreBuffer();
+				invalidateWindow();
+			}
+		} else {
+			if (_draggingItemInInventory) {
+				if (_draggingItemID == kItemCheeseGirl || _draggingItemID == kItemBioChipTranslate || _draggingItemID == kItemGenoSingleCart) {
+					if (isItemInInventory(_draggingItemID))
+						removeItem(_draggingItemID);
+				} else {
+					removeItem(_draggingItemID);
+				}
+
+				_draggingItemInInventory = false;
+				rebuildPreBuffer();
+				invalidateWindow();
+			}
+		}
+
+		ptScene.x = CLIP<int>(ptScene.x, 0, 431) - _draggingItemSpriteData.width / 2;
+		ptScene.y = MAX<int>(ptScene.y, 0) - _draggingItemSpriteData.height / 2;
+
+		int newIcon = ((GameUIWindow *)getParent())->_sceneViewWindow->draggingItem(_draggingItemID, ptView, 0);
+
+		if (_draggingIconIndex != newIcon) {
+			InventoryElement staticItemData = getItemStaticData(_draggingItemID);
+
+			if (newIcon > staticItemData.dragIDCount - 1)
+				newIcon = staticItemData.dragIDCount - 1;
+
+			if (_draggingIconIndex != newIcon) {
+				if (_draggingItemSpriteData.image) {
+					_draggingItemSpriteData.image->free();
+					delete _draggingItemSpriteData.image;
+				}
+
+				if (_vm->isDemo())
+					_draggingItemSpriteData.image = _dragFrames->getFrameCopy(staticItemData.firstDragID);
+				else
+					_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
+				_draggingItemSpriteData.xPos = 0;
+				_draggingItemSpriteData.yPos = 0;
+				_draggingItemSpriteData.width = _draggingItemSpriteData.image->w;
+				_draggingItemSpriteData.height = _draggingItemSpriteData.image->h;
+
+				if (_vm->isTrueColor()) {
+					_draggingItemSpriteData.redTrans = 255;
+					_draggingItemSpriteData.greenTrans = 255;
+					_draggingItemSpriteData.blueTrans = 255;
+				} else {
+					_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[0];
+					_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[1];
+					_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[2];
+
+					if (!_vm->isDemo()) {
+						for (int y = 0; y < _draggingItemSpriteData.height; y++) {
+							for (int x = 0; x < _draggingItemSpriteData.width; x++) {
+								byte color = *((byte *)_draggingItemSpriteData.image->getBasePtr(x, y));
+
+								if (color != 0)
+									*((byte *)_draggingItemSpriteData.image->getBasePtr(x, y)) = color + 10;
+							}
+						}
+					}
+				}
+			}
+		}
+
+		_draggingItemSpriteData.xPos = ptScene.x;
+		_draggingItemSpriteData.yPos = ptScene.y;
+		((GameUIWindow *)getParent())->_sceneViewWindow->updatePrebufferWithSprite(_draggingItemSpriteData);
 	} else {
 		Common::Rect up(95, 8, 114, 29);
 		Common::Rect down(95, 54, 114, 75);
@@ -617,8 +775,17 @@ bool InventoryWindow::isItemInInventory(int itemID) {
 }
 
 InventoryElement InventoryWindow::getItemStaticData(int itemID) {
-	// TODO
-	return InventoryElement();
+	Common::SeekableReadStream *resource = _vm->getItemData(IDER_ITEM_DB);
+	resource->seek(itemID * (2 + 4 + 4) + 2);
+
+	InventoryElement element;
+	element.itemID = resource->readSint16LE();
+	element.firstDragID = resource->readSint32LE();
+	element.dragIDCount = resource->readSint32LE();
+
+	delete resource;
+
+	return element;
 }
 
 bool InventoryWindow::destroyInfoWindow() {


Commit: cc4fd1abe24574f9b8cfa984a6a56a4c585bf2b0
    https://github.com/scummvm/scummvm/commit/cc4fd1abe24574f9b8cfa984a6a56a4c585bf2b0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add the GenericAcquireItem scene base

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 1b1d48b9a9..1553a29895 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -97,10 +97,14 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHookPresent), 0, 0, 1, 0, 0);
 	case 21:
 		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHookPresent), 0, 1, 0, 0, 0);
+	case 22:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 163, 83, 236, 162, kItemGrapplingHook, 75, offsetof(GlobalFlags, cgHookPresent));
 	case 23:
 		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgArrowPresent), 0, 0, 1, 0, 0);
 	case 24:
 		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgArrowPresent), 0, 1, 0, 0, 0);
+	case 25:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 241, 7, 284, 92, kItemBloodyArrow, 57, offsetof(GlobalFlags, cgArrowPresent));
 	case 26:
 		if (_vm->isDemo())
 			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 0, 1, 0, 0);
@@ -109,6 +113,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		if (_vm->isDemo())
 			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 1, 0, 0, 0);
 		break;
+	case 28:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 184, 111, 237, 189, kItemHammer, 3, offsetof(GlobalFlags, cgHammerPresent));
 	case 29:
 		if (_vm->isDemo())
 			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 0, 0, 1, 0);
@@ -123,6 +129,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 2 : 6, offsetof(GlobalFlags, cgBaileyOneWayGuard), IDS_HUMAN_PRESENCE_10METERS);
 	case 34:
 		return new CycleEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 5 : 7, _vm->isDemo() ? 6 : 8, offsetof(GlobalFlags, cgBaileyTwoWayGuards), IDS_HUMAN_PRESENCE_10METERS);
+	case 37:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 175, 64, 237, 126, kItemBurnedLetter, 84, offsetof(GlobalFlags, cgBurnedLetterPresent));
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	default:
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 037cd957f7..d75a104801 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -263,6 +263,14 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 11:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 200, 83, 230, 116, kItemBioChipTranslate, 61, offsetof(GlobalFlags, faKITakenPostboxItem));
+	case 12:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 202, 80, 227, 155, kItemCheeseGirl, 59, offsetof(GlobalFlags, faKITakenPostboxItem));
+	case 13:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 203, 111, 225, 129, kItemGenoSingleCart, 63, offsetof(GlobalFlags, faKITakenPostboxItem));
+	case 23:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 81, 146, 134, 189, kItemRemoteControl, 45, offsetof(GlobalFlags, faERTakenRemoteControl));
 	case 30:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14);
 	case 37:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index ebb3ee033d..ddff31a85f 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -23,8 +23,11 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
+#include "buried/inventory_window.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/scene_view.h"
@@ -105,6 +108,74 @@ TurnDepthPreChange::TurnDepthPreChange(BuriedEngine *vm, Window *viewWindow, con
 	}
 }
 
+GenericItemAcquire::GenericItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int itemID, int clearStillFrame, int itemFlagOffset) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_itemPresent = true;
+	_itemID = itemID;
+	_acquireRegion = Common::Rect(left, top, right, bottom);
+	_fullFrameIndex = sceneStaticData.navFrameIndex;
+	_clearFrameIndex = clearStillFrame;
+	_itemFlagOffset = itemFlagOffset;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) != 0) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+	}
+}
+
+int GenericItemAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_acquireRegion.contains(pointLocation) && _itemPresent) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
+
+		// Call inventory drag start function
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int GenericItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (itemID == _itemID && !_itemPresent) {
+		// Redraw the background
+		_itemPresent = true;
+		_staticData.navFrameIndex = _fullFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
+
+		viewWindow->invalidateWindow();
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int GenericItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_acquireRegion.contains(pointLocation) && _itemPresent)
+		return kCursorOpenHand;
+
+	return kCursorArrow;
+}
+
 PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID, int lastStingerFileID) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 4896950daa..78c6a7fdba 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -53,6 +53,23 @@ public:
 			int flagOffset = -1, int upDepth = -1, int leftDepth = -1, int rightDepth = -1, int downDepth = -1, int forwardDepth = -1);
 };
 
+class GenericItemAcquire : public SceneBase {
+public:
+	GenericItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = 0, int top = 0, int right = 0, int bottom = 0, int itemID = 0, int clearStillFrame = 0, int itemFlagOffset = 0);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _itemPresent;
+	Common::Rect _acquireRegion;
+	int _fullFrameIndex;
+	int _clearFrameIndex;
+	int _itemID;
+	int _itemFlagOffset;
+};
+
 class PlayStingers : public SceneBase {
 public:
 	PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 21f2d33cd90701bb416f94b19ca0d8c8689d702a
    https://github.com/scummvm/scummvm/commit/21f2d33cd90701bb416f94b19ca0d8c8689d702a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix double-free on the drag icon image

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index 048d2cabfa..12b462abd7 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -670,11 +670,6 @@ void InventoryWindow::onMouseMove(const Common::Point &point, uint flags) {
 				newIcon = staticItemData.dragIDCount - 1;
 
 			if (_draggingIconIndex != newIcon) {
-				if (_draggingItemSpriteData.image) {
-					_draggingItemSpriteData.image->free();
-					delete _draggingItemSpriteData.image;
-				}
-
 				if (_vm->isDemo())
 					_draggingItemSpriteData.image = _dragFrames->getFrameCopy(staticItemData.firstDragID);
 				else


Commit: 6d8fed8dd72bdee7e898e2374c6c17e1eb3fd1aa
    https://github.com/scummvm/scummvm/commit/6d8fed8dd72bdee7e898e2374c6c17e1eb3fd1aa
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the keep climb

The demo is completable!

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 1553a29895..44e6d5b686 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/frame_window.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
@@ -33,8 +34,105 @@
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
+#include "common/system.h"
+
 namespace Buried {
 
+class KeepInitialWallClimb : public SceneBase {
+public:
+	KeepInitialWallClimb(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _windowRect;
+};
+
+KeepInitialWallClimb::KeepInitialWallClimb(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_windowRect = Common::Rect(176, 40, 256, 80);
+}
+
+int KeepInitialWallClimb::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (_windowRect.contains(pointLocation) && itemID == kItemGrapplingHook) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_vm->isDemo() ? 3 : 1);
+
+		DestinationScene newDest;
+		newDest.destinationScene = _staticData.location;
+		newDest.destinationScene.depth = 1;
+		newDest.transitionType = TRANSITION_VIDEO;
+		newDest.transitionData = _vm->isDemo() ? 7 : 4;
+		newDest.transitionStartFrame = -1;
+		newDest.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int KeepInitialWallClimb::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (_windowRect.contains(pointLocation) && itemID == kItemGrapplingHook)
+		return 1;
+
+	return 0;
+}
+
+class KeepFinalWallClimb : public SceneBase {
+public:
+	KeepFinalWallClimb(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	bool _exitStarted;
+	uint32 _startTime;
+};
+
+KeepFinalWallClimb::KeepFinalWallClimb(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_exitStarted = false;
+	_startTime = 0;
+}
+
+int KeepFinalWallClimb::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_startTime = g_system->getMillis();
+
+	// Change the message for the demo
+	if (_vm->isDemo())
+		((SceneViewWindow *)viewWindow)->displayLiveText("What happens next?\n\nCall 1-800-943-3664 to order Buried in Time.");
+
+	return SC_TRUE;
+}
+
+int KeepFinalWallClimb::preExitRoom(Window *viewWindow, const Location &priorLocation) {
+	_exitStarted = true;
+	return SC_TRUE;
+}
+
+int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
+	if (_exitStarted)
+		return SC_TRUE;
+
+	if (g_system->getMillis() > _startTime + (_vm->isDemo() ? 10000 : 8000)) {
+		if (_vm->isDemo()) {
+			// Return to the main menu
+			((FrameWindow *)viewWindow->getParent()->getParent())->returnToMainMenu();
+		} else {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+			((SceneViewWindow *)viewWindow)->showDeathScene(3);
+			return SC_DEATH;
+		}
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	// If we passed -1, initialize time zone, otherwise the environment
 	if (environment == -1) {
@@ -87,6 +185,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 81, 25, 360, 189, 1, 4, 2, 1, 1, 1, 2, 11, 413, 25);
 	case 10:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 24, 5, 415, 189, 1, 5, 0, 2, 1, 1, 2, 11, 72, 22);
+	case 14:
+		return new KeepInitialWallClimb(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 15:
+		return new KeepFinalWallClimb(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 16:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 131, 18, 322, 189, 1, 8, 10, 1, 1, 1, 2, 11, 307, 7);
 	case 17:


Commit: 345b8924f721f0812c73662373ebbb578c25cdd8
    https://github.com/scummvm/scummvm/commit/345b8924f721f0812c73662373ebbb578c25cdd8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix the inventory info screen file name in the demo

Changed paths:
    engines/buried/inventory_info.cpp
    engines/buried/resources.h


diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index b15ef0f566..c7b6659902 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -50,7 +50,7 @@ InventoryInfoWindow::InventoryInfoWindow(BuriedEngine *vm, Window *parent, int c
 	_rect = Common::Rect(0, 0, 432, 189);
 	_videoWindow = new VideoWindow(_vm, this);
 
-	if (!_videoWindow->openVideo(_vm->getFilePath(IDS_INVENTORY_SPIN_FILENAME)))
+	if (!_videoWindow->openVideo(_vm->getFilePath(_vm->isDemo() ? IDS_INVENTORY_SPIN_FILENAME_DEMO : IDS_INVENTORY_SPIN_FILENAME)))
 		error("Failed to load inventory info file");
 
 	_videoWindow->setWindowPos(0, 268, 17, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder | kWindowPosShowWindow);
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 1b334db38c..5eb0f04ccd 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -293,6 +293,9 @@ namespace Buried {
 #define IDS_DEATH_ALIEN_FILENAME		6160
 #define IDS_DEATH_FINALE_FILENAME		6161
 
+// Demo-only:
+#define IDS_INVENTORY_SPIN_FILENAME_DEMO 10240
+
 #define IDS_BC_JUMP_VIEW_NAV_DATA		6162
 #define IDS_INVITEM_LETTER_FILENAME		6163
 


Commit: 3479260449aad5c651e3cc28fccce14644cd4aae
    https://github.com/scummvm/scummvm/commit/3479260449aad5c651e3cc28fccce14644cd4aae
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix demo inventory info timings

Changed paths:
    engines/buried/inventory_info.cpp


diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index c7b6659902..fbe9f0771b 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -69,8 +69,14 @@ InventoryInfoWindow::~InventoryInfoWindow() {
 bool InventoryInfoWindow::changeCurrentItem(int newItemID) {
 	_currentItemID = newItemID;
 
-	_spinStart = newItemID * 71;
-	_spinLength = 70;
+	if (_vm->isDemo()) {
+		_spinStart = newItemID * 72;
+		_spinLength = 71;
+	} else {
+		_spinStart = newItemID * 71;
+		_spinLength = 70;
+	}
+
 	_videoWindow->stopVideo();
 
 	_videoWindow->seekToFrame(_spinStart);


Commit: 9d81867146e3c5a4e316f9e6b9d0066a2d355950
    https://github.com/scummvm/scummvm/commit/9d81867146e3c5a4e316f9e6b9d0066a2d355950
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix destroy order for the inventory window

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index 12b462abd7..6e6371802a 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -99,6 +99,9 @@ InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 }
 
 InventoryWindow::~InventoryWindow() {
+	destroyInfoWindow();
+	destroyBurnedLetterWindow();
+
 	if (_background) {
 		_background->free();
 		delete _background;
@@ -110,10 +113,7 @@ InventoryWindow::~InventoryWindow() {
 	}
 
 	if (_scrollTimer != 0)
-		killTimer(_scrollTimer);
-
-	destroyInfoWindow();
-	destroyBurnedLetterWindow();
+		killTimer(_scrollTimer);	
 
 	delete _textFont;
 	delete _dragFrames;


Commit: 2d04529ec9b9e8b211317f66f8350e1ae4246a71
    https://github.com/scummvm/scummvm/commit/2d04529ec9b9e8b211317f66f8350e1ae4246a71
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the time jump menu

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/environ/scene_factory.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index fb8c47b41c..d0f8ab46b7 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -24,11 +24,14 @@
  */
 
 #include "buried/avi_frames.h"
+#include "buried/biochip_right.h"
 #include "buried/biochip_view.h"
 #include "buried/buried.h"
 #include "buried/fbcdata.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
+#include "buried/livetext.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 
@@ -73,6 +76,288 @@ enum {
 	REGION_NONE = 0
 };
 
+enum {
+	REGION_BRIEFING = 1,
+	REGION_JUMP = 2,
+	REGION_MAYAN = 3,
+	REGION_CASTLE = 4,
+	REGION_DAVINCI = 5,
+	REGION_SPACE_STATION = 6
+};
+
+class JumpBiochipViewWindow : public Window {
+public:
+	JumpBiochipViewWindow(BuriedEngine *vm, Window *parent);
+
+	void onPaint();
+	void onLButtonDown(const Common::Point &point, uint flags);
+	void onLButtonUp(const Common::Point &point, uint flags);
+	void onMouseMove(const Common::Point &point, uint flags);
+
+private:
+	Common::Rect _missionBriefing;
+	Common::Rect _jumpButton;
+	Common::Rect _mayanZone;
+	Common::Rect _castle;
+	Common::Rect _daVinci;
+	Common::Rect _spaceStation;
+	AVIFrames _stillFrames;
+	int _curSelection;
+
+	int _curState;
+
+	static const byte _briefingNavData[4][2];
+	int _curRegion;
+	int _curBriefingPage;
+
+	bool _currentMissionReviewed;
+};
+
+const byte JumpBiochipViewWindow::_briefingNavData[4][2] = {
+	{ 2, 2 },
+	{ 4, 3 },
+	{ 7, 2 },
+	{ 9, 4 }
+};
+
+JumpBiochipViewWindow::JumpBiochipViewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_missionBriefing = Common::Rect(306, 24, 422, 74);
+	_jumpButton = Common::Rect(306, 84, 422, 134);
+	_mayanZone = Common::Rect(9, 48, 272, 74);
+	_castle = Common::Rect(9, 78, 296, 104);
+	_daVinci = Common::Rect(9, 108, 284, 134);
+	_spaceStation = Common::Rect(9, 138, 284, 164);
+	_curRegion = REGION_NONE;
+	_curSelection = -1;
+	_curState = 0;
+	_curBriefingPage = 0;
+	_currentMissionReviewed = false;
+
+	_rect = Common::Rect(0, 0, 432, 189);
+
+	if (!_stillFrames.open(_vm->getFilePath(IDS_BC_JUMP_VIEW_FILENAME)))
+		error("Failed to open jump view video");
+}
+
+void JumpBiochipViewWindow::onPaint() {
+	Common::Rect absoluteRect = getAbsoluteRect();
+
+	if (_curState == 0) {
+		const Graphics::Surface *frame = _stillFrames.getFrame(0);
+		_vm->_gfx->blit(frame, absoluteRect.left, absoluteRect.top);
+
+		if (_curSelection >= 0) {	
+			frame = _stillFrames.getFrame(1);
+
+			Common::Rect highlightRect(11, _curSelection * 30 + 50, 11 + 23, _curSelection * 30 + 50 + 23);
+			_vm->_gfx->blit(frame, highlightRect, makeAbsoluteRect(highlightRect));
+			_vm->_gfx->blit(frame, Common::Rect(306, 24, 306 + 116, 24 + 50), makeAbsoluteRect(Common::Rect(306, 24, 306 + 116, 24 + 50)));
+
+			if (_currentMissionReviewed)
+				_vm->_gfx->blit(frame, Common::Rect(306, 84, 306 + 116, 84 + 50), makeAbsoluteRect(Common::Rect(306, 84, 306 + 116, 84 + 50)));
+		}
+	} else {
+		const Graphics::Surface *frame = _stillFrames.getFrame(_briefingNavData[_curSelection][0] + _curBriefingPage);
+		_vm->_gfx->blit(frame, absoluteRect.left, absoluteRect.top);
+	}
+}
+
+void JumpBiochipViewWindow::onLButtonDown(const Common::Point &point, uint flags) {
+	if (_curState == 0) {
+		if (_jumpButton.contains(point) && _curSelection >= 0) {
+			if (_currentMissionReviewed) {
+				if (((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().faHeardAgentFigure == 1)
+					_curRegion = REGION_JUMP;
+				else
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_MBT_JUMP_LOCKOUT_TEXT));
+			} else {
+				((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_JUMP_BC_REVIEW_MISSION_TEXT_A + _curSelection));
+				return;
+			}
+		} else if (_missionBriefing.contains(point) && _curSelection >= 0) {
+			_curRegion = REGION_BRIEFING;
+		} else if (_mayanZone.contains(point)) {
+			_curRegion = REGION_MAYAN;
+			_curSelection = 0;
+		} else if (_castle.contains(point)) {
+			_curRegion = REGION_CASTLE;
+			_curSelection = 1;
+		} else if (_daVinci.contains(point)) {
+			_curRegion = REGION_DAVINCI;
+			_curSelection = 2;
+		} else if (_spaceStation.contains(point)) {
+			_curRegion = REGION_SPACE_STATION;
+			_curSelection = 3;
+		}
+
+		invalidateWindow(false);
+	}
+}
+
+void JumpBiochipViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_curState == 0) {
+		switch (_curRegion) {
+		case REGION_BRIEFING:
+			if (_missionBriefing.contains(point)) {
+				_currentMissionReviewed = true;
+				_curState = 1;
+				_curBriefingPage = 0;
+				invalidateWindow(false);
+
+				switch (_curSelection) {
+				case 0:
+					((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpMayanBriefing = 1;
+					break;
+				case 1:
+					((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpCastleBriefing = 1;
+					break;
+				case 2:
+					((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpDaVinciBriefing = 1;
+					break;
+				case 3:
+					((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpStationBriefing = 1;
+					break;
+				}
+			}
+			break;
+		case REGION_JUMP:
+			if (_jumpButton.contains(point)) {
+				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+				SceneViewWindow *sceneViewWindow = (SceneViewWindow *)getParent()->getParent();
+				int curSelection = _curSelection;
+				GraphicsManager *gfx = _vm->_gfx;
+
+				((GameUIWindow *)getParent()->getParent()->getParent())->_bioChipRightWindow->destroyBioChipViewWindow();
+				sceneViewWindow->timeSuitJump(curSelection);
+				gfx->setCursor(oldCursor);
+				return;
+			}
+			break;
+		case REGION_MAYAN:
+			if (_mayanZone.contains(point)) {
+				if (((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpMayanBriefing == 1) {
+					_currentMissionReviewed = true;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText("");
+				} else {
+					_currentMissionReviewed = false;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_JUMP_BC_REVIEW_MISSION_TEXT_A));
+				}
+	
+				_curSelection = 0;
+				invalidateWindow(false);
+			}
+			break;
+		case REGION_CASTLE:
+			if (_castle.contains(point)) {
+				if (((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpCastleBriefing == 1) {
+					_currentMissionReviewed = true;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText("");
+				} else {
+					_currentMissionReviewed = false;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_JUMP_BC_REVIEW_MISSION_TEXT_B));
+				}
+	
+				_curSelection = 1;
+				invalidateWindow(false);
+			}
+			break;
+		case REGION_DAVINCI:
+			if (_daVinci.contains(point)) {
+				if (((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpDaVinciBriefing == 1) {
+					_currentMissionReviewed = true;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText("");
+				} else {
+					_currentMissionReviewed = false;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_JUMP_BC_REVIEW_MISSION_TEXT_C));
+				}
+	
+				_curSelection = 2;
+				invalidateWindow(false);
+			}
+			break;
+		case REGION_SPACE_STATION:
+			if (_spaceStation.contains(point)) {
+				if (((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().genJumpStationBriefing == 1) {
+					_currentMissionReviewed = true;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText("");
+				} else {
+					_currentMissionReviewed = false;
+					((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_JUMP_BC_REVIEW_MISSION_TEXT_D));
+				}
+	
+				_curSelection = 3;
+				invalidateWindow(false);
+			}
+			break;
+		}
+
+		_curRegion = REGION_NONE;
+		invalidateWindow(false);
+	} else {
+		// Browsing the mission review pages
+		Common::Rect returnRect(343, 157, 427, 185);
+		Common::Rect nextPage(230, 25, 270, 43);
+		Common::Rect prevPage(182, 25, 222, 43);
+
+		if (returnRect.contains(point)) {
+			_curState = 0;
+			invalidateWindow(false);
+		} else if (prevPage.contains(point)) {
+			if (_curBriefingPage > 0) {
+				_curBriefingPage--;
+				invalidateWindow(false);
+			}
+		} else if (nextPage.contains(point)) {
+			if (_curBriefingPage < _briefingNavData[_curSelection][1] - 1) {
+				_curBriefingPage++;
+				invalidateWindow(false);
+			}
+		}
+	}
+}
+
+void JumpBiochipViewWindow::onMouseMove(const Common::Point &point, uint flags) {
+	if (_curState == 0 && _curRegion > 0) {
+		switch (_curRegion) {
+		case REGION_BRIEFING:
+			if (!_missionBriefing.contains(point))
+				_curRegion = REGION_NONE;
+			break;
+		case REGION_JUMP:
+			if (!_jumpButton.contains(point))
+				_curRegion = REGION_NONE;
+			break;
+		case REGION_MAYAN:
+		case REGION_CASTLE:
+		case REGION_DAVINCI:
+		case REGION_SPACE_STATION: {
+			int newRegion = REGION_NONE;
+
+			if (_mayanZone.contains(point)) {
+				newRegion = REGION_MAYAN;
+				_curSelection = 0;
+			} else if (_castle.contains(point)) {
+				newRegion = REGION_CASTLE;
+				_curSelection = 1;
+			} else if (_daVinci.contains(point)) {
+				newRegion = REGION_DAVINCI;
+				_curSelection = 2;
+			} else if (_spaceStation.contains(point)) {
+				newRegion = REGION_SPACE_STATION;
+				_curSelection = 3;
+			}
+
+			if (newRegion != REGION_NONE && _curRegion != newRegion) {
+				_curRegion = newRegion;
+				invalidateWindow(false);
+			}
+			break;
+		}
+		}
+	}
+}
+
 enum {
 	REGION_SAVE = 1,
 	REGION_RESTORE = 2,
@@ -331,8 +616,7 @@ Window *BioChipMainViewWindow::createBioChipSpecificViewWindow(int bioChipID) {
 	case kItemBioChipInterface:
 		return new InterfaceBioChipViewWindow(_vm, this);
 	case kItemBioChipJump:
-		// TODO
-		break;
+		return new JumpBiochipViewWindow(_vm, this);
 	case kItemBioChipEvidence:
 		// TODO
 		break;
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 51a5d14b1b..afb293199b 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -113,7 +113,7 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
-	return 0;
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
 bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment) {


Commit: 73be4ce2e89daef350a8ccf2cbe0334bacf5c0d6
    https://github.com/scummvm/scummvm/commit/73be4ce2e89daef350a8ccf2cbe0334bacf5c0d6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add stub for the AI lab

Changed paths:
  A engines/buried/environ/ai_lab.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/global_flags.h
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
new file mode 100644
index 0000000000..88288bb2cc
--- /dev/null
+++ b/engines/buried/environ/ai_lab.cpp
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/invdata.h"
+#include "buried/inventory_window.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment) {
+	if (environment == -1) {
+		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
+
+		flags.aiHWStingerID = 0;
+		flags.aiHWStingerChannelID = 0;
+		flags.aiCRStingerID = 0;
+		flags.aiCRStingerChannelID = 0;
+		flags.aiDBStingerID = 0;
+		flags.aiDBStingerChannelID = 0;
+		flags.aiOxygenTimer = kAIHWStartingValue;
+		flags.aiCRPressurized = flags.generalWalkthroughMode;
+		flags.aiCRPressurizedAttempted = 0;
+		flags.aiMRPressurized = flags.generalWalkthroughMode;
+		flags.aiIceMined = 0;
+		flags.aiOxygenReserves = 1;
+		flags.aiSCHeardInitialSpeech = 0;
+		flags.aiMRCorrectFreqSet = 4;
+		flags.aiSCConversationStatus = 0;
+		flags.aiSCHeardNexusDoorComment = 0;
+		flags.aiSCHeardNexusDoorCode = 0;
+		flags.aiNXPlayedBrainComment = 0;
+		flags.aiDBPlayedSecondArthur = 0;
+		flags.aiDBPlayedThirdArthur = 0;
+		flags.aiDBPlayedFourthArthur = 0;
+		flags.aiCRGrabbedMetalBar = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemMetalBar) ? 1 : 0;
+		flags.aiICGrabbedWaterCanister = (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemWaterCanEmpty) || ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemWaterCanFull)) ? 1 : 0;
+	} else if (environment == 1) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredSpaceStation = 1;
+	}
+
+	return true;
+}
+
+bool SceneViewWindow::startAILabAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	// TODO: Fix sound fading
+	_vm->_sound->setAmbientSound(_vm->getFilePath(6, environment, SF_AMBIENT), false /* fade */, 64);
+	return true;
+}
+
+SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	warning("TODO: AI lab scene object %d", sceneStaticData.classID);
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index afb293199b..4d728352f2 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -82,7 +82,9 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 
 	switch (timeZone) {
 	case 4:
-		return startFutureApartmentAmbient(oldTimeZone, environment, environment, fade);
+		return startFutureApartmentAmbient(oldTimeZone, oldEnvironment, environment, fade);
+	case 6:
+		return startAILabAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 10:
 		return _vm->_sound->setAmbientSound();
 	}
@@ -100,15 +102,16 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 	case 2: // Mayan
 	case 3: // Agent 3's Lair
 	case 5: // Da Vinci
-	case 6: // AI Lab
 	case 7: // Alien
 		// TODO
 		warning("Could not create scene object for time zone %d", sceneStaticData.location.timeZone);
 		break;
 	case 1: // Castle
 		return constructCastleSceneObject(viewWindow, sceneStaticData, priorLocation);
-	case 4:
+	case 4: // Future Apartment
 		return constructFutureApartmentSceneObject(viewWindow, sceneStaticData, priorLocation);
+	case 6: // AI Lab
+		return constructAILabSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 10: // Old Apartment
 		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
@@ -121,6 +124,8 @@ bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int t
 	switch (timeZone) {
 	case 1:
 		return initializeCastleTimeZoneAndEnvironment(viewWindow, environment);
+	case 6:
+		return initializeAILabTimeZoneAndEnvironment(viewWindow, environment);
 	case 4:
 		// Nothing to do
 		return true;
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index 1826243136..9ad2ba8f83 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -323,6 +323,15 @@ struct GlobalFlags {
 
 #include "common/pack-end.h"
 
+enum {
+	kAIHWStartingValue = 100,
+	kAIICStartingValue = 100,
+	kAIOTWalkDecrement = 2,
+	kAIOTTurnDecrement = 1,
+	kAIOTWaitDecrement = 1,
+	kAIOTWaitTimePeriod = 10000
+};
+
 } // End of namespace Buried
 
 #endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 134dc2ee81..cd63929236 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -28,6 +28,7 @@ MODULE_OBJS = \
 	demo/demo_menu.o \
 	demo/features.o \
 	demo/movie_scene.o \
+	environ/ai_lab.o \
 	environ/castle.o \
 	environ/future_apartment.o \
 	environ/scene_base.o \
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 94f855565a..064a990416 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -198,6 +198,11 @@ private:
 	Common::Array<AnimEvent> getAnimationDatabase(int timeZone, int environment);
 	Common::Array<AIComment> getAICommentDatabase(int timeZone, int environment);
 
+	// AI Lab
+	bool initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	bool startAILabAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
+	SceneBase *constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
 	// Castle
 	bool initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	SceneBase *constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);


Commit: 4a2d15aacd814a8440c5d7b39eab3cf2ce146cb8
    https://github.com/scummvm/scummvm/commit/4a2d15aacd814a8440c5d7b39eab3cf2ce146cb8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add ambient sounds to the castle time zone

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 44e6d5b686..f6a10f9fbc 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -31,6 +31,7 @@
 #include "buried/inventory_window.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
+#include "buried/sound.h"
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
@@ -169,6 +170,15 @@ bool SceneViewWindow::initializeCastleTimeZoneAndEnvironment(Window *viewWindow,
 	return true;
 }
 
+bool SceneViewWindow::startCastleAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	if (_vm->isDemo())
+		return false;
+
+	// TODO: Fix sound fading
+	_vm->_sound->setAmbientSound(_vm->getFilePath(1, environment, SF_AMBIENT), false /* fade */, 64);
+	return true;
+}
+
 SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 4d728352f2..4a259463ff 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -81,6 +81,8 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 	// TODO
 
 	switch (timeZone) {
+	case 1:
+		return startCastleAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 4:
 		return startFutureApartmentAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 6:
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 064a990416..aabae45dcc 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -205,6 +205,7 @@ private:
 
 	// Castle
 	bool initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	bool startCastleAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 
 	// Future Apartment


Commit: 2affb8163b3d1b0a8c528d1afb03c63fb0d49f03
    https://github.com/scummvm/scummvm/commit/2affb8163b3d1b0a8c528d1afb03c63fb0d49f03
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add stub for mayan

Changed paths:
  A engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/global_flags.h
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
new file mode 100644
index 0000000000..8e2fa5c16f
--- /dev/null
+++ b/engines/buried/environ/mayan.cpp
@@ -0,0 +1,131 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/invdata.h"
+#include "buried/inventory_window.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
+	if (environment == -1) {
+		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
+
+		flags.myTPCodeWheelStatus = flags.generalWalkthroughMode;
+		flags.myTPCodeWheelLeftIndex = flags.generalWalkthroughMode == 1 ? 8 : 0;
+		flags.myTPCodeWheelRightIndex = flags.generalWalkthroughMode == 1 ? 12 : 0;
+		flags.myMCDeathGodOfferings = 0;
+		flags.myWGPlacedRope = flags.generalWalkthroughMode;
+		flags.myWTCurrentBridgeStatus = 0;
+		flags.myAGHeadAStatus = flags.generalWalkthroughMode == 1 ? 2 : 0;
+		flags.myAGHeadBStatus = 0;
+		flags.myAGHeadCStatus = 0;
+		flags.myAGHeadDStatus = flags.generalWalkthroughMode == 1 ? 2 : 0;
+		flags.myAGHeadAStatusSkullID = flags.generalWalkthroughMode == 1 ? kItemCavernSkull : 0;
+		flags.myAGHeadBStatusSkullID = 0;
+		flags.myAGHeadCStatusSkullID = 0;
+		flags.myAGHeadDStatusSkullID = flags.generalWalkthroughMode == 1 ? kItemSpearSkull : 0;
+		flags.myAGTimerHeadID = 0;
+		flags.myAGTimerStartTime = 0;
+		flags.myDGOfferedHeart = 0;
+		flags.myAGHeadAOpenedTime = 0;
+		flags.myAGHeadBOpenedTime = 0;
+		flags.myAGHeadCOpenedTime = 0;
+		flags.myAGHeadDOpenedTime = 0;
+
+		flags.myPickedUpCeramicBowl = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCeramicBowl) ? 1 : 0;
+		flags.myMCPickedUpSkull = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ? 1 : 0;
+		flags.myWGRetrievedJadeBlock = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemJadeBlock) ? 1 : 0;
+		flags.myWTRetrievedLimestoneBlock = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemLimestoneBlock) ? 1 : 0;
+		flags.myAGRetrievedEntrySkull = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ? 1 : 0;
+		flags.myAGRetrievedSpearSkull = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull) ? 1 : 0;
+		flags.myAGRetrievedCopperMedal = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCopperMedallion) ? 1 : 0;
+		flags.myAGRetrievedObsidianBlock = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemObsidianBlock) ? 1 : 0;
+		flags.takenEnvironCart = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemEnvironCart) ? 1 : 0;
+
+		if (flags.generalWalkthroughMode == 1) {
+			flags.myMCPickedUpSkull = 1;
+			flags.myAGRetrievedSpearSkull = 1;
+			flags.myAGRetrievedCopperMedal = 1;
+		}
+	} else if (environment == 2) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredMainCavern = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedMainCavern = 1;
+	} else if (environment == 3) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedWealthGod = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
+	} else if (environment == 4) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedWaterGod = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
+	} else if (environment == 5) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedArrowGod = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
+	} else if (environment == 6) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedDeathGod = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
+	}
+
+	return true;
+}
+
+bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	// TODO: Fix sound fading
+	fade = false;
+	bool checkFade = false;
+
+	if (environment == 3) {
+		if (oldEnvironment == 2)
+			return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 64);
+
+		return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 16); 
+	} else if (environment == 4) {
+		if (oldTimeZone == -2)
+			_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
+		else
+			_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 16);
+
+		return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 13), checkFade, 0);
+	} else if (environment == 5) {
+		_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
+		return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 12), checkFade, 128);
+	}
+
+	_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), false /* fade */, 64);
+	return true;
+}
+
+SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	warning("TODO: Mayan scene object %d", sceneStaticData.classID);
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 4a259463ff..4d2aae7309 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -83,6 +83,8 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 	switch (timeZone) {
 	case 1:
 		return startCastleAmbient(oldTimeZone, oldEnvironment, environment, fade);
+	case 2:
+		return startMayanAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 4:
 		return startFutureApartmentAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 6:
@@ -101,7 +103,6 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 
 	switch (sceneStaticData.location.timeZone) {
 	case 0: // Miscellaneous scenes
-	case 2: // Mayan
 	case 3: // Agent 3's Lair
 	case 5: // Da Vinci
 	case 7: // Alien
@@ -110,6 +111,8 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		break;
 	case 1: // Castle
 		return constructCastleSceneObject(viewWindow, sceneStaticData, priorLocation);
+	case 2: // Mayan
+		return constructMayanSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 4: // Future Apartment
 		return constructFutureApartmentSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 6: // AI Lab
@@ -126,11 +129,13 @@ bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int t
 	switch (timeZone) {
 	case 1:
 		return initializeCastleTimeZoneAndEnvironment(viewWindow, environment);
-	case 6:
-		return initializeAILabTimeZoneAndEnvironment(viewWindow, environment);
+	case 2:
+		return initializeMayanTimeZoneAndEnvironment(viewWindow, environment);
 	case 4:
 		// Nothing to do
 		return true;
+	case 6:
+		return initializeAILabTimeZoneAndEnvironment(viewWindow, environment);
 	}
 
 	return false;
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index 9ad2ba8f83..ddfb12ab42 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -62,7 +62,7 @@ struct GlobalFlags {
 	byte myMCPickedUpSkull;             // 19
 	byte myMCDeathGodOfferings;         // 20
 	byte myWGPlacedRope;                // 21
-	byte myWGRetrivedJadeBlock;         // 22
+	byte myWGRetrievedJadeBlock;        // 22
 	byte myWTRetrievedLimestoneBlock;   // 23
 	byte myWTCurrentBridgeStatus;       // 24
 	byte myAGRetrievedEntrySkull;       // 25
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index cd63929236..f195c7f96b 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -31,6 +31,7 @@ MODULE_OBJS = \
 	environ/ai_lab.o \
 	environ/castle.o \
 	environ/future_apartment.o \
+	environ/mayan.o \
 	environ/scene_base.o \
 	environ/scene_common.o \
 	environ/scene_factory.o
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index aabae45dcc..59fae7f7a0 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -211,6 +211,11 @@ private:
 	// Future Apartment
 	bool startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
+	// Mayan
+	bool initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	bool startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
+	SceneBase *constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 };
 
 } // End of namespace Buried


Commit: cade2e076f80f318dfb9a3be4dbec3901db6df30
    https://github.com/scummvm/scummvm/commit/cade2e076f80f318dfb9a3be4dbec3901db6df30
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add a Da Vinci stub

Changed paths:
  A engines/buried/environ/da_vinci.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
new file mode 100644
index 0000000000..b67f722f45
--- /dev/null
+++ b/engines/buried/environ/da_vinci.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/invdata.h"
+#include "buried/inventory_window.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+
+namespace Buried {
+
+enum {
+	DS_SC_DRIVE_ASSEMBLY = 1,
+	DS_SC_WHEEL_ASSEMBLY = 2,
+	DS_SC_PEGS = 4,
+	DS_SC_COMPLETED = 8
+};
+
+bool SceneViewWindow::initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment) {
+	if (environment == -1) {
+		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
+
+		flags.dsPTElevatorPresent = flags.generalWalkthroughMode;
+		flags.dsPTElevatorLeverA = flags.generalWalkthroughMode;
+		flags.dsPTElevatorLeverB = flags.generalWalkthroughMode;
+		flags.dsCYBallistaStatus = flags.generalWalkthroughMode;
+		flags.dsWSSiegeCycleStatus = 0;
+		flags.dsCTUnlockedDoor = flags.generalWalkthroughMode;
+		flags.dsCTPlayedBallistaFalling = 0;
+		flags.dsCYPlacedSiegeCycle = 0;
+		flags.dsCYBallistaXPos = 0;
+		flags.dsCYBallistaYPos = 0;
+
+		flags.dsWSPickedUpWheelAssembly = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemWheelAssembly) ? 1 : 0;
+		flags.dsWSPickedUpGearAssembly = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemDriveAssembly) ? 1 : 0;
+		flags.dsWSPickedUpPegs = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemWoodenPegs) ? 1 : 0;
+		flags.dsWSGrabbedSiegeCycle = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle) ? 1 : 0;
+		flags.dsGDTakenCoilOfRope = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCoilOfRope) ? 1 : 0;
+		flags.dsCTRetrievedLens = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter) ? 1 : 0;
+		flags.dsCTTakenHeart = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemPreservedHeart) ? 1 : 0;
+
+		if (flags.generalWalkthroughMode == 1) {
+			flags.dsWSSiegeCycleStatus = DS_SC_COMPLETED;
+			flags.dsWSPickedUpWheelAssembly = 1;
+			flags.dsWSPickedUpGearAssembly = 1;
+			flags.dsWSPickedUpPegs = 1;
+		}
+	} else if (environment == 2) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredCodexTower = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsVisitedCodexTower = 1;
+	}
+
+	return true;
+}
+
+bool SceneViewWindow::startDaVinciAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	// TODO: Fix sound fading
+	_vm->_sound->setAmbientSound(_vm->getFilePath(5, environment, SF_AMBIENT), false /* fade */, 64);
+	return true;
+}
+
+SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 4d2aae7309..57f780d86e 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -87,6 +87,8 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 		return startMayanAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 4:
 		return startFutureApartmentAmbient(oldTimeZone, oldEnvironment, environment, fade);
+	case 5:
+		return startDaVinciAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 6:
 		return startAILabAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 10:
@@ -104,7 +106,6 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 	switch (sceneStaticData.location.timeZone) {
 	case 0: // Miscellaneous scenes
 	case 3: // Agent 3's Lair
-	case 5: // Da Vinci
 	case 7: // Alien
 		// TODO
 		warning("Could not create scene object for time zone %d", sceneStaticData.location.timeZone);
@@ -115,6 +116,8 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		return constructMayanSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 4: // Future Apartment
 		return constructFutureApartmentSceneObject(viewWindow, sceneStaticData, priorLocation);
+	case 5: // Da Vinci
+		return constructDaVinciSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 6: // AI Lab
 		return constructAILabSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 10: // Old Apartment
@@ -134,6 +137,8 @@ bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int t
 	case 4:
 		// Nothing to do
 		return true;
+	case 5:
+		return initializeDaVinciTimeZoneAndEnvironment(viewWindow, environment);
 	case 6:
 		return initializeAILabTimeZoneAndEnvironment(viewWindow, environment);
 	}
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index f195c7f96b..f23c3d3020 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -30,6 +30,7 @@ MODULE_OBJS = \
 	demo/movie_scene.o \
 	environ/ai_lab.o \
 	environ/castle.o \
+	environ/da_vinci.o \
 	environ/future_apartment.o \
 	environ/mayan.o \
 	environ/scene_base.o \
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 59fae7f7a0..764892a08b 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -208,6 +208,11 @@ private:
 	bool startCastleAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 
+	// Da Vinci's Studio
+	bool initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	bool startDaVinciAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
+	SceneBase *constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
 	// Future Apartment
 	bool startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);


Commit: 109212e2dcf809418f2d798e5a88cdb8b9f87fb8
    https://github.com/scummvm/scummvm/commit/109212e2dcf809418f2d798e5a88cdb8b9f87fb8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add a bunch of Da Vinci scenes

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index b67f722f45..54d04f9daa 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -25,12 +25,14 @@
 
 #include "buried/buried.h"
 #include "buried/gameui.h"
+#include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
 
 namespace Buried {
 
@@ -87,6 +89,45 @@ bool SceneViewWindow::startDaVinciAmbient(int oldTimeZone, int oldEnvironment, i
 SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
+	switch (sceneStaticData.classID) {
+	case 13:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 196, 0, 262, 189, 5, 3, 10, 1, 1, 1, TRANSITION_WALK, 11, 881, 20);
+	case 14:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 208, 0, 306, 189, 5, 3, 0, 2, 1, 1, TRANSITION_WALK, 11, 740, 23);
+	case 18:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 216, 0, 324, 189, 5, 3, 2, 0, 1, 1, TRANSITION_WALK, 11, 833, 26);
+	case 19:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 194, 0, 354, 189, 5, 3, 9, 1, 1, 1, TRANSITION_WALK, 11, 791, 21);
+	case 20:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 102, 0, 208, 189, 5, 4, 14, 0, 1, 1, TRANSITION_WALK, 11, 1169, 28);
+	case 21:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 80, 0, 250, 189, 5, 4, 15, 3, 1, 1, TRANSITION_WALK, 11, 1126, 26);
+	case 22:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 110, 138, 170, 189);
+	case 23:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 4, kCursorFinger, 180, 122, 290, 189);
+	case 32:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 90, 328, 162, kItemDriveAssembly, 145, offsetof(GlobalFlags, dsWSPickedUpGearAssembly));
+	case 33:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 164, 126, 276, 160, kItemWoodenPegs, 96, offsetof(GlobalFlags, dsWSPickedUpPegs));
+	case 38:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 130, 74, 182, 120, kItemCoilOfRope, 48, offsetof(GlobalFlags, dsGDTakenCoilOfRope));
+	case 41:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 116, 0, 326, 189, 5, 2, 2, 1, 1, 1, TRANSITION_WALK, 11, 225, 15);
+	case 46:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 8, kCursorFinger, 102, 124, 164, 189);
+	case 59:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 70, 136, 190, 189);
+	case 60:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 5, kCursorFinger, 42, 0, 418, 100);
+	case 61:
+		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 3, kCursorFinger, 178, 144, 288, 189);
+	case 65:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
+	case 66:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 170, 0, 432, 189, 5, 4, 0, 0, 1, 1, TRANSITION_WALK, 11, 1220, 12);
+	}
+
 	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }


Commit: 911ac215fa24cfa6493b19e7e9ec3ba256bff191
    https://github.com/scummvm/scummvm/commit/911ac215fa24cfa6493b19e7e9ec3ba256bff191
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix navigation arrows after decloaking

Changed paths:
    engines/buried/biochip_right.cpp
    engines/buried/scene_view.cpp


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index 9467df08c9..5eaee87975 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -302,6 +302,7 @@ void BioChipRightWindow::onLButtonUp(const Common::Point &point, uint flags) {
 				invalidateWindow(false);
 
 				((GameUIWindow *)_parent)->_sceneViewWindow->getGlobalFlags().bcCloakingEnabled = 0;
+				((GameUIWindow *)_parent)->_sceneViewWindow->resetNavigationArrows();
 				((GameUIWindow *)_parent)->_inventoryWindow->enableWindow(true);
 				((GameUIWindow *)_parent)->_sceneViewWindow->enableWindow(true);
 				((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 981cbcc427..5ec82c8cf2 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2376,6 +2376,16 @@ void SceneViewWindow::onEnable(bool enable) {
 	_vm->removeMouseMessages(this);
 }
 
+bool SceneViewWindow::resetNavigationArrows() {
+	if (!_currentScene)
+		return false;
+
+	if (_globalFlags.bcCloakingEnabled != 1)
+		((GameUIWindow *)_parent)->_navArrowWindow->updateAllArrows(_currentScene->_staticData);
+
+	return true;
+}
+
 int SceneViewWindow::draggingItem(int itemID, const Common::Point &location, int itemFlags) {
 	if (!_currentScene)
 		return 0;


Commit: 89f903d3012cbf03897ce8240d03e4f3fe6f9fff
    https://github.com/scummvm/scummvm/commit/89f903d3012cbf03897ce8240d03e4f3fe6f9fff
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the castle exploding wall

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index f6a10f9fbc..4383fbba27 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -39,6 +39,80 @@
 
 namespace Buried {
 
+enum {
+	CATAPULT_TIMEOUT_VALUE = 6000
+};
+
+class ExplodingWallSafeDistance : public SceneBase {
+public:
+	ExplodingWallSafeDistance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	bool _timerStarted;
+	uint32 _startTime;
+	bool _walkthrough;
+};
+
+ExplodingWallSafeDistance::ExplodingWallSafeDistance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_timerStarted = false;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData == 0) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData = g_system->getMillis();
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 127, false, true);
+	}
+
+	_walkthrough = ((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1;
+}
+
+int ExplodingWallSafeDistance::timerCallback(Window *viewWindow) {
+	uint32 timer = ((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData;
+	if (_walkthrough || (timer + CATAPULT_TIMEOUT_VALUE < g_system->getMillis())) {
+		// Play the explosion movie
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+
+		// Change the background bitmap
+		_staticData.navFrameIndex = 139;
+		viewWindow->invalidateWindow(false);
+
+		// Reset the safety flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgWallExploded = 1;
+
+		// Move to our depth 1 counterpart
+		Location newLocation = _staticData.location;
+		newLocation.depth = 1;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+	}
+
+	return SC_TRUE;
+}
+
+class ExplodingWallDeath : public SceneBase {
+public:
+	ExplodingWallDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+};
+
+ExplodingWallDeath::ExplodingWallDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int ExplodingWallDeath::timerCallback(Window *viewWindow) {
+	// clone2727 asks why this is a timer callback
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().cgWallExploded == 0) {
+		// Play the explosion movie
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+
+		// Notify the player of his gruesome death
+		((SceneViewWindow *)viewWindow)->showDeathScene(2);
+		return SC_DEATH;
+	}
+
+	return SC_TRUE;
+}
+
 class KeepInitialWallClimb : public SceneBase {
 public:
 	KeepInitialWallClimb(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -195,6 +269,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 81, 25, 360, 189, 1, 4, 2, 1, 1, 1, 2, 11, 413, 25);
 	case 10:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 24, 5, 415, 189, 1, 5, 0, 2, 1, 1, 2, 11, 72, 22);
+	case 12:
+		return new ExplodingWallSafeDistance(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 13:
+		return new ExplodingWallDeath(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 14:
 		return new KeepInitialWallClimb(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 15:


Commit: 43b63cca28ee9cc019b06402cbdc99da14b21c50
    https://github.com/scummvm/scummvm/commit/43b63cca28ee9cc019b06402cbdc99da14b21c50
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the king's chamber guards encounter

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 4383fbba27..fb6f8ed9b0 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -208,6 +208,56 @@ int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class KingsChamberGuardEncounter : public SceneBase {
+public:
+	KingsChamberGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	uint32 _startingTime;
+	bool _finished;
+};
+
+KingsChamberGuardEncounter::KingsChamberGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_startingTime = 0;
+}
+
+int KingsChamberGuardEncounter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Start the audio cue playing and store the starting time
+	_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 127, false, true);
+	_startingTime = g_system->getMillis();
+	return SC_TRUE;
+}
+
+int KingsChamberGuardEncounter::timerCallback(Window *viewWindow) {
+	SceneBase::timerCallback(viewWindow);
+
+	if (_startingTime + 16000 < g_system->getMillis()) {
+		// Check the cloak biochip status
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 1) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(1);
+
+			// Jump to next scene depth
+			DestinationScene newDest;
+			newDest.destinationScene = _staticData.location;
+			newDest.destinationScene.depth = 0;
+			newDest.transitionType = TRANSITION_NONE;
+			newDest.transitionData = -1;
+			newDest.transitionStartFrame = -1;
+			newDest.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->jumpToScene(newDest.destinationScene);
+		} else {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+			((SceneViewWindow *)viewWindow)->showDeathScene(4);
+			return SC_DEATH;
+		}
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	// If we passed -1, initialize time zone, otherwise the environment
 	if (environment == -1) {
@@ -323,6 +373,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 175, 64, 237, 126, kItemBurnedLetter, 84, offsetof(GlobalFlags, cgBurnedLetterPresent));
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
+	case 48:
+		return new KingsChamberGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
 	default:
 		warning("TODO: Castle scene object %d", sceneStaticData.classID);
 		break;


Commit: 49bd829ec116c2bd2ea512304999c43ad8f77e91
    https://github.com/scummvm/scummvm/commit/49bd829ec116c2bd2ea512304999c43ad8f77e91
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix frame cycling

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/frame_window.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index d0f8ab46b7..4c6663470f 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -428,7 +428,7 @@ void InterfaceBioChipViewWindow::onPaint() {
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(_background, absoluteRect.left, absoluteRect.top);
 
-	if (((SceneViewWindow *)_parent)->getCyclingStatus())
+	if (((SceneViewWindow *)getParent()->getParent())->getCyclingStatus())
 		_vm->_gfx->blit(_cycleCheck, absoluteRect.left + 13, absoluteRect.top + 144);
 
 	if (_caret) {
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index edd8a85775..1034cf4ec0 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -54,7 +54,7 @@ FrameWindow::FrameWindow(BuriedEngine *vm) : Window(vm, 0) {
 	_mainChildWindow = 0;
 	_controlDown = false;
 	_cacheFrames = false;
-	_cycleDefault = false;
+	_cycleDefault = true;
 	_transitionSpeed = 2;
 	_gameInProgress = false;
 	_atMainMenu = true;


Commit: 85ce38ceed7b9f0706a59aa0cdb74db64a383fec
    https://github.com/scummvm/scummvm/commit/85ce38ceed7b9f0706a59aa0cdb74db64a383fec
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix drop inventory item icons

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index 6e6371802a..da4103c0f6 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -673,11 +673,12 @@ void InventoryWindow::onMouseMove(const Common::Point &point, uint flags) {
 				if (_vm->isDemo())
 					_draggingItemSpriteData.image = _dragFrames->getFrameCopy(staticItemData.firstDragID);
 				else
-					_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID - 1);
+					_draggingItemSpriteData.image = _vm->_gfx->getBitmap(IDB_DRAG_BITMAP_BASE + staticItemData.firstDragID + newIcon - 1);
 				_draggingItemSpriteData.xPos = 0;
 				_draggingItemSpriteData.yPos = 0;
 				_draggingItemSpriteData.width = _draggingItemSpriteData.image->w;
 				_draggingItemSpriteData.height = _draggingItemSpriteData.image->h;
+				_draggingIconIndex = newIcon;
 
 				if (_vm->isTrueColor()) {
 					_draggingItemSpriteData.redTrans = 255;


Commit: c34d32e4689454ce890ac4e81b93a67a445e6794
    https://github.com/scummvm/scummvm/commit/c34d32e4689454ce890ac4e81b93a67a445e6794
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix arrow status check when clicking

Changed paths:
    engines/buried/navarrow.cpp


diff --git a/engines/buried/navarrow.cpp b/engines/buried/navarrow.cpp
index 760094482c..b7d8e59914 100644
--- a/engines/buried/navarrow.cpp
+++ b/engines/buried/navarrow.cpp
@@ -154,10 +154,13 @@ void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
 			if (rightButton.contains(point)) {
 				Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
 
-				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255))
-					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
-				else
-					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(2);
+				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
+					if (_arrowStatus[4] == BUTTON_ENABLED)
+						((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
+				} else {
+					if (_arrowStatus[2] == BUTTON_ENABLED)
+						((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(2);
+				}
 
 				centerArrow->free();
 				delete centerArrow;
@@ -166,10 +169,13 @@ void NavArrowWindow::onLButtonDown(const Common::Point &point, uint flags) {
 			if (downButton.contains(point)) {
 				Graphics::Surface *centerArrow = _vm->_gfx->getBitmap(_arrowBitmaps[4][_arrowStatus[4]]);
 
-				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255))
-					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
-				else
-					((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(3);
+				if (_vm->_gfx->checkPointAgainstMaskedBitmap(centerArrow, 39, 49, point, 255, 255, 255)) {
+					if (_arrowStatus[4] == BUTTON_ENABLED)
+						((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(4);
+				} else {
+					if (_arrowStatus[3] == BUTTON_ENABLED)
+						((GameUIWindow *)_parent)->_sceneViewWindow->moveInDirection(3);
+				}
 
 				centerArrow->free();
 				delete centerArrow;


Commit: db0d4be62a62a58464f234c9ecfcd291455bbd2f
    https://github.com/scummvm/scummvm/commit/db0d4be62a62a58464f234c9ecfcd291455bbd2f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix sound fading

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/sound.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 88288bb2cc..4b785ba2c6 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -69,8 +69,7 @@ bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow,
 }
 
 bool SceneViewWindow::startAILabAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
-	// TODO: Fix sound fading
-	_vm->_sound->setAmbientSound(_vm->getFilePath(6, environment, SF_AMBIENT), false /* fade */, 64);
+	_vm->_sound->setAmbientSound(_vm->getFilePath(6, environment, SF_AMBIENT), fade, 64);
 	return true;
 }
 
diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index fb6f8ed9b0..39762b904b 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -298,8 +298,7 @@ bool SceneViewWindow::startCastleAmbient(int oldTimeZone, int oldEnvironment, in
 	if (_vm->isDemo())
 		return false;
 
-	// TODO: Fix sound fading
-	_vm->_sound->setAmbientSound(_vm->getFilePath(1, environment, SF_AMBIENT), false /* fade */, 64);
+	_vm->_sound->setAmbientSound(_vm->getFilePath(1, environment, SF_AMBIENT), fade, 64);
 	return true;
 }
 
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 54d04f9daa..e87c11b7bf 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -81,8 +81,7 @@ bool SceneViewWindow::initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow
 }
 
 bool SceneViewWindow::startDaVinciAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
-	// TODO: Fix sound fading
-	_vm->_sound->setAmbientSound(_vm->getFilePath(5, environment, SF_AMBIENT), false /* fade */, 64);
+	_vm->_sound->setAmbientSound(_vm->getFilePath(5, environment, SF_AMBIENT), fade, 64);
 	return true;
 }
 
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index d75a104801..c879f9e286 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -255,7 +255,7 @@ int EnvironDoorExitSound::postExitRoom(Window *viewWindow, const Location &newLo
 }
 
 bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
-	_vm->_sound->setAmbientSound(_vm->getFilePath(4, environment, SF_AMBIENT));
+	_vm->_sound->setAmbientSound(_vm->getFilePath(4, environment, SF_AMBIENT), fade, 64);
 	return true;
 }
 
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 8e2fa5c16f..728abc8bf9 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -96,9 +96,7 @@ bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow,
 }
 
 bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
-	// TODO: Fix sound fading
-	fade = false;
-	bool checkFade = false;
+	bool checkFade = true;
 
 	if (environment == 3) {
 		if (oldEnvironment == 2)
diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index 82214601eb..87bb2221e2 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -129,7 +129,7 @@ bool SoundManager::setAmbientSound(const Common::String &fileName, bool fade, by
 		}
 
 		// Load the new ambient
-		if (_soundData[kAmbientIndexBase + _lastAmbient]->load(fileName)) {
+		if (_soundData[kAmbientIndexBase + newAmbientTrack]->load(fileName)) {
 			// Set the parameters of the new ambient
 			_soundData[kAmbientIndexBase + newAmbientTrack]->_volume = 0;
 			_soundData[kAmbientIndexBase + newAmbientTrack]->_loop = true;


Commit: e825892922086742b06fcea73464281523049cf9
    https://github.com/scummvm/scummvm/commit/e825892922086742b06fcea73464281523049cf9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix the warning light

Changed paths:
    engines/buried/gameui.cpp


diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index 6214ac525d..d96b995d82 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -199,7 +199,7 @@ bool GameUIWindow::flashWarningLight() {
 	if (_warningLightDisplayed) {
 		_warningLightDisplayed = false;
 		invalidateRect(redrawRect, false);
-		_vm->_gfx->updateScreen(false);
+		_vm->_gfx->updateScreen();
 	}
 
 	uint32 startTime = g_system->getMillis();
@@ -213,7 +213,7 @@ bool GameUIWindow::flashWarningLight() {
 
 	_warningLightDisplayed = true;
 	invalidateRect(redrawRect, false);
-	_vm->_gfx->updateScreen(false);
+	_vm->_gfx->updateScreen();
 
 	_vm->_sound->playInterfaceSound("BITDATA/COMMON/MSGBEEP.BTA");
 
@@ -228,7 +228,7 @@ bool GameUIWindow::flashWarningLight() {
 
 	_warningLightDisplayed = false;
 	invalidateRect(redrawRect, false);
-	_vm->_gfx->updateScreen(false);
+	_vm->_gfx->updateScreen();
 
 	startTime = g_system->getMillis();
 	while (!_vm->shouldQuit() && (startTime + 250) > g_system->getMillis()) {
@@ -239,9 +239,9 @@ bool GameUIWindow::flashWarningLight() {
 	if (_vm->shouldQuit())
 		return false;
 
-	_warningLightDisplayed = false;
+	_warningLightDisplayed = true;
 	invalidateRect(redrawRect, false);
-	_vm->_gfx->updateScreen(false);
+	_vm->_gfx->updateScreen();
 
 	_vm->_sound->playInterfaceSound("BITDATA/COMMON/MSGBEEP.BTA");
 	return true;


Commit: 7d5dc1877c9d76b0bd36b38f0af15aa200ee7c83
    https://github.com/scummvm/scummvm/commit/7d5dc1877c9d76b0bd36b38f0af15aa200ee7c83
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the remaining two parts of the initial castle tower

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 39762b904b..c80f91daec 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -39,6 +39,84 @@
 
 namespace Buried {
 
+class TopOfTowerGuardEncounter : public SceneBase {
+public:
+	TopOfTowerGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+
+private:
+	bool _showGuard;
+};
+
+TopOfTowerGuardEncounter::TopOfTowerGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_showGuard = _staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment;
+
+	if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBloodyArrow))
+		_staticData.destForward.destinationScene.depth = 1;		
+}
+
+int TopOfTowerGuardEncounter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_showGuard) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+		_showGuard = false;
+		viewWindow->invalidateWindow(false);
+	}
+
+	return SC_TRUE;
+}
+
+int TopOfTowerGuardEncounter::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	if (!_showGuard)
+		return SceneBase::paint(viewWindow, preBuffer);
+
+	const Graphics::Surface *newFrame = ((SceneViewWindow *)viewWindow)->getStillFrame(_staticData.miscFrameIndex);
+
+	if (newFrame) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		_vm->_gfx->crossBlit(preBuffer, 0, 0, 432, 189, newFrame, 0, 0);
+	}
+
+	return SC_REPAINT;
+}
+
+class TowerStairsGuardEncounter : public SceneBase {
+public:
+	TowerStairsGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	bool _busy;
+};
+
+TowerStairsGuardEncounter::TowerStairsGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_busy = false;
+}
+
+int TowerStairsGuardEncounter::timerCallback(Window *viewWindow) {
+	if (_frameCycleCount < 0 || _busy)
+		return SC_FALSE;
+
+	if (_frameCycleCount < _staticData.cycleStartFrame + _staticData.cycleFrameCount - 1) {
+		_frameCycleCount++;
+		viewWindow->invalidateWindow(false);
+	} else {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 0) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+			_busy = true;
+			((SceneViewWindow *)viewWindow)->showDeathScene(0);
+			return SC_DEATH;
+		} else {
+			_frameCycleCount = _staticData.cycleStartFrame;
+			_busy = false;
+		}
+	}
+
+	return SC_TRUE;
+}
+
 enum {
 	CATAPULT_TIMEOUT_VALUE = 6000
 };
@@ -306,6 +384,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 1:
+		return new TopOfTowerGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 3:
+		return new TowerStairsGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 4:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 114, 0, 324, 189, 1, 2, 5, 3, 1, 1, 2, 11, 395, 9);
 	case 5:


Commit: cafba7cd6b8d9229b44c156ad3d8f35852c86be0
    https://github.com/scummvm/scummvm/commit/cafba7cd6b8d9229b44c156ad3d8f35852c86be0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement some common Mayan scenes

Changed paths:
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 728abc8bf9..a720fe5874 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -31,6 +31,7 @@
 #include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
 
 namespace Buried {
 
@@ -122,6 +123,41 @@ bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int
 SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
+	switch (sceneStaticData.classID) {
+	case 1:
+		return new VideoDeath(_vm, viewWindow, sceneStaticData, priorLocation, 10, IDS_HUMAN_PRESENCE_500METERS);
+	case 2:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 60, 134, 118, 180, kItemCeramicBowl, 96, offsetof(GlobalFlags, myPickedUpCeramicBowl));
+	case 13:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 140, 124, 174, 158, kItemCavernSkull, 3, offsetof(GlobalFlags, myMCPickedUpSkull));
+	case 31:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 194, 106, 278, 126, kItemJadeBlock, 105, offsetof(GlobalFlags, myWGRetrievedJadeBlock));
+	case 32:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 140, 22, 306, 189, 2, 3, 0, 3, 1, 1, TRANSITION_WALK, -1, 264, 14, 14);
+	case 33:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 88, 288, 116, kItemLimestoneBlock, 84, offsetof(GlobalFlags, myWTRetrievedLimestoneBlock));
+	case 34:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 80, 0, 332, 189, 2, 4, 0, 2, 1, 1, TRANSITION_WALK, -1, 401, 14, 14);
+	case 50:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation,106, 0, 294, 189, 2, 5, 0, 1, 1, 1, TRANSITION_WALK, -1, 427, 13, 11);
+	case 51:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 235, 144, 285, 181, kItemEntrySkull, 3, offsetof(GlobalFlags, myAGRetrievedEntrySkull));
+	case 52:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 200, 138, 231, 185, kItemSpearSkull, 46, offsetof(GlobalFlags, myAGRetrievedSpearSkull));
+	case 53:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 201, 4, 235, 22, kItemCopperMedallion, 45, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
+	case 54:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 110, 280, 142, kItemObsidianBlock, 72, offsetof(GlobalFlags, myAGRetrievedObsidianBlock));
+	case 65:
+		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 90, 15, 346, 189, 2, 6, 0, 0, 1, 1, TRANSITION_WALK, -1, 33, 12, 13);
+	case 68:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 76, 246, 116, kItemEnvironCart, 53, offsetof(GlobalFlags, takenEnvironCart));
+	case 70:
+		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, myMCStingerID), offsetof(GlobalFlags, myMCStingerChannelID), 11, 14);
+	case 125:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 226, 90, 256, 104, kItemCopperMedallion, 15, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
+	}
+
 	warning("TODO: Mayan scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index ddff31a85f..4d59024fd0 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -276,4 +276,30 @@ int ClickPlayVideo::specifyCursor(Window *viewWindow, const Common::Point &point
 	return kCursorArrow;
 }
 
+VideoDeath::VideoDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int deathID, int messageTextID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation), _deathID(deathID), _messageTextID(messageTextID) {
+}
+
+int VideoDeath::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_messageTextID >= -1)
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_messageTextID));
+
+	return SC_TRUE;
+}
+
+int VideoDeath::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == _staticData.location.timeZone &&
+			newLocation.environment == _staticData.location.environment &&
+			newLocation.node == _staticData.location.node &&
+			newLocation.facing == _staticData.location.facing &&
+			newLocation.orientation == _staticData.location.orientation &&
+			newLocation.depth == _staticData.location.depth) {
+		// Notify the player of his gruesome death
+		((SceneViewWindow *)viewWindow)->showDeathScene(_deathID);
+		return SC_DEATH;
+	}
+
+	return SC_TRUE;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 78c6a7fdba..cc12c9d20e 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -123,6 +123,17 @@ private:
 	Common::Rect _clickRegion;
 };
 
+class VideoDeath : public SceneBase {
+public:
+	VideoDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int deathID = 0, int messageTextID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+
+private:
+	int _deathID;
+	int _messageTextID;
+};
+
 } // End of namespace Buried
 
 #endif


Commit: 428295621b6e0e4a18c39637d665345efcb37ee4
    https://github.com/scummvm/scummvm/commit/428295621b6e0e4a18c39637d665345efcb37ee4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the painting tower door

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index e87c11b7bf..b6ab885624 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -36,6 +36,155 @@
 
 namespace Buried {
 
+class PaintingTowerRetrieveKey : public SceneBase {
+public:
+	PaintingTowerRetrieveKey(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _key;
+};
+
+PaintingTowerRetrieveKey::PaintingTowerRetrieveKey(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked >= 1) {
+		int curStillFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = _staticData.miscFrameIndex;
+		_staticData.miscFrameIndex = curStillFrame;
+	}
+
+	_key = Common::Rect(268, 50, 298, 88);
+}
+
+int PaintingTowerRetrieveKey::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_key.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked == 0) {
+		// Play the unlocking movie
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+
+		// Swap the still frame
+		int curStillFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = _staticData.miscFrameIndex;
+		_staticData.miscFrameIndex = curStillFrame;
+
+		// Add the key to the inventory
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemBalconyKey);
+
+		// Change the locked door flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked = 1;
+	}
+
+	return SC_TRUE;
+}
+
+int PaintingTowerRetrieveKey::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_key.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked == 0)
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class PaintingTowerOutsideDoor : public SceneBase {
+public:
+	PaintingTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickableArea;
+};
+
+PaintingTowerOutsideDoor::PaintingTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickableArea = Common::Rect(0, 0, 236, 189);
+}
+
+int PaintingTowerOutsideDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableArea.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1) {
+			DestinationScene destData;
+			destData.destinationScene.timeZone = 5;
+			destData.destinationScene.environment = 1;
+			destData.destinationScene.node = 7;
+			destData.destinationScene.facing = 3;
+			destData.destinationScene.orientation = 1;
+			destData.destinationScene.depth = 2;
+			destData.transitionType = TRANSITION_WALK;
+			destData.transitionData = 11;
+			destData.transitionStartFrame = 28;
+			destData.transitionLength = 12;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		} else {
+			DestinationScene destData;
+			destData.destinationScene.timeZone = 5;
+			destData.destinationScene.environment = 1;
+			destData.destinationScene.node = 7;
+			destData.destinationScene.facing = 3;
+			destData.destinationScene.orientation = 1;
+			destData.destinationScene.depth = 1;
+			destData.transitionType = TRANSITION_WALK;
+			destData.transitionData = 11;
+			destData.transitionStartFrame = 0;
+			destData.transitionLength = 12;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int PaintingTowerOutsideDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableArea.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class PaintingTowerInsideDoor : public SceneBase {
+public:
+	PaintingTowerInsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickableArea;
+};
+
+PaintingTowerInsideDoor::PaintingTowerInsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickableArea = Common::Rect(290, 0, 432, 189);
+}
+
+int PaintingTowerInsideDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableArea.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTDoorLocked >= 1) {
+			DestinationScene destData;
+			destData.destinationScene.timeZone = 5;
+			destData.destinationScene.environment = 1;
+			destData.destinationScene.node = 2;
+			destData.destinationScene.facing = 2;
+			destData.destinationScene.orientation = 1;
+			destData.destinationScene.depth = 1;
+			destData.transitionType = TRANSITION_WALK;
+			destData.transitionData = 11;
+			destData.transitionStartFrame = 338;
+			destData.transitionLength = 22;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		} else {
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 127, false, true);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int PaintingTowerInsideDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableArea.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 enum {
 	DS_SC_DRIVE_ASSEMBLY = 1,
 	DS_SC_WHEEL_ASSEMBLY = 2,
@@ -89,6 +238,12 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 4:
+		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 11:
+		return new PaintingTowerOutsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 12:
+		return new PaintingTowerInsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 196, 0, 262, 189, 5, 3, 10, 1, 1, 1, TRANSITION_WALK, 11, 881, 20);
 	case 14:


Commit: dd0e6469db19d2063110483c5cf3cda5901139b6
    https://github.com/scummvm/scummvm/commit/dd0e6469db19d2063110483c5cf3cda5901139b6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix adding evidence to the global flag table

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 5ec82c8cf2..4e8b4b37f4 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1341,7 +1341,7 @@ bool SceneViewWindow::setGlobalFlagDWord(int offset, uint32 value) {
 bool SceneViewWindow::addNumberToGlobalFlagTable(int tableOffset, int curItemCountOffset, int maxItems, byte numberToAdd) {
 	// TODO: Rewrite this
 	byte *data = (byte *)&_globalFlags;
-	int16 *itemCountPtr = (int16 *)(data + curItemCountOffset);
+	byte *itemCountPtr = data + curItemCountOffset;
 	int itemCount = *itemCountPtr;
 
 	if (itemCount >= maxItems)
@@ -1364,7 +1364,7 @@ byte SceneViewWindow::getNumberFromGlobalFlagTable(int tableOffset, int tableInd
 
 bool SceneViewWindow::isNumberInGlobalFlagTable(int tableOffset, int curItemCountOffset, byte numberToCheck) {
 	const byte *data = (const byte *)&_globalFlags;
-	int itemCount = *((const int16 *)(data + curItemCountOffset));
+	int itemCount = *(data + curItemCountOffset);
 
 	const byte *tableEntries = data + tableOffset;
 


Commit: 3bc843f72e59ba5700f29247c5927c5ec7474600
    https://github.com/scummvm/scummvm/commit/3bc843f72e59ba5700f29247c5927c5ec7474600
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the Agent 3 evidence in Da Vinci

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index b6ab885624..fb38377fef 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -192,6 +193,41 @@ enum {
 	DS_SC_COMPLETED = 8
 };
 
+class PaintingTowerCapAgent : public SceneBase {
+public:
+	PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+PaintingTowerCapAgent::PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int PaintingTowerCapAgent::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTBeenOnBalcony = 1;
+
+	if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_AGENT3)) {
+		// Play animation of capturing the evidence
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
+
+		// Attempt to add the evidence to the biochip
+		((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_AGENT3);
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+
+		// Turn off evidence capture
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+
+		// Set flag for scoring
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchAgent3DaVinci = 1;
+	} else {
+		if (false) { // TODO: If control down
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
+		}
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -280,6 +316,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
 	case 66:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 170, 0, 432, 189, 5, 4, 0, 0, 1, 1, TRANSITION_WALK, 11, 1220, 12);
+	case 70:
+		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
 	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);


Commit: 9d0e6550f928e62a1f0af2ed58bd75619b8e41c9
    https://github.com/scummvm/scummvm/commit/9d0e6550f928e62a1f0af2ed58bd75619b8e41c9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the castle storage room door

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index c80f91daec..d06d7a5117 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/frame_window.h"
 #include "buried/gameui.h"
@@ -286,6 +287,89 @@ int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class StorageRoomDoor : public SceneBase {
+public:
+	StorageRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int timeZone = -1, int environment = -1, int node = -1,
+			int facing = -1, int orientation = -1, int depth = -1, int flagOffset = 0, int data = -1, int startFrame = -1,
+			int length = -1, int animDB = -1);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _clicked;
+	Common::Rect _clickable;
+	int _flagOffset;
+	DestinationScene _destData;
+	int _agent3VideoID;
+};
+
+StorageRoomDoor::StorageRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int timeZone, int environment, int node,
+		int facing, int orientation, int depth, int flagOffset, int data, int startFrame,
+		int length, int animDB) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_agent3VideoID = animDB;
+	_clicked = false;
+	_flagOffset = flagOffset;
+	_clickable = Common::Rect(left, top, right, bottom);
+
+	_destData.destinationScene.timeZone = timeZone;
+	_destData.destinationScene.environment = environment;
+	_destData.destinationScene.node = node;
+	_destData.destinationScene.facing = facing;
+	_destData.destinationScene.orientation = orientation;
+	_destData.destinationScene.depth = depth;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) != 0) {
+		_destData.transitionType = 2; // constant?
+		_destData.transitionData = data;
+		_destData.transitionStartFrame = startFrame;
+		_destData.transitionLength = length;
+	} else {
+		_destData.transitionType = TRANSITION_VIDEO;
+		_destData.transitionData = _agent3VideoID;
+		_destData.transitionStartFrame = -1;
+		_destData.transitionLength = -1;
+	}
+}
+
+int StorageRoomDoor::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		_clicked = true;
+
+	return SC_TRUE;
+}
+
+int StorageRoomDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clicked) {
+		if (_clickable.contains(pointLocation)) {
+			((SceneViewWindow *)viewWindow)->moveToDestination(_destData);
+		} else {
+			_clicked = false;
+		}
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, CASTLE_EVIDENCE_AGENT3))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int StorageRoomDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class KingsChamberGuardEncounter : public SceneBase {
 public:
 	KingsChamberGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -452,6 +536,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new CycleEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 5 : 7, _vm->isDemo() ? 6 : 8, offsetof(GlobalFlags, cgBaileyTwoWayGuards), IDS_HUMAN_PRESENCE_10METERS);
 	case 37:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 175, 64, 237, 126, kItemBurnedLetter, 84, offsetof(GlobalFlags, cgBurnedLetterPresent));
+	case 39:
+		return new StorageRoomDoor(_vm, viewWindow, sceneStaticData, priorLocation, 38, 0, 386, 189, 1, 9, 5, 2, 1, 1, offsetof(GlobalFlags, cgStorageRoomVisit), 11, 130, 12, 0);
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	case 48:


Commit: 234e3f67f31e1ea215beb0e4fefd80cf868a6183
    https://github.com/scummvm/scummvm/commit/234e3f67f31e1ea215beb0e4fefd80cf868a6183
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement placing the ceramic bowl

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index a720fe5874..989fb24f9d 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -35,6 +35,66 @@
 
 namespace Buried {
 
+class PlaceCeramicBowl : public SceneBase {
+public:
+	PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int timerCallback(Window *viewWindow);
+
+private:
+	bool _dropped;
+};
+
+PlaceCeramicBowl::PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_dropped = false;
+}
+
+int PlaceCeramicBowl::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+	
+	if (itemID != kItemCeramicBowl)
+		return SIC_REJECT;
+
+	_staticData.navFrameIndex = 112;
+	viewWindow->invalidateWindow(false);
+	_dropped = true;
+	return SIC_ACCEPT;
+}
+
+int PlaceCeramicBowl::timerCallback(Window *viewWindow) {
+	if (_dropped) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelStatus == 0) {
+			// Play slide death animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
+
+			// Notify the player of his gruesome death
+			((SceneViewWindow *)viewWindow)->showDeathScene(11);
+			return SC_DEATH;
+		} else {
+			// Kill the ambient
+			_vm->_sound->setAmbientSound();
+
+			// Jump to the start of the main cavern
+			DestinationScene newDest;
+			newDest.destinationScene.timeZone = 2;
+			newDest.destinationScene.environment = 2;
+			newDest.destinationScene.node = 0;
+			newDest.destinationScene.facing = 1;
+			newDest.destinationScene.orientation = 1;
+			newDest.destinationScene.depth = 0;
+			newDest.transitionType = TRANSITION_VIDEO;
+			newDest.transitionData = 3;
+			newDest.transitionStartFrame = -1;
+			newDest.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
+		}
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -128,6 +188,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new VideoDeath(_vm, viewWindow, sceneStaticData, priorLocation, 10, IDS_HUMAN_PRESENCE_500METERS);
 	case 2:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 60, 134, 118, 180, kItemCeramicBowl, 96, offsetof(GlobalFlags, myPickedUpCeramicBowl));
+	case 3:
+		return new PlaceCeramicBowl(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 140, 124, 174, 158, kItemCavernSkull, 3, offsetof(GlobalFlags, myMCPickedUpSkull));
 	case 31:


Commit: 8668c6287b11b17458d4c91b8ff3fe930492a205
    https://github.com/scummvm/scummvm/commit/8668c6287b11b17458d4c91b8ff3fe930492a205
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix missing Mayan ambient fade

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 989fb24f9d..214a137253 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -176,7 +176,7 @@ bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int
 		return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 12), checkFade, 128);
 	}
 
-	_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), false /* fade */, 64);
+	_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
 	return true;
 }
 


Commit: 4a1f123f48ead5461c6ab7a0ccfe9a6556777622
    https://github.com/scummvm/scummvm/commit/4a1f123f48ead5461c6ab7a0ccfe9a6556777622
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add the sound exiting from scene common scene

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index d06d7a5117..55889424ce 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -517,7 +517,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 	case 27:
 		if (_vm->isDemo())
 			return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHammerPresent), 0, 1, 0, 0, 0);
-		break;
+		else
+			return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 28:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 184, 111, 237, 189, kItemHammer, 3, offsetof(GlobalFlags, cgHammerPresent));
 	case 29:
@@ -542,6 +543,19 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	case 48:
 		return new KingsChamberGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 55:
+		// Valid, but not implemented.
+		break;
+	case 57:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 58:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 70:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12);
+	case 71:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 74:
+		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	default:
 		warning("TODO: Castle scene object %d", sceneStaticData.classID);
 		break;
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index fb38377fef..9221586cb0 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -276,6 +276,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 	switch (sceneStaticData.classID) {
 	case 4:
 		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 10:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 11:
 		return new PaintingTowerOutsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
@@ -284,6 +286,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 196, 0, 262, 189, 5, 3, 10, 1, 1, 1, TRANSITION_WALK, 11, 881, 20);
 	case 14:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 208, 0, 306, 189, 5, 3, 0, 2, 1, 1, TRANSITION_WALK, 11, 740, 23);
+	case 16:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 18:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 216, 0, 324, 189, 5, 3, 2, 0, 1, 1, TRANSITION_WALK, 11, 833, 26);
 	case 19:
@@ -318,6 +322,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 170, 0, 432, 189, 5, 4, 0, 0, 1, 1, TRANSITION_WALK, 11, 1220, 12);
 	case 70:
 		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 72:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 13);
 	}
 
 	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 214a137253..f18a317e82 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -210,12 +210,20 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 201, 4, 235, 22, kItemCopperMedallion, 45, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
 	case 54:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 110, 280, 142, kItemObsidianBlock, 72, offsetof(GlobalFlags, myAGRetrievedObsidianBlock));
+	case 60:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 11);
 	case 65:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 90, 15, 346, 189, 2, 6, 0, 0, 1, 1, TRANSITION_WALK, -1, 33, 12, 13);
 	case 68:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 76, 246, 116, kItemEnvironCart, 53, offsetof(GlobalFlags, takenEnvironCart));
+	case 69:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
 	case 70:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, myMCStingerID), offsetof(GlobalFlags, myMCStingerChannelID), 11, 14);
+	case 120:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
+	case 121:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 125:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 226, 90, 256, 104, kItemCopperMedallion, 15, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
 	}
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 4d59024fd0..41f985f532 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -176,6 +176,32 @@ int GenericItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &p
 	return kCursorArrow;
 }
 
+PlaySoundExitingFromScene::PlaySoundExitingFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int soundFileNameID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundFileNameID = soundFileNameID;
+}
+
+int PlaySoundExitingFromScene::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_soundFileNameID >= 0 && _staticData.location.depth != newLocation.depth && _staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 128, false, true);
+
+	return SC_TRUE;
+}
+
+PlaySoundExitingFromSceneDeux::PlaySoundExitingFromSceneDeux(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int soundFileNameID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundFileNameID = soundFileNameID;
+}
+
+int PlaySoundExitingFromSceneDeux::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_soundFileNameID >= 0 && _staticData.location.node == newLocation.node && _staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 128, false, true);
+
+	return SC_TRUE;
+}
+
 PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID, int lastStingerFileID) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index cc12c9d20e..a295e8910e 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -70,6 +70,26 @@ private:
 	int _itemFlagOffset;
 };
 
+class PlaySoundExitingFromScene : public SceneBase {
+public:
+	PlaySoundExitingFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int soundFileNameID = -1);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+
+private:
+	int _soundFileNameID;
+};
+
+class PlaySoundExitingFromSceneDeux : public SceneBase {
+public:
+	PlaySoundExitingFromSceneDeux(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int soundFileNameID = -1);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+
+private:
+	int _soundFileNameID;
+};
+
 class PlayStingers : public SceneBase {
 public:
 	PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: c2e9401da0b59e4f24cc2888580344a6ad5bd6ad
    https://github.com/scummvm/scummvm/commit/c2e9401da0b59e4f24cc2888580344a6ad5bd6ad
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the ClickPlaySound common scene

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 55889424ce..e3e92a3a42 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -543,6 +543,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	case 48:
 		return new KingsChamberGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 50:
+		return new ClickPlaySoundSynchronous(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTSTriedDoorA), 14, kCursorFinger, 72, 0, 372, 189);
 	case 55:
 		// Valid, but not implemented.
 		break;
@@ -554,8 +556,14 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12);
 	case 71:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 72:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 12, kCursorFinger, 28, 34, 336, 189);
+	case 73:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 0, 0, 270, 189);
 	case 74:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 77:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTSTriedDoorB), 14, kCursorFinger, 72, 0, 372, 189);
 	default:
 		warning("TODO: Castle scene object %d", sceneStaticData.classID);
 		break;
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 9221586cb0..6293177bed 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -286,8 +286,12 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 196, 0, 262, 189, 5, 3, 10, 1, 1, 1, TRANSITION_WALK, 11, 881, 20);
 	case 14:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 208, 0, 306, 189, 5, 3, 0, 2, 1, 1, TRANSITION_WALK, 11, 740, 23);
+	case 15:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 0, 0, 384, 189);
 	case 16:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 17:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsGDClickedOnCodexDoor), 13, kCursorFinger, 222, 0, 318, 189);
 	case 18:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 216, 0, 324, 189, 5, 3, 2, 0, 1, 1, TRANSITION_WALK, 11, 833, 26);
 	case 19:
@@ -324,6 +328,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 72:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 13);
+	case 74:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 140, 0, 432, 189);
+	case 75:
+		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsCYTriedElevator), 13, kCursorFinger, 140, 130, 432, 189);
 	}
 
 	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 41f985f532..f6aaff0b68 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -235,6 +235,39 @@ int PlayStingers::postEnterRoom(Window *viewWindow, const Location &priorLocatio
 	return SC_TRUE;
 }
 
+ClickPlaySound::ClickPlaySound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, int soundID, int cursorID, int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cursorID = cursorID;
+	_soundID = soundID;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_flagOffset = flagOffset;
+}
+
+int ClickPlaySound::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundID), 127, false, true);
+
+		if (_flagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickPlaySound::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 OneShotEntryVideoWarning::OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int animID, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
 	_animID = animID;
@@ -328,4 +361,37 @@ int VideoDeath::postExitRoom(Window *viewWindow, const Location &newLocation) {
 	return SC_TRUE;
 }
 
+ClickPlaySoundSynchronous::ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, int soundID, int cursorID, int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cursorID = cursorID;
+	_soundID = soundID;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_flagOffset = flagOffset;
+}
+
+int ClickPlaySoundSynchronous::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundID), 127);
+
+		if (_flagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickPlaySoundSynchronous::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index a295e8910e..695f2612bb 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -104,6 +104,20 @@ private:
 	int _lastStingerFileID;
 };
 
+class ClickPlaySound : public SceneBase {
+public:
+	ClickPlaySound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, int soundID = 0, int cursorID = 0, int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	int _soundID;
+	Common::Rect _clickRegion;
+	int _flagOffset;
+};
+
 class OneShotEntryVideoWarning : public SceneBase {
 public:
 	OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -154,6 +168,20 @@ private:
 	int _messageTextID;
 };
 
+class ClickPlaySoundSynchronous : public SceneBase {
+public:
+	ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, int soundID = 0, int cursorID = 0, int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	int _soundID;
+	Common::Rect _clickRegion;
+	int _flagOffset;
+};
+
 } // End of namespace Buried
 
 #endif


Commit: 5df033e4b9e2f98764e2232edfcd2fc85dd73b6a
    https://github.com/scummvm/scummvm/commit/5df033e4b9e2f98764e2232edfcd2fc85dd73b6a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Add the castle wall slide death

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index e3e92a3a42..bbaf6536ad 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -118,6 +118,31 @@ int TowerStairsGuardEncounter::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class WallSlideDeath : public SceneBase {
+public:
+	WallSlideDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);	
+};
+
+WallSlideDeath::WallSlideDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int WallSlideDeath::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == _staticData.location.timeZone &&
+			newLocation.environment == _staticData.location.environment &&
+			newLocation.node == _staticData.location.node &&
+			newLocation.facing == _staticData.location.facing &&
+			newLocation.orientation == _staticData.location.orientation &&
+			newLocation.depth == _staticData.location.depth) {
+		// Notify the player of his gruesome death
+		((SceneViewWindow *)viewWindow)->showDeathScene(1);
+		return SC_DEATH;
+	}
+
+	return SC_TRUE;
+}
+
 enum {
 	CATAPULT_TIMEOUT_VALUE = 6000
 };
@@ -476,6 +501,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 114, 0, 324, 189, 1, 2, 5, 3, 1, 1, 2, 11, 395, 9);
 	case 5:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 103, 0, 355, 189, 1, 3, 5, 1, 1, 1, 2, 11, 641, 8);
+	case 6:
+		return new WallSlideDeath(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 7:
 		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgWallExploded), 0, 0, 1, 0, 0);
 	case 8:


Commit: dab0e114330ae46ad2e95d0e5661088fc80cf85b
    https://github.com/scummvm/scummvm/commit/dab0e114330ae46ad2e95d0e5661088fc80cf85b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the background catapult sounds

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index bbaf6536ad..1df3d5833e 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -312,6 +312,41 @@ int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class MainWallCatapultService : public SceneBase {
+public:
+	MainWallCatapultService(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+};
+
+MainWallCatapultService::MainWallCatapultService(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int MainWallCatapultService::timerCallback(Window *viewWindow) {
+	SceneBase::timerCallback(viewWindow);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData > 0) {
+		uint32 timer = ((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData;
+
+		if (timer + CATAPULT_TIMEOUT_VALUE < g_system->getMillis()) {
+			// Play the catapult sound
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 127, false, true);
+
+			// Reset the timer flags
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData = 0;
+
+			// Determine an interval to wait until the next launch
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultOffset = g_system->getMillis();
+		}
+	} else if ((((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultOffset + 20000) < g_system->getMillis()) {
+		// No boulder going, but it's time for another launch
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgMWCatapultData = g_system->getMillis();
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 127, false, true);
+	}
+
+	return SC_TRUE;
+}
+
 class StorageRoomDoor : public SceneBase {
 public:
 	StorageRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -579,6 +614,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 58:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 60:
+		return new MainWallCatapultService(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 70:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12);
 	case 71:


Commit: af847ff0d011a2311898b89095194585c5e9a0d9
    https://github.com/scummvm/scummvm/commit/af847ff0d011a2311898b89095194585c5e9a0d9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix async video behavior

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 4e8b4b37f4..770939a7db 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2306,7 +2306,8 @@ void SceneViewWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 
 void SceneViewWindow::onPaint() {
 	// TODO: I think this should draw when the burned letter is displayed, since I modified that code
-	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed && !_burnedLetterDisplayed && !_asyncMovie) {
+	// Original didn't draw if the async movie was playing, but that doesn't seem right.
+	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed && !_burnedLetterDisplayed) {
 		if (_currentScene->_staticData.navFrameIndex >= -1) {
 			if (_useScenePaint)
 				_currentScene->paint(this, _preBuffer);


Commit: 9c3c87564d8fc38031b1ca4d1cb04a1cdfd0f548
    https://github.com/scummvm/scummvm/commit/9c3c87564d8fc38031b1ca4d1cb04a1cdfd0f548
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Allow for right-aligned text

Changed paths:
    engines/buried/complete.cpp
    engines/buried/death.cpp
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index 566e9e304d..6c66a39027 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -213,11 +213,11 @@ void CompletionWindow::onPaint() {
 
 		// Scores
 		textColor = _vm->_gfx->getColor(255, 255, 51);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, _fontHeightA, true);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, _fontHeightA, kTextAlignRight);
 
 		// Total score
 		Common::Rect finalScoreRect(122, 386, 283, 401);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), textColor, _fontHeightB, true);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), textColor, _fontHeightB, kTextAlignRight);
 	}
 }
 
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index 45f9c8b790..25f75aa643 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -286,11 +286,11 @@ void DeathWindow::onPaint() {
 	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA);
 
 	textColor = _vm->_gfx->getColor(212, 109, 0);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA, true);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA, kTextAlignRight);
 
 	// CHECKME: This does center vertical alignment, so check the y coordinates
 	Common::Rect finalTextScoreRect(122, 386, 283, 401);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), textColor, _fontHeightB, true);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), textColor, _fontHeightB, kTextAlignRight);
 }
 
 bool DeathWindow::onEraseBackground() {
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 3ad7d1c4b0..4cf9174914 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -766,15 +766,28 @@ Common::SeekableReadStream *GraphicsManager::getThemeFontStream(const Common::St
 	return stream;
 }
 
-void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, bool rightAligned) {
+void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, TextAlign textAlign) {
 	if (text.empty())
 		return;
 
 	Common::StringArray lines;
 	font->wordWrapText(text, w, lines);
 
+	Graphics::TextAlign align;
+	switch (textAlign) {
+	case kTextAlignLeft:
+		align = Graphics::kTextAlignLeft;
+		break;
+	case kTextAlignCenter:
+		align = Graphics::kTextAlignCenter;
+		break;
+	case kTextAlignRight:
+		align = Graphics::kTextAlignRight;
+		break;
+	}
+
 	for (uint32 i = 0; i < lines.size(); i++) {
-		font->drawString(dst, lines[i], x, y, w, color, rightAligned ? Graphics::kTextAlignRight : Graphics::kTextAlignLeft);
+		font->drawString(dst, lines[i], x, y, w, color, align);
 		y += lineHeight;
 	}
 }
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index a219db2aac..4d13ef4cdf 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -68,6 +68,12 @@ enum Cursor {
 	kCursorArrowRight      =   115
 };
 
+enum TextAlign {
+	kTextAlignLeft,
+	kTextAlignCenter,
+	kTextAlignRight
+};
+
 class GraphicsManager {
 public:
 	GraphicsManager(BuriedEngine *vm);
@@ -94,7 +100,7 @@ public:
 	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
 	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
 	void crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc);
-	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, bool rightAligned = false);
+	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, TextAlign textAlign = kTextAlignLeft);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 


Commit: 853f9a8e96cafb62e35adc456fd70cee9972ed64
    https://github.com/scummvm/scummvm/commit/853f9a8e96cafb62e35adc456fd70cee9972ed64
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the kitchen unit

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index c879f9e286..2d32363fbd 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -33,8 +33,739 @@
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
+#include "graphics/font.h"
+
 namespace Buried {
 
+class KitchenUnitTurnOn : public SceneBase {
+public:
+	KitchenUnitTurnOn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _powerButton;
+};
+
+KitchenUnitTurnOn::KitchenUnitTurnOn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_powerButton = Common::Rect(49, 125, 121, 147);
+}
+
+int KitchenUnitTurnOn::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 1;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitTurnOn::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class KitchenUnitTitleScreen : public SceneBase {
+public:
+	KitchenUnitTitleScreen(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _menuButton;
+	Common::Rect _powerButton;
+};
+
+KitchenUnitTitleScreen::KitchenUnitTitleScreen(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_menuButton = Common::Rect(49, 96, 121, 118);
+	_powerButton = Common::Rect(49, 125, 121, 147);
+}
+
+int KitchenUnitTitleScreen::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_menuButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 2;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_powerButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 0;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitTitleScreen::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation) || _menuButton.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class KitchenUnitMainMenu : public SceneBase {
+public:
+	KitchenUnitMainMenu(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _menuButton;
+	Common::Rect _powerButton;
+	Common::Rect _autoChef;
+	Common::Rect _shopNet;
+	Common::Rect _postBox;
+};
+
+KitchenUnitMainMenu::KitchenUnitMainMenu(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_menuButton = Common::Rect(49, 96, 121, 118);
+	_powerButton = Common::Rect(49, 125, 121, 147);
+	_autoChef = Common::Rect(159, 65, 251, 82);
+	_shopNet = Common::Rect(159, 94, 239, 111);
+	_postBox = Common::Rect(159, 123, 243, 140);
+}
+
+int KitchenUnitMainMenu::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 0;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_autoChef.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 5;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_shopNet.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 4;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_postBox.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 3;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitMainMenu::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation) || _menuButton.contains(pointLocation)
+			|| _autoChef.contains(pointLocation) || _shopNet.contains(pointLocation) || _postBox.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class KitchenUnitAutoChef : public SceneBase {
+public:
+	KitchenUnitAutoChef(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~KitchenUnitAutoChef();
+	void preDestructor();
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int gdiPaint(Window *viewWindow);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _menuButton;
+	Common::Rect _powerButton;
+	Common::Rect _autoChefButtons;
+	int _status;
+	Graphics::Font *_textFont;
+	int _lineHeight;
+};
+
+KitchenUnitAutoChef::KitchenUnitAutoChef(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_menuButton = Common::Rect(49, 96, 121, 118);
+	_powerButton = Common::Rect(49, 125, 121, 147);
+	_autoChefButtons = Common::Rect(135, 54, 273, 137);
+	_status = 0;
+	_lineHeight = (_vm->getLanguage() == Common::JA_JPN) ? 11 : 14;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+KitchenUnitAutoChef::~KitchenUnitAutoChef() {
+	preDestructor();
+}
+
+void KitchenUnitAutoChef::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int KitchenUnitAutoChef::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_menuButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 2;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_powerButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 0;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_autoChefButtons.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		_status = 1;
+		_staticData.navFrameIndex = 58;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitAutoChef::gdiPaint(Window *viewWindow) {
+	if (_status == 1) {
+		// TODO: Vertically center align
+		uint32 textColor = _vm->_gfx->getColor(144, 200, 248);
+		Common::String text = _vm->getString(IDFAKI_AC_ORDER_FOOD_TEXT);
+		Common::Rect rect = Common::Rect(80, 26, 294, 92);
+		rect.translate(64, 128);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), textColor, _lineHeight);
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitAutoChef::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation) || _menuButton.contains(pointLocation) || _autoChefButtons.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class KitchenUnitShopNet : public SceneBase {
+public:
+	KitchenUnitShopNet(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~KitchenUnitShopNet();
+	void preDestructor();
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int onCharacter(Window *viewWindow, const Common::KeyState &character);
+	int gdiPaint(Window *viewWindow);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int preExitRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _status;
+	Common::String _shopNetCode;
+	Common::Rect _menuButton;
+	Common::Rect _powerButton;
+	Common::Rect _transmitButton;
+	Common::Rect _acceptButton;
+	Graphics::Font *_textFont;
+	Common::Rect _numberButtons[10];
+	int _lineHeight;
+};
+
+KitchenUnitShopNet::KitchenUnitShopNet(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_status = 0;
+	_menuButton = Common::Rect(49, 96, 121, 118);
+	_powerButton = Common::Rect(49, 125, 121, 147);
+	_transmitButton = Common::Rect(176, 121, 259, 138);
+	_acceptButton = Common::Rect(140, 128, 293, 145);
+	_numberButtons[0] = Common::Rect(324, 105, 342, 122);
+	_numberButtons[1] = Common::Rect(0, 0, 0, 0); // Number 1 is obscured
+	_numberButtons[2] = Common::Rect(323, 4, 341, 21);
+	_numberButtons[3] = Common::Rect(303, 13, 321, 30);
+	_numberButtons[4] = Common::Rect(324, 29, 342, 46);
+	_numberButtons[5] = Common::Rect(303, 39, 321, 56);
+	_numberButtons[6] = Common::Rect(324, 54, 342, 71);
+	_numberButtons[7] = Common::Rect(303, 64, 321, 81);
+	_numberButtons[8] = Common::Rect(324, 79, 342, 96);
+	_numberButtons[9] = Common::Rect(303, 91, 321, 108);
+	_lineHeight = (_vm->getLanguage() == Common::JA_JPN) ? 10 : 14;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+KitchenUnitShopNet::~KitchenUnitShopNet() {
+	preDestructor();
+}
+
+void KitchenUnitShopNet::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int KitchenUnitShopNet::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_menuButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 2;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_powerButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 0;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_transmitButton.contains(pointLocation) && _status == 1) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		if (_shopNetCode == _vm->getString(IDFAKI_SN_CHEESE_GIRL_CODE_TEXT)) {
+			_status = 3;
+			_staticData.navFrameIndex = 54;
+		} else if (_shopNetCode == _vm->getString(IDFAKI_SN_TRANSLATE_CHIP_CODE_TEXT)) {
+			_status = 2;
+			_staticData.navFrameIndex = 54;
+		} else if (_shopNetCode == _vm->getString(IDFAKI_SN_GENO_SINGLE_CODE_TEXT)) {
+			_status = 4;
+			_staticData.navFrameIndex = 54;
+		}
+
+		viewWindow->invalidateWindow();
+
+		switch (_status) {
+		case 2:
+			((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimation(206, 30, 84, 84, 6, true);
+			break;
+		case 3:
+			((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimation(206, 30, 84, 84, 7, true);
+			break;
+		case 4:
+			((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimation(206, 30, 84, 84, 8, true);
+			break;
+		}
+
+		return SC_TRUE;
+	} else if (_acceptButton.contains(pointLocation) && (_status >= 2 && _status <= 4)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+
+		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
+
+		if (flags.faKIPostBoxSlotA == _status || flags.faKIPostBoxSlotB == _status || flags.faKIPostBoxSlotC == _status) {
+			// Already in the post box
+			_status = 6;
+			_staticData.navFrameIndex = 55;
+		} else {
+			// Add this item to the end of the post box list
+			if (flags.faKIPostBoxSlotA == 0)
+				flags.faKIPostBoxSlotA = _status;
+			else if (flags.faKIPostBoxSlotB == 0)
+				flags.faKIPostBoxSlotB = _status;
+			else if (flags.faKIPostBoxSlotC == 0)
+				flags.faKIPostBoxSlotC = _status;
+
+			_status = 5;
+			_staticData.navFrameIndex = 55;
+		}
+
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	for (int i = 0; i < 10; i++) {
+		if (_numberButtons[i].contains(pointLocation)) {
+			// Generate a key state
+			Common::KeyState state;
+			state.keycode = (Common::KeyCode)(Common::KEYCODE_0 + i);
+			state.ascii = '0' + i;
+			state.flags = 0;
+			onCharacter(viewWindow, state);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitShopNet::onCharacter(Window *viewWindow, const Common::KeyState &character) {
+	if (_status == 0 && ((character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9)
+			|| character.keycode == Common::KEYCODE_BACKSPACE || character.keycode == Common::KEYCODE_DELETE)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9));
+
+		if (character.keycode == Common::KEYCODE_BACKSPACE || character.keycode == Common::KEYCODE_DELETE) {
+			if (_shopNetCode.empty()) {
+				// clone2727 asks why the sound effect is being played again
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9));
+
+				if (_shopNetCode.size() == 6 || _shopNetCode.size() == 11) {
+					_shopNetCode.deleteLastChar();
+					_shopNetCode.deleteLastChar();
+					_shopNetCode.deleteLastChar();
+					_shopNetCode.deleteLastChar();
+				} else {
+					_shopNetCode.deleteLastChar();
+				}
+
+				viewWindow->invalidateWindow(false);
+
+				// NOTE: Original returned here instead, but that resulted in a bad character
+				// being printed if the string was empty.
+			}
+
+			return SC_TRUE;
+		}
+
+		// Add the character to the code string
+		static const char *dashString = " - ";
+
+		switch (_shopNetCode.size()) {
+		case 0:
+		case 1:
+		case 6:
+		case 11:
+		case 12:
+			_shopNetCode += (char)(character.keycode - Common::KEYCODE_0 + '0');
+			break;
+		case 2:
+		case 7:
+			_shopNetCode += (char)(character.keycode - Common::KEYCODE_0 + '0');
+			_shopNetCode += dashString;
+			break;
+		case 13:
+			_shopNetCode += (char)(character.keycode - Common::KEYCODE_0 + '0');
+
+			if (_shopNetCode == _vm->getString(IDFAKI_SN_CHEESE_GIRL_CODE_TEXT)
+					|| _shopNetCode == _vm->getString(IDFAKI_SN_TRANSLATE_CHIP_CODE_TEXT)
+					|| _shopNetCode == _vm->getString(IDFAKI_SN_GENO_SINGLE_CODE_TEXT)) {
+				_status = 1;
+				_staticData.navFrameIndex = 53;
+			} else {
+				_shopNetCode.clear();
+			}
+			break;
+		}
+
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitShopNet::gdiPaint(Window *viewWindow) {
+	uint32 textColor = _vm->_gfx->getColor(104, 40, 168);
+	Common::String text;
+	Common::Rect rect;
+	bool vtCenter = false;
+
+	switch (_status) {
+	case 0: // Entering code
+	case 1: // Valid code
+		text = _shopNetCode;
+		rect = Common::Rect(117, 71, 244, 88);
+		vtCenter = true;
+		break;
+	case 2: // Translate BioChip
+		text = _vm->getString(IDFAKI_SN_TRANSLATE_CHIP_ORDER_TEXT);
+		rect = Common::Rect(87, 33, 179, 87);
+		break;
+	case 3: // Cheese Girl
+		text = _vm->getString(IDFAKI_SN_CHEESE_GIRL_ORDER_TEXT);
+		rect = Common::Rect(87, 33, 179, 87);
+		break;
+	case 4: // Geno Environ Cartridge
+		text = _vm->getString(IDFAKI_SN_GENO_SINGLE_ORDER_TEXT);
+		rect = Common::Rect(87, 33, 179, 87);
+		break;
+	case 5: // Ordered the item successfully
+		text = _vm->getString(IDFAKI_SN_SUCCESSFUL_ORDER_TEXT);
+		rect = Common::Rect(80, 26, 294, 92);
+		break;
+	case 6: // Ordered the item unsuccessfully
+		text = _vm->getString(IDFAKI_SN_UNSUCCESSFUL_ORDER_TEXT);
+		rect = Common::Rect(80, 26, 294, 92);
+		break;
+	}
+
+	if (!text.empty()) {
+		// TODO: Vertically center align
+		rect.translate(64, 128);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), textColor, _lineHeight);
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitShopNet::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation) || _menuButton.contains(pointLocation))
+		return kCursorFinger;
+
+	if (_transmitButton.contains(pointLocation) && _status == 1)
+		return kCursorFinger;
+
+	if (_acceptButton.contains(pointLocation) && (_status >= 2 && _status <= 4))
+		return kCursorFinger;
+
+	for (int i = 0; i < 10; i++)
+		if (_numberButtons[i].contains(pointLocation))
+			return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+int KitchenUnitShopNet::preExitRoom(Window *viewWindow, const Location &priorLocation) {
+	((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+	return SC_TRUE;
+}
+
+class KitchenUnitPostBox : public SceneBase {
+public:
+	KitchenUnitPostBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~KitchenUnitPostBox();
+	void preDestructor();
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int gdiPaint(Window *viewWindow);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _packageCount;
+	int _selectedPackage;
+	Common::Rect _menuButton;
+	Common::Rect _powerButton;
+	Common::Rect _items[3];
+	Common::Rect _replicateButton;
+	Graphics::Font *_textFont;
+	int _lineHeight;
+
+	void changeBackgroundBitmap();
+};
+
+KitchenUnitPostBox::KitchenUnitPostBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_packageCount = 0;
+	_selectedPackage = -1;
+	_menuButton = Common::Rect(49, 96, 121, 118);
+	_powerButton = Common::Rect(49, 125, 121, 147);
+	_items[0] = Common::Rect(137, 62, 285, 79);
+	_items[1] = Common::Rect(137, 91, 285, 108);
+	_items[2] = Common::Rect(137, 120, 285, 137);
+	_replicateButton = Common::Rect(200, 150, 283, 167);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotA != 0)
+		_packageCount++;
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotB != 0)
+		_packageCount++;
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotC != 0)
+		_packageCount++;
+
+	changeBackgroundBitmap();
+
+	_lineHeight = (_vm->getLanguage() == Common::JA_JPN) ? 10 : 14;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+KitchenUnitPostBox::~KitchenUnitPostBox() {
+	preDestructor();
+}
+
+void KitchenUnitPostBox::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int KitchenUnitPostBox::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_menuButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 2;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_powerButton.contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		Location newLocation = _staticData.location;
+		newLocation.depth = 0;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	} else if (_replicateButton.contains(pointLocation) && _selectedPackage >= 0) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faKITakenPostboxItem = 0;
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+
+		int item;
+		switch (_selectedPackage) {
+		case 0:
+			item = ((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotA;
+			break;
+		case 1:
+			item = ((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotB;
+			break;
+		case 2:
+			item = ((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotC;
+			break;
+		}
+
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, faKIPostBoxSlotA) + _selectedPackage)) {
+		case 2:
+			newScene.destinationScene.depth = 6;
+			newScene.transitionData = 9;
+			break;
+		case 3:
+			newScene.destinationScene.depth = 7;
+			newScene.transitionData = 10;
+			break;
+		case 4:
+			newScene.destinationScene.depth = 8;
+			newScene.transitionData = 11;
+			break;
+		}
+
+		// Remove the item from the post box
+		for (int i = _selectedPackage; i < _packageCount - 1; i++) {
+			byte nextPackage = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, faKIPostBoxSlotA) + i + 1);
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, faKIPostBoxSlotA) + i, nextPackage);
+		}
+
+		// Reset the last entry to 0
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, faKIPostBoxSlotA) + _packageCount - 1, 0);
+
+		// Move to the destination scene
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+
+		return SC_TRUE;
+	}
+
+	for (int i = 0; i < _packageCount; i++) {
+		if (_items[i].contains(pointLocation)) {
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+			_selectedPackage = i;
+			changeBackgroundBitmap();
+			viewWindow->invalidateWindow(false);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitPostBox::gdiPaint(Window *viewWindow) {
+	uint32 textColor = _vm->_gfx->getColor(144, 200, 248);
+
+	for (int i = 0; i < _packageCount; i++) {
+		Common::String text;
+
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, faKIPostBoxSlotA) + i)) {
+		case 2:
+			text = _vm->getString(IDFAKI_SN_TRANSLATE_CHIP_CODE_TITLE);
+			break;
+		case 3:
+			text = _vm->getString(IDFAKI_SN_CHEESE_GIRL_CODE_TITLE);
+			break;
+		case 4:
+			text = _vm->getString(IDFAKI_SN_GENO_SINGLE_CODE_TITLE);
+			break;
+		}
+
+		Common::Rect rect(_items[i]);
+		rect.translate(64, 128);
+		rect.translate(0, (rect.height() - _lineHeight) / 2); // HACK: Vertically center (should be implemented better)
+
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), textColor, _lineHeight, kTextAlignCenter);
+	}
+
+	return SC_FALSE;
+}
+
+int KitchenUnitPostBox::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_powerButton.contains(pointLocation) || _menuButton.contains(pointLocation))
+		return kCursorFinger;
+
+	if (_items[0].contains(pointLocation) && _packageCount >= 0)
+		return kCursorFinger;
+
+	if (_items[1].contains(pointLocation) && _packageCount >= 1)
+		return kCursorFinger;
+
+	if (_items[2].contains(pointLocation) && _packageCount >= 2)
+		return kCursorFinger;
+
+	if (_replicateButton.contains(pointLocation) && _selectedPackage >= 0)
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+void KitchenUnitPostBox::changeBackgroundBitmap() {
+	switch (_packageCount) {
+	case 0:
+		_staticData.navFrameIndex = 41;
+		break;
+	case 1:
+		switch (_selectedPackage) {
+		case -1:
+			_staticData.navFrameIndex = 42;
+			break;
+		case 0:
+			_staticData.navFrameIndex = 45;
+			break;
+		}
+		break;
+	case 2:
+		switch (_selectedPackage) {
+		case -1:
+			_staticData.navFrameIndex = 43;
+			break;
+		case 0:
+			_staticData.navFrameIndex = 46;
+			break;
+		case 1:
+			_staticData.navFrameIndex = 48;
+			break;
+		}
+		break;
+	case 3:
+		switch (_selectedPackage) {
+		case -1:
+			_staticData.navFrameIndex = 44;
+			break;
+		case 0:
+			_staticData.navFrameIndex = 47;
+			break;
+		case 1:
+			_staticData.navFrameIndex = 49;
+			break;
+		case 2:
+			_staticData.navFrameIndex = 50;
+			break;
+		}
+		break;
+	}
+}
+
 class ClickZoomToyShelf : public SceneBase {
 public:
 	ClickZoomToyShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -263,6 +994,18 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 5:
+		return new KitchenUnitTurnOn(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 6:
+		return new KitchenUnitTitleScreen(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 7:
+		return new KitchenUnitMainMenu(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 8:
+		return new KitchenUnitPostBox(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 9:
+		return new KitchenUnitShopNet(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 10:
+		return new KitchenUnitAutoChef(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 11:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 200, 83, 230, 116, kItemBioChipTranslate, 61, offsetof(GlobalFlags, faKITakenPostboxItem));
 	case 12:


Commit: 50e0db86f3d28f1bfeeac24c173721b772f09ab4
    https://github.com/scummvm/scummvm/commit/50e0db86f3d28f1bfeeac24c173721b772f09ab4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Begin implementing the AI lab

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 4b785ba2c6..6c1d386f9a 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -31,9 +31,223 @@
 #include "buried/scene_view.h"
 #include "buried/sound.h"
 #include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
+
+#include "common/system.h"
 
 namespace Buried {
 
+enum {
+	GC_AIHW_STARTING_VALUE = 100,
+	GC_AI_OT_WALK_DECREMENT = 2,
+	GC_AI_OT_TURN_DECREMENT = 1,
+	GC_AI_OT_WAIT_DECREMENT = 1,
+	GC_AI_OT_WAIT_TIME_PERIOD = 10000
+};
+
+class BaseOxygenTimer : public SceneBase {
+public:
+	BaseOxygenTimer(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	virtual int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	virtual int preExitRoom(Window *viewWindow, const Location &priorLocation);
+	virtual int timerCallback(Window *viewWindow);
+
+protected:
+	uint32 _entryStartTime;
+	int _deathID;
+	bool _jumped;
+};
+
+BaseOxygenTimer::BaseOxygenTimer(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_deathID = 41;
+	_jumped = false;
+}
+
+int BaseOxygenTimer::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_entryStartTime = g_system->getMillis();
+	return SC_TRUE;
+}
+
+int BaseOxygenTimer::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	// NOTE: v1.01 used 25% as the low threshold instead of ~14.2%
+
+	if (newLocation.timeZone == -2) {
+		_jumped = true;
+		return SC_TRUE;
+	}
+
+	int currentValue = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0) {
+		if (_staticData.location.node != newLocation.node) {
+			if (currentValue <= GC_AI_OT_WALK_DECREMENT) {
+				if (newLocation.timeZone != -2)
+					((SceneViewWindow *)viewWindow)->showDeathScene(_deathID);
+				return SC_DEATH;
+			} else {
+				currentValue -= GC_AI_OT_WALK_DECREMENT;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = currentValue;
+
+				if (currentValue < GC_AIHW_STARTING_VALUE / 7 || (currentValue % (GC_AIHW_STARTING_VALUE / 10)) == 0) {
+					if (currentValue < GC_AIHW_STARTING_VALUE / 7) {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					} else {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					}
+				}
+			}
+		} else {
+			if (currentValue <= GC_AI_OT_TURN_DECREMENT) {
+				if (newLocation.timeZone != -2)
+					((SceneViewWindow *)viewWindow)->showDeathScene(_deathID);
+				return SC_DEATH;
+			} else {
+				currentValue -= GC_AI_OT_TURN_DECREMENT;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = currentValue;
+
+				if (currentValue < GC_AIHW_STARTING_VALUE / 7 || (currentValue % (GC_AIHW_STARTING_VALUE / 10)) == 0) {
+					if (currentValue < GC_AIHW_STARTING_VALUE / 7) {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					} else {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					}
+				}
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int BaseOxygenTimer::timerCallback(Window *viewWindow) {
+	// NOTE: Earlier versions (1.01) used 25% as the low threshold instead of
+	// ~14.2%
+
+	if (_jumped)
+		return SC_TRUE;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0) {
+		if ((g_system->getMillis() - _entryStartTime) >= GC_AI_OT_WAIT_TIME_PERIOD) {
+			int currentValue = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer;
+
+			if (currentValue <= GC_AI_OT_WAIT_DECREMENT) {
+				((SceneViewWindow *)viewWindow)->showDeathScene(_deathID);
+				return SC_DEATH;
+			} else {
+				currentValue -= GC_AI_OT_WAIT_DECREMENT;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = currentValue;
+
+				if (currentValue < GC_AIHW_STARTING_VALUE / 7 || (currentValue % (GC_AIHW_STARTING_VALUE / 10)) == 0) {
+					if (currentValue < GC_AIHW_STARTING_VALUE / 7) {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					} else {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					}
+				}
+			}
+
+			_entryStartTime = g_system->getMillis();
+		}
+	}
+
+	return SC_TRUE;
+}
+
+class UseCheeseGirlPropellant : public BaseOxygenTimer {
+public:
+	UseCheeseGirlPropellant(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _badPos;
+};
+
+UseCheeseGirlPropellant::UseCheeseGirlPropellant(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_deathID = 40;
+	_badPos = Common::Rect(144, 0, 288, 189);
+}
+
+int UseCheeseGirlPropellant::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Display text message about zero-g and no propulsion and oxygen level
+	((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_IS_JUMP_IN_TEXT));
+	return SC_TRUE;
+}
+
+int UseCheeseGirlPropellant::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemCheeseGirl && !_badPos.contains(pointLocation))
+		return 1;
+
+	return 0;
+}
+
+int UseCheeseGirlPropellant::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemCheeseGirl) {
+		if (_badPos.contains(pointLocation)) {
+			DestinationScene destData;
+			destData.destinationScene.timeZone = 6;
+			destData.destinationScene.environment = 10;
+			destData.destinationScene.node = 1;
+			destData.destinationScene.facing = 0;
+			destData.destinationScene.orientation = 0;
+			destData.destinationScene.depth = 0;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 1;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		} else {
+			DestinationScene destData;
+			destData.destinationScene.timeZone = 6;
+			destData.destinationScene.environment = 1;
+			destData.destinationScene.node = 1;
+			destData.destinationScene.facing = 1;
+			destData.destinationScene.orientation = 2;
+			destData.destinationScene.depth = 0;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 0;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		}
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+class BaseOxygenTimerInSpace : public BaseOxygenTimer {
+public:
+	BaseOxygenTimerInSpace(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+};
+
+BaseOxygenTimerInSpace::BaseOxygenTimerInSpace(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_deathID = 40;
+}
+
 bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -76,6 +290,29 @@ bool SceneViewWindow::startAILabAmbient(int oldTimeZone, int oldEnvironment, int
 SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
+	switch (sceneStaticData.classID) {
+	case 1:
+		return new UseCheeseGirlPropellant(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 6:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 11:
+		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 12:
+		return new BaseOxygenTimerInSpace(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 26:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 32:
+		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 54:
+		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 60:
+		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 68:
+		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 93:
+		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	}
+
 	warning("TODO: AI lab scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }


Commit: 6c81ce558944340c7f46636298417cd9ca0215a6
    https://github.com/scummvm/scummvm/commit/6c81ce558944340c7f46636298417cd9ca0215a6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Make the synchronous sound functions use yield()

Changed paths:
    engines/buried/sound.cpp


diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index 87bb2221e2..fbcd563c4f 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -338,13 +338,7 @@ bool SoundManager::playSynchronousAIComment(const Common::String &fileName) {
 
 	while (retVal && !_vm->shouldQuit() && _soundData[kAIVoiceIndex]->isPlaying()) {
 		timerCallback();
-
-		Common::Event event;
-		while (g_system->getEventManager()->pollEvent(event))
-			if (event.type == Common::EVENT_MOUSEMOVE)
-				g_system->updateScreen();
-
-		g_system->delayMillis(10);
+		_vm->yield();
 	}
 
 	// Now that is has been played, kill it here and now
@@ -431,13 +425,7 @@ bool SoundManager::playSynchronousSoundEffect(const Common::String &fileName, in
 	// the sound finishes playing
 	do {
 		timerCallback();
-
-		Common::Event event;
-		while (g_system->getEventManager()->pollEvent(event))
-			if (event.type == Common::EVENT_MOUSEMOVE)
-				g_system->updateScreen();
-
-		g_system->delayMillis(10);
+		_vm->yield();
 	} while (!_vm->shouldQuit() && isSoundEffectPlaying(soundChannel));
 
 	// One last callback check


Commit: 7b487f22ebd5f2f8034ed48fecfcd1e069107106
    https://github.com/scummvm/scummvm/commit/7b487f22ebd5f2f8034ed48fecfcd1e069107106
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the basic space door

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 6c1d386f9a..c48fb3fda8 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -25,6 +25,7 @@
 
 #include "buried/buried.h"
 #include "buried/gameui.h"
+#include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
 #include "buried/resources.h"
@@ -172,6 +173,125 @@ int BaseOxygenTimer::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class SpaceDoorTimer : public BaseOxygenTimer {
+public:
+	SpaceDoorTimer(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int openFrame = -1, int closedFrame = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1,
+			int doorFlag = -1, int doorFlagValue = 0);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _clicked;
+	Common::Rect _clickable;
+	DestinationScene _destData;
+	int _openFrame;
+	int _closedFrame;
+	int _doorFlag;
+	int _doorFlagValue;
+};
+
+SpaceDoorTimer::SpaceDoorTimer(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int openFrame, int closedFrame, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength,
+		int doorFlag, int doorFlagValue) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clicked = false;
+	_openFrame = openFrame;
+	_closedFrame = closedFrame;
+	_doorFlag = doorFlag;
+	_doorFlagValue = doorFlagValue;
+	_clickable = Common::Rect(left, top, right, bottom);
+	_destData.destinationScene = _staticData.location;
+	_destData.destinationScene.depth = depth;
+	_destData.transitionType = transitionType;
+	_destData.transitionData = transitionData;
+	_destData.transitionStartFrame = transitionStartFrame;
+	_destData.transitionLength = transitionLength;
+}
+
+int SpaceDoorTimer::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation)) {
+		_clicked = true;
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int SpaceDoorTimer::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clicked) {
+		// If we are facing the habitat wing death door in walkthrough mode,
+		// keep it locked.
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 &&
+				_staticData.location.timeZone == 6 && _staticData.location.environment == 1 &&
+				_staticData.location.node == 3 && _staticData.location.facing == 1 &&
+				_staticData.location.orientation == 2 && _staticData.location.depth == 0) {
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12));
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
+			_clicked = false;
+			return SC_TRUE;
+		}
+
+		// If we are facing the scanning room door and we have Arthur, automatically recall
+		// to the future apartment
+		if (_staticData.location.timeZone == 6 && _staticData.location.environment == 3 &&
+				_staticData.location.node == 9 && _staticData.location.facing == 0 &&
+				_staticData.location.orientation == 0 && _staticData.location.depth == 0 &&
+				((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+			((SceneViewWindow *)viewWindow)->timeSuitJump(4);
+			return SC_TRUE;
+		}
+
+		if (_doorFlag < 0 || ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_doorFlag) == _doorFlagValue) {
+			// Change the still frame to the new one
+			if (_openFrame >= 0) {
+				_staticData.navFrameIndex = _openFrame;
+				viewWindow->invalidateWindow(false);
+				_vm->_sound->playSynchronousSoundEffect("BITDATA/AILAB/AI_LOCK.BTA"); // Broken in 1.01
+			}
+
+			((SceneViewWindow *)viewWindow)->moveToDestination(_destData);
+		} else {
+			// Display the closed frame
+			if (_closedFrame >= 0) {
+				int oldFrame = _staticData.navFrameIndex;
+				_staticData.navFrameIndex = _closedFrame;
+				viewWindow->invalidateWindow(false);
+
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12));
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
+
+				_staticData.navFrameIndex = oldFrame;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+
+		_clicked = false;
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int SpaceDoorTimer::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	// If we are in walkthrough mode and are at the death door in the habitat wing,
+	// don't allow you to open the door.
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 &&
+			_staticData.location.timeZone == 6 && _staticData.location.environment == 1 &&
+			_staticData.location.node == 3 && _staticData.location.facing == 1 &&
+			_staticData.location.orientation == 2 && _staticData.location.depth == 0) {
+		return kCursorArrow;
+	}
+
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class UseCheeseGirlPropellant : public BaseOxygenTimer {
 public:
 	UseCheeseGirlPropellant(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -293,6 +413,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new UseCheeseGirlPropellant(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 3:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 172, 46, 262, 136, 87, -1, 1, TRANSITION_VIDEO, 2, -1, -1, -1, -1);
+	case 5:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 144, 30, 268, 152, 88, -1, 1, TRANSITION_VIDEO, 4, -1, -1, -1, -1);
 	case 6:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 11:
@@ -303,12 +427,22 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 32:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 52:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 40, 276, 140, -1, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
+	case 53:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 40, 276, 140, -1, -1, 1, TRANSITION_VIDEO, 2, -1, -1, -1, -1);
 	case 54:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 60:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 65:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 26, 268, 124, -1, -1, 1, TRANSITION_VIDEO, 13, -1, -1, -1, -1);
+	case 66:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 26, 268, 124, -1, -1, 1, TRANSITION_VIDEO, 16, -1, -1, -1, -1);
 	case 68:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 70:
+		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 92, 92, 212, 189, 48, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
 	case 93:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	}


Commit: cb5ff6cc7b19f5a2fcbb24bc4860c1b7bed6f406
    https://github.com/scummvm/scummvm/commit/cb5ff6cc7b19f5a2fcbb24bc4860c1b7bed6f406
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix the scene view OnSetCursor implementation

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 770939a7db..f4cd4fc367 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2366,6 +2366,8 @@ bool SceneViewWindow::onSetCursor(uint message) {
 				_curCursor = (int)kCursorLocateA;
 			}
 		}
+	} else {
+		_curCursor = newCursor;
 	}
 
 	_vm->_gfx->setCursor((Cursor)_curCursor);


Commit: dae2d4d6cb943effb8c5755939499607564ef41f
    https://github.com/scummvm/scummvm/commit/dae2d4d6cb943effb8c5755939499607564ef41f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the habitat wing locked doors

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index c48fb3fda8..4b33d090fe 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -358,6 +358,57 @@ int UseCheeseGirlPropellant::droppedItem(Window *viewWindow, int itemID, const C
 	return SIC_REJECT;
 }
 
+class HabitatWingLockedDoor : public BaseOxygenTimer {
+public:
+	HabitatWingLockedDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int newFrameID = -1, int beepSoundID = -1, int voSoundID = -1, int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _newFrameID;
+	Common::Rect _clickRegion;
+	int _beepSoundID;
+	int _voSoundID;
+};
+
+HabitatWingLockedDoor::HabitatWingLockedDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int newFrameID, int beepSoundID, int voSoundID, int left, int top, int right, int bottom) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_newFrameID = newFrameID;
+	_beepSoundID = beepSoundID;
+	_voSoundID = voSoundID;
+}
+
+int HabitatWingLockedDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		int oldFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = _newFrameID;
+		viewWindow->invalidateWindow(false);
+
+		if (_beepSoundID != -1)
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _beepSoundID));
+
+		if (_voSoundID != -1)
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _voSoundID));
+
+		_staticData.navFrameIndex = oldFrame;
+		viewWindow->invalidateWindow(false);
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int HabitatWingLockedDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class BaseOxygenTimerInSpace : public BaseOxygenTimer {
 public:
 	BaseOxygenTimerInSpace(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -419,6 +470,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 144, 30, 268, 152, 88, -1, 1, TRANSITION_VIDEO, 4, -1, -1, -1, -1);
 	case 6:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 7:
+		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 99, 12, 13, 166, 32, 286, 182);
+	case 8:
+		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 100, 12, 13, 130, 48, 290, 189);
 	case 11:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
@@ -443,6 +498,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 70:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 92, 92, 212, 189, 48, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
+	case 75:
+		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 51, 4, 5, 146, 0, 396, 84);
 	case 93:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	}


Commit: 020989eefe9560817ec4be605172cf7000782aeb
    https://github.com/scummvm/scummvm/commit/020989eefe9560817ec4be605172cf7000782aeb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Improve the text positioning a bit

Changed paths:
    engines/buried/complete.cpp
    engines/buried/death.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/inventory_info.cpp
    engines/buried/inventory_window.cpp
    engines/buried/livetext.cpp


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index 6c66a39027..a3eef1d83f 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -200,24 +200,24 @@ void CompletionWindow::onPaint() {
 		uint32 textColor = _vm->_gfx->getColor(102, 204, 153);
 		Common::String firstBlockText = _vm->getString(2100);
 		Common::Rect firstBlockRect(10, 54, 283, 86);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlockText, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, _fontHeightA);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlockText, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), firstBlockRect.height(), textColor, _fontHeightA);
 
 		// Draw the cause text
 		Common::String secondBlockText = _vm->getString(2102);
 		Common::Rect secondBlockRect(10, 120, 283, 215);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlockText, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, _fontHeightA);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlockText, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), secondBlockRect.height(), textColor, _fontHeightA);
 
 		// Description text
 		Common::Rect scoringTextRect(10, 248, 283, 378);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, _fontHeightA);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), scoringTextRect.height(), textColor, _fontHeightA);
 
 		// Scores
 		textColor = _vm->_gfx->getColor(255, 255, 51);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), textColor, _fontHeightA, kTextAlignRight);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringTextRect.left, scoringTextRect.top, scoringTextRect.width(), scoringTextRect.height(), textColor, _fontHeightA, kTextAlignRight);
 
 		// Total score
 		Common::Rect finalScoreRect(122, 386, 283, 401);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), textColor, _fontHeightB, kTextAlignRight);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalScoreRect.left, finalScoreRect.top, finalScoreRect.width(), finalScoreRect.height(), textColor, _fontHeightB, kTextAlignRight);
 	}
 }
 
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index 25f75aa643..b8b82877ba 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -276,21 +276,21 @@ void DeathWindow::onPaint() {
 	uint32 textColor = _vm->_gfx->getColor(153, 102, 204);
 	Common::String firstBlock = _vm->getString(IDS_DEATH_SCENE_MESSAGE_TEXT_BASE + _deathSceneIndex * 5);
 	Common::Rect firstBlockRect(10, 54, 283, 86);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlock, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), textColor, _fontHeightA);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, firstBlock, firstBlockRect.left, firstBlockRect.top, firstBlockRect.width(), firstBlockRect.height(), textColor, _fontHeightA);
 
 	Common::String secondBlock = _vm->getString(IDS_DEATH_SCENE_MESSAGE_TEXT_BASE + _deathSceneIndex * 5 + 1);
 	Common::Rect secondBlockRect(10, 120, 283, 215);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlock, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), textColor, _fontHeightA);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, secondBlock, secondBlockRect.left, secondBlockRect.top, secondBlockRect.width(), secondBlockRect.height(), textColor, _fontHeightA);
 
 	Common::Rect scoringDescRect(10, 248, 283, 378);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextDescriptions, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), scoringDescRect.height(), textColor, _fontHeightA);
 
 	textColor = _vm->_gfx->getColor(212, 109, 0);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), textColor, _fontHeightA, kTextAlignRight);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontA, _scoringTextScores, scoringDescRect.left, scoringDescRect.top, scoringDescRect.width(), scoringDescRect.height(), textColor, _fontHeightA, kTextAlignRight);
 
 	// CHECKME: This does center vertical alignment, so check the y coordinates
 	Common::Rect finalTextScoreRect(122, 386, 283, 401);
-	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), textColor, _fontHeightB, kTextAlignRight);
+	_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFontB, _scoringTextFinalScore, finalTextScoreRect.left, finalTextScoreRect.top, finalTextScoreRect.width(), finalTextScoreRect.height(), textColor, _fontHeightB, kTextAlignRight);
 }
 
 bool DeathWindow::onEraseBackground() {
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 2d32363fbd..e0af205e59 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -247,12 +247,11 @@ int KitchenUnitAutoChef::mouseUp(Window *viewWindow, const Common::Point &pointL
 
 int KitchenUnitAutoChef::gdiPaint(Window *viewWindow) {
 	if (_status == 1) {
-		// TODO: Vertically center align
 		uint32 textColor = _vm->_gfx->getColor(144, 200, 248);
 		Common::String text = _vm->getString(IDFAKI_AC_ORDER_FOOD_TEXT);
 		Common::Rect rect = Common::Rect(80, 26, 294, 92);
 		rect.translate(64, 128);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), textColor, _lineHeight);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), rect.height(), textColor, _lineHeight, kTextAlignLeft, true);
 	}
 
 	return SC_FALSE;
@@ -506,9 +505,8 @@ int KitchenUnitShopNet::gdiPaint(Window *viewWindow) {
 	}
 
 	if (!text.empty()) {
-		// TODO: Vertically center align
 		rect.translate(64, 128);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), textColor, _lineHeight);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), rect.height(), textColor, _lineHeight, kTextAlignLeft, true);
 	}
 
 	return SC_FALSE;
@@ -692,9 +690,7 @@ int KitchenUnitPostBox::gdiPaint(Window *viewWindow) {
 
 		Common::Rect rect(_items[i]);
 		rect.translate(64, 128);
-		rect.translate(0, (rect.height() - _lineHeight) / 2); // HACK: Vertically center (should be implemented better)
-
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), textColor, _lineHeight, kTextAlignCenter);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), rect.height(), textColor, _lineHeight, kTextAlignCenter, true);
 	}
 
 	return SC_FALSE;
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 4cf9174914..fccd72bab3 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -766,7 +766,7 @@ Common::SeekableReadStream *GraphicsManager::getThemeFontStream(const Common::St
 	return stream;
 }
 
-void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, TextAlign textAlign) {
+void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, int h, uint32 color, int lineHeight, TextAlign textAlign, bool centerVertically) {
 	if (text.empty())
 		return;
 
@@ -786,6 +786,12 @@ void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, c
 		break;
 	}
 
+	if (centerVertically)
+		y += (h - (lines.size() * lineHeight)) / 2;
+
+	// Why is this needed? Dunno, but I guess Windows adds one row of space on the top
+	y++;
+
 	for (uint32 i = 0; i < lines.size(); i++) {
 		font->drawString(dst, lines[i], x, y, w, color, align);
 		y += lineHeight;
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 4d13ef4cdf..c6c65041aa 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -100,7 +100,7 @@ public:
 	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
 	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
 	void crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc);
-	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, uint32 color, int lineHeight, TextAlign textAlign = kTextAlignLeft);
+	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, int h, uint32 color, int lineHeight, TextAlign textAlign = kTextAlignLeft, bool centerVertically = false);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index fbe9f0771b..0f0ffb64fd 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -98,13 +98,13 @@ void InventoryInfoWindow::onPaint() {
 	Common::Rect titleRect(10, 56, 263, 71);
 	Common::String title = _vm->getString(IDES_ITEM_TITLE_BASE + _currentItemID);
 	assert(!title.empty());
-	_vm->_gfx->renderText(background, _textFont, title, titleRect.left, titleRect.top, titleRect.width(), textColor, 14);
+	_vm->_gfx->renderText(background, _textFont, title, titleRect.left, titleRect.top, titleRect.width(), titleRect.height(), textColor, _fontHeight);
 
 	// Draw the description
 	Common::Rect descRect(10, 89, 263, 186);
 	Common::String desc = _vm->getString(IDES_ITEM_DESC_BASE + _currentItemID * 5);
 	assert(!desc.empty());
-	_vm->_gfx->renderText(background, _textFont, desc, descRect.left, descRect.top, descRect.width(), textColor, 14);
+	_vm->_gfx->renderText(background, _textFont, desc, descRect.left, descRect.top, descRect.width(), descRect.height(), textColor, _fontHeight);
 
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(background, absoluteRect.left, absoluteRect.top);
diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index da4103c0f6..db5c34fece 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -319,6 +319,9 @@ void InventoryWindow::onPaint() {
 				textRect.bottom++;
 			}
 
+			// Shift another pixel to adjust for Windows
+			textRect.top++;
+
 			textRect.translate(absoluteRect.left, absoluteRect.top);
 			Common::String text = _vm->getString(IDES_ITEM_TITLE_BASE + _itemArray[_curItem + i]);
 			_textFont->drawString(_vm->_gfx->getScreen(), text, textRect.left, textRect.top, textRect.width(), textColor);
diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index 0b5de602c2..5698d9c862 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -112,7 +112,7 @@ void LiveTextWindow::onPaint() {
 
 	// Draw the text on top of that
 	if (!_text.empty())
-		_vm->_gfx->renderText(surface, _font, _text, 30, 4, 270, _vm->_gfx->getColor(212, 109, 0), _fontHeight);
+		_vm->_gfx->renderText(surface, _font, _text, 30, 4, 270, 50, _vm->_gfx->getColor(212, 109, 0), _fontHeight);
 
 	Common::Rect absoluteRect = getAbsoluteRect();
 	_vm->_gfx->blit(surface, absoluteRect.left, absoluteRect.top);


Commit: 09c1f91c4225a93d1031a02db10540370f2dae73
    https://github.com/scummvm/scummvm/commit/09c1f91c4225a93d1031a02db10540370f2dae73
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Be sure to take a copy of the global flags when dying

The scene view window is destroyed, taking them with it

Changed paths:
    engines/buried/complete.cpp
    engines/buried/complete.h
    engines/buried/death.cpp
    engines/buried/death.h
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index a3eef1d83f..2a51b7bfbe 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -53,7 +53,7 @@ namespace Buried {
 	if (_globalFlags.evcapBaseID[i] == flag) \
 		supportingEvidence++
 
-CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, const GlobalFlags &globalFlags) : Window(vm, parent), _globalFlags(globalFlags) {
+CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, GlobalFlags globalFlags) : Window(vm, parent), _globalFlags(globalFlags) {
 	_vm->_sound->setAmbientSound();
 
 	_status = 0;
diff --git a/engines/buried/complete.h b/engines/buried/complete.h
index eb46c8b320..2c1e8f9bb9 100644
--- a/engines/buried/complete.h
+++ b/engines/buried/complete.h
@@ -40,7 +40,7 @@ class VideoWindow;
 
 class CompletionWindow : public Window {
 public:
-	CompletionWindow(BuriedEngine *vm, Window *parent, const GlobalFlags &globalFlags);
+	CompletionWindow(BuriedEngine *vm, Window *parent, GlobalFlags globalFlags);
 	~CompletionWindow();
 
 	void onPaint();
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index b8b82877ba..da69107cad 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -59,7 +59,7 @@ enum {
 	if (_globalFlags.evcapBaseID[i] == flag) \
 		supportingEvidence++
 
-DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, const GlobalFlags &globalFlags) : Window(vm, parent), _deathSceneIndex(deathSceneIndex), _globalFlags(globalFlags) {
+DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, GlobalFlags globalFlags) : Window(vm, parent), _deathSceneIndex(deathSceneIndex), _globalFlags(globalFlags) {
 	_curButton = 0;
 	_deathFrameIndex = -1;
 	_lightOn = false;
diff --git a/engines/buried/death.h b/engines/buried/death.h
index 471f276fed..ed82e847e3 100644
--- a/engines/buried/death.h
+++ b/engines/buried/death.h
@@ -40,7 +40,7 @@ class AVIFrames;
 
 class DeathWindow : public Window {
 public:
-	DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, const GlobalFlags &globalFlags);
+	DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, GlobalFlags globalFlags);
 	~DeathWindow();
 
 	void onPaint();
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 1034cf4ec0..110273ec89 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -276,7 +276,7 @@ bool FrameWindow::startNewGame(const Common::String &fileName) {
 	return true;
 }
 
-bool FrameWindow::showDeathScene(int deathSceneIndex, const GlobalFlags &globalFlags) {
+bool FrameWindow::showDeathScene(int deathSceneIndex, GlobalFlags globalFlags) {
 	_gameInProgress = false;
 	_atMainMenu = false;
 
@@ -290,7 +290,7 @@ bool FrameWindow::showDeathScene(int deathSceneIndex, const GlobalFlags &globalF
 	return true;
 }
 
-bool FrameWindow::showCompletionScene(const GlobalFlags &globalFlags) {
+bool FrameWindow::showCompletionScene(GlobalFlags globalFlags) {
 	_gameInProgress = false;
 	_atMainMenu = false;
 
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index 1fa5d06ede..c8ec5fbcf2 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -47,8 +47,8 @@ public:
 	bool startNewGame(bool walkthrough = false, bool introMovie = false);
 	bool startNewGame(const Common::String &fileName);
 	// TODO: startNewGame with continue data
-	bool showDeathScene(int deathSceneIndex, const GlobalFlags &globalFlags);
-	bool showCompletionScene(const GlobalFlags &globalFlags);
+	bool showDeathScene(int deathSceneIndex, GlobalFlags globalFlags);
+	bool showCompletionScene(GlobalFlags globalFlags);
 	bool showCredits();
 	bool showOverview();
 	bool notifyUserOfFrameCycling();


Commit: 894c48834150cb028211b1f0a1969c79647f3b11
    https://github.com/scummvm/scummvm/commit/894c48834150cb028211b1f0a1969c79647f3b11
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the arthur scary voices

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 4b33d090fe..c4d36dc475 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -358,6 +358,72 @@ int UseCheeseGirlPropellant::droppedItem(Window *viewWindow, int itemID, const C
 	return SIC_REJECT;
 }
 
+class PlayArthurOffsetTimed : public BaseOxygenTimer {
+public:
+	PlayArthurOffsetTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int stingerVolume = 127, int lastStingerFlagOffset = -1, int effectIDFlagOffset = -1, int firstStingerFileID = -1,
+			int lastStingerFileID = -1, int stingerDelay = 1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _stingerVolume;
+	int _lastStingerFlagOffset;
+	int _effectIDFlagOffset;
+	int _firstStingerFileID;
+	int _lastStingerFileID;
+	int _stingerDelay;
+	int _timerFlagOffset;
+};
+
+PlayArthurOffsetTimed::PlayArthurOffsetTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID,
+		int lastStingerFileID, int stingerDelay) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_stingerVolume = stingerVolume;
+	_lastStingerFlagOffset = lastStingerFlagOffset;
+	_effectIDFlagOffset = effectIDFlagOffset;
+	_firstStingerFileID = firstStingerFileID;
+	_lastStingerFileID = lastStingerFileID;
+	_stingerDelay = stingerDelay;
+}
+
+int PlayArthurOffsetTimed::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_effectIDFlagOffset >= 0 && (priorLocation.node != _staticData.location.node || priorLocation.environment != _staticData.location.environment)) {
+		byte effectID = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_effectIDFlagOffset);
+
+		if (!_vm->_sound->isSoundEffectPlaying(effectID - 1)) {
+			int lastStinger = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_lastStingerFlagOffset) + 1;
+
+			if ((lastStinger % _stingerDelay) == 0) {
+				if (lastStinger <= (_lastStingerFileID - _firstStingerFileID) * _stingerDelay) {
+					int fileNameIndex = _vm->computeFileNameResourceID(_staticData.location.timeZone, _staticData.location.environment, _firstStingerFileID + lastStinger / _stingerDelay - 1);
+					byte newStingerID = 0;
+
+					if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+						newStingerID = _vm->_sound->playSoundEffect(_vm->getFilePath(fileNameIndex), _stingerVolume / 2, false, true) + 1;
+						byte &lastArthurComment = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiHWLastCommentPlayed;
+
+						if ((lastStinger / 2) != 0 && lastArthurComment < 4) {
+							lastArthurComment++;
+							_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 10, lastArthurComment + 5), 128, false, true);
+						}
+					} else {
+						newStingerID = _vm->_sound->playSoundEffect(_vm->getFilePath(fileNameIndex), _stingerVolume, false, true) + 1;
+					}
+
+					((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_effectIDFlagOffset, newStingerID);
+					((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
+				}
+			} else {
+				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_effectIDFlagOffset, 0xFF);
+				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
 class HabitatWingLockedDoor : public BaseOxygenTimer {
 public:
 	HabitatWingLockedDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -466,6 +532,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new UseCheeseGirlPropellant(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 3:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 172, 46, 262, 136, 87, -1, 1, TRANSITION_VIDEO, 2, -1, -1, -1, -1);
+	case 4:
+		return new PlayArthurOffsetTimed(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, aiHWStingerID), offsetof(GlobalFlags, aiHWStingerChannelID), 4, 10, 1); // 1.01 uses a delay of 2, clone2727 likes that better
 	case 5:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 144, 30, 268, 152, 88, -1, 1, TRANSITION_VIDEO, 4, -1, -1, -1, -1);
 	case 6:


Commit: 88abb972efaa63935c8f0cb522fffc7cd0f955bb
    https://github.com/scummvm/scummvm/commit/88abb972efaa63935c8f0cb522fffc7cd0f955bb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Start implementing the painting tower elevator

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 6293177bed..f802b33b55 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -37,6 +37,69 @@
 
 namespace Buried {
 
+class SwapStillOnFlag : public SceneBase {
+public:
+	SwapStillOnFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, int flagValue = -1);
+};
+
+SwapStillOnFlag::SwapStillOnFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, int flagValue) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) >= flagValue) {
+		int curStillFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = _staticData.miscFrameIndex;
+		_staticData.miscFrameIndex = curStillFrame;
+	}
+}
+
+class PaintingTowerWalkOntoElevator : public SceneBase {
+public:
+	PaintingTowerWalkOntoElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+};
+
+PaintingTowerWalkOntoElevator::PaintingTowerWalkOntoElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1) {
+		// If the elevator is present, don't die
+		int curStillFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = _staticData.miscFrameIndex;
+		_staticData.miscFrameIndex = curStillFrame;
+
+		_staticData.destForward.destinationScene.timeZone = 5;
+		_staticData.destForward.destinationScene.environment = 1;
+		_staticData.destForward.destinationScene.node = 8;
+		_staticData.destForward.destinationScene.facing = 0;
+		_staticData.destForward.destinationScene.orientation = 1;
+		_staticData.destForward.destinationScene.depth = 0;
+		_staticData.destForward.transitionType = TRANSITION_WALK;
+		_staticData.destForward.transitionData = 6;
+		_staticData.destForward.transitionStartFrame = 56;
+		_staticData.destForward.transitionLength = 16;
+	}
+}
+
+int PaintingTowerWalkOntoElevator::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == _staticData.location.timeZone &&
+			newLocation.environment == _staticData.location.environment &&
+			newLocation.node == _staticData.location.node &&
+			newLocation.facing == _staticData.location.facing &&
+			newLocation.orientation == _staticData.location.orientation &&
+			newLocation.depth == _staticData.location.depth) {
+		// Notify the player of his gruesome death
+		((SceneViewWindow *)viewWindow)->showDeathScene(30);
+		return SC_DEATH;
+	}
+
+	// Reset the elevator since we walked down (clone2727 asks if this is possible)
+	if (newLocation.timeZone == _staticData.location.timeZone && newLocation.environment == 3)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent = 0;
+
+	return SC_TRUE;
+}
+
 class PaintingTowerRetrieveKey : public SceneBase {
 public:
 	PaintingTowerRetrieveKey(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -274,8 +337,12 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 1:
+		return new SwapStillOnFlag(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsPTElevatorPresent), 1);
 	case 4:
 		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 8:
+		return new PaintingTowerWalkOntoElevator(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 10:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 11:


Commit: 961a93ba805e5941684def1bebd2c71e2021b76c
    https://github.com/scummvm/scummvm/commit/961a93ba805e5941684def1bebd2c71e2021b76c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Fix evidence locate cursor logic

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index f4cd4fc367..554aadd45b 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2355,10 +2355,10 @@ bool SceneViewWindow::onSetCursor(uint message) {
 
 	// If the locate button is enabled, follow different logic
 	if (_globalFlags.bcLocateEnabled == 1) {
-		if (_curCursor >= 0 || (newCursor > 65530 && newCursor != _curCursor)) {
+		if (_curCursor >= 0 || (newCursor < 0 && newCursor != _curCursor)) {
 			// If the new cursor is less than zero, use it, otherwise use the default locate cursor
-			if (newCursor > 65533) {
-				if (newCursor == 65534)
+			if (newCursor < 0) {
+				if (newCursor == -2)
 					_curCursor = (int)kCursorLocateB;
 				else
 					_curCursor = (int)kCursorLocateA;


Commit: c1f9f93b9b3ff77720a3adea90af9fc4e62c15ff
    https://github.com/scummvm/scummvm/commit/c1f9f93b9b3ff77720a3adea90af9fc4e62c15ff
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:40+01:00

Commit Message:
BURIED: Implement the Da Vinci footprint evidence

Changed paths:
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index f802b33b55..9da5c51ef3 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -53,6 +53,62 @@ SwapStillOnFlag::SwapStillOnFlag(BuriedEngine *vm, Window *viewWindow, const Loc
 	}
 }
 
+class CapturePaintingTowerFootprint : public SceneBase {
+public:
+	CapturePaintingTowerFootprint(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _footprint;
+};
+
+CapturePaintingTowerFootprint::CapturePaintingTowerFootprint(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1) {
+		int curStillFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = _staticData.miscFrameIndex;
+		_staticData.miscFrameIndex = curStillFrame;
+	}
+
+	_footprint = Common::Rect(218, 112, 244, 132);
+}
+
+int CapturePaintingTowerFootprint::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && _footprint.contains(pointLocation)) {
+		// Play the capture animation
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent >= 1)
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(1);
+		else
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+
+		// Attempt to add it to the biochip
+		if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_FOOTPRINT))
+			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+		else
+			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+		// Disable capture
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CapturePaintingTowerFootprint::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_footprint.contains(pointLocation)) // Cursor change
+			return -2;
+
+		// Use locate A
+		return -1;
+	}
+
+	return kCursorArrow;
+}
+
 class PaintingTowerWalkOntoElevator : public SceneBase {
 public:
 	PaintingTowerWalkOntoElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -339,6 +395,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new SwapStillOnFlag(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsPTElevatorPresent), 1);
+	case 2:
+		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, DAVINCI_EVIDENCE_FOOTPRINT, IDS_MBT_EVIDENCE_PRESENT);
+	case 3:
+		return new CapturePaintingTowerFootprint(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 4:
 		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 8:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index f6aaff0b68..88dd3c6da2 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -268,6 +268,27 @@ int ClickPlaySound::specifyCursor(Window *viewWindow, const Common::Point &point
 	return kCursorArrow;
 }
 
+DisplayMessageWithEvidenceWhenEnteringNode::DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow,
+			const LocationStaticData &sceneStaticData, const Location &priorLocation, int evidenceID, int messageBoxTextID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_evidenceID = evidenceID;
+	_messageBoxTextID = messageBoxTextID;
+}
+
+int DisplayMessageWithEvidenceWhenEnteringNode::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if ((_staticData.location.timeZone != priorLocation.timeZone ||
+			_staticData.location.environment != priorLocation.environment ||
+			_staticData.location.node != priorLocation.node ||
+			_staticData.location.facing != priorLocation.facing ||
+			_staticData.location.orientation != priorLocation.orientation ||
+			_staticData.location.depth != priorLocation.depth) &&
+			!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), _evidenceID)) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(_messageBoxTextID));
+	}
+
+	return SC_TRUE;
+}
+
 OneShotEntryVideoWarning::OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int animID, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
 	_animID = animID;
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 695f2612bb..c0b31f0342 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -118,6 +118,17 @@ private:
 	int _flagOffset;
 };
 
+class DisplayMessageWithEvidenceWhenEnteringNode : public SceneBase {
+public:
+	DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int evidenceID = -1, int messageBoxTextID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _messageBoxTextID;
+	byte _evidenceID;
+};
+
 class OneShotEntryVideoWarning : public SceneBase {
 public:
 	OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: a3f2bef3f385c7c6a251665bdf99a18de5d94f87
    https://github.com/scummvm/scummvm/commit/a3f2bef3f385c7c6a251665bdf99a18de5d94f87
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the evidence review screen

Changed paths:
    engines/buried/biochip_view.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 4c6663470f..5c6f96ed80 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -36,6 +36,7 @@
 #include "buried/scene_view.h"
 
 #include "common/stream.h"
+#include "common/system.h"
 #include "graphics/surface.h"
 
 namespace Buried {
@@ -358,6 +359,132 @@ void JumpBiochipViewWindow::onMouseMove(const Common::Point &point, uint flags)
 	}
 }
 
+class EvidenceBioChipViewWindow : public Window {
+public:
+	EvidenceBioChipViewWindow(BuriedEngine *vm, Window *parent);
+	~EvidenceBioChipViewWindow();
+
+	void onPaint();
+	void onLButtonUp(const Common::Point &point, uint flags);
+
+private:
+	Common::Rect _evidence[6];
+	Common::Rect _pageButton;
+	AVIFrames _stillFrames;
+	AVIFrames _evidenceFrames;
+	int _status;
+	int _pageIndex;
+	Graphics::Surface _preBuffer;
+
+	bool rebuildMainPrebuffer();
+};
+
+EvidenceBioChipViewWindow::EvidenceBioChipViewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
+	_evidence[0] = Common::Rect(14, 49, 96, 83);
+	_evidence[1] = Common::Rect(14, 91, 96, 125);
+	_evidence[2] = Common::Rect(14, 133, 96, 167);
+	_evidence[3] = Common::Rect(225, 20, 307, 54);
+	_evidence[4] = Common::Rect(225, 61, 307, 95);
+	_evidence[5] = Common::Rect(225, 103, 307, 137);
+	_pageButton = Common::Rect(336, 156, 420, 185);
+	_status = 0;
+	_pageIndex = 0;
+
+	_rect = Common::Rect(0, 0, 432, 189);
+
+	_preBuffer.create(432, 189, g_system->getScreenFormat());
+
+	if (!_stillFrames.open(_vm->getFilePath(IDS_BC_EVIDENCE_VIEW_FILENAME)))
+		error("Failed to open evidence still frames video");
+
+	if (!_evidenceFrames.open(_vm->getFilePath(IDS_BC_EVIDENCE_ITEMS_FILENAME)))
+		error("Failed to open evidence frames video");
+
+	// Build the initial page
+	rebuildMainPrebuffer();
+
+	// Display some live text if no evidence is present
+	if (((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().evcapNumCaptured == 0)
+		((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_MBT_EVIDENCE_NONE_ACQUIRED));
+}
+
+EvidenceBioChipViewWindow::~EvidenceBioChipViewWindow() {
+	_preBuffer.free();
+}
+
+void EvidenceBioChipViewWindow::onPaint() {
+	Common::Rect absoluteRect = getAbsoluteRect();
+
+	if (_status == 0) {
+		_vm->_gfx->blit(&_preBuffer, absoluteRect.left, absoluteRect.top);
+	} else {
+		const Graphics::Surface *frame = _stillFrames.getFrame(_status + 2);
+		_vm->_gfx->blit(frame, absoluteRect.left, absoluteRect.top);
+	}
+}
+
+void EvidenceBioChipViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
+	if (_status == 0) {
+		// Get the number of items urrently captured
+		int itemCount = ((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().evcapNumCaptured;
+
+		// Loop through the evidence piece regions, determining if we have another page to go to
+		for (int i = 0; i < 6; i++) {
+			if (_evidence[i].contains(point) && (_pageIndex * 6 + i) < itemCount) {
+				_status = ((SceneViewWindow *)getParent()->getParent())->getNumberFromGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), _pageIndex * 6 + i);
+				invalidateWindow(false);
+				((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText(_vm->getString(IDS_EC_DESC_TEXT_A + _status - 1), false);
+
+				// Give scores for research
+				if (_status + 2 == 3)
+					((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().scoreResearchCastleFootprint = 1;
+				else if (_status + 2 == 10)
+					((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().scoreResearchDaVinciFootprint = 1;
+			}
+		}
+
+		// Did we click on the next page button and is it valid?
+		if (_pageButton.contains(point)) {
+			if (itemCount > 6) {
+				if (_pageIndex * 6 < itemCount - 6) {
+					_pageIndex++;
+				} else {
+					_pageIndex = 0;
+				}
+
+				rebuildMainPrebuffer();
+				invalidateWindow(false);
+			}
+		}
+	} else {
+		// Return to the last evidence page displayed
+		_status = 0;
+		invalidateWindow(false);
+		((GameUIWindow *)getParent()->getParent()->getParent())->_liveTextWindow->updateLiveText("");
+	}
+}
+
+bool EvidenceBioChipViewWindow::rebuildMainPrebuffer() {
+	int itemCount = ((SceneViewWindow *)getParent()->getParent())->getGlobalFlags().evcapNumCaptured;
+	int frameIndex = (itemCount > 6) ? 1 : 0;
+	const Graphics::Surface *frame = _stillFrames.getFrame(frameIndex);
+	_vm->_gfx->crossBlit(&_preBuffer, 0, 0, 432, 189, frame, 0, 0);
+
+	for (int i = 0; i < 6; i++) {
+		if ((_pageIndex * 6 + i) < itemCount) {
+			frameIndex = ((SceneViewWindow *)getParent()->getParent())->getNumberFromGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), _pageIndex * 6 + i) - 1;
+			frame = _evidenceFrames.getFrame(frameIndex);
+
+			if (frame) {
+				byte transparentColor = _vm->isTrueColor() ? 255 : 248;
+				_vm->_gfx->opaqueTransparentBlit(&_preBuffer, _evidence[i].left, _evidence[i].top, 203, 34, frame, 2, 2, 0, transparentColor, transparentColor, transparentColor);
+			}
+		}
+	}
+
+	return true;
+}
+
 enum {
 	REGION_SAVE = 1,
 	REGION_RESTORE = 2,
@@ -618,8 +745,7 @@ Window *BioChipMainViewWindow::createBioChipSpecificViewWindow(int bioChipID) {
 	case kItemBioChipJump:
 		return new JumpBiochipViewWindow(_vm, this);
 	case kItemBioChipEvidence:
-		// TODO
-		break;
+		return new EvidenceBioChipViewWindow(_vm, this);
 	case kItemBioChipFiles:
 		return new FilesBioChipViewWindow(_vm, this);
 	}


Commit: aceeeb9a9c97df490b94c6a067dba500c5b2fa89
    https://github.com/scummvm/scummvm/commit/aceeeb9a9c97df490b94c6a067dba500c5b2fa89
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement a bunch of Mayan translation stuff

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index f18a317e82..9f1b0ca7fd 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -25,6 +25,7 @@
 
 #include "buried/buried.h"
 #include "buried/gameui.h"
+#include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
 #include "buried/resources.h"
@@ -33,6 +34,8 @@
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
+#include "graphics/surface.h"
+
 namespace Buried {
 
 class PlaceCeramicBowl : public SceneBase {
@@ -95,6 +98,157 @@ int PlaceCeramicBowl::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class DateCombinationRead : public SceneBase {
+public:
+	DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _currentRegion;
+};
+
+DateCombinationRead::DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_currentRegion = -1;
+}
+
+int DateCombinationRead::gdiPaint(Window *viewWindow) {
+	if (_currentRegion >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		int left = _currentRegion * 43 + 20 + absoluteRect.left;
+		Common::Rect rect(left, absoluteRect.top + 18, left + 43, absoluteRect.top + 110);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int DateCombinationRead::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect symbols(20, 18, 407, 110);
+
+		if (symbols.contains(pointLocation)) {
+			int translatedSymbolIndex = (pointLocation.x - 20) / 43;
+
+			if (_currentRegion != translatedSymbolIndex) {
+				// Update flags
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCalendarListTranslated = 1;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPTextTranslated = 1;
+
+				// Display the text
+				((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(IDMYTP_WALLS_COMBO_TRANS_TEXT_BASE + translatedSymbolIndex));
+
+				// Reset the current region and redraw
+				_currentRegion = translatedSymbolIndex;
+				viewWindow->invalidateWindow(false);
+			}
+		} else {
+			if (_currentRegion >= 0) {
+				_currentRegion = -1;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+class ViewSingleTranslation : public SceneBase {
+public:
+	ViewSingleTranslation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int translatedTextID = -1, int left = -1, int top = -1, int right = -1, int bottom = -1,
+			int flagAOffset = -1, int flagBOffset = -1, int visitedFlagOffset = -1);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _textTranslated;
+	int _textID;
+	Common::Rect _clickableRegion;
+	int _flagAOffset;
+	int _flagBOffset;
+	int _visitedFlagOffset;
+};
+
+ViewSingleTranslation::ViewSingleTranslation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int translatedTextID, int left, int top, int right, int bottom,
+		int flagAOffset, int flagBOffset, int visitedFlagOffset) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_textTranslated = false;
+	_textID = translatedTextID;
+	_clickableRegion = Common::Rect(left, top, right, bottom);
+	_flagAOffset = flagAOffset;
+	_flagBOffset = flagBOffset;
+	_visitedFlagOffset = visitedFlagOffset;
+
+	if (_visitedFlagOffset >= 0)
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_visitedFlagOffset, 1);
+}
+
+int ViewSingleTranslation::gdiPaint(Window *viewWindow) {
+	// Draw the translated box, if applicable
+	if (_textTranslated && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_clickableRegion);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int ViewSingleTranslation::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_staticData.location.depth != 0) {
+		// If we're not at depth zero, move to depth zero
+		Location newLocation = _staticData.location;
+		newLocation.depth = 0;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ViewSingleTranslation::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		if (_clickableRegion.contains(pointLocation)) {
+			// Make sure we didn't already render the text
+			if (!_textTranslated) {
+				if (_flagAOffset >= 0)
+					((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagAOffset, 1);
+				if (_flagBOffset >= 0)
+					((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagBOffset, 1);
+
+				// Load and display the text
+				((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(_textID));
+				_textTranslated = true;
+				viewWindow->invalidateWindow(false);
+			}
+		} else {
+			if (_textTranslated) {
+				_textTranslated = false;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ViewSingleTranslation::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_staticData.location.depth != 0)
+		return kCursorPutDown;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -190,8 +344,38 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 60, 134, 118, 180, kItemCeramicBowl, 96, offsetof(GlobalFlags, myPickedUpCeramicBowl));
 	case 3:
 		return new PlaceCeramicBowl(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 6:
+		return new DateCombinationRead(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 7:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_DOOR_TRANS_TEXT, 16, 6, 402, 110, offsetof(GlobalFlags, myTPTextTranslated), offsetof(GlobalFlags, myTPTransBreathOfItzamna));
+	case 8:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_LEFT_TRANS_TEXT, 1, 6, 431, 98, offsetof(GlobalFlags, myTPTextTranslated));
+	case 9:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_MIDDLE_TRANS_TEXT, 16, 8, 430, 114, offsetof(GlobalFlags, myTPTextTranslated), offsetof(GlobalFlags, myTPCalendarTopTranslated));
+	case 10:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_SOUTHLEFT_TRANS_TEXT, 4, 55, 426, 95, offsetof(GlobalFlags, myTPTextTranslated));
+	case 11:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_WEST_TRANS_TEXT, 4, 72, 420, 108, offsetof(GlobalFlags, myTPTextTranslated));
+	case 12:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_NORTH_TRANS_TEXT, 6, 38, 428, 76, offsetof(GlobalFlags, myTPTextTranslated));
 	case 13:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 140, 124, 174, 158, kItemCavernSkull, 3, offsetof(GlobalFlags, myMCPickedUpSkull));
+	case 15:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myWGTransDoorTop));
+	case 16:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWGOffering));
+	case 19:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
+	case 20:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWTOffering));
+	case 23:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
+	case 24:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransAGOffering));
+	case 27:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
+	case 28:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransDGOffering));
 	case 31:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 194, 106, 278, 126, kItemJadeBlock, 105, offsetof(GlobalFlags, myWGRetrievedJadeBlock));
 	case 32:
@@ -226,6 +410,12 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 125:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 226, 90, 256, 104, kItemCopperMedallion, 15, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
+	case 126:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_AG_ALTAR_TEXT, 120, 44, 330, 72, -1, -1, offsetof(GlobalFlags, myAGVisitedAltar));
+	case 127:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WG_ALTAR_TEXT, 118, 14, 338, 44);
+	case 128:
+		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WT_ALTAR_TEXT, 106, 128, 344, 162);
 	}
 
 	warning("TODO: Mayan scene object %d", sceneStaticData.classID);


Commit: 882c7597a7475a153423f2cf8deb490389ac8b4e
    https://github.com/scummvm/scummvm/commit/882c7597a7475a153423f2cf8deb490389ac8b4e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the Mayan calendar puzzle

Changed paths:
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h
    engines/buried/resources.h


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 9f1b0ca7fd..2a5ac35235 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/avi_frames.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -98,6 +99,232 @@ int PlaceCeramicBowl::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class AdjustWheels : public SceneBase {
+public:
+	AdjustWheels(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	void preDestructor();
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	AVIFrames _leftWheelFrames;
+	int _curLeftFrame;
+	AVIFrames _rightWheelFrames;
+	int _curRightFrame;
+	Common::Rect _leftUpRegion;
+	Common::Rect _leftDownRegion;
+	Common::Rect _rightUpRegion;
+	Common::Rect _rightDownRegion;
+	bool _translateText;
+};
+
+AdjustWheels::AdjustWheels(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_curLeftFrame = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelLeftIndex;
+	_curRightFrame = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelRightIndex;
+	_leftUpRegion = Common::Rect(46, 0, 200, 70);
+	_leftDownRegion = Common::Rect(46, 106, 200, 189);
+	_rightUpRegion = Common::Rect(212, 0, 432, 66);
+	_rightDownRegion = Common::Rect(212, 109, 432, 189);
+	_translateText = false;
+
+	if (!_leftWheelFrames.open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9)))
+		error("Failed to open left wheel frames video");
+
+	if (!_rightWheelFrames.open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10)))
+		error("Failed to open right wheel frames video");
+}
+
+void AdjustWheels::preDestructor() {
+	_leftWheelFrames.close();
+	_rightWheelFrames.close();
+}
+
+int AdjustWheels::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	if (_staticData.navFrameIndex >= 0) {
+		const Graphics::Surface *leftFrame = _leftWheelFrames.getFrame(_curLeftFrame);
+		if (leftFrame)
+			_vm->_gfx->crossBlit(preBuffer, 0, 0, 208, 189, leftFrame, 0, 0);
+
+		const Graphics::Surface *rightFrame = _rightWheelFrames.getFrame(_curRightFrame);
+		if (rightFrame)
+			_vm->_gfx->crossBlit(preBuffer, 208, 0, 224, 189, rightFrame, 0, 0);
+	}
+
+	return SC_REPAINT;
+}
+
+int AdjustWheels::gdiPaint(Window *viewWindow) {
+	if (_translateText && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(168, 70, 262, 108);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int AdjustWheels::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// TODO: Wait between frames after figuring out timing
+
+	if (_leftUpRegion.contains(pointLocation) || _leftDownRegion.contains(pointLocation) ||
+			_rightUpRegion.contains(pointLocation) || _rightDownRegion.contains(pointLocation)) {
+		if (_leftDownRegion.contains(pointLocation)) {
+			// Move the wheel one frame and redraw
+			_curLeftFrame++;
+
+			if (_curLeftFrame > _leftWheelFrames.getFrameCount() - 1)
+				_curLeftFrame = 0;
+
+			viewWindow->invalidateWindow(false);
+
+			// And again for the final frame
+			_curLeftFrame++;
+
+			if (_curLeftFrame > _leftWheelFrames.getFrameCount() - 1)
+				_curLeftFrame = 0;
+
+			viewWindow->invalidateWindow(false);
+		} else if (_leftUpRegion.contains(pointLocation)) {
+			// Move the wheel one frame and redraw
+			_curLeftFrame--;
+
+			if (_curLeftFrame < 0)
+				_curLeftFrame = _leftWheelFrames.getFrameCount() - 1;
+
+			viewWindow->invalidateWindow(false);
+
+			// And again for the final frame
+			_curLeftFrame--;
+
+			if (_curLeftFrame < 0)
+				_curLeftFrame = _leftWheelFrames.getFrameCount() - 1;
+
+			viewWindow->invalidateWindow(false);
+		} else if (_rightDownRegion.contains(pointLocation)) {
+			// Move the wheel one frame and redraw
+			_curRightFrame++;
+
+			if (_curRightFrame > _rightWheelFrames.getFrameCount() - 1)
+				_curRightFrame = 0;
+
+			viewWindow->invalidateWindow(false);
+
+			// And again for the final frame
+			_curRightFrame++;
+
+			if (_curRightFrame > _rightWheelFrames.getFrameCount() - 1)
+				_curRightFrame = 0;
+
+			viewWindow->invalidateWindow(false);
+		} else if (_rightUpRegion.contains(pointLocation)) {
+			// Move the wheel one frame and redraw
+			_curRightFrame--;
+
+			if (_curRightFrame < 0)
+				_curRightFrame = _rightWheelFrames.getFrameCount() - 1;
+
+			viewWindow->invalidateWindow(false);
+
+			// And again for the final frame
+			_curRightFrame--;
+
+			if (_curRightFrame < 0)
+				_curRightFrame = _rightWheelFrames.getFrameCount() - 1;
+
+			viewWindow->invalidateWindow(false);
+		}
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelLeftIndex = _curLeftFrame;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelRightIndex = _curRightFrame;
+
+		byte status = 0;
+		if (_curLeftFrame == 8 && _curRightFrame == 12)
+			status = 1;
+		else if (_curLeftFrame == 16 && _curRightFrame == 22)
+			status = 1;
+		else if (_curLeftFrame == 20 && _curRightFrame == 4)
+			status = 1;
+		else if (_curLeftFrame == 0 && _curRightFrame == 24)
+			status = 1;
+		else if (_curLeftFrame == 14 && _curRightFrame == 8)
+			status = 1;
+		else if (_curLeftFrame == 6 && _curRightFrame == 6)
+			status = 1;
+		else if (_curLeftFrame == 6 && _curRightFrame == 30)
+			status = 1;
+		else if (_curLeftFrame == 24 && _curRightFrame == 0)
+			status = 1;
+		else if (_curLeftFrame == 10 && _curRightFrame == 28)
+			status = 1;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelStatus = status;
+
+		return SC_TRUE;
+	}
+
+	// Did not click on the wheels, pop back to depth 0
+	DestinationScene newDest;
+	newDest.destinationScene = _staticData.location;
+	newDest.destinationScene.depth = 0;
+	newDest.transitionType = TRANSITION_NONE;
+	newDest.transitionData = -1;
+	newDest.transitionStartFrame = -1;
+	newDest.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
+	return SC_TRUE;
+}
+
+int AdjustWheels::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect translateTextRegion(168, 72, 260, 106);
+
+		if (translateTextRegion.contains(pointLocation)) {
+			if (!_translateText) {
+				Common::String leftText = _vm->getString(IDMYTP_WHEELS_LEFT_TRANS_TEXT_BASE + _curLeftFrame / 2);
+				Common::String rightText = _vm->getString(IDMYTP_WHEELS_RIGHT_TRANS_TEXT_BASE + _curRightFrame / 2);
+				Common::String finalString = leftText + rightText;
+
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 &&
+						((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelStatus == 1) {
+
+					if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+						finalString += _vm->getString(IDS_MYTP_WALKTHROUGH_HINT_TEXT);
+					else
+						finalString += " (Mayan Sacred Day)";
+				}
+
+				((SceneViewWindow *)viewWindow)->displayTranslationText(finalString);
+				_translateText = true;
+				viewWindow->invalidateWindow(false);
+			}
+		} else {
+			if (_translateText) {
+				_translateText = false;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int AdjustWheels::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_leftUpRegion.contains(pointLocation) || _rightUpRegion.contains(pointLocation))
+		return kCursorArrowUp;
+
+	if (_leftDownRegion.contains(pointLocation) || _rightDownRegion.contains(pointLocation))
+		return kCursorArrowDown;
+
+	return kCursorPutDown;
+}
+
 class DateCombinationRead : public SceneBase {
 public:
 	DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -344,6 +571,10 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 60, 134, 118, 180, kItemCeramicBowl, 96, offsetof(GlobalFlags, myPickedUpCeramicBowl));
 	case 3:
 		return new PlaceCeramicBowl(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 4:
+		return new ClickChangeDepth(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorMagnifyingGlass, 0, 0, 432, 189);
+	case 5:
+		return new AdjustWheels(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 6:
 		return new DateCombinationRead(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 7:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 88dd3c6da2..09433b0016 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -382,6 +382,36 @@ int VideoDeath::postExitRoom(Window *viewWindow, const Location &newLocation) {
 	return SC_TRUE;
 }
 
+ClickChangeDepth::ClickChangeDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int newDepth, int cursorID, int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_newDepth = newDepth;
+	_cursorID = cursorID;
+	_clickableRegion = Common::Rect(left, top, right, bottom);
+}
+
+int ClickChangeDepth::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableRegion.contains(pointLocation)) {
+		DestinationScene clickDestination;
+		clickDestination.destinationScene = _staticData.location;
+		clickDestination.destinationScene.depth = _newDepth;
+		clickDestination.transitionType = TRANSITION_FADE;
+		clickDestination.transitionData = -1;
+		clickDestination.transitionStartFrame = -1;
+		clickDestination.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(clickDestination);
+	}
+
+	return SC_TRUE;
+}
+
+int ClickChangeDepth::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 ClickPlaySoundSynchronous::ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int flagOffset, int soundID, int cursorID, int left, int top, int right, int bottom) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index c0b31f0342..6e1b81d798 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -179,6 +179,19 @@ private:
 	int _messageTextID;
 };
 
+class ClickChangeDepth : public SceneBase {
+public:
+	ClickChangeDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int newDepth = 0, int cursorID = 0, int left = -1, int top = -1, int right = -1, int bottom = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _newDepth;
+	int _cursorID;
+	Common::Rect _clickableRegion;
+};
+
 class ClickPlaySoundSynchronous : public SceneBase {
 public:
 	ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 5eb0f04ccd..1c34929d2e 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -363,6 +363,7 @@ namespace Buried {
 #define IDS_DEATH_FINAL_SCORE_TEMPL     9035
 
 // 1.04+:
+#define IDS_MYTP_WALKTHROUGH_HINT_TEXT  9080
 #define IDS_PLAY_MODE_WALKTHROUGH_TEXT  9085
 #define IDS_PLAY_MODE_NORMAL_TEXT       9086
 #define IDS_OLD_APT_RECALL_MESSAGE      9088


Commit: e593a6a3bb7860c8310a367f9ac473d21961a1ca
    https://github.com/scummvm/scummvm/commit/e593a6a3bb7860c8310a367f9ac473d21961a1ca
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement basic save/load support through the GMM

In-game save/load buttons don't work yet

Changed paths:
  A engines/buried/saveload.cpp
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/detection.cpp
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h
    engines/buried/inventory_window.h
    engines/buried/module.mk
    engines/buried/scene_view.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 18941d19f2..fadef031a4 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -28,8 +28,10 @@
 #include "common/error.h"
 #include "common/events.h"
 #include "common/fs.h"
+#include "common/savefile.h"
 #include "common/system.h"
 #include "common/textconsole.h"
+#include "common/translation.h"
 #include "engines/util.h"
 
 #include "buried/buried.h"
@@ -117,7 +119,16 @@ Common::Error BuriedEngine::run() {
 		((FrameWindow *)_mainWindow)->showTitleSequence();
 		((FrameWindow *)_mainWindow)->showMainMenu();
 	} else {
-		((FrameWindow *)_mainWindow)->showClosingScreen();
+		bool doIntro = true;
+
+		if (ConfMan.hasKey("save_slot")) {
+			uint32 gameToLoad = ConfMan.getInt("save_slot");
+			doIntro = (loadGameState(gameToLoad).getCode() != Common::kNoError);
+		}
+
+		// Play the intro only if we're starting from scratch
+		if (doIntro)
+			((FrameWindow *)_mainWindow)->showClosingScreen();
 	}
 
 	while (!shouldQuit()) {
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 6a9dffb27f..e9a848d8b4 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -27,6 +27,7 @@
 #include "common/array.h"
 #include "common/list.h"
 #include "common/hashmap.h"
+#include "common/str-array.h"
 
 #include "engines/engine.h"
 
@@ -34,6 +35,8 @@ class OSystem;
 
 namespace Common {
 class SeekableReadStream;
+class Serializer;
+class WriteStream;
 }
 
 namespace Buried {
@@ -41,7 +44,9 @@ namespace Buried {
 class BuriedConsole;
 struct BuriedGameDescription;
 class Database;
+struct GlobalFlags;
 class GraphicsManager;
+struct Location;
 class Message;
 class SoundManager;
 class Window;
@@ -120,6 +125,15 @@ public:
 	void setTransitionSpeed(int newSpeed);
 	void releaseCapture() { _captureWindow = 0; }
 
+	// Save/Load
+	bool canLoadGameStateCurrently();
+	bool canSaveGameStateCurrently();
+	Common::Error loadGameState(int slot);
+	Common::Error saveGameState(int slot, const Common::String &desc);
+	static Common::StringArray listSaveFiles();
+	bool loadState(Common::SeekableReadStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems);
+	bool saveState(Common::WriteStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems);
+
 private:
 	Database *_library;
 
@@ -145,6 +159,10 @@ private:
 	typedef Common::List<MessageInfo> MessageQueue;
 	MessageQueue _messageQueue;
 	void pollForEvents();
+
+	// Saves
+	bool syncLocation(Common::Serializer &s, Location &location);
+	bool syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags);
 };
 
 // Macro for creating a version field
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index f92a721058..7b13592781 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -26,6 +26,7 @@
 #include "common/config-manager.h"
 #include "common/file.h"
 #include "common/savefile.h"
+#include "common/system.h"
 
 #include "buried/buried.h"
 
@@ -43,7 +44,9 @@ enum {
 
 bool BuriedEngine::hasFeature(EngineFeature f) const {
 	return
-		(f == kSupportsRTL);
+		(f == kSupportsRTL)
+		|| (f == kSupportsLoadingDuringRuntime)
+		|| (f == kSupportsSavingDuringRuntime);
 }
 
 bool BuriedEngine::isDemo() const {
@@ -282,7 +285,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformWindows,
 			ADGF_DEMO,
-			GUIO0()
+			GUIO1(GUIO_NOLAUNCHLOAD)
 		},
 	},
 
@@ -295,7 +298,7 @@ static const BuriedGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformWindows,
 			ADGF_DEMO | GF_TRUECOLOR,
-			GUIO0()
+			GUIO1(GUIO_NOLAUNCHLOAD)
 		},
 	},
 
@@ -328,9 +331,45 @@ public:
 		return "The Journeyman Project 2: Buried in Time (C) Presto Studios";
 	}
 
+	virtual bool hasFeature(MetaEngineFeature f) const;
 	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual SaveStateList listSaves(const char *target) const;
+	virtual int getMaximumSaveSlot() const { return 999; }
+	virtual void removeSaveState(const char *target, int slot) const;
 };
 
+bool BuriedMetaEngine::hasFeature(MetaEngineFeature f) const {
+	return
+		(f == kSupportsListSaves)
+		|| (f == kSupportsLoadingDuringStartup)
+		|| (f == kSupportsDeleteSave);
+}
+
+SaveStateList BuriedMetaEngine::listSaves(const char *target) const {
+	// The original had no pattern, so the user must rename theirs
+	// Note that we ignore the target because saves are compatible between
+	// all versions
+	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
+
+	SaveStateList saveList;
+	for (uint32 i = 0; i < fileNames.size(); i++) {
+		// Isolate the description from the file name
+		Common::String desc = fileNames[i].c_str() + 7;
+		for (int j = 0; j < 4; j++)
+			desc.deleteLastChar();
+
+		saveList.push_back(SaveStateDescriptor(i, desc));
+	}
+
+	return saveList;
+}
+
+void BuriedMetaEngine::removeSaveState(const char *target, int slot) const {
+	// See listSaves() for info on the pattern
+	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
+	g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str());
+}
+
 bool BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
 	const Buried::BuriedGameDescription *gd = (const Buried::BuriedGameDescription *)desc;
 
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 110273ec89..2ebe138fac 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -35,6 +35,7 @@
 #include "buried/frame_window.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
+#include "buried/inventory_window.h"
 #include "buried/main_menu.h"
 #include "buried/message.h"
 #include "buried/overview.h"
@@ -389,4 +390,27 @@ void FrameWindow::setTransitionSpeed(int newSpeed) {
 	ConfMan.setInt(_vm->isDemo() ? "TransitionSpeed" : _vm->getString(IDS_INI_KEY_TRANS_SPEED), newSpeed);
 }
 
+void FrameWindow::loadFromState(const Location &location, const GlobalFlags &flags, const Common::Array<int> &inventoryItems) {
+	if (!_gameInProgress) {
+		// Make the game in progress
+		_atMainMenu = false;
+		_gameInProgress = true;
+		delete _mainChildWindow;
+		_mainChildWindow = new GameUIWindow(_vm, this);
+		_mainChildWindow->showWindow(kWindowShow);
+	}
+
+	GameUIWindow *gameUI = (GameUIWindow *)_mainChildWindow;
+
+	// Set the flags
+	gameUI->_sceneViewWindow->getGlobalFlags() = flags;
+
+	// Set the inventory array
+	gameUI->_inventoryWindow->setItemArray(inventoryItems);
+	gameUI->_inventoryWindow->rebuildPreBuffer();
+	gameUI->_inventoryWindow->invalidateWindow(false);
+
+	gameUI->startNewGame(location);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index c8ec5fbcf2..db3798c7ca 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -68,6 +68,10 @@ public:
 
 	bool _reviewerMode;
 
+	bool isGameInProgress() const { return _gameInProgress; }
+	Window *getMainChildWindow() const { return _mainChildWindow; }
+	void loadFromState(const Location &location, const GlobalFlags &flags, const Common::Array<int> &inventoryItems);
+
 private:
 	Window *_mainChildWindow;
 	bool _controlDown;
diff --git a/engines/buried/inventory_window.h b/engines/buried/inventory_window.h
index 2b708402a7..eca429d66f 100644
--- a/engines/buried/inventory_window.h
+++ b/engines/buried/inventory_window.h
@@ -58,8 +58,8 @@ public:
 	InventoryElement getItemStaticData(int itemID);
 	int getItemCount() { return _itemArray.size(); }
 	int getItemID(int itemIndex) { return _itemArray[itemIndex]; }
-	// getItemArray
-	// setItemArray
+	void setItemArray(const Common::Array<int> &array) { _itemArray = array; }
+	Common::Array<int> &getItemArray() { return _itemArray; }
 
 	bool destroyInfoWindow();
 	InventoryInfoWindow *getInfoWindow() { return _infoWindow; }
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index f23c3d3020..9024b643fd 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -20,6 +20,7 @@ MODULE_OBJS = \
 	main_menu.o \
 	navarrow.o \
 	overview.o \
+	saveload.o \
 	scene_view.o \
 	sound.o \
 	title_sequence.o \
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
new file mode 100644
index 0000000000..4e95ba81b8
--- /dev/null
+++ b/engines/buried/saveload.cpp
@@ -0,0 +1,500 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/error.h"
+#include "common/savefile.h"
+#include "common/serializer.h"
+#include "common/system.h"
+#include "common/translation.h"
+
+#include "buried/buried.h"
+#include "buried/frame_window.h"
+#include "buried/gameui.h"
+#include "buried/global_flags.h"
+#include "buried/inventory_window.h"
+#include "buried/navdata.h"
+#include "buried/scene_view.h"
+
+namespace Buried {
+
+Common::StringArray BuriedEngine::listSaveFiles() {
+	Common::StringArray fileNames = g_system->getSavefileManager()->listSavefiles("buried-*.sav");
+	Common::sort(fileNames.begin(), fileNames.end());
+	return fileNames;
+}
+
+bool BuriedEngine::canLoadGameStateCurrently() {
+	// TODO: This probably needs to be more strict
+	return !isDemo() && _mainWindow;
+}
+
+bool BuriedEngine::canSaveGameStateCurrently() {
+	// TODO: This should be OK, except possibly synchronous video saving may give
+	// weird results. Need to investigate.
+	return !isDemo() && _mainWindow && ((FrameWindow *)_mainWindow)->isGameInProgress();
+}
+
+Common::Error BuriedEngine::loadGameState(int slot) {
+	Common::StringArray fileNames = listSaveFiles();
+	Common::InSaveFile *loadFile = _saveFileMan->openForLoading(fileNames[slot]);
+	if (!loadFile)
+		return Common::kUnknownError;	
+
+	Location location;
+	GlobalFlags flags;
+	Common::Array<int> inventoryItems;
+	if (!loadState(loadFile, location, flags, inventoryItems)) {
+		delete loadFile;
+		return Common::kUnknownError;
+	}
+
+	((FrameWindow *)_mainWindow)->loadFromState(location, flags, inventoryItems);
+	delete loadFile;
+	return Common::kNoError;
+}
+
+static bool isValidSaveFileChar(char c) {
+	// Limit it to letters, digits, and a few other characters that should be safe
+	return Common::isAlnum(c) || c == ' ' || c == '_' || c == '+' || c == '-' || c == '.';
+}
+
+static bool isValidSaveFileName(const Common::String &desc) {
+	for (uint32 i = 0; i < desc.size(); i++)
+		if (!isValidSaveFileChar(desc[i]))
+			return false;
+
+	return true;
+}
+
+Common::Error BuriedEngine::saveGameState(int slot, const Common::String &desc) {
+	if (!isValidSaveFileName(desc))
+		return Common::Error(Common::kCreatingFileFailed, _("Invalid save file name"));
+
+	Common::String output = Common::String::format("buried-%s.sav", desc.c_str());
+	Common::OutSaveFile *saveFile = _saveFileMan->openForSaving(output, false);
+	if (!saveFile)
+		return Common::kUnknownError;
+
+	GameUIWindow *gameUI = (GameUIWindow *)((FrameWindow *)_mainWindow)->getMainChildWindow();
+
+	Location location;
+	gameUI->_sceneViewWindow->getCurrentSceneLocation(location);
+	GlobalFlags &flags = gameUI->_sceneViewWindow->getGlobalFlags();
+	Common::Array<int> &inventoryItems = gameUI->_inventoryWindow->getItemArray();
+
+	if (!saveState(saveFile, location, flags, inventoryItems)) {
+		delete saveFile;
+		return Common::kUnknownError;
+	}
+
+	delete saveFile;
+	return Common::kNoError;
+}
+
+enum {
+	kSavedGameHeaderSize = 9,
+	kSavedGameHeaderSizeAlt = 7
+};
+
+static const byte s_savedGameHeader[kSavedGameHeaderSize] = { 'B', 'I', 'T', 'M', 'P', 'C', 0, 5, 0 };
+
+bool BuriedEngine::loadState(Common::SeekableReadStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems) {
+	byte header[9];
+	saveFile->read(header, kSavedGameHeaderSize);
+
+	// Only compare the first 6 bytes
+	// Win95 version of the game output garbage as the last two bytes
+	if (saveFile->eos() || memcmp(header, s_savedGameHeader, kSavedGameHeaderSizeAlt) != 0)
+		return false;
+
+	Common::Serializer s(saveFile, 0);
+
+	if (!syncLocation(s, location))
+		return false;
+
+	if (saveFile->eos())
+		return false;
+
+	if (!syncGlobalFlags(s, flags))
+		return false;
+
+	if (saveFile->eos())
+		return false;
+
+	uint16 itemCount = saveFile->readUint16LE();
+
+	if (saveFile->eos())
+		return false;
+
+	inventoryItems.clear();
+	for (uint16 i = 0; i < itemCount; i++)
+		inventoryItems.push_back(saveFile->readUint16LE());
+
+	return !saveFile->eos();
+}
+
+bool BuriedEngine::saveState(Common::WriteStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems) {
+	saveFile->write(s_savedGameHeader, kSavedGameHeaderSize);
+
+	Common::Serializer s(0, saveFile);
+
+	if (!syncLocation(s, location))
+		return false;
+
+	if (!syncGlobalFlags(s, flags))
+		return false;
+
+	saveFile->writeUint16LE(inventoryItems.size());
+
+	for (uint16 i = 0; i < inventoryItems.size(); i++)
+		saveFile->writeUint16LE(inventoryItems[i]);
+
+	// Fill in remaining items with all zeroes
+	uint16 fillItems = 50 - inventoryItems.size();
+	while (fillItems--)
+		saveFile->writeUint16LE(0);
+
+	return true;
+}
+
+// Since we can't take the address of a uint16 or uint32 from
+// the packed GlobalFlags struct, we need to work around
+// it this way.
+
+#define SYNC_FLAG_UINT16(x) \
+	do { \
+		if (s.isSaving()) { \
+			uint16 value = flags.x; \
+			s.syncAsUint16LE(value); \
+		} else { \
+			uint16 value; \
+			s.syncAsUint16LE(value); \
+			flags.x = value; \
+		} \
+	} while (0)
+
+#define SYNC_FLAG_UINT32(x) \
+	do { \
+		if (s.isSaving()) { \
+			uint32 value = flags.x; \
+			s.syncAsUint32LE(value); \
+		} else { \
+			uint32 value; \
+			s.syncAsUint32LE(value); \
+			flags.x = value; \
+		} \
+	} while (0)
+
+bool BuriedEngine::syncLocation(Common::Serializer &s, Location &location) {
+	s.syncAsSint16LE(location.timeZone);
+	s.syncAsSint16LE(location.environment);
+	s.syncAsSint16LE(location.node);
+	s.syncAsSint16LE(location.facing);
+	s.syncAsSint16LE(location.orientation);
+	s.syncAsSint16LE(location.depth);
+	return s.bytesSynced() == 12;
+} 
+
+bool BuriedEngine::syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags) {
+	uint32 startBytes = s.bytesSynced();
+
+	s.syncAsByte(flags.cgWallExploded);
+	s.syncAsByte(flags.cgHookPresent);
+	s.syncAsByte(flags.cgArrowPresent);
+	s.syncAsByte(flags.cgHammerPresent);
+	s.syncAsByte(flags.cgSmithyStatus);
+	s.syncAsByte(flags.cgSmithyGuard);
+	s.syncAsByte(flags.cgBaileyOneWayGuard);
+	s.syncAsByte(flags.cgBaileyTwoWayGuards);
+	s.syncAsByte(flags.cgTapestryFlag);
+	s.syncAsByte(flags.cgBurnedLetterPresent);
+	s.syncAsByte(flags.cgGoldCoinsPresent);
+	s.syncAsByte(flags.cgStorageRoomVisit);
+	s.syncAsByte(flags.bcTranslateEnabled);
+	s.syncAsByte(flags.bcCloakingEnabled);
+	s.syncAsByte(flags.bcLocateEnabled);
+	s.syncAsByte(flags.myPickedUpCeramicBowl);
+	s.syncAsByte(flags.myTPCodeWheelStatus);
+	s.syncAsByte(flags.myTPCodeWheelLeftIndex);
+	s.syncAsByte(flags.myTPCodeWheelRightIndex);
+	s.syncAsByte(flags.myMCPickedUpSkull);
+	s.syncAsByte(flags.myMCDeathGodOfferings);
+	s.syncAsByte(flags.myWGPlacedRope);
+	s.syncAsByte(flags.myWGRetrievedJadeBlock);
+	s.syncAsByte(flags.myWTRetrievedLimestoneBlock);
+	s.syncAsByte(flags.myWTCurrentBridgeStatus);
+	s.syncAsByte(flags.myAGRetrievedEntrySkull);
+	s.syncAsByte(flags.myAGRetrievedSpearSkull);
+	s.syncAsByte(flags.myAGRetrievedCopperMedal);
+	s.syncAsByte(flags.myAGRetrievedObsidianBlock);
+	s.syncAsByte(flags.myAGHeadAStatus);
+	s.syncAsByte(flags.myAGHeadBStatus);
+	s.syncAsByte(flags.myAGHeadCStatus);
+	s.syncAsByte(flags.myAGHeadDStatus);
+	s.syncAsByte(flags.myAGHeadAStatusSkullID);
+	s.syncAsByte(flags.myAGHeadBStatusSkullID);
+	s.syncAsByte(flags.myAGHeadCStatusSkullID);
+	s.syncAsByte(flags.myAGHeadDStatusSkullID);
+	s.syncAsByte(flags.myAGTimerHeadID);
+	SYNC_FLAG_UINT32(myAGTimerStartTime);
+	s.syncAsByte(flags.myDGOfferedHeart);
+	s.syncAsByte(flags.takenEnvironCart);
+	s.syncAsByte(flags.alRDTakenLiveCore);
+	s.syncAsByte(flags.alRDTakenDeadCore);
+	s.syncAsByte(flags.alNMWrongAlienPrefixCode);
+	s.syncAsByte(flags.faKIOvenStatus);
+	s.syncAsByte(flags.faKIPostBoxSlotA);
+	s.syncAsByte(flags.faKIPostBoxSlotB);
+	s.syncAsByte(flags.faKIPostBoxSlotC);
+	s.syncAsByte(flags.faERCurrentCartridge);
+	s.syncAsByte(flags.faERTakenRemoteControl);
+	s.syncAsByte(flags.myMCStingerID);
+	s.syncAsByte(flags.myMCStingerChannelID);
+	s.syncAsByte(flags.faStingerID);
+	s.syncAsByte(flags.faStingerChannelID);
+	s.syncBytes(flags.unused0, sizeof(flags.unused0));
+	SYNC_FLAG_UINT32(cgMWCatapultData);
+	SYNC_FLAG_UINT32(cgMWCatapultOffset);
+	s.syncAsByte(flags.cgTSTriedDoor);
+	s.syncAsByte(flags.cgMBCrossedMoat);
+	s.syncAsByte(flags.cgKSSmithyEntryRead);
+	s.syncAsByte(flags.cgKSSmithyEntryTranslated);
+	s.syncAsByte(flags.cgBSFoundMold);
+	s.syncAsByte(flags.readBurnedLetter);
+	s.syncAsByte(flags.evcapNumCaptured);
+	s.syncBytes(flags.evcapBaseID, sizeof(flags.evcapBaseID));
+	s.syncBytes(flags.unused1, sizeof(flags.unused1));
+	s.syncAsByte(flags.faMNEnvironDoor);
+	s.syncAsByte(flags.faMNClockClicked);
+	s.syncAsByte(flags.faMNBooksClicked);
+	s.syncAsByte(flags.faMNTazClicked);
+	s.syncAsByte(flags.faMNPongClicked);
+	s.syncAsByte(flags.faKIBirdsBobbed);
+	s.syncAsByte(flags.faKICoffeeSpilled);
+	s.syncAsByte(flags.cgViewedKeepPlans);
+	s.syncAsByte(flags.cgFoundChestPanel);
+	s.syncAsByte(flags.cgTRFoundSword);
+	s.syncAsByte(flags.faHeardAgentFigure);
+	s.syncAsByte(flags.jumpBCNoInfoMessageCycle);
+	s.syncAsByte(flags.myTPCalendarTopTranslated);
+	s.syncAsByte(flags.myTPCalendarListTranslated);
+	s.syncAsByte(flags.myTPTextTranslated);
+	s.syncAsByte(flags.myMCTransDoor);
+	s.syncAsByte(flags.myMCTransAGOffering);
+	s.syncAsByte(flags.myMCTransWGOffering);
+	s.syncAsByte(flags.myMCTransWTOffering);
+	s.syncAsByte(flags.myMCTransDGOffering);
+	s.syncAsByte(flags.myMCTransMadeAnOffering);
+	s.syncAsByte(flags.myWGTransDoorTop);
+	s.syncAsByte(flags.myWGSeenLowerPassage);
+	s.syncAsByte(flags.myWGCrossedRopeBridge);
+	s.syncAsByte(flags.myWMCViewedDeathGodDoor);
+	s.syncAsByte(flags.myTPTransBreathOfItzamna);
+	SYNC_FLAG_UINT32(myAGHeadAOpenedTime);
+	SYNC_FLAG_UINT32(myAGHeadBOpenedTime);
+	SYNC_FLAG_UINT32(myAGHeadCOpenedTime);
+	SYNC_FLAG_UINT32(myAGHeadDOpenedTime);
+	s.syncAsByte(flags.myAGHeadATouched);
+	s.syncAsByte(flags.myAGHeadBTouched);
+	s.syncAsByte(flags.myAGHeadCTouched);
+	s.syncAsByte(flags.myAGHeadDTouched);
+	s.syncAsByte(flags.lensFilterActivated);
+	s.syncAsByte(flags.dsPTElevatorPresent);
+	s.syncAsByte(flags.dsPTElevatorLeverA);
+	s.syncAsByte(flags.dsPTElevatorLeverB);
+	s.syncAsByte(flags.dsPTDoorLocked);
+	s.syncAsByte(flags.dsWSPickedUpWheelAssembly);
+	s.syncAsByte(flags.dsWSPickedUpGearAssembly);
+	s.syncAsByte(flags.dsWSPickedUpPegs);
+	s.syncAsByte(flags.dsWSSiegeCycleStatus);
+	s.syncAsByte(flags.dsWSGrabbedSiegeCycle);
+	s.syncAsByte(flags.dsPTUseElevatorControls);
+	s.syncAsByte(flags.dsPTTransElevatorControls);
+	s.syncAsByte(flags.dsGDTakenCoilOfRope);
+	s.syncAsByte(flags.dsCTUnlockedDoor);
+	s.syncAsByte(flags.dsCTViewedAgent3);
+	s.syncAsByte(flags.dsPTViewedAgent3);
+	s.syncAsByte(flags.dsCTRetrievedLens);
+	s.syncAsByte(flags.dsCTTakenHeart);
+	s.syncAsByte(flags.dsCYFiredCannon);
+	s.syncAsByte(flags.dsCYBallistaStatus);
+	s.syncAsByte(flags.dsCYPlacedSiegeCycle);
+	s.syncAsByte(flags.dsCYBallistaXPos);
+	s.syncAsByte(flags.dsCYBallistaYPos);
+	s.syncAsByte(flags.aiHWStingerID);
+	s.syncAsByte(flags.aiHWStingerChannelID);
+	s.syncAsByte(flags.aiCRStingerID);
+	s.syncAsByte(flags.aiCRStingerChannelID);
+	s.syncAsByte(flags.aiDBStingerID);
+	s.syncAsByte(flags.aiDBStingerChannelID);
+	s.syncAsByte(flags.aiCRGrabbedMetalBar);
+	s.syncAsByte(flags.aiICGrabbedWaterCanister);
+	s.syncAsByte(flags.aiOxygenTimer);
+	s.syncAsByte(flags.aiCRPressurized);
+	s.syncAsByte(flags.aiCRPressurizedAttempted);
+	s.syncAsByte(flags.aiMRPressurized);
+	s.syncAsByte(flags.aiIceMined);
+	s.syncAsByte(flags.aiOxygenReserves);
+	s.syncAsByte(flags.aiSCHeardInitialSpeech);
+	s.syncAsByte(flags.aiSCInitialAudioChannel);
+	s.syncAsByte(flags.aiSCDBDoorWarning);
+	s.syncAsByte(flags.aiSCMoveCenterWarning);
+	s.syncAsByte(flags.aiSCConversationStatus);
+	s.syncAsByte(flags.aiHWIceDoorUnlocked);
+	s.syncAsByte(flags.aiICWaterInFillHandle);
+	s.syncAsByte(flags.aiICTakenWaterCanister);
+	s.syncAsByte(flags.aiSWStingerID);
+	s.syncAsByte(flags.aiSWStingerChannelID);
+	s.syncAsByte(flags.aiMRCorrectFreqSet);
+	s.syncAsByte(flags.aiSCHeardNexusDoorComment);
+	s.syncAsByte(flags.aiSCHeardNexusDoorCode);
+	s.syncAsByte(flags.asInitialGuardsPass);
+	s.syncAsByte(flags.asRBPodAStatus);
+	s.syncAsByte(flags.asRBPodBStatus);
+	s.syncAsByte(flags.asRBPodCStatus);
+	s.syncAsByte(flags.asRBPodDStatus);
+	s.syncAsByte(flags.asRBPodEStatus);
+	s.syncAsByte(flags.asRBPodFStatus);
+	s.syncAsByte(flags.asRBPodATakenEnvironCart);
+	s.syncAsByte(flags.asRBPodBTakenPuzzleBox);
+	s.syncAsByte(flags.asRBPodCTakenCodex);
+	s.syncAsByte(flags.asRBPodDTakenSculpture);
+	s.syncAsByte(flags.asRBPodETakenSword);
+	s.syncAsByte(flags.asTakenEvidenceThisTrip);
+	s.syncAsByte(flags.asDangerDoorASealed);
+	s.syncAsByte(flags.asDoorBGuardsSeen);
+	s.syncAsByte(flags.asAmbassadorEncounter);
+	s.syncAsByte(flags.dsCTTriedLockedDoor);
+	s.syncAsByte(flags.dsCTCodexTranslateAttempted);
+	s.syncAsByte(flags.dsCTCodexFormulaeFound);
+	s.syncAsByte(flags.dsCTCodexAtlanticusPage2);
+	s.syncAsByte(flags.dsCTTriedElevatorControls);
+	s.syncAsByte(flags.aiDBPlayedMomComment);
+	s.syncAsByte(flags.aiDBPlayedFirstArthur);
+	s.syncAsByte(flags.aiDBPlayedSecondArthur);
+	s.syncAsByte(flags.aiDBPlayedThirdArthur);
+	s.syncAsByte(flags.aiDBPlayedFourthArthur);
+	s.syncAsByte(flags.aiSCPlayedNoStinger);
+	s.syncAsByte(flags.faKITakenPostboxItem);
+	s.syncAsByte(flags.cgMBVisited);
+	s.syncAsByte(flags.cgKCVisited);
+	s.syncAsByte(flags.cgTRVisited);
+	s.syncAsByte(flags.cgKSReadJournal);
+	s.syncAsByte(flags.cgSRClickedOnLockedChest);
+	s.syncAsByte(flags.cgSROpenedChest);
+	s.syncAsByte(flags.dsVisitedCodexTower);
+	s.syncAsByte(flags.dsPTRaisedPlatform);
+	s.syncAsByte(flags.dsPTWalkedDownElevator);
+	s.syncAsByte(flags.dsPTBeenOnBalcony);
+	s.syncAsByte(flags.dsGDClickedOnCodexDoor);
+	s.syncAsByte(flags.dsWSSeenCycleSketch);
+	s.syncAsByte(flags.dsWSSeenBallistaSketch);
+	s.syncAsByte(flags.genHadSiegeCycle);
+	s.syncAsByte(flags.genHadDriveAssembly);
+	s.syncAsByte(flags.genHadWheelAssembly);
+	s.syncAsByte(flags.dsCYNeverConnectedHook);
+	s.syncAsByte(flags.dsCYNeverShotBallista);
+	s.syncAsByte(flags.dsCYNeverUsedCrank);
+	s.syncAsByte(flags.dsCYNeverOpenedBalconyDoor);
+	s.syncAsByte(flags.dsCYTranslatedCodex);
+	s.syncAsByte(flags.dsCYTriedOpeningDoor);
+	s.syncAsByte(flags.dsCYTriedElevator);
+	s.syncAsByte(flags.dsCYFoundCodexes);
+	s.syncAsByte(flags.myVisitedMainCavern);
+	s.syncAsByte(flags.myVisitedArrowGod);
+	s.syncAsByte(flags.myVisitedWaterGod);
+	s.syncAsByte(flags.myVisitedWealthGod);
+	s.syncAsByte(flags.myVisitedDeathGod);
+	s.syncAsByte(flags.myVisitedSpecRooms);
+	s.syncAsByte(flags.myWTSteppedOnSwings);
+	s.syncAsByte(flags.myWTSteppedOnFarLedge);
+	s.syncAsByte(flags.myDGOpenedPuzzleBox);
+	s.syncAsByte(flags.myAGVisitedAltar);
+	s.syncAsByte(flags.dsCTPlayedBallistaFalling);
+	s.syncAsByte(flags.cgTSTriedDoorA);
+	s.syncAsByte(flags.cgTSTriedDoorB);
+	s.syncAsByte(flags.aiHWLastCommentPlayed);
+	s.syncAsByte(flags.aiNXPlayedBrainComment);
+	s.syncAsByte(flags.asRBLastStingerID);
+	s.syncAsByte(flags.asRBStingerID);
+	s.syncAsByte(flags.aiICProcessedOxygen);
+	s.syncAsByte(flags.dsCYWeeblieClicked);
+	s.syncAsByte(flags.aiICUsedMiningControls);
+	s.syncAsByte(flags.aiSWAttemptedPresMR);
+	s.syncAsByte(flags.aiICRefilledOxygen);
+	s.syncAsByte(flags.aiMRUsedHarmonicsInterface);
+	s.syncAsByte(flags.alRestoreSkipAgent3Initial);
+	s.syncBytes(flags.unused2, sizeof(flags.unused2));
+	s.syncAsByte(flags.scoreGotTranslateBioChip);
+	s.syncAsByte(flags.scoreEnteredSpaceStation);
+	s.syncAsByte(flags.scoreDownloadedArthur);
+	s.syncAsByte(flags.scoreFoundSculptureDiagram);
+	s.syncAsByte(flags.scoreEnteredKeep);
+	s.syncAsByte(flags.scoreGotKeyFromSmithy);
+	s.syncAsByte(flags.scoreEnteredTreasureRoom);
+	s.syncAsByte(flags.scoreFoundSwordDiamond);
+	s.syncAsByte(flags.scoreMadeSiegeCycle);
+	s.syncAsByte(flags.scoreEnteredCodexTower);
+	s.syncAsByte(flags.scoreLoggedCodexEvidence);
+	s.syncAsByte(flags.scoreEnteredMainCavern);
+	s.syncAsByte(flags.scoreGotWealthGodPiece);
+	s.syncAsByte(flags.scoreGotRainGodPiece);
+	s.syncAsByte(flags.scoreGotWarGodPiece);
+	s.syncAsByte(flags.scoreCompletedDeathGod);
+	s.syncAsByte(flags.scoreEliminatedAgent3);
+	s.syncAsByte(flags.scoreTransportToKrynn);
+	s.syncAsByte(flags.scoreGotKrynnArtifacts);
+	s.syncAsByte(flags.scoreDefeatedIcarus);
+	s.syncAsByte(flags.scoreResearchINNLouvreReport);
+	s.syncAsByte(flags.scoreResearchINNHighBidder);
+	s.syncAsByte(flags.scoreResearchINNAppeal);
+	s.syncAsByte(flags.scoreResearchINNUpdate);
+	s.syncAsByte(flags.scoreResearchINNJumpsuit);
+	s.syncAsByte(flags.scoreResearchBCJumpsuit);
+	s.syncAsByte(flags.scoreResearchMichelle);
+	s.syncAsByte(flags.scoreResearchMichelleBkg);
+	s.syncAsByte(flags.scoreResearchLensFilter);
+	s.syncAsByte(flags.scoreResearchCastleFootprint);
+	s.syncAsByte(flags.scoreResearchDaVinciFootprint);
+	s.syncAsByte(flags.scoreResearchMorphSculpture);
+	s.syncAsByte(flags.scoreResearchEnvironCart);
+	s.syncAsByte(flags.scoreResearchAgent3Note);
+	s.syncAsByte(flags.scoreResearchAgent3DaVinci);
+	SYNC_FLAG_UINT16(scoreHintsTotal);
+	s.syncBytes(flags.unused3, sizeof(flags.unused3));
+	s.syncAsByte(flags.genJumpCastleBriefing);
+	s.syncAsByte(flags.genJumpMayanBriefing);
+	s.syncAsByte(flags.genJumpDaVinciBriefing);
+	s.syncAsByte(flags.genJumpStationBriefing);
+	s.syncBytes(flags.unused4, sizeof(flags.unused4));
+	s.syncAsByte(flags.generalWalkthroughMode);
+	s.syncBytes(flags.unused5, sizeof(flags.unused5));
+	s.syncBytes(flags.aiData, sizeof(flags.aiData));
+
+	return s.bytesSynced() - startBytes == 1024;
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 554aadd45b..a79f95b17b 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -410,7 +410,79 @@ bool SceneViewWindow::jumpToScene(const Location &newLocation) {
 }
 
 bool SceneViewWindow::jumpToSceneRestore(const Location &newLocation) {
-	// TODO
+	Location oldLocation(-2, -2, -2, -2, -2, -2);
+	Location passedLocation(-2, -2, -2, -2, -2, -2);
+
+	if (_infoWindowDisplayed)
+		((GameUIWindow *)getParent())->_inventoryWindow->destroyInfoWindow();
+	if (_bioChipWindowDisplayed)
+		((GameUIWindow *)getParent())->_bioChipRightWindow->destroyBioChipViewWindow();
+	if (_burnedLetterDisplayed)
+		((GameUIWindow *)getParent())->_inventoryWindow->destroyBurnedLetterWindow();
+
+	// Get the static scene data for this new location
+	LocationStaticData newSceneStaticData;
+	if (!getSceneStaticData(newLocation, newSceneStaticData))
+		return false;
+	if (_currentScene)
+		oldLocation = _currentScene->_staticData.location;
+
+	// Clear the live text window
+	if (newLocation.timeZone != oldLocation.timeZone || newLocation.environment != oldLocation.environment)
+		((GameUIWindow *)getParent())->_liveTextWindow->updateLiveText("");
+
+	// If we have a scene, call the pre-transition function
+	if (_currentScene)
+		_currentScene->preExitRoom(this, passedLocation);
+
+	if (newLocation.timeZone != oldLocation.timeZone && newLocation.timeZone != -2)
+		initializeTimeZoneAndEnvironment(this, newLocation.timeZone, -1);
+	if (newLocation.timeZone != oldLocation.timeZone && newLocation.environment != -2)
+		initializeTimeZoneAndEnvironment(this, newLocation.timeZone, newLocation.environment);
+
+	// Create the new scene object
+	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, passedLocation);
+
+	// Call the post-transition function
+	if (_currentScene && _currentScene->postExitRoom(this, passedLocation) == SC_DEATH)
+		return false;
+
+	if (_currentScene) {
+		_currentScene->preDestructor();
+		delete _currentScene;
+		_currentScene = 0;
+	}
+
+	// Change the ambient music
+	if (newLocation.timeZone != oldLocation.timeZone || newLocation.environment != oldLocation.environment || oldLocation.timeZone < 0)
+		startEnvironmentAmbient(passedLocation.timeZone, passedLocation.environment, newLocation.timeZone, newLocation.environment);
+
+	_currentScene = newScene;
+
+	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+		flushCycleFrameCache();
+
+	if (_currentScene->preEnterRoom(this, passedLocation) == SC_END_PROCESSING)
+		return true;
+
+	if (_globalFlags.bcCloakingEnabled != 1)
+		((GameUIWindow *)getParent())->_navArrowWindow->updateAllArrows(newScene->_staticData);
+
+	if (newLocation.timeZone != oldLocation.timeZone)
+		((GameUIWindow *)getParent())->changeCurrentDate(newLocation.timeZone);
+
+	invalidateWindow(false);
+
+	_currentScene->postEnterRoom(this, passedLocation);
+	getParent()->invalidateWindow(false);
+
+	// Check AI database for a spontaneous comment
+	if (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+		playAIComment(newSceneStaticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+	// Notify biochip right window of change
+	((GameUIWindow *)getParent())->_bioChipRightWindow->sceneChanged();
+
 	return true;
 }
 


Commit: 912c673e34edac1be2cc0864b86aaf97b19bb13e
    https://github.com/scummvm/scummvm/commit/912c673e34edac1be2cc0864b86aaf97b19bb13e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the smithy bench

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/invdata.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 1df3d5833e..a0c12f15e1 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -312,6 +312,206 @@ int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class SmithyBench : public SceneBase {
+public:
+	SmithyBench(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	byte _status;
+	Common::Rect _pan;
+	Common::Rect _mold;
+	Common::Rect _bellows;
+
+	void resetBackgroundBitmap();
+};
+
+SmithyBench::SmithyBench(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_status = ((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus;
+	resetBackgroundBitmap();
+
+	_pan = Common::Rect(0, 73, 227, 123);
+	_mold = Common::Rect(333, 57, 423, 105);
+	_bellows = Common::Rect(0, 0, 302, 34);
+}
+
+int SmithyBench::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_pan.contains(pointLocation) && (_status == 2 || _status == 3)) {
+		_status %= 2;
+		resetBackgroundBitmap();
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+
+		Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemCopperMedallion, ptInventoryWindow);
+		return SC_TRUE;
+	} else if (_mold.contains(pointLocation) && _status == 6) {
+		_status = 1;
+		resetBackgroundBitmap();
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+
+		Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemCopperKey, ptInventoryWindow);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int SmithyBench::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_mold.contains(pointLocation) && _status < 6 && (!_vm->isDemo() || ((FrameWindow *)_vm->_mainWindow)->_reviewerMode)) {
+		if ((_status % 2) == 1) {
+			// Brick has been removed, so play the returning movie
+			_status--;
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_status + 8);
+			resetBackgroundBitmap();
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgBSFoundMold = 1;
+		} else {
+			// The brick is still covering the mold, so remove it
+			_status++;
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_status + 6);
+			resetBackgroundBitmap();
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+		}
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	} else if (_pan.contains(pointLocation) && _status == 5) {
+		_status = 6;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(13);
+		resetBackgroundBitmap();
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	} else if (_bellows.contains(pointLocation) && _status < 4) {
+		switch (_status) {
+		case 0:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+			break;
+		case 1:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
+			break;
+		case 2:
+			_status = 4;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(5);
+			resetBackgroundBitmap();
+			break;
+		case 3:
+			_status = 5;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
+			resetBackgroundBitmap();
+			break;
+		}
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int SmithyBench::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemCopperKey)
+		return 2; // Third dragging bitmap
+
+	return 0;
+}
+
+int SmithyBench::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (_pan.contains(pointLocation) && itemID == kItemCopperMedallion && _status < 2) {
+		// Did we drop the medallion in the pan?
+		_status += 2;
+		resetBackgroundBitmap();
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+		viewWindow->invalidateWindow();
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SIC_ACCEPT;
+	} else if (_mold.contains(pointLocation) && itemID == kItemCopperKey && _status == 1) {
+		// Did we drop the key?
+		_status = 6;
+		resetBackgroundBitmap();
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSmithyStatus = _status;
+		viewWindow->invalidateWindow();
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int SmithyBench::specifyCursor(Window *viewWindow, const Common::Point &pointLocation){
+	if (_bellows.contains(pointLocation) && _status < 4)
+		return kCursorFinger;
+
+	if (_mold.contains(pointLocation) && _status < 6 && (!_vm->isDemo() || ((FrameWindow *)_vm->_mainWindow)->_reviewerMode))
+		return kCursorFinger;
+
+	if (_pan.contains(pointLocation) && (_status == 2 || _status == 3))
+		return kCursorOpenHand;
+
+	if (_mold.contains(pointLocation) && _status == 6)
+		return kCursorOpenHand;
+
+	if (_pan.contains(pointLocation) && _status == 5)
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+void SmithyBench::resetBackgroundBitmap() {
+	switch (_status) {
+	case 0: // Nothing in with brick in place
+		_staticData.navFrameIndex = 52;
+		break;
+	case 1: // Nothing in with brick removed
+		_staticData.navFrameIndex = 53;
+		break;
+	case 2: // Unmelted medallion, brick -inplace
+		_staticData.navFrameIndex = 55;
+		break;
+	case 3: // Unmelted medallion, brick moved
+		_staticData.navFrameIndex = 57;
+		break;
+	case 4: // Melted medallion in with brick in place
+		_staticData.navFrameIndex = 56;
+		break;
+	case 5: // Melted medallion in with brick removed
+		_staticData.navFrameIndex = 58;
+		break;
+	case 6: // Poured key with brick removed
+		_staticData.navFrameIndex = 59;
+		break;
+	}
+}
+
 class MainWallCatapultService : public SceneBase {
 public:
 	MainWallCatapultService(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -601,6 +801,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 175, 64, 237, 126, kItemBurnedLetter, 84, offsetof(GlobalFlags, cgBurnedLetterPresent));
 	case 39:
 		return new StorageRoomDoor(_vm, viewWindow, sceneStaticData, priorLocation, 38, 0, 386, 189, 1, 9, 5, 2, 1, 1, offsetof(GlobalFlags, cgStorageRoomVisit), 11, 130, 12, 0);
+	case 42:
+		return new SmithyBench(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	case 48:
diff --git a/engines/buried/invdata.h b/engines/buried/invdata.h
index 87eff0d2ed..1a044db7fe 100644
--- a/engines/buried/invdata.h
+++ b/engines/buried/invdata.h
@@ -47,8 +47,8 @@ enum {
 	kItemCheeseGirl = 13,
 	kItemClassicGamesCart = 14, // Unused!
 	kItemCodexAtlanticus = 15,
-	kItemCoilOfRope = 15,
-	kItemCopperKey = 16,
+	kItemCoilOfRope = 16,
+	kItemCopperKey = 17,
 	kItemCopperMedallion = 18,
 	kItemCreditChip = 19, // Unused!
 	kItemEnvironCart = 20,


Commit: 01afc91cf47f7b5eb39ffbb87580efcf29265d4a
    https://github.com/scummvm/scummvm/commit/01afc91cf47f7b5eb39ffbb87580efcf29265d4a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement some more common scenes

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index a0c12f15e1..9075edb844 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -818,6 +818,12 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 60:
 		return new MainWallCatapultService(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 61:
+		return new SetFlagOnEntry(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgMBCrossedMoat), 1);
+	case 63:
+		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_FOOTPRINT, IDS_MBT_EVIDENCE_PRESENT);
+	case 64:
+		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_SWORD, IDS_MBT_EVIDENCE_PRESENT);
 	case 70:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12);
 	case 71:
@@ -828,6 +834,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 0, 0, 270, 189);
 	case 74:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 76:
+		return new SetFlagOnEntry(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgSROpenedChest), 1);
 	case 77:
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTSTriedDoorB), 14, kCursorFinger, 72, 0, 372, 189);
 	default:
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 2a5ac35235..c752818f53 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/avi_frames.h"
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -635,6 +636,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
 	case 70:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, myMCStingerID), offsetof(GlobalFlags, myMCStingerChannelID), 11, 14);
+	case 71:
+		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID, IDS_MBT_EVIDENCE_PRESENT);
 	case 120:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
 	case 121:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 09433b0016..0e994a2b12 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -268,6 +268,13 @@ int ClickPlaySound::specifyCursor(Window *viewWindow, const Common::Point &point
 	return kCursorArrow;
 }
 
+SetFlagOnEntry::SetFlagOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, byte flagNewValue) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (flagOffset >= 0)
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagOffset, flagNewValue);
+}
+
 DisplayMessageWithEvidenceWhenEnteringNode::DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow,
 			const LocationStaticData &sceneStaticData, const Location &priorLocation, int evidenceID, int messageBoxTextID) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 6e1b81d798..7d7676a667 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -118,6 +118,12 @@ private:
 	int _flagOffset;
 };
 
+class SetFlagOnEntry : public SceneBase {
+public:
+	SetFlagOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, byte flagNewValue = 1);
+};
+
 class DisplayMessageWithEvidenceWhenEnteringNode : public SceneBase {
 public:
 	DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 89a6bd800089b8d2115c7583ea627a5e3c171d72
    https://github.com/scummvm/scummvm/commit/89a6bd800089b8d2115c7583ea627a5e3c171d72
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the ClickChangeScene base scene

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 9075edb844..9fd229b03c 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -547,6 +547,53 @@ int MainWallCatapultService::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class MiddleBaileyFootprintCapture : public SceneBase {
+public:
+	MiddleBaileyFootprintCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _footprint;
+};
+
+MiddleBaileyFootprintCapture::MiddleBaileyFootprintCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_footprint = Common::Rect(307, 134, 361, 160);
+}
+
+int MiddleBaileyFootprintCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_footprint.contains(pointLocation)) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+
+			// Add it to the list
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, CASTLE_EVIDENCE_FOOTPRINT))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Turn off capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MiddleBaileyFootprintCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_footprint.contains(pointLocation))
+			return -2;
+
+		return -1;
+	}
+
+	return kCursorArrow;
+}
+
 class StorageRoomDoor : public SceneBase {
 public:
 	StorageRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -803,6 +850,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new StorageRoomDoor(_vm, viewWindow, sceneStaticData, priorLocation, 38, 0, 386, 189, 1, 9, 5, 2, 1, 1, offsetof(GlobalFlags, cgStorageRoomVisit), 11, 130, 12, 0);
 	case 42:
 		return new SmithyBench(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 43:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 10, 0, 376, 189, kCursorFinger, 1, 6, 5, 1, 0, 1, TRANSITION_VIDEO, 2, -1, -1);
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	case 48:
@@ -820,10 +869,14 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new MainWallCatapultService(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 61:
 		return new SetFlagOnEntry(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgMBCrossedMoat), 1);
+	case 62:
+		return new MiddleBaileyFootprintCapture(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 63:
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_FOOTPRINT, IDS_MBT_EVIDENCE_PRESENT);
 	case 64:
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_SWORD, IDS_MBT_EVIDENCE_PRESENT);
+	case 67:
+		return new ClickChangeSceneSetFlag(_vm, viewWindow, sceneStaticData, priorLocation, 10, 0, 376, 189, kCursorPutDown, 1, 6, 5, 1, 0, 0, TRANSITION_VIDEO, 5, -1, -1, offsetof(GlobalFlags, cgFoundChestPanel));
 	case 70:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12);
 	case 71:
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 9da5c51ef3..c963e0c148 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -403,6 +403,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 8:
 		return new PaintingTowerWalkOntoElevator(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 9:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 170, 80, 428, 184, kCursorFinger, 5, 1, 8, 3, 0, 0, TRANSITION_VIDEO, 0, -1, -1);
 	case 10:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 11:
@@ -431,6 +433,20 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 110, 138, 170, 189);
 	case 23:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 4, kCursorFinger, 180, 122, 290, 189);
+	case 24:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 186, 28, 292, 158, kCursorMagnifyingGlass, 5, 4, 4, 2, 1, 1, TRANSITION_VIDEO, 5, -1, -1);
+	case 26:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 44, 232, 189, kCursorMagnifyingGlass, 5, 4, 4, 3, 0, 1, TRANSITION_VIDEO, 7, -1, -1);
+	case 27:
+		return new ClickChangeSceneSetFlag(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 4, 3, 0, 0, TRANSITION_VIDEO, 8, -1, -1, offsetof(GlobalFlags, dsWSSeenBallistaSketch));
+	case 28:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 112, 52, 380, 189, kCursorMagnifyingGlass, 5, 4, 4, 2, 0, 1, TRANSITION_VIDEO, 9, -1, -1);
+	case 29:
+		return new ClickChangeSceneSetFlag(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 4, 2, 0, 0, TRANSITION_VIDEO, 10, -1, -1, offsetof(GlobalFlags, dsWSSeenBallistaSketch));
+	case 30:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 96, 130, 222, 164, kCursorMagnifyingGlass, 5, 4, 7, 3, 1, 1, TRANSITION_VIDEO, 11, -1, -1 );
+	case 31:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 7, 3, 1, 0, TRANSITION_VIDEO, 12, -1, -1);
 	case 32:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 90, 328, 162, kItemDriveAssembly, 145, offsetof(GlobalFlags, dsWSPickedUpGearAssembly));
 	case 33:
@@ -441,6 +457,16 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 116, 0, 326, 189, 5, 2, 2, 1, 1, 1, TRANSITION_WALK, 11, 225, 15);
 	case 46:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 8, kCursorFinger, 102, 124, 164, 189);
+	case 51:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 36, 240, 189, kCursorMagnifyingGlass, 5, 2, 4, 0, 0, 1, TRANSITION_VIDEO, 11, -1, -1);
+	case 52:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 4, 0, 0, 0, TRANSITION_VIDEO, 12, -1, -1);
+	case 53:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 284, 46, 350, 182, kCursorMagnifyingGlass, 5, 2, 0, 2, 1, 1, TRANSITION_VIDEO, 13, -1, -1);
+	case 54:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 14, -1, -1);
+	case 55:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 210, 0, 330, 110, kCursorMagnifyingGlass, 5, 2, 3, 4, 1, 1, TRANSITION_VIDEO, 15, -1, -1);
 	case 59:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 70, 136, 190, 189);
 	case 60:
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index e0af205e59..75d31a0c43 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1008,10 +1008,20 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 202, 80, 227, 155, kItemCheeseGirl, 59, offsetof(GlobalFlags, faKITakenPostboxItem));
 	case 13:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 203, 111, 225, 129, kItemGenoSingleCart, 63, offsetof(GlobalFlags, faKITakenPostboxItem));
+	case 15:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 134, 0, 300, 189, kCursorFinger, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 0, -1, -1);
+	case 16:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 163, 25, 273, 145, kCursorMagnifyingGlass, 4, 2, 2, 0, 1, 2, TRANSITION_VIDEO, 1, -1, -1);
+	case 21:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 4, -1, -1);
 	case 23:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 81, 146, 134, 189, kItemRemoteControl, 45, offsetof(GlobalFlags, faERTakenRemoteControl));
 	case 30:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14);
+	case 32:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 9, 0, 1, 0, TRANSITION_VIDEO, 10, -1, -1);
+	case 35:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 9, 0, 0, 0, TRANSITION_VIDEO, 8, -1, -1);
 	case 37:
 		return new ClickZoomToyShelf(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 38:
@@ -1022,6 +1032,14 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 104, 10, 270, 189, 0, 20, 21);
 	case 41:
 		return new ToyClick(_vm, viewWindow, sceneStaticData, priorLocation, 128, 0, 332, 189, 0, 23, 24);
+	case 42:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 168, 38, 268, 108, kCursorMagnifyingGlass, 4, 3, 5, 0, 0, 1, TRANSITION_VIDEO, 28, -1, -1);
+	case 43:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 5, 0, 0, 0, TRANSITION_VIDEO, 29, -1, -1);
+	case 46:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 44, 26, 254, 144, kCursorMagnifyingGlass, 4, 3, 0, 2, 0, 1, TRANSITION_VIDEO, 30, -1, -1);
+	case 50:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 82, 38, 346, 138, kCursorMagnifyingGlass, 4, 3, 9, 2, 0, 1, TRANSITION_VIDEO, 38, -1, -1);
 	case 54:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 36, kCursorFinger, 0, 0, 432, 189);
 	case 56:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 0e994a2b12..606bc44ab7 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -202,6 +202,50 @@ int PlaySoundExitingFromSceneDeux::postExitRoom(Window *viewWindow, const Locati
 	return SC_TRUE;
 }
 
+ClickChangeScene::ClickChangeScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int cursorID,
+		int timeZone, int environment, int node, int facing, int orientation, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_cursorID = cursorID;
+
+	_clickDestination.destinationScene.timeZone = timeZone;
+	_clickDestination.destinationScene.environment = environment;
+	_clickDestination.destinationScene.node = node;
+	_clickDestination.destinationScene.facing = facing;
+	_clickDestination.destinationScene.orientation = orientation;
+	_clickDestination.destinationScene.depth = depth;
+	_clickDestination.transitionType = transitionType;
+	_clickDestination.transitionData = transitionData;
+	_clickDestination.transitionStartFrame = transitionStartFrame;
+	_clickDestination.transitionLength = transitionLength;
+}
+
+int ClickChangeScene::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int ClickChangeScene::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
+ClickChangeSceneSetFlag::ClickChangeSceneSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int cursorID,
+		int timeZone, int environment, int node, int facing, int orientation, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength, int flagIndex) :
+		ClickChangeScene(vm, viewWindow, sceneStaticData, priorLocation, left, top, right, bottom, cursorID, timeZone, environment, node, facing, orientation, depth,
+			transitionType, transitionData, transitionStartFrame, transitionLength) {
+	if (flagIndex >= 0)
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagIndex, 1);
+}
+
 PlayStingers::PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID, int lastStingerFileID) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 7d7676a667..4366f7bf7f 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -90,6 +90,29 @@ private:
 	int _soundFileNameID;
 };
 
+class ClickChangeScene : public SceneBase {
+public:
+	ClickChangeScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0,
+			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+};
+
+class ClickChangeSceneSetFlag : public ClickChangeScene {
+public:
+	ClickChangeSceneSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0,
+			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1, int flagIndex = -1);
+};
+
 class PlayStingers : public SceneBase {
 public:
 	PlayStingers(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 21750706721332a4c819561d5d531176de49cd22
    https://github.com/scummvm/scummvm/commit/21750706721332a4c819561d5d531176de49cd22
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement ClickPlayVideoSwitch scene base

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 9fd229b03c..62ea8dbe39 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -844,6 +844,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new OneShotEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 2 : 6, offsetof(GlobalFlags, cgBaileyOneWayGuard), IDS_HUMAN_PRESENCE_10METERS);
 	case 34:
 		return new CycleEntryVideoWarning(_vm, viewWindow, sceneStaticData, priorLocation, _vm->isDemo() ? 5 : 7, _vm->isDemo() ? 6 : 8, offsetof(GlobalFlags, cgBaileyTwoWayGuards), IDS_HUMAN_PRESENCE_10METERS);
+	case 35:
+		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 3, kCursorFinger, offsetof(GlobalFlags, cgTapestryFlag), 0, 0, 330, 189);
+	case 36:
+		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 4, kCursorFinger, offsetof(GlobalFlags, cgTapestryFlag), 0, 0, 330, 189);
 	case 37:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 175, 64, 237, 126, kItemBurnedLetter, 84, offsetof(GlobalFlags, cgBurnedLetterPresent));
 	case 39:
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index c963e0c148..558523c951 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -467,6 +467,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 14, -1, -1);
 	case 55:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 210, 0, 330, 110, kCursorMagnifyingGlass, 5, 2, 3, 4, 1, 1, TRANSITION_VIDEO, 15, -1, -1);
+	case 58:
+		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, offsetof(GlobalFlags, dsCYWeeblieClicked), 200, 88, 270, 189);
 	case 59:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 70, 136, 190, 189);
 	case 60:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 606bc44ab7..989acf0620 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -382,6 +382,41 @@ int CycleEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &pr
 	return SC_TRUE;
 }
 
+ClickPlayVideoSwitch::ClickPlayVideoSwitch(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int animID, int cursorID, int flagOffset, int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cursorID = cursorID;
+	_animID = animID;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_flagOffset = flagOffset;
+}
+
+int ClickPlayVideoSwitch::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
+
+		if (_flagOffset >= 0) {
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+
+			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickPlayVideoSwitch::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 ClickPlayVideo::ClickPlayVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int animID, int cursorID, int left, int top, int right, int bottom)
 		: SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 4366f7bf7f..b35aeb7008 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -183,6 +183,21 @@ private:
 	int _warningMessageID;
 };
 
+class ClickPlayVideoSwitch : public SceneBase {
+public:
+	ClickPlayVideoSwitch(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int animID = 0, int cursorID = -1, int flagOffset = 0, int left = 0, int top = 0, int right = 0, int bottom = 0); 
+
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	int _animID;
+	Common::Rect _clickRegion;
+	int _flagOffset;
+};
+
 class ClickPlayVideo : public SceneBase {
 public:
 	ClickPlayVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 6a9a93b2601696afe8993055539771993005c157
    https://github.com/scummvm/scummvm/commit/6a9a93b2601696afe8993055539771993005c157
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the king's study guard

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 62ea8dbe39..f21f6801fe 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -312,6 +312,47 @@ int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class KingsStudyGuard : public SceneBase {
+public:
+	KingsStudyGuard(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+};
+
+KingsStudyGuard::KingsStudyGuard(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int KingsStudyGuard::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14));
+	return SC_TRUE;
+}
+
+int KingsStudyGuard::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Display warning
+	((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_HUMAN_PRESENCE_3METERS));
+	return SC_TRUE;
+}
+
+int KingsStudyGuard::timerCallback(Window *viewWindow) {
+	if (_frameCycleCount < _staticData.cycleStartFrame + _staticData.cycleFrameCount - 1) {
+		_frameCycleCount++;
+		viewWindow->invalidateWindow(false);
+	} else {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 0) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+			((SceneViewWindow *)viewWindow)->showDeathScene(5);
+			return SC_DEATH;
+		} else {
+			_frameCycleCount = _staticData.cycleStartFrame;
+		}
+	}
+
+	return SC_TRUE;
+}
+
 class SmithyBench : public SceneBase {
 public:
 	SmithyBench(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -807,6 +848,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 42, 0, 357, 189, 1, 8, 11, 3, 1, 1, 2, 11, 314, 7);
 	case 18:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 26, 0, 432, 189, 1, 8, 6, 3, 1, 1, 2, 11, 288, 8);
+	case 19:
+		return new KingsStudyGuard(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 20:
 		return new TurnDepthPreChange(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgHookPresent), 0, 0, 1, 0, 0);
 	case 21:


Commit: 588b4ccba90fa92c799b97cef6f3d32aec80c467
    https://github.com/scummvm/scummvm/commit/588b4ccba90fa92c799b97cef6f3d32aec80c467
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Add remaining king's study specific scenes

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index f21f6801fe..b612bcc716 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -553,6 +553,65 @@ void SmithyBench::resetBackgroundBitmap() {
 	}
 }
 
+class PickupKingsStudyBooksA : public SceneBase {
+public:
+	PickupKingsStudyBooksA(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _diaryA, _diaryB;
+};
+
+PickupKingsStudyBooksA::PickupKingsStudyBooksA(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_diaryA = Common::Rect(148, 46, 344, 168);
+	_diaryB = Common::Rect(216, 0, 306, 48);
+}
+
+int PickupKingsStudyBooksA::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_diaryA.contains(pointLocation)) {
+		// Move to the first diary
+		DestinationScene pickUpDestination;
+		pickUpDestination.destinationScene.timeZone = 1;
+		pickUpDestination.destinationScene.environment = 8;
+		pickUpDestination.destinationScene.node = 5;
+		pickUpDestination.destinationScene.facing = 2;
+		pickUpDestination.destinationScene.orientation = 0;
+		pickUpDestination.destinationScene.depth = 2;
+		pickUpDestination.transitionType = TRANSITION_VIDEO;
+		pickUpDestination.transitionData = 1;
+		pickUpDestination.transitionStartFrame = -1;
+		pickUpDestination.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(pickUpDestination);
+		return SC_TRUE;
+	} else if (_diaryB.contains(pointLocation)) {
+		// Move to the second diary
+		DestinationScene pickUpDestination;
+		pickUpDestination.destinationScene.timeZone = 1;
+		pickUpDestination.destinationScene.environment = 8;
+		pickUpDestination.destinationScene.node = 5;
+		pickUpDestination.destinationScene.facing = 2;
+		pickUpDestination.destinationScene.orientation = 0;
+		pickUpDestination.destinationScene.depth = 1;
+		pickUpDestination.transitionType = TRANSITION_VIDEO;
+		pickUpDestination.transitionData = 3;
+		pickUpDestination.transitionStartFrame = -1;
+		pickUpDestination.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(pickUpDestination);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int PickupKingsStudyBooksA::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_diaryA.contains(pointLocation) || _diaryB.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 class MainWallCatapultService : public SceneBase {
 public:
 	MainWallCatapultService(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -899,6 +958,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new SmithyBench(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 43:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 10, 0, 376, 189, kCursorFinger, 1, 6, 5, 1, 0, 1, TRANSITION_VIDEO, 2, -1, -1);
+	case 46:
+		return new PickupKingsStudyBooksA(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 47:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 0, 75, 258, 123);
 	case 48:
@@ -922,6 +983,9 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_FOOTPRINT, IDS_MBT_EVIDENCE_PRESENT);
 	case 64:
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_SWORD, IDS_MBT_EVIDENCE_PRESENT);
+	case 66:
+		// Original incremented the flag each time, but it's expected that the code will never go above 1
+		return new SetFlagOnEntry(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgViewedKeepPlans), 1);
 	case 67:
 		return new ClickChangeSceneSetFlag(_vm, viewWindow, sceneStaticData, priorLocation, 10, 0, 376, 189, kCursorPutDown, 1, 6, 5, 1, 0, 0, TRANSITION_VIDEO, 5, -1, -1, offsetof(GlobalFlags, cgFoundChestPanel));
 	case 70:


Commit: b883626caab0051c85ace0123e60e312efb2a752
    https://github.com/scummvm/scummvm/commit/b883626caab0051c85ace0123e60e312efb2a752
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement browsing books

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index b612bcc716..82a27213a7 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -958,6 +958,10 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new SmithyBench(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 43:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 10, 0, 376, 189, kCursorFinger, 1, 6, 5, 1, 0, 1, TRANSITION_VIDEO, 2, -1, -1);
+	case 44:
+		return new BrowseBook(_vm, viewWindow, sceneStaticData, priorLocation, IDBD_DIARY1, IDBD_DIARY1_TRANS_TEXT_BASE, 0, 1, 8, 5, 2, 0, 0, TRANSITION_VIDEO, 4, -1, -1);
+	case 45:
+		return new BrowseBook(_vm, viewWindow, sceneStaticData, priorLocation, IDBD_DIARY2, IDBD_DIARY2_TRANS_TEXT_BASE, 1, 1, 8, 5, 2, 0, 0, TRANSITION_VIDEO, 2, -1, -1);
 	case 46:
 		return new PickupKingsStudyBooksA(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 47:
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 75d31a0c43..cab4b83e99 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1040,6 +1040,8 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 44, 26, 254, 144, kCursorMagnifyingGlass, 4, 3, 0, 2, 0, 1, TRANSITION_VIDEO, 30, -1, -1);
 	case 50:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 82, 38, 346, 138, kCursorMagnifyingGlass, 4, 3, 9, 2, 0, 1, TRANSITION_VIDEO, 38, -1, -1);
+	case 52:
+		return new BrowseBook(_vm, viewWindow, sceneStaticData, priorLocation, IDBD_LETTERS_BOOK_DATA, -1, 0, 4, 3, 9, 2, 0, 1, TRANSITION_VIDEO, 41, -1, -1);
 	case 54:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 36, kCursorFinger, 0, 0, 432, 189);
 	case 56:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 989acf0620..964bf2c080 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -33,6 +33,9 @@
 #include "buried/scene_view.h"
 #include "buried/environ/scene_common.h"
 
+#include "common/stream.h"
+#include "graphics/surface.h"
+
 namespace Buried {
 
 BasicDoor::BasicDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -498,6 +501,200 @@ int ClickChangeDepth::specifyCursor(Window *viewWindow, const Common::Point &poi
 	return kCursorArrow;
 }
 
+BrowseBook::BrowseBook(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int bookResID, int textStartResID, int startingPageID, int timeZone, int environment,
+		int node, int facing, int orientation, int depth, int transitionType, int transitionData,
+		int transitionStartFrame, int transitionLength) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_putDownDestination.destinationScene.timeZone = timeZone;
+	_putDownDestination.destinationScene.environment = environment;
+	_putDownDestination.destinationScene.node = node;
+	_putDownDestination.destinationScene.facing = facing;
+	_putDownDestination.destinationScene.orientation = orientation;
+	_putDownDestination.destinationScene.depth = depth;
+	_putDownDestination.transitionType = transitionType;
+	_putDownDestination.transitionData = transitionData;
+	_putDownDestination.transitionStartFrame = transitionStartFrame;
+	_putDownDestination.transitionLength = transitionLength;
+
+	Common::SeekableReadStream *pageData = _vm->getBookData(bookResID);
+	if (!pageData)
+		error("Failed to find book resource %d", bookResID);
+
+	uint16 pageCount = pageData->readUint16LE();
+
+	for (uint16 i = 0; i < pageCount; i++) {
+		BookPage page;
+		page.pageID = pageData->readSint16LE();
+		page.pageFrameIndex = pageData->readSint32LE();
+		page.numLines = pageData->readSint16LE();
+		page.up.typeOfTrans = pageData->readSint16LE();
+		page.up.destPage = pageData->readSint16LE();
+		page.left.typeOfTrans = pageData->readSint16LE();
+		page.left.destPage = pageData->readSint16LE();
+		page.right.typeOfTrans = pageData->readSint16LE();
+		page.right.destPage = pageData->readSint16LE();
+		page.down.typeOfTrans = pageData->readSint16LE();
+		page.down.destPage = pageData->readSint16LE();
+		_bookDatabase.push_back(page);
+	}
+
+	delete pageData;
+
+	_curPage = _bookDatabase[startingPageID].pageID;
+	_staticData.navFrameIndex = _bookDatabase[startingPageID].pageFrameIndex;
+	_curLineIndex = -1;
+	_translatedTextResourceID = textStartResID;
+
+	_top = Common::Rect(150, 0, 282, 70);
+	_bottom = Common::Rect(150, 119, 282, 189);
+	_left = Common::Rect(0, 0, 150, 189);
+	_right = Common::Rect(282, 0, 432, 189);
+	_putDown = Common::Rect(150, 70, 282, 119);
+
+	// Mark that we read the journals in the King's Study
+	if (_staticData.location.timeZone == 1 && _staticData.location.environment == 8)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKSReadJournal = 1;
+}
+
+int BrowseBook::gdiPaint(Window *viewWindow) {
+	if (_curLineIndex >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		int lineCount = _bookDatabase[_curPage].numLines;
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(1, (187 / lineCount) * _curLineIndex, 430, (187 / lineCount) * (_curLineIndex + 1) - 1);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int BrowseBook::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	const BookPage &pageData = _bookDatabase[_curPage];
+
+	if (_top.contains(pointLocation) && pageData.up.destPage >= 0) {
+		// Change the still
+		_curPage = pageData.up.destPage;
+		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
+
+		// Perform the transition
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 0, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
+		_curLineIndex = -1;
+		viewWindow->invalidateWindow(false);
+		pageChanged(viewWindow);
+		return SC_TRUE;
+	} else if (_bottom.contains(pointLocation) && pageData.down.destPage >= 0) {
+		// Change the still
+		_curPage = pageData.down.destPage;
+		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
+
+		// Perform the transition
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 3, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
+		_curLineIndex = -1;
+		viewWindow->invalidateWindow(false);
+		pageChanged(viewWindow);
+		return SC_TRUE;
+	} else if (_left.contains(pointLocation) && pageData.left.destPage >= 0) {
+		// Change the still
+		_curPage = pageData.left.destPage;
+		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
+
+		// Perform the transition
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
+		_curLineIndex = -1;
+		viewWindow->invalidateWindow(false);
+		pageChanged(viewWindow);
+		return SC_TRUE;
+	} else if (_right.contains(pointLocation) && pageData.right.destPage >= 0) {
+		// Change the still
+		_curPage = pageData.right.destPage;
+		_staticData.navFrameIndex = _bookDatabase[_curPage].pageFrameIndex;
+
+		// Perform the transition
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
+		_curLineIndex = -1;
+		viewWindow->invalidateWindow(false);
+		pageChanged(viewWindow);
+		return SC_TRUE;
+	} else if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0) {
+		// Move to the new destination
+		((SceneViewWindow *)viewWindow)->moveToDestination(_putDownDestination);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int BrowseBook::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	const BookPage &pageData = _bookDatabase[_curPage];
+
+	if (_top.contains(pointLocation) && pageData.up.destPage >= 0)
+		return kCursorMoveUp;
+	else if (_bottom.contains(pointLocation) && pageData.down.destPage >= 0)
+		return kCursorMoveDown;
+	else if (_left.contains(pointLocation) && pageData.left.destPage >= 0)
+		return kCursorPrevPage;
+	else if (_right.contains(pointLocation) && pageData.right.destPage >= 0)
+		return kCursorNextPage;
+	else if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0)
+		return kCursorPutDown;
+
+	return kCursorArrow;
+}
+
+int BrowseBook::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_translatedTextResourceID >= 0) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+			int lineCount = _bookDatabase[_curPage].numLines;
+
+			int textLineNumber = 0;
+			for (int i = 0; i < _curPage; i++)
+				textLineNumber += _bookDatabase[i].numLines;
+
+			// Determine the line index of the cursor
+			int lineIndex = (pointLocation.y - 2) / (187 / lineCount);
+			if (lineIndex > lineCount - 1)
+				lineIndex = lineCount - 1;
+
+			if (_curLineIndex != lineIndex) {
+				_curLineIndex = lineIndex;
+				viewWindow->invalidateWindow(false);
+
+				Common::String translatedText = _vm->getString(_translatedTextResourceID + textLineNumber + _curLineIndex);
+				((SceneViewWindow *)viewWindow)->displayTranslationText(translatedText);
+				textTranslated(viewWindow);
+			}
+
+			return SC_TRUE;
+		}
+
+		if (_curLineIndex != -1) {
+			_curLineIndex = -1;
+			viewWindow->invalidateWindow(false);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int BrowseBook::pageChanged(Window *viewWindow) {
+	if (_translatedTextResourceID == IDBD_DIARY2_TRANS_TEXT_BASE && _curPage >= 7 && _curPage <= 10)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKSSmithyEntryRead = 1;
+
+	return SC_TRUE;
+}
+
+int BrowseBook::textTranslated(Window *viewWindow) {
+	if (_translatedTextResourceID == IDBD_DIARY2_TRANS_TEXT_BASE && _curPage >= 7 && _curPage <= 10)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgKSSmithyEntryTranslated = 1;
+
+	return SC_TRUE;
+}
+
 ClickPlaySoundSynchronous::ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int flagOffset, int soundID, int cursorID, int left, int top, int right, int bottom) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index b35aeb7008..bc6911b597 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -26,6 +26,7 @@
 #ifndef BURIED_SCENE_COMMON_H
 #define BURIED_SCENE_COMMON_H
 
+#include "buried/bookdata.h"
 #include "buried/environ/scene_base.h"
 
 namespace Buried {
@@ -236,6 +237,29 @@ private:
 	Common::Rect _clickableRegion;
 };
 
+class BrowseBook : public SceneBase {
+public:
+	BrowseBook(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int bookResID = 0, int textStartResID = -1, int startingPageID = 0, int timeZone = -1, int environment = -1,
+			int node = -1, int facing = -1, int orientation = -1, int depth = -1, int transitionType = -1, int transitionData = -1,
+			int transitionStartFrame = -1, int transitionLength = -1);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int pageChanged(Window *viewWindow);
+	int textTranslated(Window *viewWindow);
+
+	Common::Array<BookPage> _bookDatabase;
+	int _curPage;
+	Common::Rect _top, _bottom, _left, _right, _putDown;
+	DestinationScene _putDownDestination;
+	int _translatedTextResourceID;
+	int _curLineIndex;
+};
+
 class ClickPlaySoundSynchronous : public SceneBase {
 public:
 	ClickPlaySoundSynchronous(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 0732557f6f1771df56645b7f7946a7fd47ba67cd
    https://github.com/scummvm/scummvm/commit/0732557f6f1771df56645b7f7946a7fd47ba67cd
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement opening the castle storage room chest

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 82a27213a7..df483a3c9f 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -777,6 +777,89 @@ int StorageRoomDoor::specifyCursor(Window *viewWindow, const Common::Point &poin
 	return kCursorArrow;
 }
 
+class StorageRoomCheckUnlock : public SceneBase {
+public:
+	StorageRoomCheckUnlock(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = 0, int itemID = 0, int filledFrameIndex = 0, int animID = 0, int depthA = 0, int depthB = 0,
+			int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _flagOffset;
+	int _itemID;
+	int _filledFrameIndex;
+	int _animID;
+	int _depthA;
+	int _depthB;
+	Common::Rect _dropRegion;
+	Common::Rect _chest;
+};
+
+StorageRoomCheckUnlock::StorageRoomCheckUnlock(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, int itemID, int filledFrameIndex, int animID, int depthA, int depthB,
+		int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_flagOffset = flagOffset;
+	_itemID = itemID;
+	_filledFrameIndex = filledFrameIndex;
+	_depthA = depthA;
+	_depthB = depthB;
+	_animID = animID;
+	_dropRegion = Common::Rect(left, top, right, bottom);
+	_chest = Common::Rect(55, 35, 432, 189);
+}
+
+int StorageRoomCheckUnlock::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// If we clicked on the chest, play the locked key sound we are so familiar with
+	if (_chest.contains(pointLocation)) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().cgSRClickedOnLockedChest = 1;
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+	}
+
+	return SC_FALSE;
+}
+
+int StorageRoomCheckUnlock::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (_dropRegion.contains(pointLocation) && _itemID == itemID)
+		return 1;
+
+	return 0;
+}
+
+int StorageRoomCheckUnlock::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (_dropRegion.contains(pointLocation) && _itemID == itemID) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
+		_staticData.navFrameIndex = _filledFrameIndex;
+
+		Location newDest = _staticData.location;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) != 0)
+			newDest.depth = _depthB;
+		else
+			newDest.depth = _depthA;
+
+		((SceneViewWindow *)viewWindow)->jumpToScene(newDest);
+	}
+
+	// Key remains in inventory
+	return SIC_REJECT;
+}
+
+int StorageRoomCheckUnlock::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_chest.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class KingsChamberGuardEncounter : public SceneBase {
 public:
 	KingsChamberGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -952,6 +1035,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 4, kCursorFinger, offsetof(GlobalFlags, cgTapestryFlag), 0, 0, 330, 189);
 	case 37:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 175, 64, 237, 126, kItemBurnedLetter, 84, offsetof(GlobalFlags, cgBurnedLetterPresent));
+	case 38:
+		return new StorageRoomCheckUnlock(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTapestryFlag), kItemCopperKey, 51, 1, 2, 1, 258, 100, 320, 185);
 	case 39:
 		return new StorageRoomDoor(_vm, viewWindow, sceneStaticData, priorLocation, 38, 0, 386, 189, 1, 9, 5, 2, 1, 1, offsetof(GlobalFlags, cgStorageRoomVisit), 11, 130, 12, 0);
 	case 42:


Commit: f0c37500a47219a57fc4c56f9e80f18eeb91bf03
    https://github.com/scummvm/scummvm/commit/f0c37500a47219a57fc4c56f9e80f18eeb91bf03
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Fix some invalid reads with the storage room door

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index df483a3c9f..2e4e2fbad0 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -751,19 +751,22 @@ int StorageRoomDoor::mouseDown(Window *viewWindow, const Common::Point &pointLoc
 
 int StorageRoomDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
 	if (_clicked) {
+		BuriedEngine *vm = _vm;
+		int flagOffset = _flagOffset;
+
 		if (_clickable.contains(pointLocation)) {
 			((SceneViewWindow *)viewWindow)->moveToDestination(_destData);
 		} else {
 			_clicked = false;
 		}
 
-		if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) == 0) {
 			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, CASTLE_EVIDENCE_AGENT3))
-				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
 			else
-				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
 
-			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagOffset, 1);
 		}
 	}
 


Commit: 38ed1a93cf33971840121122efa4ba3481d791fb
    https://github.com/scummvm/scummvm/commit/38ed1a93cf33971840121122efa4ba3481d791fb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Add the PlaySoundEnteringFromScene common scene

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 2e4e2fbad0..d89b9edb06 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -1061,6 +1061,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 	case 55:
 		// Valid, but not implemented.
 		break;
+	case 56:
+		return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14, 1, 9, 0, 3, 1, 0);
 	case 57:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 58:
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index c752818f53..18d0c269f7 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -638,6 +638,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, myMCStingerID), offsetof(GlobalFlags, myMCStingerChannelID), 11, 14);
 	case 71:
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID, IDS_MBT_EVIDENCE_PRESENT);
+	case 103:
+		return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, 2, 4, 4, 2, 1, 5);
 	case 120:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
 	case 121:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 964bf2c080..358d999c28 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -315,6 +315,31 @@ int ClickPlaySound::specifyCursor(Window *viewWindow, const Common::Point &point
 	return kCursorArrow;
 }
 
+PlaySoundEnteringFromScene::PlaySoundEnteringFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int soundFileNameID, int timeZone, int environment, int node, int facing, int orientation, int depth) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundFileNameID = soundFileNameID;
+	_soundLocation.timeZone = timeZone;
+	_soundLocation.environment = environment;
+	_soundLocation.node = node;
+	_soundLocation.facing = facing;
+	_soundLocation.orientation = orientation;
+	_soundLocation.depth = depth;
+}
+
+int PlaySoundEnteringFromScene::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_soundLocation.timeZone == priorLocation.timeZone &&
+			_soundLocation.environment == priorLocation.environment &&
+			_soundLocation.node == priorLocation.node &&
+			_soundLocation.facing == priorLocation.facing &&
+			_soundLocation.orientation == priorLocation.orientation &&
+			_soundLocation.depth == priorLocation.depth) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 127, false, true);
+	}
+
+	return SC_TRUE;
+}
+
 SetFlagOnEntry::SetFlagOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int flagOffset, byte flagNewValue) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index bc6911b597..3fa43199b8 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -142,6 +142,17 @@ private:
 	int _flagOffset;
 };
 
+class PlaySoundEnteringFromScene : public SceneBase {
+public:
+	PlaySoundEnteringFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int soundFileNameID = -1, int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	Location _soundLocation;
+	int _soundFileNameID;
+};
+
 class SetFlagOnEntry : public SceneBase {
 public:
 	SetFlagOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: b79655ab1c59585f0289a332cec6a7e6efed8166
    https://github.com/scummvm/scummvm/commit/b79655ab1c59585f0289a332cec6a7e6efed8166
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Don't reset the environment upon loading a saved game

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index a79f95b17b..ac8823331b 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -435,10 +435,13 @@ bool SceneViewWindow::jumpToSceneRestore(const Location &newLocation) {
 	if (_currentScene)
 		_currentScene->preExitRoom(this, passedLocation);
 
-	if (newLocation.timeZone != oldLocation.timeZone && newLocation.timeZone != -2)
-		initializeTimeZoneAndEnvironment(this, newLocation.timeZone, -1);
-	if (newLocation.timeZone != oldLocation.timeZone && newLocation.environment != -2)
-		initializeTimeZoneAndEnvironment(this, newLocation.timeZone, newLocation.environment);
+	// The original resets the environment upon loading, which is clearly not correct.
+	// We won't.
+
+	//if (newLocation.timeZone != oldLocation.timeZone && newLocation.timeZone != -2)
+	//	initializeTimeZoneAndEnvironment(this, newLocation.timeZone, -1);
+	//if (newLocation.timeZone != oldLocation.timeZone && newLocation.environment != -2)
+	//	initializeTimeZoneAndEnvironment(this, newLocation.timeZone, newLocation.environment);
 
 	// Create the new scene object
 	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, passedLocation);


Commit: 1d14a528f9f0039baa2c691bbbc0bccfb44d3044
    https://github.com/scummvm/scummvm/commit/1d14a528f9f0039baa2c691bbbc0bccfb44d3044
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement scenes for the first node of the castle hidden room

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index d89b9edb06..cf72a9b238 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -863,6 +863,23 @@ int StorageRoomCheckUnlock::specifyCursor(Window *viewWindow, const Common::Poin
 	return kCursorArrow;
 }
 
+class DeliverLightMessage : public SceneBase {
+public:
+	DeliverLightMessage(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+DeliverLightMessage::DeliverLightMessage(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int DeliverLightMessage::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment)
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_JUMPSUIT_LIGHT_TURN_ON_MESSAGE));
+
+	return SC_TRUE;
+}
+
 class KingsChamberGuardEncounter : public SceneBase {
 public:
 	KingsChamberGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1042,6 +1059,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new StorageRoomCheckUnlock(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTapestryFlag), kItemCopperKey, 51, 1, 2, 1, 258, 100, 320, 185);
 	case 39:
 		return new StorageRoomDoor(_vm, viewWindow, sceneStaticData, priorLocation, 38, 0, 386, 189, 1, 9, 5, 2, 1, 1, offsetof(GlobalFlags, cgStorageRoomVisit), 11, 130, 12, 0);
+	case 41:
+		return new OpenFirstItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 138, 32, 288, 107, 175, 65, 226, 90, 2, 1, kItemGoldCoins, 34, 35, offsetof(GlobalFlags, cgGoldCoinsPresent));
 	case 42:
 		return new SmithyBench(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 43:
@@ -1092,6 +1111,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 0, 0, 270, 189);
 	case 74:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 75:
+		return new DeliverLightMessage(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 76:
 		return new SetFlagOnEntry(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgSROpenedChest), 1);
 	case 77:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 358d999c28..9d2b44cc78 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -526,6 +526,85 @@ int ClickChangeDepth::specifyCursor(Window *viewWindow, const Common::Point &poi
 	return kCursorArrow;
 }
 
+OpenFirstItemAcquire::OpenFirstItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int openLeft, int openTop, int openRight, int openBottom, int getLeft, int getTop, int getRight,
+		int getBottom, int animOpenWith, int animOpenWithout, int itemID, int fullStillFrame, int clearStillFrame,
+		int itemFlagOffset):
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_open = false;
+	_itemPresent = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(itemFlagOffset) == 0;
+	_openClickRegion = Common::Rect(openLeft, openTop, openRight, openBottom);
+	_acquireRegion = Common::Rect(getLeft, getTop, getRight, getBottom);
+	_fullFrameIndex = fullStillFrame;
+	_clearFrameIndex = clearStillFrame;
+	_itemID = itemID;
+	_itemFlagOffset = itemFlagOffset;
+	_animOpenWith = animOpenWith;
+	_animOpenWithout = animOpenWithout;
+}
+
+int OpenFirstItemAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_acquireRegion.contains(pointLocation) && _itemPresent && _open) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
+
+		// Call inventory drag start function
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int OpenFirstItemAcquire::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_openClickRegion.contains(pointLocation) && !_open) {
+		_open = true;
+
+		if (_itemPresent) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animOpenWith);
+			_staticData.navFrameIndex = _fullFrameIndex;
+		} else {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animOpenWithout);
+			_staticData.navFrameIndex = _clearFrameIndex;
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int OpenFirstItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (_itemID == itemID && !_itemPresent && _open && pointLocation.x != -1 && pointLocation.y != -1) {
+		_itemPresent = true;
+		_staticData.navFrameIndex = _fullFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
+
+		viewWindow->invalidateWindow(false);
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int OpenFirstItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_openClickRegion.contains(pointLocation) && !_open)
+		return kCursorFinger;
+
+	if (_acquireRegion.contains(pointLocation) && _itemPresent && _open)
+		return kCursorOpenHand;
+
+	return kCursorArrow;
+}
+
 BrowseBook::BrowseBook(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int bookResID, int textStartResID, int startingPageID, int timeZone, int environment,
 		int node, int facing, int orientation, int depth, int transitionType, int transitionData,
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 3fa43199b8..5ced455239 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -248,6 +248,30 @@ private:
 	Common::Rect _clickableRegion;
 };
 
+class OpenFirstItemAcquire : public SceneBase {
+public:
+	OpenFirstItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int openLeft = 0, int openTop = 0, int openRight = 0, int openBottom = 0, int getLeft = 0, int getTop = 0, int getRight = 0,
+			int getBottom = 0, int animOpenWith = 0, int animOpenWithout = 0, int itemID = 0, int fullStillFrame = 0, int clearStillFrame = 0,
+			int itemFlagOffset = 0);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _itemPresent;
+	bool _open;
+	Common::Rect _openClickRegion;
+	Common::Rect _acquireRegion;
+	int _fullFrameIndex;
+	int _clearFrameIndex;
+	int _itemID;
+	int _itemFlagOffset;
+	int _animOpenWith;
+	int _animOpenWithout;
+};
+
 class BrowseBook : public SceneBase {
 public:
 	BrowseBook(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: d7e045a7ee966d278a4032df923875cf79352232
    https://github.com/scummvm/scummvm/commit/d7e045a7ee966d278a4032df923875cf79352232
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the ClickZoom scene base

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index cf72a9b238..45aa152864 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -1077,6 +1077,12 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new KingsChamberGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 50:
 		return new ClickPlaySoundSynchronous(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTSTriedDoorA), 14, kCursorFinger, 72, 0, 372, 189);
+	case 51:
+		return new ClickZoom(_vm, viewWindow, sceneStaticData, priorLocation, 5, 36, 6, 12, kCursorMagnifyingGlass, 0, 0, 432, 189);
+	case 52:
+		return new ClickZoom(_vm, viewWindow, sceneStaticData, priorLocation, 7, 37, 8, 18, kCursorMagnifyingGlass, 0, 90, 140, 189);
+	case 53:
+		return new ClickZoom(_vm, viewWindow, sceneStaticData, priorLocation, 9, 38, 10, 24, kCursorMagnifyingGlass, 130, 120, 432, 189);
 	case 55:
 		// Valid, but not implemented.
 		break;
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 9d2b44cc78..3c07d3ee85 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -28,6 +28,7 @@
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/inventory_window.h"
+#include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/scene_view.h"
@@ -315,6 +316,54 @@ int ClickPlaySound::specifyCursor(Window *viewWindow, const Common::Point &point
 	return kCursorArrow;
 }
 
+ClickZoom::ClickZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int animInID, int stillInID, int animOutID, int stillOutID,
+		int cursorID, int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cursorID = cursorID;
+	_animInID = animInID;
+	_stillInID = stillInID;
+	_animOutID = animOutID;
+	_stillOutID = stillOutID;
+	_zoomedIn = false;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_savedNavData = _staticData;
+}
+
+int ClickZoom::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_zoomedIn) {
+		_staticData.navFrameIndex = _stillOutID;
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animOutID);
+		_zoomedIn = false;
+		_staticData = _savedNavData;
+		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
+		return SC_TRUE;
+	} else if (_clickRegion.contains(pointLocation)) {
+		_staticData.navFrameIndex = _stillInID;
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animInID);
+		_zoomedIn = true;
+		_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickZoom::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_zoomedIn)
+		return kCursorPutDown;
+
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 PlaySoundEnteringFromScene::PlaySoundEnteringFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int soundFileNameID, int timeZone, int environment, int node, int facing, int orientation, int depth) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 5ced455239..1f6722391e 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -142,6 +142,25 @@ private:
 	int _flagOffset;
 };
 
+class ClickZoom : public SceneBase {
+public:
+	ClickZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int animInID = -1, int stillInID = -1, int animOutID = -1, int stillOutID = -1,
+			int cursorID = 0, int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	int _animInID;
+	int _stillInID;
+	int _animOutID;
+	int _stillOutID;
+	bool _zoomedIn;
+	LocationStaticData _savedNavData;
+};
+
 class PlaySoundEnteringFromScene : public SceneBase {
 public:
 	PlaySoundEnteringFromScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 2528ab9fd8b752a0bccb3e2d88417c3274d73854
    https://github.com/scummvm/scummvm/commit/2528ab9fd8b752a0bccb3e2d88417c3274d73854
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the sword evidence

Chateau Gaillard is now complete

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 45aa152864..95176a5fe9 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -694,6 +694,67 @@ int MiddleBaileyFootprintCapture::specifyCursor(Window *viewWindow, const Common
 	return kCursorArrow;
 }
 
+class TreasureRoomSwordCapture : public SceneBase {
+public:
+	TreasureRoomSwordCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _footprint;
+};
+
+TreasureRoomSwordCapture::TreasureRoomSwordCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_footprint = Common::Rect(118, 28, 190, 108);
+}
+
+int TreasureRoomSwordCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_footprint.contains(pointLocation)) {
+			// Play the animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+
+			// Play Arthur's comment
+			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				_vm->_sound->playSynchronousSoundEffect("BITDATA/CASTLE/CGTR_C01.BTA");
+
+			// Set the located flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().cgTRFoundSword = 1;
+
+			// Attempt to add it to the biochip
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, CASTLE_EVIDENCE_SWORD))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Turn off evidence capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+
+			// Reset the AI biochip display
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+			// Set the scoring flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreFoundSwordDiamond = 1;
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int TreasureRoomSwordCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_footprint.contains(pointLocation))
+			return -2; // Over the item, return the capture cursor
+
+		return -1;
+	}
+
+	return kCursorArrow;
+}
+
 class StorageRoomDoor : public SceneBase {
 public:
 	StorageRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -1102,6 +1163,8 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_FOOTPRINT, IDS_MBT_EVIDENCE_PRESENT);
 	case 64:
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, CASTLE_EVIDENCE_SWORD, IDS_MBT_EVIDENCE_PRESENT);
+	case 65:
+		return new TreasureRoomSwordCapture(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 66:
 		// Original incremented the flag each time, but it's expected that the code will never go above 1
 		return new SetFlagOnEntry(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgViewedKeepPlans), 1);


Commit: be3f65324c0458c95cee4a8d791fe8e76f382c56
    https://github.com/scummvm/scummvm/commit/be3f65324c0458c95cee4a8d791fe8e76f382c56
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the painting tower elevator

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 558523c951..533503768f 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -35,6 +35,8 @@
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
+#include "graphics/surface.h"
+
 namespace Buried {
 
 class SwapStillOnFlag : public SceneBase {
@@ -204,6 +206,168 @@ int PaintingTowerRetrieveKey::specifyCursor(Window *viewWindow, const Common::Po
 	return kCursorArrow;
 }
 
+class PaintingTowerElevatorControls : public SceneBase {
+public:
+	PaintingTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _lockHandle[2];
+	Common::Rect _directionHandle[2];
+	Common::Rect _transText[4];
+	int _textTranslated;
+};
+
+PaintingTowerElevatorControls::PaintingTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_lockHandle[0] = Common::Rect(152, 72, 186, 109);
+	_lockHandle[1] = Common::Rect(152, 108, 186, 146);
+	_directionHandle[0] = Common::Rect(252, 72, 312, 108);
+	_directionHandle[1] = Common::Rect(252, 109, 312, 144);
+	_transText[0] = Common::Rect(134, 50, 202, 70);
+	_transText[1] = Common::Rect(136, 150, 198, 168);
+	_transText[2] = Common::Rect(226, 52, 278, 70);
+	_transText[3] = Common::Rect(224, 148, 288, 166);
+	_textTranslated = -1;
+}
+
+int PaintingTowerElevatorControls::gdiPaint(Window *viewWindow) {
+	if (_textTranslated >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_transText[_textTranslated]);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int PaintingTowerElevatorControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_lockHandle[0].contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
+		return SC_TRUE;
+	} else if (_lockHandle[1].contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
+		return SC_TRUE;
+	} else if (_directionHandle[0].contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
+		return SC_TRUE;
+	} else if (_directionHandle[1].contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(5);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB = 0;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTUseElevatorControls = 1;
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int PaintingTowerElevatorControls::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		int newTextTrans = -1;
+
+		for (int i = 0; i < 4; i++) {
+			if (_transText[i].contains(pointLocation)) {
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTTransElevatorControls = 1;
+				newTextTrans = i;
+
+				if (newTextTrans != _textTranslated) {
+					// Load and display the new text
+					((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(IDDS_ELEVATOR_CONTROLS_TEXT_A + newTextTrans));
+					_textTranslated = newTextTrans;
+					viewWindow->invalidateWindow(false);
+					break;
+				}
+			}
+		}
+	} else {
+		if (_textTranslated != -1) {
+			_textTranslated = -1;
+			viewWindow->invalidateWindow(false);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int PaintingTowerElevatorControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_lockHandle[0].contains(pointLocation))
+		return kCursorArrowUp;
+	else if (_lockHandle[1].contains(pointLocation))
+		return kCursorArrowDown;
+	else if (_directionHandle[0].contains(pointLocation))
+		return kCursorArrowUp;
+	else if (_directionHandle[1].contains(pointLocation))
+		return kCursorArrowDown;
+
+	return kCursorArrow;
+}
+
+class PaintingTowerElevatorWheel : public SceneBase {
+public:
+	PaintingTowerElevatorWheel(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _wheel;
+};
+
+PaintingTowerElevatorWheel::PaintingTowerElevatorWheel(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_wheel = Common::Rect(94, 0, 380, 189);
+}
+
+int PaintingTowerElevatorWheel::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_wheel.contains(pointLocation)) {
+		byte lockStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA;
+		byte direction = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB;
+		byte elevatorPosition = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent;
+
+		if (lockStatus == 1) {
+			if (direction == 0 && elevatorPosition == 1) {
+				((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent = 0;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTRaisedPlatform = 0;
+				return SC_TRUE;
+			} else if (direction == 1 && elevatorPosition == 0) {
+				((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent = 1;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTRaisedPlatform = 1;
+				return SC_TRUE;
+			}
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int PaintingTowerElevatorWheel::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_wheel.contains(pointLocation)) {
+		byte lockStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA;
+		byte direction = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverB;
+		byte elevatorPosition = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorPresent;
+
+		if (lockStatus == 1) {
+			if (direction == 1 && elevatorPosition == 0)
+				return kCursorArrowLeft;
+			else if (direction == 0 && elevatorPosition == 1)
+				return kCursorArrowRight;
+		}
+	}
+
+	return kCursorArrow;
+}
+
 class PaintingTowerOutsideDoor : public SceneBase {
 public:
 	PaintingTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -347,6 +511,49 @@ int PaintingTowerCapAgent::postEnterRoom(Window *viewWindow, const Location &pri
 	return SC_TRUE;
 }
 
+class WalkDownPaintingTowerElevator : public SceneBase {
+public:
+	WalkDownPaintingTowerElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+};
+
+WalkDownPaintingTowerElevator::WalkDownPaintingTowerElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(48, 136, 306, 184);
+	_cursorID = kCursorFinger;
+	_clickDestination.destinationScene = Location(5, 3, 10, 0, 0, 0);
+	_clickDestination.transitionType = TRANSITION_VIDEO;
+	_clickDestination.transitionData = 9;
+	_clickDestination.transitionStartFrame = -1;
+	_clickDestination.transitionLength = -1;
+}
+
+int WalkDownPaintingTowerElevator::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTElevatorLeverA == 1) {
+			((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTWalkedDownElevator = 1;
+		} else {
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 127, false, true);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int WalkDownPaintingTowerElevator::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -401,6 +608,12 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new CapturePaintingTowerFootprint(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 4:
 		return new PaintingTowerRetrieveKey(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 5:
+		return new PaintingTowerElevatorControls(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 6:
+		return new PaintingTowerElevatorWheel(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 7:
+		return new WalkDownPaintingTowerElevator(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 8:
 		return new PaintingTowerWalkOntoElevator(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 9:


Commit: b6ee7ca56f23f760c48883fb507679a8a72a00be
    https://github.com/scummvm/scummvm/commit/b6ee7ca56f23f760c48883fb507679a8a72a00be
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the capacitance array to habitat door

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index c4d36dc475..4b3fa2a2f5 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -485,6 +486,346 @@ BaseOxygenTimerInSpace::BaseOxygenTimerInSpace(BuriedEngine *vm, Window *viewWin
 	_deathID = 40;
 }
 
+class BaseOxygenTimerCapacitance : public SceneBase {
+public:
+	BaseOxygenTimerCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	virtual int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	virtual int preExitRoom(Window *viewWindow, const Location &priorLocation);
+	virtual int timerCallback(Window *viewWindow);
+
+protected:
+	uint32 _entryStartTime;
+	bool _jumped;
+};
+
+BaseOxygenTimerCapacitance::BaseOxygenTimerCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_jumped = false;
+}
+
+int BaseOxygenTimerCapacitance::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_entryStartTime = g_system->getMillis();
+	return SC_TRUE;
+}
+
+int BaseOxygenTimerCapacitance::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	// This does the 25% warning, unlike BaseOxygenTimer
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 0) {
+		if (newLocation.timeZone == -2) {
+			_jumped = true;
+			return SC_TRUE;
+		}
+
+		int currentValue = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer;
+
+		if (_staticData.location.node != newLocation.node) {
+			if (currentValue <= GC_AI_OT_WALK_DECREMENT) {
+				if (newLocation.timeZone != -2)
+					((SceneViewWindow *)viewWindow)->showDeathScene(41);
+				return SC_DEATH;
+			} else {
+				currentValue -= GC_AI_OT_WALK_DECREMENT;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = currentValue;
+
+				if (currentValue < GC_AIHW_STARTING_VALUE / 4 || (currentValue % (GC_AIHW_STARTING_VALUE / 10)) == 0) {
+					if (currentValue < GC_AIHW_STARTING_VALUE / 4) {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					} else {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					}
+				}
+			}
+		} else {
+			if (currentValue <= GC_AI_OT_TURN_DECREMENT) {
+				if (newLocation.timeZone != -2)
+					((SceneViewWindow *)viewWindow)->showDeathScene(41);
+				return SC_DEATH;
+			} else {
+				currentValue -= GC_AI_OT_TURN_DECREMENT;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = currentValue;
+
+				if (currentValue < GC_AIHW_STARTING_VALUE / 4 || (currentValue % (GC_AIHW_STARTING_VALUE / 10)) == 0) {
+					if (currentValue < GC_AIHW_STARTING_VALUE / 4) {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					} else {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					}
+				}
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int BaseOxygenTimerCapacitance::timerCallback(Window *viewWindow) {
+	// This does the 25% warning, unlike BaseOxygenTimer
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 0) {
+		if (_jumped)
+			return SC_TRUE;
+
+		if ((g_system->getMillis() - _entryStartTime) >= GC_AI_OT_WAIT_TIME_PERIOD) {
+			int currentValue = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer;
+
+			if (currentValue <= GC_AI_OT_WAIT_DECREMENT) {
+				((SceneViewWindow *)viewWindow)->showDeathScene(41);
+				return SC_DEATH;
+			} else {
+				currentValue -= GC_AI_OT_WAIT_DECREMENT;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = currentValue;
+
+				if (currentValue < GC_AIHW_STARTING_VALUE / 4 || (currentValue % (GC_AIHW_STARTING_VALUE / 10)) == 0) {
+					if (currentValue < GC_AIHW_STARTING_VALUE / 4) {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_LOW);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					} else {
+						Common::String oxygenMessage = _vm->getString(IDS_AI_OXY_LEVEL_TEXT_TEMPLATE_NORM);
+						assert(!oxygenMessage.empty());
+						oxygenMessage = Common::String::format(oxygenMessage.c_str(), currentValue * 100 / GC_AIHW_STARTING_VALUE);
+						((SceneViewWindow *)viewWindow)->displayLiveText(oxygenMessage);
+					}
+				}
+			}
+
+			_entryStartTime = g_system->getMillis();
+		}
+	}
+
+	return SC_TRUE;
+}
+
+class CapacitanceToHabitatDoorClosed : public BaseOxygenTimerCapacitance {
+public:
+	CapacitanceToHabitatDoorClosed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _metalBar;
+	Common::Rect _door;
+};
+
+CapacitanceToHabitatDoorClosed::CapacitanceToHabitatDoorClosed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimerCapacitance(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 1)
+		_staticData.navFrameIndex = 7;
+	else
+		_staticData.navFrameIndex = 55;
+
+	_metalBar = Common::Rect(184, 146, 264, 184);
+	_door = Common::Rect(132, 14, 312, 180);
+}
+
+int CapacitanceToHabitatDoorClosed::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_metalBar.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 0) {
+		_staticData.navFrameIndex = 7;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar = 1;
+
+		Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemMetalBar, ptInventoryWindow);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CapacitanceToHabitatDoorClosed::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_door.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 0) {
+			_staticData.navFrameIndex = 96;
+			viewWindow->invalidateWindow(false);
+
+			// Wait for a second (why?)
+			uint32 startTime = g_system->getMillis();
+
+			while (!_vm->shouldQuit() && g_system->getMillis() < startTime + 1000) {
+				_vm->yield();
+				_vm->_sound->timerCallback();
+			}
+
+			DestinationScene destData;
+			destData.destinationScene = _staticData.location;
+			destData.destinationScene.depth = 1;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 1;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+
+			// Move to the final destination
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		} else {
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 0) {
+				_staticData.navFrameIndex = 97;
+				viewWindow->invalidateWindow(false);
+
+				// Wait for a second (why?)
+				uint32 startTime = g_system->getMillis();
+
+				while (!_vm->shouldQuit() && g_system->getMillis() < startTime + 1000) {
+					_vm->yield();
+					_vm->_sound->timerCallback();
+				}
+
+				DestinationScene destData;
+				destData.destinationScene = _staticData.location;
+				destData.destinationScene.depth = 1;
+				destData.transitionType = TRANSITION_VIDEO;
+				destData.transitionData = 2;
+				destData.transitionStartFrame = -1;
+				destData.transitionLength = -1;
+
+				// Move to the final destination
+				((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+				return SC_TRUE;
+			} else {
+				int oldFrame = _staticData.navFrameIndex;
+				_staticData.navFrameIndex = 121;
+				viewWindow->invalidateWindow(false);
+
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment - 1, 12));
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment - 1, 13));
+
+				_staticData.navFrameIndex = oldFrame;
+				viewWindow->invalidateWindow(false);
+				return SC_TRUE;
+			}
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int CapacitanceToHabitatDoorClosed::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_metalBar.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 0)
+		return kCursorOpenHand;
+
+	if (_door.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+int CapacitanceToHabitatDoorClosed::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemMetalBar && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 1)
+		return 1;
+
+	return 0;
+}
+
+int CapacitanceToHabitatDoorClosed::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0; // ???
+
+	return SIC_REJECT;
+}
+
+class CapacitanceToHabitatDoorOpen : public BaseOxygenTimerCapacitance {
+public:
+	CapacitanceToHabitatDoorOpen(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _metalBar;
+};
+
+CapacitanceToHabitatDoorOpen::CapacitanceToHabitatDoorOpen(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimerCapacitance(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 1) {
+		_staticData.navFrameIndex = 101;
+		_staticData.destForward.transitionStartFrame = 0;
+		_staticData.destForward.transitionLength = 28;
+	} else {
+		_staticData.navFrameIndex = 100;
+		_staticData.destForward.transitionStartFrame = 53;
+		_staticData.destForward.transitionLength = 28;
+	}
+
+	_metalBar = Common::Rect(184, 146, 264, 184);
+}
+
+int CapacitanceToHabitatDoorOpen::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	// Play the door closing sound
+	if (_staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
+
+	return SC_TRUE;
+}
+
+int CapacitanceToHabitatDoorOpen::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_metalBar.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 0) {
+		_staticData.navFrameIndex = 101;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar = 1;
+		_staticData.destForward.transitionStartFrame = 0;
+		_staticData.destForward.transitionLength = 28;
+
+		Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemMetalBar, ptInventoryWindow);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CapacitanceToHabitatDoorOpen::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_metalBar.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 0)
+		return kCursorOpenHand;
+
+	return kCursorArrow;
+}
+
+int CapacitanceToHabitatDoorOpen::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemMetalBar && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 1)
+		return 1;
+
+	return 0;
+}
+
+int CapacitanceToHabitatDoorOpen::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0; // ???
+
+	if (itemID == kItemMetalBar && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 1) {
+		_staticData.navFrameIndex = 100;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar = 0;
+		viewWindow->invalidateWindow(false);
+		_staticData.destForward.transitionStartFrame = 53;
+		_staticData.destForward.transitionLength = 28;
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
 bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -546,6 +887,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
 		return new BaseOxygenTimerInSpace(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 21:
+		return new CapacitanceToHabitatDoorClosed(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 22:
+		return new CapacitanceToHabitatDoorOpen(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 26:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 32:


Commit: 225f45da153a28f184c1f83e1bc226fd92ea8de6
    https://github.com/scummvm/scummvm/commit/225f45da153a28f184c1f83e1bc226fd92ea8de6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the capacitance array scenes

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 4b3fa2a2f5..0b5376038b 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -36,6 +36,7 @@
 #include "buried/environ/scene_common.h"
 
 #include "common/system.h"
+#include "graphics/font.h"
 
 namespace Buried {
 
@@ -826,6 +827,484 @@ int CapacitanceToHabitatDoorOpen::droppedItem(Window *viewWindow, int itemID, co
 	return SIC_REJECT;
 }
 
+class CapacitancePanelInterface : public BaseOxygenTimerCapacitance {
+public:
+	CapacitancePanelInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~CapacitancePanelInterface();
+	void preDestructor();
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int gdiPaint(Window *viewWindow);
+
+private:
+	Common::Rect _stationRegions[15];
+	int _currentSelection;
+	int _currentTextIndex;
+	int _lineHeight;
+	Graphics::Font *_textFont;
+	Common::Rect _leftTextRegion;
+	Common::Rect _rightTextRegion;
+};
+
+CapacitancePanelInterface::CapacitancePanelInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimerCapacitance(vm, viewWindow, sceneStaticData, priorLocation) {
+	_currentSelection = -1;
+	_currentTextIndex = -1;
+	_stationRegions[0] = Common::Rect(265, 110, 286, 135);
+	_stationRegions[1] = Common::Rect(102, 45, 180, 134);
+	_stationRegions[2] = Common::Rect(195, 106, 216, 133);
+	_stationRegions[3] = Common::Rect(268, 72, 283, 87);
+	_stationRegions[4] = Common::Rect(221, 46, 236, 74);
+	_stationRegions[5] = Common::Rect(290, 72, 317, 108);
+	_stationRegions[6] = Common::Rect(264, 55, 288, 67);
+	_stationRegions[7] = Common::Rect(194, 74, 266, 84);
+	_stationRegions[8] = Common::Rect(198, 62, 214, 74);
+	_stationRegions[9] = Common::Rect(221, 106, 236, 134);
+	_stationRegions[10] = Common::Rect(245, 46, 260, 74);
+	_stationRegions[11] = Common::Rect(245, 106, 260, 134);
+	_stationRegions[12] = Common::Rect(266, 92, 290, 109);
+	_stationRegions[13] = Common::Rect(194, 96, 264, 106);
+	_stationRegions[14] = Common::Rect(180, 85, 194, 94);
+	_leftTextRegion = Common::Rect(83, 144, 211, 170);
+	_rightTextRegion = Common::Rect(228, 144, 356, 170);
+	_lineHeight = _vm->getLanguage() == Common::JA_JPN ? 10 : 13;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+CapacitancePanelInterface::~CapacitancePanelInterface() {
+	preDestructor();
+}
+
+void CapacitancePanelInterface::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int CapacitancePanelInterface::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	byte &oxygenReserves = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves;
+
+	if (_currentSelection == 2) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized == 0 && (_stationRegions[_currentSelection].contains(pointLocation) || _rightTextRegion.contains(pointLocation))) {
+			if (oxygenReserves > 0) {
+				// Decrement reserves flag
+				oxygenReserves--;
+
+				// Set the machine room to pressurized
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized = 1;
+
+				// Display pressurizing message
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_PRES_ENV_TEXT;
+
+				// Play sound file
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+
+				// Display pressurized text
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			} else {
+				// Not enough oxygen reserves
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_INSUF_OXYGEN;
+				return SC_TRUE;
+			}
+		}
+	} else if (_currentSelection == 3) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 0 && (_stationRegions[_currentSelection].contains(pointLocation) || _rightTextRegion.contains(pointLocation))) {
+			if (oxygenReserves > 0) {
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 0) {
+					if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurizedAttempted == 0) {
+						// Display pressurizing message
+						viewWindow->invalidateWindow(false);
+						_currentTextIndex = IDS_AI_PRES_PANEL_PRES_ENV_TEXT;
+
+						// Play sound file
+						_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+
+						// Display bulkhead message
+						viewWindow->invalidateWindow(false);
+						_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+
+						// Play Mom audio
+						// (Is this an Alien reference?)
+						_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11));
+
+						// Update attempt flag
+						((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurizedAttempted = 1;
+					}
+				} else {
+					// Decrement reserves flag
+					oxygenReserves--;
+
+					// Set the capacitance array to pressurized
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized = 1;
+
+					// Display pressurizing message
+					viewWindow->invalidateWindow(false);
+					_currentTextIndex = IDS_AI_PRES_PANEL_PRES_ENV_TEXT;
+
+					// Play sound file
+					_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+
+					// Display pressurized text
+					viewWindow->invalidateWindow(false);
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+
+					// Display oxygen text in the message window
+					((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_ENTERING_PRES_ENV_TEXT));
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = GC_AIHW_STARTING_VALUE;
+				}
+
+				return SC_TRUE;
+			} else {
+				// Not enough oxygen reserves
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_INSUF_OXYGEN;
+				return SC_TRUE;
+			}
+		}
+	}
+
+	// Check against the hotspots
+	for (int i = 0; i < 15; i++) {
+		if (_stationRegions[i].contains(pointLocation) && _currentSelection != i) {
+			switch (i) {
+			case 0:
+				_staticData.navFrameIndex = 107;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			case 1:
+				_staticData.navFrameIndex = 108;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ZERO_PRES_ENV;
+				return SC_TRUE;
+			case 2:
+				_staticData.navFrameIndex = 109;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized == 1)
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				else
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES;
+				return SC_TRUE;
+			case 3:
+				_staticData.navFrameIndex = 110;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 1)
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				else
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES;
+				return SC_TRUE;
+			case 4:
+				_staticData.navFrameIndex = 111;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 5:
+				_staticData.navFrameIndex = 112;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			case 6:
+				_staticData.navFrameIndex = 113;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 7:
+				_staticData.navFrameIndex = 114;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 8:
+				_staticData.navFrameIndex = 115;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 9:
+				_staticData.navFrameIndex = 116;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 10:
+				_staticData.navFrameIndex = 117;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 11:
+				_staticData.navFrameIndex = 118;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 12:
+				_staticData.navFrameIndex = 119;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			case 13:
+			case 14:
+				_staticData.navFrameIndex = 120;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			}
+		}
+	}
+
+	// By default, return to depth zero (zoomed out)
+	DestinationScene destData;
+	destData.destinationScene = _staticData.location;
+	destData.destinationScene.depth = 0;
+	destData.transitionType = TRANSITION_NONE;
+	destData.transitionData = -1;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int CapacitancePanelInterface::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 15; i++)
+		if (_stationRegions[i].contains(pointLocation))
+			return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+int CapacitancePanelInterface::gdiPaint(Window *viewWindow) {
+	if (_currentSelection >= 0) {
+		uint32 color = _vm->_gfx->getColor(208, 144, 24);
+
+		Common::String location = _vm->getString(IDS_AI_PRES_PANEL_DESC_BASE + _currentSelection);
+		if (_currentSelection == 3)
+			location += _vm->getString(IDS_AI_PRES_PANEL_DESC_BASE + 19);
+
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_leftTextRegion);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, location, rect.left, rect.top, rect.width(), rect.height(), color, _lineHeight, kTextAlignCenter, true);
+
+		if (_currentTextIndex >= 0) {
+			rect = _rightTextRegion;
+			rect.translate(absoluteRect.left, absoluteRect.top);
+			_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, _vm->getString(_currentTextIndex), rect.left, rect.top, rect.width(), rect.height(), color, _lineHeight, kTextAlignCenter, true);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+class PlayArthurOffsetCapacitance : public BaseOxygenTimerCapacitance {
+public:
+	PlayArthurOffsetCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int stingerVolume = 127, int lastStingerFlagOffset = -1, int effectIDFlagOffset = -1, int firstStingerFileID = -1,
+			int lastStingerFileID = -1, int stingerDelay = 1, int flagOffset = -1, int newStill = -1, int newNavStart = -1, int newNavLength = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _stingerVolume;
+	int _lastStingerFlagOffset;
+	int _effectIDFlagOffset;
+	int _firstStingerFileID;
+	int _lastStingerFileID;
+	int _stingerDelay;
+};
+
+PlayArthurOffsetCapacitance::PlayArthurOffsetCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int stingerVolume, int lastStingerFlagOffset, int effectIDFlagOffset, int firstStingerFileID,
+		int lastStingerFileID, int stingerDelay, int flagOffset, int newStill, int newNavStart, int newNavLength) :
+		BaseOxygenTimerCapacitance(vm, viewWindow, sceneStaticData, priorLocation) {
+	_stingerVolume = stingerVolume;
+	_lastStingerFlagOffset = lastStingerFlagOffset;
+	_effectIDFlagOffset = effectIDFlagOffset;
+	_firstStingerFileID = firstStingerFileID;
+	_lastStingerFileID = lastStingerFileID;
+	_stingerDelay = stingerDelay;
+
+	if (flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) == 0) {
+		// This is completely wrong.
+		//if (newStill >= 0)
+		//	_staticData.navFrameIndex;
+		if (newNavStart >= 0)
+			_staticData.destForward.transitionStartFrame = newNavStart;
+		if (newNavLength >= 0)
+			_staticData.destForward.transitionLength = newNavLength;
+	}
+}
+
+int PlayArthurOffsetCapacitance::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	BaseOxygenTimerCapacitance::postEnterRoom(viewWindow, priorLocation);
+
+	if (_effectIDFlagOffset >= 0) {
+		byte effectID = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_effectIDFlagOffset);
+
+		if (!_vm->_sound->isSoundEffectPlaying(effectID - 1)) {
+			byte lastStinger = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_lastStingerFlagOffset) + 1;
+
+			if ((lastStinger % _stingerDelay) == 0) {
+				if (lastStinger < (_lastStingerFileID - _firstStingerFileID) * _stingerDelay) {
+					int fileNameIndex = _vm->computeFileNameResourceID(_staticData.location.timeZone, _staticData.location.environment, _firstStingerFileID + (lastStinger / _stingerDelay) - 1);
+
+					if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI) && (lastStinger / _stingerDelay) < 3) {
+						_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(fileNameIndex));
+
+						// Play an Arthur comment if we have the chip
+						switch (lastStinger / _stingerDelay) {
+						case 0:
+							_vm->_sound->playSynchronousSoundEffect("BITDATA/AILAB/AICR_C01.BTA", 127);
+							break;
+						case 1:
+							_vm->_sound->playSynchronousSoundEffect("BITDATA/AILAB/AICR_C02.BTA", 127);
+							break;
+						case 2:
+							_vm->_sound->playSynchronousSoundEffect("BITDATA/AILAB/AICR_C03.BTA", 127);
+							break;
+						}
+
+						// Update the global flags
+						((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
+					} else {
+						byte newStingerID = _vm->_sound->playSoundEffect(_vm->getFilePath(fileNameIndex), _stingerVolume, false, true) + 1;
+
+						// Update the global flags
+						((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_effectIDFlagOffset, newStingerID);
+						((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
+					}
+				}
+			} else {
+				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_effectIDFlagOffset, 0xFF);
+				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_lastStingerFlagOffset, lastStinger);
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+class ClickChangeSceneCapacitance : public BaseOxygenTimerCapacitance {
+public:
+	ClickChangeSceneCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0,
+			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+};
+
+ClickChangeSceneCapacitance::ClickChangeSceneCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int cursorID,
+		int timeZone, int environment, int node, int facing, int orientation, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
+		BaseOxygenTimerCapacitance(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_cursorID = cursorID;
+	_clickDestination.destinationScene = Location(timeZone, environment, node, facing, orientation, depth);
+	_clickDestination.transitionType = transitionType;
+	_clickDestination.transitionData = transitionData;
+	_clickDestination.transitionStartFrame = transitionStartFrame;
+	_clickDestination.transitionLength = transitionLength;
+}
+
+int ClickChangeSceneCapacitance::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int ClickChangeSceneCapacitance::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
+class CapacitanceDockingBayDoor : public BaseOxygenTimerCapacitance {
+public:
+	CapacitanceDockingBayDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _door;
+};
+
+CapacitanceDockingBayDoor::CapacitanceDockingBayDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimerCapacitance(vm, viewWindow, sceneStaticData, priorLocation) {
+	_door = Common::Rect(160, 54, 276, 168);
+}
+
+int CapacitanceDockingBayDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_door.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 1) {
+			_staticData.navFrameIndex = 98;
+			viewWindow->invalidateWindow(false);
+
+			_vm->_sound->playSynchronousSoundEffect("BITDATA/AILAB/AI_LOCK.BTA");
+
+			// Wait a second?
+			uint32 startTime = g_system->getMillis();
+			while (!_vm->shouldQuit() && g_system->getMillis() < startTime + 1000) {
+				_vm->yield();
+				_vm->_sound->timerCallback();
+			}
+
+			DestinationScene destData;
+			destData.destinationScene = _staticData.location;
+			destData.destinationScene.depth = 1;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 0;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+
+			// Move to the final destination
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		} else {
+			int oldFrame = _staticData.navFrameIndex;
+			_staticData.navFrameIndex = 99;
+			viewWindow->invalidateWindow(false);
+
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment - 1, 12));
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment - 1, 13));
+
+			_staticData.navFrameIndex = oldFrame;
+			viewWindow->invalidateWindow(false);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int CapacitanceDockingBayDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_door.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -887,12 +1366,24 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
 		return new BaseOxygenTimerInSpace(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 20:
+		return new PlayArthurOffsetCapacitance(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, aiCRStingerID), offsetof(GlobalFlags, aiCRStingerChannelID), 4, 11, 1);
 	case 21:
 		return new CapacitanceToHabitatDoorClosed(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 22:
 		return new CapacitanceToHabitatDoorOpen(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 23:
+		return new ClickChangeSceneCapacitance(_vm, viewWindow, sceneStaticData, priorLocation, 122, 32, 310, 140, kCursorMagnifyingGlass, 6, 2, 3, 0, 1, 1, TRANSITION_VIDEO, 3, -1, -1);
+	case 24:
+		return new CapacitancePanelInterface(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 25:
+		return new CapacitanceDockingBayDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 26:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 27:
+		return new PlayArthurOffsetCapacitance(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, aiCRStingerID), offsetof(GlobalFlags, aiCRStingerChannelID), 4, 11, 1, offsetof(GlobalFlags, aiCRGrabbedMetalBar), 73, 320, 40);
+	case 28:
+		return new PlayArthurOffsetCapacitance(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, aiCRStingerID), offsetof(GlobalFlags, aiCRStingerChannelID), 4, 11, 1, offsetof(GlobalFlags, aiCRGrabbedMetalBar), 66, 241, 25);
 	case 32:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 52:


Commit: 03b2be8c14d78a42be89fd221cc065566221ac8f
    https://github.com/scummvm/scummvm/commit/03b2be8c14d78a42be89fd221cc065566221ac8f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Stop ambient sounds when playing synchronous animations with audio

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index ac8823331b..81b2122fd6 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1497,7 +1497,9 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
 
-	// TODO: Stop background sound if the video has sound (ugh!)
+	// Stop background sound if the video has sound
+	if (animDatabase[i].audioStreamCount > 0)
+		_vm->_sound->stop();
 
 	animationMovie->playToFrame(animDatabase[i].startFrame + animDatabase[i].frameCount - 1);
 
@@ -1514,7 +1516,9 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
 
-	// TODO: Restart background sound if the video had sound (ugh!)
+	// Restart background sound if the video had sound
+	if (animDatabase[i].audioStreamCount > 0)
+		_vm->_sound->restart();
 
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
@@ -1612,7 +1616,9 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
 
-	// TODO: Stop background sound if the video has sound (ugh!)
+	// Stop background sound if the video has sound
+	if (animDatabase[i].audioStreamCount > 0)
+		_vm->_sound->stop();
 
 	animationMovie->playToFrame(animDatabase[i].startFrame + animDatabase[i].frameCount - 1);
 
@@ -1629,7 +1635,9 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
 
-	// TODO: Restart background sound if the video had sound (ugh!)
+	// Restart background sound if the video had sound
+	if (animDatabase[i].audioStreamCount > 0)
+		_vm->_sound->restart();
 
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;


Commit: 4d4f7ad8f6a4c7c5b1bbc9354d6404a4e92c0fcb
    https://github.com/scummvm/scummvm/commit/4d4f7ad8f6a4c7c5b1bbc9354d6404a4e92c0fcb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the docking bay

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 0b5376038b..de1fe8b93f 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -1305,6 +1305,127 @@ int CapacitanceDockingBayDoor::specifyCursor(Window *viewWindow, const Common::P
 	return kCursorArrow;
 }
 
+class SpaceDoor : public SceneBase {
+public:
+	SpaceDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int openFrame = -1, int closedFrame = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1,
+			int doorFlag = -1, int doorFlagValue = 0);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _clicked;
+	Common::Rect _clickable;
+	DestinationScene _destData;
+	int _openFrame;
+	int _closedFrame;
+	int _doorFlag;
+	int _doorFlagValue;
+};
+
+SpaceDoor::SpaceDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int openFrame, int closedFrame, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength,
+		int doorFlag, int doorFlagValue) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clicked = false;
+	_openFrame = openFrame;
+	_closedFrame = closedFrame;
+	_doorFlag = doorFlag;
+	_doorFlagValue = doorFlagValue;
+	_clickable = Common::Rect(left, top, right, bottom);
+	_destData.destinationScene = _staticData.location;
+	_destData.destinationScene.depth = depth;
+	_destData.transitionType = transitionType;
+	_destData.transitionData = transitionData;
+	_destData.transitionStartFrame = transitionStartFrame;
+	_destData.transitionLength = transitionLength;
+}
+
+int SpaceDoor::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation)) {
+		_clicked = true;
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int SpaceDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clicked) {
+		// If we are facing the scanning room door and we have Arthur, automatically recall
+		// to the future apartment
+		if (_staticData.location.timeZone == 6 && _staticData.location.environment == 3 &&
+				_staticData.location.node == 9 && _staticData.location.facing == 0 &&
+				_staticData.location.orientation == 0 && _staticData.location.depth == 0 &&
+				((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+			((SceneViewWindow *)viewWindow)->timeSuitJump(4);
+			return SC_TRUE;
+		}
+
+		if (_doorFlag < 0 || ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_doorFlag) == _doorFlagValue) {
+			// Change the still frame to the new one
+			if (_openFrame >= 0) {
+				_staticData.navFrameIndex = _openFrame;
+				viewWindow->invalidateWindow(false);
+				_vm->_sound->playSynchronousSoundEffect("BITDATA/AILAB/AI_LOCK.BTA");
+			}
+
+			((SceneViewWindow *)viewWindow)->moveToDestination(_destData);
+		} else {
+			// Display the closed frame
+			if (_closedFrame >= 0) {
+				_staticData.navFrameIndex = _closedFrame;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+
+		_clicked = false;
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int SpaceDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class DockingBayPlaySoundEntering : public SceneBase {
+public:
+	DockingBayPlaySoundEntering(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int soundFileNameID = -1, int flagOffset = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _soundFileNameID;
+	int _flagOffset;
+};
+
+DockingBayPlaySoundEntering::DockingBayPlaySoundEntering(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int soundFileNameID, int flagOffset) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundFileNameID = soundFileNameID;
+	_flagOffset = flagOffset;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1)
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+}
+
+int DockingBayPlaySoundEntering::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID));
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -1384,8 +1505,24 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlayArthurOffsetCapacitance(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, aiCRStingerID), offsetof(GlobalFlags, aiCRStingerChannelID), 4, 11, 1, offsetof(GlobalFlags, aiCRGrabbedMetalBar), 73, 320, 40);
 	case 28:
 		return new PlayArthurOffsetCapacitance(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, aiCRStingerID), offsetof(GlobalFlags, aiCRStingerChannelID), 4, 11, 1, offsetof(GlobalFlags, aiCRGrabbedMetalBar), 66, 241, 25);
+	case 30:
+		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 5, offsetof(GlobalFlags, aiDBPlayedFirstArthur));
+	case 31:
+		return new SpaceDoor(_vm, viewWindow, sceneStaticData, priorLocation, 174, 70, 256, 152, 166, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, 0);
 	case 32:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 33:
+		return new SpaceDoor(_vm, viewWindow, sceneStaticData, priorLocation, 185, 42, 253, 110, 167, -1, 1, TRANSITION_VIDEO, 1, -1, -1, -1, 0);
+	case 35:
+		return new DockingBayPlaySoundEntering(_vm, viewWindow, sceneStaticData, priorLocation, 4, offsetof(GlobalFlags, aiDBPlayedMomComment));
+	case 36:
+		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 6, offsetof(GlobalFlags, aiDBPlayedSecondArthur));
+	case 37:
+		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 7, offsetof(GlobalFlags, aiDBPlayedThirdArthur));
+	case 38:
+		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 8, offsetof(GlobalFlags, aiDBPlayedFourthArthur));
+	case 39:
+		return new DisableForwardMovement(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, generalWalkthroughMode), 1);
 	case 52:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 40, 276, 140, -1, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
 	case 53:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 3c07d3ee85..252f8121ba 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -206,6 +206,22 @@ int PlaySoundExitingFromSceneDeux::postExitRoom(Window *viewWindow, const Locati
 	return SC_TRUE;
 }
 
+PlaySoundEnteringScene::PlaySoundEnteringScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int soundFileNameID, int flagOffset) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundFileNameID = soundFileNameID;
+	_flagOffset = flagOffset;
+}
+
+int PlaySoundEnteringScene::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 0) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID));
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+	}
+
+	return SC_TRUE;
+}
+
 ClickChangeScene::ClickChangeScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int left, int top, int right, int bottom, int cursorID,
 		int timeZone, int environment, int node, int facing, int orientation, int depth,
@@ -436,6 +452,13 @@ int OneShotEntryVideoWarning::postEnterRoom(Window *viewWindow, const Location &
 	return SC_TRUE;
 }
 
+DisableForwardMovement::DisableForwardMovement(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, int flagValue) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) == flagValue)
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+}
+
 CycleEntryVideoWarning::CycleEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int animIDA, int animIDB, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
 	_animIDA = animIDA;
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 1f6722391e..d9c6be8e5c 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -91,6 +91,17 @@ private:
 	int _soundFileNameID;
 };
 
+class PlaySoundEnteringScene : public SceneBase {
+public:
+	PlaySoundEnteringScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int soundFileNameID = -1, int flagOffset = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _soundFileNameID;
+	int _flagOffset;
+};
+
 class ClickChangeScene : public SceneBase {
 public:
 	ClickChangeScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -201,6 +212,12 @@ private:
 	int _warningMessageID;
 };
 
+class DisableForwardMovement : public SceneBase {
+public:
+	DisableForwardMovement(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, int flagValue = 1);
+};
+
 class CycleEntryVideoWarning : public SceneBase {
 public:
 	CycleEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: cbf96064b69c672f5fc06f44df01f311a8e977bc
    https://github.com/scummvm/scummvm/commit/cbf96064b69c672f5fc06f44df01f311a8e977bc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the scanner room

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index de1fe8b93f..8f1b464a00 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -29,6 +29,7 @@
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
+#include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -1305,6 +1306,622 @@ int CapacitanceDockingBayDoor::specifyCursor(Window *viewWindow, const Common::P
 	return kCursorArrow;
 }
 
+class ScanningRoomEntryScan : public SceneBase {
+public:
+	ScanningRoomEntryScan(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	DestinationScene _savedForwardData;
+};
+
+ScanningRoomEntryScan::ScanningRoomEntryScan(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_savedForwardData = _staticData.destForward;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardInitialSpeech == 0)
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel > 0) {
+		if (_vm->_sound->isSoundEffectPlaying(((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel - 1))
+			_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		else
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = 0;
+	}
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus == 3)
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+}
+
+int ScanningRoomEntryScan::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardInitialSpeech == 0) {
+		// Play the scanning movie
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+
+		// Set the flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardInitialSpeech = 1;
+
+		// Start the initial monologue
+		byte channel = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 127, false, true) + 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = channel;
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomEntryScan::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == 6 && newLocation.environment == 4 && newLocation.node != 3 && newLocation.node != 0 &&
+			_staticData.location.timeZone == newLocation.timeZone) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128, false, true);
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomEntryScan::timerCallback(Window *viewWindow) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel > 0 && !_vm->_sound->isSoundEffectPlaying(((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel - 1)) {
+		_staticData.destForward = _savedForwardData;
+		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = 0;
+	}
+
+	return SC_TRUE;
+}
+
+class ScanningRoomWalkWarning : public SceneBase {
+public:
+	ScanningRoomWalkWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	DestinationScene _savedForwardData;
+};
+
+ScanningRoomWalkWarning::ScanningRoomWalkWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_savedForwardData = _staticData.destForward;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel > 0) {
+		if (_vm->_sound->isSoundEffectPlaying(((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel - 1))
+			_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		else
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = 0;
+	}
+}
+
+int ScanningRoomWalkWarning::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == 6 && newLocation.environment == 4 && newLocation.node != 3 && newLocation.node != 0 &&
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCMoveCenterWarning == 0) {
+		if (_staticData.location.timeZone == newLocation.timeZone)
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128, false, true);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCMoveCenterWarning = 1;
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomWalkWarning::timerCallback(Window *viewWindow) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel > 0 && !_vm->_sound->isSoundEffectPlaying(((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel - 1)) {
+		_staticData.destForward = _savedForwardData;
+		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = 0;
+	}
+
+	return SC_TRUE;
+}
+
+class ScanningRoomDockingBayDoor : public SceneBase {
+public:
+	ScanningRoomDockingBayDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int timerCallback(Window *viewWindow);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _audioEnded;
+	Common::Rect _doorRegion;
+};
+
+ScanningRoomDockingBayDoor::ScanningRoomDockingBayDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_audioEnded = true;
+	_doorRegion = Common::Rect(152, 34, 266, 148);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel > 0) {
+		if (!_vm->_sound->isSoundEffectPlaying(((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel - 1)) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = 0;
+			_audioEnded = true;
+		} else {
+			_audioEnded = false;
+		}
+	}
+}
+
+int ScanningRoomDockingBayDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_audioEnded && _doorRegion.contains(pointLocation)) {
+		// Change the still frame
+		int oldFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = 46;
+		viewWindow->invalidateWindow(false);
+
+		// Play the beep and voiceovers
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 1, 12));
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 1, 13));
+
+		// Reset the frame
+		_staticData.navFrameIndex = oldFrame;
+		viewWindow->invalidateWindow(false);
+
+		// Play Arthur's voiceover
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCDBDoorWarning == 0) {
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCDBDoorWarning = 1;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ScanningRoomDockingBayDoor::timerCallback(Window *viewWindow) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel > 0 && !_vm->_sound->isSoundEffectPlaying(((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel - 1)) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCInitialAudioChannel = 0;
+		_audioEnded = true;
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomDockingBayDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_audioEnded && _doorRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class ScanningRoomScienceWingDoor : public SceneBase {
+public:
+	ScanningRoomScienceWingDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _doorRegion;
+};
+
+ScanningRoomScienceWingDoor::ScanningRoomScienceWingDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_doorRegion = Common::Rect(152, 34, 266, 148);
+}
+
+int ScanningRoomScienceWingDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorRegion.contains(pointLocation)) {
+		// Change the still frame
+		int oldFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = 44;
+		viewWindow->invalidateWindow(false);
+
+		// Play the beep and voiceovers
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 1, 12));
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 1, 13));
+
+		// Reset the frame
+		_staticData.navFrameIndex = oldFrame;
+		viewWindow->invalidateWindow(false);
+	}
+
+	return SC_FALSE;
+}
+
+int ScanningRoomScienceWingDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class ArthurScanningRoomConversation : public SceneBase {
+public:
+	ArthurScanningRoomConversation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _yes;
+	Common::Rect _no;
+};
+
+ArthurScanningRoomConversation::ArthurScanningRoomConversation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_yes = Common::Rect(152, 54, 284, 124);
+	_no = Common::Rect(194, 128, 244, 152);
+}
+
+int ArthurScanningRoomConversation::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// If this is the initial entry, play Arthur's comment
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus == 0) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCPlayedNoStinger = 0;
+	}
+
+	_staticData.cycleStartFrame = 0;
+	_staticData.cycleFrameCount = 20;
+	_staticData.navFrameIndex = 37;
+	viewWindow->invalidateWindow(false);
+	return SC_TRUE;
+}
+
+int ArthurScanningRoomConversation::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_yes.contains(pointLocation)) {
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus) {
+		case 1: // Proceed with scan, then ask about downloading into biochips
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
+			_staticData.navFrameIndex = 36;
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
+			_staticData.navFrameIndex = 37;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus = 2;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCPlayedNoStinger = 0;
+			viewWindow->invalidateWindow(false); // Original doesn't do this, but I can't see how it works otherwise
+			return SC_TRUE;
+		case 2: { // Proceed with downloading
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
+			_staticData.navFrameIndex = 36;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus = 3;
+
+			// Move the player back and play the instructions for the door
+			DestinationScene destData;
+			destData.destinationScene = Location(6, 4, 1, 2, 1, 0);
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 0;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		}
+		}
+	} else if (_no.contains(pointLocation)) {
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus) {
+		case 1: { // No-go on the scan, so drop the player back and play the rejection sound file
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCPlayedNoStinger == 0) {
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9), 128, false, true);
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCPlayedNoStinger = 1;
+			}
+
+			DestinationScene destData;
+			destData.destinationScene = Location(6, 4, 1, 2, 1, 0);
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 0;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		}
+		case 2: { // No-go on the download, so drop the player back and play the rejection sound file
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCPlayedNoStinger == 0) {
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCPlayedNoStinger = 1;
+			}
+
+			DestinationScene destData;
+			destData.destinationScene = Location(6, 4, 1, 2, 1, 0);
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 0;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		}
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ArthurScanningRoomConversation::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_yes.contains(pointLocation) || _no.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class ScanningRoomNexusDoorNormalFacing : public SceneBase {
+public:
+	ScanningRoomNexusDoorNormalFacing(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickable;
+};
+
+ScanningRoomNexusDoorNormalFacing::ScanningRoomNexusDoorNormalFacing(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickable = Common::Rect(162, 67, 284, 189);
+}
+
+int ScanningRoomNexusDoorNormalFacing::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardNexusDoorComment == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus == 3) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardNexusDoorComment = 1;
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomNexusDoorNormalFacing::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation)) {
+		// Change the still frame
+		int oldFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = 43;
+		viewWindow->invalidateWindow(false);
+
+		// Play the beep and voiceovers
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 1, 12));
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, 1, 13));
+
+		// Reset the frame
+		_staticData.navFrameIndex = oldFrame;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ScanningRoomNexusDoorNormalFacing::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class ScanningRoomNexusDoorZoomInCodePad : public SceneBase {
+public:
+	ScanningRoomNexusDoorZoomInCodePad(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _controls;
+};
+
+ScanningRoomNexusDoorZoomInCodePad::ScanningRoomNexusDoorZoomInCodePad(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_controls = Common::Rect(160, 50, 282, 140);
+}
+
+int ScanningRoomNexusDoorZoomInCodePad::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation)) {
+		DestinationScene destinationData;
+		destinationData.destinationScene = _staticData.location;
+		destinationData.destinationScene.depth = 1;
+		destinationData.transitionType = TRANSITION_VIDEO;
+		destinationData.transitionData = 1;
+		destinationData.transitionStartFrame = -1;
+		destinationData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ScanningRoomNexusDoorZoomInCodePad::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class ScanningRoomNexusDoorCodePad : public SceneBase {
+public:
+	ScanningRoomNexusDoorCodePad(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~ScanningRoomNexusDoorCodePad();
+	void preDestructor();
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int onCharacter(Window *viewWindow, const Common::KeyState &character);
+	int gdiPaint(Window *viewWindow);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _numbers[10];
+	Common::String _entries;
+	Graphics::Font *_textFont;
+	int _lineHeight;
+	Common::Rect _display;
+};
+
+ScanningRoomNexusDoorCodePad::ScanningRoomNexusDoorCodePad(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_numbers[0] = Common::Rect(200, 129, 229, 146);
+	_numbers[1] = Common::Rect(165, 63, 194, 80);
+	_numbers[2] = Common::Rect(200, 63, 229, 80);
+	_numbers[3] = Common::Rect(235, 63, 264, 80);
+	_numbers[4] = Common::Rect(165, 85, 194, 102);
+	_numbers[5] = Common::Rect(200, 85, 229, 102);
+	_numbers[6] = Common::Rect(235, 85, 264, 102);
+	_numbers[7] = Common::Rect(165, 107, 194, 124);
+	_numbers[8] = Common::Rect(200, 107, 229, 124);
+	_numbers[9] = Common::Rect(235, 107, 264, 124);
+	_display = Common::Rect(166, 40, 262, 58);
+	_lineHeight = _vm->getLanguage() == Common::JA_JPN ? 12 : 14;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+ScanningRoomNexusDoorCodePad::~ScanningRoomNexusDoorCodePad() {
+	preDestructor();
+}
+
+void ScanningRoomNexusDoorCodePad::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int ScanningRoomNexusDoorCodePad::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Play Arthur's comment, if applicable
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardNexusDoorCode == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus == 3) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardNexusDoorCode = 1;
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomNexusDoorCodePad::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 10; i++) {
+		if (_numbers[i].contains(pointLocation)) {
+			if (_entries.size() < 5) {
+				// Append
+				_entries += (char)('0' + i);
+				viewWindow->invalidateWindow(false);
+
+				if (_entries == "32770") {
+					// If the answer is correct, move to the depth with the open hatch movie
+					DestinationScene destinationData;
+					destinationData.destinationScene = _staticData.location;
+					destinationData.destinationScene.depth = 2;
+					destinationData.transitionType = TRANSITION_VIDEO;
+					destinationData.transitionData = 3;
+					destinationData.transitionStartFrame = -1;
+					destinationData.transitionLength = -1;
+					((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+				}
+
+				return SC_TRUE;
+			} else {
+				// Reset
+				_entries = (char)('0' + i);
+				viewWindow->invalidateWindow(false);
+				return SC_TRUE;
+			}
+		}
+	}
+
+	DestinationScene destinationData;
+	destinationData.destinationScene = _staticData.location;
+	destinationData.destinationScene.depth = 0;
+	destinationData.transitionType = TRANSITION_VIDEO;
+	destinationData.transitionData = 2;
+	destinationData.transitionStartFrame = -1;
+	destinationData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+	return SC_TRUE;
+}
+
+int ScanningRoomNexusDoorCodePad::onCharacter(Window *viewWindow, const Common::KeyState &character) {
+	if (character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9) {
+		char c = (char)('0' + character.keycode - Common::KEYCODE_0);
+
+		if (_entries.size() < 5) {
+			// Append
+			_entries += c;
+			viewWindow->invalidateWindow(false);
+
+			if (_entries == "32770") {
+				// If the answer is correct, move to the depth with the open hatch movie
+				DestinationScene destinationData;
+				destinationData.destinationScene = _staticData.location;
+				destinationData.destinationScene.depth = 2;
+				destinationData.transitionType = TRANSITION_VIDEO;
+				destinationData.transitionData = 3;
+				destinationData.transitionStartFrame = -1;
+				destinationData.transitionLength = -1;
+				((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+			}
+
+			return SC_TRUE;
+		} else {
+			// Reset
+			_entries = c;
+			viewWindow->invalidateWindow(false);
+			return SC_TRUE;
+		}
+	}
+
+	if ((character.keycode == Common::KEYCODE_BACKSPACE || character.keycode == Common::KEYCODE_DELETE) && !_entries.empty()) {
+		// Delete last character
+		_entries.deleteLastChar();
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ScanningRoomNexusDoorCodePad::gdiPaint(Window *viewWindow) {
+	if (!_entries.empty()) {
+		uint32 textColor = _vm->_gfx->getColor(208, 144, 24);
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_display);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, _entries, rect.left, rect.top, rect.width(), rect.height(), textColor, _lineHeight, kTextAlignLeft, true);
+	}
+
+	return SC_REPAINT;
+}
+
+int ScanningRoomNexusDoorCodePad::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 10; i++)
+		if (_numbers[i].contains(pointLocation))
+			return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+class ScanningRoomNexusDoorPullHandle : public SceneBase {
+public:
+	ScanningRoomNexusDoorPullHandle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _handle;
+};
+
+ScanningRoomNexusDoorPullHandle::ScanningRoomNexusDoorPullHandle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_handle = Common::Rect(186, 44, 276, 154);
+}
+
+int ScanningRoomNexusDoorPullHandle::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Play Arthur's comment, if applicable
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardNexusDoorCode == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus == 3) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCHeardNexusDoorCode = 1;
+	}
+
+	return SC_TRUE;
+}
+
+int ScanningRoomNexusDoorPullHandle::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_handle.contains(pointLocation)) {
+		DestinationScene destinationData;
+		destinationData.destinationScene = Location(6, 5, 0, 0, 1, 0);
+		destinationData.transitionType = TRANSITION_VIDEO;
+		destinationData.transitionData = 4;
+		destinationData.transitionStartFrame = -1;
+		destinationData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ScanningRoomNexusDoorPullHandle::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_handle.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class SpaceDoor : public SceneBase {
 public:
 	SpaceDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -1396,6 +2013,17 @@ int SpaceDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocat
 	return kCursorArrow;
 }
 
+class ScanningRoomNexusDoorToGlobe : public SceneBase {
+public:
+	ScanningRoomNexusDoorToGlobe(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+};
+
+ScanningRoomNexusDoorToGlobe::ScanningRoomNexusDoorToGlobe(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSCConversationStatus == 3)
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+}
+
 class DockingBayPlaySoundEntering : public SceneBase {
 public:
 	DockingBayPlaySoundEntering(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -1523,6 +2151,26 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 8, offsetof(GlobalFlags, aiDBPlayedFourthArthur));
 	case 39:
 		return new DisableForwardMovement(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, generalWalkthroughMode), 1);
+	case 40:
+		return new ScanningRoomEntryScan(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 41:
+		return new ScanningRoomWalkWarning(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 42:
+		return new ScanningRoomDockingBayDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 43:
+		return new ScanningRoomScienceWingDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 44:
+		return new ArthurScanningRoomConversation(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 45:
+		return new ScanningRoomNexusDoorNormalFacing(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 46:
+		return new ScanningRoomNexusDoorZoomInCodePad(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 47:
+		return new ScanningRoomNexusDoorCodePad(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 48:
+		return new ScanningRoomNexusDoorPullHandle(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 49:
+		return new ScanningRoomNexusDoorToGlobe(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 52:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 40, 276, 140, -1, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
 	case 53:


Commit: ceb175329fa19945504db3b1711fe515d4182529
    https://github.com/scummvm/scummvm/commit/ceb175329fa19945504db3b1711fe515d4182529
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the AI Nexus puzzle

Arthur!

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/resources.h


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 8f1b464a00..d980d72271 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -427,6 +427,319 @@ int PlayArthurOffsetTimed::postEnterRoom(Window *viewWindow, const Location &pri
 	return SC_TRUE;
 }
 
+class NexusDoor : public BaseOxygenTimer {
+public:
+	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	uint32 _entryStartTime;
+	Common::Rect _door;
+	bool _jumped;
+};
+
+NexusDoor::NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_door = Common::Rect(148, 30, 328, 192);
+}
+
+int NexusDoor::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	BaseOxygenTimer::postEnterRoom(viewWindow, priorLocation);
+
+	if (priorLocation.environment != _staticData.location.environment || priorLocation.timeZone != _staticData.location.timeZone) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = GC_AIHW_STARTING_VALUE;
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_ENTERING_NON_PRES_ENV_TEXT));
+	}
+
+	return SC_TRUE;
+}
+
+int NexusDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_door.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = Location(6, 5, 1, 0, 1, 0);
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 0;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int NexusDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_door.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class NexusPuzzle : public SceneBase {
+public:
+	NexusPuzzle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _lights[7];
+	int _data[7];
+	bool _resetMessage;
+};
+
+NexusPuzzle::NexusPuzzle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_data[0] = 2;
+	_data[1] = 2;
+	_data[2] = 2;
+	_data[3] = 0;
+	_data[4] = 1;
+	_data[5] = 1;
+	_data[6] = 1;
+
+	_lights[0] = Common::Rect(209, 39, 225, 47);
+	_lights[1] = Common::Rect(209, 52, 225, 63);
+	_lights[2] = Common::Rect(209, 71, 225, 84);
+	_lights[3] = Common::Rect(209, 90, 225, 106);
+	_lights[4] = Common::Rect(209, 110, 225, 123);
+	_lights[5] = Common::Rect(209, 126, 225, 137);
+	_lights[6] = Common::Rect(209, 140, 225, 148);
+
+	_resetMessage = false;
+}
+
+int NexusPuzzle::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// If we came from outside (node zero), display the atmosphere message
+	if (priorLocation.node == 0) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_ENTERING_PRES_ENV_TEXT));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = GC_AIHW_STARTING_VALUE;
+	}
+
+	// Check to see if we heard the brain comment before
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiNXPlayedBrainComment == 0) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiNXPlayedBrainComment = 1;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0) {
+			// Play a synchronous comment here to introduce the player to the puzzle
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9));
+		} else {
+			// Play a synchronous comment to introduce what is about to happen
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+			// Play the Farnstein voiceover
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14));
+
+			// Move to the next node, playing the Arthur retrieval movie
+			DestinationScene destData;
+			destData.destinationScene = _staticData.location;
+			destData.destinationScene.node = 2;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 1;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int NexusPuzzle::gdiPaint(Window *viewWindow) {
+	// Puzzle is only in adventure mode
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1)
+		return SC_REPAINT;
+
+	uint32 green = _vm->_gfx->getColor(0, 255, 0);
+	uint32 red = _vm->_gfx->getColor(255, 0, 0);
+	Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+
+	for (int i = 0; i < 7; i++) {
+		if (_data[i] != 0) {
+			uint32 color = (_data[i] == 1) ? green : red;
+
+			Common::Rect rect(_lights[i]);
+			rect.translate(absoluteRect.left, absoluteRect.top);
+			rect.left++;
+			rect.top++;
+
+			_vm->_gfx->drawEllipse(rect, color);
+		}
+	}
+
+	return SC_REPAINT;
+}
+	
+int NexusPuzzle::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	// Puzzle is only in adventure mode
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1)
+		return SC_FALSE;
+
+	// Reset the live text, if the puzzle was reset
+	if (_resetMessage) {
+		((SceneViewWindow *)viewWindow)->displayLiveText("");
+		_resetMessage = false;
+	}
+
+	// Check to see if we clicked on any of the colored circles, and if a jump is allowed
+	for (int i = 0; i < 7; i++) {
+		if (_lights[i].contains(pointLocation) && _data[i] != 0) {
+			if (_data[i] == 1) {
+				// Can we move up one?
+				if (i > 0) {
+					if (_data[i - 1] == 0) {
+						_data[i - 1] = _data[i];
+						_data[i] = 0;
+						viewWindow->invalidateWindow(false);
+					} else if (i > 1 && _data[i - 2] == 0) {
+						_data[i - 2] = _data[i];
+						_data[i] = 0;
+						viewWindow->invalidateWindow(false);
+					}
+				}
+			} else {
+				if (i < 6) {
+					if (_data[i + 1] == 0) {
+						_data[i + 1] = _data[i];
+						_data[i] = 0;
+						viewWindow->invalidateWindow(false);
+					} else if (i < 5 && _data[i + 2] == 0) {
+						_data[i + 2] = _data[i];
+						_data[i] = 0;
+						viewWindow->invalidateWindow(false);
+					}
+				}
+			}
+
+			// Check to see if we completed the puzzle
+			if (_data[0] == 1 && _data[1] == 1 && _data[2] == 1 && _data[3] == 0 && _data[4] == 2 && _data[5] == 2 && _data[6] == 2) {
+				// Play the Farnstein voiceover
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14));
+
+				// Move to the next node, playing the Arthur retrieval movie
+				DestinationScene destData;
+				destData.destinationScene = _staticData.location;
+				destData.destinationScene.node = 2;
+				destData.transitionType = TRANSITION_VIDEO;
+				destData.transitionData = 1;
+				destData.transitionStartFrame = -1;
+				destData.transitionLength = -1;
+				((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+				return SC_TRUE;
+			}
+
+			// Check to see that we can still make valid moves
+			bool validMove = false;
+			for (int j = 0; j < 7; j++) {
+				if (_data[j] == 1) {
+					if (j > 1 && _data[j - 2] == 0) {
+						validMove = true;
+						break;
+					}
+
+					if (j > 0 && _data[j - 1] == 0) {
+						validMove = true;
+						break;
+					}
+				} else if (_data[j] == 2) {
+					if (j < 5 && _data[j + 2] == 0) {
+						validMove = true;
+						break;
+					}
+
+					if (j < 6 && _data[j + 1] == 0) {
+						validMove = true;
+						break;
+					}
+				}
+			}
+
+			if (!validMove) {
+				// Reset the puzzle
+				_data[0] = 2;
+				_data[1] = 2;
+				_data[2] = 2;
+				_data[3] = 0;
+				_data[4] = 1;
+				_data[5] = 1;
+				_data[6] = 1;
+				viewWindow->invalidateWindow(false);
+
+				Common::String text;
+				if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+					text = _vm->getString(IDS_AI_NX_CODE_RESET_MESSAGE);
+				else
+					text = "Unable to complete in current state. Resetting code lock.";
+
+				((SceneViewWindow *)viewWindow)->displayLiveText(text);
+				_resetMessage = true;
+			}
+
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int NexusPuzzle::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	// Puzzle is only in adventure mode
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1)
+		return kCursorArrow;
+
+	for (int i = 0; i < 7; i++)
+		if (_lights[i].contains(pointLocation) && _data[i] != 0) // In the liiiiiight
+			return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class NexusEnd : public SceneBase {
+public:
+	NexusEnd(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+NexusEnd::NexusEnd(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int NexusEnd::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (!((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+		// Congrats, you have Arthur!
+
+		// Swap and activate the chips
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->removeItem(kItemBioChipBlank);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemBioChipAI);
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipAI);
+
+		// Play Arthur's comments
+
+		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->_forceComment = true;
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->invalidateWindow(false);
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10));
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->_forceComment = false;
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->_forceHelp = true;
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->invalidateWindow(false);
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11));
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->_forceHelp = false;
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->invalidateWindow(false);
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12));
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
+		_vm->_gfx->setCursor(oldCursor);
+	}
+
+	return SC_TRUE;
+}
+
 class HabitatWingLockedDoor : public BaseOxygenTimer {
 public:
 	HabitatWingLockedDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -2189,6 +2502,12 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 92, 92, 212, 189, 48, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
 	case 75:
 		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 51, 4, 5, 146, 0, 396, 84);
+	case 90:
+		return new NexusDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 91:
+		return new NexusPuzzle(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 92:
+		return new NexusEnd(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 93:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index fccd72bab3..0ba2047adf 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -798,4 +798,38 @@ void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, c
 	}
 }
 
+void GraphicsManager::drawEllipse(const Common::Rect &rect, uint32 color) {
+	// HACK: This just hardcodes the sizes of the rows of the ellipses
+	// for the one thing in the game that needs it.
+
+	static const int rows7[7] = { 7, 13, 15, 15, 15, 13, 7 };
+	static const int rows10[10] = { 7, 11, 13, 15, 15, 15, 15, 13, 11, 7 };
+	static const int rows12[12] = { 7, 11, 13, 13, 15, 15, 15, 15, 13, 13, 11, 7 };
+	static const int rows15[15] = { 5, 9, 11, 13, 13, 15, 15, 15, 15, 15, 13, 13, 11, 9, 5 };
+
+	const int *table = 0;
+	switch (rect.height()) {
+	case 7:
+		table = rows7;
+		break;
+	case 10:
+		table = rows10;
+		break;
+	case 12:
+		table = rows12;
+		break;
+	case 15:
+		table = rows15;
+		break;
+	}
+
+	assert(table);
+
+	for (int y = 0; y < rect.height(); y++) {
+		int width = table[y];
+		int x = rect.left + (rect.width() - width) / 2;
+		_screen->hLine(x, y + rect.top, x + width, color);
+	}
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index c6c65041aa..c9232bcbf0 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -101,6 +101,7 @@ public:
 	bool checkPointAgainstMaskedBitmap(const Graphics::Surface *bitmap, int x, int y, const Common::Point &point, byte rTrans, byte gTrans, byte bTrans);
 	void crossBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc);
 	void renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, int h, uint32 color, int lineHeight, TextAlign textAlign = kTextAlignLeft, bool centerVertically = false);
+	void drawEllipse(const Common::Rect &rect, uint32 color);
 
 	Graphics::Surface *remapPalettedFrame(const Graphics::Surface *frame, const byte *palette);
 
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 1c34929d2e..5ba7ba9f8b 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -160,6 +160,9 @@ namespace Buried {
 
 #define IDS_AI_IS_JUMP_IN_TEXT                  1755
 
+// 1.04+:
+#define IDS_AI_NX_CODE_RESET_MESSAGE    1768
+
 
 #define IDS_DEATH_SCENE_MESSAGE_TEXT_BASE		1800
 #define IDS_DEATH_SCENE_CAUSE_TEXT_BASE			1801


Commit: f986fc85fedc1336b19e898fcf63c994e17401b3
    https://github.com/scummvm/scummvm/commit/f986fc85fedc1336b19e898fcf63c994e17401b3
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Fix Arthur's commenting

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 81b2122fd6..7a86e19b81 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2032,7 +2032,7 @@ bool SceneViewWindow::playAICommentFromData(const AIComment &commentData) {
 			return false;
 		}
 		break;
-	case 3: // Future Apartment
+	case 4: // Future Apartment
 		commentFileName += "FUTAPT/";
 
 		switch (commentData.location.environment) {
@@ -2049,7 +2049,7 @@ bool SceneViewWindow::playAICommentFromData(const AIComment &commentData) {
 			return false;
 		}
 		break;
-	case 4: // Da Vinci
+	case 5: // Da Vinci
 		commentFileName += "DAVINCI/";
 
 		switch (commentData.location.environment) {
@@ -2072,7 +2072,7 @@ bool SceneViewWindow::playAICommentFromData(const AIComment &commentData) {
 			return false;
 		}
 		break;
-	case 5: // Space Station
+	case 6: // Space Station
 		commentFileName += "AILAB/";
 
 		switch (commentData.location.environment) {
@@ -2542,7 +2542,7 @@ Common::Array<AnimEvent> SceneViewWindow::getAnimationDatabase(int timeZone, int
 }
 
 Common::Array<AIComment> SceneViewWindow::getAICommentDatabase(int timeZone, int environment) {
-	Common::SeekableReadStream *stream = _vm->getAnimData(_vm->computeAIDBResourceID(timeZone, environment));
+	Common::SeekableReadStream *stream = _vm->getAIData(_vm->computeAIDBResourceID(timeZone, environment));
 	Common::Array<AIComment> comments;
 
 	if (!stream)


Commit: 57ddbd0890e6f0661d70ea8df495da79fe98d456
    https://github.com/scummvm/scummvm/commit/57ddbd0890e6f0661d70ea8df495da79fe98d456
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the Iceteroid door

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index d980d72271..237519afa8 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -427,6 +427,69 @@ int PlayArthurOffsetTimed::postEnterRoom(Window *viewWindow, const Location &pri
 	return SC_TRUE;
 }
 
+class HabitatWingIceteroidDoor : public BaseOxygenTimer {
+public:
+	HabitatWingIceteroidDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _doorHandle;
+};
+
+HabitatWingIceteroidDoor::HabitatWingIceteroidDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_doorHandle = Common::Rect(122, 48, 246, 172);
+}
+
+int HabitatWingIceteroidDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorHandle.contains(pointLocation)) {
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+			if (((SceneViewWindow * )viewWindow)->getGlobalFlags().aiHWIceDoorUnlocked == 0) {
+				// Move to depth one (door open)
+				DestinationScene destData;
+				destData.destinationScene = _staticData.location;
+				destData.destinationScene.depth = 1;
+				destData.transitionType = TRANSITION_VIDEO;
+				destData.transitionData = 6;
+				destData.transitionStartFrame = -1;
+				destData.transitionLength = -1;
+				((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+
+				// Add the explosive charge to your inventory
+				((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemExplosiveCharge);
+
+				// Set the door unlocked flag
+				((SceneViewWindow * )viewWindow)->getGlobalFlags().aiHWIceDoorUnlocked = 1;
+			} else {
+				// Move to depth one (door open)
+				DestinationScene destData;
+				destData.destinationScene = _staticData.location;
+				destData.destinationScene.depth = 1;
+				destData.transitionType = TRANSITION_VIDEO;
+				destData.transitionData = 3;
+				destData.transitionStartFrame = -1;
+				destData.transitionLength = -1;
+				((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			}
+		} else {
+			// Play the closed door video clip
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int HabitatWingIceteroidDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorHandle.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class NexusDoor : public BaseOxygenTimer {
 public:
 	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2424,6 +2487,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 99, 12, 13, 166, 32, 286, 182);
 	case 8:
 		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 100, 12, 13, 130, 48, 290, 189);
+	case 9:
+		return new HabitatWingIceteroidDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 11:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:


Commit: b1d44240b2bca6060e82f63188d5c9f929c14fff
    https://github.com/scummvm/scummvm/commit/b1d44240b2bca6060e82f63188d5c9f929c14fff
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the Iceteroid pods

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 237519afa8..2273ce35de 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -490,6 +490,45 @@ int HabitatWingIceteroidDoor::specifyCursor(Window *viewWindow, const Common::Po
 	return kCursorArrow;
 }
 
+class IceteroidPodTimed : public BaseOxygenTimer {
+public:
+	IceteroidPodTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int animID = -1, int timeZone = -1,
+			int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _engageButton;
+	DestinationScene _clickDestination;
+};
+
+IceteroidPodTimed::IceteroidPodTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left, int top, int right, int bottom, int animID, int timeZone,
+			int environment, int node, int facing, int orientation, int depth) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_engageButton = Common::Rect(left, top, right, bottom);
+	_clickDestination.destinationScene = Location(timeZone, environment, node, facing, orientation, depth);
+	_clickDestination.transitionType = TRANSITION_VIDEO;
+	_clickDestination.transitionData = animID;
+	_clickDestination.transitionStartFrame = -1;
+	_clickDestination.transitionLength = -1;
+}
+
+int IceteroidPodTimed::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_engageButton.contains(pointLocation)) // Make it so!
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int IceteroidPodTimed::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_engageButton.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class NexusDoor : public BaseOxygenTimer {
 public:
 	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2549,6 +2588,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new ScanningRoomNexusDoorPullHandle(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 49:
 		return new ScanningRoomNexusDoorToGlobe(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 50:
+		return new IceteroidPodTimed(_vm, viewWindow, sceneStaticData, priorLocation, 174, 96, 246, 118, 1, 6, 6, 1, 0, 1, 0);
+	case 51:
+		return new IceteroidPodTimed(_vm, viewWindow, sceneStaticData, priorLocation, 174, 96, 246, 118, 3, 6, 6, 0, 0, 1, 0);
 	case 52:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 40, 276, 140, -1, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
 	case 53:
@@ -2557,6 +2600,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 60:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 63:
+		return new IceteroidPodTimed(_vm, viewWindow, sceneStaticData, priorLocation, 174, 96, 246, 118, 14, 6, 6, 5, 0, 1, 0);
+	case 64:
+		return new IceteroidPodTimed(_vm, viewWindow, sceneStaticData, priorLocation, 174, 96, 246, 118, 15, 6, 6, 4, 0, 1, 0);
 	case 65:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 26, 268, 124, -1, -1, 1, TRANSITION_VIDEO, 13, -1, -1, -1, -1);
 	case 66:


Commit: f4a82540879a94cf3ece17d7ce89575fcd19f7f8
    https://github.com/scummvm/scummvm/commit/f4a82540879a94cf3ece17d7ce89575fcd19f7f8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the Iceteroid elevator

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 2273ce35de..92abcec268 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -529,6 +529,64 @@ int IceteroidPodTimed::specifyCursor(Window *viewWindow, const Common::Point &po
 	return kCursorArrow;
 }
 
+class IceteroidElevatorExtremeControls : public BaseOxygenTimer {
+public:
+	IceteroidElevatorExtremeControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int upTimeZone = -1, int upEnvironment = -1, int upNode = -1, int upFacing = -1, int upOrientation = -1, int upDepth = -1, int upAnimID = -1,
+			int downTimeZone = -1, int downEnvironment = -1, int downNode = -1, int downFacing = -1, int downOrientation = -1, int downDepth = -1, int downAnimID = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _up, _down;
+	DestinationScene _upDestination;
+	DestinationScene _downDestination;
+};
+
+IceteroidElevatorExtremeControls::IceteroidElevatorExtremeControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int upTimeZone, int upEnvironment, int upNode, int upFacing, int upOrientation, int upDepth, int upAnimID,
+		int downTimeZone, int downEnvironment, int downNode, int downFacing, int downOrientation, int downDepth, int downAnimID) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_up = Common::Rect(192, 123, 212, 143);
+	_down = Common::Rect(192, 148, 212, 168);
+
+	_upDestination.destinationScene = Location(upTimeZone, upEnvironment, upNode, upFacing, upOrientation, upDepth);
+	_upDestination.transitionType = TRANSITION_VIDEO;
+	_upDestination.transitionData = upAnimID;
+	_upDestination.transitionStartFrame = -1;
+	_upDestination.transitionLength = -1;
+
+	_downDestination.destinationScene = Location(downTimeZone, downEnvironment, downNode, downFacing, downOrientation, downDepth);
+	_downDestination.transitionType = TRANSITION_VIDEO;
+	_downDestination.transitionData = downAnimID;
+	_downDestination.transitionStartFrame = -1;
+	_downDestination.transitionLength = -1;
+}
+
+int IceteroidElevatorExtremeControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_up.contains(pointLocation) && _upDestination.transitionData >= 0) {
+		((SceneViewWindow *)viewWindow)->moveToDestination(_upDestination);
+		return SC_TRUE;
+	}
+
+	if (_down.contains(pointLocation) && _downDestination.transitionData >= 0) {
+		((SceneViewWindow *)viewWindow)->moveToDestination(_downDestination);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int IceteroidElevatorExtremeControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_up.contains(pointLocation) && _upDestination.transitionData >= 0)
+		return kCursorFinger;
+
+	if (_down.contains(pointLocation) && _downDestination.transitionData >= 0)
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class NexusDoor : public BaseOxygenTimer {
 public:
 	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2598,6 +2656,12 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 40, 276, 140, -1, -1, 1, TRANSITION_VIDEO, 2, -1, -1, -1, -1);
 	case 54:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 55:
+		return new IceteroidElevatorExtremeControls(_vm, viewWindow, sceneStaticData, priorLocation, 6, 6, 6, 0, 1, 0, 6);
+	case 56:
+		return new IceteroidElevatorExtremeControls(_vm, viewWindow, sceneStaticData, priorLocation, 6, 6, 3, 0, 1, 0, 5, 6, 6, 2, 0, 1, 0, 7);
+	case 57:
+		return new IceteroidElevatorExtremeControls(_vm, viewWindow, sceneStaticData, priorLocation, -1, -1, -1, -1, -1, -1, -1, 6, 6, 6, 0, 1, 0, 4);
 	case 60:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 63:


Commit: 5e146eaffbc9d95e8374e44ab40cc9150f125e41
    https://github.com/scummvm/scummvm/commit/5e146eaffbc9d95e8374e44ab40cc9150f125e41
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the science wing stingers

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 92abcec268..3e2a2fa2bd 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -587,6 +587,37 @@ int IceteroidElevatorExtremeControls::specifyCursor(Window *viewWindow, const Co
 	return kCursorArrow;
 }
 
+class ScienceWingStingersTimed : public BaseOxygenTimer {
+public:
+	ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+ScienceWingStingersTimed::ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int ScienceWingStingersTimed::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	BaseOxygenTimer::postEnterRoom(viewWindow, priorLocation);
+
+	byte effectID = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSWStingerChannelID;
+
+	if (!_vm->_sound->isSoundEffectPlaying(effectID - 1)) {
+		byte &lastStinger = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSWStingerID;
+
+		byte newStingerID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, lastStinger + 7)) + 1;
+
+		lastStinger++;
+		if (lastStinger > 3)
+			lastStinger = 0;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSWStingerChannelID = newStingerID;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSWStingerID = lastStinger;
+	}
+
+	return SC_TRUE;
+}
+
 class NexusDoor : public BaseOxygenTimer {
 public:
 	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2676,6 +2707,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 70:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 92, 92, 212, 189, 48, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
+	case 74:
+		return new ScienceWingStingersTimed(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 75:
 		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 51, 4, 5, 146, 0, 396, 84);
 	case 90:


Commit: b6f398a9225f38e8f7a6ea18bef2a0b360219281
    https://github.com/scummvm/scummvm/commit/b6f398a9225f38e8f7a6ea18bef2a0b360219281
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement picking up the water canister

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 3e2a2fa2bd..faf40ef382 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -587,6 +587,54 @@ int IceteroidElevatorExtremeControls::specifyCursor(Window *viewWindow, const Co
 	return kCursorArrow;
 }
 
+class TakeWaterCanister : public BaseOxygenTimer {
+public:
+	TakeWaterCanister(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _canister;
+}; 
+
+TakeWaterCanister::TakeWaterCanister(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_canister = Common::Rect(232, 76, 376, 134);
+
+	// If the canister has not been taken, change the still
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICTakenWaterCanister == 0)
+		_staticData.navFrameIndex = 111;
+}
+
+int TakeWaterCanister::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_canister.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICTakenWaterCanister == 0) {
+		// Set the frame
+		_staticData.navFrameIndex = 51;
+
+		// Walkthrough mode skips the filling the canister puzzle and gets it filled already
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICTakenWaterCanister = 1;
+		int itemID = (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) ? kItemWaterCanFull : kItemWaterCanEmpty;
+
+		// Start dragging
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(itemID, ptInventoryWindow);
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+	
+int TakeWaterCanister::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_canister.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICTakenWaterCanister == 0)
+		return kCursorOpenHand;
+
+	return kCursorArrow;
+}
+
 class ScienceWingStingersTimed : public BaseOxygenTimer {
 public:
 	ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2703,6 +2751,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 26, 268, 124, -1, -1, 1, TRANSITION_VIDEO, 13, -1, -1, -1, -1);
 	case 66:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 164, 26, 268, 124, -1, -1, 1, TRANSITION_VIDEO, 16, -1, -1, -1, -1);
+	case 67:
+		return new TakeWaterCanister(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 68:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 70:
@@ -2719,6 +2769,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new NexusEnd(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 93:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 100:
+		return new TakeWaterCanister(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
 	warning("TODO: AI lab scene object %d", sceneStaticData.classID);


Commit: 283913da63873ed33b5f153c50328ebd78210cf9
    https://github.com/scummvm/scummvm/commit/283913da63873ed33b5f153c50328ebd78210cf9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the iceteroid mining controls

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index faf40ef382..041fc1c492 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -587,6 +587,126 @@ int IceteroidElevatorExtremeControls::specifyCursor(Window *viewWindow, const Co
 	return kCursorArrow;
 }
 
+class IceteroidZoomInMineControls : public BaseOxygenTimer {
+public:
+	IceteroidZoomInMineControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _controls;
+};
+
+IceteroidZoomInMineControls::IceteroidZoomInMineControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_controls = Common::Rect(152, 76, 180, 114);
+}
+
+int IceteroidZoomInMineControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation)) {
+		DestinationScene destinationData;
+		destinationData.destinationScene = _staticData.location;
+		destinationData.destinationScene.depth = 1;
+		destinationData.transitionType = TRANSITION_VIDEO;
+		destinationData.transitionData = 8;
+		destinationData.transitionStartFrame = -1;
+		destinationData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int IceteroidZoomInMineControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class IceteroidMineControls : public BaseOxygenTimer {
+public:
+	IceteroidMineControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _mineButton, _makeOxygenButton;
+};
+
+IceteroidMineControls::IceteroidMineControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_mineButton = Common::Rect(190, 40, 204, 128);
+	_makeOxygenButton = Common::Rect(205, 40, 220, 128);
+}
+
+int IceteroidMineControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_mineButton.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined < 255) {
+		GraphicsManager *gfx = _vm->_gfx;
+		Cursor oldCursor = gfx->setCursor(kCursorWait);
+
+		// Update the amount of ice mined
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined++;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICUsedMiningControls = 1;
+
+		// Transition to another scene, using the video clip
+		DestinationScene destinationData;
+		destinationData.destinationScene = _staticData.location;
+		destinationData.destinationScene.facing = 2;
+		destinationData.destinationScene.orientation = 2;
+		destinationData.destinationScene.depth = 0;
+		destinationData.transitionType = TRANSITION_VIDEO;
+		destinationData.transitionData = 10;
+		destinationData.transitionStartFrame = -1;
+		destinationData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+
+		// Reset the cursor
+		gfx->setCursor(oldCursor);
+		return SC_TRUE;
+	}
+
+	if (_makeOxygenButton.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined > 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves < 255) {
+		int currentStillFrame = _staticData.navFrameIndex;
+		_staticData.navFrameIndex = 108;
+		viewWindow->invalidateWindow(false);
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICProcessedOxygen = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined--;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves++;
+
+		// Play the conversion audio file
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+
+		// Reset the frame
+		_staticData.navFrameIndex = currentStillFrame;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	// Move back to the far view
+	DestinationScene destinationData;
+	destinationData.destinationScene = _staticData.location;
+	destinationData.destinationScene.depth = 0;
+	destinationData.transitionType = TRANSITION_VIDEO;
+	destinationData.transitionData = 9;
+	destinationData.transitionStartFrame = -1;
+	destinationData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+	return SC_TRUE;
+}
+
+int IceteroidMineControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_mineButton.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined < 255)
+		return kCursorFinger;
+
+	if (_makeOxygenButton.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined > 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves < 255)
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class TakeWaterCanister : public BaseOxygenTimer {
 public:
 	TakeWaterCanister(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2741,6 +2861,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new IceteroidElevatorExtremeControls(_vm, viewWindow, sceneStaticData, priorLocation, 6, 6, 3, 0, 1, 0, 5, 6, 6, 2, 0, 1, 0, 7);
 	case 57:
 		return new IceteroidElevatorExtremeControls(_vm, viewWindow, sceneStaticData, priorLocation, -1, -1, -1, -1, -1, -1, -1, 6, 6, 6, 0, 1, 0, 4);
+	case 58:
+		return new IceteroidZoomInMineControls(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 59:
+		return new IceteroidMineControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 60:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 63:


Commit: 2b1a427212150819060c6f12de43f96e1a4da461
    https://github.com/scummvm/scummvm/commit/2b1a427212150819060c6f12de43f96e1a4da461
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the iceteroid dispenser

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/resources.h


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 041fc1c492..d4d1c9bae5 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -707,6 +707,200 @@ int IceteroidMineControls::specifyCursor(Window *viewWindow, const Common::Point
 	return kCursorPutDown;
 }
 
+class IceteroidZoomInDispenser : public BaseOxygenTimer {
+public:
+	IceteroidZoomInDispenser(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _controls;
+};
+
+IceteroidZoomInDispenser::IceteroidZoomInDispenser(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_controls = Common::Rect(90, 0, 350, 189);
+}
+
+int IceteroidZoomInDispenser::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation)) {
+		DestinationScene destinationData;
+		destinationData.destinationScene = _staticData.location;
+		destinationData.destinationScene.depth = 1;
+		destinationData.transitionType = TRANSITION_VIDEO;
+		destinationData.transitionData = 11;
+		destinationData.transitionStartFrame = -1;
+		destinationData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int IceteroidZoomInDispenser::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class IceteroidDispenserControls : public BaseOxygenTimer {
+public:
+	IceteroidDispenserControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _oxygenHandle;
+	Common::Rect _fillHandle;
+	Common::Rect _dropZone;
+};
+
+IceteroidDispenserControls::IceteroidDispenserControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_oxygenHandle = Common::Rect(290, 42, 410, 128);
+	_fillHandle = Common::Rect(0, 36, 102, 132);
+	_dropZone = Common::Rect(0, 136, 148, 189);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0)
+		_staticData.navFrameIndex = 110;
+}
+
+int IceteroidDispenserControls::preExitRoom(Window *viewWindow, const Location &priorLocation) {
+	// Add the canister back into the inventory
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0) {
+		_staticData.navFrameIndex = 109;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle == 1)
+			((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemWaterCanEmpty);
+		else
+			((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemWaterCanFull);
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle = 0;
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+	}
+
+	return BaseOxygenTimer::preExitRoom(viewWindow, priorLocation);
+}
+
+int IceteroidDispenserControls::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_dropZone.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0) {
+		int itemID = (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle == 1) ? kItemWaterCanEmpty : kItemWaterCanFull;
+
+		// Reset present flag and change the frame of the background
+		_staticData.navFrameIndex = 109;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle = 0;
+
+		// Start dragging
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(itemID, ptInventoryWindow);
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int IceteroidDispenserControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_oxygenHandle.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves > 0 || ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICProcessedOxygen == 1) {
+			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+			// Reset the flags
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICProcessedOxygen == 0)
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves--;
+
+			// Set the use flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICRefilledOxygen = 1;
+
+			// Play the refill animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(18);
+
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = GC_AIHW_STARTING_VALUE;
+
+			// Place a message in the window
+			Common::String text;
+			if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+				text = _vm->getString(IDS_AI_IC_OXYGEN_REFILLED);
+			else
+				text = "Emergency oxygen reserves refilled.";
+			((SceneViewWindow *)viewWindow)->displayLiveText(text, false);
+
+			_vm->_gfx->setCursor(oldCursor);
+		} else {
+			// Play voiceover informing the player the oxygen needs to be refilled
+			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12));
+		}
+
+		return SC_TRUE;
+	}
+
+	if (_fillHandle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0) {
+		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle = 2;
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(17);
+		_vm->_gfx->setCursor(oldCursor);
+		return SC_TRUE;
+	}
+
+	DestinationScene destinationData;
+	destinationData.destinationScene = _staticData.location;
+	destinationData.destinationScene.depth = 0;
+	destinationData.transitionType = TRANSITION_VIDEO;
+	destinationData.transitionData = 12;
+	destinationData.transitionStartFrame = -1;
+	destinationData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
+	return SC_TRUE;
+}
+
+int IceteroidDispenserControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	// Water canister
+	if (_dropZone.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0)
+		return kCursorOpenHand;
+
+	// Oxygen handle
+	if (_oxygenHandle.contains(pointLocation))
+		return kCursorFinger;
+
+	// Fill handle
+	if (_fillHandle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0)
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+int IceteroidDispenserControls::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if ((itemID == kItemWaterCanFull || itemID == kItemWaterCanEmpty) && _dropZone.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle == 0)
+		return 1;
+
+	return 0;
+}
+
+int IceteroidDispenserControls::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if ((itemID == kItemWaterCanFull || itemID == kItemWaterCanEmpty) && _dropZone.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle == 0) {
+		_staticData.navFrameIndex = 110;
+		viewWindow->invalidateWindow(false);
+
+		if (itemID == kItemWaterCanEmpty)
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle = 1;
+		else
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle = 2;
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
 class TakeWaterCanister : public BaseOxygenTimer {
 public:
 	TakeWaterCanister(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2867,6 +3061,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new IceteroidMineControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 60:
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 61:
+		return new IceteroidZoomInDispenser(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 62:
+		return new IceteroidDispenserControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 63:
 		return new IceteroidPodTimed(_vm, viewWindow, sceneStaticData, priorLocation, 174, 96, 246, 118, 14, 6, 6, 5, 0, 1, 0);
 	case 64:
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 5ba7ba9f8b..1cd30dd1d9 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -161,6 +161,7 @@ namespace Buried {
 #define IDS_AI_IS_JUMP_IN_TEXT                  1755
 
 // 1.04+:
+#define IDS_AI_IC_OXYGEN_REFILLED       1767
 #define IDS_AI_NX_CODE_RESET_MESSAGE    1768
 
 


Commit: 9ce7c7130392fbe8be3aff01d739900ac655abbb
    https://github.com/scummvm/scummvm/commit/9ce7c7130392fbe8be3aff01d739900ac655abbb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the PlaySoundExitingForward scene

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index d4d1c9bae5..a095f577af 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -901,6 +901,27 @@ int IceteroidDispenserControls::droppedItem(Window *viewWindow, int itemID, cons
 	return SIC_REJECT;
 }
 
+class PlaySoundExitingForward : public BaseOxygenTimer {
+public:
+	PlaySoundExitingForward(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int soundFileNameID);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+
+private:
+	int _soundFileNameID;
+};
+
+PlaySoundExitingForward::PlaySoundExitingForward(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int soundFileNameID) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundFileNameID = soundFileNameID;
+}
+
+int PlaySoundExitingForward::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_soundFileNameID >= 0 && _staticData.location.timeZone == newLocation.timeZone && _staticData.location.node != newLocation.node)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _soundFileNameID), 128, false, true);
+
+	return SC_TRUE;
+}
+
 class TakeWaterCanister : public BaseOxygenTimer {
 public:
 	TakeWaterCanister(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -3077,6 +3098,8 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new TakeWaterCanister(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 68:
 		return new PlaySoundExitingFromSceneDeux(_vm, viewWindow, sceneStaticData, priorLocation, 14);
+	case 69:
+		return new PlaySoundExitingForward(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 70:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 92, 92, 212, 189, 48, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
 	case 74:


Commit: d09e01aace1a880e069095a51b178e57eb37eadb
    https://github.com/scummvm/scummvm/commit/d09e01aace1a880e069095a51b178e57eb37eadb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the science wing panel

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index a095f577af..de08117b9d 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -970,6 +970,276 @@ int TakeWaterCanister::specifyCursor(Window *viewWindow, const Common::Point &po
 	return kCursorArrow;
 }
 
+class ScienceWingZoomIntoPanel : public BaseOxygenTimer {
+public:
+	ScienceWingZoomIntoPanel(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+};
+
+ScienceWingZoomIntoPanel::ScienceWingZoomIntoPanel(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(282, 6, 390, 189);
+	_cursorID = kCursorMagnifyingGlass;
+	_clickDestination.destinationScene = _staticData.location;
+	_clickDestination.destinationScene.depth = 1;
+	_clickDestination.transitionType = TRANSITION_VIDEO;
+	_clickDestination.transitionData = 1;
+	_clickDestination.transitionStartFrame = -1;
+	_clickDestination.transitionLength = -1;
+}
+
+int ScienceWingZoomIntoPanel::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+	
+	return SC_FALSE;
+}
+
+int ScienceWingZoomIntoPanel::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
+class ScienceWingPanelInterface : public BaseOxygenTimer {
+public:
+	ScienceWingPanelInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~ScienceWingPanelInterface();
+	void preDestructor();
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int gdiPaint(Window *viewWindow);
+
+private:
+	Common::Rect _stationRegions[15];
+	int _currentSelection;
+	int _currentTextIndex;
+	int _lineHeight;
+	Graphics::Font *_textFont;
+	Common::Rect _leftTextRegion;
+	Common::Rect _rightTextRegion;
+};
+
+ScienceWingPanelInterface::ScienceWingPanelInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_currentSelection = -1;
+	_currentTextIndex = -1;
+	_stationRegions[0] = Common::Rect(265, 110, 286, 135);
+	_stationRegions[1] = Common::Rect(102, 45, 180, 134);
+	_stationRegions[2] = Common::Rect(195, 106, 216, 133);
+	_stationRegions[3] = Common::Rect(268, 72, 283, 87);
+	_stationRegions[4] = Common::Rect(221, 46, 236, 74);
+	_stationRegions[5] = Common::Rect(290, 72, 317, 108);
+	_stationRegions[6] = Common::Rect(264, 55, 288, 67);
+	_stationRegions[7] = Common::Rect(194, 74, 266, 84);
+	_stationRegions[8] = Common::Rect(198, 62, 214, 74);
+	_stationRegions[9] = Common::Rect(221, 106, 236, 134);
+	_stationRegions[10] = Common::Rect(245, 46, 260, 74);
+	_stationRegions[11] = Common::Rect(245, 106, 260, 134);
+	_stationRegions[12] = Common::Rect(266, 92, 290, 109);
+	_stationRegions[13] = Common::Rect(194, 96, 264, 106);
+	_stationRegions[14] = Common::Rect(180, 85, 194, 94);
+	_leftTextRegion = Common::Rect(83, 144, 211, 170);
+	_rightTextRegion = Common::Rect(228, 144, 356, 170);
+	_lineHeight = _vm->getLanguage() == Common::JA_JPN ? 10 : 13;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+ScienceWingPanelInterface::~ScienceWingPanelInterface() {
+	preDestructor();
+}
+
+void ScienceWingPanelInterface::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int ScienceWingPanelInterface::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	byte &oxygenReserves = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves;
+
+	if (_currentSelection == 2) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized == 0 && (_stationRegions[_currentSelection].contains(pointLocation) || _rightTextRegion.contains(pointLocation))) {
+			if (oxygenReserves > 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICProcessedOxygen != 0) {
+				// Decrement reserves flag
+				oxygenReserves--;
+
+				// Set the machine room to pressurized
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized = 1;
+
+				// Display pressurizing message
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_PRES_ENV_TEXT;
+
+				// Play sound file
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+
+				// Display pressurized text
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			} else {
+				// Not enough oxygen reserves
+				viewWindow->invalidateWindow(false);
+				_currentTextIndex = IDS_AI_PRES_PANEL_INSUF_OXYGEN;
+
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().aiSWAttemptedPresMR = 1;
+
+				return SC_TRUE;
+			}
+		}
+	}
+
+	// Check against the hotspots
+	for (int i = 0; i < 15; i++) {
+		if (_stationRegions[i].contains(pointLocation) && _currentSelection != i) {
+			switch (i) {
+			case 0:
+				_staticData.navFrameIndex = 60;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			case 1:
+				_staticData.navFrameIndex = 61;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ZERO_PRES_ENV;
+				return SC_TRUE;
+			case 2:
+				_staticData.navFrameIndex = 62;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized == 1)
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				else
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES;
+				return SC_TRUE;
+			case 3:
+				_staticData.navFrameIndex = 63;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRPressurized == 1)
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				else
+					_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_OBST;
+				return SC_TRUE;
+			case 4:
+				_staticData.navFrameIndex = 64;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 5:
+				_staticData.navFrameIndex = 65;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			case 6:
+				_staticData.navFrameIndex = 66;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 7:
+				_staticData.navFrameIndex = 67;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 8:
+				_staticData.navFrameIndex = 68;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 9:
+				_staticData.navFrameIndex = 69;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 10:
+				_staticData.navFrameIndex = 70;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 11:
+				_staticData.navFrameIndex = 71;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			case 12:
+				_staticData.navFrameIndex = 72;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_PRES_TEXT;
+				return SC_TRUE;
+			case 13:
+			case 14:
+				_staticData.navFrameIndex = 73;
+				viewWindow->invalidateWindow(false);
+				_currentSelection = i;
+				_currentTextIndex = IDS_AI_PRES_PANEL_ENV_DEPRES_BREACH;
+				return SC_TRUE;
+			}
+		}
+	}
+
+	// By default, return to depth zero (zoomed out)
+	DestinationScene destData;
+	destData.destinationScene = _staticData.location;
+	destData.destinationScene.depth = 0;
+	destData.transitionType = TRANSITION_NONE;
+	destData.transitionData = -1;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int ScienceWingPanelInterface::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 15; i++)
+		if (_stationRegions[i].contains(pointLocation))
+			return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+int ScienceWingPanelInterface::gdiPaint(Window *viewWindow) {
+	if (_currentSelection >= 0) {
+		uint32 color = _vm->_gfx->getColor(208, 144, 24);
+
+		Common::String location = _vm->getString(IDS_AI_PRES_PANEL_DESC_BASE + _currentSelection);
+		if (_currentSelection == 2)
+			location += _vm->getString(IDS_AI_PRES_PANEL_DESC_BASE + 19);
+
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_leftTextRegion);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, location, rect.left, rect.top, rect.width(), rect.height(), color, _lineHeight, kTextAlignCenter, true);
+
+		if (_currentTextIndex >= 0) {
+			rect = _rightTextRegion;
+			rect.translate(absoluteRect.left, absoluteRect.top);
+			_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, _vm->getString(_currentTextIndex), rect.left, rect.top, rect.width(), rect.height(), color, _lineHeight, kTextAlignCenter, true);
+		}
+	}
+
+	return SC_FALSE;
+}
+
 class ScienceWingStingersTimed : public BaseOxygenTimer {
 public:
 	ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -3102,6 +3372,10 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingForward(_vm, viewWindow, sceneStaticData, priorLocation, 14);
 	case 70:
 		return new SpaceDoorTimer(_vm, viewWindow, sceneStaticData, priorLocation, 92, 92, 212, 189, 48, -1, 1, TRANSITION_VIDEO, 0, -1, -1, -1, -1);
+	case 71:
+		return new ScienceWingZoomIntoPanel(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 72:
+		return new ScienceWingPanelInterface(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 74:
 		return new ScienceWingStingersTimed(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 75:


Commit: f6ec60569749eca3b3dc5bb968a9fcba59fd2131
    https://github.com/scummvm/scummvm/commit/f6ec60569749eca3b3dc5bb968a9fcba59fd2131
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Fix dying while in a timer

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 7a86e19b81..9c69d2abca 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2411,7 +2411,8 @@ void SceneViewWindow::onPaint() {
 }
 
 void SceneViewWindow::onTimer(uint timer) {
-	_vm->_sound->timerCallback();
+	SoundManager *sound = _vm->_sound; // Take a copy in case we die while in the timer
+	sound->timerCallback();
 
 	if (_paused)
 		return;
@@ -2422,7 +2423,7 @@ void SceneViewWindow::onTimer(uint timer) {
 	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed && !_burnedLetterDisplayed)
 		_currentScene->timerCallback(this);
 
-	_vm->_sound->timerCallback();
+	sound->timerCallback();
 }
 
 bool SceneViewWindow::onSetCursor(uint message) {


Commit: f024f5631e43a405d53a3c4d0bae0a6e9ee8d76b
    https://github.com/scummvm/scummvm/commit/f024f5631e43a405d53a3c4d0bae0a6e9ee8d76b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement entering the biomass processing room

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index de08117b9d..abeeb504da 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -1240,6 +1240,43 @@ int ScienceWingPanelInterface::gdiPaint(Window *viewWindow) {
 	return SC_FALSE;
 }
 
+class ScienceWingMachineRoomDoor : public BaseOxygenTimer {
+public:
+	ScienceWingMachineRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+};
+
+ScienceWingMachineRoomDoor::ScienceWingMachineRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(162, 54, 250, 142);
+	_cursorID = kCursorFinger;
+	_clickDestination.destinationScene = Location(6, 8, 0, 0, 1, 0);
+	_clickDestination.transitionType = TRANSITION_VIDEO;
+	_clickDestination.transitionData = (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized == 0) ? 2 : 3;
+	_clickDestination.transitionStartFrame = -1;
+	_clickDestination.transitionLength = -1;
+}
+
+int ScienceWingMachineRoomDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int ScienceWingMachineRoomDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return 0;
+}
+
 class ScienceWingStingersTimed : public BaseOxygenTimer {
 public:
 	ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1294,7 +1331,7 @@ int NexusDoor::postEnterRoom(Window *viewWindow, const Location &priorLocation)
 
 	if (priorLocation.environment != _staticData.location.environment || priorLocation.timeZone != _staticData.location.timeZone) {
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = GC_AIHW_STARTING_VALUE;
-		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_ENTERING_NON_PRES_ENV_TEXT));
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_ENTERING_PRES_ENV_TEXT));
 	}
 
 	return SC_TRUE;
@@ -3181,6 +3218,50 @@ ScanningRoomNexusDoorToGlobe::ScanningRoomNexusDoorToGlobe(BuriedEngine *vm, Win
 		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
 }
 
+class MachineRoomEntry : public SceneBase {
+public:
+	MachineRoomEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int soundID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	int _soundID;
+	bool _die;
+};
+
+MachineRoomEntry::MachineRoomEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int soundID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundID = soundID;
+	_die = false;
+}
+
+int MachineRoomEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// If the machine room is not pressurized, flag ourselves for death
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRPressurized == 0) {
+		_die = true;
+		((SceneViewWindow *)viewWindow)->_disableArthur = true;
+		return SC_TRUE;
+	}
+
+	// Otherwise, notify the player they have entered a pressurized room and their oxygen has replenished
+	if (_staticData.location.node != priorLocation.node) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AI_ENTERING_PRES_ENV_TEXT));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenTimer = GC_AIHW_STARTING_VALUE;
+	}
+
+	return SC_TRUE;
+}
+
+int MachineRoomEntry::timerCallback(Window *viewWindow) {
+	// If we have not pressurized the room, kill the player
+	if (_die) {
+		((SceneViewWindow *)viewWindow)->showDeathScene(41);
+		return SC_DEATH;
+	}
+
+	return SC_TRUE;
+}
+
 class DockingBayPlaySoundEntering : public SceneBase {
 public:
 	DockingBayPlaySoundEntering(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -3376,10 +3457,17 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new ScienceWingZoomIntoPanel(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 72:
 		return new ScienceWingPanelInterface(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 73:
+		return new ScienceWingMachineRoomDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 74:
 		return new ScienceWingStingersTimed(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 75:
 		return new HabitatWingLockedDoor(_vm, viewWindow, sceneStaticData, priorLocation, 51, 4, 5, 146, 0, 396, 84);
+	case 80:
+		// Scene exists, but is just the default one
+		break;
+	case 87:
+		return new MachineRoomEntry(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 90:
 		return new NexusDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 91:
@@ -3390,9 +3478,11 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 		return new BaseOxygenTimer(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 100:
 		return new TakeWaterCanister(_vm, viewWindow, sceneStaticData, priorLocation);
+	default:
+		warning("TODO: AI lab scene object %d", sceneStaticData.classID);
+		break;
 	}
 
-	warning("TODO: AI lab scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 


Commit: 6528929f8ea311196f3eb8a9f2bf2f259c88ca3c
    https://github.com/scummvm/scummvm/commit/6528929f8ea311196f3eb8a9f2bf2f259c88ca3c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the biomass processing room

The Farnstein Lab is complete!

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index abeeb504da..ce79019dcd 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -3116,6 +3116,383 @@ int ScanningRoomNexusDoorPullHandle::specifyCursor(Window *viewWindow, const Com
 	return kCursorArrow;
 }
 
+class MachineRoomExitDoor : public SceneBase {
+public:
+	MachineRoomExitDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickable;
+	DestinationScene _destData;
+};
+
+MachineRoomExitDoor::MachineRoomExitDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickable = Common::Rect(138, 0, 338, 189);
+	_destData.destinationScene = Location(6, 7, 1, 3, 1, 0);
+	_destData.transitionType = TRANSITION_VIDEO;
+	_destData.transitionData = 4;
+	_destData.transitionStartFrame = -1;
+	_destData.transitionLength = -1;
+}
+
+int MachineRoomExitDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->moveToDestination(_destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MachineRoomExitDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class MachineRoomTamperedSculpture : public SceneBase {
+public:
+	MachineRoomTamperedSculpture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickable;
+};
+
+MachineRoomTamperedSculpture::MachineRoomTamperedSculpture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickable = Common::Rect(184, 54, 274, 142);
+}
+
+int MachineRoomTamperedSculpture::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRCorrectFreqSet == 2) {
+			// Play the morph movie
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(1);
+
+			// Attempt to add it to the biochip
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, AI_EVIDENCE_SCULPTURE))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Turn off evidence capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+
+			// Set the scoring flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreFoundSculptureDiagram = 1;
+
+			// Update the AI chip and check for spontaneous comments
+			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		} else {
+			// Play the normal morphing animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MachineRoomTamperedSculpture::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// If we have not yet captured it, set the anachronism message
+	if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), AI_EVIDENCE_SCULPTURE))
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+
+	return SC_TRUE;
+}
+
+int MachineRoomTamperedSculpture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && _clickable.contains(pointLocation) &&
+			!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), AI_EVIDENCE_SCULPTURE)) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED)); // All will be reveaaaaaled
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MachineRoomTamperedSculpture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_clickable.contains(pointLocation))
+			return -2;
+		return -1;
+	}
+
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class MachineRoomHarmonicsInterface : public SceneBase {
+public:
+	MachineRoomHarmonicsInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _testButton;
+	Common::Rect _turnRight;
+	Common::Rect _turnLeft;
+	int _currentSelection;
+	bool _tested;
+};
+
+MachineRoomHarmonicsInterface::MachineRoomHarmonicsInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_testButton = Common::Rect(122, 90, 160, 118);
+	_turnRight = Common::Rect(128, 27, 173, 48);
+	_turnLeft = Common::Rect(128, 53, 173, 80);
+	_currentSelection = ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRCorrectFreqSet;
+	_tested = false;
+
+	switch (_currentSelection) {
+	case 0:
+		_staticData.navFrameIndex = 105;
+		break;
+	case 1:
+		_staticData.navFrameIndex = 107;
+		break;
+	case 2:
+		_staticData.navFrameIndex = 109;
+		break;
+	case 3:
+		_staticData.navFrameIndex = 111;
+		break;
+	case 4:
+		_staticData.navFrameIndex = 113;
+		break;
+	case 5:
+		_staticData.navFrameIndex = 115;
+		break;
+	case 6:
+		_staticData.navFrameIndex = 116;
+		break;
+	case 7:
+		_staticData.navFrameIndex = 118;
+		break;
+	}
+}
+
+int MachineRoomHarmonicsInterface::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_turnRight.contains(pointLocation)) {
+		_staticData.navFrameIndex = 103;
+		viewWindow->invalidateWindow(false);
+
+		// TODO: Delay
+
+		_staticData.navFrameIndex = 104;
+		viewWindow->invalidateWindow(false);
+
+		// TODO: Delay
+
+		_currentSelection++;
+		if (_currentSelection > 7)
+			_currentSelection = 0;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRCorrectFreqSet = _currentSelection;
+		_tested = false;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRUsedHarmonicsInterface = 1;
+
+		switch (_currentSelection) {
+		case 0:
+			_staticData.navFrameIndex = 105;
+			break;
+		case 1:
+			_staticData.navFrameIndex = 107;
+			break;
+		case 2:
+			_staticData.navFrameIndex = 109;
+			break;
+		case 3:
+			_staticData.navFrameIndex = 111;
+			break;
+		case 4:
+			_staticData.navFrameIndex = 113;
+			break;
+		case 5:
+			_staticData.navFrameIndex = 115;
+			break;
+		case 6:
+			_staticData.navFrameIndex = 116;
+			break;
+		case 7:
+			_staticData.navFrameIndex = 118;
+			break;
+		}
+
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	if (_turnLeft.contains(pointLocation)) {
+		_staticData.navFrameIndex = 104;
+		viewWindow->invalidateWindow(false);
+
+		// TODO: Delay
+
+		_staticData.navFrameIndex = 103;
+		viewWindow->invalidateWindow(false);
+
+		// TODO: Delay
+
+		_currentSelection--;
+		if (_currentSelection < 0)
+			_currentSelection = 7;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRCorrectFreqSet = _currentSelection;
+		_tested = false;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRUsedHarmonicsInterface = 1;
+
+		switch (_currentSelection) {
+		case 0:
+			_staticData.navFrameIndex = 105;
+			break;
+		case 1:
+			_staticData.navFrameIndex = 107;
+			break;
+		case 2:
+			_staticData.navFrameIndex = 109;
+			break;
+		case 3:
+			_staticData.navFrameIndex = 111;
+			break;
+		case 4:
+			_staticData.navFrameIndex = 113;
+			break;
+		case 5:
+			_staticData.navFrameIndex = 115;
+			break;
+		case 6:
+			_staticData.navFrameIndex = 116;
+			break;
+		case 7:
+			_staticData.navFrameIndex = 118;
+			break;
+		}
+
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	if (_testButton.contains(pointLocation) && _currentSelection != 5 && !_tested) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRUsedHarmonicsInterface = 1;
+
+		// Play the proper sound effect
+		int fileID;
+		switch (_currentSelection) {
+		case 0:
+			fileID = 6;
+			break;
+		case 1:
+			fileID = 7;
+			break;
+		case 2:
+			fileID = 8;
+			break;
+		case 3:
+			fileID = 9;
+			break;
+		case 4:
+			fileID = 10;
+			break;
+		case 6:
+			fileID = 11;
+			break;
+		case 7:
+			fileID = 12;
+			break;
+		}
+
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, fileID), 128);
+
+		// Increment the frame to display the results
+		_staticData.navFrameIndex++;
+		viewWindow->invalidateWindow(false);
+
+		_tested = true;
+
+		// Set the score flag
+		if (_currentSelection == 2)
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchMorphSculpture = 1;
+
+		return SC_TRUE;
+	}
+
+	// Return the player to the original position (depth zero)
+	DestinationScene destData;
+	destData.destinationScene = _staticData.location;
+	destData.destinationScene.depth = 0;
+	destData.transitionType = TRANSITION_NONE;
+	destData.transitionData = -1;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int MachineRoomHarmonicsInterface::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_turnRight.contains(pointLocation))
+		return kCursorArrowRight;
+
+	if (_turnLeft.contains(pointLocation))
+		return kCursorArrowRight;
+
+	if (_testButton.contains(pointLocation) && _currentSelection != 5 && !_tested)
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+class MachineRoomHarmonicsZoomIn : public SceneBase {
+public:
+	MachineRoomHarmonicsZoomIn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+};
+
+MachineRoomHarmonicsZoomIn::MachineRoomHarmonicsZoomIn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(90, 60, 178, 134);
+	_clickDestination.destinationScene = _staticData.location;
+	_clickDestination.destinationScene.depth = 1;
+	_clickDestination.transitionType = TRANSITION_NONE;
+	_clickDestination.transitionData = -1;
+	_clickDestination.transitionStartFrame = -1;
+	_clickDestination.transitionLength = -1;
+}
+
+int MachineRoomHarmonicsZoomIn::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int MachineRoomHarmonicsZoomIn::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 class SpaceDoor : public SceneBase {
 public:
 	SpaceDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -3292,6 +3669,41 @@ int DockingBayPlaySoundEntering::postEnterRoom(Window *viewWindow, const Locatio
 	return SC_TRUE;
 }
 
+class MachineRoomPlayAnim : public SceneBase {
+public:
+	MachineRoomPlayAnim(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int animID = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickable;
+	int _animID;
+};
+
+MachineRoomPlayAnim::MachineRoomPlayAnim(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int animID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickable = Common::Rect(left, top, right, bottom);
+	_animID = animID;
+}
+
+int MachineRoomPlayAnim::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation) && _animID >= 0) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MachineRoomPlayAnim::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickable.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -3466,6 +3878,18 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 	case 80:
 		// Scene exists, but is just the default one
 		break;
+	case 81:
+		return new MachineRoomExitDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 82:
+		return new MachineRoomPlayAnim(_vm, viewWindow, sceneStaticData, priorLocation, 156, 30, 251, 125, 2);
+	case 83:
+		return new MachineRoomPlayAnim(_vm, viewWindow, sceneStaticData, priorLocation, 184, 38, 272, 126, 3);
+	case 84:
+		return new MachineRoomTamperedSculpture(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 85:
+		return new MachineRoomHarmonicsInterface(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 86:
+		return new MachineRoomHarmonicsZoomIn(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 87:
 		return new MachineRoomEntry(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 90:


Commit: 35bcf1d216adbf54f0cd72cca127f82cd30a5f66
    https://github.com/scummvm/scummvm/commit/35bcf1d216adbf54f0cd72cca127f82cd30a5f66
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement Chateau Gaillard custom AI dependencies

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 95176a5fe9..7719b2fa92 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -1035,6 +1035,87 @@ bool SceneViewWindow::startCastleAmbient(int oldTimeZone, int oldEnvironment, in
 	return true;
 }
 
+bool SceneViewWindow::checkCustomCastleAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	switch (commentData.dependencyFlagOffsetB) {
+	case 1: // Did we click on the tower door at node 3?
+		return _globalFlags.cgTSTriedDoorA == 1;
+	case 2: // Did we click on the tower door at node 5?
+		return _globalFlags.cgTSTriedDoorB == 1;
+	case 3: // Did we click on either of the tower doors?
+		return _globalFlags.cgTSTriedDoorA == 1 || _globalFlags.cgTSTriedDoorB == 1;
+	case 4: // Is the grappling hook in our inventory?
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemGrapplingHook);
+	case 5: // Have we not been to the middle bailey?
+		return _globalFlags.cgMBVisited == 0;
+	case 6: // Have we not been to the keep?
+		return _globalFlags.cgKCVisited == 0;
+	case 7: // Have we not been across the moat?
+		return _globalFlags.cgMBCrossedMoat == 0;
+	case 8: // If we have not been in the keep, and the hook is in our inventory
+		return _globalFlags.cgKCVisited == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemGrapplingHook);
+	case 9: // If we have not been in the keep and if AI table 33 is equal to 0
+		return _globalFlags.cgKCVisited == 0 && _globalFlags.aiData[33] == 0;
+	case 10: // If we have found the mold, did not read the journal, and do not have a key
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgSmithyStatus == 1 && _globalFlags.cgKSSmithyEntryRead == 0;
+	case 11: // If we have found the mold, did not read the journal, and do not have a key
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgSmithyStatus == 1 && _globalFlags.cgKSSmithyEntryRead == 1;
+	case 12: // If we have found the mold, do not have the medallion, and do not have the key
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgBSFoundMold == 1 && _globalFlags.cgSmithyStatus == 1 && _globalFlags.cgKSSmithyEntryRead == 1;
+	case 13: // If we have found the mold, have a medallion, do not have a key, and AI offset 41 >= 2
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgBSFoundMold == 1 && _globalFlags.cgSmithyStatus == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperMedallion) && _globalFlags.aiData[41] >= 2;
+	case 14: // Is the hammer not in our invetory
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemHammer);
+	case 15: // If we have not found the mold, did not read the journal, and do not have a key
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgBSFoundMold == 0 && _globalFlags.cgKSSmithyEntryRead == 0;
+	case 16: // If we have not found the mold, did read the journal, and do not have a key
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgBSFoundMold == 0 && _globalFlags.cgKSSmithyEntryRead == 1;
+	case 17: // If we have not been to the treasure room, and if we are not waiting for the guards
+		return commentLocation.depth != 1 && _globalFlags.cgTRVisited == 0;
+	case 18: // Is the letter not in our inventory?
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBurnedLetter);
+	case 19: // If we have not read either journal and not been to the treasure room
+		return _globalFlags.cgTRVisited == 0 && _globalFlags.cgKSReadJournal == 0;
+	case 20: // If we are in the king's study and if we have not been to the treasure room
+		return _globalFlags.cgTRVisited == 0 && commentLocation.node != 11;
+	case 21: // If we are inside the king's study
+		return commentLocation.node != 11;
+	case 22: // If the key is not in the inventory, have not opened the chest and have clicked on the locked chest
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgSRClickedOnLockedChest == 1;
+	case 23: // If the key is not in the inventory, have not opened the chest, have clicked on the locked chest, read the journal entry, and not found the armoire
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgSRClickedOnLockedChest == 1 && _globalFlags.cgKSSmithyEntryRead == 1 && _globalFlags.cgFoundChestPanel == 0;
+	case 24: // If we have not made the copper key, we have clicked on the chest, and have found the panel in the armoire
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgSRClickedOnLockedChest == 1 && _globalFlags.cgFoundChestPanel == 1;
+	case 25: // If we have the key and have clicked on the locked chest
+		return ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey) && _globalFlags.cgSRClickedOnLockedChest == 1;
+	case 26: // If we have not read the letter, have not been to 1/8/3/3/0/0, have not been to the treasure room
+		return _globalFlags.readBurnedLetter == 0 && _globalFlags.cgTRVisited == 0 && _globalFlags.cgViewedKeepPlans == 0 && _globalFlags.cgTapestryFlag == 0;
+	case 27: // Have not been to the treasure room
+		return _globalFlags.cgTRVisited == 0 && _globalFlags.cgTapestryFlag == 0;
+	case 28: // Has read the burned letter, have not been to treasure room
+		return _globalFlags.readBurnedLetter == 1 && _globalFlags.cgTRVisited == 0 && _globalFlags.cgTapestryFlag == 0;
+	case 29: // Has seen 1/8/3/3/0/0, has not been to treasure room
+		return _globalFlags.cgViewedKeepPlans == 1 && _globalFlags.cgTRVisited == 0 && _globalFlags.cgTapestryFlag == 0;
+	case 30: // Has seen 1/8/3/3/0/0, has not been to treasure room, has read the burned letter
+		return _globalFlags.cgViewedKeepPlans == 1 && _globalFlags.cgTRVisited == 0 && _globalFlags.readBurnedLetter == 1 && _globalFlags.cgTapestryFlag == 0;
+	case 31: // If the door to CGSR has been opened, hasn't opened chest
+		return _globalFlags.cgSROpenedChest == 0 && commentLocation.node != 5;
+	case 32: // If the door to CGSR has been opened, has been to 1/8/3/3/0/0, has not been to treasure room
+		return _globalFlags.cgViewedKeepPlans == 1 && _globalFlags.cgTRVisited == 0;
+	case 33: // Has opened chest, has read burned letter, has not clicked on tapestry
+		return _globalFlags.cgSROpenedChest == 1 && _globalFlags.readBurnedLetter == 1 && _globalFlags.cgTapestryFlag == 0;
+	case 34: // If the door to CGSR has been opened
+		return commentLocation.node != 5;
+	case 35: // If we have not used the locate feature in the treasure room, have not found the sword
+		return _globalFlags.cgTRFoundSword == 0;
+	case 36: // If we do not have the key
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey);
+	case 37: // If we have not been in the keep and the hook is in our inventory (clone2727: ????????)
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBloodyArrow);
+	}
+
+	return false;
+}
+
 SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 57f780d86e..4a60ec5602 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -74,6 +74,12 @@ int OldApartmentSuitCap::postEnterRoom(Window *viewWindow, const Location &prior
 
 bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
 	// TODO
+
+	switch (commentLocation.timeZone) {
+	case 1:
+		return checkCustomCastleAICommentDependencies(commentLocation, commentData);
+	}
+
 	return false;
 }
 
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 764892a08b..0b43e9fb0c 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -207,6 +207,7 @@ private:
 	bool initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	bool startCastleAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	bool checkCustomCastleAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
 
 	// Da Vinci's Studio
 	bool initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment);


Commit: 00ef60aa1f6a9d55abfe7ed813104b133f080415
    https://github.com/scummvm/scummvm/commit/00ef60aa1f6a9d55abfe7ed813104b133f080415
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement Farnstein Lab custom AI comment dependencies

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index ce79019dcd..a443223889 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -3743,6 +3743,38 @@ bool SceneViewWindow::startAILabAmbient(int oldTimeZone, int oldEnvironment, int
 	return true;
 }
 
+bool SceneViewWindow::checkCustomSpaceStationAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	switch (commentData.dependencyFlagOffsetB) {
+	case 1: // After failing to pressurize from SW panel interface, before using mining controls
+		return _globalFlags.aiSWAttemptedPresMR == 1 && _globalFlags.aiICUsedMiningControls == 1;
+	case 2: // Never used oxygen before
+		return _globalFlags.aiICRefilledOxygen == 0;
+	case 3: // If no water canister is in our inventory
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemWaterCanFull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemWaterCanEmpty);
+	case 4: // Have not used pressurization interface
+		return _globalFlags.aiSWAttemptedPresMR == 0;
+	case 5: // If tried biomass, not enough reserve oxygen
+		return _globalFlags.aiSWAttemptedPresMR == 1 && _globalFlags.aiOxygenReserves == 0;
+	case 6: // If tried biomass, not enough reserve, has not run mining sequence
+		return _globalFlags.aiSWAttemptedPresMR == 1 && _globalFlags.aiOxygenReserves == 0 && _globalFlags.aiICUsedMiningControls == 0;
+	case 7: // If tried biomass, not enough reserve, has run mining sequence, has not run processing sequence
+		return _globalFlags.aiSWAttemptedPresMR == 1 && _globalFlags.aiOxygenReserves == 0 && _globalFlags.aiICUsedMiningControls == 1 && _globalFlags.aiICProcessedOxygen == 0;
+	case 8: // If we have not pressurized the machine room
+		return _globalFlags.aiMRPressurized == 0;
+	case 9: // If we have not revealed the diagram
+		return _globalFlags.scoreFoundSculptureDiagram == 0;
+	case 10: // If we have not revealed the diagram or used the harmonics interface
+		return _globalFlags.scoreFoundSculptureDiagram == 0 && _globalFlags.aiMRUsedHarmonicsInterface == 0;
+	case 11: // After we have recorded evidence
+		return _globalFlags.scoreFoundSculptureDiagram == 1;
+	case 12: // Before using mining control, after having tried to pressurize biomass room
+		// clone2727: This was mistakenly cut out of the original
+		return _globalFlags.aiICUsedMiningControls == 0 && _globalFlags.aiSWAttemptedPresMR == 1;
+	}
+
+	return false;
+}
+
 SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 4a60ec5602..07b0e229c7 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -78,6 +78,8 @@ bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLo
 	switch (commentLocation.timeZone) {
 	case 1:
 		return checkCustomCastleAICommentDependencies(commentLocation, commentData);
+	case 6:
+		return checkCustomSpaceStationAICommentDependencies(commentLocation, commentData);
 	}
 
 	return false;
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 0b43e9fb0c..58233836fe 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -202,6 +202,7 @@ private:
 	bool initializeAILabTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	bool startAILabAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	bool checkCustomSpaceStationAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
 
 	// Castle
 	bool initializeCastleTimeZoneAndEnvironment(Window *viewWindow, int environment);


Commit: 85fa17a732d11ff186df3b258c6773adcf441b9e
    https://github.com/scummvm/scummvm/commit/85fa17a732d11ff186df3b258c6773adcf441b9e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement the Da Vinci AI comment dependencies

Changed paths:
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/global_flags.h
    engines/buried/saveload.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 533503768f..552d68e99b 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -596,6 +596,103 @@ bool SceneViewWindow::startDaVinciAmbient(int oldTimeZone, int oldEnvironment, i
 	return true;
 }
 
+bool SceneViewWindow::checkCustomDaVinciAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	switch (commentData.dependencyFlagOffsetB) {
+	case 1: // Has not raised platform
+		return _globalFlags.dsPTRaisedPlatform == 0;
+	case 2: // Has raised platform
+		return _globalFlags.dsPTRaisedPlatform == 1;
+	case 3: // Has not been to codec tower
+		return _globalFlags.dsVisitedCodexTower == 0;
+	case 4: // Has not been on balcony, has not been down elevator
+		return _globalFlags.dsPTBeenOnBalcony == 0 && _globalFlags.dsPTWalkedDownElevator == 0;
+	case 5: // Has not raised platform, has not translated levers
+		return _globalFlags.dsPTRaisedPlatform == 0 && _globalFlags.dsPTTransElevatorControls == 0;
+	case 6: // Has not raised platform, has not translated levers, translation biochip is in inventory
+		return _globalFlags.dsPTRaisedPlatform == 0 && _globalFlags.dsPTTransElevatorControls == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
+	case 7: // If clicked on codex door
+		return _globalFlags.dsGDClickedOnCodexDoor == 1;
+	case 8: // If clicked on codex door, siege cycle not in inventory
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
+	case 9: // If gear assembly has never been in inventory
+		return _globalFlags.genHadDriveAssembly == 0;
+	case 10: // If siege cycle has never been inventory
+		return _globalFlags.genHadSiegeCycle == 0;
+	case 11: // If neither wheel assembly or drive assembly have ever been in inventory, and after viewing siege cycle plans
+		return _globalFlags.genHadDriveAssembly == 0 && _globalFlags.genHadWheelAssembly == 0;
+	case 12: // After player has been to 5/4/8/1/1/1, siege cycle has never been in inventory
+		return (_globalFlags.dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0 && (_globalFlags.dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0;
+	case 13: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, siege cycle has never been in inventory
+		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.genHadSiegeCycle == 0;
+	case 14: // After player has been to (5/4/4/2/0/1 or 5/4/4/3/0/1) and 5/4/8/1/1/1, before any parts are on the jig
+		return _globalFlags.dsWSSeenCycleSketch == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSGrabbedSiegeCycle == 0;
+	case 15: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, before any parts are on the jig
+		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSGrabbedSiegeCycle == 0;
+	case 16: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, if wheel assembly and drive assembly have never been in inventory
+		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSGrabbedSiegeCycle == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemDriveAssembly) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemWoodenPegs);
+	case 17: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1
+		return _globalFlags.dsWSSeenBallistaSketch == 1;
+	case 18: // Has tried door of codex tower, has never connected ballista hook, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsCYNeverConnectedHook == 0 && _globalFlags.dsWSSeenBallistaSketch == 0;
+	case 19: // Has tried door of codex tower, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 0 && _globalFlags.dsVisitedCodexTower == 0;
+	case 20: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has never shot ballista
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsCYNeverShotBallista == 0;
+	case 21: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has never used crank
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsCYNeverUsedCrank == 0;
+	case 22: // Has never connected ballista hook to codex tower
+		return _globalFlags.dsCYNeverConnectedHook == 0;
+	case 23: // Has tried door of codex tower, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 0 && _globalFlags.dsVisitedCodexTower == 0;
+	case 24: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower, siege cycle not in inventory
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsVisitedCodexTower == 0 && _globalFlags.dsCYBallistaStatus == 2 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
+	case 25: // Has tried door of codex tower, has seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower, has siege cycle in inventory
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsVisitedCodexTower == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
+	case 26: // Has tried door of codex tower, has not seen 5/4/4/2/0/1 or 5/4/4/3/0/1, has not been to codex tower, has siege cycle in inventory
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsWSSeenBallistaSketch == 0 && _globalFlags.dsVisitedCodexTower == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSiegeCycle);
+	case 27: // Has tried door of codex tower, has not connected ballista hook to codex tower
+		return _globalFlags.dsGDClickedOnCodexDoor == 1 && _globalFlags.dsCYBallistaStatus < 2;
+	case 28: // Before ever opening codex tower balcony door
+		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0;
+	case 29: // Before ever opening codex tower balcony door, after trying unsuccessfully to open door
+		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0 && _globalFlags.dsCYTriedOpeningDoor == 1;
+	case 30: // Before ever opening codex tower balcony door, after trying unsuccessfully to open door, balcony key in inventory
+		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0 && _globalFlags.dsCYTriedOpeningDoor == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBalconyKey);
+	case 31: // Before ever opening codex tower balcony door, after trying unsuccessfully to open door, metal bar in inventory, balcony key not in inventory
+		return _globalFlags.dsCYNeverOpenedBalconyDoor == 0 && _globalFlags.dsCYTriedOpeningDoor == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemMetalBar) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBalconyKey);
+	case 32: // Lens filter not in ineventory
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter);
+	case 33: // Player has not found formulae, before trying to translate any codex
+		return _globalFlags.dsCTCodexFormulaeFound == 0 && _globalFlags.dsCYTranslatedCodex == 0;
+	case 34: // Player has not found formulae, after trying to translate any codex
+		return _globalFlags.dsCTCodexFormulaeFound == 0 && _globalFlags.dsCYTranslatedCodex == 1;
+	case 35: // Player has not found formulae, after trying to translate any codex, lens filter in inventory, lens filter not being used
+		return _globalFlags.dsCTCodexFormulaeFound == 0 && _globalFlags.dsCYTranslatedCodex == 1 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter) && _globalFlags.lensFilterActivated == 0;
+	case 36: // After trying unsuccessfully to open the door
+		return _globalFlags.dsCYTriedOpeningDoor == 1;
+	case 37: // Player has not found formulae
+		return _globalFlags.dsCTCodexFormulaeFound == 0;
+	case 38: // Heart not in inventory
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemPreservedHeart);
+	case 39: // After trying to use the codex tower elevator
+		return _globalFlags.dsCYTriedElevator == 1;
+	case 40: // After trying to translate any codex
+		return _globalFlags.dsCYTranslatedCodex == 1;
+	case 41: // Not node 8, 9, 10, or 11, player has not found codex
+		return commentLocation.node != 8 && commentLocation.node != 9 && commentLocation.node != 10 && commentLocation.node != 11 && _globalFlags.dsCYFoundCodexes == 1;
+	case 42: // Not node 8, 9, 10, or 11
+		return commentLocation.node != 8 && commentLocation.node != 9 && commentLocation.node != 10 && commentLocation.node != 11;
+	case 43: // Not node 8, 9, 10, or 11, player has not found formulae, lens filter in inventory
+		return commentLocation.node != 8 && commentLocation.node != 9 && commentLocation.node != 10 && commentLocation.node != 11 && _globalFlags.dsCTCodexFormulaeFound == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemLensFilter);
+	case 44: // After player has been to 5/4/4/2/0/1 or 5/4/4/3/0/1, before building siege cycle, drive/gear assembly not in inventory
+		return _globalFlags.dsWSSeenBallistaSketch == 1 && _globalFlags.dsWSSiegeCycleStatus == 0 && _globalFlags.dsWSPickedUpWheelAssembly == 0;
+	case 45: // After weeble has been spun/clicked
+		return _globalFlags.dsCYWeebleClicked == 1;
+	}
+
+	return false;
+}
+
 SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
@@ -681,7 +778,7 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 	case 55:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 210, 0, 330, 110, kCursorMagnifyingGlass, 5, 2, 3, 4, 1, 1, TRANSITION_VIDEO, 15, -1, -1);
 	case 58:
-		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, offsetof(GlobalFlags, dsCYWeeblieClicked), 200, 88, 270, 189);
+		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, offsetof(GlobalFlags, dsCYWeebleClicked), 200, 88, 270, 189);
 	case 59:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 2, kCursorFinger, 70, 136, 190, 189);
 	case 60:
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 07b0e229c7..45f5d5a962 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -78,6 +78,8 @@ bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLo
 	switch (commentLocation.timeZone) {
 	case 1:
 		return checkCustomCastleAICommentDependencies(commentLocation, commentData);
+	case 5:
+		return checkCustomDaVinciAICommentDependencies(commentLocation, commentData);
 	case 6:
 		return checkCustomSpaceStationAICommentDependencies(commentLocation, commentData);
 	}
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index ddfb12ab42..af4847b531 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -260,7 +260,7 @@ struct GlobalFlags {
 	byte asRBLastStingerID;             // 253
 	byte asRBStingerID;                 // 254
 	byte aiICProcessedOxygen;           // 255
-	byte dsCYWeeblieClicked;            // 256
+	byte dsCYWeebleClicked;             // 256
 	byte aiICUsedMiningControls;        // 257
 	byte aiSWAttemptedPresMR;           // 258
 	byte aiICRefilledOxygen;            // 259
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index 4e95ba81b8..53d5f1f5c6 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -441,7 +441,7 @@ bool BuriedEngine::syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags) {
 	s.syncAsByte(flags.asRBLastStingerID);
 	s.syncAsByte(flags.asRBStingerID);
 	s.syncAsByte(flags.aiICProcessedOxygen);
-	s.syncAsByte(flags.dsCYWeeblieClicked);
+	s.syncAsByte(flags.dsCYWeebleClicked);
 	s.syncAsByte(flags.aiICUsedMiningControls);
 	s.syncAsByte(flags.aiSWAttemptedPresMR);
 	s.syncAsByte(flags.aiICRefilledOxygen);
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 58233836fe..31d5492521 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -214,6 +214,7 @@ private:
 	bool initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	bool startDaVinciAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	bool checkCustomDaVinciAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
 
 	// Future Apartment
 	bool startFutureApartmentAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);


Commit: 67a38919a3c04ed12264dafea79c7c5230bf508d
    https://github.com/scummvm/scummvm/commit/67a38919a3c04ed12264dafea79c7c5230bf508d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Add the Future Apartment AI comment dependency

Changed paths:
    engines/buried/environ/scene_factory.cpp


diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 45f5d5a962..f4355c9bb8 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -78,6 +78,8 @@ bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLo
 	switch (commentLocation.timeZone) {
 	case 1:
 		return checkCustomCastleAICommentDependencies(commentLocation, commentData);
+	case 4:
+		return commentData.dependencyFlagOffsetB == 1; // Not sure what this one does
 	case 5:
 		return checkCustomDaVinciAICommentDependencies(commentLocation, commentData);
 	case 6:


Commit: 5f3160c98470b3d9bcf5a416298b652343b00840
    https://github.com/scummvm/scummvm/commit/5f3160c98470b3d9bcf5a416298b652343b00840
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement picking up the wheel assembly

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 552d68e99b..52b2c97efb 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -469,6 +469,102 @@ int PaintingTowerInsideDoor::specifyCursor(Window *viewWindow, const Common::Poi
 	return kCursorArrow;
 }
 
+class WheelAssemblyItemAcquire : public SceneBase {
+public:
+	WheelAssemblyItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = 0, int top = 0, int right = 0, int bottom = 0, int itemID = 0, int clearStillFrame = 0, int itemFlagOffset = 0);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _itemPresent;
+	Common::Rect _acquireRegion;
+	int _fullFrameIndex;
+	int _clearFrameIndex;
+	int _itemID;
+	int _itemFlagOffset;
+	Common::Rect _zoomUpRegion;
+};
+
+WheelAssemblyItemAcquire::WheelAssemblyItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int itemID, int clearStillFrame, int itemFlagOffset) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_itemPresent = true;
+	_itemID = itemID;
+	_acquireRegion = Common::Rect(left, top, right, bottom);
+	_fullFrameIndex = _staticData.navFrameIndex;
+	_clearFrameIndex = clearStillFrame;
+	_itemFlagOffset = itemFlagOffset;
+	_zoomUpRegion = Common::Rect(134, 168, 200, 189);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) != 0) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+	}
+}
+
+int WheelAssemblyItemAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_itemPresent && _acquireRegion.contains(pointLocation)) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+		viewWindow->invalidateWindow(false);
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
+
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int WheelAssemblyItemAcquire::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (!_itemPresent && _zoomUpRegion.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = Location(5, 4, 8, 1, 1, 1);
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 15;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	}
+
+	return SC_FALSE;
+}
+
+int WheelAssemblyItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (_itemID == itemID && !_itemPresent && pointLocation.x >= 0 && pointLocation.y >= 0) {
+		_itemPresent = true;
+		_staticData.navFrameIndex = _fullFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
+
+		viewWindow->invalidateWindow(false);
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int WheelAssemblyItemAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_itemPresent && _acquireRegion.contains(pointLocation))
+		return kCursorOpenHand;
+
+	if (!_itemPresent && _zoomUpRegion.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 enum {
 	DS_SC_DRIVE_ASSEMBLY = 1,
 	DS_SC_WHEEL_ASSEMBLY = 2,
@@ -554,6 +650,81 @@ int WalkDownPaintingTowerElevator::specifyCursor(Window *viewWindow, const Commo
 	return kCursorArrow;
 }
 
+class ViewSiegeCyclePlans : public SceneBase {
+public:
+	ViewSiegeCyclePlans(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _transText[3];
+	int _textTranslated;
+};
+
+ViewSiegeCyclePlans::ViewSiegeCyclePlans(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_transText[0] = Common::Rect(245, 8, 307, 24);
+	_transText[1] = Common::Rect(132, 40, 188, 76);
+	_transText[2] = Common::Rect(278, 146, 332, 178);
+	_textTranslated = -1;
+
+	// Set the scene visited flag
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSeenCycleSketch = 1;
+}
+
+int ViewSiegeCyclePlans::gdiPaint(Window *viewWindow) {
+	if (_textTranslated >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_transText[_textTranslated]);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int ViewSiegeCyclePlans::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// Return to depth zero
+	DestinationScene destData;
+	destData.destinationScene = _staticData.location;
+	destData.destinationScene.depth = 0;
+	destData.transitionType = TRANSITION_VIDEO;
+	destData.transitionData = 16;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int ViewSiegeCyclePlans::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		for (int i = 0; i < 3; i++) {
+			if (_transText[i].contains(pointLocation)) {
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTTransElevatorControls = 1;
+
+				Common::String text = _vm->getString(IDS_DS_WS_CYCLE_PLANS_TEXT_A + i);
+				((SceneViewWindow *)viewWindow)->displayTranslationText(text);
+				_textTranslated = i;
+				viewWindow->invalidateWindow(false);
+				break;
+			}
+		}
+	} else {
+		if (_textTranslated >= 0) {
+			_textTranslated = -1;
+			viewWindow->invalidateWindow(false);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ViewSiegeCyclePlans::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	return kCursorPutDown;
+}
+
 bool SceneViewWindow::initializeDaVinciTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -761,6 +932,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 90, 328, 162, kItemDriveAssembly, 145, offsetof(GlobalFlags, dsWSPickedUpGearAssembly));
 	case 33:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 164, 126, 276, 160, kItemWoodenPegs, 96, offsetof(GlobalFlags, dsWSPickedUpPegs));
+	case 34:
+		return new WheelAssemblyItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 150, 150, 276, 189, kItemWheelAssembly, 100, offsetof(GlobalFlags, dsWSPickedUpWheelAssembly));
+	case 35:
+		return new ViewSiegeCyclePlans(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 38:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 130, 74, 182, 120, kItemCoilOfRope, 48, offsetof(GlobalFlags, dsGDTakenCoilOfRope));
 	case 41:


Commit: 74aff808a4ce938616ee201e38f629ac0c47cc82
    https://github.com/scummvm/scummvm/commit/74aff808a4ce938616ee201e38f629ac0c47cc82
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement assembling the siege cycle

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 52b2c97efb..5b02c608e5 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -572,6 +572,195 @@ enum {
 	DS_SC_COMPLETED = 8
 };
 
+class AssembleSiegeCycle : public SceneBase {
+public:
+	AssembleSiegeCycle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _driveDropRegion;
+	Common::Rect _wheelDropRegion;
+	Common::Rect _pegDropRegion;
+	Common::Rect _completedCycle;
+
+	bool resetStillFrame(Window *viewWindow);
+};
+
+AssembleSiegeCycle::AssembleSiegeCycle(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_driveDropRegion = Common::Rect(102, 0, 170, 140);
+	_wheelDropRegion = Common::Rect(264, 0, 334, 170);
+	_pegDropRegion = Common::Rect(260, 10, 310, 162);
+	_completedCycle = Common::Rect(102, 0, 330, 189);
+
+	// Determine which still frame to display
+	resetStillFrame(viewWindow);
+}
+
+int AssembleSiegeCycle::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_completedCycle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle == 0) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_COMPLETED) {
+			// Reset the present flag and change frame index of background
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle = 1;
+			resetStillFrame(viewWindow);
+
+			// Begin dragging
+			Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+			ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+			((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemSiegeCycle, ptInventoryWindow);
+			return SC_TRUE;
+		} else {
+			// Otherwise, check to see if the pegs have been placed and haven't been hammer in
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS)
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_DS_WS_UNSTABLE_CYCLE_MESSAGE));
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int AssembleSiegeCycle::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_completedCycle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_COMPLETED) != 0)
+		return kCursorOpenHand;
+
+	if (_completedCycle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0
+			&& (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) != 0)
+		return kCursorOpenHand;
+
+	return kCursorArrow;
+}
+
+int AssembleSiegeCycle::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	switch (itemID) {
+	case kItemDriveAssembly:
+		if (_driveDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) == 0)
+			return 1;
+		break;
+	case kItemWheelAssembly:
+		if (_wheelDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) == 0)
+			return 1;
+		break;
+	case kItemWoodenPegs:
+		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0)
+			return 1;
+		break;
+	case kItemHammer:
+		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0)
+			return 1;
+		break;
+	}
+
+	return 0;
+}
+
+int AssembleSiegeCycle::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	switch (itemID) {
+	case kItemDriveAssembly:
+		if (_driveDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) == 0) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_DRIVE_ASSEMBLY;
+			resetStillFrame(viewWindow);
+			viewWindow->invalidateWindow(false);
+			return SIC_ACCEPT;
+		}
+		break;
+	case kItemWheelAssembly:
+		if (_wheelDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) == 0) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_WHEEL_ASSEMBLY;
+			resetStillFrame(viewWindow);
+			viewWindow->invalidateWindow(false);
+			return SIC_ACCEPT;
+		}
+		break;
+	case kItemWoodenPegs:
+		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) == 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_PEGS;
+			resetStillFrame(viewWindow);
+			viewWindow->invalidateWindow(false);
+			return SIC_ACCEPT;
+		}
+		break;
+	case kItemHammer:
+		if (_pegDropRegion.contains(pointLocation) && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_PEGS) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_WHEEL_ASSEMBLY) != 0 && (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus & DS_SC_DRIVE_ASSEMBLY) != 0) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus |= DS_SC_COMPLETED;
+			resetStillFrame(viewWindow);
+
+			// Play the hammer movie
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+
+			viewWindow->invalidateWindow(false);
+		}
+		break;
+	}
+
+	return SIC_REJECT;
+}
+
+bool AssembleSiegeCycle::resetStillFrame(Window *viewWindow) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle >= 1) {
+		_staticData.navFrameIndex = 213;
+	} else {
+		byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus;
+		_staticData.navFrameIndex = 105;
+
+		if (status & DS_SC_COMPLETED) {
+			_staticData.navFrameIndex = 220;
+		} else {
+			if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0 && (status & DS_SC_PEGS) != 0) {
+				_staticData.navFrameIndex = 215;
+			} else {
+				if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0) {
+					_staticData.navFrameIndex = 220;
+				} else {
+					if ((status & DS_SC_DRIVE_ASSEMBLY) != 0)
+						_staticData.navFrameIndex = 216;
+					else if ((status & DS_SC_WHEEL_ASSEMBLY) != 0)
+						_staticData.navFrameIndex = 218;
+				}
+			}
+		}
+	}
+
+	return true;
+}
+
+class SiegeCycleTopView : public SceneBase {
+public:
+	SiegeCycleTopView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+};
+
+SiegeCycleTopView::SiegeCycleTopView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSGrabbedSiegeCycle >= 1) {
+		_staticData.navFrameIndex = 214;
+	} else {
+		byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsWSSiegeCycleStatus;
+		_staticData.navFrameIndex = 106;
+
+		if (status & DS_SC_COMPLETED) {
+			_staticData.navFrameIndex = 221;
+		} else {
+			if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0 && (status & DS_SC_PEGS) != 0) {
+				_staticData.navFrameIndex = 221;
+			} else {
+				if ((status & DS_SC_DRIVE_ASSEMBLY) != 0 && (status & DS_SC_WHEEL_ASSEMBLY) != 0) {
+					_staticData.navFrameIndex = 221;
+				} else {
+					if ((status & DS_SC_DRIVE_ASSEMBLY) != 0)
+						_staticData.navFrameIndex = 217;
+					else if ((status & DS_SC_WHEEL_ASSEMBLY) != 0)
+						_staticData.navFrameIndex = 219;
+				}
+			}
+		}
+	}
+}
+
 class PaintingTowerCapAgent : public SceneBase {
 public:
 	PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -936,6 +1125,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new WheelAssemblyItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 150, 150, 276, 189, kItemWheelAssembly, 100, offsetof(GlobalFlags, dsWSPickedUpWheelAssembly));
 	case 35:
 		return new ViewSiegeCyclePlans(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 36:
+		return new AssembleSiegeCycle(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 37:
+		return new SiegeCycleTopView(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 38:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 130, 74, 182, 120, kItemCoilOfRope, 48, offsetof(GlobalFlags, dsGDTakenCoilOfRope));
 	case 41:


Commit: 456c08003c2c475ba7028bb9f9f8d6eb0df648bc
    https://github.com/scummvm/scummvm/commit/456c08003c2c475ba7028bb9f9f8d6eb0df648bc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Implement some courtyard and workshop random scenes

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 5b02c608e5..bd821aa2c5 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -761,6 +761,70 @@ SiegeCycleTopView::SiegeCycleTopView(BuriedEngine *vm, Window *viewWindow, const
 	}
 }
 
+class CourtyardCannon : public SceneBase {
+public:
+	CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _cannon;
+};
+
+CourtyardCannon::CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cannon = Common::Rect(160, 10, 280, 140);
+}
+
+int CourtyardCannon::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_cannon.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+
+	return SC_TRUE;
+}
+
+int CourtyardCannon::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_cannon.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class CourtyardGunDeath : public SceneBase {
+public:
+	CourtyardGunDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _gun;
+};
+
+CourtyardGunDeath::CourtyardGunDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_gun = Common::Rect(140, 68, 294, 189);
+}
+
+int CourtyardGunDeath::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_gun.contains(pointLocation)) {
+		// Play the animation
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
+
+		// Kill the player
+		((SceneViewWindow *)viewWindow)->showDeathScene(31);
+	}
+
+	// Success!
+	return SC_TRUE;
+}
+
+int CourtyardGunDeath::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_gun.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class PaintingTowerCapAgent : public SceneBase {
 public:
 	PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -796,6 +860,97 @@ int PaintingTowerCapAgent::postEnterRoom(Window *viewWindow, const Location &pri
 	return SC_TRUE;
 }
 
+class ClickChangeSceneTranslate : public SceneBase {
+public:
+	ClickChangeSceneTranslate(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0, int timeZone = -1, int environment = -1,
+			int node = -1, int facing = -1, int orientation = -1, int depth = -1, int transitionType = -1, int transitionData = -1,
+			int transitionStartFrame = -1, int transitionLength = -1, int transLeft = -1, int transTop = -1, int transRight = -1,
+			int transBottom = -1, int transTextID = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+	Common::Rect _translateRect;
+	int _textID;
+	bool _textTranslated;
+};
+
+ClickChangeSceneTranslate::ClickChangeSceneTranslate(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int cursorID, int timeZone, int environment,
+		int node, int facing, int orientation, int depth, int transitionType, int transitionData,
+		int transitionStartFrame, int transitionLength, int transLeft, int transTop, int transRight,
+		int transBottom, int transTextID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_cursorID = cursorID;
+	_clickDestination.destinationScene.timeZone = timeZone;
+	_clickDestination.destinationScene.environment = environment;
+	_clickDestination.destinationScene.node = node;
+	_clickDestination.destinationScene.facing = facing;
+	_clickDestination.destinationScene.orientation = orientation;
+	_clickDestination.destinationScene.depth = depth;
+	_clickDestination.transitionType = transitionType;
+	_clickDestination.transitionData = transitionData;
+	_clickDestination.transitionStartFrame = transitionStartFrame;
+	_clickDestination.transitionLength = transitionLength;
+	_translateRect = Common::Rect(transLeft, transTop, transRight, transBottom);
+	_textTranslated = false;
+	_textID = transTextID;
+}
+
+int ClickChangeSceneTranslate::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int ClickChangeSceneTranslate::gdiPaint(Window *viewWindow) {
+	if (_textTranslated && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_translateRect);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int ClickChangeSceneTranslate::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		if (_translateRect.contains(pointLocation)) {
+			((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(_textID));
+			_textTranslated = true;
+			viewWindow->invalidateWindow(false);
+		} else {
+			if (_textTranslated) {
+				_textTranslated = false;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+	} else {
+		if (_textTranslated) {
+			_textTranslated = false;
+			viewWindow->invalidateWindow(false);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ClickChangeSceneTranslate::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return 0;
+}
+
 class WalkDownPaintingTowerElevator : public SceneBase {
 public:
 	WalkDownPaintingTowerElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1105,6 +1260,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 4, kCursorFinger, 180, 122, 290, 189);
 	case 24:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 186, 28, 292, 158, kCursorMagnifyingGlass, 5, 4, 4, 2, 1, 1, TRANSITION_VIDEO, 5, -1, -1);
+	case 25:
+		return new ClickChangeSceneTranslate(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 4, 4, 2, 1, 0, TRANSITION_VIDEO, 6, -1, -1, 190, 88, 308, 160, IDDS_WORKSHOP_TOOLS_TEXT);
 	case 26:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 44, 232, 189, kCursorMagnifyingGlass, 5, 4, 4, 3, 0, 1, TRANSITION_VIDEO, 7, -1, -1);
 	case 27:
@@ -1145,6 +1302,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 14, -1, -1);
 	case 55:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 210, 0, 330, 110, kCursorMagnifyingGlass, 5, 2, 3, 4, 1, 1, TRANSITION_VIDEO, 15, -1, -1);
+	case 57:
+		return new CourtyardCannon(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 58:
 		return new ClickPlayVideoSwitch(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, offsetof(GlobalFlags, dsCYWeebleClicked), 200, 88, 270, 189);
 	case 59:
@@ -1153,6 +1312,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 5, kCursorFinger, 42, 0, 418, 100);
 	case 61:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 3, kCursorFinger, 178, 144, 288, 189);
+	case 62:
+		return new CourtyardGunDeath(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 65:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
 	case 66:


Commit: 7c86219b99b102b88928061dc82d16f9e332ea18
    https://github.com/scummvm/scummvm/commit/7c86219b99b102b88928061dc82d16f9e332ea18
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Fix keyboard focus

Changed paths:
    engines/buried/frame_window.cpp
    engines/buried/overview.cpp


diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 2ebe138fac..b960435891 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -248,6 +248,7 @@ bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
 	// Create Game UI window to kick things off
 	_mainChildWindow = new GameUIWindow(_vm, this);
 	_mainChildWindow->showWindow(kWindowShow);
+	_mainChildWindow->setFocus();
 
 	if (introMovie)
 		((GameUIWindow *)_mainChildWindow)->startNewGameIntro(walkthrough);
@@ -270,6 +271,7 @@ bool FrameWindow::startNewGame(const Common::String &fileName) {
 	// Create Game UI window to kick things off
 	_mainChildWindow = new GameUIWindow(_vm, this);
 	_mainChildWindow->showWindow(kWindowShow);
+	_mainChildWindow->setFocus();
 	((GameUIWindow *)_mainChildWindow)->startNewGame(fileName);
 
 	_vm->removeMouseMessages(this);
@@ -398,6 +400,7 @@ void FrameWindow::loadFromState(const Location &location, const GlobalFlags &fla
 		delete _mainChildWindow;
 		_mainChildWindow = new GameUIWindow(_vm, this);
 		_mainChildWindow->showWindow(kWindowShow);
+		_mainChildWindow->setFocus();
 	}
 
 	GameUIWindow *gameUI = (GameUIWindow *)_mainChildWindow;
diff --git a/engines/buried/overview.cpp b/engines/buried/overview.cpp
index 63e4de223d..1fedef87d4 100644
--- a/engines/buried/overview.cpp
+++ b/engines/buried/overview.cpp
@@ -68,6 +68,7 @@ bool OverviewWindow::startOverview() {
 
 	showWindow(kWindowShow);
 	invalidateWindow();
+	setFocus();
 
 	_timer = setTimer(1000);
 	return true;


Commit: f11771b2e649ea737a9f87d8dce4593187906777
    https://github.com/scummvm/scummvm/commit/f11771b2e649ea737a9f87d8dce4593187906777
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:41+01:00

Commit Message:
BURIED: Fix backspace in shop net

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index cab4b83e99..44fdaf920e 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -410,7 +410,7 @@ int KitchenUnitShopNet::onCharacter(Window *viewWindow, const Common::KeyState &
 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9));
 
 		if (character.keycode == Common::KEYCODE_BACKSPACE || character.keycode == Common::KEYCODE_DELETE) {
-			if (_shopNetCode.empty()) {
+			if (!_shopNetCode.empty()) {
 				// clone2727 asks why the sound effect is being played again
 				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9));
 


Commit: c80c5590c6c8334842a0463ca39996c420768ab3
    https://github.com/scummvm/scummvm/commit/c80c5590c6c8334842a0463ca39996c420768ab3
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Fix drag sprites in 8bpp

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index db5c34fece..c98ec8fda4 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -254,17 +254,6 @@ bool InventoryWindow::startDraggingNewItem(int itemID, const Common::Point &poin
 		_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3];
 		_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 1];
 		_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 2];
-
-		if (!_vm->isDemo()) {
-			for (int y = 0; y < _draggingItemSpriteData.height; y++) {
-				for (int x = 0; x < _draggingItemSpriteData.width; x++) {
-					byte color = *((byte *)_draggingItemSpriteData.image->getBasePtr(x, y));
-
-					if (color != 0)
-						*((byte *)_draggingItemSpriteData.image->getBasePtr(x, y)) = color + 10;
-				}
-			}
-		}
 	}
 
 	setCapture();
@@ -448,17 +437,6 @@ void InventoryWindow::onLButtonDown(const Common::Point &point, uint flags) {
 				_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3];
 				_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 1];
 				_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 2];
-
-				if (!_vm->isDemo()) {
-					for (int y = 0; y < _draggingItemSpriteData.height; y++) {
-						for (int x = 0; x < _draggingItemSpriteData.width; x++) {
-							byte color = *((byte *)_draggingItemSpriteData.image->getBasePtr(x, y));
-
-							if (color != 0)
-								*((byte *)_draggingItemSpriteData.image->getBasePtr(x, y)) = color + 10;
-						}
-					}
-				}
 			}
 
 			setCapture();
@@ -688,20 +666,10 @@ void InventoryWindow::onMouseMove(const Common::Point &point, uint flags) {
 					_draggingItemSpriteData.greenTrans = 255;
 					_draggingItemSpriteData.blueTrans = 255;
 				} else {
-					_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[0];
-					_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[1];
-					_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[2];
-
-					if (!_vm->isDemo()) {
-						for (int y = 0; y < _draggingItemSpriteData.height; y++) {
-							for (int x = 0; x < _draggingItemSpriteData.width; x++) {
-								byte color = *((byte *)_draggingItemSpriteData.image->getBasePtr(x, y));
-
-								if (color != 0)
-									*((byte *)_draggingItemSpriteData.image->getBasePtr(x, y)) = color + 10;
-							}
-						}
-					}
+					byte firstPixel = *((byte *)_draggingItemSpriteData.image->getBasePtr(0, 0));
+					_draggingItemSpriteData.redTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3];
+					_draggingItemSpriteData.greenTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 1];
+					_draggingItemSpriteData.blueTrans = _vm->_gfx->getDefaultPalette()[firstPixel * 3 + 2];
 				}
 			}
 		}


Commit: f95d9be8a1c2e5655652f07c80ae79f82a3171c9
    https://github.com/scummvm/scummvm/commit/f95d9be8a1c2e5655652f07c80ae79f82a3171c9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement turning the ballista

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index bd821aa2c5..07b0107a9c 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -825,6 +825,66 @@ int CourtyardGunDeath::specifyCursor(Window *viewWindow, const Common::Point &po
 	return kCursorArrow;
 }
 
+class ChangeBallistaDepth : public SceneBase {
+public:
+	ChangeBallistaDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+};
+
+ChangeBallistaDepth::ChangeBallistaDepth(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus != _staticData.location.depth) {
+		Location newLocation = _staticData.location;
+		newLocation.depth = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus;
+		((SceneViewWindow *)viewWindow)->getSceneStaticData(newLocation, _staticData);
+	}
+}
+
+class SpinBallista : public SceneBase {
+public:
+	SpinBallista(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _handle;
+};
+
+SpinBallista::SpinBallista(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_handle = Common::Rect(126, 106, 190, 162);
+}
+
+int SpinBallista::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_handle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus < 2) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus == 1) {
+			destData.transitionData = 7;
+			destData.destinationScene.depth = 0;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus = 0;
+		} else {
+			destData.transitionData = 6;
+			destData.destinationScene.depth = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus = 1;
+		}
+
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	}
+
+	return SC_TRUE;
+}
+
+int SpinBallista::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_handle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus < 2)
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class PaintingTowerCapAgent : public SceneBase {
 public:
 	PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1314,6 +1374,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 3, kCursorFinger, 178, 144, 288, 189);
 	case 62:
 		return new CourtyardGunDeath(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 63:
+		return new ChangeBallistaDepth(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 64:
+		return new SpinBallista(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 65:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
 	case 66:


Commit: 5a4a5bcf5e23ba74d460014ed7f9a4219bb00e4d
    https://github.com/scummvm/scummvm/commit/5a4a5bcf5e23ba74d460014ed7f9a4219bb00e4d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement clipping animations

Changed paths:
    engines/buried/scene_view.cpp
    engines/buried/video_window.cpp
    engines/buried/video_window.h


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 9c69d2abca..dd83681332 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1648,8 +1648,78 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 }
 
 bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left, int top, int right, int bottom) {
-	// TODO
-	return playPlacedSynchronousAnimation(animationID, left, top);
+	_useWaitCursor = true;
+
+	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
+
+	bool found = false;
+	uint i = 0;
+	for (; i < animDatabase.size(); i++) {
+		if (animDatabase[i].animationID == animationID) {
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+		return false;
+
+	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animDatabase[i].fileNameID);
+	if (!animationMovie->openVideo(fileName))
+		error("Failed to open video '%s'", fileName.c_str());
+
+	animationMovie->setWindowPos(kWindowPosTopMost, left, top, right - left, bottom - top, kWindowPosNoActivate | kWindowPosNoZOrder);
+
+	animationMovie->setSourceRect(Common::Rect(left, top, right, bottom));
+	animationMovie->setDestRect(Common::Rect(0, 0, right - left, bottom - top));
+
+	// TODO: Try switching to the second audio stream if translation is enabled
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
+		// FIXME: Nah, why bother to free the movie
+		// (Probably, this is never hit)
+		return false;
+	}
+
+	animationMovie->seekToFrame(animDatabase[i].startFrame);
+	animationMovie->enableWindow(false);
+	animationMovie->showWindow(kWindowShow);
+	_parent->invalidateWindow(false);
+
+	// Empty the input queue
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// Stop background sound if the video has sound
+	if (animDatabase[i].audioStreamCount > 0)
+		_vm->_sound->stop();
+
+	animationMovie->playToFrame(animDatabase[i].startFrame + animDatabase[i].frameCount - 1);
+
+	while (!_vm->shouldQuit() && animationMovie->getMode() != VideoWindow::kModeStopped) {
+		_vm->yield();
+		_vm->_sound->timerCallback();
+	}
+
+	if (_vm->shouldQuit()) {
+		delete animationMovie;
+		return true;
+	}
+
+	_vm->removeMouseMessages(this);
+	_vm->removeKeyboardMessages(this);
+
+	// Restart background sound if the video had sound
+	if (animDatabase[i].audioStreamCount > 0)
+		_vm->_sound->restart();
+
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+		return false;
+
+	delete animationMovie;
+	_useWaitCursor = false;
+	return true;
 }
 
 bool SceneViewWindow::startAsynchronousAnimation(int animationID, bool loopAnimation) {
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 0a417518ed..26cf88eed3 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -129,6 +129,8 @@ void VideoWindow::closeVideo() {
 		_mode = kModeClosed;
 		_lastFrame = 0;
 		_rect = Common::Rect();
+		_srcRect = Common::Rect();
+		_dstRect = Common::Rect();
 
 		if (_ownedFrame) {
 			_ownedFrame->free();
@@ -184,8 +186,20 @@ void VideoWindow::updateVideo() {
 void VideoWindow::onPaint() {
 	if (_lastFrame) {
 		Common::Rect absoluteRect = getAbsoluteRect();
-		_vm->_gfx->blit(_lastFrame, absoluteRect.left, absoluteRect.top);
+
+		if (_srcRect.isEmpty() && _dstRect.isEmpty())
+			_vm->_gfx->blit(_lastFrame, absoluteRect.left, absoluteRect.top);
+		else
+			_vm->_gfx->crossBlit(_vm->_gfx->getScreen(), absoluteRect.left + _dstRect.left, absoluteRect.top + _dstRect.top, _dstRect.width(), _dstRect.height(), _lastFrame, _srcRect.left, _srcRect.top);
 	}
 }
 
+void VideoWindow::setSourceRect(const Common::Rect &srcRect) {
+	_srcRect = srcRect;
+}
+
+void VideoWindow::setDestRect(const Common::Rect &dstRect) {
+	_dstRect = dstRect;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
index 740153940d..ce02628662 100644
--- a/engines/buried/video_window.h
+++ b/engines/buried/video_window.h
@@ -50,6 +50,8 @@ public:
 	void stopVideo(); // MCIWndStop
 	int getCurFrame(); // MCIWndGetPosition
 	int getFrameCount(); // MCIWndGetLength
+	void setSourceRect(const Common::Rect &srcRect); // MCIWndPutSource
+	void setDestRect(const Common::Rect &dstRect); // MCIWndPutDest
 
 	bool openVideo(const Common::String &fileName); // MCIWndOpen
 	void closeVideo(); // MCIWndClose
@@ -74,6 +76,7 @@ private:
 	Mode _mode;
 	Graphics::Surface *_ownedFrame;
 	bool _needsPalConversion;
+	Common::Rect _srcRect, _dstRect;
 };
 
 } // End of namespace Buried


Commit: 3081fd6d01f327c9aacc7be76d0bc87e24f8c057
    https://github.com/scummvm/scummvm/commit/3081fd6d01f327c9aacc7be76d0bc87e24f8c057
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement firing the ballista

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 07b0107a9c..5ae0a17efb 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/avi_frames.h"
 #include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
@@ -885,6 +886,181 @@ int SpinBallista::specifyCursor(Window *viewWindow, const Common::Point &pointLo
 	return kCursorArrow;
 }
 
+class AimBallistaAwayFromTower : public SceneBase {
+public:
+	AimBallistaAwayFromTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~AimBallistaAwayFromTower();
+	void preDestructor();
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _raiseBallista;
+	Common::Rect _lowerBallista;
+	Common::Rect _turnBallistaLeft;
+	Common::Rect _turnBallistaRight;
+	Common::Rect _ballistaHandle;
+	AVIFrames *_viewFrameExtractor;
+};
+
+AimBallistaAwayFromTower::AimBallistaAwayFromTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_turnBallistaLeft = Common::Rect(0, 84, 44, 189);
+	_turnBallistaRight = Common::Rect(45, 84, 90, 189);
+	_lowerBallista = Common::Rect(368, 82, 432, 189);
+	_raiseBallista = Common::Rect(304, 82, 367, 189);
+	_ballistaHandle = Common::Rect(170, 116, 212, 189);
+
+	_viewFrameExtractor = new AVIFrames(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 6));
+}
+
+AimBallistaAwayFromTower::~AimBallistaAwayFromTower() {
+	preDestructor();
+}
+
+void AimBallistaAwayFromTower::preDestructor() {
+	delete _viewFrameExtractor;
+	_viewFrameExtractor = 0;
+}
+
+int AimBallistaAwayFromTower::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	SceneBase::paint(viewWindow, preBuffer);
+
+	byte xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+	byte yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+	const Graphics::Surface *frame = _viewFrameExtractor->getFrame(yPos * 20 + xPos + 200);
+
+	if (frame)
+		_vm->_gfx->crossBlit(preBuffer, 120, 51, 160, 56, frame, 0, 0);
+
+	return SC_REPAINT;
+}
+
+int AimBallistaAwayFromTower::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_ballistaHandle.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverShotBallista = 1;
+
+		// Play the handle movie
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(14, 96, 110, 296, 189);
+
+		return SC_TRUE;
+	} else if (_raiseBallista.contains(pointLocation)) {
+		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+
+		if (yPos == 0)
+			return SC_FALSE;
+
+		yPos--;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(17, 300, 70, 432, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_lowerBallista.contains(pointLocation)) {
+		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+
+		if (yPos >= 4)
+			return SC_FALSE;
+
+		yPos++;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(18, 300, 70, 432, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_turnBallistaRight.contains(pointLocation)) {
+		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+
+		if (xPos >= 19)
+			return SC_FALSE;
+
+		xPos++;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(16, 0, 70, 100, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_turnBallistaLeft.contains(pointLocation)) {
+		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+
+		if (xPos == 0)
+			return SC_FALSE;
+
+		xPos--;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(15, 0, 70, 100, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	// Return to previous scene
+	DestinationScene destData;
+	destData.destinationScene = Location(5, 5, 8, 5, 1, 0);
+	destData.transitionType = TRANSITION_VIDEO;
+	destData.transitionData = 10;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int AimBallistaAwayFromTower::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_raiseBallista.contains(pointLocation))
+		return kCursorArrowUp;
+
+	if (_lowerBallista.contains(pointLocation))
+		return kCursorArrowDown;
+
+	if (_turnBallistaRight.contains(pointLocation))
+		return kCursorArrowRight;
+
+	if (_turnBallistaLeft.contains(pointLocation))
+		return kCursorArrowLeft;
+
+	if (_ballistaHandle.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class PaintingTowerCapAgent : public SceneBase {
 public:
 	PaintingTowerCapAgent(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1011,6 +1187,201 @@ int ClickChangeSceneTranslate::specifyCursor(Window *viewWindow, const Common::P
 	return 0;
 }
 
+class AimBallistaToTower : public SceneBase {
+public:
+	AimBallistaToTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~AimBallistaToTower();
+	void preDestructor();
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _raiseBallista;
+	Common::Rect _lowerBallista;
+	Common::Rect _turnBallistaLeft;
+	Common::Rect _turnBallistaRight;
+	Common::Rect _ballistaHandle;
+	AVIFrames *_viewFrameExtractor;
+};
+
+AimBallistaToTower::AimBallistaToTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_turnBallistaLeft = Common::Rect(0, 84, 44, 189);
+	_turnBallistaRight = Common::Rect(45, 84, 90, 189);
+	_lowerBallista = Common::Rect(368, 82, 432, 189);
+	_raiseBallista = Common::Rect(304, 82, 367, 189);
+	_ballistaHandle = Common::Rect(170, 116, 212, 189);
+
+	_viewFrameExtractor = new AVIFrames(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 6));
+}
+
+AimBallistaToTower::~AimBallistaToTower() {
+	preDestructor();
+}
+
+void AimBallistaToTower::preDestructor() {
+	delete _viewFrameExtractor;
+	_viewFrameExtractor = 0;
+}
+
+int AimBallistaToTower::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	SceneBase::paint(viewWindow, preBuffer);
+
+	byte xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+	byte yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+	const Graphics::Surface *frame = _viewFrameExtractor->getFrame(yPos * 20 + xPos);
+
+	if (frame)
+		_vm->_gfx->crossBlit(preBuffer, 120, 51, 160, 56, frame, 0, 0);
+
+	return SC_REPAINT;
+}
+
+int AimBallistaToTower::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_ballistaHandle.contains(pointLocation)) {
+		byte xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+		byte yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverShotBallista = 1;
+
+		if (xPos == 9 && yPos == 2) {
+			// Play the launch movie
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(20);
+
+			// Reset the ballista status
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaStatus = 2;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverConnectedHook = 1;
+
+			// Step down
+			DestinationScene destData;
+			destData.destinationScene = Location(5, 5, 8, 5, 1, 2);
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 11;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		} else {
+			// Play the launch movie
+			((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(19, 110, 108, 290, 189);
+		}
+
+		return SC_TRUE;
+	} else if (_raiseBallista.contains(pointLocation)) {
+		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+
+		if (yPos == 0)
+			return SC_FALSE;
+
+		yPos--;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(23, 300, 70, 432, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_lowerBallista.contains(pointLocation)) {
+		byte &yPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaYPos;
+
+		if (yPos >= 4)
+			return SC_FALSE;
+
+		yPos++;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(24, 300, 70, 432, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_turnBallistaRight.contains(pointLocation)) {
+		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+
+		if (xPos >= 19)
+			return SC_FALSE;
+
+		xPos++;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(22, 0, 70, 100, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_turnBallistaLeft.contains(pointLocation)) {
+		byte &xPos = ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYBallistaXPos;
+
+		if (xPos == 0)
+			return SC_FALSE;
+
+		xPos--;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverUsedCrank = 1;
+
+		// Start the spin sound
+		int soundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12), 128, true, false);
+
+		// Spin the wheel halfway
+		((SceneViewWindow *)viewWindow)->playClippedSynchronousAnimation(21, 0, 70, 100, 189);
+
+		// Stop the spin sound
+		_vm->_sound->stopSoundEffect(soundID);
+
+		// Repaint
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	// Return to previous scene
+	DestinationScene destData;
+	destData.destinationScene = Location(5, 5, 8, 5, 1, 1);
+	destData.transitionType = TRANSITION_VIDEO;
+	destData.transitionData = 11;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int AimBallistaToTower::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_raiseBallista.contains(pointLocation))
+		return kCursorArrowUp;
+
+	if (_lowerBallista.contains(pointLocation))
+		return kCursorArrowDown;
+
+	if (_turnBallistaRight.contains(pointLocation))
+		return kCursorArrowRight;
+
+	if (_turnBallistaLeft.contains(pointLocation))
+		return kCursorArrowLeft;
+
+	if (_ballistaHandle.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class WalkDownPaintingTowerElevator : public SceneBase {
 public:
 	WalkDownPaintingTowerElevator(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1382,6 +1753,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
 	case 66:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 170, 0, 432, 189, 5, 4, 0, 0, 1, 1, TRANSITION_WALK, 11, 1220, 12);
+	case 68:
+		return new AimBallistaAwayFromTower(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 69:
+		return new AimBallistaToTower(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 70:
 		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 72:


Commit: 377c4c86642cd8173989b678afb52b0e5433bee4
    https://github.com/scummvm/scummvm/commit/377c4c86642cd8173989b678afb52b0e5433bee4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement placing the siege cycle

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 5ae0a17efb..1dc565f933 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -30,6 +30,7 @@
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
+#include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -886,6 +887,85 @@ int SpinBallista::specifyCursor(Window *viewWindow, const Common::Point &pointLo
 	return kCursorArrow;
 }
 
+class PlaceSiegeCycleOnTrack : public SceneBase {
+public:
+	PlaceSiegeCycleOnTrack(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _cycleRect;
+	void setArrows(Window *viewWindow);
+};
+
+PlaceSiegeCycleOnTrack::PlaceSiegeCycleOnTrack(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cycleRect = Common::Rect(0, 0, 350, 160);
+
+	// If we placed the cycle on the track, change the still frame
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle != 0) {
+		_staticData.navFrameIndex = 229;
+		setArrows(viewWindow);
+	}
+}
+
+int PlaceSiegeCycleOnTrack::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemSiegeCycle && _cycleRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle == 0)
+		return 1;
+
+	return 0;
+}
+
+int PlaceSiegeCycleOnTrack::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (itemID == kItemSiegeCycle && _cycleRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle == 0) {
+		_staticData.navFrameIndex = 229;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle = 1;
+		viewWindow->invalidateWindow(false);
+		setArrows(viewWindow);
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+void PlaceSiegeCycleOnTrack::setArrows(Window *viewWindow) {
+	// Can only walk to the siege cycle
+	_staticData.destForward.destinationScene = Location(5, 5, 13, 0, 0, 0);
+	_staticData.destForward.transitionType = TRANSITION_VIDEO;
+	_staticData.destForward.transitionData = 12;
+	_staticData.destForward.transitionStartFrame = -1;
+	_staticData.destForward.transitionLength = -1;
+
+	_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destUp.transitionType = -1;
+	_staticData.destUp.transitionData = -1;
+	_staticData.destUp.transitionStartFrame = -1;
+	_staticData.destUp.transitionLength = -1;
+
+	_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destLeft.transitionType = -1;
+	_staticData.destLeft.transitionData = -1;
+	_staticData.destLeft.transitionStartFrame = -1;
+	_staticData.destLeft.transitionLength = -1;
+
+	_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destRight.transitionType = -1;
+	_staticData.destRight.transitionData = -1;
+	_staticData.destRight.transitionStartFrame = -1;
+	_staticData.destRight.transitionLength = -1;
+
+	_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destDown.transitionType = -1;
+	_staticData.destDown.transitionData = -1;
+	_staticData.destDown.transitionStartFrame = -1;
+	_staticData.destDown.transitionLength = -1;
+
+	((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
+}
+
 class AimBallistaAwayFromTower : public SceneBase {
 public:
 	AimBallistaAwayFromTower(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1753,6 +1833,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 122, 8, 326, 189, 5, 5, 0, 2, 1, 1, TRANSITION_WALK, 11, 738, 18);
 	case 66:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 170, 0, 432, 189, 5, 4, 0, 0, 1, 1, TRANSITION_WALK, 11, 1220, 12);
+	case 67:
+		return new PlaceSiegeCycleOnTrack(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 68:
 		return new AimBallistaAwayFromTower(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 69:


Commit: daa42fea2d0d4dbc393fbbbaeef46c77b954e931
    https://github.com/scummvm/scummvm/commit/daa42fea2d0d4dbc393fbbbaeef46c77b954e931
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement getting into the codex tower

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 1dc565f933..57739b9ee1 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -763,6 +763,140 @@ SiegeCycleTopView::SiegeCycleTopView(BuriedEngine *vm, Window *viewWindow, const
 	}
 }
 
+class UnlockCodexTowerDoor : public SceneBase {
+public:
+	UnlockCodexTowerDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _dropRect;
+};
+
+UnlockCodexTowerDoor::UnlockCodexTowerDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_dropRect = Common::Rect(138, 120, 198, 189);
+}
+
+int UnlockCodexTowerDoor::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemBalconyKey && _dropRect.contains(pointLocation))
+		return 1;
+
+	return 0;
+}
+
+int UnlockCodexTowerDoor::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (itemID == kItemBalconyKey && _dropRect.contains(pointLocation)) {
+		// Play the unlocking animation
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(0);
+
+		// Set the unlocked door flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor = 1;
+	}
+
+	// Player keeps the item
+	return SIC_REJECT;
+}
+
+class CodexTowerOutsideDoor : public SceneBase {
+public:
+	CodexTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _dropRect;
+	Common::Rect _doorRect;
+};
+
+CodexTowerOutsideDoor::CodexTowerOutsideDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_dropRect = Common::Rect(130, 0, 200, 189);
+	_doorRect = Common::Rect(0, 0, 166, 189);
+}
+
+int CodexTowerOutsideDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorRect.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor >= 1) {
+			// Set the opened door flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYNeverOpenedBalconyDoor = 1;
+
+			DestinationScene destData;
+			destData.destinationScene = _staticData.location;
+			destData.destinationScene.depth = 1;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 2;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+
+			// Play a different video otherwise
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0) {
+				destData.transitionType = TRANSITION_VIDEO;
+				destData.transitionData = 1;
+			}
+
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		} else {
+			// Door is locked, play the door lock sound and set the tried flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTriedLockedDoor = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYTriedOpeningDoor = 1;
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
+
+			// Check for spontaneous AI comments
+			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerOutsideDoor::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	// Little known fact that the metal bar can be used to unlock the door
+	if (itemID == kItemMetalBar && _dropRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0)
+		return 1;
+
+	return 0;
+}
+
+int CodexTowerOutsideDoor::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (itemID == kItemMetalBar && _dropRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0) {
+		// Move to the next scene
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 1;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 2;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+
+		// Set the unlocked door flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor = 1;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 = 1;
+	}
+
+	// Player keeps the item
+	return SIC_REJECT;
+}
+
+int CodexTowerOutsideDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorRect.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class CourtyardCannon : public SceneBase {
 public:
 	CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1799,6 +1933,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new SiegeCycleTopView(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 38:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 130, 74, 182, 120, kItemCoilOfRope, 48, offsetof(GlobalFlags, dsGDTakenCoilOfRope));
+	case 39:
+		return new UnlockCodexTowerDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 40:
+		return new CodexTowerOutsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 41:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 116, 0, 326, 189, 5, 2, 2, 1, 1, 1, TRANSITION_WALK, 11, 225, 15);
 	case 46:
@@ -1847,6 +1985,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 140, 0, 432, 189);
 	case 75:
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsCYTriedElevator), 13, kCursorFinger, 140, 130, 432, 189);
+	case 76:
+		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, offsetof(GlobalFlags, dsCTPlayedBallistaFalling));
 	}
 
 	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);


Commit: 0fe51571dbc1eab68c5ff73193359df085fce996
    https://github.com/scummvm/scummvm/commit/0fe51571dbc1eab68c5ff73193359df085fce996
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the lens filter evidence

Changed paths:
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 57739b9ee1..ca5a9512fd 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -897,6 +897,117 @@ int CodexTowerOutsideDoor::specifyCursor(Window *viewWindow, const Common::Point
 	return kCursorArrow;
 }
 
+class CodexTowerLensEvidenceCapture : public SceneBase {
+public:
+	CodexTowerLensEvidenceCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _evidenceRegion;
+	bool _captured;
+	Common::Rect _drum;
+};
+
+CodexTowerLensEvidenceCapture::CodexTowerLensEvidenceCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_evidenceRegion = Common::Rect(210, 106, 238, 132);
+	_drum = Common::Rect(288, 0, 368, 52);
+	_captured = false;
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTRetrievedLens >= 1) {
+		_staticData.navFrameIndex = 172;
+		_captured = true;
+	}
+}
+
+int CodexTowerLensEvidenceCapture::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_drum.contains(pointLocation)) {
+		// Play the drum animation
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerLensEvidenceCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTRetrievedLens == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_evidenceRegion.contains(pointLocation)) {
+			BuriedEngine *vm = _vm;
+
+			DestinationScene destData;
+			destData.destinationScene = _staticData.location;
+			destData.destinationScene.depth = 1;
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 3;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+
+			// Add it to the list
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_LENS_FILTER))
+				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Turn off capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerLensEvidenceCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTRetrievedLens == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_evidenceRegion.contains(pointLocation))
+			return -2;
+
+		return -1;
+	}
+
+	if (_drum.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class CodexTowerGrabLens : public GenericItemAcquire {
+public:
+	CodexTowerGrabLens(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+};
+
+CodexTowerGrabLens::CodexTowerGrabLens(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		GenericItemAcquire(vm, viewWindow, sceneStaticData, priorLocation, 200, 78, 262, 123, kItemLensFilter, 169, offsetof(GlobalFlags, dsCTRetrievedLens)) {
+}
+
+int CodexTowerGrabLens::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1 && itemID == _itemID && !_itemPresent) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated = 1;
+			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_LENS_FILTER_ACTIVATED));
+		}
+
+		// Move back
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 0;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 4;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return 0;
+	}
+
+	return GenericItemAcquire::droppedItem(viewWindow, itemID, pointLocation, itemFlags);
+}
+
 class CourtyardCannon : public SceneBase {
 public:
 	CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1639,6 +1750,23 @@ int WalkDownPaintingTowerElevator::specifyCursor(Window *viewWindow, const Commo
 	return kCursorArrow;
 }
 
+class LensFilterNotify : public SceneBase {
+public:
+	LensFilterNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &newLocation);
+};
+
+LensFilterNotify::LensFilterNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int LensFilterNotify::postEnterRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.node != _staticData.location.node && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_LENS_FILTER))
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+
+	return SC_TRUE;
+}
+
 class ViewSiegeCyclePlans : public SceneBase {
 public:
 	ViewSiegeCyclePlans(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1939,6 +2067,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new CodexTowerOutsideDoor(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 41:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 116, 0, 326, 189, 5, 2, 2, 1, 1, 1, TRANSITION_WALK, 11, 225, 15);
+	case 42:
+		return new CodexTowerLensEvidenceCapture(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 43:
+		return new CodexTowerGrabLens(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 46:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 8, kCursorFinger, 102, 124, 164, 189);
 	case 51:
@@ -1981,6 +2113,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 72:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 13);
+	case 73:
+		return new LensFilterNotify(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 74:
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, -1, 13, kCursorFinger, 140, 0, 432, 189);
 	case 75:
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index d9c6be8e5c..7a5087a620 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -59,10 +59,10 @@ public:
 	GenericItemAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 			int left = 0, int top = 0, int right = 0, int bottom = 0, int itemID = 0, int clearStillFrame = 0, int itemFlagOffset = 0);
 	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
-	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	virtual int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
 
-private:
+protected:
 	bool _itemPresent;
 	Common::Rect _acquireRegion;
 	int _fullFrameIndex;


Commit: 0e148ce14aff77244a6880f86e30b8345fd8d42b
    https://github.com/scummvm/scummvm/commit/0e148ce14aff77244a6880f86e30b8345fd8d42b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement a couple random codex tower scenes

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index ca5a9512fd..ca8b96d2c6 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -1008,6 +1008,47 @@ int CodexTowerGrabLens::droppedItem(Window *viewWindow, int itemID, const Common
 	return GenericItemAcquire::droppedItem(viewWindow, itemID, pointLocation, itemFlags);
 }
 
+class ClickBirdDevice : public SceneBase {
+public:
+	ClickBirdDevice(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _birdToy;
+};
+
+ClickBirdDevice::ClickBirdDevice(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_birdToy = Common::Rect(90, 52, 198, 98);
+}
+
+int ClickBirdDevice::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_birdToy.contains(pointLocation)) {
+		// Play the animation
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
+	} else {
+		// Return back
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 0;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 16;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	}
+
+	return SC_TRUE;
+}
+
+int ClickBirdDevice::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_birdToy.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class CourtyardCannon : public SceneBase {
 public:
 	CourtyardCannon(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1767,6 +1808,23 @@ int LensFilterNotify::postEnterRoom(Window *viewWindow, const Location &newLocat
 	return SC_TRUE;
 }
 
+class CodexFormulaeNotify : public SceneBase {
+public:
+	CodexFormulaeNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &newLocation);
+};
+
+CodexFormulaeNotify::CodexFormulaeNotify(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int CodexFormulaeNotify::postEnterRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.node != _staticData.location.node && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX))
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+
+	return SC_TRUE;
+}
+
 class ViewSiegeCyclePlans : public SceneBase {
 public:
 	ViewSiegeCyclePlans(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2083,6 +2141,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 5, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 14, -1, -1);
 	case 55:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 210, 0, 330, 110, kCursorMagnifyingGlass, 5, 2, 3, 4, 1, 1, TRANSITION_VIDEO, 15, -1, -1);
+	case 56:
+		return new ClickBirdDevice(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 57:
 		return new CourtyardCannon(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 58:
@@ -2121,6 +2181,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsCYTriedElevator), 13, kCursorFinger, 140, 130, 432, 189);
 	case 76:
 		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, offsetof(GlobalFlags, dsCTPlayedBallistaFalling));
+	case 77:
+		return new CodexFormulaeNotify(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
 	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);


Commit: be0204f26ef26ab2d5658d56eec65e39f7f94f82
    https://github.com/scummvm/scummvm/commit/be0204f26ef26ab2d5658d56eec65e39f7f94f82
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Fix bad reads when going through AI comments

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index dd83681332..dd7889363e 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1947,7 +1947,7 @@ bool SceneViewWindow::startPlacedAsynchronousAnimationExtern(int left, int top,
 }
 
 bool SceneViewWindow::retrieveAICommentEntry(const Location &commentLocation, int commentType, const Common::Array<AIComment> &commentDatabase, int &lastFoundIndex, AIComment &currentCommentData) {
-	if (commentDatabase.empty())
+	if (commentDatabase.empty() || (uint32)lastFoundIndex >= commentDatabase.size())
 		return false;
 
 	const AIComment *commentData = &commentDatabase[lastFoundIndex];
@@ -2619,9 +2619,9 @@ Common::Array<AIComment> SceneViewWindow::getAICommentDatabase(int timeZone, int
 	if (!stream)
 		return comments;
 
-	stream->readUint16LE();
+	uint16 count = stream->readUint16LE();
 	
-	while (stream->pos() < stream->size()) {
+	for (uint16 i = 0; i < count; i++) {
 		AIComment comment;
 		comment.location.timeZone = stream->readSint16LE();
 		comment.location.environment = stream->readSint16LE();


Commit: 6ac35b1c34d95d8708381ff535dd3c81f6900758
    https://github.com/scummvm/scummvm/commit/6ac35b1c34d95d8708381ff535dd3c81f6900758
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement pauseEngineIntern()

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/video_window.cpp
    engines/buried/video_window.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index fadef031a4..edfea87717 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -57,6 +57,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_focusedWindow = 0;
 	_captureWindow = 0;
 	_console = 0;
+	_pauseStartTime = 0;
 
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2);
@@ -424,4 +425,25 @@ uint32 BuriedEngine::computeFileNameResourceID(int timeZone, int environment, in
 	return RESID_FILENAMES_BASE + RESOFFSET_FILENAME_TIMEZONE * timeZone + RESOFFSET_FILENAME_ENVIRON * environment + fileOffset;
 }
 
+void BuriedEngine::pauseEngineIntern(bool pause) {
+	if (pause) {
+		_sound->stop();
+
+		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+			(*it)->pauseVideo();
+
+		_pauseStartTime = g_system->getMillis();
+	} else {
+		_sound->restart();
+
+		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+			(*it)->resumeVideo();
+
+		uint32 timeDiff = g_system->getMillis() - _pauseStartTime;
+
+		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++)
+			it->_value.nextTrigger += timeDiff;
+	}
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index e9a848d8b4..a1fe36ab1d 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -72,6 +72,7 @@ public:
 
 	bool hasFeature(EngineFeature f) const;
 	GUI::Debugger *getDebugger();
+	void pauseEngineIntern(bool pause);
 
 	// Resources
 	Common::String getString(uint32 stringID);
@@ -146,6 +147,7 @@ private:
 	typedef Common::HashMap<uint, Timer> TimerMap;
 	TimerMap _timers;
 	uint _timerSeed;
+	uint32 _pauseStartTime;
 
 	typedef Common::List<VideoWindow *> VideoList;
 	VideoList _videos;
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 26cf88eed3..01b3d36650 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -202,4 +202,14 @@ void VideoWindow::setDestRect(const Common::Rect &dstRect) {
 	_dstRect = dstRect;
 }
 
+void VideoWindow::pauseVideo() {
+	if (_video)
+		_video->pauseVideo(true);
+}
+
+void VideoWindow::resumeVideo() {
+	if (_video)
+		_video->pauseVideo(false);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
index ce02628662..a22cbeb1d2 100644
--- a/engines/buried/video_window.h
+++ b/engines/buried/video_window.h
@@ -42,6 +42,8 @@ public:
 
 	// ScummVM-specific interface
 	void updateVideo();
+	void pauseVideo();
+	void resumeVideo();
 
 	// VFW interface
 	bool playVideo(); // MCIWndPlay


Commit: d8226496e05be0716001bd5f5868b0f382b4253d
    https://github.com/scummvm/scummvm/commit/d8226496e05be0716001bd5f5868b0f382b4253d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Prevent saving during a synchronous sequence

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/saveload.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index edfea87717..42f15d412f 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -58,6 +58,7 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_captureWindow = 0;
 	_console = 0;
 	_pauseStartTime = 0;
+	_yielding = false;
 
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2);
@@ -326,6 +327,10 @@ bool BuriedEngine::hasMessage(Window *window, int messageBegin, int messageEnd)
 void BuriedEngine::yield() {
 	// A cut down version of the Win16 yield function. Win32 handles this
 	// asynchronously, which we don't want. Only needed for internal event loops.
+
+	// Mark us that we're yielding so we can't save or load in a synchronous sequence
+	_yielding = true;
+
 	updateTimers();
 	updateVideos();
 
@@ -336,6 +341,8 @@ void BuriedEngine::yield() {
 
 	_gfx->updateScreen();
 	_system->delayMillis(10);
+
+	_yielding = false;
 }
 
 void BuriedEngine::pollForEvents() {
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index a1fe36ab1d..c8b82cff33 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -152,6 +152,8 @@ private:
 	typedef Common::List<VideoWindow *> VideoList;
 	VideoList _videos;
 
+	bool _yielding;
+
 	struct MessageInfo { // I did think about calling this "Envelope"
 		Window *dest;
 		Message *message;
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index 53d5f1f5c6..dc8d303728 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -47,14 +47,11 @@ Common::StringArray BuriedEngine::listSaveFiles() {
 }
 
 bool BuriedEngine::canLoadGameStateCurrently() {
-	// TODO: This probably needs to be more strict
-	return !isDemo() && _mainWindow;
+	return !isDemo() && _mainWindow && !_yielding;
 }
 
 bool BuriedEngine::canSaveGameStateCurrently() {
-	// TODO: This should be OK, except possibly synchronous video saving may give
-	// weird results. Need to investigate.
-	return !isDemo() && _mainWindow && ((FrameWindow *)_mainWindow)->isGameInProgress();
+	return !isDemo() && _mainWindow && !_yielding && ((FrameWindow *)_mainWindow)->isGameInProgress();
 }
 
 Common::Error BuriedEngine::loadGameState(int slot) {


Commit: d37f680e0fe47aeedcb20821baa9896e4cf90829
    https://github.com/scummvm/scummvm/commit/d37f680e0fe47aeedcb20821baa9896e4cf90829
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement picking up the preserved heart

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index ca8b96d2c6..88cb6a48a6 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -1008,6 +1008,157 @@ int CodexTowerGrabLens::droppedItem(Window *viewWindow, int itemID, const Common
 	return GenericItemAcquire::droppedItem(viewWindow, itemID, pointLocation, itemFlags);
 }
 
+class CodexCabinetOpenDoor : public SceneBase {
+public:
+	CodexCabinetOpenDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _openDoor;
+};
+
+CodexCabinetOpenDoor::CodexCabinetOpenDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+
+	_openDoor = Common::Rect(80, 0, 302, 189);
+}
+
+int CodexCabinetOpenDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_openDoor.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 1;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTakenHeart == 0)
+			destData.transitionData = 5;
+		else
+			destData.transitionData = 6;
+
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CodexCabinetOpenDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_openDoor.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+class CodexTowerGrabHeart : public SceneBase {
+public:
+	CodexTowerGrabHeart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	bool _itemPresent;
+	Common::Rect _acquireRegion;
+	int _fullFrameIndex;
+	int _clearFrameIndex;
+	int _itemID;
+	int _itemFlagOffset;
+	Common::Rect _eyeRegion;
+};
+
+CodexTowerGrabHeart::CodexTowerGrabHeart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_itemPresent = true;
+	_itemID = kItemPreservedHeart;
+	_acquireRegion = Common::Rect(214, 118, 270, 189);
+	_fullFrameIndex = _staticData.navFrameIndex;
+	_clearFrameIndex = 162;
+	_itemFlagOffset = offsetof(GlobalFlags, dsCTTakenHeart);
+	_eyeRegion = Common::Rect(248, 116, 286, 180);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTakenHeart != 0) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+	}
+}
+
+int CodexTowerGrabHeart::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.depth != newLocation.depth && _staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14));
+
+	return SC_TRUE;
+}
+
+int CodexTowerGrabHeart::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_acquireRegion.contains(pointLocation) && _itemPresent) {
+		_itemPresent = false;
+		_staticData.navFrameIndex = _clearFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
+
+		// Call inventory drag start function
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerGrabHeart::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_eyeRegion.contains(pointLocation) && !_itemPresent) {
+		// Play the spinning eyes animation
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerGrabHeart::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (itemID == _itemID && !_itemPresent) {
+		// Redraw the background
+		_itemPresent = true;
+		_staticData.navFrameIndex = _fullFrameIndex;
+
+		if (_itemFlagOffset >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
+
+		viewWindow->invalidateWindow();
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int CodexTowerGrabHeart::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_acquireRegion.contains(pointLocation) && _itemPresent)
+		return kCursorOpenHand;
+
+	if (_eyeRegion.contains(pointLocation) && !_itemPresent)
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class ClickBirdDevice : public SceneBase {
 public:
 	ClickBirdDevice(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2129,6 +2280,10 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new CodexTowerLensEvidenceCapture(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 43:
 		return new CodexTowerGrabLens(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 44:
+		return new CodexCabinetOpenDoor(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 45:
+		return new CodexTowerGrabHeart(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 46:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 8, kCursorFinger, 102, 124, 164, 189);
 	case 51:


Commit: c2cce6687d9fb37f1c8b8db720491732d0c23eda
    https://github.com/scummvm/scummvm/commit/c2cce6687d9fb37f1c8b8db720491732d0c23eda
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the codex tower elevator controls

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 88cb6a48a6..7dbc464481 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -1613,6 +1613,82 @@ int PaintingTowerCapAgent::postEnterRoom(Window *viewWindow, const Location &pri
 	return SC_TRUE;
 }
 
+class CodexTowerElevatorControls : public SceneBase {
+public:
+	CodexTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _transText[4];
+	Common::Rect _controls[2];
+	int _textTranslated;
+};
+
+CodexTowerElevatorControls::CodexTowerElevatorControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_transText[0] = Common::Rect(234, 52, 301, 72);
+	_transText[1] = Common::Rect(232, 147, 299, 167);
+	_transText[2] = Common::Rect(325, 51, 380, 71);
+	_transText[3] = Common::Rect(321, 147, 388, 168);
+	_controls[0] = Common::Rect(236, 38, 296, 264);
+	_controls[1] = Common::Rect(350, 70, 432, 140);
+	_textTranslated = -1;
+}
+
+int CodexTowerElevatorControls::gdiPaint(Window *viewWindow) {
+	if (_textTranslated >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_transText[_textTranslated]);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int CodexTowerElevatorControls::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		for (int i = 0; i < 4; i++) {
+			if (_transText[i].contains(pointLocation)) {
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsPTTransElevatorControls = 1;
+
+				Common::String text = _vm->getString(IDDS_ELEVATOR_CONTROLS_TEXT_A + i);
+				((SceneViewWindow *)viewWindow)->displayTranslationText(text);
+				_textTranslated = i;
+				viewWindow->invalidateWindow(false);
+				break;
+			}
+		}
+	} else {
+		if (_textTranslated >= 0) {
+			_textTranslated = -1;
+			viewWindow->invalidateWindow(false);
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerElevatorControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls[0].contains(pointLocation) || _controls[1].contains(pointLocation)) {
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTTriedElevatorControls = 1;
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CodexTowerElevatorControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls[0].contains(pointLocation) || _controls[1].contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class ClickChangeSceneTranslate : public SceneBase {
 public:
 	ClickChangeSceneTranslate(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -2326,6 +2402,8 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new AimBallistaToTower(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 70:
 		return new PaintingTowerCapAgent(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 71:
+		return new CodexTowerElevatorControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 72:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 13);
 	case 73:


Commit: f8e573c43c385ea80dc28405baee27720fd6cb05
    https://github.com/scummvm/scummvm/commit/f8e573c43c385ea80dc28405baee27720fd6cb05
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the codexes

Da Vinci's studio is completable!

Changed paths:
    engines/buried/environ/da_vinci.cpp


diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 7dbc464481..c5602b09d3 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -1159,6 +1159,321 @@ int CodexTowerGrabHeart::specifyCursor(Window *viewWindow, const Common::Point &
 	return kCursorArrow;
 }
 
+class ZoomInOnCodexes : public SceneBase {
+public:
+	ZoomInOnCodexes(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	
+private:
+	Common::Rect _leftCodex;
+	Common::Rect _middleCodex;
+	Common::Rect _rightCodex;
+};
+
+ZoomInOnCodexes::ZoomInOnCodexes(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_leftCodex = Common::Rect(82, 32, 212, 92);
+	_middleCodex = Common::Rect(218, 58, 284, 128);
+	_rightCodex = Common::Rect(285, 35, 345, 91);
+}
+
+int ZoomInOnCodexes::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// If we have not yet captured the codex evidence, display a message
+	if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX))
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYFoundCodexes = 1;
+	return SC_TRUE;
+}
+
+int ZoomInOnCodexes::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_leftCodex.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 1;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 17;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	} else if (_middleCodex.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 2;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 21;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	} else if (_rightCodex.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 3;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 19;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ZoomInOnCodexes::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && _middleCodex.contains(pointLocation) && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX)) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED));
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ZoomInOnCodexes::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_middleCodex.contains(pointLocation))
+			return -2;
+
+		return -1;
+	}
+
+	if (_leftCodex.contains(pointLocation) || _middleCodex.contains(pointLocation) || _rightCodex.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class BrowseCodex : public SceneBase {
+public:
+	BrowseCodex(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1,
+			int depth = -1, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1,
+			int startFrame = -1, int frameCount = -1, int lensStartFrame = -1);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int timerCallback(Window *viewWindow);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _curPage;
+	Common::Rect _top, _bottom, _left, _right, _putDown;
+	DestinationScene _putDownDestination;
+	int _startFrame;
+	int _frameCount;
+	int _lensStartFrame;
+	bool _translateAttempted;
+	bool _lensActivated;
+};
+
+BrowseCodex::BrowseCodex(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int timeZone, int environment, int node, int facing, int orientation,
+		int depth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength,
+		int startFrame, int frameCount, int lensStartFrame) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_curPage = 0;
+	_lensActivated = false;
+	_translateAttempted = false;
+	_startFrame = startFrame;
+	_frameCount = frameCount;
+	_lensStartFrame = lensStartFrame;
+	_putDownDestination.destinationScene = Location(timeZone, environment, node, facing, orientation, depth);
+	_putDownDestination.transitionType = transitionType;
+	_putDownDestination.transitionData = transitionData;
+	_putDownDestination.transitionStartFrame = transitionStartFrame;
+	_putDownDestination.transitionLength = transitionLength;
+
+	_staticData.navFrameIndex = startFrame;
+
+	_top = Common::Rect(150, 0, 282, 70);
+	_bottom = Common::Rect(150, 119, 282, 189);
+	_left = Common::Rect(0, 0, 150, 189);
+	_right = Common::Rect(282, 0, 432, 189);
+	_putDown = Common::Rect(150, 70, 282, 119);
+}
+
+int BrowseCodex::gdiPaint(Window *viewWindow) {
+	if (_translateAttempted) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(5, 5, 427, 184);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int BrowseCodex::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	int startingPage = _startFrame;
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1 && _lensStartFrame >= 0)
+		startingPage = _lensStartFrame;
+
+	if (_top.contains(pointLocation) && (_curPage % 2) != 0) {
+		_curPage--;
+		_staticData.navFrameIndex = startingPage + _curPage;
+
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 0, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
+		newBackground->free();
+		delete newBackground;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_bottom.contains(pointLocation) && (_curPage % 2) == 0) {
+		_curPage++;
+		_staticData.navFrameIndex = startingPage + _curPage;
+
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->pushNewTransition(newBackground, 3, _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed()), 0);
+		newBackground->free();
+		delete newBackground;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_left.contains(pointLocation) && _curPage >= 2) {
+		_curPage -= 2;
+		_staticData.navFrameIndex = startingPage + _curPage;
+
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->slideInTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
+		newBackground->free();
+		delete newBackground;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_right.contains(pointLocation) && _curPage < _frameCount - 2) {
+		_curPage += 2;
+		_staticData.navFrameIndex = startingPage + _curPage;
+
+		if (_staticData.location.timeZone == 5 && _staticData.location.environment == 2 &&
+				_staticData.location.node == 5 && _staticData.location.facing == 2 &&
+				_staticData.location.orientation == 5 && _staticData.location.depth == 2 &&
+				_curPage == 2) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTCodexAtlanticusPage2 = 1;
+		} else {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTCodexAtlanticusPage2 = 0;
+		}
+
+		Graphics::Surface *newBackground = ((SceneViewWindow *)viewWindow)->getStillFrameCopy(_staticData.navFrameIndex);
+		((SceneViewWindow *)viewWindow)->slideOutTransition(newBackground, 1, _vm->_gfx->computeHPushOffset(_vm->getTransitionSpeed()), 0);
+		newBackground->free();
+		delete newBackground;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	} else if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0) {
+		((SceneViewWindow *)viewWindow)->moveToDestination(_putDownDestination);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int BrowseCodex::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	Common::Rect transRegion(25, 25, 382, 139);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYTranslatedCodex = 1;
+
+		if (transRegion.contains(pointLocation)) {
+			if (!_translateAttempted) {
+				_translateAttempted = true;
+				viewWindow->invalidateWindow(false);
+				((SceneViewWindow *)viewWindow)->displayTranslationText("");
+			}
+		} else {
+			if (_translateAttempted) {
+				_translateAttempted = false;
+				viewWindow->invalidateWindow(false);
+				((SceneViewWindow *)viewWindow)->displayTranslationText("");
+			}
+		}
+	} else {
+		if (_translateAttempted) {
+			_translateAttempted = false;
+			viewWindow->invalidateWindow(false);
+			((SceneViewWindow *)viewWindow)->displayTranslationText("");
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int BrowseCodex::timerCallback(Window *viewWindow) {
+	if (_translateAttempted && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 0) {
+		_translateAttempted = false;
+		viewWindow->invalidateWindow(false);
+	}
+
+	// Are we looking at the proper codex?
+	if (_lensStartFrame >= 0) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1) {
+			if (!_lensActivated) {
+				_lensActivated = true;
+				_staticData.navFrameIndex = _lensStartFrame;
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTCodexFormulaeFound = 1;
+				_curPage = 0;
+				viewWindow->invalidateWindow(false);
+
+				// Play the capture animation
+				((SceneViewWindow *)viewWindow)->playSynchronousAnimation(24);
+
+				// Attempt to add it to your evidence biochip
+				if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, DAVINCI_EVIDENCE_CODEX))
+					((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
+				else
+					((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+				// Set the scoring flag
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreLoggedCodexEvidence = 1;
+			}
+		} else {
+			if (_lensActivated) {
+				_lensActivated = false;
+				_staticData.navFrameIndex = _startFrame + _curPage;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int BrowseCodex::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_lensStartFrame >= 0 && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX)) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED));
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int BrowseCodex::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_lensStartFrame >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), DAVINCI_EVIDENCE_CODEX))
+		return -2;
+
+	if (_top.contains(pointLocation) && (_curPage % 2) != 0)
+		return kCursorMoveUp;
+
+	if (_left.contains(pointLocation) && _curPage >= 2)
+		return kCursorPrevPage;
+
+	if (_right.contains(pointLocation) && _curPage < _frameCount - 2)
+		return kCursorNextPage;
+
+	if (_bottom.contains(pointLocation) && (_curPage % 2) == 0)
+		return kCursorMoveDown;
+
+	if (_putDown.contains(pointLocation) && _putDownDestination.destinationScene.timeZone >= 0)
+		return kCursorPutDown;
+
+	return kCursorArrow;
+}
+
 class ClickBirdDevice : public SceneBase {
 public:
 	ClickBirdDevice(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2362,6 +2677,14 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new CodexTowerGrabHeart(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 46:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 8, kCursorFinger, 102, 124, 164, 189);
+	case 47:
+		return new ZoomInOnCodexes(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 48:
+		return new BrowseCodex(_vm, viewWindow, sceneStaticData, priorLocation, 5, 2, 3, 1, 0, 0, TRANSITION_VIDEO, 18, -1, -1, 181, 8, -1);
+	case 49:
+		return new BrowseCodex(_vm, viewWindow, sceneStaticData, priorLocation, 5, 2, 3, 1, 0, 0, TRANSITION_VIDEO, 22, -1, -1, 189, 10, 199);
+	case 50:
+		return new BrowseCodex(_vm, viewWindow, sceneStaticData, priorLocation, 5, 2, 3, 1, 0, 0, TRANSITION_VIDEO, 20, -1, -1, 173, 8, -1);
 	case 51:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 36, 240, 189, kCursorMagnifyingGlass, 5, 2, 4, 0, 0, 1, TRANSITION_VIDEO, 11, -1, -1);
 	case 52:


Commit: 0a3b06d996f066328941d31f48581a7b2562948d
    https://github.com/scummvm/scummvm/commit/0a3b06d996f066328941d31f48581a7b2562948d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Make sure syncSoundSettings() is called from run()

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 42f15d412f..acee45d480 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -112,6 +112,8 @@ Common::Error BuriedEngine::run() {
 	if (_library && !_library->load(getLibraryName()))
 		error("Failed to load library DLL '%s'", getLibraryName().c_str());
 
+	syncSoundSettings();
+
 	_gfx = new GraphicsManager(this);
 	_sound = new SoundManager(this);
 	_mainWindow = new FrameWindow(this);


Commit: 384d8f2c956ba8b11c1557ecf4c674186891202d
    https://github.com/scummvm/scummvm/commit/384d8f2c956ba8b11c1557ecf4c674186891202d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Add some commands to add/remove inventory items

Changed paths:
    engines/buried/buried.cpp
    engines/buried/console.cpp
    engines/buried/console.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index acee45d480..b0e692425e 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -366,8 +366,14 @@ void BuriedEngine::pollForEvents() {
 				_focusedWindow->postMessage(new KeyUpMessage(event.kbd, 0));
 			break;
 		case Common::EVENT_KEYDOWN:
-			if (_focusedWindow)
-				_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
+			if (event.kbd.keycode == Common::KEYCODE_d && (event.kbd.flags & Common::KBD_CTRL)) {
+				// Gobble up ctrl+d for the console
+				_console->attach();
+				_console->onFrame();
+			} else {
+				if (_focusedWindow)
+					_focusedWindow->postMessage(new KeyDownMessage(event.kbd, 0));
+			}
 			break;
 		case Common::EVENT_LBUTTONDOWN: {
 			Window *window = _captureWindow ? _captureWindow : _mainWindow->childWindowAtPoint(event.mouse);
diff --git a/engines/buried/console.cpp b/engines/buried/console.cpp
index d911754df2..74acd0f12e 100644
--- a/engines/buried/console.cpp
+++ b/engines/buried/console.cpp
@@ -22,13 +22,90 @@
 
 #include "buried/buried.h"
 #include "buried/console.h"
+#include "buried/frame_window.h"
+#include "buried/gameui.h"
+#include "buried/inventory_window.h"
 
 namespace Buried {
 
 BuriedConsole::BuriedConsole(BuriedEngine *vm) : _vm(vm) {
+	registerCmd("giveitem", WRAP_METHOD(BuriedConsole, cmdGiveItem));
+	registerCmd("removeitem", WRAP_METHOD(BuriedConsole, cmdRemoveItem));
 }
 
 BuriedConsole::~BuriedConsole() {
 }
 
+bool BuriedConsole::cmdGiveItem(int argc, const char **argv) {
+	if (argc < 2) {
+		debugPrintf("Usage: %s <item ID>\n", argv[0]);
+		return true;
+	}
+
+	int itemID = atoi(argv[1]);
+
+	if (itemID < 0 || itemID > kItemWoodenPegs) {
+		debugPrintf("Invalid item ID %d!\n", itemID);
+		return true;
+	}
+
+	FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
+
+	if (!frameWindow) {
+		debugPrintf("Main window not yet created!\n");
+		return true;
+	}
+
+	if (!frameWindow->isGameInProgress()) {
+		debugPrintf("The game is currently not in progress!\n");
+		return true;
+	}
+
+	InventoryWindow *inventory = ((GameUIWindow *)frameWindow->getMainChildWindow())->_inventoryWindow;
+	if (inventory->isItemInInventory(itemID)) {
+		debugPrintf("Item %d is already in the inventory\n", itemID);
+		return true;
+	}
+
+	inventory->addItem(itemID);
+	debugPrintf("Added item %d to the inventory\n", itemID);
+	return true;
+}
+
+bool BuriedConsole::cmdRemoveItem(int argc, const char **argv) {
+	if (argc < 2) {
+		debugPrintf("Usage: %s <item ID>\n", argv[0]);
+		return true;
+	}
+
+	int itemID = atoi(argv[1]);
+
+	if (itemID < 0 || itemID > kItemWoodenPegs) {
+		debugPrintf("Invalid item ID %d!\n", itemID);
+		return true;
+	}
+
+	FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
+
+	if (!frameWindow) {
+		debugPrintf("Main window not yet created!\n");
+		return true;
+	}
+
+	if (!frameWindow->isGameInProgress()) {
+		debugPrintf("The game is currently not in progress!\n");
+		return true;
+	}
+
+	InventoryWindow *inventory = ((GameUIWindow *)frameWindow->getMainChildWindow())->_inventoryWindow;
+	if (!inventory->isItemInInventory(itemID)) {
+		debugPrintf("Item %d is not in the inventory\n", itemID);
+		return true;
+	}
+
+	inventory->removeItem(itemID);
+	debugPrintf("Removed item %d to the inventory\n", itemID);
+	return true;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/console.h b/engines/buried/console.h
index 1e8a728eeb..3811b58bd0 100644
--- a/engines/buried/console.h
+++ b/engines/buried/console.h
@@ -34,6 +34,9 @@ public:
 	BuriedConsole(BuriedEngine *vm);
 	~BuriedConsole();
 
+	bool cmdGiveItem(int argc, const char **argv);
+	bool cmdRemoveItem(int argc, const char **argv);
+
 private:
 	BuriedEngine *_vm;
 };


Commit: 661738d36fa43b0f7b3d005a2fb9bdd24519cc49
    https://github.com/scummvm/scummvm/commit/661738d36fa43b0f7b3d005a2fb9bdd24519cc49
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the oven door

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 44fdaf920e..1beb8652d4 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -37,6 +37,84 @@
 
 namespace Buried {
 
+class OvenDoor : public SceneBase {
+public:
+	OvenDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int openAnimID = 0, int closeAnimID = 0, int openFrame = 0, int closedFrame = 0, int flagOffset = 0,
+			int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _openAnimationID;
+	int _closeAnimationID;
+	int _openFrame;
+	int _closedFrame;
+	int _flagOffset;
+	Common::Rect _clickableRegion;
+};
+
+OvenDoor::OvenDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int openAnimID, int closeAnimID, int openFrame, int closedFrame, int flagOffset,
+		int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_openAnimationID = openAnimID;
+	_closeAnimationID = closeAnimID;
+	_openFrame = openFrame;
+	_closedFrame = closedFrame;
+	_flagOffset = flagOffset;
+	_clickableRegion = Common::Rect(left, top, right, bottom);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 1)
+		_staticData.navFrameIndex = _openFrame;
+	else
+		_staticData.navFrameIndex = _closedFrame;
+}
+
+int OvenDoor::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if ((newLocation.orientation == 0 || newLocation.facing != _staticData.location.facing || newLocation.node != _staticData.location.node) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 1) {
+		if (_staticData.location.timeZone == newLocation.timeZone)
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7));
+
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 0);
+	}
+
+	return SC_TRUE;
+}
+
+int OvenDoor::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableRegion.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_flagOffset) == 1) {
+			// Change the flag status
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 0);
+
+			// Play the specified animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_closeAnimationID);
+			_staticData.navFrameIndex = _closedFrame;
+
+			return SC_TRUE;
+		} else {
+			// Change the flag status
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+
+			// Play the specified animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_openAnimationID);
+			_staticData.navFrameIndex = _openFrame;
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int OvenDoor::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class KitchenUnitTurnOn : public SceneBase {
 public:
 	KitchenUnitTurnOn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -990,6 +1068,10 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 3:
+		return new OvenDoor(_vm, viewWindow, sceneStaticData, priorLocation, 2, 3, 37, 25, offsetof(GlobalFlags, faKIOvenStatus), 0, 0, 270, 80);
+	case 4:
+		return new OvenDoor(_vm, viewWindow, sceneStaticData, priorLocation, 4, 5, 38, 26, offsetof(GlobalFlags, faKIOvenStatus), 0, 50, 300, 189);
 	case 5:
 		return new KitchenUnitTurnOn(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 6:


Commit: 0478b7778a4113f6c1bab7c5649fe4c17b6b5758
    https://github.com/scummvm/scummvm/commit/0478b7778a4113f6c1bab7c5649fe4c17b6b5758
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement some custom videos with AI comments

Changed paths:
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 1beb8652d4..9adba9c902 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1068,6 +1068,10 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 1:
+		return new ClickPlayVideoSwitchAI(_vm, viewWindow, sceneStaticData, priorLocation, 0, kCursorFinger, offsetof(GlobalFlags, faKICoffeeSpilled), 212, 114, 246, 160);
+	case 2:
+		return new ClickPlayVideoSwitchAI(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorFinger, offsetof(GlobalFlags, faKIBirdsBobbed), 150, 40, 260, 164);
 	case 3:
 		return new OvenDoor(_vm, viewWindow, sceneStaticData, priorLocation, 2, 3, 37, 25, offsetof(GlobalFlags, faKIOvenStatus), 0, 0, 270, 80);
 	case 4:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 252f8121ba..bcf0477559 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -256,6 +256,41 @@ int ClickChangeScene::specifyCursor(Window *viewWindow, const Common::Point &poi
 	return kCursorArrow;
 }
 
+
+ClickPlayVideoSwitchAI::ClickPlayVideoSwitchAI(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int animID, int cursorID, int flagOffset, int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cursorID = cursorID;
+	_animID = animID;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_flagOffset = flagOffset;
+}
+
+int ClickPlayVideoSwitchAI::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		// Play the animation clip
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animID);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, 1);
+
+		// Play any spontaneous AI comments
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI)) {
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickPlayVideoSwitchAI::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 ClickChangeSceneSetFlag::ClickChangeSceneSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int left, int top, int right, int bottom, int cursorID,
 		int timeZone, int environment, int node, int facing, int orientation, int depth,
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 7a5087a620..1f7a3dc8d9 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -117,6 +117,20 @@ private:
 	DestinationScene _clickDestination;
 };
 
+class ClickPlayVideoSwitchAI : public SceneBase {
+public:
+	ClickPlayVideoSwitchAI(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int animID = 0, int cursorID = 0, int flagOffset = 0, int left = 0, int top = 0, int right = 0, int bottom = 0);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	int _animID;
+	Common::Rect _clickRegion;
+	int _flagOffset;
+};
+
 class ClickChangeSceneSetFlag : public ClickChangeScene {
 public:
 	ClickChangeSceneSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: f3e92d1333749614f83e50946e8c0a80a9304308
    https://github.com/scummvm/scummvm/commit/f3e92d1333749614f83e50946e8c0a80a9304308
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement changing the background based on whether the remote is there

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 9adba9c902..694122c0c3 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -840,6 +840,19 @@ void KitchenUnitPostBox::changeBackgroundBitmap() {
 	}
 }
 
+class FlagChangeBackground : public SceneBase {
+public:
+	FlagChangeBackground(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int flagOffset = -1, byte minFlagValue = 1, int newStillFrame = 0);
+};
+
+FlagChangeBackground::FlagChangeBackground(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int flagOffset, byte minFlagValue, int newStillFrame) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (flagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(flagOffset) >= minFlagValue)
+		_staticData.navFrameIndex = newStillFrame;
+}
+
 class ClickZoomToyShelf : public SceneBase {
 public:
 	ClickZoomToyShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1102,6 +1115,12 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 4, -1, -1);
 	case 23:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 81, 146, 134, 189, kItemRemoteControl, 45, offsetof(GlobalFlags, faERTakenRemoteControl));
+	case 24:
+		return new FlagChangeBackground(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, faERTakenRemoteControl), 1, 33);
+	case 25:
+		return new FlagChangeBackground(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, faERTakenRemoteControl), 1, 21);
+	case 26:
+		return new FlagChangeBackground(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, faERTakenRemoteControl), 1, 9);
 	case 30:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14);
 	case 32:


Commit: 358c706fce3a89539295564c7b14c465d0711adb
    https://github.com/scummvm/scummvm/commit/358c706fce3a89539295564c7b14c465d0711adb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the apartment bookshelf

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 694122c0c3..527d4142fd 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -853,6 +854,57 @@ FlagChangeBackground::FlagChangeBackground(BuriedEngine *vm, Window *viewWindow,
 		_staticData.navFrameIndex = newStillFrame;
 }
 
+class ClickZoomInTopOfBookshelf : public SceneBase {
+public:
+	ClickZoomInTopOfBookshelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _awardZoom, _bookZoom;
+};
+
+ClickZoomInTopOfBookshelf::ClickZoomInTopOfBookshelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_awardZoom = Common::Rect(66, 20, 168, 64);
+	_bookZoom = Common::Rect(206, 0, 370, 84);
+}
+
+int ClickZoomInTopOfBookshelf::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_awardZoom.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 9;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	if (_bookZoom.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 2;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 11;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickZoomInTopOfBookshelf::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_awardZoom.contains(pointLocation) || _bookZoom.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 class ClickZoomToyShelf : public SceneBase {
 public:
 	ClickZoomToyShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -958,6 +1010,117 @@ int ToyClick::specifyCursor(Window *viewWindow, const Common::Point &pointLocati
 	return kCursorPutDown;
 }
 
+class ClickZoomInBottomOfBookshelf : public SceneBase {
+public:
+	ClickZoomInBottomOfBookshelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _leftClocks;
+	Common::Rect _rightClocks;
+};
+
+ClickZoomInBottomOfBookshelf::ClickZoomInBottomOfBookshelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_leftClocks = Common::Rect(72, 32, 186, 110);
+	_rightClocks = Common::Rect(194, 10, 370, 100);
+}
+
+int ClickZoomInBottomOfBookshelf::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_leftClocks.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 7;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	if (_rightClocks.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 2;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 3;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ClickZoomInBottomOfBookshelf::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_leftClocks.contains(pointLocation) || _rightClocks.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class RightClockShelf : public SceneBase {
+public:
+	RightClockShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _alienClock;
+	Common::Rect _alarmClock;
+	Common::Rect _pendulum;
+};
+
+RightClockShelf::RightClockShelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_alienClock = Common::Rect(0, 152, 80, 189);
+	_alarmClock = Common::Rect(82, 102, 148, 189);
+	_pendulum = Common::Rect(274, 0, 384, 189);
+}
+
+int RightClockShelf::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_alienClock.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
+		return SC_TRUE;
+	}
+
+	if (_alarmClock.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faMNClockClicked = 1;
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	if (_pendulum.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(5);
+		return SC_TRUE;
+	}
+
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 0;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 6;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int RightClockShelf::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_alienClock.contains(pointLocation) || _alarmClock.contains(pointLocation) || _pendulum.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class MainEnvironDoorDown : public SceneBase {
 public:
 	MainEnvironDoorDown(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1055,6 +1218,70 @@ int MainEnvironDoorExit::postEnterRoom(Window *viewWindow, const Location &prior
 	return SC_FALSE;
 }
 
+class ClickOnBooks : public SceneBase {
+public:
+	ClickOnBooks(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0,
+			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1,
+			int soundFileNameID = -1, int soundLeft = -1, int soundTop = -1, int soundRight = -1, int soundBottom = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	Common::Rect _clickRegion;
+	DestinationScene _clickDestination;
+	int _soundFileNameID;
+	Common::Rect _soundRegion;
+};
+
+ClickOnBooks::ClickOnBooks(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int cursorID,
+		int timeZone, int environment, int node, int facing, int orientation, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength,
+		int soundFileNameID, int soundLeft, int soundTop, int soundRight, int soundBottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_cursorID = cursorID;
+	_clickDestination.destinationScene = Location(timeZone, environment, node, facing, orientation, depth);
+	_clickDestination.transitionType = transitionType;
+	_clickDestination.transitionData = transitionData;
+	_clickDestination.transitionStartFrame = transitionStartFrame;
+	_clickDestination.transitionLength = transitionLength;
+	_soundFileNameID = soundFileNameID;
+	_soundRegion = Common::Rect(soundLeft, soundTop, soundRight, soundBottom);
+}
+
+int ClickOnBooks::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_soundRegion.contains(pointLocation)) {
+		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_soundFileNameID), 128);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faMNBooksClicked = 1;
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		return SC_TRUE;
+	}
+
+	if (_clickRegion.contains(pointLocation))
+		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
+
+	return SC_FALSE;
+}
+
+int ClickOnBooks::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_soundRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 class EnvironDoorExitSound : public SceneBase {
 public:
 	EnvironDoorExitSound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1123,10 +1350,18 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new FlagChangeBackground(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, faERTakenRemoteControl), 1, 9);
 	case 30:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, faStingerID), offsetof(GlobalFlags, faStingerChannelID), 10, 14);
+	case 31:
+		return new ClickZoomInTopOfBookshelf(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 32:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 9, 0, 1, 0, TRANSITION_VIDEO, 10, -1, -1);
+	case 33:
+		return new ClickOnBooks(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 9, 0, 1, 0, TRANSITION_VIDEO, 12, -1, -1, IDS_FUTAPT_BOOK_AUDIO_FILENAME, 182, 8, 396, 156);
+	case 34:
+		return new ClickZoomInBottomOfBookshelf(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 35:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 9, 0, 0, 0, TRANSITION_VIDEO, 8, -1, -1);
+	case 36:
+		return new RightClockShelf(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 37:
 		return new ClickZoomToyShelf(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 38:


Commit: 80567b391f7f28bfe21c2de476c5bb03d7b7058c
    https://github.com/scummvm/scummvm/commit/80567b391f7f28bfe21c2de476c5bb03d7b7058c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Don't clear the video rect when closing a video

Changed paths:
    engines/buried/video_window.cpp


diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 01b3d36650..de8ce79790 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -128,9 +128,6 @@ void VideoWindow::closeVideo() {
 		_video = 0;
 		_mode = kModeClosed;
 		_lastFrame = 0;
-		_rect = Common::Rect();
-		_srcRect = Common::Rect();
-		_dstRect = Common::Rect();
 
 		if (_ownedFrame) {
 			_ownedFrame->free();


Commit: 8bbfe49d8eeac3b71032e76898962bfb056ef7e5
    https://github.com/scummvm/scummvm/commit/8bbfe49d8eeac3b71032e76898962bfb056ef7e5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the apartment desk

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 527d4142fd..9ebf86fe65 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1121,6 +1121,220 @@ int RightClockShelf::specifyCursor(Window *viewWindow, const Common::Point &poin
 	return kCursorPutDown;
 }
 
+class MainDeskView : public SceneBase {
+public:
+	MainDeskView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _papers;
+	Common::Rect _terminal;
+	Common::Rect _vidPhone;
+	Common::Rect _deskLight;
+};
+
+MainDeskView::MainDeskView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_papers = Common::Rect(38, 126, 132, 154);
+	_terminal = Common::Rect(138, 118, 274, 166);
+	_vidPhone = Common::Rect(334, 46, 418, 142);
+	_deskLight = Common::Rect(20, 62, 82, 122);
+}
+
+int MainDeskView::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_papers.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 2;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 40;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	if (_terminal.contains(pointLocation)) {
+		// Play the terminal access movie
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(44);
+		return SC_TRUE;
+	}
+
+	if (_vidPhone.contains(pointLocation)) {
+		// Move to the vidphone
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 3;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 42;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	if (_deskLight.contains(pointLocation)) {
+		// Play the desk light animation
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(39);
+		return SC_TRUE;
+	}
+
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 0;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 45;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int MainDeskView::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_papers.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0)
+		return kCursorMagnifyingGlass;
+
+	if (_terminal.contains(pointLocation) || _deskLight.contains(pointLocation))
+		return kCursorFinger;
+
+	if (_vidPhone.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorPutDown;
+}
+
+class ViewVidPhone : public SceneBase {
+public:
+	ViewVidPhone(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status);
+
+private:
+	Common::Rect _playButton;
+	Common::Rect _pauseButton;
+	Common::Rect _prevButton;
+	bool _playingMovie;
+	int _curMovie;
+};
+
+ViewVidPhone::ViewVidPhone(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_playButton = Common::Rect(102, 22, 120, 40);
+	_pauseButton = Common::Rect(98, 49, 112, 63);
+	_prevButton = Common::Rect(91, 81, 105, 95);
+	_playingMovie = false;
+	_curMovie = -1;
+}
+
+int ViewVidPhone::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Play messages sound effect here
+	_vm->_sound->playSoundEffect("BITDATA/FUTAPT/FAMN_ANS.BTA");
+	return SC_TRUE;
+}
+
+int ViewVidPhone::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_playingMovie) {
+		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+		_playingMovie = false;
+		_vm->_sound->restart();
+	}
+
+	return SC_TRUE;
+}
+
+int ViewVidPhone::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_playButton.contains(pointLocation)) {
+		if (_curMovie == 0) {
+			((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+			_vm->_sound->restart();
+			_curMovie = -1;
+		} else {
+			if (_playingMovie)
+				((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+
+			_curMovie = 0;
+			_vm->_sound->stop();
+			((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(33, false);
+			_playingMovie = true;
+		}
+
+		return SC_TRUE;
+	}
+
+	if (_pauseButton.contains(pointLocation)) {
+		if (_curMovie == 1) {
+			((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+			_vm->_sound->restart();
+			_curMovie = -1;
+		} else {
+			if (_playingMovie)
+				((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+
+			_curMovie = 1;
+			_vm->_sound->stop();
+			((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(34, false);
+			_playingMovie = true;
+		}
+
+		return SC_TRUE;
+	}
+
+	if (_prevButton.contains(pointLocation)) {
+		if (_curMovie == 2) {
+			((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+			_vm->_sound->restart();
+			_curMovie = -1;
+		} else {
+			if (_playingMovie)
+				((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+
+			_curMovie = 2;
+			_vm->_sound->stop();
+			((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(35, false);
+			_playingMovie = true;
+		}
+
+		return SC_TRUE;
+	}
+
+	if (_playingMovie)
+		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+
+	_playingMovie = false;
+	_vm->_sound->restart();
+
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 1;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 43;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int ViewVidPhone::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_playButton.contains(pointLocation) || _pauseButton.contains(pointLocation) || _prevButton.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
+int ViewVidPhone::movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) {
+	if (animationID == -1 && status == MOVIE_STOPPED) {
+		_vm->_sound->restart();
+		_playingMovie = false;
+		_curMovie = -1;
+	}
+
+	return SC_TRUE;
+}
+
 class MainEnvironDoorDown : public SceneBase {
 public:
 	MainEnvironDoorDown(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1380,8 +1594,12 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 44, 26, 254, 144, kCursorMagnifyingGlass, 4, 3, 0, 2, 0, 1, TRANSITION_VIDEO, 30, -1, -1);
 	case 50:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 82, 38, 346, 138, kCursorMagnifyingGlass, 4, 3, 9, 2, 0, 1, TRANSITION_VIDEO, 38, -1, -1);
+	case 51:
+		return new MainDeskView(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 52:
 		return new BrowseBook(_vm, viewWindow, sceneStaticData, priorLocation, IDBD_LETTERS_BOOK_DATA, -1, 0, 4, 3, 9, 2, 0, 1, TRANSITION_VIDEO, 41, -1, -1);
+	case 53:
+		return new ViewVidPhone(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 54:
 		return new ClickPlayVideo(_vm, viewWindow, sceneStaticData, priorLocation, 36, kCursorFinger, 0, 0, 432, 189);
 	case 56:


Commit: ae5de7b230edb8076f263c66e5167e73c0c4870c
    https://github.com/scummvm/scummvm/commit/ae5de7b230edb8076f263c66e5167e73c0c4870c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the coffee table area scenes

Changed paths:
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 9ebf86fe65..2fe8f3ee09 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1010,6 +1010,58 @@ int ToyClick::specifyCursor(Window *viewWindow, const Common::Point &pointLocati
 	return kCursorPutDown;
 }
 
+class ClickOnCoffeeTable : public SceneBase {
+public:
+	ClickOnCoffeeTable(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _toyClickRect;
+	Common::Rect _tazClickRect;
+};
+
+ClickOnCoffeeTable::ClickOnCoffeeTable(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_toyClickRect = Common::Rect(242, 56, 358, 138);
+	_tazClickRect = Common::Rect(174, 0, 234, 56);
+}
+
+int ClickOnCoffeeTable::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_toyClickRect.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(31);
+		return SC_TRUE;
+	}
+
+	if (_tazClickRect.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(26);
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faMNTazClicked = 1;
+
+		if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+			((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 0;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 32;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int ClickOnCoffeeTable::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_toyClickRect.contains(pointLocation) || _tazClickRect.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class ClickZoomInBottomOfBookshelf : public SceneBase {
 public:
 	ClickZoomInBottomOfBookshelf(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1590,8 +1642,14 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 168, 38, 268, 108, kCursorMagnifyingGlass, 4, 3, 5, 0, 0, 1, TRANSITION_VIDEO, 28, -1, -1);
 	case 43:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 3, 5, 0, 0, 0, TRANSITION_VIDEO, 29, -1, -1);
+	case 44:
+		return new ClickPlayLoopingVideoClip(_vm, viewWindow, sceneStaticData, priorLocation, kCursorFinger, 25, 120, 0, 299, 132, offsetof(GlobalFlags, faMNPongClicked), 1);
+	case 45:
+		return new ClickPlayLoopingVideoClip(_vm, viewWindow, sceneStaticData, priorLocation, kCursorFinger, 27, 0, 0, 432, 189);
 	case 46:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 44, 26, 254, 144, kCursorMagnifyingGlass, 4, 3, 0, 2, 0, 1, TRANSITION_VIDEO, 30, -1, -1);
+	case 47:
+		return new ClickOnCoffeeTable(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 50:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 82, 38, 346, 138, kCursorMagnifyingGlass, 4, 3, 9, 2, 0, 1, TRANSITION_VIDEO, 38, -1, -1);
 	case 51:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index bcf0477559..f174814e8f 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -468,6 +468,66 @@ int DisplayMessageWithEvidenceWhenEnteringNode::postEnterRoom(Window *viewWindow
 	return SC_TRUE;
 }
 
+ClickPlayLoopingVideoClip::ClickPlayLoopingVideoClip(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int cursorID, int animID, int left, int top, int right, int bottom, int flagOffset, int newFlagValue) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_cursorID = cursorID;
+	_animID = animID;
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_flagOffset = flagOffset;
+	_flagValue = newFlagValue;
+	_playing = false;
+}
+
+int ClickPlayLoopingVideoClip::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_playing) {
+		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+		_vm->_sound->restart();
+		_playing = false;
+
+		if (_flagOffset >= 0 && _flagValue >= 0)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, _flagValue);
+	}
+
+	return SC_TRUE;
+}
+
+int ClickPlayLoopingVideoClip::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		if (_playing) {
+			// Stop the clip
+			((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+			_playing = false;
+			_vm->_sound->restart();
+
+			// Change the flag
+			if (_flagOffset >= 0 && _flagValue >= 0)
+				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagOffset, _flagValue);
+
+			// Check for spontaneous AI comments
+			if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				((SceneViewWindow *)viewWindow)->playAIComment(_staticData.location, AI_COMMENT_TYPE_SPONTANEOUS);
+
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+			return SC_TRUE;
+		} else {
+			// Start playing asynchronously
+			_vm->_sound->stop();
+			_playing = ((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(_animID, true);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ClickPlayLoopingVideoClip::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return _cursorID;
+
+	return kCursorArrow;
+}
+
 OneShotEntryVideoWarning::OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 		int animID, int flagOffset, int warningMessageID) : SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
 	_animID = animID;
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index 1f7a3dc8d9..a012ce9ae1 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -214,6 +214,23 @@ private:
 	byte _evidenceID;
 };
 
+class ClickPlayLoopingVideoClip : public SceneBase {
+public:
+	ClickPlayLoopingVideoClip(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int cursorID = 0, int animID = -1, int left = 0, int top = 0, int right = 0, int bottom = 0, int flagOffset = -1, int newFlagValue = -1);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _cursorID;
+	int _animID;
+	Common::Rect _clickRegion;
+	int _flagOffset;
+	int _flagValue;
+	bool _playing;
+};
+
 class OneShotEntryVideoWarning : public SceneBase {
 public:
 	OneShotEntryVideoWarning(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: 13a5d366321c1f4ba24f6a3418948a40020bb876
    https://github.com/scummvm/scummvm/commit/13a5d366321c1f4ba24f6a3418948a40020bb876
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the cavern door views

Changed paths:
    engines/buried/environ/mayan.cpp
    engines/buried/global_flags.h
    engines/buried/saveload.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 18d0c269f7..c6e0ba4fd1 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -477,6 +477,87 @@ int ViewSingleTranslation::specifyCursor(Window *viewWindow, const Common::Point
 	return kCursorArrow;
 }
 
+class GenericCavernDoorMainView : public SceneBase {
+public:
+	GenericCavernDoorMainView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int topZoomDepth = 0, int topLeft = -1, int topTop = -1, int topRight = -1, int topBottom = -1,
+			int rightZoomDepth = 0, int rightLeft = -1, int rightTop = -1, int rightRight = -1, int rightBottom = -1,
+			int offeringHeadZoomDepth = 0, int offeringHeadLeft = -1, int offeringHeadTop = -1, int offeringHeadRight = -1, int offeringHeadBottom = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _topZoomDepth;
+	int _rightZoomDepth;
+	int _offeringHeadZoomDepth;
+	Common::Rect _topZoomRegion;
+	Common::Rect _rightZoomRegion;
+	Common::Rect _offeringHeadZoomRegion;
+};
+
+GenericCavernDoorMainView::GenericCavernDoorMainView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int topZoomDepth, int topLeft, int topTop, int topRight, int topBottom,
+		int rightZoomDepth, int rightLeft, int rightTop, int rightRight, int rightBottom,
+		int offeringHeadZoomDepth, int offeringHeadLeft, int offeringHeadTop, int offeringHeadRight, int offeringHeadBottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_topZoomDepth = topZoomDepth;
+	_rightZoomDepth = rightZoomDepth;
+	_offeringHeadZoomDepth = offeringHeadZoomDepth;
+	_topZoomRegion = Common::Rect(topLeft, topTop, topRight, topBottom);
+	_rightZoomRegion = Common::Rect(rightLeft, rightTop, rightRight, rightBottom);
+	_offeringHeadZoomRegion = Common::Rect(offeringHeadLeft, offeringHeadTop, offeringHeadRight, offeringHeadBottom);
+
+	if (_staticData.location.node == 7)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCViewedDeathGodDoor = 1;
+}
+
+int GenericCavernDoorMainView::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_staticData.location.node == 7 && (_staticData.location.timeZone != priorLocation.timeZone ||
+			_staticData.location.environment != priorLocation.environment || _staticData.location.node != priorLocation.node ||
+			_staticData.location.facing != priorLocation.facing || _staticData.location.orientation != priorLocation.orientation ||
+			_staticData.location.depth != priorLocation.depth) && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID))
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+	return SC_TRUE;
+}
+
+int GenericCavernDoorMainView::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// Build a default structure
+	DestinationScene newDestination;
+	newDestination.destinationScene = _staticData.location;
+	newDestination.transitionType = TRANSITION_FADE;
+	newDestination.transitionData = -1;
+	newDestination.transitionStartFrame = -1;
+	newDestination.transitionLength = -1;
+
+	if (_topZoomRegion.contains(pointLocation)) {
+		newDestination.destinationScene.depth = _topZoomDepth;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
+		return SC_TRUE;
+	}
+
+	if (_rightZoomRegion.contains(pointLocation)) {
+		newDestination.destinationScene.depth = _rightZoomDepth;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
+		return SC_TRUE;
+	}
+
+	if (_offeringHeadZoomRegion.contains(pointLocation)) {
+		newDestination.destinationScene.depth = _offeringHeadZoomDepth;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int GenericCavernDoorMainView::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_topZoomRegion.contains(pointLocation) || _rightZoomRegion.contains(pointLocation) || _offeringHeadZoomRegion.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -592,18 +673,26 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_NORTH_TRANS_TEXT, 6, 38, 428, 76, offsetof(GlobalFlags, myTPTextTranslated));
 	case 13:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 140, 124, 174, 158, kItemCavernSkull, 3, offsetof(GlobalFlags, myMCPickedUpSkull));
+	case 14:
+		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 15:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myWGTransDoorTop));
 	case 16:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWGOffering));
+	case 18:
+		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 19:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 20:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWTOffering));
+	case 22:
+		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 23:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 24:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransAGOffering));
+	case 26:
+		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 27:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 28:
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index af4847b531..87462223aa 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -130,7 +130,7 @@ struct GlobalFlags {
 	byte myWGTransDoorTop;              // 111
 	byte myWGSeenLowerPassage;          // 112
 	byte myWGCrossedRopeBridge;         // 113
-	byte myWMCViewedDeathGodDoor;       // 114
+	byte myMCViewedDeathGodDoor;        // 114
 	byte myTPTransBreathOfItzamna;      // 115
 	uint32 myAGHeadAOpenedTime;         // 116-119
 	uint32 myAGHeadBOpenedTime;         // 120-123
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index dc8d303728..04fb31e5df 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -308,7 +308,7 @@ bool BuriedEngine::syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags) {
 	s.syncAsByte(flags.myWGTransDoorTop);
 	s.syncAsByte(flags.myWGSeenLowerPassage);
 	s.syncAsByte(flags.myWGCrossedRopeBridge);
-	s.syncAsByte(flags.myWMCViewedDeathGodDoor);
+	s.syncAsByte(flags.myMCViewedDeathGodDoor);
 	s.syncAsByte(flags.myTPTransBreathOfItzamna);
 	SYNC_FLAG_UINT32(myAGHeadAOpenedTime);
 	SYNC_FLAG_UINT32(myAGHeadBOpenedTime);


Commit: 22440cf87d6983ac8a49b55abdec9ba9d55bfa80
    https://github.com/scummvm/scummvm/commit/22440cf87d6983ac8a49b55abdec9ba9d55bfa80
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the glass pyramid evidence

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index c6e0ba4fd1..5b15acc11a 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -558,6 +558,54 @@ int GenericCavernDoorMainView::specifyCursor(Window *viewWindow, const Common::P
 	return kCursorArrow;
 }
 
+class MainCavernGlassCapture : public SceneBase {
+public:
+	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _glass;
+};
+
+MainCavernGlassCapture::MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_glass = Common::Rect(305, 126, 355, 156);
+}
+
+int MainCavernGlassCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_glass.contains(pointLocation)) {
+			// Play the animation
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(22);
+
+			// Attempt to add it to the biochip
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Disable capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MainCavernGlassCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_glass.contains(pointLocation))
+			return -2;
+
+		return -1;
+	}
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -727,6 +775,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, myMCStingerID), offsetof(GlobalFlags, myMCStingerChannelID), 11, 14);
 	case 71:
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID, IDS_MBT_EVIDENCE_PRESENT);
+	case 72:
+		return new MainCavernGlassCapture(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 103:
 		return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, 2, 4, 4, 2, 1, 5);
 	case 120:


Commit: d4df81743a1d942228bc41e7403dcabacad4495c
    https://github.com/scummvm/scummvm/commit/d4df81743a1d942228bc41e7403dcabacad4495c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement some parts of the environ system

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 2fe8f3ee09..8e81d5bfdf 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -36,6 +36,13 @@
 
 #include "graphics/font.h"
 
+// For some reason, the Win32 API thinks it's OK to define "_environ" in stdlib.h.
+// I refuse to give in and rename a variable on grounds that Windows is completely
+// wrong, so this shall remain.
+#ifdef WIN32
+#undef _environ
+#endif
+
 namespace Buried {
 
 class OvenDoor : public SceneBase {
@@ -841,6 +848,197 @@ void KitchenUnitPostBox::changeBackgroundBitmap() {
 	}
 }
 
+class EnvironSystemControls : public SceneBase {
+public:
+	EnvironSystemControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _environCart;
+	Common::Rect _environButton;
+	Common::Rect _allSatButton;
+};
+
+EnvironSystemControls::EnvironSystemControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_environCart = Common::Rect(176, 70, 256, 136);
+	_environButton = Common::Rect(102, 85, 152, 143);
+	_allSatButton = Common::Rect(278, 85, 326, 143);
+}
+
+int EnvironSystemControls::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	switch (((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge) {
+	case 0: // No cartridge inserted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
+		_staticData.navFrameIndex = 57;
+		break;
+	case 1: // Geno single inserted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+		_staticData.navFrameIndex = 59;
+		break;
+	case 2: // Agent 3's cartridge inserted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+		_staticData.navFrameIndex = 56;
+		break;
+	}
+
+	return SC_TRUE;
+}
+
+int EnvironSystemControls::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	_staticData.navFrameIndex = 50;
+
+	switch (((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge) {
+	case 0: // No cartridge inserted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
+		break;
+	case 1: // Geno single inserted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
+		_staticData.navFrameIndex = 59;
+		break;
+	case 2: // Agent 3's cartridge inserted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
+		_staticData.navFrameIndex = 56;
+		break;
+	}
+
+	return SC_TRUE;
+}
+
+int EnvironSystemControls::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_environCart.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge > 0) {
+		int itemID = 0;
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge) {
+		case 1:
+			itemID = kItemGenoSingleCart;
+			break;
+		case 2:
+			itemID = kItemEnvironCart;
+			break;
+		case 3:
+			itemID = kItemClassicGamesCart; // Alas, the only time this is used in the code
+			break;
+		}
+
+		// Reset the flag and change the frame index
+		_staticData.navFrameIndex = 57;
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge = 0;
+
+		// Start dragging
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(itemID, ptInventoryWindow);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int EnvironSystemControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 1;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 2;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+
+	// If there is something in the slot, return here
+	if (_environCart.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge > 0)
+		return SC_FALSE;
+
+	if (_environButton.contains(pointLocation)) {
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge) {
+		case 0:
+			newScene.destinationScene.depth = 3;
+			newScene.transitionData = 16;
+			break;
+		case 1:
+			newScene.destinationScene.depth = 4;
+			newScene.transitionData = 16;
+			break;
+		case 2:
+			newScene.destinationScene.depth = 5;
+			newScene.transitionData = 16;
+			break;
+		}
+	} else if (_allSatButton.contains(pointLocation)) {
+		newScene.destinationScene.depth = 7;
+		newScene.transitionData = 16;
+	}
+
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int EnvironSystemControls::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if ((itemID == kItemGenoSingleCart || itemID == kItemEnvironCart || itemID == kItemClassicGamesCart) &&
+			_environCart.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge == 0)
+		return 1;
+
+	return 0;
+}
+
+int EnvironSystemControls::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if ((itemID == kItemGenoSingleCart || itemID == kItemEnvironCart || itemID == kItemClassicGamesCart) &&
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge == 0) {
+		switch (itemID) {
+		case kItemGenoSingleCart: {
+			_staticData.navFrameIndex = 59;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge = 1;
+			viewWindow->invalidateWindow(false);
+			DestinationScene newScene;
+			newScene.destinationScene = _staticData.location;
+			newScene.destinationScene.depth = 4;
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionData = 16;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+			return SIC_ACCEPT;
+		}
+		case kItemEnvironCart: {
+			_staticData.navFrameIndex = 56;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge = 2;
+			viewWindow->invalidateWindow(false);
+			DestinationScene newScene;
+			newScene.destinationScene = _staticData.location;
+			newScene.destinationScene.depth = 5;
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionData = 16;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+			return SIC_ACCEPT;
+		}
+		}
+
+		viewWindow->invalidateWindow(false);
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int EnvironSystemControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_environCart.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge > 0)
+		return kCursorOpenHand;
+
+	if (_environButton.contains(pointLocation) || _allSatButton.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorPutDown;
+}
+
 class FlagChangeBackground : public SceneBase {
 public:
 	FlagChangeBackground(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -1548,6 +1746,111 @@ int ClickOnBooks::specifyCursor(Window *viewWindow, const Common::Point &pointLo
 	return kCursorArrow;
 }
 
+class ViewEnvironCart : public SceneBase {
+public:
+	ViewEnvironCart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+};
+
+ViewEnvironCart::ViewEnvironCart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 0)
+		_staticData.navFrameIndex = 66;
+}
+
+int ViewEnvironCart::timerCallback(Window *viewWindow) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1) {
+		_staticData.navFrameIndex = 64;
+
+		// Kill the ambient sound
+		_vm->_sound->setAmbientSound();
+
+		// Set the research scoring flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchEnvironCart = 1;
+
+		// Sit back and relax as you get abducted
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(15);
+		_staticData.navFrameIndex = 55;
+
+		// Empty the input queue
+		BuriedEngine *vm = _vm;
+		vm->removeMouseMessages(viewWindow);
+		vm->removeKeyboardMessages(viewWindow);
+
+		// Make the jump to Agent 3's lair
+		DestinationScene newScene;
+		newScene.destinationScene = Location(3, 2, 6, 0, 0, 0);
+		newScene.transitionType = TRANSITION_NONE;
+		newScene.transitionData = -1;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+
+		vm->removeMouseMessages(viewWindow);
+		vm->removeKeyboardMessages(viewWindow);
+	}
+
+	return SC_TRUE;
+}
+
+int ViewEnvironCart::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// Move back
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 1;
+	newScene.transitionType = TRANSITION_VIDEO;
+	newScene.transitionData = 4;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int ViewEnvironCart::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	return kCursorFinger;
+}
+
+class MainEnvironSitDownClick : public SceneBase {
+public:
+	MainEnvironSitDownClick(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _environ;
+};
+
+MainEnvironSitDownClick::MainEnvironSitDownClick(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_environ = Common::Rect(120, 0, 302, 189);
+}
+
+int MainEnvironSitDownClick::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_environ.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.orientation = 1;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_NONE;
+		newScene.transitionData = -1;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int MainEnvironSitDownClick::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_environ.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class EnvironDoorExitSound : public SceneBase {
 public:
 	EnvironDoorExitSound(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1604,6 +1907,10 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 134, 0, 300, 189, kCursorFinger, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 0, -1, -1);
 	case 16:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 163, 25, 273, 145, kCursorMagnifyingGlass, 4, 2, 2, 0, 1, 2, TRANSITION_VIDEO, 1, -1, -1);
+	case 17:
+		return new EnvironSystemControls(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 20:
+		return new ViewEnvironCart(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 21:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 4, -1, -1);
 	case 23:
@@ -1664,6 +1971,8 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new MainEnvironDoorDown(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 57:
 		return new MainEnvironDoorExit(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 58:
+		return new MainEnvironSitDownClick(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 59:
 		return new EnvironDoorExitSound(_vm, viewWindow, sceneStaticData, priorLocation);
 	}


Commit: ca9fedb6c11613d0ebbc457f805e6e879344c1c5
    https://github.com/scummvm/scummvm/commit/ca9fedb6c11613d0ebbc457f805e6e879344c1c5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Add base for Agent 3's lair

Changed paths:
  A engines/buried/environ/agent3_lair.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
new file mode 100644
index 0000000000..f8b6f20d03
--- /dev/null
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/gameui.h"
+#include "buried/graphics.h"
+#include "buried/inventory_window.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
+
+namespace Buried {
+
+bool SceneViewWindow::initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment) {
+	if (environment == -1)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode = 0;
+
+	return true;
+}
+
+bool SceneViewWindow::startAgent3LairAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	_vm->_sound->setAmbientSound(_vm->getFilePath(3, environment, SF_AMBIENT), fade, 64);
+	return true;
+}
+
+SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	switch (sceneStaticData.classID) {
+	case 1:
+		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 177, 96, 231, 184, kItemGeneratorCore, 15, offsetof(GlobalFlags, alRDTakenLiveCore));
+	case 20:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 36, 15, 396, 189, kCursorFinger, 3, 2, 0, 1, 1, 1, TRANSITION_VIDEO, 0, -1, -1);
+	case 25:
+		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 150, 24, 280, 124, kCursorFinger, 3, 2, 4, 0, 1, 1, TRANSITION_VIDEO, 6, -1, -1);
+	}
+
+	warning("TODO: Agent 3 lair scene object %d", sceneStaticData.classID);
+
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index f4355c9bb8..ea9cefd55d 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -97,6 +97,8 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 		return startCastleAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 2:
 		return startMayanAmbient(oldTimeZone, oldEnvironment, environment, fade);
+	case 3:
+		return startAgent3LairAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 4:
 		return startFutureApartmentAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 5:
@@ -117,7 +119,6 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 
 	switch (sceneStaticData.location.timeZone) {
 	case 0: // Miscellaneous scenes
-	case 3: // Agent 3's Lair
 	case 7: // Alien
 		// TODO
 		warning("Could not create scene object for time zone %d", sceneStaticData.location.timeZone);
@@ -126,6 +127,8 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		return constructCastleSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 2: // Mayan
 		return constructMayanSceneObject(viewWindow, sceneStaticData, priorLocation);
+	case 3: // Agent 3's Lair
+		return constructAgent3LairSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 4: // Future Apartment
 		return constructFutureApartmentSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 5: // Da Vinci
@@ -146,6 +149,8 @@ bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int t
 		return initializeCastleTimeZoneAndEnvironment(viewWindow, environment);
 	case 2:
 		return initializeMayanTimeZoneAndEnvironment(viewWindow, environment);
+	case 3:
+		return initializeAgent3LairTimeZoneAndEnvironment(viewWindow, environment);
 	case 4:
 		// Nothing to do
 		return true;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 9024b643fd..9bc2ede3ce 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -29,6 +29,7 @@ MODULE_OBJS = \
 	demo/demo_menu.o \
 	demo/features.o \
 	demo/movie_scene.o \
+	environ/agent3_lair.o \
 	environ/ai_lab.o \
 	environ/castle.o \
 	environ/da_vinci.o \
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 31d5492521..ccda148965 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -224,6 +224,11 @@ private:
 	bool initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	bool startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
+	// Agent 3's Lair
+	bool initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	bool startAgent3LairAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
+	SceneBase *constructAgent3LairSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 };
 
 } // End of namespace Buried


Commit: b81a6c949ac0014f8902888572529be7ea38c90a
    https://github.com/scummvm/scummvm/commit/b81a6c949ac0014f8902888572529be7ea38c90a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the Agent 3 lair entry scene

Changed paths:
    engines/buried/environ/agent3_lair.cpp
    engines/buried/resources.h
    engines/buried/sound.h


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index f8b6f20d03..153affb186 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
@@ -33,8 +34,365 @@
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
+#include "common/system.h"
+
 namespace Buried {
 
+class LairEntry : public SceneBase {
+public:
+	LairEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+	int onCharacter(Window *viewWindow, const Common::KeyState &character);
+
+private:
+	int _movieIndex;
+	uint32 _timerStart;
+	Common::String _passwordEntered;
+	int _currentSoundID;
+	int _passwordIndex;
+	uint32 _stepDelay;
+	uint32 _rawStepDelay;
+	bool _flickerOn;
+};
+
+LairEntry::LairEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_movieIndex = 0;
+	_timerStart = 0;
+	_currentSoundID = -1;
+	_passwordIndex = 0;
+	_stepDelay = 0;
+	_rawStepDelay = 15000;
+	_flickerOn = ((SceneViewWindow *)viewWindow)->getCyclingStatus();
+	((SceneViewWindow *)viewWindow)->enableCycling(true);
+}
+
+int LairEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alRestoreSkipAgent3Initial == 1) {
+		// Disable frame caching
+		((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
+
+		// Start new secondary ambient
+		_vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 64);
+
+		_staticData.cycleStartFrame = 0;
+		_staticData.cycleFrameCount = 54;
+		_frameCycleCount = _staticData.cycleStartFrame;
+
+		_passwordIndex = 0;
+		_stepDelay = 0;
+		_timerStart = g_system->getMillis();
+
+		// Empty the input queue
+		_vm->removeMouseMessages(viewWindow);
+		_vm->removeKeyboardMessages(viewWindow);
+
+		return SC_TRUE;
+	}
+
+	// Disable frame caching
+	((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
+
+	// Turn on flicker
+	_flickerOn = ((SceneViewWindow *)viewWindow)->getCyclingStatus();
+	((SceneViewWindow *)viewWindow)->enableCycling(true);
+
+	// Empty the input queue
+	_vm->removeMouseMessages(viewWindow);
+	_vm->removeKeyboardMessages(viewWindow);
+
+	// Make sure we have the proper cycle going on
+	_staticData.cycleStartFrame = 54;
+	_staticData.cycleFrameCount = 90;
+	_frameCycleCount = _staticData.cycleStartFrame;
+
+	// Reset the timer and cursor
+	uint32 lastTimerValue = 0;
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	// Remove some inventory items
+	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
+	((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->removeItem(kItemBioChipJump);
+	((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->removeItem(kItemEnvironCart);
+
+	_vm->_gfx->setCursor(oldCursor);
+	_staticData.navFrameIndex = -1;
+	((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
+	_staticData.navFrameIndex = 75;
+	oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	viewWindow->invalidateWindow(false);
+	_vm->_gfx->updateScreen();
+
+	// Play the next Arthur speech
+	_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE), 128, false, true);
+	_timerStart = g_system->getMillis();
+	lastTimerValue = g_system->getMillis();
+
+	while (!_vm->shouldQuit() && _vm->_sound->isSoundEffectPlaying(_currentSoundID)) {
+		if (g_system->getMillis() - lastTimerValue >= 50) {
+			timerCallback(viewWindow);
+			lastTimerValue = g_system->getMillis();
+		}
+
+		_vm->_sound->timerCallback();
+		_vm->yield();
+	}
+
+	_vm->_sound->stopSoundEffect(_currentSoundID);
+
+	_vm->_gfx->setCursor(oldCursor);
+	((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
+	oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	// Add message here
+	Common::String text;
+	if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+		text = _vm->getString(IDS_AGENT3_VIRUS_NETWORK_TEXT);
+	else
+		text = "Neuroconductor uplink connected. Network on-line.";
+	((SceneViewWindow *)viewWindow)->displayLiveText(text, false);
+
+	// Play the next Arthur speech
+	_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE + 1), 128, false, true);
+	_timerStart = g_system->getMillis();
+	lastTimerValue = g_system->getMillis();
+
+	while (!_vm->shouldQuit() && _vm->_sound->isSoundEffectPlaying(_currentSoundID)) {
+		if (g_system->getMillis() - lastTimerValue >= 50) {
+			timerCallback(viewWindow);
+			lastTimerValue = g_system->getMillis();
+		}
+
+		_vm->_sound->timerCallback();
+		_vm->yield();
+	}
+
+	_vm->_sound->stopSoundEffect(_currentSoundID);
+
+	_staticData.cycleStartFrame = 0;
+	_staticData.cycleFrameCount = 54;
+	_frameCycleCount = _staticData.cycleStartFrame;
+
+	_vm->_gfx->setCursor(oldCursor);
+	((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
+	oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+	_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE + 6), 128, false, true);
+
+	// Start new secondary ambient
+	_vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 64);
+
+	_passwordIndex = 0;
+	_stepDelay = 0;
+	_timerStart = g_system->getMillis();
+
+	// Empty the input queue
+	_vm->removeMouseMessages(viewWindow);
+	_vm->removeKeyboardMessages(viewWindow);
+
+	_vm->_gfx->setCursor(oldCursor);
+	return SC_TRUE;
+}
+
+int LairEntry::timerCallback(Window *viewWindow) {
+	SceneBase::timerCallback(viewWindow);
+
+	if (_currentSoundID >= 0) {
+		if (_vm->_sound->isSoundEffectPlaying(_currentSoundID)) {
+			return SC_TRUE;
+		} else {
+			_vm->_sound->stopSoundEffect(_currentSoundID);
+			_currentSoundID = -1;
+			_timerStart = g_system->getMillis();
+		}
+	}
+
+	Common::KeyState dummyKey;
+	dummyKey.keycode = Common::KEYCODE_INVALID;
+	dummyKey.ascii = 0;
+	dummyKey.flags = 0;
+
+	if (g_system->getMillis() > _timerStart + _stepDelay) {
+		switch (_passwordIndex) {
+		case 0:
+			_passwordIndex = 1;
+			onCharacter(viewWindow, dummyKey);
+			_timerStart = g_system->getMillis();
+			_stepDelay = _rawStepDelay;
+			break;
+		case 1:
+			_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE + 2), 128, false, true);
+			_passwordIndex = 2;
+			onCharacter(viewWindow, dummyKey);
+			_timerStart = g_system->getMillis();
+			_stepDelay = _rawStepDelay;
+			break;
+		case 2:
+			_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE + 3), 128, false, true);
+			_passwordIndex = 3;
+			onCharacter(viewWindow, dummyKey);
+			_timerStart = g_system->getMillis();
+			_stepDelay = _rawStepDelay;
+			break;
+		case 3:
+			_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE + 4), 128, false, true);
+			_passwordIndex = 4;
+			onCharacter(viewWindow, dummyKey);
+			_timerStart = g_system->getMillis();
+			_stepDelay = _rawStepDelay;
+			break;
+		case 4:
+			// Mind wipe.
+			_vm->_sound->setAmbientSound();
+			_vm->_sound->setSecondaryAmbientSound();
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(13);
+			((SceneViewWindow *)viewWindow)->enableCycling(_flickerOn);
+			((SceneViewWindow *)viewWindow)->showDeathScene(20);
+			break;
+		case 5: {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEliminatedAgent3 = 1;
+
+			// "Kill" off Agent 3 *snicker*
+			_passwordIndex = 1;
+			onCharacter(viewWindow, dummyKey);
+			((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(3, 1, SF_STILLS));
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(14);
+			_frameCycleCount = -1;
+			_staticData.cycleStartFrame = -1;
+			_staticData.cycleFrameCount = -1;
+			_staticData.navFrameIndex = 75;
+
+			DestinationScene newScene;
+			newScene.destinationScene = Location(3, 1, 3, 3, 1, 0);
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionData = 15;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			bool flickerOn = _flickerOn;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+			((SceneViewWindow *)viewWindow)->enableCycling(flickerOn);
+			break;
+		}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int LairEntry::onCharacter(Window *viewWindow, const Common::KeyState &character) {
+	// Only accept input if we are beyond first voiceover
+	if (_passwordIndex <= 0)
+		return SC_TRUE;
+
+	if (character.keycode == Common::KEYCODE_DELETE || character.keycode == Common::KEYCODE_BACKSPACE) {
+		if (!_passwordEntered.empty())
+			_passwordEntered.deleteLastChar();
+	} else if (character.keycode == Common::KEYCODE_SPACE || (character.keycode >= Common::KEYCODE_a && character.keycode <= Common::KEYCODE_z) ||
+			(character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9) && _passwordEntered.size() < 15) {
+	
+		if (character.keycode == Common::KEYCODE_SPACE)
+			_passwordEntered += ' ';
+		else if (character.keycode >= Common::KEYCODE_a && character.keycode <= Common::KEYCODE_z)
+			_passwordEntered += (char)(character.keycode - Common::KEYCODE_a + 'A');
+		else
+			_passwordEntered += (char)(character.keycode - Common::KEYCODE_0 + '0');
+	}
+
+	Common::String liveText = _vm->getString(IDS_AGENT3_VIRUS_TEXT_A);
+	liveText += _passwordEntered;
+	liveText += _vm->getString(IDS_AGENT3_VIRUS_CURSOR);
+
+	if (_passwordIndex > 1)
+		liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_B);
+	if (_passwordIndex > 2)
+		liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_C);
+	if (_passwordIndex > 3)
+		liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_D);
+
+	((SceneViewWindow  *)viewWindow)->displayLiveText(liveText, false);
+
+	if (character.keycode == Common::KEYCODE_RETURN) {
+		if (_passwordEntered == _vm->getString(IDS_AGENT3_VIRUS_PASSWORD)) {
+			liveText = _vm->getString(IDS_AGENT3_VIRUS_PW_ACCEPTED);
+
+			if (_passwordIndex > 1)
+				liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_B);
+			if (_passwordIndex > 2)
+				liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_C);
+			if (_passwordIndex > 3)
+				liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_D);
+
+			((SceneViewWindow  *)viewWindow)->displayLiveText(liveText, false);
+
+			if (_currentSoundID >= 0)
+				_vm->_sound->stopSoundEffect(_currentSoundID);
+
+			_currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_AGENT3_VIRUS_SOUND_BASE + 5), 128, false, true);
+
+			_timerStart = g_system->getMillis();
+			while (!_vm->shouldQuit() && _vm->_sound->isSoundEffectPlaying(_currentSoundID)) {
+				if ((g_system->getMillis() - _timerStart) % 20 < 5)
+					timerCallback(viewWindow);
+
+				_vm->_sound->timerCallback();
+				_vm->yield();
+			}
+
+			_vm->_sound->stopSoundEffect(_currentSoundID);
+			((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->removeItem(kItemBioChipAI);
+			((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemBioChipBlank);
+
+			_vm->_sound->setAmbientSound(_vm->getFilePath(3, 2, SF_AMBIENT), false, 64);
+			_passwordIndex = 5;
+			_timerStart = 0;
+			_stepDelay = 0;
+			return SC_TRUE;
+		}
+
+		// Watch out, some curse words in here
+		Common::String vulgarLangA = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_A) : "FUCKER";
+		Common::String vulgarLangB = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_B) : "SHITHEAD";
+		Common::String vulgarLangC = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_C) : "BITCH";
+		Common::String vulgarLangD = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_D) : "CUNT";
+		Common::String vulgarLangE = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_E) : "WHORE";
+		Common::String vulgarLangF = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_F) : "ASSHOLE";
+		Common::String vulgarLangG = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_G) : "TWAT";
+		Common::String vulgarLangH = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_H) : "FUCK";
+		Common::String vulgarLangI = (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_VULGAR_LANG_I) : "SHIT";
+
+		if (_passwordEntered == vulgarLangA || _passwordEntered == vulgarLangB || _passwordEntered == vulgarLangC ||
+				_passwordEntered == vulgarLangD || _passwordEntered == vulgarLangE || _passwordEntered == vulgarLangF ||
+				_passwordEntered == vulgarLangG || _passwordEntered == vulgarLangH || _passwordEntered == vulgarLangI) {
+			liveText = _vm->getString(IDS_AGENT3_VIRUS_TEXT_A);
+			liveText += _passwordEntered;
+			liveText += _vm->getString(IDS_AGENT3_VIRUS_CURSOR);
+			liveText += (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0)) ? _vm->getString(IDS_AL_CASTRATION_TEXT) : "\nVULGAR LANGUAGE UNACCEPTABLE. CASTRATION TOOL ACTIVATED.";
+			((SceneViewWindow  *)viewWindow)->displayLiveText(liveText, false);
+			_passwordIndex = 4;
+			_timerStart = 0;
+			_stepDelay = 0;
+			return SC_TRUE;
+		}
+
+		_passwordEntered.clear();
+		liveText = _vm->getString(IDS_AGENT3_VIRUS_TEXT_A);
+		liveText += _passwordEntered;
+		liveText += _vm->getString(IDS_AGENT3_VIRUS_CURSOR);
+
+		if (_passwordIndex > 1)
+			liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_B);
+		if (_passwordIndex > 2)
+			liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_C);
+		if (_passwordIndex > 3)
+			liveText += "\n" + _vm->getString(IDS_AGENT3_VIRUS_TEXT_D);
+
+		((SceneViewWindow  *)viewWindow)->displayLiveText(liveText, false);
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1)
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode = 0;
@@ -53,6 +411,8 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 177, 96, 231, 184, kItemGeneratorCore, 15, offsetof(GlobalFlags, alRDTakenLiveCore));
+	case 10:
+		return new LairEntry(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 20:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 36, 15, 396, 189, kCursorFinger, 3, 2, 0, 1, 1, 1, TRANSITION_VIDEO, 0, -1, -1);
 	case 25:
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 1cd30dd1d9..7179c9dd42 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -328,6 +328,9 @@ namespace Buried {
 #define IDS_FUTAPT_ENVIRON_DOOR_CLOSE	6196
 #define IDS_AGENT3_VIRUS_PW_ACCEPTED    6197
 
+// 1.04+:
+#define IDS_AGENT3_VIRUS_NETWORK_TEXT   6198
+
 #define IDS_FOOTSTEPS_FILENAME_BASE		6200
 
 #define IDS_INN_STILL_FRAME_FILENAME	6300
@@ -355,6 +358,16 @@ namespace Buried {
 #define IDES_ITEM_DESC_BASE				8256
 
 // 1.04+:
+#define IDS_AL_VULGAR_LANG_A            9000
+#define IDS_AL_VULGAR_LANG_B            9001
+#define IDS_AL_VULGAR_LANG_C            9002
+#define IDS_AL_VULGAR_LANG_D            9003
+#define IDS_AL_VULGAR_LANG_E            9004
+#define IDS_AL_VULGAR_LANG_F            9005
+#define IDS_AL_VULGAR_LANG_G            9006
+#define IDS_AL_VULGAR_LANG_H            9007
+#define IDS_AL_VULGAR_LANG_I            9009
+#define IDS_AL_CASTRATION_TEXT          9016
 #define IDS_COMPL_WALK_SCORE_DESC_TEMPL 9031
 #define IDS_DEATH_WALK_SCORE_DESC_TEMPL 9031
 #define IDS_COMPL_WALK_SCORE_AMT_TEMPL  9032
diff --git a/engines/buried/sound.h b/engines/buried/sound.h
index d7661f6fac..cbf2a7b3d7 100644
--- a/engines/buried/sound.h
+++ b/engines/buried/sound.h
@@ -51,7 +51,7 @@ public:
 	bool adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
 	uint32 getAmbientPosition();
 
-	bool setSecondaryAmbientSound(const Common::String &fileName, bool fade = false, byte finalVolumeLevel = 64);
+	bool setSecondaryAmbientSound(const Common::String &fileName = "", bool fade = false, byte finalVolumeLevel = 64);
 	bool adjustSecondaryAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
 	uint32 getSecondaryAmbientPosition();
 	bool restartSecondaryAmbientSound();


Commit: a3dc50a6a2d7fa1c5178aaec529807c728169cde
    https://github.com/scummvm/scummvm/commit/a3dc50a6a2d7fa1c5178aaec529807c728169cde
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Fix jump biochip display

Technically both a regression and a bug; it worked by accident before my video rect fix

Changed paths:
    engines/buried/biochip_right.cpp


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index 5eaee87975..e925ed3c81 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -203,6 +203,8 @@ void BioChipRightWindow::onPaint() {
 			if (currentLocation.timeZone == 4)
 				bitmapResID++;
 
+		if (_jumpInProgress)
+			bitmapResID += 6;
 		break;
 	}
 	case kItemBioChipTranslate:


Commit: 13fb5c21d4847679f04cf598637485beee1fa4dd
    https://github.com/scummvm/scummvm/commit/13fb5c21d4847679f04cf598637485beee1fa4dd
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the cavern offering heads

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 5b15acc11a..3099b6f600 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -558,6 +558,178 @@ int GenericCavernDoorMainView::specifyCursor(Window *viewWindow, const Common::P
 	return kCursorArrow;
 }
 
+class GenericCavernDoorOfferingHead : public SceneBase {
+public:
+	GenericCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int correctOfferingID = -1, int correctOfferingDestDepth = 0, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	DestinationScene _correctDestination;
+	int _correctOfferingID;
+	Common::Rect _dropRegion;
+
+	bool isValidItemToDrop(Window *viewWindow, int itemID);
+};
+
+GenericCavernDoorOfferingHead::GenericCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int correctOfferingID, int correctOfferingDestDepth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_correctDestination.destinationScene = _staticData.location;
+	_correctDestination.destinationScene.depth = correctOfferingDestDepth;
+	_correctDestination.transitionType = transitionType;
+	_correctDestination.transitionData = transitionData;
+	_correctDestination.transitionStartFrame = transitionStartFrame;
+	_correctDestination.transitionLength = transitionLength;
+	_correctOfferingID = correctOfferingID;
+	_dropRegion = Common::Rect(24, 92, 226, 154);
+}
+
+int GenericCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	// If this is walkthrough mode, only accept the correct item
+	if (isValidItemToDrop(viewWindow, itemID) && _dropRegion.contains(pointLocation))
+		return 1;
+
+	return 0;
+}
+
+int GenericCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (!isValidItemToDrop(viewWindow, itemID))
+		return SIC_REJECT;
+
+	if (_dropRegion.contains(pointLocation)) {
+		switch (itemID) {
+		case kItemBalconyKey:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+			break;
+		case kItemBloodyArrow:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+			break;
+		case kItemObsidianBlock:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(5);
+			break;
+		case kItemCoilOfRope:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
+			break;
+		case kItemCopperKey:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+			break;
+		case kItemCopperMedallion:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
+			break;
+		case kItemCeramicBowl:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+			break;
+		case kItemGrapplingHook:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
+			break;
+		case kItemHammer:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
+			break;
+		case kItemPreservedHeart:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
+			break;
+		case kItemJadeBlock:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(13);
+			break;
+		case kItemLimestoneBlock:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(14);
+			break;
+		case kItemMetalBar:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(15);
+			break;
+		case kItemCavernSkull:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(16);
+			break;
+		case kItemEntrySkull:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(17);
+			break;
+		case kItemSpearSkull:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(18);
+			break;
+		case kItemWaterCanFull:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(19);
+			break;
+		case kItemWoodenPegs:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(20);
+			break;
+		case kItemGoldCoins:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(21);
+			break;
+		}
+
+		// Reset the offering flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCTransMadeAnOffering = 1;
+
+		// If this was the correct offering, move to the open door scene
+		if (itemID == _correctOfferingID) {
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
+			((SceneViewWindow *)viewWindow)->moveToDestination(_correctDestination);
+		}
+
+		// These items don't get consumed
+		if (itemID == kItemWaterCanFull || itemID == kItemGoldCoins)
+			return SIC_REJECT;
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int GenericCavernDoorOfferingHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	Location newLocation = _staticData.location;
+	newLocation.depth = 0;
+	((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+	return SC_TRUE;
+}
+
+int GenericCavernDoorOfferingHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	return kCursorPutDown;
+}
+
+bool GenericCavernDoorOfferingHead::isValidItemToDrop(Window *viewWindow, int itemID) {
+	// If this is walkthrough mode, only accept the correct item
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
+		if (itemID == _correctOfferingID || (_staticData.location.node == 8 && itemID == kItemBloodyArrow))
+			return true;
+
+		return false;
+	}
+
+	// Otherwise, any of the allowed items
+	switch (itemID) {
+	case kItemCavernSkull:
+	case kItemEntrySkull:
+	case kItemSpearSkull:
+	case kItemBloodyArrow:
+	case kItemCopperMedallion:
+	case kItemCoilOfRope:
+	case kItemCopperKey:
+	case kItemJadeBlock:
+	case kItemLimestoneBlock:
+	case kItemObsidianBlock:
+	case kItemGrapplingHook:
+	case kItemPreservedHeart:
+	case kItemHammer:
+	case kItemGoldCoins:
+	case kItemWaterCanEmpty:
+	case kItemWaterCanFull:
+	case kItemWoodenPegs:
+	case kItemBalconyKey:
+	case kItemBurnedLetter: // Can't actually drop this, though
+		return true;
+	}
+
+	return false;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -727,18 +899,24 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myWGTransDoorTop));
 	case 16:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWGOffering));
+	case 17:
+		return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemGoldCoins, 4, TRANSITION_WALK, -1, 1082, 13);
 	case 18:
 		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 19:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 20:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWTOffering));
+	case 21:
+		return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemWaterCanFull, 4, TRANSITION_WALK, -1, 1125, 13);
 	case 22:
 		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 23:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 24:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransAGOffering));
+	case 25:
+		return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemBloodyArrow, 4, TRANSITION_WALK, -1, 1010, 12);
 	case 26:
 		return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
 	case 27:


Commit: debf417c4ef14bcf993184c363c63a7cd8c23ec5
    https://github.com/scummvm/scummvm/commit/debf417c4ef14bcf993184c363c63a7cd8c23ec5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the WalkVolumeChange scene

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 3099b6f600..d2452d75c7 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -778,6 +778,43 @@ int MainCavernGlassCapture::specifyCursor(Window *viewWindow, const Common::Poin
 	return kCursorArrow;
 }
 
+class WalkVolumeChange : public SceneBase {
+public:
+	WalkVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			byte newVolume = 0, uint32 volumeChangeTime = 0, int stepCount = -1, int entryEffectFileNameID = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+
+private:
+	byte _newVolume;
+	uint32 _volumeChangeTime;
+	int _stepCount;
+	int _entryEffectFileNameID;
+};
+
+WalkVolumeChange::WalkVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		byte newVolume, uint32 volumeChangeTime, int stepCount, int entryEffectFileNameID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_newVolume = newVolume;
+	_volumeChangeTime = volumeChangeTime;
+	_stepCount = stepCount;
+	_entryEffectFileNameID = entryEffectFileNameID;
+}
+
+int WalkVolumeChange::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (_entryEffectFileNameID >= 0 && priorLocation.node != _staticData.location.node)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _entryEffectFileNameID), 128, false, true);
+
+	return SC_TRUE;
+}
+
+int WalkVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_stepCount >= 0 && newLocation.node != _staticData.location.node)
+		_vm->_sound->adjustAmbientSoundVolume(_newVolume, true, _stepCount, _volumeChangeTime);
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -955,6 +992,36 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID, IDS_MBT_EVIDENCE_PRESENT);
 	case 72:
 		return new MainCavernGlassCapture(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 75:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4500, 12, 14);
+	case 76:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 6333, 12);
+	case 77:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 2, 1000, 2);
+	case 78:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 2, 1000, 2, 14);
+	case 79:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 6500, 12);
+	case 80:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 4750, 12);
+	case 81:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 30, 7750, 6);
+	case 82:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 2250, 18);
+	case 83:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 30, 2410, 6);
+	case 84:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 7666, 18);
+	case 85:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 255, 0, -1, 10); // First param has to be wrong
+	case 90:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 3160, 12, 14);
+	case 91:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 4160, 12);
+	case 92:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4160, 12);
+	case 93:
+		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 3160, 12);
 	case 103:
 		return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, 2, 4, 4, 2, 1, 5);
 	case 120:


Commit: b5476472347b847fe27d13ea18a7d8c8f5df3307
    https://github.com/scummvm/scummvm/commit/b5476472347b847fe27d13ea18a7d8c8f5df3307
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the Mayan AI comment dependencies

Changed paths:
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index d2452d75c7..f9e44e1656 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -900,6 +900,115 @@ bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int
 	return true;
 }
 
+bool SceneViewWindow::checkCustomMayanAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
+	//((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory
+
+	switch (commentData.dependencyFlagOffsetB) {
+	case 1: // Player hasn't translated any inscriptions
+		return _globalFlags.myTPTextTranslated == 0;
+	case 2: // Player hasn't translated any inscriptions, has translate biochip
+		return _globalFlags.myTPTextTranslated == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
+	case 3: // Player hasn't translated any inscriptions, doesn't have translate biochip
+		return _globalFlags.myTPTextTranslated == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
+	case 4: // Has translated inscription above calendar, calendar not set to sacred day, player has never been to main cavern
+		return _globalFlags.myTPCalendarTopTranslated == 1 && _globalFlags.myTPCodeWheelStatus == 0 && _globalFlags.myVisitedMainCavern == 0;
+	case 5: // Has translated inscription above calendar, calendar is set to sacred day, player has never been to main cavern
+		return _globalFlags.myTPCalendarTopTranslated == 1 && _globalFlags.myTPCodeWheelStatus == 1 && _globalFlags.myVisitedMainCavern == 0;
+	case 6: // Player has never been to main cavern
+		return _globalFlags.myVisitedMainCavern == 0;
+	case 7: // Player has never been to main cavern, calendar not set to sacred day
+		return _globalFlags.myVisitedMainCavern == 0 && _globalFlags.myTPCodeWheelStatus == 0;
+	case 8: // Ceramic bowl not in the inventory
+		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCeramicBowl);
+	case 9: // If node is not 5, 6, or 8
+		return commentLocation.node != 6 && commentLocation.node != 5 && commentLocation.node != 8;
+	case 10: // If node is not 1, 0, 7, or 8
+		return commentLocation.node != 1 && commentLocation.node != 0 && commentLocation.node != 7 && commentLocation.node != 8;
+	case 11: // If node is not 0, 8, or 1
+		return commentLocation.node != 0 && commentLocation.node != 8 && commentLocation.node != 1;
+	case 12: // If not translated any sacred days
+		return _globalFlags.myTPCalendarListTranslated == 0;
+	case 13: // Not any door, no translations
+		return _globalFlags.myVisitedSpecRooms == 0 && _globalFlags.myMCTransDoor == 0;
+	case 14: // Not any door, no translations, has translate chip
+		return _globalFlags.myVisitedSpecRooms == 0 && _globalFlags.myMCTransDoor == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
+	case 15: // Not any door, has translated arrow or translated water or translated wealth
+		return _globalFlags.myVisitedSpecRooms == 0 && (_globalFlags.myMCTransAGOffering == 1 || _globalFlags.myMCTransWGOffering == 1 || _globalFlags.myMCTransWTOffering == 1);
+	case 16: // Has translated wealth, has not been through wealth god door
+		return _globalFlags.myMCTransWGOffering == 1 && _globalFlags.myVisitedWealthGod == 0;
+	case 17: // Has translated water, has not been through water god door
+		return _globalFlags.myMCTransWTOffering == 1 && _globalFlags.myVisitedWaterGod == 0;
+	case 18: // Has translated arrow, has not been through arrow god door
+		return _globalFlags.myMCTransAGOffering == 1 && _globalFlags.myVisitedArrowGod == 0;
+	case 19: // Has translated death, has not been through death god door
+		return _globalFlags.myMCTransDGOffering == 1 && _globalFlags.myVisitedDeathGod == 0;
+	case 20: // Has not been through death god door
+		return _globalFlags.myVisitedDeathGod == 0;
+	case 21: // Has translated death
+		return _globalFlags.myMCTransDGOffering == 1;
+	case 22: // After making any offering
+		return _globalFlags.myMCTransMadeAnOffering == 1;
+	case 23: // Before crossing rope bridge
+		return _globalFlags.myWGCrossedRopeBridge == 0;
+	case 24: // If player has translated inscription above wealth god door in cavern
+		return _globalFlags.myMCTransWGOffering == 1;
+	case 25: // If player has not translated inscription above wealth god door in cavern
+		return _globalFlags.myMCTransWGOffering == 0;
+	case 26: // If player has translated inscription above wealth god door in cavern, has never been to wealth god altar room
+		return _globalFlags.myMCTransWGOffering == 1 && _globalFlags.myWGSeenLowerPassage == 0;
+	case 27: // Has not attached either rope or grappling hook, has never been to wealth god altar room
+		return _globalFlags.myWGPlacedRope == 0 && _globalFlags.myWGSeenLowerPassage == 0;
+	case 28: // Player has never stepped on swings
+		return _globalFlags.myWTSteppedOnSwings == 0;
+	case 29: // Player has never been on far ledge
+		return _globalFlags.myWTSteppedOnFarLedge == 0;
+	case 30: // Never put in heart
+		return _globalFlags.myDGOfferedHeart == 0;
+	case 31: // Never put in heart, no heart in inventory
+		return _globalFlags.myDGOfferedHeart == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemPreservedHeart);
+	case 32: // After put in heart, puzzle box never opened
+		return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0;
+	case 33: // After put in heart, puzzle box never opened, player has not translated 'Itzamna' inscription over inside door of temple
+		return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0 && _globalFlags.myTPTransBreathOfItzamna == 0;
+	case 34: // After put in heart, puzzle box never opened, player has translated 'Itzamna' inscription over inside door of temple
+		return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0 && _globalFlags.myTPTransBreathOfItzamna == 1;
+	case 35: // Before interacting with any heads
+		return _globalFlags.myAGHeadATouched == 0 && _globalFlags.myAGHeadBTouched == 0 && _globalFlags.myAGHeadCTouched == 0 && _globalFlags.myAGHeadDTouched == 0;
+	case 36: // After interacting with any head, before jamming any head
+		return (_globalFlags.myAGHeadATouched == 1 || _globalFlags.myAGHeadBTouched == 1 || _globalFlags.myAGHeadCTouched == 1 || _globalFlags.myAGHeadDTouched == 1) && _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0;
+	case 37: // S2 jam, S1 not jam, not altar
+		return _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
+	case 38: // S1 jam, S2 not jam, S3 not jam, not altar
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0;
+	case 39: // S1 jam, S2 not jam, S3 not jam, S4 not jam, not altar, no skulls
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
+	case 40: // Before interacting with S3 or S4, not altar
+		return _globalFlags.myAGHeadCTouched == 0 && _globalFlags.myAGHeadDTouched == 0 && _globalFlags.myAGVisitedAltar == 0;
+	case 41: // S1 jam, S2 jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, no skulls
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
+	case 42: // S1 jam, S2 not jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, only 1 skull in inventory
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull));
+	case 43: // S1 jam, S2 jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, no skulls
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
+	case 44: // S1 jam, S2 not jam, S3 jam, S4 not jam, not altar, no skulls
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
+	case 45: // S1 jam, S2 not jam, S3 not jam, S4 jam, not altar, no skulls
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
+	case 46: // S1 jam, S2 not jam, S3 not jam, S4 jam, not altar, only 1 skull in inventory
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull));
+	case 47: // S1 jam, S3 jam, S4 jam, not altar
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
+	case 48: // S1 jam, S3 jam, not altar, only 1 skull in inventory
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull));
+	case 49: // S1 jam, S2 jam, S3 jam, not altar
+		return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
+	case 50: // S1 not jam, S2 jam, not altar
+		return _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
+	}
+
+	return false;
+}
+
 SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index ea9cefd55d..81251052f0 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -73,11 +73,11 @@ int OldApartmentSuitCap::postEnterRoom(Window *viewWindow, const Location &prior
 }
 
 bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
-	// TODO
-
 	switch (commentLocation.timeZone) {
 	case 1:
 		return checkCustomCastleAICommentDependencies(commentLocation, commentData);
+	case 2:
+		return checkCustomMayanAICommentDependencies(commentLocation, commentData);
 	case 4:
 		return commentData.dependencyFlagOffsetB == 1; // Not sure what this one does
 	case 5:
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index ccda148965..6318f11447 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -224,6 +224,7 @@ private:
 	bool initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	bool startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	bool checkCustomMayanAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
 
 	// Agent 3's Lair
 	bool initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment);


Commit: f55d5b3e2fa049fb0616facdffcc288a756ecd1d
    https://github.com/scummvm/scummvm/commit/f55d5b3e2fa049fb0616facdffcc288a756ecd1d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Add the SetVolumeAndFlag scene base

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index f9e44e1656..d76240824c 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -815,6 +815,21 @@ int WalkVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocatio
 	return SC_TRUE;
 }
 
+class SetVolumeAndFlag : public SceneBase {
+public:
+	SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			byte newVolume = 64, int flagOffset = -1, byte flagValue = 255);
+};
+
+SetVolumeAndFlag::SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		byte newVolume, int flagOffset, byte flagValue) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_vm->_sound->adjustAmbientSoundVolume(newVolume, false, 0, 0);
+
+	if (flagOffset >= 0)
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagOffset, flagValue);
+}
+
 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -1123,6 +1138,12 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 7666, 18);
 	case 85:
 		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 255, 0, -1, 10); // First param has to be wrong
+	case 86:
+		return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, offsetof(GlobalFlags, myWGSeenLowerPassage));
+	case 87:
+		return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, offsetof(GlobalFlags, myWGCrossedRopeBridge));
+	case 88:
+		return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64);
 	case 90:
 		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 3160, 12, 14);
 	case 91:


Commit: bb3623cbcae169dfe6df8bfe046d6598d746cd57
    https://github.com/scummvm/scummvm/commit/bb3623cbcae169dfe6df8bfe046d6598d746cd57
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the wealth god puzzle

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index d76240824c..30bed228e7 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -730,6 +730,58 @@ bool GenericCavernDoorOfferingHead::isValidItemToDrop(Window *viewWindow, int it
 	return false;
 }
 
+class WealthGodRopeDrop : public SceneBase {
+public:
+	WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+
+private:
+	Common::Rect _dropRope;
+};
+
+WealthGodRopeDrop::WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope == 1)
+		_staticData.navFrameIndex = 121;
+
+	_dropRope = Common::Rect(222, 149, 282, 189);
+}
+
+int WealthGodRopeDrop::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope != 0) {
+		Location newLocation = _staticData.location;
+		newLocation.depth = 1;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+	}
+
+	return SC_TRUE;
+}
+
+int WealthGodRopeDrop::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	// OK, I honestly didn't know you could use the grappling hook here
+	if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook))
+		return 1;
+
+	return 0;
+}
+
+int WealthGodRopeDrop::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook)) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope = 1;
+		Location newLocation = _staticData.location;
+		newLocation.depth = 1;
+		((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1084,6 +1136,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 28:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransDGOffering));
+	case 30:
+		return new WealthGodRopeDrop(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 31:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 194, 106, 278, 126, kItemJadeBlock, 105, offsetof(GlobalFlags, myWGRetrievedJadeBlock));
 	case 32:


Commit: c4ea3070b0262809460306a4d90c7714846b2f04
    https://github.com/scummvm/scummvm/commit/c4ea3070b0262809460306a4d90c7714846b2f04
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Make sure the async movie is deleted

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index dd7889363e..b7c89eb24a 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -93,6 +93,7 @@ SceneViewWindow::~SceneViewWindow() {
 	delete _stillFrames;
 	delete _cycleFrames;
 	delete _walkMovie;
+	delete _asyncMovie;
 }
 
 bool SceneViewWindow::startNewGame(bool walkthrough) {


Commit: f507a66533de67dd01db49e56376b2b685452827
    https://github.com/scummvm/scummvm/commit/f507a66533de67dd01db49e56376b2b685452827
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the water god puzzle

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 30bed228e7..80cae475d1 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -30,6 +30,7 @@
 #include "buried/graphics.h"
 #include "buried/invdata.h"
 #include "buried/inventory_window.h"
+#include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -782,6 +783,144 @@ int WealthGodRopeDrop::droppedItem(Window *viewWindow, int itemID, const Common:
 	return SIC_REJECT;
 }
 
+class WaterGodInitialWalkSetFlag : public SceneBase {
+public:
+	WaterGodInitialWalkSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+};
+
+WaterGodInitialWalkSetFlag::WaterGodInitialWalkSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	// Set flag on entry
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().myWTCurrentBridgeStatus = 1;
+}
+
+class WaterGodBridgeJump : public SceneBase {
+public:
+	WaterGodBridgeJump(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int movieFileNameID = 0, int playingStartingFrame = 0, int sequenceStartingFrame = 0, int framesPerCycle = 0,
+			int jumpFudgeFrames = 0, int sequenceLength = 0, bool jumpMidCycle = false, int frameOffsetToEndOfSwing = 0);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int timerCallback(Window *viewWindow);
+	int movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status);
+
+private:
+	int _movieID;
+	int _startingMovieFrame;
+	int _playingStartingFrame;
+	int _framesPerCycle;
+	int _sequenceLength;
+	int _jumpFudgeFrames;
+	int _finalFrameIndex;
+	int _soundID;
+	DestinationScene _savedDestForward;
+	bool _jumpMidCycle;
+	int _frameOffsetToEndOfSwing;
+};
+
+WaterGodBridgeJump::WaterGodBridgeJump(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int movieFileNameID, int playingStartingFrame, int sequenceStartingFrame, int framesPerCycle,
+		int jumpFudgeFrames, int sequenceLength, bool jumpMidCycle, int frameOffsetToEndOfSwing) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_movieID = movieFileNameID;
+	_playingStartingFrame = playingStartingFrame;
+	_startingMovieFrame = sequenceStartingFrame;
+	_framesPerCycle = framesPerCycle;
+	_sequenceLength = sequenceLength;
+	_jumpFudgeFrames = jumpFudgeFrames;
+	_finalFrameIndex = -1;
+	_soundID = -1;
+	_jumpMidCycle = jumpMidCycle;
+	_frameOffsetToEndOfSwing = frameOffsetToEndOfSwing;
+
+	// Save the forward movement data for later
+	_savedDestForward = _staticData.destForward;
+	_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destForward.transitionType = -1;
+	_staticData.destForward.transitionData = -1;
+	_staticData.destForward.transitionStartFrame = -1;
+	_staticData.destForward.transitionLength = -1;
+
+	// Set visited flag
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().myWTSteppedOnSwings = 1;
+}
+
+int WaterGodBridgeJump::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Raise the ambient sound
+	_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+	uint32 ambientPos = _vm->_sound->getSecondaryAmbientPosition();
+
+	int frameStartingOffset = (ambientPos / 1838) % _sequenceLength + (_startingMovieFrame - _playingStartingFrame) % _sequenceLength;
+
+	// Load and start the new asynchronous animation
+	((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(_movieID, _startingMovieFrame, _playingStartingFrame + frameStartingOffset, _sequenceLength, true);
+	return SC_TRUE;
+}
+
+int WaterGodBridgeJump::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	_finalFrameIndex = ((SceneViewWindow *)viewWindow)->getAsynchronousAnimationCurrentPosition();
+
+	// Moving to another node should kill the anim
+	if (newLocation.node != 4 || newLocation.timeZone != 2 || newLocation.environment != 4)
+		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+
+	// If we are walking into a node less than 5, kill the ambient
+	if (newLocation.node <= 3)
+		_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+
+	return SC_TRUE;
+}
+
+int WaterGodBridgeJump::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.facing == _staticData.location.facing && newLocation.timeZone == _staticData.location.timeZone &&
+			newLocation.facing == _staticData.location.facing && newLocation.timeZone == _staticData.location.timeZone &&
+			newLocation.facing == _staticData.location.facing && newLocation.timeZone == _staticData.location.timeZone) {
+		if (_jumpMidCycle) {
+			int diff = (_finalFrameIndex - _playingStartingFrame) % (_framesPerCycle * 2);
+			int diffB = (_finalFrameIndex - _playingStartingFrame - _framesPerCycle) % _framesPerCycle;
+			int diffC = _framesPerCycle - (_finalFrameIndex - _playingStartingFrame) % _framesPerCycle;
+
+			if (diff > _framesPerCycle || diffB > _framesPerCycle || diffC > _jumpFudgeFrames * 2) {
+				if (_staticData.location.facing == 0)
+					((SceneViewWindow *)viewWindow)->showDeathScene(14);
+				else
+					((SceneViewWindow *)viewWindow)->showDeathScene(15);
+
+				return SC_DEATH;
+			}
+		} else {
+			if ((_finalFrameIndex - _playingStartingFrame) % _framesPerCycle > _jumpFudgeFrames && _framesPerCycle - (_finalFrameIndex - _playingStartingFrame) % _framesPerCycle > _jumpFudgeFrames) {
+				if (_staticData.location.facing == 0)
+					((SceneViewWindow *)viewWindow)->showDeathScene(14);
+				else
+					((SceneViewWindow *)viewWindow)->showDeathScene(15);
+
+				return SC_DEATH;
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int WaterGodBridgeJump::timerCallback(Window *viewWindow) {
+	// If we have reached the end of the starting sequence, reset the arrows
+	if (_staticData.destForward.destinationScene.timeZone == -1 && ((SceneViewWindow *)viewWindow)->getAsynchronousAnimationCurrentPosition() >= _startingMovieFrame) {
+		_staticData.destForward = _savedDestForward;
+		((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
+	}
+
+	return SC_TRUE;
+}
+
+int WaterGodBridgeJump::movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) {
+	if (status == MOVIE_LOOPING_RESTART)
+		_vm->_sound->restartSecondaryAmbientSound();
+
+	return SC_TRUE;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -867,6 +1006,67 @@ int WalkVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocatio
 	return SC_TRUE;
 }
 
+class AdjustSecondaryAmbientOnEntry : public SceneBase {
+public:
+	AdjustSecondaryAmbientOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+};
+
+AdjustSecondaryAmbientOnEntry::AdjustSecondaryAmbientOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int AdjustSecondaryAmbientOnEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+	return SC_TRUE;
+}
+
+int AdjustSecondaryAmbientOnEntry::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	// Kill the ambient if moving to a different node
+	if (newLocation.node != _staticData.location.node)
+		_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+
+	return SC_TRUE;
+}
+
+class WalkDualAmbientVolumeChange : public SceneBase {
+public:
+	WalkDualAmbientVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			byte newVolume = 0, byte secondVolume = 0, uint32 volumeChangeTime = 0, int stepCount = -1);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+
+private:
+	byte _newVolume;
+	uint32 _volumeChangeTime;
+	int _stepCount;
+	byte _secondVolume;
+};
+
+WalkDualAmbientVolumeChange::WalkDualAmbientVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		byte newVolume, byte secondVolume, uint32 volumeChangeTime, int stepCount) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_newVolume = newVolume;
+	_volumeChangeTime = volumeChangeTime;
+	_stepCount = stepCount;
+	_secondVolume = secondVolume;
+
+	// If we have stepped on the far ledge, set the flag
+	if (_staticData.location.timeZone == 2 && _staticData.location.environment == 4 &&
+			_staticData.location.node == 5 && _staticData.location.facing == 0 &&
+			_staticData.location.orientation == 1 && _staticData.location.depth == 0)
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myWTSteppedOnFarLedge = 1;
+}
+
+int WalkDualAmbientVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_stepCount >= 0 && newLocation.node != _staticData.location.node) {
+		_vm->_sound->adjustAmbientSoundVolume(_newVolume, true, _stepCount, _volumeChangeTime);
+		_vm->_sound->adjustSecondaryAmbientSoundVolume(_secondVolume, true, _stepCount, _volumeChangeTime);
+	}
+
+	return SC_TRUE;
+}
+
 class SetVolumeAndFlag : public SceneBase {
 public:
 	SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -1146,6 +1346,32 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 88, 288, 116, kItemLimestoneBlock, 84, offsetof(GlobalFlags, myWTRetrievedLimestoneBlock));
 	case 34:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 80, 0, 332, 189, 2, 4, 0, 2, 1, 1, TRANSITION_WALK, -1, 401, 14, 14);
+	case 35:
+		return new WaterGodInitialWalkSetFlag(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 36:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 0, 93, 37, 10, 73, false, 18);
+	case 37:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 166, 259, 37, 10, 73);
+	case 38:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 332, 425, 37, 10, 73);
+	case 39:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 498, 591, 37, 10, 73);
+	case 40:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 664, 757, 37, 10, 73);
+	case 41:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 830, 925, 37, 10, 71, true);
+	case 42:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 999, 1075, 37, 10, 73);
+	case 43:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1149, 1242, 37, 10, 73);
+	case 44:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1315, 1408, 37, 10, 73);
+	case 45:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1481, 1574, 37, 10, 73);
+	case 46:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1647, 1740, 37, 10, 73);
+	case 47:
+		return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1813, 1906, 37, 10, 73);
 	case 50:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation,106, 0, 294, 189, 2, 5, 0, 1, 1, 1, TRANSITION_WALK, -1, 427, 13, 11);
 	case 51:
@@ -1206,6 +1432,12 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4160, 12);
 	case 93:
 		return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 3160, 12);
+	case 100:
+		return new AdjustSecondaryAmbientOnEntry(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 101:
+		return new WalkDualAmbientVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 32, 6900, 12);
+	case 102:
+		return new WalkDualAmbientVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 128, 6900, 12);
 	case 103:
 		return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, 2, 4, 4, 2, 1, 5);
 	case 120:


Commit: 27c82b7174e3810bc40a34667eba9c3c9ddf3cb7
    https://github.com/scummvm/scummvm/commit/27c82b7174e3810bc40a34667eba9c3c9ddf3cb7
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Fix some gcc warnings when compiling with optimization

Changed paths:
    engines/buried/environ/agent3_lair.cpp
    engines/buried/environ/ai_lab.cpp
    engines/buried/graphics.cpp
    engines/buried/scene_view.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 153affb186..4fdbc4e3dd 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -288,8 +288,8 @@ int LairEntry::onCharacter(Window *viewWindow, const Common::KeyState &character
 	if (character.keycode == Common::KEYCODE_DELETE || character.keycode == Common::KEYCODE_BACKSPACE) {
 		if (!_passwordEntered.empty())
 			_passwordEntered.deleteLastChar();
-	} else if (character.keycode == Common::KEYCODE_SPACE || (character.keycode >= Common::KEYCODE_a && character.keycode <= Common::KEYCODE_z) ||
-			(character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9) && _passwordEntered.size() < 15) {
+	} else if ((character.keycode == Common::KEYCODE_SPACE || (character.keycode >= Common::KEYCODE_a && character.keycode <= Common::KEYCODE_z) ||
+			(character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9)) && _passwordEntered.size() < 15) {
 	
 		if (character.keycode == Common::KEYCODE_SPACE)
 			_passwordEntered += ' ';
diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index a443223889..c15fde2ad7 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -3392,7 +3392,7 @@ int MachineRoomHarmonicsInterface::mouseUp(Window *viewWindow, const Common::Poi
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiMRUsedHarmonicsInterface = 1;
 
 		// Play the proper sound effect
-		int fileID;
+		int fileID = -1;
 		switch (_currentSelection) {
 		case 0:
 			fileID = 6;
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 0ba2047adf..3d8c0ec236 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -773,7 +773,7 @@ void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, c
 	Common::StringArray lines;
 	font->wordWrapText(text, w, lines);
 
-	Graphics::TextAlign align;
+	Graphics::TextAlign align = Graphics::kTextAlignLeft;
 	switch (textAlign) {
 	case kTextAlignLeft:
 		align = Graphics::kTextAlignLeft;
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index b7c89eb24a..c77827523c 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1126,7 +1126,7 @@ bool SceneViewWindow::walkTransition(const Location &location, const Destination
 
 bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics::Surface *newBackground, int direction, int stripSize, int totalTime) {
 	// Check the validity of the parameters
-	if (!curBackground || !newBackground || direction < 0 | direction > 4 || stripSize <= 0 || totalTime < 0)
+	if (!curBackground || !newBackground || direction < 0 || direction > 4 || stripSize <= 0 || totalTime < 0)
 		return false;
 
 	// Change the cursor to an hourglass


Commit: 902a9f6dc3854b9c5cc3def689bf4d082c8f9c20
    https://github.com/scummvm/scummvm/commit/902a9f6dc3854b9c5cc3def689bf4d082c8f9c20
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the arrow god heads

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 80cae475d1..a40209319e 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -37,10 +37,15 @@
 #include "buried/environ/scene_base.h"
 #include "buried/environ/scene_common.h"
 
+#include "common/system.h"
 #include "graphics/surface.h"
 
 namespace Buried {
 
+enum {
+	WAR_GOD_HEAD_TIMER_VALUE = 3000
+};
+
 class PlaceCeramicBowl : public SceneBase {
 public:
 	PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -921,6 +926,339 @@ int WaterGodBridgeJump::movieCallback(Window *viewWindow, VideoWindow *movie, in
 	return SC_TRUE;
 }
 
+class ArrowGodHead : public SceneBase {
+public:
+	ArrowGodHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int headID = 0, int clickLeft = -1, int clickTop = -1, int clickRight = -1, int clickBottom = -1,
+			int emptyClosedStill = -1, int emptyOpenStill = -1, int fullClosedStill = -1, int fullOpenStill = -1,
+			int emptyClosedAnim = -1, int emptyOpenAnim = -1, int fullClosedAnim = -1, int fullOpenAnim = -1);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	int _headID;
+	Common::Rect _skullRegion;
+	int _stillFrames[4];
+	int _soundID;
+	int _headAnimations[4];
+};
+
+ArrowGodHead::ArrowGodHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int headID, int clickLeft, int clickTop, int clickRight, int clickBottom,
+		int emptyClosedStill, int emptyOpenStill, int fullClosedStill, int fullOpenStill,
+		int emptyClosedAnim, int emptyOpenAnim, int fullClosedAnim, int fullOpenAnim) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_soundID = -1;
+	_headID = headID;
+	_skullRegion = Common::Rect(clickLeft, clickTop, clickRight, clickBottom);
+	_stillFrames[0] = emptyClosedStill;
+	_stillFrames[1] = emptyOpenStill;
+	_stillFrames[2] = fullClosedStill;
+	_stillFrames[3] = fullOpenStill;
+	_headAnimations[0] = emptyClosedAnim;
+	_headAnimations[1] = emptyOpenAnim;
+	_headAnimations[2] = fullClosedAnim;
+	_headAnimations[3] = fullOpenAnim;
+	_staticData.navFrameIndex = _stillFrames[((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID)];
+}
+
+int ArrowGodHead::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+	byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+	if (_staticData.location.node == 0) {
+		if (headAStatus == 0)
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+		else if (headDStatus == 0)
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
+		else
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+	} else if (_staticData.location.node == 2) {
+		if (headAStatus == 0 || headDStatus == 0)
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+		else
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+	}
+
+	return SC_TRUE;
+}
+
+int ArrowGodHead::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	// For walkthrough mode, don't allow input
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
+		return SC_FALSE;
+
+	if (_skullRegion.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 3) {
+		byte skullIndex = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatusSkullID) + _headID);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatusSkullID) + _headID, 0);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, 1);
+		_staticData.navFrameIndex = _stillFrames[1];
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadATouched) + _headID, 1);
+
+		// Begin dragging
+		Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(skullIndex, ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ArrowGodHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// For walkthrough mode, don't allow input
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
+		return SC_FALSE;
+
+	// Did we click on the head?
+	if (_skullRegion.contains(pointLocation)) {
+		byte headStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadATouched) + _headID, 1);
+
+		if (headStatus & 1)
+			headStatus--;
+		else
+			headStatus++;
+
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, headStatus);
+
+		// Play the proper movie
+		int currentSoundID = -1;
+		if (headStatus == 2)
+			currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
+		else
+			currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128, false, true);
+
+		if ((_headID == 1 || _headID == 2) && headStatus == 0) {
+			if (_staticData.location.node == 0)
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
+			else
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
+		}
+
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_headAnimations[headStatus]);
+
+		_staticData.navFrameIndex = _stillFrames[headStatus];
+		viewWindow->invalidateWindow(false);
+
+		byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+		byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
+		byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
+		byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+		if (_staticData.location.node == 0) {
+			if (headAStatus == 0)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+			else if (headDStatus == 0)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
+			else
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+		} else if (_staticData.location.node == 2) {
+			if (headAStatus == 0 || headDStatus == 0)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+			else
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+		}
+
+		_vm->_sound->stopSoundEffect(currentSoundID);
+
+		if (_staticData.location.node == 0 && (headBStatus < 3 && headCStatus < 3))
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
+		else if (_staticData.location.node == 2 && (headBStatus < 3 && headCStatus < 3))
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
+
+		if (headStatus & 1)
+			((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + _headID * 4, g_system->getMillis());
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ArrowGodHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
+		return 0;
+
+	if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) < 2 && _skullRegion.contains(pointLocation))
+		return 1;
+
+	return 0;
+}
+
+int ArrowGodHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
+		return SIC_REJECT;
+
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 1 && _skullRegion.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, 2);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadATouched) + _headID, 1);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatusSkullID) + _headID, itemID);
+
+		int currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
+
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_headAnimations[2]);
+
+		_staticData.navFrameIndex = _stillFrames[2];
+		viewWindow->invalidateWindow(false);
+
+		byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+		byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+		if (_staticData.location.node == 0) {
+			if (headAStatus == 0)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+			else if (headDStatus == 0)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
+			else
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+		} else if (_staticData.location.node == 2) {
+			if (headAStatus == 0 || headDStatus == 0)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+			else
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+		}
+
+		_vm->_sound->stopSoundEffect(currentSoundID);
+
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int ArrowGodHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
+		return 0;
+
+	if (_skullRegion.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 3)
+			return kCursorOpenHand;
+
+		return kCursorFinger;
+	}
+
+	return 0;
+}
+
+int ArrowGodHead::timerCallback(Window *viewWindow) {
+	for (int i = 0; i < 4; i++) {
+		uint32 lastStartedTimer = ((SceneViewWindow *)viewWindow)->getGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4);
+
+		if (lastStartedTimer > 0 && g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE)) {
+			((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4, 0);
+
+			if (i == _headID) {
+				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+				byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
+
+				if (status & 1) {
+					status--;
+					((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i, status);
+
+					int currentSoundID = -1;
+					if (status == 2)
+						currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
+					else
+						currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128, false, true);
+
+					((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_headAnimations[status]);
+
+					_staticData.navFrameIndex = _stillFrames[status];
+					viewWindow->invalidateWindow(false);
+
+					_vm->_sound->stopSoundEffect(currentSoundID);
+
+					byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+					byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
+					byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
+					byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+					if (_staticData.location.node == 0) {
+						if (headAStatus == 0)
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+						else if (headDStatus == 0)
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
+						else
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+					} else if (_staticData.location.node == 2) {
+						if (headAStatus == 0 || headDStatus == 0)
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+						else
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+					}
+
+					// Play the door closing sound, if applicable
+					if (i == 1 || i == 2) {
+						if (_staticData.location.node == 0 && (headBStatus == 0 || headCStatus == 0))
+							_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
+						else if (_staticData.location.node == 2 && (headBStatus == 0 || headCStatus == 0))
+							_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
+					}
+				}
+
+				((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+				_vm->_gfx->setCursor(oldCursor);
+			} else {
+				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+
+				byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
+
+				if (status & 1) {
+					status--;
+					((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i, status);
+
+					if (status == 2)
+						_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128);
+					else
+						_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+
+					byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+					byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+					if (_staticData.location.node == 0) {
+						if (headAStatus == 0)
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+						else if (headDStatus == 0)
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
+						else
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+					} else if (_staticData.location.node == 2) {
+						if (headAStatus == 0 || headDStatus == 0)
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+						else
+							_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+					}
+				}
+
+				((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+
+				if (_headID == 1 || _headID == 2) {
+					if (_staticData.location.node == 0)
+						_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
+					else if (_staticData.location.node == 2)
+						_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
+				}
+
+				_vm->_gfx->setCursor(oldCursor);
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1382,6 +1720,14 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 201, 4, 235, 22, kItemCopperMedallion, 45, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
 	case 54:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 110, 280, 142, kItemObsidianBlock, 72, offsetof(GlobalFlags, myAGRetrievedObsidianBlock));
+	case 55:
+		return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 0,  182, 87, 242, 189, 4, 75, 83, 79, 0, 2, 1, 3);
+	case 56:
+		return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 1,  194, 89, 256, 189, 10, 76, 84, 80, 4, 6, 5, 7);
+	case 57:
+		return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 2,  178, 93, 246, 189, 28, 77, 85, 81, 8, 10, 9, 11);
+	case 58:
+		return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 3,  188, 92, 252, 189, 34, 78, 86, 82, 12, 14, 13, 15);
 	case 60:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 11);
 	case 65:


Commit: 423c702c9bac9e84169955b8bd3d740a7804d048
    https://github.com/scummvm/scummvm/commit/423c702c9bac9e84169955b8bd3d740a7804d048
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the spear room puzzle

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index a40209319e..a9b8c9ec0b 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -1259,6 +1259,225 @@ int ArrowGodHead::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class ArrowGodDepthChange : public SceneBase {
+public:
+	ArrowGodDepthChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	bool _scheduledDepthChange;
+	int _soundID;
+
+	bool adjustSpearVolume(Window *viewWindow);
+};
+
+ArrowGodDepthChange::ArrowGodDepthChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_scheduledDepthChange = false;
+	_soundID = -1;
+
+	byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+	byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
+	byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
+	byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+	int targetDepth = 0;
+
+	if (headBStatus > 0 || headCStatus > 0) {
+		if (headBStatus > 0) {
+			if (headAStatus == 0 || headDStatus == 0) {
+				if (headAStatus == 0 && headDStatus == 0) {
+					targetDepth = 11;
+				} else if (headAStatus > 0 && headDStatus == 0) {
+					targetDepth = 10;
+				} else if (headAStatus == 0 && headDStatus > 0) {
+					targetDepth = 9;
+				}
+			} else {
+				targetDepth = 8;
+			}
+		} else if (headCStatus > 0) {
+			if (headAStatus == 0 || headDStatus == 0) {
+				if (headAStatus == 0 && headDStatus == 0) {
+					targetDepth = 7;
+				} else if (headAStatus > 0 && headDStatus == 0) {
+					targetDepth = 6;
+				} else if (headAStatus == 0 && headDStatus > 0) {
+					targetDepth = 5;
+				}
+			} else {
+				targetDepth = 4;
+			}
+		}
+	} else if (headAStatus == 0 || headDStatus == 0) {
+		if (headAStatus == 0 && headBStatus == 0) {
+			targetDepth = 3;
+		} else {
+			if (headAStatus > 0 && headDStatus == 0) {
+				targetDepth = 2;
+			} else if (headAStatus == 0 && headDStatus > 0) {
+				targetDepth = 1;
+			}
+		}
+	}
+
+	if (_staticData.location.depth != targetDepth) {
+		Location newLocation = _staticData.location;
+		newLocation.depth = targetDepth;
+		((SceneViewWindow *)viewWindow)->getSceneStaticData(newLocation, _staticData);
+		_frameCycleCount = _staticData.cycleStartFrame;
+
+		// Reload the frame files, if applicable
+		((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
+
+		if (_staticData.cycleStartFrame >= 0)
+			((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
+	}
+}
+
+int ArrowGodDepthChange::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((priorLocation.depth >= 8 && priorLocation.depth <= 11) && _staticData.location.depth < 8) ||
+			((priorLocation.depth >= 4 && priorLocation.depth <= 7) && _staticData.location.depth < 4)) {
+		byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
+		byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
+		byte &headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+		byte doorLevelVolume = 0;
+
+		switch (_staticData.location.node) {
+		case 0:
+		case 1:
+			doorLevelVolume = 127;
+			break;
+		case 2:
+			doorLevelVolume = 96;
+
+			if (headDStatus == 2) {
+				headDStatus--;
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
+				_scheduledDepthChange = true;
+				adjustSpearVolume(viewWindow);
+				((SceneViewWindow *)viewWindow)->jumpToScene(_staticData.location);
+				return SC_TRUE; // Original does not return here, but the status of this would be bad in that case
+			}
+			break;
+		case 3:
+			if (headCStatus == 0)
+				doorLevelVolume = 127;
+			else if (headBStatus == 0)
+				doorLevelVolume = 64;
+			break;
+		}
+
+		if (doorLevelVolume > 0)
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), doorLevelVolume);
+	}
+
+	adjustSpearVolume(viewWindow);
+	return SC_TRUE;
+}
+
+int ArrowGodDepthChange::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.timeZone == newLocation.timeZone &&
+			_staticData.location.environment == newLocation.environment &&
+			_staticData.location.node == newLocation.node &&
+			_staticData.location.facing == newLocation.facing &&
+			_staticData.location.orientation == newLocation.orientation &&
+			_staticData.location.depth == newLocation.depth &&
+			!_scheduledDepthChange) {
+		// Notify the player of his gruesome death
+		((SceneViewWindow *)viewWindow)->showDeathScene(13);
+		return SC_DEATH;
+	}
+
+	return SC_TRUE;
+}
+
+int ArrowGodDepthChange::timerCallback(Window *viewWindow) {
+	SceneBase::timerCallback(viewWindow);
+
+	// Check to see if we moved into a death scene
+	if (_staticData.location.timeZone == 2 && _staticData.location.environment == 5 &&
+			_staticData.location.node == 1 && _staticData.location.facing == 3 &&
+			_staticData.location.orientation == 1 && (_staticData.location.depth == 1 ||
+			_staticData.location.depth == 3 || _staticData.location.depth == 11 ||
+			_staticData.location.depth == 7 || _staticData.location.depth == 5 ||
+			_staticData.location.depth == 9)) {
+		if (_staticData.location.depth == 1)
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(19);
+
+		((SceneViewWindow *)viewWindow)->showDeathScene(13);
+		return SC_DEATH;
+	}
+
+	if (_staticData.location.timeZone == 2 && _staticData.location.environment == 5 &&
+			_staticData.location.node == 3 && _staticData.location.facing == 3 &&
+			_staticData.location.orientation == 1 && (_staticData.location.depth == 2 ||
+			_staticData.location.depth == 3 || _staticData.location.depth == 11 ||
+			_staticData.location.depth == 10 || _staticData.location.depth == 6 ||
+			_staticData.location.depth == 7)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(17);
+		((SceneViewWindow *)viewWindow)->showDeathScene(13);
+		return SC_DEATH;
+	}
+
+	// Loop through the four heads
+	for (int i = 0; i < 4; i++) {
+		uint32 lastStartedTimer = ((SceneViewWindow *)viewWindow)->getGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4);
+
+		// Check if there is a timer going for this head
+		if (lastStartedTimer > 0 && (g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE) ||
+				i == 0 || (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && i == 1) ||
+				(((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i) == 2 && i == 3))) {
+			((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4, 0);
+			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+			byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
+
+			if (status & 1) {
+				status--;
+				((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i, status);
+				_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, (status == 2) ? 14 : 13), 128);
+				_scheduledDepthChange = true;
+				adjustSpearVolume(viewWindow);
+			}
+
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+			_vm->_gfx->setCursor(oldCursor);
+		}
+	}
+
+	if (_scheduledDepthChange) {
+		_scheduledDepthChange = false;
+		Location location = _staticData.location;
+		((SceneViewWindow *)viewWindow)->jumpToScene(location);
+	}
+
+	return SC_TRUE;
+}
+
+bool ArrowGodDepthChange::adjustSpearVolume(Window *viewWindow) {
+	// TODO: Looks like there's a bug in the original. node == 3 should also be in here, I think
+	// Need to investigate
+	if (_staticData.location.node >= 0 && _staticData.location.node <= 2) {
+		byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
+		byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
+
+		if (headAStatus == 0) {
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+		} else if (headDStatus == 0) {
+			if (_staticData.location.node == 2)
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
+			else
+				_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
+		} else {
+			_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
+		}
+	}
+
+	return true;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1728,6 +1947,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 2,  178, 93, 246, 189, 28, 77, 85, 81, 8, 10, 9, 11);
 	case 58:
 		return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 3,  188, 92, 252, 189, 34, 78, 86, 82, 12, 14, 13, 15);
+	case 59:
+		return new ArrowGodDepthChange(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 60:
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 11);
 	case 65:


Commit: 069b6d7b1065501cd271193630b29f45645e1e0a
    https://github.com/scummvm/scummvm/commit/069b6d7b1065501cd271193630b29f45645e1e0a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the death god door

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index a9b8c9ec0b..bde701561a 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -736,6 +736,163 @@ bool GenericCavernDoorOfferingHead::isValidItemToDrop(Window *viewWindow, int it
 	return false;
 }
 
+class DeathGodCavernDoorOfferingHead : public SceneBase {
+public:
+	DeathGodCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int correctOfferingDestDepth = 0, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	DestinationScene _correctDestination;
+	Common::Rect _dropRegion;
+};
+
+DeathGodCavernDoorOfferingHead::DeathGodCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int correctOfferingDestDepth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_correctDestination.destinationScene = _staticData.location;
+	_correctDestination.destinationScene.depth = correctOfferingDestDepth;
+	_correctDestination.transitionType = transitionType;
+	_correctDestination.transitionData = transitionData;
+	_correctDestination.transitionStartFrame = transitionStartFrame;
+	_correctDestination.transitionLength = transitionLength;
+	_dropRegion = Common::Rect(50, 76, 228, 182);
+
+	byte offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
+
+	if (offerings & 1) {
+		if (offerings & 2) {
+			if (offerings & 4)
+				_staticData.navFrameIndex = 190;
+			else
+				_staticData.navFrameIndex = 189;
+		} else if (offerings & 4) {
+			_staticData.navFrameIndex = 188;
+		} else {
+			_staticData.navFrameIndex = 186;
+		}
+	} else if (offerings & 2) {
+		if (offerings & 4)
+			_staticData.navFrameIndex = 187;
+		else
+			_staticData.navFrameIndex = 185;
+	} else if (offerings & 4) {
+		_staticData.navFrameIndex = 184;
+	}
+}
+
+int DeathGodCavernDoorOfferingHead::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	// Put any pieces placed in the head back in the inventory
+	byte &offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
+
+	if (offerings & 1)
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemObsidianBlock);
+	if (offerings & 2)
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemJadeBlock);
+	if (offerings & 4)
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemLimestoneBlock);
+
+	offerings = 0;
+	return SC_TRUE;
+}
+
+int DeathGodCavernDoorOfferingHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	// Return to depth zero
+	DestinationScene newDest;
+	newDest.destinationScene = _staticData.location;
+	newDest.destinationScene.depth = 0;
+	newDest.transitionType = TRANSITION_NONE;
+	newDest.transitionData = -1;
+	newDest.transitionStartFrame = -1;
+	newDest.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
+	return SC_TRUE;
+}
+
+int DeathGodCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
+		byte offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
+
+		if ((offerings & 1) != 0 && itemID == kItemObsidianBlock)
+			return 0;
+		if ((offerings & 2) != 0 && itemID == kItemJadeBlock)
+			return 0;
+		if ((offerings & 4) != 0 && itemID == kItemLimestoneBlock)
+			return 0;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+int DeathGodCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
+		byte &offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
+
+		// Make sure we didn't already place the item
+		if ((offerings & 1) != 0 && itemID == kItemObsidianBlock)
+			return SIC_REJECT;
+		if ((offerings & 2) != 0 && itemID == kItemJadeBlock)
+			return SIC_REJECT;
+		if ((offerings & 4) != 0 && itemID == kItemLimestoneBlock)
+			return SIC_REJECT;
+
+		// Add the item
+		if (itemID == kItemObsidianBlock)
+			offerings |= 1;
+		else if (itemID == kItemJadeBlock)
+			offerings |= 2;
+		else if (itemID == kItemLimestoneBlock)
+			offerings |= 4;
+
+		// Change the image
+		if (offerings & 1) {
+			if (offerings & 2) {
+				if (offerings & 4)
+					_staticData.navFrameIndex = 190;
+				else
+					_staticData.navFrameIndex = 189;
+			} else if (offerings & 4) {
+				_staticData.navFrameIndex = 188;
+			} else {
+				_staticData.navFrameIndex = 186;
+			}
+		} else if (offerings & 2) {
+			if (offerings & 4)
+				_staticData.navFrameIndex = 187;
+			else
+				_staticData.navFrameIndex = 185;
+		} else if (offerings & 4) {
+			_staticData.navFrameIndex = 184;
+		} else {
+			_staticData.navFrameIndex = 152;
+		}
+
+		viewWindow->invalidateWindow(false);
+
+		if ((offerings & 1) != 0 && (offerings & 2) != 0 && (offerings & 4) != 0) {
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
+			((SceneViewWindow *)viewWindow)->moveToDestination(_correctDestination);
+		}
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int DeathGodCavernDoorOfferingHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	return kCursorPutDown;
+}
+
 class WealthGodRopeDrop : public SceneBase {
 public:
 	WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1893,6 +2050,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
 	case 28:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransDGOffering));
+	case 29:
+		return new DeathGodCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, 4, TRANSITION_WALK, -1, 1010, 12);
 	case 30:
 		return new WealthGodRopeDrop(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 31:


Commit: ed0e8368f58f2b7bcc59b6224d7002818050f528
    https://github.com/scummvm/scummvm/commit/ed0e8368f58f2b7bcc59b6224d7002818050f528
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the death god altar

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index bde701561a..bce90cb339 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -1635,6 +1635,136 @@ bool ArrowGodDepthChange::adjustSpearVolume(Window *viewWindow) {
 	return true;
 }
 
+class DeathGodAltar : public SceneBase {
+public:
+	DeathGodAltar(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _heartPool;
+	Common::Rect _puzzleBox;
+	Common::Rect _blood;
+};
+
+DeathGodAltar::DeathGodAltar(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_heartPool = Common::Rect(89, 80, 159, 112);
+	_puzzleBox = Common::Rect(150, 45, 260, 111);
+	_blood = Common::Rect(88, 76, 162, 114);
+}
+
+int DeathGodAltar::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1) {
+		if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART)) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+			_staticData.navFrameIndex = 51;
+			viewWindow->invalidateWindow(false);
+
+			if ((_staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment ||
+					_staticData.location.node != priorLocation.node || _staticData.location.facing != priorLocation.facing ||
+					_staticData.location.orientation != priorLocation.orientation || _staticData.location.depth != priorLocation.depth) &&
+					!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+		}
+	} else if ((_staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment ||
+			_staticData.location.node != priorLocation.node || _staticData.location.facing != priorLocation.facing ||
+			_staticData.location.orientation != priorLocation.orientation || _staticData.location.depth != priorLocation.depth) &&
+			!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_PHONY_BLOOD)) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+	}
+
+	return SC_TRUE;
+}
+
+int DeathGodAltar::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_puzzleBox.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0) {
+		Location puzzleLocation = _staticData.location;
+		puzzleLocation.depth = 1;
+		((SceneViewWindow *)viewWindow)->jumpToScene(puzzleLocation);
+	}
+
+	return SC_FALSE;
+}
+
+int DeathGodAltar::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemPreservedHeart && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 0 && _heartPool.contains(pointLocation))
+		return 1;
+
+	return 0;
+}
+
+int DeathGodAltar::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (itemID == kItemPreservedHeart && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 0 && _heartPool.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart = 1;
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+		_staticData.navFrameIndex = 51;
+
+		if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART))
+			((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int DeathGodAltar::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1 &&
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0 &&
+				_staticData.navFrameIndex == 51 && _puzzleBox.contains(pointLocation))
+			return -2;
+
+		if (_blood.contains(pointLocation))
+			return -2;
+
+		return -1;
+	} else if (_puzzleBox.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0) {
+		// This logic is broken in 1.04, 1.05, and 1.10. I fixed it here to match mouseUp
+		return kCursorFinger;
+	}
+
+	return kCursorArrow;
+}
+
+int DeathGodAltar::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 &&
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0 &&
+			_puzzleBox.contains(pointLocation) && _staticData.navFrameIndex == 51 &&
+			!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART)) {
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED)); // All will be reveaaaaaaaaled (Yes, I used this joke twice now)
+		return SC_TRUE;
+	}
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
+		if (_blood.contains(pointLocation)) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
+
+			// Attempt to add it to the biochip
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, MAYAN_EVIDENCE_PHONY_BLOOD))
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Disable capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2112,6 +2242,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 11);
 	case 65:
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 90, 15, 346, 189, 2, 6, 0, 0, 1, 1, TRANSITION_WALK, -1, 33, 12, 13);
+	case 66:
+		return new DeathGodAltar(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 68:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 76, 246, 116, kItemEnvironCart, 53, offsetof(GlobalFlags, takenEnvironCart));
 	case 69:


Commit: 071d870a9e59105119c3ce5857b158c9a5f364b0
    https://github.com/scummvm/scummvm/commit/071d870a9e59105119c3ce5857b158c9a5f364b0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the Mayan puzzle box... puzzle

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index bce90cb339..1a3182c528 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -1765,6 +1765,236 @@ int DeathGodAltar::locateAttempted(Window *viewWindow, const Common::Point &poin
 	return SC_FALSE;
 }
 
+class DeathGodPuzzleBox : public SceneBase {
+public:
+	DeathGodPuzzleBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~DeathGodPuzzleBox();
+	void preDestructor();
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	int gdiPaint(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _puzzleIndexes[4];
+	Common::Rect _clickableRegions[4];
+	Common::Rect _puzzleRightHandle;
+	AVIFrames _puzzleFrames[4];
+	bool _translateText;
+
+	bool isPuzzleSolved() const;
+};
+
+DeathGodPuzzleBox::DeathGodPuzzleBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_translateText = false;
+	_puzzleIndexes[0] = _puzzleIndexes[1] = _puzzleIndexes[2] = _puzzleIndexes[3] = 0;
+	_clickableRegions[0] = Common::Rect(30, 0, 111, 189);
+	_clickableRegions[1] = Common::Rect(112, 0, 187, 189);
+	_clickableRegions[2] = Common::Rect(188, 0, 252, 189);
+	_clickableRegions[3] = Common::Rect(253, 0, 330, 189);
+	_puzzleRightHandle = Common::Rect(380, 0, 432, 189);
+
+	// Load the spinner movies
+	_puzzleFrames[0].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 4));
+	_puzzleFrames[1].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 5));
+	_puzzleFrames[2].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 6));
+	_puzzleFrames[3].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7));
+}
+
+DeathGodPuzzleBox::~DeathGodPuzzleBox() {
+	preDestructor();
+}
+
+void DeathGodPuzzleBox::preDestructor() {
+	_puzzleFrames[0].close();
+	_puzzleFrames[1].close();
+	_puzzleFrames[2].close();
+	_puzzleFrames[3].close();
+}
+
+int DeathGodPuzzleBox::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	SceneBase::paint(viewWindow, preBuffer);
+
+	for (int i = 0; i < 4; i++) {
+		const Graphics::Surface *spinnerFrame = _puzzleFrames[i].getFrame(_puzzleIndexes[i]);
+		_vm->_gfx->crossBlit(preBuffer, _clickableRegions[i].left, _clickableRegions[i].top, _clickableRegions[i].width(), _clickableRegions[i].height(), spinnerFrame, 0, 0);
+	}
+
+	return SC_REPAINT;
+}
+
+int DeathGodPuzzleBox::gdiPaint(Window *viewWindow) {
+	if (_translateText && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(42, 64, 324, 125);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int DeathGodPuzzleBox::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 4; i++) {
+		if (_clickableRegions[i].contains(pointLocation)) {
+			if (pointLocation.y - _clickableRegions[i].top > _clickableRegions[i].height() / 2) {
+				// Start the roll sound
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
+
+				// Spin the wheel, stop at the new value
+				// FIXME: Timing
+				for (int j = 0; j < 6; j++) {
+					_puzzleIndexes[i]--;
+					if (_puzzleIndexes[i] < 0)
+						_puzzleIndexes[i] = _puzzleFrames[i].getFrameCount() - 2;
+					viewWindow->invalidateWindow();
+					_vm->_gfx->updateScreen();
+				}
+
+				_translateText = false;
+				mouseMove(viewWindow, pointLocation);
+			} else {
+				// Start the roll sound
+				_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
+
+				// Spin the wheel, stop at the new value
+				// FIXME: Timing
+				for (int j = 0; j < 6; j++) {
+					_puzzleIndexes[i]++;
+					if (_puzzleIndexes[i] > _puzzleFrames[i].getFrameCount() - 2)
+						_puzzleIndexes[i] = 0;
+					viewWindow->invalidateWindow();
+					_vm->_gfx->updateScreen();
+				}
+
+				_translateText = false;
+				mouseMove(viewWindow, pointLocation);
+			}
+		}
+	}
+
+	if (_puzzleRightHandle.contains(pointLocation)) {
+		if (isPuzzleSolved()) {
+			DestinationScene newDestination;
+			newDestination.destinationScene = _staticData.location;
+			newDestination.destinationScene.depth = 2;
+			newDestination.transitionType = TRANSITION_VIDEO;
+			newDestination.transitionStartFrame = -1;
+			newDestination.transitionLength = -1;
+
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0)
+				newDestination.transitionData = 4;
+			else
+				newDestination.transitionData = 5;
+
+			BuriedEngine *vm = _vm;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
+
+			// Play animation capturing the evidence
+			// FIXME: Is this right? Shouldn't this be if takenEnvironCart == 0 only?
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
+
+			// Attempt to add it to the biochip
+			if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, MAYAN_EVIDENCE_ENVIRON_CART))
+				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
+			else
+				((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
+
+			// Disable capture
+			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
+
+			// Set the scoring flag
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreCompletedDeathGod = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOpenedPuzzleBox = 1;
+
+			// Play an Arthur comment
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0 && ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
+				vm->_sound->playSoundEffect("BITDATA/MAYAN/MYDG_C01.BTA"); // Broken in 1.01
+
+			return SC_TRUE;
+		} else {
+			// We did the puzzle incorrectly, so spin the wheels and kill the player
+			((SceneViewWindow *)viewWindow)->playPlacedSynchronousAnimation(8, 320, 0);
+			((SceneViewWindow *)viewWindow)->showDeathScene(12);
+			return SC_DEATH;
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int DeathGodPuzzleBox::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect translateTextRegion(42, 64, 324, 126);
+
+		if (translateTextRegion.contains(pointLocation)) {
+			if (!_translateText) {
+				Common::String translatedText = _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + _puzzleIndexes[0] / 6);
+				translatedText += ' ';
+				translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 10 + _puzzleIndexes[1] / 6);
+				translatedText += ' ';
+				translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 20 + _puzzleIndexes[2] / 6);
+				translatedText += ' ';
+				translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 30 + _puzzleIndexes[3] / 6);
+
+				((SceneViewWindow *)viewWindow)->displayTranslationText(translatedText);
+
+				_translateText = true;
+				viewWindow->invalidateWindow(false);
+			}
+		} else {
+			if (_translateText) {
+				_translateText = false;
+				viewWindow->invalidateWindow(false);
+			}
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int DeathGodPuzzleBox::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 4; i++) {
+		if (_clickableRegions[i].contains(pointLocation)) {
+			if (pointLocation.y - _clickableRegions[i].top > _clickableRegions[i].height() / 2)
+				return kCursorArrowDown;
+
+			return kCursorArrowUp;
+		}
+	}
+
+	if (_puzzleRightHandle.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+bool DeathGodPuzzleBox::isPuzzleSolved() const {
+	// TODO: Ask players for solutions for other languages
+	// clone2727 only has the English, French, and Japanese source
+
+	switch (_vm->getLanguage()) {
+	case Common::DE_DEU:
+		return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 24;
+	case Common::EN_ANY:
+		return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;
+	case Common::FR_FRA:
+		return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 42 && _puzzleIndexes[3] == 24;
+	case Common::JA_JPN:
+		return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 24 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 18;
+	default:
+		// Default to English, but warn about it
+		warning("Unknown language for puzzle box");
+		return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;
+	}
+
+	return false;
+}
+
 class MainCavernGlassCapture : public SceneBase {
 public:
 	MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -2244,6 +2474,8 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 90, 15, 346, 189, 2, 6, 0, 0, 1, 1, TRANSITION_WALK, -1, 33, 12, 13);
 	case 66:
 		return new DeathGodAltar(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 67:
+		return new DeathGodPuzzleBox(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 68:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 76, 246, 116, kItemEnvironCart, 53, offsetof(GlobalFlags, takenEnvironCart));
 	case 69:


Commit: 4f563aff73c5ff253d3696f7491384bbf41275ad
    https://github.com/scummvm/scummvm/commit/4f563aff73c5ff253d3696f7491384bbf41275ad
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Fix frame cycling in the Agent 3 lair entry segment

Changed paths:
    engines/buried/environ/agent3_lair.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 4fdbc4e3dd..a42da8ac25 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -66,6 +66,9 @@ LairEntry::LairEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticD
 	_rawStepDelay = 15000;
 	_flickerOn = ((SceneViewWindow *)viewWindow)->getCyclingStatus();
 	((SceneViewWindow *)viewWindow)->enableCycling(true);
+
+	// Force load the cycle file
+	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
 }
 
 int LairEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {


Commit: 270b7768878f6e0e5453d8d50fdc305d0f0906bd
    https://github.com/scummvm/scummvm/commit/270b7768878f6e0e5453d8d50fdc305d0f0906bd
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement replacing the generator core

Changed paths:
    engines/buried/environ/agent3_lair.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index a42da8ac25..e880281e62 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -396,6 +396,166 @@ int LairEntry::onCharacter(Window *viewWindow, const Common::KeyState &character
 	return SC_TRUE;
 }
 
+class GeneratorCoreZoom : public SceneBase {
+public:
+	GeneratorCoreZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickableArea;
+};
+
+GeneratorCoreZoom::GeneratorCoreZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alRDTakenDeadCore == 1)
+		_staticData.navFrameIndex = 82;
+
+	_clickableArea = Common::Rect(42, 34, 132, 116);
+}
+
+int GeneratorCoreZoom::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableArea.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alRDTakenDeadCore == 1)
+			newScene.transitionData = 7;
+		else
+			newScene.transitionData = 6;
+
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int GeneratorCoreZoom::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickableArea.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class GeneratorCoreAcquire : public SceneBase {
+public:
+	GeneratorCoreAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _currentStatus;
+	Common::Rect _deadCore;
+	Common::Rect _closedEmpty;
+};
+
+GeneratorCoreAcquire::GeneratorCoreAcquire(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alRDTakenDeadCore == 1) {
+		_staticData.navFrameIndex = 80;
+		_currentStatus = 2;
+	} else {
+		_currentStatus = 0;
+	}
+
+	_deadCore = Common::Rect(167, 0, 257, 138);
+	_closedEmpty = Common::Rect(181, 76, 257, 132);
+}
+
+int GeneratorCoreAcquire::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_currentStatus == 1 && _deadCore.contains(pointLocation)) {
+		_staticData.navFrameIndex = 80;
+		_currentStatus = 2;
+		viewWindow->invalidateWindow(false);
+
+		// Taken the core
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().alRDTakenDeadCore = 1;
+
+		Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(kItemBurnedOutCore, ptInventoryWindow);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int GeneratorCoreAcquire::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_currentStatus == 0 && _closedEmpty.contains(pointLocation)) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+		_staticData.navFrameIndex = 77;
+		_currentStatus = 1;
+		return SC_TRUE;
+	}
+
+	DestinationScene newScene;
+	newScene.destinationScene = _staticData.location;
+	newScene.destinationScene.depth = 0;
+	newScene.transitionType = TRANSITION_NONE;
+	newScene.transitionData = -1;
+	newScene.transitionStartFrame = -1;
+	newScene.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+	return SC_TRUE;
+}
+
+int GeneratorCoreAcquire::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (_currentStatus == 2 && (itemID == kItemGeneratorCore || itemID == kItemBurnedOutCore) && _closedEmpty.contains(pointLocation))
+		return 1;
+
+	return 0; // Original had a nice bug here returning the put down cursor
+}
+
+int GeneratorCoreAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (pointLocation.x == -1 && pointLocation.y == -1)
+		return 0;
+
+	if (_currentStatus == 2 && (itemID == kItemGeneratorCore || itemID == kItemBurnedOutCore) && _closedEmpty.contains(pointLocation)) {
+		if (itemID == kItemBurnedOutCore) {
+			// Change background and status
+			_staticData.navFrameIndex = 77;
+			_currentStatus = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().alRDTakenDeadCore = 0;
+			viewWindow->invalidateWindow(false);
+		} else if (itemID == kItemGeneratorCore) {
+			_staticData.navFrameIndex = 79;
+
+			// Move to the new scene
+			DestinationScene newScene;
+			newScene.destinationScene = _staticData.location;
+			newScene.destinationScene.depth = 0;
+			newScene.destinationScene.environment = 2;
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionData = 8;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		}
+
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int GeneratorCoreAcquire::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_currentStatus == 0 && _closedEmpty.contains(pointLocation))
+		return kCursorFinger;
+
+	if (_currentStatus == 1 && _deadCore.contains(pointLocation))
+		return kCursorOpenHand;
+
+	return kCursorPutDown;
+}
+
 bool SceneViewWindow::initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1)
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode = 0;
@@ -414,6 +574,10 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 177, 96, 231, 184, kItemGeneratorCore, 15, offsetof(GlobalFlags, alRDTakenLiveCore));
+	case 2:
+		return new GeneratorCoreZoom(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 3:
+		return new GeneratorCoreAcquire(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 10:
 		return new LairEntry(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 20:


Commit: 7879a8c810b822229db5dc407731b6dc6bdf7a1b
    https://github.com/scummvm/scummvm/commit/7879a8c810b822229db5dc407731b6dc6bdf7a1b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the replicator

Changed paths:
    engines/buried/environ/agent3_lair.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index e880281e62..507e7a09c8 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -396,6 +396,90 @@ int LairEntry::onCharacter(Window *viewWindow, const Common::KeyState &character
 	return SC_TRUE;
 }
 
+class ReplicatorInterface : public SceneBase {
+public:
+	ReplicatorInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _currentItem;
+	Common::Rect _runProgram, _scrollUp, _scrollDown;
+};
+
+ReplicatorInterface::ReplicatorInterface(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_currentItem = 0;
+	_runProgram = Common::Rect(140, 45, 228, 67);
+	_scrollUp = Common::Rect(253, 61, 277, 83);
+	_scrollDown = Common::Rect(253, 83, 277, 105);
+}
+
+int ReplicatorInterface::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == _staticData.location.timeZone && newLocation.environment == _staticData.location.environment)
+		_vm->_sound->playSoundEffect("BITDATA/AGENT3/ALNMRCLS.BTA");
+
+	return SC_TRUE;
+}
+
+int ReplicatorInterface::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_runProgram.contains(pointLocation)) {
+		_vm->_sound->playSynchronousSoundEffect("BITDATA/COMMON/GENB14.BTA");
+
+		switch (_currentItem) {
+		case 1:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
+			break;
+		case 2:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
+			break;
+		case 3:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(1);
+			break;
+		case 4:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
+			break;
+		}
+
+		_staticData.navFrameIndex = 76;
+		_currentItem = 0;
+		viewWindow->invalidateWindow(false);
+		return SC_TRUE;
+	}
+
+	if (_scrollUp.contains(pointLocation)) {
+		_currentItem++;
+		if (_currentItem > 4)
+			_currentItem = 1;
+
+		_staticData.navFrameIndex = _currentItem + 76;
+		viewWindow->invalidateWindow(false);
+		_vm->_sound->playSynchronousSoundEffect("BITDATA/COMMON/GENB14.BTA");
+		return SC_TRUE;
+	}
+
+	if (_scrollDown.contains(pointLocation)) {
+		_currentItem--;
+		if (_currentItem < 1)
+			_currentItem = 4;
+
+		_staticData.navFrameIndex = _currentItem + 76;
+		viewWindow->invalidateWindow(false);
+		_vm->_sound->playSynchronousSoundEffect("BITDATA/COMMON/GENB14.BTA");
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ReplicatorInterface::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_runProgram.contains(pointLocation) || _scrollUp.contains(pointLocation) || _scrollDown.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class GeneratorCoreZoom : public SceneBase {
 public:
 	GeneratorCoreZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -582,6 +666,8 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 		return new LairEntry(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 20:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 36, 15, 396, 189, kCursorFinger, 3, 2, 0, 1, 1, 1, TRANSITION_VIDEO, 0, -1, -1);
+	case 21:
+		return new ReplicatorInterface(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 25:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 150, 24, 280, 124, kCursorFinger, 3, 2, 4, 0, 1, 1, TRANSITION_VIDEO, 6, -1, -1);
 	}


Commit: a2c2042a12d9f3b1274c9f623aa49c3785059d6d
    https://github.com/scummvm/scummvm/commit/a2c2042a12d9f3b1274c9f623aa49c3785059d6d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement the environ system nature scenes

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 8e81d5bfdf..2bc06d9989 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1746,6 +1746,50 @@ int ClickOnBooks::specifyCursor(Window *viewWindow, const Common::Point &pointLo
 	return kCursorArrow;
 }
 
+class ClickEnvironNatureScenes : public SceneBase {
+public:
+	ClickEnvironNatureScenes(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _controls;
+};
+
+ClickEnvironNatureScenes::ClickEnvironNatureScenes(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_controls = Common::Rect(0, 160, 432, 189);
+	_staticData.navFrameIndex = 52;
+}
+
+int ClickEnvironNatureScenes::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 4;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	// Update the image
+	_staticData.navFrameIndex++;
+	if (_staticData.navFrameIndex > 54)
+		_staticData.navFrameIndex = 52;
+	viewWindow->invalidateWindow(false);
+	return SC_TRUE;
+}
+
+int ClickEnvironNatureScenes::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_controls.contains(pointLocation))
+		return kCursorPutDown;
+
+	return kCursorArrow;
+}
+
 class ViewEnvironCart : public SceneBase {
 public:
 	ViewEnvironCart(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -1909,6 +1953,8 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 163, 25, 273, 145, kCursorMagnifyingGlass, 4, 2, 2, 0, 1, 2, TRANSITION_VIDEO, 1, -1, -1);
 	case 17:
 		return new EnvironSystemControls(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 18:
+		return new ClickEnvironNatureScenes(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 20:
 		return new ViewEnvironCart(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 21:


Commit: 2333f6f12c68682344d03ec5f0fdce8b72a9f43a
    https://github.com/scummvm/scummvm/commit/2333f6f12c68682344d03ec5f0fdce8b72a9f43a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:42+01:00

Commit Message:
BURIED: Implement Geno's music video

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 2bc06d9989..4c30fa391f 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1039,6 +1039,58 @@ int EnvironSystemControls::specifyCursor(Window *viewWindow, const Common::Point
 	return kCursorPutDown;
 }
 
+class EnvironGenoVideo : public SceneBase {
+public:
+	EnvironGenoVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _returnRegion;
+};
+
+EnvironGenoVideo::EnvironGenoVideo(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_returnRegion = Common::Rect(136, 150, 292, 189);
+}
+
+int EnvironGenoVideo::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_vm->_sound->stop();
+	((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(13, false);
+	return SC_TRUE;
+}
+
+int EnvironGenoVideo::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+	_vm->_sound->restart();
+	return SC_TRUE;
+}
+
+int EnvironGenoVideo::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_returnRegion.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 4;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int EnvironGenoVideo::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_returnRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class FlagChangeBackground : public SceneBase {
 public:
 	FlagChangeBackground(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -1955,6 +2007,8 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new EnvironSystemControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 18:
 		return new ClickEnvironNatureScenes(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 19:
+		return new EnvironGenoVideo(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 20:
 		return new ViewEnvironCart(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 21:


Commit: 2d0d6e82276d779b6d8dd3b76da9bfcc3594d30f
    https://github.com/scummvm/scummvm/commit/2d0d6e82276d779b6d8dd3b76da9bfcc3594d30f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the interactive news network

Changed paths:
    engines/buried/environ/agent3_lair.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 507e7a09c8..4b9a93e168 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -670,6 +670,8 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 		return new ReplicatorInterface(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 25:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 150, 24, 280, 124, kCursorFinger, 3, 2, 4, 0, 1, 1, TRANSITION_VIDEO, 6, -1, -1);
+	case 29:
+		return new InteractiveNewsNetwork(_vm, viewWindow, sceneStaticData, priorLocation, -1, 3, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 17, -1, -1);
 	}
 
 	warning("TODO: Agent 3 lair scene object %d", sceneStaticData.classID);
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 4c30fa391f..3a744ed4c4 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -2013,6 +2013,8 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new ViewEnvironCart(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 21:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 0, 0, 432, 189, kCursorPutDown, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 4, -1, -1);
+	case 22:
+		return new InteractiveNewsNetwork(_vm, viewWindow, sceneStaticData, priorLocation, -1, 4, 2, 2, 0, 1, 1, TRANSITION_VIDEO, 4, -1, -1);
 	case 23:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 81, 146, 134, 189, kItemRemoteControl, 45, offsetof(GlobalFlags, faERTakenRemoteControl));
 	case 24:
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index f174814e8f..88e5a424d3 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -447,6 +447,283 @@ SetFlagOnEntry::SetFlagOnEntry(BuriedEngine *vm, Window *viewWindow, const Locat
 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagOffset, flagNewValue);
 }
 
+InteractiveNewsNetwork::InteractiveNewsNetwork(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int enterTransition, int timeZone, int environment, int node, int facing, int orientation, int depth,
+		int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	// Close the cycle/still movies
+	((SceneViewWindow *)viewWindow)->changeStillFrameMovie("");
+	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie("");
+
+	_currentMovieFrame = 0;
+	_returnDestination.destinationScene.timeZone = timeZone;
+	_returnDestination.destinationScene.environment = environment;
+	_returnDestination.destinationScene.node = node;
+	_returnDestination.destinationScene.facing = facing;
+	_returnDestination.destinationScene.orientation = orientation;
+	_returnDestination.destinationScene.depth = depth;
+	_returnDestination.transitionType = transitionType;
+	_returnDestination.transitionData = transitionData;
+	_returnDestination.transitionStartFrame = transitionStartFrame;
+	_returnDestination.transitionLength = transitionLength;
+	_playingMovie = false;
+	_loopingMovie = false;
+	_playingAudio = false;
+	_enterTransition = enterTransition;
+	_audioChannel = -1;
+
+	loadFrameDatabase();
+	loadMovieDatabase();
+
+	if (!_stillFrames.open(_vm->getFilePath(IDS_INN_STILL_FRAME_FILENAME)))
+		error("Failed to open INN still frames");
+}
+
+InteractiveNewsNetwork::~InteractiveNewsNetwork() {
+	// Restart sound
+	_vm->_sound->restart();
+}
+
+int InteractiveNewsNetwork::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Play any entry animation
+	if (_enterTransition >= 0)
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_enterTransition);
+
+	// Stop the ambient sound
+	_vm->_sound->setAmbientSound();
+
+	// Play the intro movie
+	_playingMovie = ((SceneViewWindow *)viewWindow)->playSynchronousAnimationExtern(IDS_INN_MEDIA_FILENAME_BASE);
+	_currentMovieFrame = 1;
+
+	// Start the INN ambient
+	_vm->_sound->setAmbientSound(_vm->getFilePath(IDS_INN_AMBIENT_FILENAME));
+	return SC_TRUE;
+}
+
+int InteractiveNewsNetwork::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	// Stop a playing movie
+	if (_playingMovie) {
+		((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+		_playingMovie = false;
+		_loopingMovie = false;
+		_vm->_sound->restart();
+	}
+
+	// Stop audio
+	if (_playingAudio && _audioChannel != -1) {
+		_vm->_sound->stopSoundEffect(_audioChannel);
+		_audioChannel = -1;
+		_playingAudio = false;
+	}
+
+	// Stop the INN ambient
+	_vm->_sound->setAmbientSound();
+
+	// Start the environment ambient
+	((SceneViewWindow *)viewWindow)->startEnvironmentAmbient(-1, -1, _staticData.location.timeZone, _staticData.location.environment);
+
+	return SC_TRUE;
+}
+
+int InteractiveNewsNetwork::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	int oldMovieFrame = _currentMovieFrame;
+
+	if (_currentMovieFrame > (int)_frameDatabase.size())
+		return SC_FALSE;
+
+	const INNFrame &currentData = _frameDatabase[_currentMovieFrame];
+
+	for (int i = 0; i < 8; i++) {
+		const INNHotspotData &hotspotData = currentData.hotspots[i];
+
+		if (hotspotData.stillFrameOffset >= 0 || hotspotData.stillFrameOffset == -2) {
+			Common::Rect currentRegion(hotspotData.left, hotspotData.top, hotspotData.right, hotspotData.bottom);
+
+			if (currentRegion.contains(pointLocation)) {
+				if (hotspotData.stillFrameOffset == -2) {
+					// Return from a hyperlink
+					if (!_hyperLinkHistory.empty()) {
+						_currentMovieFrame = _hyperLinkHistory.back();
+						_hyperLinkHistory.pop_back();
+					}
+				} else {
+					// Check if we clicked on a hyperlink
+					int newMovieFrame = hotspotData.stillFrameOffset - 1;
+
+					if (i < 5 && newMovieFrame > 58 && newMovieFrame < 157)
+						_hyperLinkHistory.push_back(_currentMovieFrame);
+
+					_currentMovieFrame = newMovieFrame;
+				}
+
+				// Check for the exit frame
+				if (_currentMovieFrame == 157) {
+					((SceneViewWindow *)viewWindow)->moveToDestination(_returnDestination);
+					return SC_TRUE;
+				}
+
+				// If we are in Agent 3's lair, and we clicked on the symbiotry talks, change the destination
+				if (_staticData.location.timeZone == 3 && _currentMovieFrame == 8 && _currentMovieFrame == 8 && oldMovieFrame != 7) {
+					_currentMovieFrame = 7;
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNUpdate = 1;
+				}
+
+				// If we are playing a video, make sure it's stipped
+				if (_playingMovie) {
+					((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
+					_playingMovie = false;
+					_loopingMovie = false;
+				}
+
+				if (_playingAudio && _audioChannel != -1) {
+					_vm->_sound->stopSoundEffect(_audioChannel);
+					_audioChannel = -1;
+					_playingAudio = false;
+				}
+
+				// Repaint
+				viewWindow->invalidateWindow();
+
+				// Start playing any video clip
+				const INNFrame &newFrame = _frameDatabase[_currentMovieFrame];
+
+				// No full screen video -> restart the sound
+				if (newFrame.pageType != MEDIA_TYPE_VIDEO_FULL)
+					_vm->_sound->restart();
+
+				if (newFrame.pageType > 0) {
+					for (uint j = 0; j < _movieDatabase.size(); j++) {
+						const INNMediaElement &mediaCurrentData = _movieDatabase[j];
+
+						if (mediaCurrentData.frameIndex == _currentMovieFrame) {
+							switch (mediaCurrentData.mediaType) {
+							case MEDIA_TYPE_VIDEO_FULL:
+								// Check for a commercial, play the sponsor clip
+								if (_currentMovieFrame >= 2 && _currentMovieFrame <= 4)
+									_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(IDS_INN_MEDIA_FILENAME_BASE + 39));
+
+
+								_vm->_sound->stop();
+								_playingMovie = ((SceneViewWindow *)viewWindow)->startAsynchronousAnimationExtern(IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset, -1, -1, -1, false);
+								_loopingMovie = false;
+								break;
+							case MEDIA_TYPE_VIDEO_SMALL_A:
+								_playingMovie = ((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimationExtern(275, 16, 120, 120, IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset, -1, -1, -1, true);
+								_loopingMovie = true;
+								break;
+							case MEDIA_TYPE_VIDEO_SMALL_B:
+								_playingMovie = ((SceneViewWindow *)viewWindow)->startPlacedAsynchronousAnimationExtern(255, 16, 159, 120, IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset, -1, -1, -1, true);
+								_loopingMovie = true;
+								break;
+							case MEDIA_TYPE_AUDIO:
+								_playingAudio = true;
+								_audioChannel = _vm->_sound->playSoundEffect(_vm->getFilePath(IDS_INN_MEDIA_FILENAME_BASE + mediaCurrentData.fileIDOffset));
+								break;
+							}
+						}
+					}
+				}
+
+				// Check for scoring frames
+				switch (_currentMovieFrame) {
+				case 20:
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNHighBidder = 1;
+					break;
+				case 25:
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNAppeal = 1;
+					break;
+				case 109:
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNJumpsuit = 1;
+					break;
+				case 159: // Read global_flags.h to see why I hate this
+					((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchINNLouvreReport = 1;
+					break;
+				}
+	
+				return SC_TRUE;
+			}
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int InteractiveNewsNetwork::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	const Graphics::Surface *stillFrame = _stillFrames.getFrame(_currentMovieFrame);
+
+	if (stillFrame)
+		_vm->_gfx->crossBlit(preBuffer, 0, 0, 432, 189, stillFrame, 0, 0);
+
+	return SC_REPAINT;
+}
+
+int InteractiveNewsNetwork::movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) {
+	// Restart sound if the movie has ended
+	if (animationID == -1 && status == MOVIE_STOPPED) {
+		_vm->_sound->restart();
+		return SC_FALSE;
+	}
+
+	return SC_TRUE;
+}
+
+int InteractiveNewsNetwork::timerCallback(Window *viewWindow) {
+	// Check to see if audio has stopped
+	if (_playingAudio && _audioChannel != -1 && !_vm->_sound->isSoundEffectPlaying(_audioChannel)) {
+		_audioChannel = -1;
+		_playingAudio = false;
+	}
+
+	return SC_TRUE;
+}
+
+void InteractiveNewsNetwork::loadFrameDatabase() {
+	Common::SeekableReadStream *frameData = _vm->getINNData(IDBD_INN_BINARY_DATA);
+
+	if (!frameData)
+		error("Failed to find INN frame database");
+
+	uint16 count = frameData->readUint16LE();
+	_frameDatabase.resize(count);
+
+	for (uint16 i = 0; i < count; i++) {
+		 INNFrame &frame = _frameDatabase[i];
+		 frame.topicID = frameData->readSint16LE();
+		 frame.pageType = frameData->readSint16LE();
+		 frame.stillFrameOffset = frameData->readSint32LE();
+
+		for (int j = 0; j < 8; j++) {
+			frame.hotspots[j].left = frameData->readSint16LE();
+			frame.hotspots[j].top = frameData->readSint16LE();
+			frame.hotspots[j].right = frameData->readSint16LE();
+			frame.hotspots[j].bottom = frameData->readSint16LE();
+			frame.hotspots[j].stillFrameOffset = frameData->readSint32LE();
+		}
+	}
+
+	delete frameData;
+}
+
+void InteractiveNewsNetwork::loadMovieDatabase() {
+	Common::SeekableReadStream *movieData = _vm->getINNData(IDBD_INN_MEDIA_BINARY_DATA);
+
+	if (!movieData)
+		error("Failed to find INN movie database");
+
+	uint16 count = movieData->readUint16LE();
+	_movieDatabase.resize(count);
+
+	for (uint16 i = 0; i < count; i++) {
+		INNMediaElement &element = _movieDatabase[i];
+		element.frameIndex = movieData->readSint32LE();
+		element.mediaType = movieData->readSint16LE();
+		element.fileIDOffset = movieData->readSint16LE();
+	}
+
+	delete movieData;
+}
+
 DisplayMessageWithEvidenceWhenEnteringNode::DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow,
 			const LocationStaticData &sceneStaticData, const Location &priorLocation, int evidenceID, int messageBoxTextID) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index a012ce9ae1..efa41acfc5 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -26,7 +26,9 @@
 #ifndef BURIED_SCENE_COMMON_H
 #define BURIED_SCENE_COMMON_H
 
+#include "buried/avi_frames.h"
 #include "buried/bookdata.h"
+#include "buried/inndata.h"
 #include "buried/environ/scene_base.h"
 
 namespace Buried {
@@ -203,6 +205,36 @@ public:
 			int flagOffset = -1, byte flagNewValue = 1);
 };
 
+class InteractiveNewsNetwork : public SceneBase {
+public:
+	InteractiveNewsNetwork(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int enterTransition = -1, int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
+	~InteractiveNewsNetwork();
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	int movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status);
+	int timerCallback(Window *viewWindow);
+
+private:
+	int _enterTransition;
+	int _currentMovieFrame;
+	DestinationScene _returnDestination;
+	AVIFrames _stillFrames;
+	Common::Array<INNFrame> _frameDatabase;
+	Common::Array<INNMediaElement> _movieDatabase;
+	Common::Array<byte> _hyperLinkHistory;
+	bool _playingMovie;
+	bool _loopingMovie;
+	bool _playingAudio;
+	int _audioChannel;
+
+	void loadFrameDatabase();
+	void loadMovieDatabase();
+};
+
 class DisplayMessageWithEvidenceWhenEnteringNode : public SceneBase {
 public:
 	DisplayMessageWithEvidenceWhenEnteringNode(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,


Commit: b7e30acb631e003967e235af2c9f775bd0f15c47
    https://github.com/scummvm/scummvm/commit/b7e30acb631e003967e235af2c9f775bd0f15c47
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement INN for Agent 3's lair

Changed paths:
    engines/buried/environ/agent3_lair.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 4b9a93e168..259a8a8478 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -640,6 +640,76 @@ int GeneratorCoreAcquire::specifyCursor(Window *viewWindow, const Common::Point
 	return kCursorPutDown;
 }
 
+class ZoomInPostItAndINN : public SceneBase {
+public:
+	ZoomInPostItAndINN(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _postItNote;
+	Common::Rect _innScreen;
+};
+
+ZoomInPostItAndINN::ZoomInPostItAndINN(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_postItNote = Common::Rect(8, 150, 57, 189);
+	_innScreen = Common::Rect(64, 97, 208, 160);
+}
+
+int ZoomInPostItAndINN::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_postItNote.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 1;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 5;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = 1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	if (_innScreen.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 2;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 16;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = 1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int ZoomInPostItAndINN::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_postItNote.contains(pointLocation) || _innScreen.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+class ClickChangeScenePostIt : public ClickChangeScene {
+public:
+	ClickChangeScenePostIt(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int cursorID = 0,
+			int timeZone = -1, int environment = -1, int node = -1, int facing = -1, int orientation = -1, int depth = -1,
+			int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
+};
+
+ClickChangeScenePostIt::ClickChangeScenePostIt(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left, int top, int right, int bottom, int cursorID,
+			int timeZone, int environment, int node, int facing, int orientation, int depth,
+			int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
+			ClickChangeScene(vm, viewWindow, sceneStaticData, priorLocation, left, top, right, bottom, cursorID,
+					timeZone, environment, node, facing, orientation, depth, transitionType, transitionData,
+					transitionStartFrame, transitionLength) {
+	((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchAgent3Note = 1;
+}
+
 bool SceneViewWindow::initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1)
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode = 0;
@@ -670,6 +740,10 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 		return new ReplicatorInterface(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 25:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 150, 24, 280, 124, kCursorFinger, 3, 2, 4, 0, 1, 1, TRANSITION_VIDEO, 6, -1, -1);
+	case 27:
+		return new ZoomInPostItAndINN(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 28:
+		return new ClickChangeScenePostIt(_vm, viewWindow, sceneStaticData, priorLocation, 109, 0, 322, 189, kCursorPutDown, 3, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 9, -1, -1);
 	case 29:
 		return new InteractiveNewsNetwork(_vm, viewWindow, sceneStaticData, priorLocation, -1, 3, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 17, -1, -1);
 	}


Commit: d8feab64f4d0783e99fef084970ebad889defba4
    https://github.com/scummvm/scummvm/commit/d8feab64f4d0783e99fef084970ebad889defba4
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the Agent 3 transporter

Changed paths:
    engines/buried/environ/agent3_lair.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 259a8a8478..cdaf243609 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -35,6 +35,7 @@
 #include "buried/environ/scene_common.h"
 
 #include "common/system.h"
+#include "graphics/font.h"
 
 namespace Buried {
 
@@ -480,6 +481,196 @@ int ReplicatorInterface::specifyCursor(Window *viewWindow, const Common::Point &
 	return kCursorArrow;
 }
 
+class TransporterControls : public SceneBase {
+public:
+	TransporterControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	~TransporterControls();
+	void preDestructor();
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int onCharacter(Window *viewWindow, const Common::KeyState &character);
+	int gdiPaint(Window *viewWindow);
+
+private:
+	Common::Rect _monitor, _retract;
+	Common::String _transportCode;
+	Common::String _prefixCode;
+	int _monitorStatus;
+	Graphics::Font *_textFont;
+	int _lineHeight;
+};
+
+TransporterControls::TransporterControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_monitor = Common::Rect(171, 42, 307, 136);
+	_retract = Common::Rect(362, 115, 394, 132);
+	_monitorStatus = 0;
+
+	_lineHeight = (_vm->getLanguage() == Common::JA_JPN) ? 10 : 12;
+	_textFont = _vm->_gfx->createFont(_lineHeight);
+}
+
+TransporterControls::~TransporterControls() {
+	preDestructor();
+}
+
+void TransporterControls::preDestructor() {
+	delete _textFont;
+	_textFont = 0;
+}
+
+int TransporterControls::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (newLocation.timeZone == _staticData.location.timeZone && newLocation.environment == _staticData.location.environment &&
+			newLocation.node == _staticData.location.node && newLocation.facing != _staticData.location.facing) {
+		_vm->_sound->playSoundEffect("BITDATA/AGENT3/ALNMTRO.BTA");
+	}
+
+	return SC_TRUE;
+}
+
+int TransporterControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_monitor.contains(pointLocation) && (_monitorStatus == 0 || _monitorStatus == 2)) {
+		_monitorStatus = 1;
+		_staticData.navFrameIndex = 84;
+		viewWindow->invalidateWindow();
+	} else if (_retract.contains(pointLocation)) {
+		DestinationScene newScene;
+		newScene.destinationScene = _staticData.location;
+		newScene.destinationScene.depth = 0;
+		newScene.transitionType = TRANSITION_VIDEO;
+		newScene.transitionData = 20;
+		newScene.transitionStartFrame = -1;
+		newScene.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int TransporterControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if ((_monitor.contains(pointLocation) && (_monitorStatus == 0 || _monitorStatus == 2)) || _retract.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
+int TransporterControls::onCharacter(Window *viewWindow, const Common::KeyState &character) {
+	if (_monitorStatus == 1) {
+		if (character.keycode == Common::KEYCODE_BACKSPACE || character.keycode == Common::KEYCODE_DELETE) {
+			if (!_transportCode.empty()) {
+				_transportCode.deleteLastChar();
+				_vm->_sound->playSoundEffect("BITDATA/COMMON/GENB14.BTA");
+			}
+		} else if (character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9) {
+			_transportCode += (char)(character.keycode - Common::KEYCODE_0 + '0');
+			_vm->_sound->playSoundEffect("BITDATA/COMMON/GENB14.BTA");
+		}
+
+		viewWindow->invalidateWindow(false);
+
+		if (_transportCode.size() >= 12) {
+			if (_transportCode == "657255190235") {
+				if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
+					// Bypass the prefix code puzzle in walkthrough mode
+					_monitorStatus = 4;
+					_staticData.navFrameIndex = 87;
+					viewWindow->invalidateWindow(false);
+
+					// Wait two seconds
+					uint32 startTime = g_system->getMillis();
+					while (!_vm->shouldQuit() && startTime + 2000 > g_system->getMillis())
+						_vm->yield();
+
+					// Move to a different depth to enter the transporter
+					DestinationScene newScene;
+					newScene.destinationScene = _staticData.location;
+					newScene.destinationScene.depth = 2;
+					newScene.transitionType = TRANSITION_VIDEO;
+					newScene.transitionData = 7;
+					newScene.transitionStartFrame = -1;
+					newScene.transitionLength = -1;
+					((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+				} else {
+					_monitorStatus = 3;
+					_staticData.navFrameIndex = 85;
+					viewWindow->invalidateWindow(false);
+				}
+			} else {
+				_monitorStatus = 2;
+				_staticData.navFrameIndex = 86;
+				_transportCode.clear();
+				viewWindow->invalidateWindow(false);
+			}
+		}
+
+		return SC_TRUE;
+	} else if (_monitorStatus == 3) {
+		// Original allows any character to be printed and doesn't include backspace here
+		// That sucks; I'm using the same code as for the transporter code.
+		if (character.keycode == Common::KEYCODE_BACKSPACE || character.keycode == Common::KEYCODE_DELETE) {
+			if (!_prefixCode.empty()) {
+				_prefixCode.deleteLastChar();
+				_vm->_sound->playSoundEffect("BITDATA/COMMON/GENB14.BTA");
+			}
+		} else if (character.keycode >= Common::KEYCODE_0 && character.keycode <= Common::KEYCODE_9) {
+			_prefixCode += (char)(character.keycode - Common::KEYCODE_0 + '0');
+			_vm->_sound->playSoundEffect("BITDATA/COMMON/GENB14.BTA");
+		}
+
+		viewWindow->invalidateWindow(false);
+
+		if (_prefixCode.size() >= 3) {
+			// Flag a wrong prefix for later
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode = (_prefixCode != "272");
+
+			_prefixCode.clear();
+			_monitorStatus = 4;
+			_staticData.navFrameIndex = 87;
+			viewWindow->invalidateWindow(false);
+
+			// Wait two seconds
+			uint32 startTime = g_system->getMillis();
+			while (!_vm->shouldQuit() && startTime + 2000 > g_system->getMillis())
+				_vm->yield();
+
+			// Move to a different depth to enter the transporter
+			DestinationScene newScene;
+			newScene.destinationScene = _staticData.location;
+			newScene.destinationScene.depth = 2;
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionData = 7;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int TransporterControls::gdiPaint(Window *viewWindow) {
+	if (_monitorStatus == 1 || _monitorStatus == 3) {
+		uint32 color = _vm->_gfx->getColor(80, 216, 144);
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+
+		if (_monitorStatus == 1) {
+			Common::Rect textRegion(190, 78, 280, 128);
+			textRegion.translate(absoluteRect.left, absoluteRect.top);
+			_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, _transportCode, textRegion.left, textRegion.top, textRegion.width(), textRegion.height(), color, _lineHeight);
+		} else {
+			Common::Rect textRegion(190, 120, 253, 133);
+			textRegion.translate(absoluteRect.left, absoluteRect.top);
+			_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, _prefixCode, textRegion.left, textRegion.top, textRegion.width(), textRegion.height(), color, _lineHeight);
+		}
+	}
+
+	return SC_TRUE;
+}
+
 class GeneratorCoreZoom : public SceneBase {
 public:
 	GeneratorCoreZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -692,6 +883,44 @@ int ZoomInPostItAndINN::specifyCursor(Window *viewWindow, const Common::Point &p
 	return kCursorArrow;
 }
 
+class CompleteTransport : public SceneBase {
+public:
+	CompleteTransport(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+};
+
+CompleteTransport::CompleteTransport(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int CompleteTransport::timerCallback(Window *viewWindow) {
+	((SceneViewWindow *)viewWindow)->playSynchronousAnimation(19);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode == 1) {
+		((SceneViewWindow *)viewWindow)->showDeathScene(21);
+	} else {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1) {
+			DestinationScene newScene;
+			newScene.destinationScene = Location(7, 1, 5, 3, 1, 0);
+			newScene.transitionType = TRANSITION_VIDEO;
+			newScene.transitionData = 18;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
+		} else {
+			DestinationScene newScene;
+			newScene.destinationScene = Location(7, 1, 5, 3, 1, 1);
+			newScene.transitionType = TRANSITION_NONE;
+			newScene.transitionData = -1;
+			newScene.transitionStartFrame = -1;
+			newScene.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->jumpToScene(newScene.destinationScene);
+		}
+	}
+
+	return SC_TRUE;
+}
+
 class ClickChangeScenePostIt : public ClickChangeScene {
 public:
 	ClickChangeScenePostIt(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -710,6 +939,23 @@ ClickChangeScenePostIt::ClickChangeScenePostIt(BuriedEngine *vm, Window *viewWin
 	((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchAgent3Note = 1;
 }
 
+class PlayTransporterClosing : public SceneBase {
+public:
+	PlayTransporterClosing(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+};
+
+PlayTransporterClosing::PlayTransporterClosing(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int PlayTransporterClosing::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.node == newLocation.node && _staticData.location.timeZone == newLocation.timeZone)
+		_vm->_sound->playSoundEffect("BITDATA/AGENT3/ALNMTCLS.BTA");
+
+	return SC_TRUE;
+}
+ 
 bool SceneViewWindow::initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1)
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().alNMWrongAlienPrefixCode = 0;
@@ -723,8 +969,6 @@ bool SceneViewWindow::startAgent3LairAmbient(int oldTimeZone, int oldEnvironment
 }
 
 SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 177, 96, 231, 184, kItemGeneratorCore, 15, offsetof(GlobalFlags, alRDTakenLiveCore));
@@ -740,15 +984,21 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 		return new ReplicatorInterface(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 25:
 		return new ClickChangeScene(_vm, viewWindow, sceneStaticData, priorLocation, 150, 24, 280, 124, kCursorFinger, 3, 2, 4, 0, 1, 1, TRANSITION_VIDEO, 6, -1, -1);
+	case 26:
+		return new TransporterControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 27:
 		return new ZoomInPostItAndINN(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 28:
 		return new ClickChangeScenePostIt(_vm, viewWindow, sceneStaticData, priorLocation, 109, 0, 322, 189, kCursorPutDown, 3, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 9, -1, -1);
 	case 29:
 		return new InteractiveNewsNetwork(_vm, viewWindow, sceneStaticData, priorLocation, -1, 3, 2, 0, 2, 1, 0, TRANSITION_VIDEO, 17, -1, -1);
+	case 30:
+		return new CompleteTransport(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 31:
+		return new PlayTransporterClosing(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
-	warning("TODO: Agent 3 lair scene object %d", sceneStaticData.classID);
+	warning("Unknown Agent 3 lair scene object %d", sceneStaticData.classID);
 
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }


Commit: 8887e2dc0372e6c4751fbf5f66a9c26bb9fcfcfc
    https://github.com/scummvm/scummvm/commit/8887e2dc0372e6c4751fbf5f66a9c26bb9fcfcfc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Add the alien time zone

Changed paths:
  A engines/buried/environ/alien.cpp
    engines/buried/environ/scene_factory.cpp
    engines/buried/module.mk
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
new file mode 100644
index 0000000000..893d20fb22
--- /dev/null
+++ b/engines/buried/environ/alien.cpp
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * Additional copyright for this file:
+ * Copyright (C) 1995 Presto Studios, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "buried/buried.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/sound.h"
+#include "buried/environ/scene_base.h"
+#include "buried/environ/scene_common.h"
+
+#include "common/system.h"
+
+namespace Buried {
+
+bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
+	if (environment == -1) {
+		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
+
+		flags.asInitialGuardsPass = 0;
+		flags.asRBPodAStatus = 0;
+		flags.asRBPodBStatus = 0;
+		flags.asRBPodCStatus = 0;
+		flags.asRBPodDStatus = 0;
+		flags.asRBPodEStatus = 0;
+		flags.asRBPodFStatus = 0;
+	} else if (environment == 1) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreTransportToKrynn = 1;
+	}
+
+	return true;
+}
+
+bool SceneViewWindow::startAlienAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
+	_vm->_sound->setAmbientSound(_vm->getFilePath(7, environment, SF_AMBIENT), oldTimeZone == 7 && fade, 64);
+	return true;
+}
+
+
+SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// TODO
+
+	switch (sceneStaticData.classID) {
+	case 50:
+		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
+	}
+
+	warning("TODO: Alien scene object %d", sceneStaticData.classID);
+	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
+}
+
+} // End of namespace Buried
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index 81251052f0..ce3bb23fce 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -90,8 +90,6 @@ bool SceneViewWindow::checkCustomAICommentDependencies(const Location &commentLo
 }
 
 bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironment, int timeZone, int environment, bool fade) {
-	// TODO
-
 	switch (timeZone) {
 	case 1:
 		return startCastleAmbient(oldTimeZone, oldEnvironment, environment, fade);
@@ -105,6 +103,8 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 		return startDaVinciAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 6:
 		return startAILabAmbient(oldTimeZone, oldEnvironment, environment, fade);
+	case 7:
+		return startAlienAmbient(oldTimeZone, oldEnvironment, environment, fade);
 	case 10:
 		return _vm->_sound->setAmbientSound();
 	}
@@ -119,8 +119,7 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 
 	switch (sceneStaticData.location.timeZone) {
 	case 0: // Miscellaneous scenes
-	case 7: // Alien
-		// TODO
+		// This seems unused?
 		warning("Could not create scene object for time zone %d", sceneStaticData.location.timeZone);
 		break;
 	case 1: // Castle
@@ -135,6 +134,8 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		return constructDaVinciSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 6: // AI Lab
 		return constructAILabSceneObject(viewWindow, sceneStaticData, priorLocation);
+	case 7: // Alien
+		return constructAlienSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 10: // Old Apartment
 		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
@@ -143,7 +144,6 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 }
 
 bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment) {
-	// TODO
 	switch (timeZone) {
 	case 1:
 		return initializeCastleTimeZoneAndEnvironment(viewWindow, environment);
@@ -158,6 +158,8 @@ bool SceneViewWindow::initializeTimeZoneAndEnvironment(Window *viewWindow, int t
 		return initializeDaVinciTimeZoneAndEnvironment(viewWindow, environment);
 	case 6:
 		return initializeAILabTimeZoneAndEnvironment(viewWindow, environment);
+	case 7:
+		return initializeAlienTimeZoneAndEnvironment(viewWindow, environment);
 	}
 
 	return false;
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index 9bc2ede3ce..c21123e2cb 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -31,6 +31,7 @@ MODULE_OBJS = \
 	demo/movie_scene.o \
 	environ/agent3_lair.o \
 	environ/ai_lab.o \
+	environ/alien.o \
 	environ/castle.o \
 	environ/da_vinci.o \
 	environ/future_apartment.o \
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 6318f11447..4179d91b06 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -230,6 +230,11 @@ private:
 	bool initializeAgent3LairTimeZoneAndEnvironment(Window *viewWindow, int environment);
 	bool startAgent3LairAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
 	SceneBase *constructAgent3LairSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+
+	// Alien
+	bool initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment);
+	bool startAlienAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade);
+	SceneBase *constructAlienSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 };
 
 } // End of namespace Buried


Commit: e66faa92b821553079ced41d87168c0930613a31
    https://github.com/scummvm/scummvm/commit/e66faa92b821553079ced41d87168c0930613a31
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the alien transporter

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 893d20fb22..9ab997dd3a 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "buried/buried.h"
+#include "buried/graphics.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -34,6 +35,50 @@
 
 namespace Buried {
 
+class NormalTransporter : public SceneBase {
+public:
+	NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickRegion;
+};
+
+NormalTransporter::NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(118, 93, 153, 125);
+}
+
+int NormalTransporter::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asAmbassadorEncounter == 1) {
+			_vm->_sound->setAmbientSound();
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(1);
+			_staticData.navFrameIndex = -1;
+			((SceneViewWindow *)viewWindow)->showCompletionScene();
+		} else {
+			DestinationScene destData;
+			destData.destinationScene = Location(3, 2, 4, 0, 1, 0);
+			destData.transitionType = TRANSITION_VIDEO;
+			destData.transitionData = 1;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int NormalTransporter::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -62,6 +107,8 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 12:
+		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 50:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
 	}


Commit: 8153960b2b963c897c882474964a998af2bdae61
    https://github.com/scummvm/scummvm/commit/8153960b2b963c897c882474964a998af2bdae61
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement entering the alien ship without the lens filter

Changed paths:
    engines/buried/environ/alien.cpp
    engines/buried/resources.h


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 9ab997dd3a..8278569156 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -32,6 +32,7 @@
 #include "buried/environ/scene_common.h"
 
 #include "common/system.h"
+#include "graphics/surface.h"
 
 namespace Buried {
 
@@ -79,6 +80,56 @@ int NormalTransporter::specifyCursor(Window *viewWindow, const Common::Point &po
 	return kCursorArrow;
 }
 
+class EntryWithoutLensFilter : public SceneBase {
+public:
+	EntryWithoutLensFilter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int paint(Window *viewWindow, Graphics::Surface *preBuffer);
+	int timerCallback(Window *viewWindow);
+
+private:
+	bool _transPlayed;
+};
+
+EntryWithoutLensFilter::EntryWithoutLensFilter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_transPlayed = false;
+}
+
+int EntryWithoutLensFilter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 8));
+
+	Common::String text;
+	if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
+		text = _vm->getString(IDS_AS_VISIBILITY_MESSAGE);
+	else
+		text = "Alert: No visible light waves detected. Jumpsuit's built-in light source ineffective.";
+
+	((SceneViewWindow *)viewWindow)->displayLiveText(text);
+	return SC_TRUE;
+}
+
+int EntryWithoutLensFilter::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
+	preBuffer->fillRect(Common::Rect(432, 189), _vm->_gfx->getColor(0, 0, 0));
+	return SC_REPAINT;
+}
+
+int EntryWithoutLensFilter::timerCallback(Window *viewWindow) {
+	if (!_transPlayed && ((SceneViewWindow *)viewWindow)->getGlobalFlags().lensFilterActivated == 1) {
+		_transPlayed = true;
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 0;
+		destData.transitionType = TRANSITION_NONE;
+		destData.transitionData = -1;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -109,6 +160,8 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 	switch (sceneStaticData.classID) {
 	case 12:
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 13:
+		return new EntryWithoutLensFilter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 50:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
 	}
diff --git a/engines/buried/resources.h b/engines/buried/resources.h
index 7179c9dd42..dc0f145345 100644
--- a/engines/buried/resources.h
+++ b/engines/buried/resources.h
@@ -368,6 +368,7 @@ namespace Buried {
 #define IDS_AL_VULGAR_LANG_H            9007
 #define IDS_AL_VULGAR_LANG_I            9009
 #define IDS_AL_CASTRATION_TEXT          9016
+#define IDS_AS_VISIBILITY_MESSAGE       9022
 #define IDS_COMPL_WALK_SCORE_DESC_TEMPL 9031
 #define IDS_DEATH_WALK_SCORE_DESC_TEMPL 9031
 #define IDS_COMPL_WALK_SCORE_AMT_TEMPL  9032


Commit: 5bcf46ce9ebc444649f908a004a89545498e713f
    https://github.com/scummvm/scummvm/commit/5bcf46ce9ebc444649f908a004a89545498e713f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the transport pod descriptions

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 8278569156..863394c1f2 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -130,6 +130,34 @@ int EntryWithoutLensFilter::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+class PlayPodAudio : public SceneBase {
+public:
+	PlayPodAudio(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int untransAudio, int transSoundID);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+
+private:
+	int _untransSoundID;
+	int _transSoundID;
+};
+
+PlayPodAudio::PlayPodAudio(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation, int untransAudio, int transSoundID) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_untransSoundID = untransAudio;
+	_transSoundID = transSoundID;
+}
+
+int PlayPodAudio::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		if (_transSoundID >= 0)
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _transSoundID));
+	} else {
+		if (_untransSoundID >= 0)
+			_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _untransSoundID));
+	}
+
+	return SC_TRUE;
+}
+
 bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -162,6 +190,10 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:
 		return new EntryWithoutLensFilter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 30:
+		return new PlayPodAudio(_vm, viewWindow, sceneStaticData, priorLocation, 9, 10);
+	case 31:
+		return new PlayPodAudio(_vm, viewWindow, sceneStaticData, priorLocation, 11, 12);
 	case 50:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
 	}


Commit: 3ad17ea0573b331831567e3a3acf5fca9f943dff
    https://github.com/scummvm/scummvm/commit/3ad17ea0573b331831567e3a3acf5fca9f943dff
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the inorganic matter transporters

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 863394c1f2..26665a39c2 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -158,6 +158,45 @@ int PlayPodAudio::postEnterRoom(Window *viewWindow, const Location &priorLocatio
 	return SC_TRUE;
 }
 
+class InorganicPodTransDeath : public SceneBase {
+public:
+	InorganicPodTransDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1, int animID = -1, int deathScene = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _clickRegion;
+	int _transportAnimID;
+	int _deathScene;
+};
+
+InorganicPodTransDeath::InorganicPodTransDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom, int animID, int deathScene) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_clickRegion = Common::Rect(left, top, right, bottom);
+	_transportAnimID = animID;
+	_deathScene = deathScene;
+}
+
+int InorganicPodTransDeath::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation)) {
+		_vm->_sound->setAmbientSound();
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_transportAnimID);
+		_staticData.navFrameIndex = -1;
+		((SceneViewWindow *)viewWindow)->showDeathScene(_deathScene);
+	}
+
+	return SC_FALSE;
+}
+
+int InorganicPodTransDeath::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_clickRegion.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -194,6 +233,10 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new PlayPodAudio(_vm, viewWindow, sceneStaticData, priorLocation, 9, 10);
 	case 31:
 		return new PlayPodAudio(_vm, viewWindow, sceneStaticData, priorLocation, 11, 12);
+	case 32:
+		return new InorganicPodTransDeath(_vm, viewWindow, sceneStaticData, priorLocation, 92, 88, 158, 128, 2, 52);
+	case 33:
+		return new InorganicPodTransDeath(_vm, viewWindow, sceneStaticData, priorLocation, 92, 88, 158, 128, 26, 53);
 	case 50:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
 	}


Commit: 131ca518df52b8daaf37404e2a2ca43fc78a1d59
    https://github.com/scummvm/scummvm/commit/131ca518df52b8daaf37404e2a2ca43fc78a1d59
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the arm controls

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 26665a39c2..34a0b5a4eb 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -36,6 +36,46 @@
 
 namespace Buried {
 
+class ArmControls : public SceneBase {
+public:
+	ArmControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _controls[3];
+	int _animIDs[3];
+};
+
+ArmControls::ArmControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_controls[0] = Common::Rect(124, 150, 140, 164);
+	_controls[1] = Common::Rect(145, 146, 161, 160);
+	_controls[2] = Common::Rect(155, 162, 165, 172);
+	_animIDs[0] = 3;
+	_animIDs[1] = 4;
+	_animIDs[2] = 5;
+}
+
+int ArmControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 3; i++) {
+		if (_controls[i].contains(pointLocation)) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_animIDs[i]);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int ArmControls::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 3; i++)
+		if (_controls[i].contains(pointLocation))
+			return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class NormalTransporter : public SceneBase {
 public:
 	NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -225,6 +265,8 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 	// TODO
 
 	switch (sceneStaticData.classID) {
+	case 1:
+		return new ArmControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:


Commit: 329513c37aabf15a14c61f5a63b2da7f2fcca743
    https://github.com/scummvm/scummvm/commit/329513c37aabf15a14c61f5a63b2da7f2fcca743
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement alien door A

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 34a0b5a4eb..a032278144 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -25,6 +25,7 @@
 
 #include "buried/buried.h"
 #include "buried/graphics.h"
+#include "buried/invdata.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -76,6 +77,144 @@ int ArmControls::specifyCursor(Window *viewWindow, const Common::Point &pointLoc
 	return kCursorArrow;
 }
 
+class OpenAlienDoorA : public SceneBase {
+public:
+	OpenAlienDoorA(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+OpenAlienDoorA::OpenAlienDoorA(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int OpenAlienDoorA::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDangerDoorASealed != 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 0) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 1;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 16;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+
+		Common::String text = _vm->getString(IDS_AS_RA_BEINGS_DETECTED_20_METERS);
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		((SceneViewWindow *)viewWindow)->displayLiveText(text);
+		return SC_FALSE;
+	}
+
+	return SC_TRUE;
+}
+
+class AlienDoorAEncounter : public SceneBase {
+public:
+	AlienDoorAEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int timerCallback(Window *viewWindow);
+
+private:
+	uint32 _timerStart;
+	LocationStaticData _originalSceneData;
+	bool _cloaked;
+	Common::Rect _nerve;
+};
+
+AlienDoorAEncounter::AlienDoorAEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_timerStart = 0;
+	_cloaked = false;
+	_nerve = Common::Rect(184, 160, 268, 189);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asTakenEvidenceThisTrip == 1) {
+		_originalSceneData = _staticData;
+		_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	}
+}
+
+int AlienDoorAEncounter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asTakenEvidenceThisTrip == 1)
+		_timerStart = g_system->getMillis();
+
+	return SC_TRUE;
+}
+
+int AlienDoorAEncounter::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.depth != newLocation.depth && _staticData.location.timeZone == newLocation.timeZone && _staticData.location.node == newLocation.node)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7), 128, false, true);
+
+	return SC_TRUE;
+}
+
+int AlienDoorAEncounter::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemRichardsSword && ((SceneViewWindow *)viewWindow)->getGlobalFlags().asTakenEvidenceThisTrip == 1 && _nerve.contains(pointLocation))
+		return 1;
+
+	return 0;
+}
+
+int AlienDoorAEncounter::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemRichardsSword && ((SceneViewWindow *)viewWindow)->getGlobalFlags().asTakenEvidenceThisTrip == 1 && _nerve.contains(pointLocation)) {
+		// Reset the nerve flag
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().asDangerDoorASealed = 1;
+
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 0;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 11;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	}
+
+	return SIC_REJECT;
+}
+
+int AlienDoorAEncounter::timerCallback(Window *viewWindow) {
+	if (_timerStart != 0) {
+		if (_cloaked) {
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 0) {
+				_cloaked = false;
+				_timerStart = g_system->getMillis();
+			}
+		} else {
+			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 1) {
+				_cloaked = true;
+			} else {
+				if (_timerStart + 15000 < g_system->getMillis()) {
+					((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
+					((SceneViewWindow *)viewWindow)->showDeathScene(50);
+					return SC_DEATH;
+				}
+			}
+		}
+	}
+
+	return SC_TRUE;
+}
+
+class AlienDoorAMoveDeath : public SceneBase {
+public:
+	AlienDoorAMoveDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+};
+
+AlienDoorAMoveDeath::AlienDoorAMoveDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int AlienDoorAMoveDeath::timerCallback(Window *viewWindow) {
+	((SceneViewWindow *)viewWindow)->showDeathScene(50);
+	return SC_DEATH;
+}
+
 class NormalTransporter : public SceneBase {
 public:
 	NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -267,6 +406,12 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new ArmControls(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 4:
+		return new OpenAlienDoorA(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 5:
+		return new AlienDoorAEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 6:
+		return new AlienDoorAMoveDeath(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:


Commit: ecfc52c7bb408a69fc6ce8792cffda6495f617f0
    https://github.com/scummvm/scummvm/commit/ecfc52c7bb408a69fc6ce8792cffda6495f617f0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement alien door B

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index a032278144..d53b80407e 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -215,6 +215,119 @@ int AlienDoorAMoveDeath::timerCallback(Window *viewWindow) {
 	return SC_DEATH;
 }
 
+class AlienDoorBOpen : public SceneBase {
+public:
+	AlienDoorBOpen(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
+AlienDoorBOpen::AlienDoorBOpen(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+}
+
+int AlienDoorBOpen::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDangerDoorASealed != 1) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 1;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDoorBGuardsSeen == 1) ? 15 : 13;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_FALSE;
+	}
+
+	return SC_TRUE;
+}
+
+class AlienDoorBEncounter : public SceneBase {
+public:
+	AlienDoorBEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
+	int timerCallback(Window *viewWindow);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	uint32 _timerStart;
+	LocationStaticData _originalSceneData;
+	Common::Rect _nerve;
+	Location _forwardLocation;
+};
+
+AlienDoorBEncounter::AlienDoorBEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_timerStart = 0;
+	_nerve = Common::Rect(154, 155, 256, 189);
+	_forwardLocation = _staticData.destForward.destinationScene;
+	_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDoorBGuardsSeen == 0) {
+		_originalSceneData = _staticData;
+		_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	} else {
+		_staticData.navFrameIndex = 122;
+	}
+}
+
+int AlienDoorBEncounter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDoorBGuardsSeen == 0) {
+		_timerStart = g_system->getMillis();
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AS_RA_BEINGS_DETECTED_20_METERS));
+	}
+
+	return SC_TRUE;
+}
+
+int AlienDoorBEncounter::postExitRoom(Window *viewWindow, const Location &newLocation) {
+	if (_staticData.location.depth != newLocation.depth && _staticData.location.timeZone == newLocation.timeZone && _staticData.location.node == newLocation.node)
+		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7), 128, false, true);
+
+	return SC_TRUE;
+}
+
+int AlienDoorBEncounter::timerCallback(Window *viewWindow) {
+	if (_timerStart != 0 && (_timerStart + 15000 < g_system->getMillis() || ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 1)) {
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcCloakingEnabled == 0) {
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
+			((SceneViewWindow *)viewWindow)->showDeathScene(50);
+		} else {
+			_staticData = _originalSceneData;
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
+			_staticData.navFrameIndex = 122;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asDoorBGuardsSeen = 1;
+			_timerStart = 0;
+			_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+		}
+	}
+
+	return SC_TRUE;
+}
+
+int AlienDoorBEncounter::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDoorBGuardsSeen == 1 && _nerve.contains(pointLocation)) {
+		_staticData.destForward.destinationScene = _forwardLocation;
+		((SceneViewWindow *)viewWindow)->moveToDestination(_staticData.destForward);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int AlienDoorBEncounter::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asDoorBGuardsSeen == 1 && _nerve.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class NormalTransporter : public SceneBase {
 public:
 	NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -412,6 +525,10 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new AlienDoorAEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 6:
 		return new AlienDoorAMoveDeath(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 7:
+		return new AlienDoorBOpen(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 8:
+		return new AlienDoorBEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:


Commit: 3513bb1a64ef29e70355b92a9c848a07abfb0af5
    https://github.com/scummvm/scummvm/commit/3513bb1a64ef29e70355b92a9c848a07abfb0af5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement krynn ship nerve movement

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index d53b80407e..bc265bbc84 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -37,6 +37,43 @@
 
 namespace Buried {
 
+class NerveNavigation : public SceneBase {
+public:
+	NerveNavigation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int left = -1, int top = -1, int right = -1, int bottom = -1);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _nerve;
+	Location _forwardLocation;
+};
+
+NerveNavigation::NerveNavigation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int left, int top, int right, int bottom) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_nerve = Common::Rect(left, top, right, bottom);
+	_forwardLocation = _staticData.destForward.destinationScene;
+	_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+}
+
+int NerveNavigation::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_nerve.contains(pointLocation)) {
+		_staticData.destForward.destinationScene = _forwardLocation;
+		((SceneViewWindow *)viewWindow)->moveToDestination(_staticData.destForward);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int NerveNavigation::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_nerve.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class ArmControls : public SceneBase {
 public:
 	ArmControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -541,6 +578,12 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new InorganicPodTransDeath(_vm, viewWindow, sceneStaticData, priorLocation, 92, 88, 158, 128, 2, 52);
 	case 33:
 		return new InorganicPodTransDeath(_vm, viewWindow, sceneStaticData, priorLocation, 92, 88, 158, 128, 26, 53);
+	case 40:
+		return new NerveNavigation(_vm, viewWindow, sceneStaticData, priorLocation, 262, 122, 302, 189);
+	case 41:
+		return new NerveNavigation(_vm, viewWindow, sceneStaticData, priorLocation, 170, 144, 250, 180);
+	case 42:
+		return new NerveNavigation(_vm, viewWindow, sceneStaticData, priorLocation, 180, 160, 270, 189);
 	case 50:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
 	}


Commit: 5ad6ad3a42c6c36becc684cd45348a154b879fbb
    https://github.com/scummvm/scummvm/commit/5ad6ad3a42c6c36becc684cd45348a154b879fbb
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the alien artifact pods

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index bc265bbc84..7d771423aa 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -23,9 +23,12 @@
  *
  */
 
+#include "buried/biochip_right.h"
 #include "buried/buried.h"
+#include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
+#include "buried/inventory_window.h"
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 #include "buried/sound.h"
@@ -37,6 +40,241 @@
 
 namespace Buried {
 
+class RetrieveFromPods : public SceneBase {
+public:
+	RetrieveFromPods(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int doorLeft = -1, int doorTop = -1, int doorRight = -1, int doorBottom = -1, int openAnim = -1, int openNormFrame = -1,
+			int popAnim = -1, int openPoppedAnim = -1, int openPoppedFrame = -1, int grabLeft = -1, int grabTop = -1, int grabRight = -1,
+			int grabBottom = -1, int openEmptyAnim = -1, int openEmptyFrame = -1, int itemID = -1, int takenFlagOffset = -1,
+			int podStatusFlagOffset = -1, int returnDepth = -1, int popSwordAnim = -1);
+	virtual int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	virtual int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+protected:
+	Common::Rect _openDoor;
+	Common::Rect _grabObject;
+	int _itemID;
+	int _itemFlagOffset;
+	int _podStatusFlagOffset;
+	int _openNormFrame;
+	int _openPoppedFrame;
+	int _openEmptyFrame;
+	int _openAnim;
+	int _popAnim;
+	int _openPoppedAnim;
+	int _openEmptyAnim;
+	int _popSwordAnim;
+	int _returnDepth;
+	bool _doorOpen;
+};
+
+RetrieveFromPods::RetrieveFromPods(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int doorLeft, int doorTop, int doorRight, int doorBottom, int openAnim, int openNormFrame,
+		int popAnim, int openPoppedAnim, int openPoppedFrame, int grabLeft, int grabTop, int grabRight,
+		int grabBottom, int openEmptyAnim, int openEmptyFrame, int itemID, int takenFlagOffset,
+		int podStatusFlagOffset, int returnDepth, int popSwordAnim) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_openDoor = Common::Rect(doorLeft, doorTop, doorRight, doorBottom);
+	_grabObject = Common::Rect(grabLeft, grabTop, grabRight, grabBottom);
+	_itemID = itemID;
+	_itemFlagOffset = takenFlagOffset;
+	_podStatusFlagOffset = podStatusFlagOffset;
+	_openNormFrame = openNormFrame;
+	_openPoppedFrame = openPoppedFrame;
+	_openEmptyFrame = openEmptyFrame;
+	_openAnim = openAnim;
+	_popAnim = popAnim;
+	_openPoppedAnim = openPoppedAnim;
+	_openEmptyAnim = openEmptyAnim;
+	_returnDepth = returnDepth;
+	_doorOpen = false;
+	_popSwordAnim = popSwordAnim;
+}
+
+int RetrieveFromPods::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorOpen && _grabObject.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) == 0) {
+		_staticData.navFrameIndex = _openEmptyFrame;
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 1);
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_podStatusFlagOffset, 2);
+
+		// Begin dragging
+		Common::Point ptInventoryWindow = viewWindow->convertPointToGlobal(pointLocation);
+		ptInventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->convertPointToLocal(ptInventoryWindow);
+		((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(_itemID, ptInventoryWindow);
+
+		// Update the biochips
+		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int RetrieveFromPods::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (!_doorOpen && _openDoor.contains(pointLocation)) {
+		_doorOpen = true;
+
+		switch (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset)) {
+		case 0:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_openAnim);
+			_staticData.navFrameIndex = _openNormFrame;
+			break;
+		case 1:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_openPoppedAnim);
+			_staticData.navFrameIndex = _openPoppedFrame;
+			break;
+		case 2:
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_openEmptyAnim);
+			_staticData.navFrameIndex = _openEmptyFrame;
+			break;
+		}
+
+		return SC_TRUE;
+	}
+
+	if (_returnDepth >= 0) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = _returnDepth;
+		destData.transitionType = TRANSITION_NONE;
+		destData.transitionData = -1;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int RetrieveFromPods::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemExplosiveCharge || itemID == kItemRichardsSword) {
+		if (_doorOpen && _openDoor.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 0)
+			return 1;
+
+		return 0;
+	}
+
+	if (itemID == _itemID && _doorOpen && _grabObject.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 2)
+		return 1;
+
+	return 0;
+}
+
+int RetrieveFromPods::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if ((itemID == kItemExplosiveCharge || itemID == kItemRichardsSword) && _doorOpen && _openDoor.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 0) {
+		// Play the popping movie and change the still frame
+		if (itemID == kItemRichardsSword && _popSwordAnim >= 0)
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_popSwordAnim);
+		else
+			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_popAnim);
+
+		_staticData.navFrameIndex = _openPoppedFrame;
+
+		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_podStatusFlagOffset, 1);
+
+		// If in walkthrough mode, open all the pods
+		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asRBPodAStatus = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asRBPodBStatus = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asRBPodCStatus = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asRBPodDStatus = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asRBPodEStatus = 1;
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asRBPodFStatus = 1;
+		}
+
+		// Explosive charge doesn't get returned
+		if (itemID == kItemExplosiveCharge)
+			return SIC_ACCEPT;
+
+		// Sword does
+		return SIC_REJECT;
+	}
+
+	if (itemID == _itemID && _doorOpen) {
+		if (pointLocation.x == -1 && pointLocation.y == -1) {
+			((SceneViewWindow *)viewWindow)->getGlobalFlags().asTakenEvidenceThisTrip = 1;
+
+			InventoryWindow *invWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow;
+			if (invWindow->isItemInInventory(kItemEnvironCart) && invWindow->isItemInInventory(kItemMayanPuzzleBox) && invWindow->isItemInInventory(kItemCodexAtlanticus) && invWindow->isItemInInventory(kItemInteractiveSculpture) && invWindow->isItemInInventory(kItemRichardsSword))
+				((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreGotKrynnArtifacts = 1;
+		} else if (_grabObject.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 2) {
+			// Change the still frame to reflect the return of the inventory item
+			_staticData.navFrameIndex = _openPoppedFrame;
+			viewWindow->invalidateWindow(false);
+
+			// Reset flags
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_itemFlagOffset, 0);
+			((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_podStatusFlagOffset, 1);
+			return SIC_ACCEPT;
+		}
+	}
+
+	return SIC_REJECT;
+}
+
+class DoubleZoomIn : public SceneBase {
+public:
+	DoubleZoomIn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+			int leftA, int topA, int rightA, int bottomA, int depthA, int leftB, int topB, int rightB, int bottomB, int depthB);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _zoomRegion[2];
+	int _zoomDest[2];
+};
+
+DoubleZoomIn::DoubleZoomIn(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
+		int leftA, int topA, int rightA, int bottomA, int depthA, int leftB, int topB, int rightB, int bottomB, int depthB) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_zoomRegion[0] = Common::Rect(leftA, topA, rightA, bottomA);
+	_zoomRegion[1] = Common::Rect(leftB, topB, rightB, bottomB);
+	_zoomDest[0] = depthA;
+	_zoomDest[1] = depthB;
+}
+
+int DoubleZoomIn::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	for (int i = 0; i < 2; i++) {
+		if (_zoomRegion[i].contains(pointLocation)) {
+			DestinationScene destData;
+			destData.destinationScene = _staticData.location;
+			destData.destinationScene.depth = _zoomDest[i];
+			destData.transitionType = TRANSITION_NONE;
+			destData.transitionData = -1;
+			destData.transitionStartFrame = -1;
+			destData.transitionLength = -1;
+			((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+			return SC_TRUE;
+		}
+	}
+
+	return SC_FALSE;
+}
+
+int DoubleZoomIn::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_zoomRegion[0].contains(pointLocation) || _zoomRegion[1].contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
+int RetrieveFromPods::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_openDoor.contains(pointLocation) && !_doorOpen)
+		return kCursorFinger;
+
+	if (_grabObject.contains(pointLocation) && _itemFlagOffset >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_itemFlagOffset) == 0)
+		return kCursorOpenHand;
+
+	if (_returnDepth >= 0)
+		return kCursorPutDown;
+
+	return kCursorArrow;
+}
+
 class NerveNavigation : public SceneBase {
 public:
 	NerveNavigation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -526,6 +764,40 @@ int InorganicPodTransDeath::specifyCursor(Window *viewWindow, const Common::Poin
 	return kCursorArrow;
 }
 
+class CheeseGirlPod : public RetrieveFromPods {
+public:
+	CheeseGirlPod(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+};
+
+CheeseGirlPod::CheeseGirlPod(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		RetrieveFromPods(vm, viewWindow, sceneStaticData, priorLocation, 128, 0, 352, 189, 20, 76, 21, 22, 77, 170, 54, 252, 156, 23, 78, -1, -1, offsetof(GlobalFlags, asRBPodFStatus), 0, 28) {
+}
+
+int CheeseGirlPod::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_doorOpen && _grabObject.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 1) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(23);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int CheeseGirlPod::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_openDoor.contains(pointLocation) && !_doorOpen)
+		return kCursorFinger;
+
+	// If we're over the grab region, use the finger cursor so we can click on Frank
+	if (_grabObject.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(_podStatusFlagOffset) == 1)
+		return kCursorFinger;
+
+	if (_returnDepth >= 0)
+		return kCursorPutDown;
+
+	return kCursorArrow;
+}
+
 bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -570,6 +842,22 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:
 		return new EntryWithoutLensFilter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 20:
+		return new RetrieveFromPods(_vm, viewWindow, sceneStaticData, priorLocation, 172, 46, 272, 166, 0, 61, 1, 2, 62, 198, 78, 248, 116, 3, 63, kItemEnvironCart, offsetof(GlobalFlags, asRBPodATakenEnvironCart), offsetof(GlobalFlags, asRBPodAStatus), -1, 29);
+	case 21:
+		return new DoubleZoomIn(_vm, viewWindow, sceneStaticData, priorLocation, 240, 88, 300, 178, 1, 100, 0, 160, 98, 2);
+	case 22:
+		return new RetrieveFromPods(_vm, viewWindow, sceneStaticData, priorLocation, 150, 0, 394, 189, 4, 64, 5, 6, 65, 190, 74, 312, 142, 7, 66, kItemMayanPuzzleBox, offsetof(GlobalFlags, asRBPodBTakenPuzzleBox), offsetof(GlobalFlags, asRBPodBStatus), 0, 25);
+	case 23:
+		return new RetrieveFromPods(_vm, viewWindow, sceneStaticData, priorLocation, 140, 8, 274, 189, 8, 67, 9, 10, 68, 176, 42, 232, 124, 11, 69, kItemCodexAtlanticus, offsetof(GlobalFlags, asRBPodCTakenCodex), offsetof(GlobalFlags, asRBPodCStatus), 0, 26);
+	case 24:
+		return new RetrieveFromPods(_vm, viewWindow, sceneStaticData, priorLocation, 100, 0, 280, 189, 12, 70, 13, 14, 71, 146, 60, 252, 156, 15, 72, kItemInteractiveSculpture, offsetof(GlobalFlags, asRBPodDTakenSculpture), offsetof(GlobalFlags, asRBPodDStatus), -1, 27);
+	case 25:
+		return new DoubleZoomIn(_vm, viewWindow, sceneStaticData, priorLocation, 256, 0, 322, 100, 1, 106, 84, 172, 189, 2);
+	case 26:
+		return new RetrieveFromPods(_vm, viewWindow, sceneStaticData, priorLocation, 134, 0, 276, 189, 16, 73, 17, 18, 74, 190, 4, 224, 166, 19, 75, kItemRichardsSword, offsetof(GlobalFlags, asRBPodETakenSword), offsetof(GlobalFlags, asRBPodEStatus), 0);
+	case 27:
+		return new CheeseGirlPod(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 30:
 		return new PlayPodAudio(_vm, viewWindow, sceneStaticData, priorLocation, 9, 10);
 	case 31:


Commit: cbeba842f10b43f5cc3365d5d486a606d5e7551e
    https://github.com/scummvm/scummvm/commit/cbeba842f10b43f5cc3365d5d486a606d5e7551e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the first part of the final sequence

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 7d771423aa..1e0fb226ad 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -603,6 +603,66 @@ int AlienDoorBEncounter::specifyCursor(Window *viewWindow, const Common::Point &
 	return kCursorArrow;
 }
 
+class EncounterAmbassadorFirstZoom : public SceneBase {
+public:
+	EncounterAmbassadorFirstZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	Common::Rect _panel;
+};
+
+EncounterAmbassadorFirstZoom::EncounterAmbassadorFirstZoom(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_panel = Common::Rect(110, 0, 420, 62);
+}
+
+int EncounterAmbassadorFirstZoom::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().asTakenEvidenceThisTrip == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().asAmbassadorEncounter == 0) {
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().asAmbassadorEncounter = 1;
+
+		// Here we go!
+		((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_AS_RA_BEINGS_DETECTED_5_METERS));
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(18); // "Why are you here?"
+		_staticData.navFrameIndex = 127;
+
+		DestinationScene destData;
+		destData.destinationScene = Location(7, 1, 6, 0, 1, 1);
+		destData.transitionType = TRANSITION_NONE;
+		destData.transitionData = -1;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	}
+
+	return SC_TRUE;
+}
+
+int EncounterAmbassadorFirstZoom::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_panel.contains(pointLocation)) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 1;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 6;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int EncounterAmbassadorFirstZoom::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_panel.contains(pointLocation))
+		return kCursorMagnifyingGlass;
+
+	return kCursorArrow;
+}
+
 class NormalTransporter : public SceneBase {
 public:
 	NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -798,6 +858,82 @@ int CheeseGirlPod::specifyCursor(Window *viewWindow, const Common::Point &pointL
 	return kCursorArrow;
 }
 
+class TransporterStatusRead : public SceneBase {
+public:
+	TransporterStatusRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int gdiPaint(Window *viewWindow);
+	int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	int _currentRegion;
+	Common::Rect _transRegions[3];
+};
+
+TransporterStatusRead::TransporterStatusRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_currentRegion = -1;
+	_transRegions[0] = Common::Rect(184, 40, 208, 62);
+	_transRegions[1] = Common::Rect(221, 55, 245, 77);
+	_transRegions[2] = Common::Rect(262, 39, 286, 61);
+}
+
+int TransporterStatusRead::gdiPaint(Window *viewWindow) {
+	if (_currentRegion >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+		Common::Rect rect(_transRegions[_currentRegion]);
+		rect.translate(absoluteRect.left, absoluteRect.top);
+		_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
+	}
+
+	return SC_REPAINT;
+}
+
+int TransporterStatusRead::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
+		bool found = false;
+
+		for (int i = 0; i < 3 && !found; i++) {
+			if (_transRegions[i].contains(pointLocation)) {
+				found = true;
+
+				if (_currentRegion != i) {
+					_currentRegion = i;
+					viewWindow->invalidateWindow(false);
+					((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(IDS_AS_RA_POD_A_STATUS_TEXT + i));
+				}
+			}
+		}
+
+		if (!found && _currentRegion >= 0) {
+			_currentRegion = -1;
+			viewWindow->invalidateWindow(false);
+			((SceneViewWindow *)viewWindow)->displayLiveText();
+		}
+
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int TransporterStatusRead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	DestinationScene destData;
+	destData.destinationScene = _staticData.location;
+	destData.destinationScene.depth = 0;
+	destData.transitionType = TRANSITION_VIDEO;
+	destData.transitionData = 7;
+	destData.transitionStartFrame = -1;
+	destData.transitionLength = -1;
+	((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+	return SC_TRUE;
+}
+
+int TransporterStatusRead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	return kCursorPutDown;
+}
+
 bool SceneViewWindow::initializeAlienTimeZoneAndEnvironment(Window *viewWindow, int environment) {
 	if (environment == -1) {
 		GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
@@ -821,13 +957,16 @@ bool SceneViewWindow::startAlienAmbient(int oldTimeZone, int oldEnvironment, int
 	return true;
 }
 
-
 SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	// TODO
 
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new ArmControls(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 2:
+		return new EncounterAmbassadorFirstZoom(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 3:
+		return new TransporterStatusRead(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 4:
 		return new OpenAlienDoorA(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 5:


Commit: 46bbc3d63a5818852bafe70ef9b920e96ccc011b
    https://github.com/scummvm/scummvm/commit/46bbc3d63a5818852bafe70ef9b920e96ccc011b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the final sequence

El fin.

Changed paths:
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 1e0fb226ad..d36fdd871f 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -663,6 +663,156 @@ int EncounterAmbassadorFirstZoom::specifyCursor(Window *viewWindow, const Common
 	return kCursorArrow;
 }
 
+class AmbassadorEncounterPodField : public SceneBase {
+public:
+	AmbassadorEncounterPodField(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int timerCallback(Window *viewWindow);
+
+private:
+	uint32 _timerStart;
+};
+
+AmbassadorEncounterPodField::AmbassadorEncounterPodField(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_timerStart = 0;
+}
+
+int AmbassadorEncounterPodField::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_timerStart = g_system->getMillis();
+	return SC_TRUE;
+}
+
+int AmbassadorEncounterPodField::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemBurnedOutCore)
+		return 1;
+
+	return 0;
+}
+
+int AmbassadorEncounterPodField::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
+	if (itemID == kItemBurnedOutCore) {
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 2;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 20;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SIC_ACCEPT;
+	}
+
+	return SIC_REJECT;
+}
+
+int AmbassadorEncounterPodField::timerCallback(Window *viewWindow) {
+	if (_timerStart != 0 && (_timerStart + 30000) < g_system->getMillis()) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(19);
+		((SceneViewWindow *)viewWindow)->showDeathScene(51);
+		return SC_DEATH;
+	}
+
+	SceneBase::timerCallback(viewWindow);
+	return SC_TRUE;
+}
+
+class AmbassadorEncounterPodWalkForward : public SceneBase {
+public:
+	AmbassadorEncounterPodWalkForward(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int timerCallback(Window *viewWindow);
+
+private:
+	uint32 _timerStart;
+};
+
+AmbassadorEncounterPodWalkForward::AmbassadorEncounterPodWalkForward(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_timerStart = 0;
+}
+
+int AmbassadorEncounterPodWalkForward::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_timerStart = g_system->getMillis();
+	return SC_TRUE;
+}
+
+int AmbassadorEncounterPodWalkForward::timerCallback(Window *viewWindow) {
+	if (_timerStart != 0 && (_timerStart + 15000) < g_system->getMillis()) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(21);
+		((SceneViewWindow *)viewWindow)->showDeathScene(55);
+		return SC_DEATH;
+	}
+
+	SceneBase::timerCallback(viewWindow);
+	return SC_TRUE;
+}
+
+class AmbassadorEncounterTransportArmsOff : public SceneBase {
+public:
+	AmbassadorEncounterTransportArmsOff(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
+	int timerCallback(Window *viewWindow);
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+
+private:
+	uint32 _timerStart;
+	Common::Rect _transportButton;
+};
+
+AmbassadorEncounterTransportArmsOff::AmbassadorEncounterTransportArmsOff(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	_timerStart = 0;
+	_transportButton = Common::Rect(258, 38, 288, 82);
+}
+
+int AmbassadorEncounterTransportArmsOff::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	_timerStart = g_system->getMillis();
+	return SC_TRUE;
+}
+
+int AmbassadorEncounterTransportArmsOff::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_transportButton.contains(pointLocation)) {
+		// Congrats, you defeated Icarus!
+		_timerStart = 0;
+
+		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreDefeatedIcarus = 1;
+
+		DestinationScene destData;
+		destData.destinationScene = _staticData.location;
+		destData.destinationScene.depth = 0;
+		destData.transitionType = TRANSITION_VIDEO;
+		destData.transitionData = 24;
+		destData.transitionStartFrame = -1;
+		destData.transitionLength = -1;
+		((SceneViewWindow *)viewWindow)->moveToDestination(destData);
+		return SC_TRUE;
+	}
+
+	return SC_FALSE;
+}
+
+int AmbassadorEncounterTransportArmsOff::timerCallback(Window *viewWindow) {
+	if (_timerStart != 0 && (_timerStart + 20000) < g_system->getMillis()) {
+		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(23);
+		((SceneViewWindow *)viewWindow)->showDeathScene(54);
+		return SC_DEATH;
+	}
+
+	SceneBase::timerCallback(viewWindow);
+	return SC_TRUE;
+}
+
+int AmbassadorEncounterTransportArmsOff::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
+	if (_transportButton.contains(pointLocation))
+		return kCursorFinger;
+
+	return kCursorArrow;
+}
+
 class NormalTransporter : public SceneBase {
 public:
 	NormalTransporter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -977,6 +1127,12 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new AlienDoorBOpen(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 8:
 		return new AlienDoorBEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 9:
+		return new AmbassadorEncounterPodField(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 10:
+		return new AmbassadorEncounterPodWalkForward(_vm, viewWindow, sceneStaticData, priorLocation);
+	case 11:
+		return new AmbassadorEncounterTransportArmsOff(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 12:
 		return new NormalTransporter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 13:


Commit: e9ec786111e2483498fda533c652cc5d854f373d
    https://github.com/scummvm/scummvm/commit/e9ec786111e2483498fda533c652cc5d854f373d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix missing puzzle score flag

Changed paths:
    engines/buried/complete.cpp
    engines/buried/death.cpp


diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index 2a51b7bfbe..9a9716fa0b 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -87,6 +87,7 @@ CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, GlobalFlags
 	CHECK_PUZZLE_FLAG(scoreLoggedCodexEvidence);
 	CHECK_PUZZLE_FLAG(scoreEnteredMainCavern);
 	CHECK_PUZZLE_FLAG(scoreGotWealthGodPiece);
+	CHECK_PUZZLE_FLAG(scoreGotRainGodPiece);
 	CHECK_PUZZLE_FLAG(scoreGotWarGodPiece);
 	CHECK_PUZZLE_FLAG(scoreCompletedDeathGod);
 	CHECK_PUZZLE_FLAG(scoreEliminatedAgent3);
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index da69107cad..d2188fe462 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -130,6 +130,7 @@ DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex,
 	CHECK_PUZZLE_FLAG(scoreLoggedCodexEvidence);
 	CHECK_PUZZLE_FLAG(scoreEnteredMainCavern);
 	CHECK_PUZZLE_FLAG(scoreGotWealthGodPiece);
+	CHECK_PUZZLE_FLAG(scoreGotRainGodPiece);
 	CHECK_PUZZLE_FLAG(scoreGotWarGodPiece);
 	CHECK_PUZZLE_FLAG(scoreCompletedDeathGod);
 	CHECK_PUZZLE_FLAG(scoreEliminatedAgent3);


Commit: 05ee6ecf063e32cd880d202864ee65c2792822dc
    https://github.com/scummvm/scummvm/commit/05ee6ecf063e32cd880d202864ee65c2792822dc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement internal load/save dialog boxes

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/buried.h
    engines/buried/death.cpp
    engines/buried/main_menu.cpp
    engines/buried/saveload.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 5c6f96ed80..59bfcd3e3c 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -28,6 +28,7 @@
 #include "buried/biochip_view.h"
 #include "buried/buried.h"
 #include "buried/fbcdata.h"
+#include "buried/frame_window.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
@@ -35,6 +36,7 @@
 #include "buried/resources.h"
 #include "buried/scene_view.h"
 
+#include "common/error.h"
 #include "common/stream.h"
 #include "common/system.h"
 #include "graphics/surface.h"
@@ -584,10 +586,23 @@ void InterfaceBioChipViewWindow::onLButtonDown(const Common::Point &point, uint
 void InterfaceBioChipViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	switch (_curRegion) {
 	case REGION_SAVE:
-		// TODO
+		if (!_vm->isDemo())
+			_vm->runSaveDialog();
 		break;
 	case REGION_RESTORE:
-		// TODO
+		if (!_vm->isDemo()) {
+			FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
+			Common::Error result = _vm->runLoadDialog();
+
+			if (result.getCode() == Common::kUnknownError) {
+				// Try to get us back to the main menu at this point
+				frameWindow->showMainMenu();
+				return;
+			} else if (result.getCode() == Common::kNoError) {
+				// Loaded successfully
+				return;
+			}
+		}
 		break;
 	case REGION_QUIT:
 		// TODO
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index c8b82cff33..37373d13e1 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -134,6 +134,8 @@ public:
 	static Common::StringArray listSaveFiles();
 	bool loadState(Common::SeekableReadStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems);
 	bool saveState(Common::WriteStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems);
+	Common::Error runSaveDialog();
+	Common::Error runLoadDialog();
 
 private:
 	Database *_library;
diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index d2188fe462..7d1b9091c1 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -32,6 +32,7 @@
 #include "buried/resources.h"
 #include "buried/sound.h"
 
+#include "common/error.h"
 #include "graphics/font.h"
 #include "graphics/surface.h"
 
@@ -371,7 +372,18 @@ void DeathWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			if (_walkthroughMode) {
 				// TODO: Do fake continue
 			} else {
-				// TODO: Show restore game window
+				// Show restore game window
+				FrameWindow *frameWindow = (FrameWindow *)_parent;
+				Common::Error result = _vm->runLoadDialog();
+
+				if (result.getCode() == Common::kUnknownError) {
+					// Try to get us back to the main menu at this point
+					frameWindow->showMainMenu();
+					return;
+				} else if (result.getCode() == Common::kNoError) {
+					// Loaded successfully
+					return;
+				}
 			}
 		}
 		break;
diff --git a/engines/buried/main_menu.cpp b/engines/buried/main_menu.cpp
index 617a2d3c43..91954cd05c 100644
--- a/engines/buried/main_menu.cpp
+++ b/engines/buried/main_menu.cpp
@@ -30,6 +30,7 @@
 #include "buried/resources.h"
 #include "buried/sound.h"
 
+#include "common/error.h"
 #include "graphics/surface.h"
 
 namespace Buried {
@@ -199,9 +200,21 @@ void MainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			// TODO: Easter egg with control down
 			((FrameWindow *)_parent)->startNewGame(_walkthrough, _showIntro);
 			return;
-		case BUTTON_RESTORE_GAME:
-			// TODO
+		case BUTTON_RESTORE_GAME: {
+			FrameWindow *frameWindow = (FrameWindow *)_parent;
+			Common::Error result = _vm->runLoadDialog();
+
+			if (result.getCode() == Common::kUnknownError) {
+				// Try to get us back to the main menu at this point
+				frameWindow->showMainMenu();
+				return;
+			} else if (result.getCode() == Common::kNoError) {
+				// Loaded successfully
+				return;
+			}
+
 			break;
+		}
 		case BUTTON_CREDITS:
 			((FrameWindow *)_parent)->showCredits();
 			return;
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index 04fb31e5df..f49cf53156 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -24,11 +24,13 @@
  */
 
 #include "common/scummsys.h"
+#include "common/config-manager.h"
 #include "common/error.h"
 #include "common/savefile.h"
 #include "common/serializer.h"
 #include "common/system.h"
 #include "common/translation.h"
+#include "gui/saveload.h"
 
 #include "buried/buried.h"
 #include "buried/frame_window.h"
@@ -494,4 +496,52 @@ bool BuriedEngine::syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags) {
 	return s.bytesSynced() - startBytes == 1024;
 }
 
+Common::Error BuriedEngine::runLoadDialog() {
+	GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false);
+
+	Common::String gameId = ConfMan.get("gameid");
+
+	const EnginePlugin *plugin = 0;
+	EngineMan.findGame(gameId, &plugin);
+
+	int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+
+	Common::Error result;
+
+	if (slot >= 0) {
+		if (loadGameState(slot).getCode() == Common::kNoError)
+			result = Common::kNoError;
+		else
+			result = Common::kUnknownError;
+	} else {
+		result = Common::kUserCanceled;
+	}
+
+	return result;
+}
+
+Common::Error BuriedEngine::runSaveDialog() {
+	GUI::SaveLoadChooser slc(_("Save game:"), _("Save"), true);
+
+	Common::String gameId = ConfMan.get("gameid");
+
+	const EnginePlugin *plugin = 0;
+	EngineMan.findGame(gameId, &plugin);
+
+	int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+
+	Common::Error result;
+
+	if (slot >= 0) {
+		if (saveGameState(slot, slc.getResultString()).getCode() == Common::kNoError)
+			result = Common::kNoError;
+		else
+			result = Common::kUnknownError;
+	} else {
+		result = Common::kUserCanceled;
+	}
+
+	return result;
+}
+
 } // End of namespace Buried


Commit: 3273594eac6c9a9ba84b3f699c208b69004a1cf8
    https://github.com/scummvm/scummvm/commit/3273594eac6c9a9ba84b3f699c208b69004a1cf8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement returning to the main menu

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/scene_view.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 59bfcd3e3c..9aa37df316 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -605,7 +605,10 @@ void InterfaceBioChipViewWindow::onLButtonUp(const Common::Point &point, uint fl
 		}
 		break;
 	case REGION_QUIT:
-		// TODO
+		if (_vm->runQuitDialog()) {
+			((FrameWindow *)_vm->_mainWindow)->showMainMenu();
+			return;
+		}
 		break;
 	case REGION_PAUSE:
 		// TODO
diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b0e692425e..e8932cf0a9 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -33,6 +33,7 @@
 #include "common/textconsole.h"
 #include "common/translation.h"
 #include "engines/util.h"
+#include "gui/message.h"
 
 #include "buried/buried.h"
 #include "buried/console.h"
@@ -461,4 +462,11 @@ void BuriedEngine::pauseEngineIntern(bool pause) {
 	}
 }
 
+bool BuriedEngine::runQuitDialog() {
+	// TODO: Would be nice to load the text out of the EXE for this
+	// v1.04+: IDS_APP_MESSAGE_QUIT_TEXT (9024)
+	GUI::MessageDialog dialog(_("Are you sure you want to quit?"), _("Yes"), _("No"));
+	return dialog.runModal() == GUI::kMessageOK;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 37373d13e1..f8b7e8c986 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -125,6 +125,7 @@ public:
 	int getTransitionSpeed();
 	void setTransitionSpeed(int newSpeed);
 	void releaseCapture() { _captureWindow = 0; }
+	bool runQuitDialog();
 
 	// Save/Load
 	bool canLoadGameStateCurrently();
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index c77827523c..7e3e0689f7 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2436,7 +2436,9 @@ void SceneViewWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 		break;
 	case Common::KEYCODE_q:
 		if (key.flags & Common::KBD_CTRL) {
-			// TODO: Return to main menu
+			// Return to main menu
+			if (_vm->runQuitDialog())
+				((FrameWindow *)_vm->_mainWindow)->showMainMenu();
 			return;
 		}
 		break;


Commit: 4687e061cacce4e692c1617882e8947d6141b384
    https://github.com/scummvm/scummvm/commit/4687e061cacce4e692c1617882e8947d6141b384
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Remove some obsolete TODOs

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/alien.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index c15fde2ad7..6281fb8e0f 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -3776,8 +3776,6 @@ bool SceneViewWindow::checkCustomSpaceStationAICommentDependencies(const Locatio
 }
 
 SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new UseCheeseGirlPropellant(_vm, viewWindow, sceneStaticData, priorLocation);
@@ -3935,7 +3933,7 @@ SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const
 	case 100:
 		return new TakeWaterCanister(_vm, viewWindow, sceneStaticData, priorLocation);
 	default:
-		warning("TODO: AI lab scene object %d", sceneStaticData.classID);
+		warning("Unknown AI lab scene object %d", sceneStaticData.classID);
 		break;
 	}
 
diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index d36fdd871f..e2670f5229 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -1108,8 +1108,6 @@ bool SceneViewWindow::startAlienAmbient(int oldTimeZone, int oldEnvironment, int
 }
 
 SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new ArmControls(_vm, viewWindow, sceneStaticData, priorLocation);
@@ -1171,7 +1169,7 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
 	}
 
-	warning("TODO: Alien scene object %d", sceneStaticData.classID);
+	warning("Unknown Alien scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index c5602b09d3..30c3352668 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -2582,8 +2582,6 @@ bool SceneViewWindow::checkCustomDaVinciAICommentDependencies(const Location &co
 }
 
 SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new SwapStillOnFlag(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsPTElevatorPresent), 1);
@@ -2741,7 +2739,7 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new CodexFormulaeNotify(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
-	warning("TODO: Da Vinci scene object %d", sceneStaticData.classID);
+	warning("Unknown Da Vinci scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 3a744ed4c4..45f770f2c7 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1970,8 +1970,6 @@ bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnviro
 }
 
 SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new ClickPlayVideoSwitchAI(_vm, viewWindow, sceneStaticData, priorLocation, 0, kCursorFinger, offsetof(GlobalFlags, faKICoffeeSpilled), 212, 114, 246, 160);
@@ -2079,7 +2077,7 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new EnvironDoorExitSound(_vm, viewWindow, sceneStaticData, priorLocation);
 	}
 
-	warning("TODO: Future apartment scene object %d", sceneStaticData.classID);
+	warning("Unknown Future apartment scene object %d", sceneStaticData.classID);
 
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 1a3182c528..2bf4c77283 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -2351,8 +2351,6 @@ bool SceneViewWindow::checkCustomMayanAICommentDependencies(const Location &comm
 }
 
 SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
 	case 1:
 		return new VideoDeath(_vm, viewWindow, sceneStaticData, priorLocation, 10, IDS_HUMAN_PRESENCE_500METERS);
@@ -2544,7 +2542,7 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WT_ALTAR_TEXT, 106, 128, 344, 162);
 	}
 
-	warning("TODO: Mayan scene object %d", sceneStaticData.classID);
+	warning("Unknown Mayan scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 


Commit: 80db452ed4aff5a452effbac4575c1a960669b66
    https://github.com/scummvm/scummvm/commit/80db452ed4aff5a452effbac4575c1a960669b66
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Have the frame window keep focus instead of one of its child windows

Changed paths:
    engines/buried/frame_window.cpp


diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index b960435891..54e736203e 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -248,7 +248,7 @@ bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
 	// Create Game UI window to kick things off
 	_mainChildWindow = new GameUIWindow(_vm, this);
 	_mainChildWindow->showWindow(kWindowShow);
-	_mainChildWindow->setFocus();
+	setFocus();
 
 	if (introMovie)
 		((GameUIWindow *)_mainChildWindow)->startNewGameIntro(walkthrough);
@@ -271,7 +271,7 @@ bool FrameWindow::startNewGame(const Common::String &fileName) {
 	// Create Game UI window to kick things off
 	_mainChildWindow = new GameUIWindow(_vm, this);
 	_mainChildWindow->showWindow(kWindowShow);
-	_mainChildWindow->setFocus();
+	setFocus();
 	((GameUIWindow *)_mainChildWindow)->startNewGame(fileName);
 
 	_vm->removeMouseMessages(this);
@@ -400,7 +400,7 @@ void FrameWindow::loadFromState(const Location &location, const GlobalFlags &fla
 		delete _mainChildWindow;
 		_mainChildWindow = new GameUIWindow(_vm, this);
 		_mainChildWindow->showWindow(kWindowShow);
-		_mainChildWindow->setFocus();
+		setFocus();
 	}
 
 	GameUIWindow *gameUI = (GameUIWindow *)_mainChildWindow;


Commit: 8de136a125a867ee9eba2a449c7f923d39011741
    https://github.com/scummvm/scummvm/commit/8de136a125a867ee9eba2a449c7f923d39011741
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement escape-to-quit

Changed paths:
    engines/buried/frame_window.cpp


diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 54e736203e..e9640bf38e 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -363,7 +363,14 @@ void FrameWindow::onKeyDown(const Common::KeyState &key, uint flags) {
 	_controlDown = (key.flags & Common::KBD_CTRL) != 0;
 
 	if (key.keycode == Common::KEYCODE_ESCAPE) {
-		// TODO: Possibly quit
+		if (_gameInProgress || !_atMainMenu) {
+			// Ask if the player wants to return 
+			if (_vm->runQuitDialog())
+				showMainMenu();
+		} else {
+			// Quit from the main menu
+			_vm->quitGame();
+		}
 	}
 }
 


Commit: e9542e6e67b4f5d45edbcff15bb9bc19a060e5df
    https://github.com/scummvm/scummvm/commit/e9542e6e67b4f5d45edbcff15bb9bc19a060e5df
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Use runLoadDialog/runSaveDialog instead of the old save/load code

Changed paths:
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h
    engines/buried/gameui.cpp
    engines/buried/gameui.h
    engines/buried/scene_view.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index e9640bf38e..ca51f4370e 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -260,25 +260,6 @@ bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
 	return true;
 }
 
-bool FrameWindow::startNewGame(const Common::String &fileName) {
-	_gameInProgress = true;
-	_atMainMenu = false;
-
-	_vm->removeMouseMessages(this);
-
-	delete _mainChildWindow;
-
-	// Create Game UI window to kick things off
-	_mainChildWindow = new GameUIWindow(_vm, this);
-	_mainChildWindow->showWindow(kWindowShow);
-	setFocus();
-	((GameUIWindow *)_mainChildWindow)->startNewGame(fileName);
-
-	_vm->removeMouseMessages(this);
-	_vm->removeMouseMessages(_mainChildWindow);
-	return true;
-}
-
 bool FrameWindow::showDeathScene(int deathSceneIndex, GlobalFlags globalFlags) {
 	_gameInProgress = false;
 	_atMainMenu = false;
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index db3798c7ca..96ffab489b 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -45,7 +45,6 @@ public:
 	bool showClosingScreen();
 	bool showFeaturesScreen();
 	bool startNewGame(bool walkthrough = false, bool introMovie = false);
-	bool startNewGame(const Common::String &fileName);
 	// TODO: startNewGame with continue data
 	bool showDeathScene(int deathSceneIndex, GlobalFlags globalFlags);
 	bool showCompletionScene(GlobalFlags globalFlags);
diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index d96b995d82..f05f5dae03 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -25,6 +25,7 @@
 
 #include "buried/biochip_right.h"
 #include "buried/buried.h"
+#include "buried/frame_window.h"
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/invdata.h"
@@ -37,6 +38,7 @@
 #include "buried/sound.h"
 #include "buried/video_window.h"
 
+#include "common/error.h"
 #include "common/keyboard.h"
 #include "common/system.h"
 #include "graphics/surface.h"
@@ -130,41 +132,6 @@ bool GameUIWindow::startNewGame(const Location &startingLocation) {
 	return true;
 }
 
-bool GameUIWindow::startNewGame(const Common::String &fileName) {
-	_doNotDraw = false;
-	showWindow(kWindowShow);
-	invalidateWindow(false);
-
-	_navArrowWindow->showWindow(kWindowShow);
-	_liveTextWindow->showWindow(kWindowShow);
-	_sceneViewWindow->showWindow(kWindowShow);
-	_inventoryWindow->showWindow(kWindowShow);
-	_bioChipRightWindow->showWindow(kWindowShow);
-	_sceneViewWindow->startNewGame(fileName);
-
-	return true;
-}
-
-bool GameUIWindow::loadGame() {
-	_doNotDraw = false;
-
-	// TODO;
-
-	return false;
-}
-
-bool GameUIWindow::loadGame(const Common::String &fileName) {
-	// TODO
-
-	return true;
-}
-
-bool GameUIWindow::saveGame() {
-	// TODO
-
-	return false;
-}
-
 bool GameUIWindow::changeCurrentDate(int timeZoneID) {
 	switch (timeZoneID) {
 	case 1:
@@ -341,7 +308,7 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 			_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
 			_bioChipRightWindow->invalidateWindow(false);
 			_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 130), 0));
-			saveGame();
+			_vm->runSaveDialog();
 			return;
 		}
 		// Fall through
@@ -351,7 +318,9 @@ void GameUIWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 			_bioChipRightWindow->changeCurrentBioChip(kItemBioChipInterface);
 			_bioChipRightWindow->invalidateWindow(false);
 			_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 130), 0));
-			loadGame();
+
+			if (_vm->runLoadDialog().getCode() == Common::kUnknownError)
+				((FrameWindow *)_vm->_mainWindow)->showMainMenu();
 			return;
 		}
 		// Fall through
diff --git a/engines/buried/gameui.h b/engines/buried/gameui.h
index 84c10b403d..849388c99d 100644
--- a/engines/buried/gameui.h
+++ b/engines/buried/gameui.h
@@ -49,11 +49,7 @@ public:
 	bool startNewGame(bool walkthrough = false);
 	bool startNewGameIntro(bool walkthrough = false);
 	bool startNewGame(const Location &startingLocation);
-	bool startNewGame(const Common::String &fileName);
 	// startNewGame(continue data, location struct);
-	bool loadGame();
-	bool loadGame(const Common::String &fileName);
-	bool saveGame();
 	bool changeCurrentDate(int timeZoneID);
 	bool flashWarningLight();
 	bool setWarningState(bool newState);
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 7e3e0689f7..4ef8b32910 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -194,12 +194,6 @@ bool SceneViewWindow::startNewGame(const Location &startingLocation) {
 	return true;
 }
 
-bool SceneViewWindow::startNewGame(const Common::String &restoreFile) {
-	((GameUIWindow *)_parent)->loadGame(restoreFile);
-	invalidateWindow(false);
-	return true;
-}
-
 bool SceneViewWindow::showDeathScene(int deathSceneIndex) {
 	return ((FrameWindow *)(_parent->getParent()))->showDeathScene(deathSceneIndex, _globalFlags); // TODO: Inventory
 }
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 4179d91b06..24a29b4f30 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -55,7 +55,6 @@ public:
 	bool startNewGame(bool walkthrough = false);
 	bool startNewGameIntro(bool walkthrough = false);
 	bool startNewGame(const Location &startingLocation);
-	bool startNewGame(const Common::String &restoreFile);
 	bool showDeathScene(int deathSceneIndex);
 	bool showCompletionScene();
 


Commit: 948a6a55aeec8519338ba051e3caab45cb388fd0
    https://github.com/scummvm/scummvm/commit/948a6a55aeec8519338ba051e3caab45cb388fd0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement control down

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/demo/demo_menu.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h
    engines/buried/main_menu.cpp
    engines/buried/scene_view.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index e8932cf0a9..9232f7beef 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -469,4 +469,8 @@ bool BuriedEngine::runQuitDialog() {
 	return dialog.runModal() == GUI::kMessageOK;
 }
 
+bool BuriedEngine::isControlDown() const {
+	return _mainWindow && ((FrameWindow *)_mainWindow)->_controlDown;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index f8b7e8c986..6440268d01 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -126,6 +126,7 @@ public:
 	void setTransitionSpeed(int newSpeed);
 	void releaseCapture() { _captureWindow = 0; }
 	bool runQuitDialog();
+	bool isControlDown() const;
 
 	// Save/Load
 	bool canLoadGameStateCurrently();
diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
index bbfc34cc37..ed4286051d 100644
--- a/engines/buried/demo/demo_menu.cpp
+++ b/engines/buried/demo/demo_menu.cpp
@@ -155,7 +155,11 @@ void DemoMainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	case BUTTON_INTERACTIVE:
 		if (_interactive.contains(point)) {
 			_vm->_sound->setAmbientSound();
-			// TODO: Reviewer mode check (control)
+
+			// Reviewer mode check (control)
+			if (_vm->isControlDown())
+				((FrameWindow *)_parent)->_reviewerMode = true;
+
 			((FrameWindow *)_parent)->startNewGame();
 		}
 		return;
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 30c3352668..8e6dd7ad05 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -1920,9 +1920,9 @@ int PaintingTowerCapAgent::postEnterRoom(Window *viewWindow, const Location &pri
 		// Set flag for scoring
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreResearchAgent3DaVinci = 1;
 	} else {
-		if (false) { // TODO: If control down
+		// Moonwalk
+		if (_vm->isControlDown())
 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
-		}
 	}
 
 	return SC_TRUE;
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index ca51f4370e..176f904807 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -145,6 +145,7 @@ bool FrameWindow::showMainMenu() {
 		((MainMenuWindow *)_mainChildWindow)->showMainMenu();
 	}
 
+	setFocus();
 	_vm->removeMouseMessages(this);
 	_vm->removeMouseMessages(_mainChildWindow);
 	return true;
@@ -171,6 +172,8 @@ bool FrameWindow::returnToMainMenu() {
 		((MainMenuWindow *)_mainChildWindow)->showMainMenu();
 	}
 
+	setFocus();
+
 	// Empty input queue
 	_vm->removeMouseMessages(this);
 	_vm->removeMouseMessages(_mainChildWindow);
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index 96ffab489b..9a73fe136d 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -66,6 +66,7 @@ public:
 	bool isFrameCachingAllowed() const { return _cacheFrames; }
 
 	bool _reviewerMode;
+	bool _controlDown;
 
 	bool isGameInProgress() const { return _gameInProgress; }
 	Window *getMainChildWindow() const { return _mainChildWindow; }
@@ -73,7 +74,6 @@ public:
 
 private:
 	Window *_mainChildWindow;
-	bool _controlDown;
 
 	bool _cacheFrames;
 	bool _cycleDefault;
diff --git a/engines/buried/main_menu.cpp b/engines/buried/main_menu.cpp
index 91954cd05c..34faf8ff39 100644
--- a/engines/buried/main_menu.cpp
+++ b/engines/buried/main_menu.cpp
@@ -29,6 +29,7 @@
 #include "buried/main_menu.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
+#include "buried/video_window.h"
 
 #include "common/error.h"
 #include "graphics/surface.h"
@@ -197,8 +198,37 @@ void MainMenuWindow::onLButtonUp(const Common::Point &point, uint flags) {
 			((FrameWindow *)_parent)->showOverview();
 			return;
 		case BUTTON_NEW_GAME:
-			// TODO: Easter egg with control down
-			((FrameWindow *)_parent)->startNewGame(_walkthrough, _showIntro);
+			if (_vm->isControlDown()) {
+				// Easter egg
+				_disableDrawing = true;
+				invalidateWindow(false);
+
+				// Play the intro movie
+				VideoWindow *video = new VideoWindow(_vm, this);
+
+				if (video->openVideo("BITDATA/INTRO/INTRO_O.BTV")) {
+					video->setWindowPos(0, 104, 145, 0, 0, kWindowPosNoSize | kWindowPosNoZOrder);
+					video->enableWindow(false);
+					video->showWindow(kWindowShow);
+					_vm->_sound->stop();
+					video->playVideo();
+
+					while (!_vm->shouldQuit() && video->getMode() != VideoWindow::kModeStopped)
+						_vm->yield();
+
+					_vm->_sound->restart();
+				}
+
+				delete video;
+
+				if (_vm->shouldQuit())
+					return;
+
+				_disableDrawing = false;
+				invalidateWindow(false);
+			} else {
+				((FrameWindow *)_parent)->startNewGame(_walkthrough, _showIntro);
+			}
 			return;
 		case BUTTON_RESTORE_GAME: {
 			FrameWindow *frameWindow = (FrameWindow *)_parent;
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 4ef8b32910..6a9f739d10 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -899,7 +899,7 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 	// Call the appropriate function for the transition type
 	switch (destinationData.transitionType) {
 	case TRANSITION_PUSH:
-		if (false) { // TODO: control down check
+		if (_vm->isControlDown()) {
 			if (navFrame >= 0) {
 				LocationStaticData destinationStaticData;
 				if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))
@@ -933,7 +933,7 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 		}
 		break;
 	case TRANSITION_WALK:
-		if (false) { // TODO: control down check
+		if (_vm->isControlDown()) {
 			if (navFrame >= 0) {
 				LocationStaticData destinationStaticData;
 				if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))
@@ -952,7 +952,7 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 		}
 		break;
 	case TRANSITION_VIDEO:
-		if (false) { // TODO: control down check and debug mode check (maybe?)
+		if (_vm->isControlDown() && false) { // TODO: debug mode check (maybe?)
 			if (navFrame >= 0) {
 				LocationStaticData destinationStaticData;
 				if (!getSceneStaticData(destinationData.destinationScene, destinationStaticData))


Commit: 43ea41678bd7d9a9a8daec69048dc310dc8a4836
    https://github.com/scummvm/scummvm/commit/43ea41678bd7d9a9a8daec69048dc310dc8a4836
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement the pause button

Changed paths:
    engines/buried/biochip_view.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 9aa37df316..cbba3cabaa 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -39,7 +39,9 @@
 #include "common/error.h"
 #include "common/stream.h"
 #include "common/system.h"
+#include "common/translation.h"
 #include "graphics/surface.h"
+#include "gui/message.h"
 
 namespace Buried {
 
@@ -611,7 +613,15 @@ void InterfaceBioChipViewWindow::onLButtonUp(const Common::Point &point, uint fl
 		}
 		break;
 	case REGION_PAUSE:
-		// TODO
+		if (!_vm->isDemo()) {
+			((SceneViewWindow *)getParent()->getParent())->_paused = true;
+
+			// TODO: Would be nice to load the translated text from IDS_APP_MESSAGE_PAUSED_TEXT (9023)
+			GUI::MessageDialog dialog(_("Your game is now Paused.  Click OK to continue."));
+			dialog.runModal();
+
+			((SceneViewWindow *)getParent()->getParent())->_paused = false;
+		}
 		break;
 	case REGION_FLICKER:
 		if (_flicker.contains(point)) {


Commit: 9739542b736dd2d7c23df83c91e817fc13e08c0c
    https://github.com/scummvm/scummvm/commit/9739542b736dd2d7c23df83c91e817fc13e08c0c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
CREDITS: Add credits for buried

Changed paths:
    AUTHORS
    devtools/credits.pl
    gui/credits.h


diff --git a/AUTHORS b/AUTHORS
index b01d51378a..1fb5849d97 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -121,6 +121,9 @@ ScummVM Team
        Peter Kohaut
        Eugene Sandulenko
 
+    Buried:
+       Matthew Hoops
+
     CGE:
        Arnaud Boutonne
        Paul Gilbert
@@ -1085,8 +1088,9 @@ Special thanks to
    Jan Nedoma for providing the sources to the Wintermute-engine, and for his
    support while porting the engine to ScummVM.
 
-   Bob Bell, Michel Kripalani, Tommy Yune, from Presto Studios for providing
-   the source code of The Journeyman Project: Pegasus Prime.
+   Bob Bell, David Black, Michel Kripalani, and Tommy Yune from Presto
+   Studios for providing the source code of The Journeyman Project: Pegasus
+   Prime and The Journeyman Project 2: Buried in Time.
 
    Electronic Arts IP Preservation Team, particularly Stefan Serbicki, and
    Vasyl Tsvirkunov of Electronic Arts for providing the source code of the
diff --git a/devtools/credits.pl b/devtools/credits.pl
index fdb79a5881..564d499903 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -690,6 +690,10 @@ begin_credits("Credits");
 				add_person("Eugene Sandulenko", "sev", "");
 			end_section();
 
+			begin_section("Buried");
+				add_person("Matthew Hoops", "clone2727", "");
+			end_section();
+
 			begin_section("CGE");
 				add_person("Arnaud Boutonné", "Strangerke", "");
 				add_person("Paul Gilbert", "dreammaster", "");
@@ -1696,6 +1700,7 @@ begin_credits("Credits");
 			add_person("Anton Yartsev", "Zidane", "For the original re-implementation of the Z-Vision engine");
 		end_persons();
 
+<<<<<<< HEAD
 		add_paragraph(
 			"Tony Warriner and everyone at Revolution Software Ltd. for sharing ".
 			"with us the source of some of their brilliant games, allowing us to ".
@@ -1780,6 +1785,68 @@ begin_credits("Credits");
 
 		add_paragraph(
 			"Benjamin Haisch, for emimeshviewer, which our EMI code borrows heavily from.");
+=======
+	add_paragraph(
+    "Tony Warriner and everyone at Revolution Software Ltd. for sharing ".
+    "with us the source of some of their brilliant games, allowing us to ".
+    "release Beneath a Steel Sky as freeware... and generally being ".
+    "supportive above and beyond the call of duty.");
+
+	add_paragraph(
+    "John Passfield and Steve Stamatiadis for sharing the source of their ".
+    "classic title, Flight of the Amazon Queen and also being incredibly ".
+    "supportive.");
+
+	add_paragraph(
+    "Joe Pearce from The Wyrmkeep Entertainment Co. for sharing the source ".
+    "of their famous title Inherit the Earth and always prompt replies to ".
+    "our questions.");
+
+	add_paragraph(
+    "Aric Wilmunder, Ron Gilbert, David Fox, Vince Lee, and all those at ".
+    "LucasFilm/LucasArts who made SCUMM the insane mess to reimplement ".
+    "that it is today. Feel free to drop us a line and tell us what you ".
+    "think, guys!");
+
+	add_paragraph(
+    "Alan Bridgman, Simon Woodroffe and everyone at Adventure Soft for ".
+    "sharing the source code of some of their games with us.");
+
+	add_paragraph(
+    "John Young, Colin Smythe and especially Terry Pratchett himself for ".
+    "sharing the source code of Discworld I & II with us.");
+
+	add_paragraph(
+    "Emilio de Paz Aragón from Alcachofa Soft for sharing the source code ".
+    "of Drascula: The Vampire Strikes Back with us and his generosity with ".
+    "freewaring the game.");
+
+	add_paragraph(
+    "David P. Gray from Gray Design Associates for sharing the source code ".
+    "of the Hugo trilogy.");
+
+	add_paragraph(
+    "Broken Sword 2.5 team for providing sources of their engine and their great ".
+    "support.");
+
+	add_paragraph(
+    "Neil Dodwell and David Dew from Creative Reality for providing the source ".
+    "of Dreamweb and for their tremendous support.");
+
+	add_paragraph(
+    "Janusz Wiśniewski and Miroslaw Liminowicz from Laboratorium Komputerowe Avalon ".
+    "for providing full source code for Sołtys and Sfinx and letting us redistribute the games.");
+
+	add_paragraph(
+    "Jan Nedoma for providing the sources to the Wintermute-engine, and for his ".
+    "support while porting the engine to ScummVM.");
+
+	add_paragraph(
+    "Bob Bell, David Black, Michel Kripalani, and Tommy Yune from Presto Studios ".
+    "for providing the source code of The Journeyman Project: Pegasus Prime ".
+    "and The Journeyman Project 2: Buried in Time.");
+
+>>>>>>> 4fbf293bbf (CREDITS: Add credits for buried)
 	end_section();
 
 end_credits();
diff --git a/gui/credits.h b/gui/credits.h
index 9964655dea..f662c335b0 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -172,6 +172,9 @@ static const char *credits[] = {
 "C0""Peter Kohaut",
 "C0""Eugene Sandulenko",
 "",
+"C1""Buried",
+"C0""Matthew Hoops",
+"",
 "C1""CGE",
 "C0""Arnaud Boutonn\351",
 "C0""Paul Gilbert",
@@ -1325,7 +1328,7 @@ static const char *credits[] = {
 "C0""",
 "C0""Jan Nedoma for providing the sources to the Wintermute-engine, and for his support while porting the engine to ScummVM.",
 "C0""",
-"C0""Bob Bell, Michel Kripalani, Tommy Yune, from Presto Studios for providing the source code of The Journeyman Project: Pegasus Prime.",
+"C0""Bob Bell, David Black, Michel Kripalani, and Tommy Yune from Presto Studios for providing the source code of The Journeyman Project: Pegasus Prime and The Journeyman Project 2: Buried in Time.",
 "C0""",
 "C0""Electronic Arts IP Preservation Team, particularly Stefan Serbicki, and Vasyl Tsvirkunov of Electronic Arts for providing the source code of the two Lost Files of Sherlock Holmes games. James M. Ferguson and Barry Duncan for their tenacious efforts to recover the sources.",
 "C0""",


Commit: bdd386f883e40dc008888a6c19376e53af442c11
    https://github.com/scummvm/scummvm/commit/bdd386f883e40dc008888a6c19376e53af442c11
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement switching video audio tracks

Changed paths:
    engines/buried/scene_view.cpp
    engines/buried/video_window.cpp
    engines/buried/video_window.h


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 6a9f739d10..3e5e2ac175 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1475,7 +1475,9 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	if (!animationMovie->openVideo(fileName))
 		error("Failed to open video '%s'", fileName.c_str());
 
-	// TODO: Try switching to the second audio stream if translation is enabled
+	// Switch to the second audio stream if translation is enabled
+	if (_globalFlags.bcTranslateEnabled == 1 && animDatabase[i].audioStreamCount > 1)
+		animationMovie->setAudioTrack(2);
 
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
 		// FIXME: Nah, why bother to free the movie
@@ -1594,7 +1596,9 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 
 	animationMovie->setWindowPos(kWindowPosTopMost, left, top, 0, 0, kWindowPosNoSize | kWindowPosNoActivate | kWindowPosNoZOrder);
 
-	// TODO: Try switching to the second audio stream if translation is enabled
+	// Switch to the second audio stream if translation is enabled
+	if (_globalFlags.bcTranslateEnabled == 1 && animDatabase[i].audioStreamCount > 1)
+		animationMovie->setAudioTrack(2);
 
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
 		// FIXME: Nah, why bother to free the movie
@@ -1669,7 +1673,9 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 	animationMovie->setSourceRect(Common::Rect(left, top, right, bottom));
 	animationMovie->setDestRect(Common::Rect(0, 0, right - left, bottom - top));
 
-	// TODO: Try switching to the second audio stream if translation is enabled
+	// Switch to the second audio stream if translation is enabled
+	if (_globalFlags.bcTranslateEnabled == 1 && animDatabase[i].audioStreamCount > 1)
+		animationMovie->setAudioTrack(2);
 
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
 		// FIXME: Nah, why bother to free the movie
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index de8ce79790..4677025348 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -199,6 +199,11 @@ void VideoWindow::setDestRect(const Common::Rect &dstRect) {
 	_dstRect = dstRect;
 }
 
+void VideoWindow::setAudioTrack(int track) {
+	if (_video)
+		_video->setAudioTrack(track);
+}
+
 void VideoWindow::pauseVideo() {
 	if (_video)
 		_video->pauseVideo(true);
diff --git a/engines/buried/video_window.h b/engines/buried/video_window.h
index a22cbeb1d2..899fa8f4c2 100644
--- a/engines/buried/video_window.h
+++ b/engines/buried/video_window.h
@@ -54,6 +54,7 @@ public:
 	int getFrameCount(); // MCIWndGetLength
 	void setSourceRect(const Common::Rect &srcRect); // MCIWndPutSource
 	void setDestRect(const Common::Rect &dstRect); // MCIWndPutDest
+	void setAudioTrack(int track); // MCIWndSendString + "setaudio stream to %d"
 
 	bool openVideo(const Common::String &fileName); // MCIWndOpen
 	void closeVideo(); // MCIWndClose


Commit: 13e09b1e73fbc35d227b3e7707e9595d06216967
    https://github.com/scummvm/scummvm/commit/13e09b1e73fbc35d227b3e7707e9595d06216967
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Add support for the ms core fonts path for arial

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 3d8c0ec236..4953e0bbb1 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -615,6 +615,13 @@ Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
 				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), baseName);
 		}
 	}
+#elif defined(__linux__)
+	// TODO: Could also check for other fonts, other paths, etc.
+	Common::String baseName = bold ? "arialbd.ttf" : "arial.ttf";
+	Common::FSNode fontPath("/usr/share/fonts/truetype/msttcorefonts/" + baseName);
+
+	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
+		stream = fontPath.createReadStream();
 #endif
 
 	if (!stream) {


Commit: eb30d39e9ac4a9ad5facf2a75d72dd5d1e408af8
    https://github.com/scummvm/scummvm/commit/eb30d39e9ac4a9ad5facf2a75d72dd5d1e408af8
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Silence some gcc warnings

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_base.cpp
    engines/buried/graphics.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 7719b2fa92..814801c232 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -74,10 +74,8 @@ int TopOfTowerGuardEncounter::paint(Window *viewWindow, Graphics::Surface *preBu
 
 	const Graphics::Surface *newFrame = ((SceneViewWindow *)viewWindow)->getStillFrame(_staticData.miscFrameIndex);
 
-	if (newFrame) {
-		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+	if (newFrame)
 		_vm->_gfx->crossBlit(preBuffer, 0, 0, 432, 189, newFrame, 0, 0);
-	}
 
 	return SC_REPAINT;
 }
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 45f770f2c7..6873810c98 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -592,7 +592,7 @@ int KitchenUnitShopNet::gdiPaint(Window *viewWindow) {
 
 	if (!text.empty()) {
 		rect.translate(64, 128);
-		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), rect.height(), textColor, _lineHeight, kTextAlignLeft, true);
+		_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, rect.left, rect.top, rect.width(), rect.height(), textColor, _lineHeight, kTextAlignLeft, vtCenter);
 	}
 
 	return SC_FALSE;
@@ -700,19 +700,6 @@ int KitchenUnitPostBox::mouseUp(Window *viewWindow, const Common::Point &pointLo
 		newScene.transitionStartFrame = -1;
 		newScene.transitionLength = -1;
 
-		int item;
-		switch (_selectedPackage) {
-		case 0:
-			item = ((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotA;
-			break;
-		case 1:
-			item = ((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotB;
-			break;
-		case 2:
-			item = ((SceneViewWindow *)viewWindow)->getGlobalFlags().faKIPostBoxSlotC;
-			break;
-		}
-
 		switch (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, faKIPostBoxSlotA) + _selectedPackage)) {
 		case 2:
 			newScene.destinationScene.depth = 6;
diff --git a/engines/buried/environ/scene_base.cpp b/engines/buried/environ/scene_base.cpp
index 917b896649..eccf8f084c 100644
--- a/engines/buried/environ/scene_base.cpp
+++ b/engines/buried/environ/scene_base.cpp
@@ -52,10 +52,8 @@ int SceneBase::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
 		newFrame = ((SceneViewWindow *)viewWindow)->getStillFrame(_staticData.navFrameIndex);
 	}
 
-	if (newFrame) {
-		Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
+	if (newFrame)
 		_vm->_gfx->crossBlit(preBuffer, 0, 0, 432, 189, newFrame, 0, 0);
-	}
 
 	return SC_REPAINT;
 }
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 4953e0bbb1..0306753cde 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -461,9 +461,9 @@ bool GraphicsManager::checkPointAgainstMaskedBitmap(const Graphics::Surface *bit
 		uint32 color;
 
 		if (bitmap->format.bytesPerPixel == 2)
-			color = *((uint16 *)bitmap->getBasePtr(point.x - x, point.y - y));
+			color = *((const uint16 *)bitmap->getBasePtr(point.x - x, point.y - y));
 		else
-			color = *((uint32 *)bitmap->getBasePtr(point.x - x, point.y - y));
+			color = *((const uint32 *)bitmap->getBasePtr(point.x - x, point.y - y));
 
 		return transColor != color;
 	} else {
@@ -568,7 +568,7 @@ Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *
 
 	for (int y = 0; y < frame->h; y++)
 		for (int x = 0; x < frame->w; x++)
-			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((byte *)frame->getBasePtr(x, y))];
+			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((const byte *)frame->getBasePtr(x, y))];
 
 	return convertedSurface;
 }


Commit: 97692662f4cc48980b03e41184e80a0de1f0a0d0
    https://github.com/scummvm/scummvm/commit/97692662f4cc48980b03e41184e80a0de1f0a0d0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix death god door open animation

Changed paths:
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 2bf4c77283..9cd153bdf2 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -2409,7 +2409,7 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 	case 28:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransDGOffering));
 	case 29:
-		return new DeathGodCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, 4, TRANSITION_WALK, -1, 1010, 12);
+		return new DeathGodCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, 4, TRANSITION_WALK, -1, 1045, 13);
 	case 30:
 		return new WealthGodRopeDrop(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 31:


Commit: 1fe81654a7e4ec942fe36e4a4e1e6c8267184f35
    https://github.com/scummvm/scummvm/commit/1fe81654a7e4ec942fe36e4a4e1e6c8267184f35
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Properly clip rects to their parent's rect

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/video_window.cpp
    engines/buried/window.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 0306753cde..e6439f5592 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -353,6 +353,13 @@ void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y) {
 		memcpy(_screen->getBasePtr(x, y + i), surface->getBasePtr(0, i), surface->w * surface->format.bytesPerPixel);
 }
 
+void GraphicsManager::blit(const Graphics::Surface *surface, int x, int y, int width, int height) {
+	assert(surface->format.bytesPerPixel == _screen->format.bytesPerPixel);
+
+	for (int i = 0; i < height; i++)
+		memcpy(_screen->getBasePtr(x, y + i), surface->getBasePtr(0, i), width * surface->format.bytesPerPixel);
+}
+
 void GraphicsManager::blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect) {
 	assert(surface->format.bytesPerPixel == _screen->format.bytesPerPixel);
 
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index c9232bcbf0..e8af52a8e8 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -95,6 +95,7 @@ public:
 	bool needsErase() const { return _needsErase; }
 
 	void blit(const Graphics::Surface *surface, int x, int y);
+	void blit(const Graphics::Surface *surface, int x, int y, int width, int height);
 	void blit(const Graphics::Surface *surface, const Common::Rect &srcRect, const Common::Rect &dstRect);
 	void fillRect(const Common::Rect &rect, uint32 color);
 	void opaqueTransparentBlit(Graphics::Surface *dst, int xDst, int yDst, int w, int h, const Graphics::Surface *src, int xSrc, int ySrc, int opacityValue, byte r, byte g, byte b);
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index 4677025348..ed42f11572 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -185,7 +185,7 @@ void VideoWindow::onPaint() {
 		Common::Rect absoluteRect = getAbsoluteRect();
 
 		if (_srcRect.isEmpty() && _dstRect.isEmpty())
-			_vm->_gfx->blit(_lastFrame, absoluteRect.left, absoluteRect.top);
+			_vm->_gfx->blit(_lastFrame, absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height());
 		else
 			_vm->_gfx->crossBlit(_vm->_gfx->getScreen(), absoluteRect.left + _dstRect.left, absoluteRect.top + _dstRect.top, _dstRect.width(), _dstRect.height(), _lastFrame, _srcRect.left, _srcRect.top);
 	}
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 4706b1d07c..feaed9eb14 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -241,6 +241,8 @@ Common::Rect Window::makeAbsoluteRect(const Common::Rect &rect) const {
 	Common::Rect parentRect = _parent->getAbsoluteRect();
 	Common::Rect absoluteRect = rect;
 	absoluteRect.translate(parentRect.left, parentRect.top);
+	absoluteRect.right = MIN(parentRect.right, absoluteRect.right);
+	absoluteRect.bottom = MIN(parentRect.bottom, absoluteRect.bottom);
 	return absoluteRect;
 }
 


Commit: b8f51e9f2f263018ea6c4fe0598b50319a1d1e56
    https://github.com/scummvm/scummvm/commit/b8f51e9f2f263018ea6c4fe0598b50319a1d1e56
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Implement continue game from the death screen

Changed paths:
    engines/buried/death.cpp
    engines/buried/death.h
    engines/buried/frame_window.cpp
    engines/buried/frame_window.h
    engines/buried/inventory_window.cpp
    engines/buried/inventory_window.h
    engines/buried/scene_view.cpp


diff --git a/engines/buried/death.cpp b/engines/buried/death.cpp
index 7d1b9091c1..3bfa549d48 100644
--- a/engines/buried/death.cpp
+++ b/engines/buried/death.cpp
@@ -29,6 +29,8 @@
 #include "buried/death.h"
 #include "buried/frame_window.h"
 #include "buried/graphics.h"
+#include "buried/invdata.h"
+#include "buried/navdata.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
 
@@ -60,7 +62,8 @@ enum {
 	if (_globalFlags.evcapBaseID[i] == flag) \
 		supportingEvidence++
 
-DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, GlobalFlags globalFlags) : Window(vm, parent), _deathSceneIndex(deathSceneIndex), _globalFlags(globalFlags) {
+DeathWindow::DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, GlobalFlags globalFlags, Common::Array<int> itemArray)
+		: Window(vm, parent), _deathSceneIndex(deathSceneIndex), _globalFlags(globalFlags), _itemArray(itemArray) {
 	_curButton = 0;
 	_deathFrameIndex = -1;
 	_lightOn = false;
@@ -370,7 +373,77 @@ void DeathWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	case BUTTON_RESTORE_GAME:
 		if (_restoreGame.contains(point)) {
 			if (_walkthroughMode) {
-				// TODO: Do fake continue
+				Location startingLocation;
+
+				switch (_deathSceneIndex) {
+				case 0:
+					startingLocation = Location(1, 2, 1, 2, 1, 0);
+					break;
+				case 1:
+					startingLocation = Location(1, 3, 2, 0, 0, 0);
+					break;
+				case 3:
+				case 4:
+					startingLocation = Location(1, 4, 7, 0, 2, 0);
+					_itemArray.push_back(kItemGrapplingHook);
+					break;
+				case 5:
+					startingLocation = Location(1, 8, 6, 3, 1, 0);
+					break;
+				case 10:
+					startingLocation = Location(2, 1, 4, 2, 1, 0);
+					break;
+				case 11:
+					startingLocation = Location(2, 1, 7, 3, 1, 0);
+					_itemArray.push_back(kItemCeramicBowl);
+					break;
+				case 12:
+					startingLocation = Location(2, 6, 3, 2, 0, 0);
+					_itemArray.push_back(kItemPreservedHeart);
+					break;
+				case 14:
+					startingLocation = Location(2, 4, 2, 0, 1, 0);
+					break;
+				case 15:
+					startingLocation = Location(2, 4, 5, 2, 1, 0);
+					break;
+				case 20:
+					startingLocation = Location(3, 2, 6, 0, 0, 0);
+					_globalFlags.alRestoreSkipAgent3Initial = 1;
+					break;
+				case 30:
+					startingLocation = Location(5, 1, 2, 0, 1, 0);
+					break;
+				case 31:
+					startingLocation = Location(5, 5, 10, 3, 0, 0);
+					break;
+				case 50:
+					startingLocation = Location(7, 1, 0, 2, 1, 0);
+					break;
+				case 51:
+					startingLocation = Location(7, 1, 6, 0, 1, 1);
+					break;
+				case 52:
+					startingLocation = Location(7, 1, 6, 0, 1, 0);
+					break;
+				case 53:
+					startingLocation = Location(7, 1, 4, 2, 1, 0);
+					break;
+				case 54:
+					startingLocation = Location(7, 1, 3, 3, 1, 1);
+					break;
+				case 55:
+					startingLocation = Location(7, 1, 6, 0, 1, 2);
+					break;
+				case 61:
+					startingLocation = Location(7, 1, 2, 0, 1, 0);
+					break;
+				}
+
+				if (startingLocation.timeZone >= 0) {
+					((FrameWindow *)_vm->_mainWindow)->loadFromState(startingLocation, _globalFlags, _itemArray);
+					return;
+				}
 			} else {
 				// Show restore game window
 				FrameWindow *frameWindow = (FrameWindow *)_parent;
diff --git a/engines/buried/death.h b/engines/buried/death.h
index ed82e847e3..86c75c0b55 100644
--- a/engines/buried/death.h
+++ b/engines/buried/death.h
@@ -40,7 +40,7 @@ class AVIFrames;
 
 class DeathWindow : public Window {
 public:
-	DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, GlobalFlags globalFlags);
+	DeathWindow(BuriedEngine *vm, Window *parent, int deathSceneIndex, GlobalFlags globalFlags, Common::Array<int> itemArray);
 	~DeathWindow();
 
 	void onPaint();
@@ -59,6 +59,7 @@ private:
 	AVIFrames *_deathSceneFrames;
 	int _deathSceneIndex;
 	GlobalFlags _globalFlags;
+	Common::Array<int> _itemArray;
 	int32 _deathFrameIndex;
 	bool _lightOn;
 	Graphics::Font *_textFontA;
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 176f904807..10d005d208 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -263,14 +263,14 @@ bool FrameWindow::startNewGame(bool walkthrough, bool introMovie) {
 	return true;
 }
 
-bool FrameWindow::showDeathScene(int deathSceneIndex, GlobalFlags globalFlags) {
+bool FrameWindow::showDeathScene(int deathSceneIndex, GlobalFlags globalFlags, Common::Array<int> itemArray) {
 	_gameInProgress = false;
 	_atMainMenu = false;
 
 	_vm->removeMouseMessages(this);
 
 	delete _mainChildWindow;
-	_mainChildWindow = new DeathWindow(_vm, this, deathSceneIndex, globalFlags);
+	_mainChildWindow = new DeathWindow(_vm, this, deathSceneIndex, globalFlags, itemArray);
 	_mainChildWindow->showWindow(kWindowShow);
 	_mainChildWindow->invalidateWindow(false);
 
@@ -383,7 +383,7 @@ void FrameWindow::setTransitionSpeed(int newSpeed) {
 	ConfMan.setInt(_vm->isDemo() ? "TransitionSpeed" : _vm->getString(IDS_INI_KEY_TRANS_SPEED), newSpeed);
 }
 
-void FrameWindow::loadFromState(const Location &location, const GlobalFlags &flags, const Common::Array<int> &inventoryItems) {
+void FrameWindow::loadFromState(const Location &location, GlobalFlags flags, Common::Array<int> inventoryItems) {
 	if (!_gameInProgress) {
 		// Make the game in progress
 		_atMainMenu = false;
diff --git a/engines/buried/frame_window.h b/engines/buried/frame_window.h
index 9a73fe136d..0d48d0a4f4 100644
--- a/engines/buried/frame_window.h
+++ b/engines/buried/frame_window.h
@@ -45,8 +45,7 @@ public:
 	bool showClosingScreen();
 	bool showFeaturesScreen();
 	bool startNewGame(bool walkthrough = false, bool introMovie = false);
-	// TODO: startNewGame with continue data
-	bool showDeathScene(int deathSceneIndex, GlobalFlags globalFlags);
+	bool showDeathScene(int deathSceneIndex, GlobalFlags globalFlags, Common::Array<int> itemArray);
 	bool showCompletionScene(GlobalFlags globalFlags);
 	bool showCredits();
 	bool showOverview();
@@ -70,7 +69,7 @@ public:
 
 	bool isGameInProgress() const { return _gameInProgress; }
 	Window *getMainChildWindow() const { return _mainChildWindow; }
-	void loadFromState(const Location &location, const GlobalFlags &flags, const Common::Array<int> &inventoryItems);
+	void loadFromState(const Location &location, GlobalFlags flags, Common::Array<int> inventoryItems);
 
 private:
 	Window *_mainChildWindow;
diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index c98ec8fda4..fd16ea9f93 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -771,4 +771,9 @@ bool InventoryWindow::destroyInfoWindow() {
 	return true;
 }
 
+void InventoryWindow::setItemArray(const Common::Array<int> &array) {
+	_itemArray = array;
+	Common::sort(_itemArray.begin(), _itemArray.end());
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/inventory_window.h b/engines/buried/inventory_window.h
index eca429d66f..fa09c2731c 100644
--- a/engines/buried/inventory_window.h
+++ b/engines/buried/inventory_window.h
@@ -58,7 +58,7 @@ public:
 	InventoryElement getItemStaticData(int itemID);
 	int getItemCount() { return _itemArray.size(); }
 	int getItemID(int itemIndex) { return _itemArray[itemIndex]; }
-	void setItemArray(const Common::Array<int> &array) { _itemArray = array; }
+	void setItemArray(const Common::Array<int> &array);
 	Common::Array<int> &getItemArray() { return _itemArray; }
 
 	bool destroyInfoWindow();
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 3e5e2ac175..36b337f48c 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -195,11 +195,11 @@ bool SceneViewWindow::startNewGame(const Location &startingLocation) {
 }
 
 bool SceneViewWindow::showDeathScene(int deathSceneIndex) {
-	return ((FrameWindow *)(_parent->getParent()))->showDeathScene(deathSceneIndex, _globalFlags); // TODO: Inventory
+	return ((FrameWindow *)(_parent->getParent()))->showDeathScene(deathSceneIndex, _globalFlags, ((GameUIWindow *)_parent)->_inventoryWindow->getItemArray());
 }
 
 bool SceneViewWindow::showCompletionScene() {
-	return ((FrameWindow *)(_parent->getParent()))->showCompletionScene(_globalFlags); // TODO: Inventory
+	return ((FrameWindow *)(_parent->getParent()))->showCompletionScene(_globalFlags);
 }
 
 bool SceneViewWindow::getSceneStaticData(const Location &location, LocationStaticData &sceneStaticData) {


Commit: 542b8e6b10874808b7734f7d2d46b9658fc52870
    https://github.com/scummvm/scummvm/commit/542b8e6b10874808b7734f7d2d46b9658fc52870
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix demo ambient when returning to the courtyard

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 36b337f48c..bba361ac31 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -658,8 +658,12 @@ bool SceneViewWindow::moveToDestination(const DestinationScene &destinationData)
 	((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
 
 	// Hardcoded demo ambient
-	if (_vm->isDemo() && newSceneStaticData.location.environment != oldLocation.environment)
-		_vm->_sound->setAmbientSound("CASTLE/CGBSSNG.WAV");
+	if (_vm->isDemo() && newSceneStaticData.location.environment != oldLocation.environment) {
+		if (_currentScene->_staticData.location.environment == 5)
+			_vm->_sound->setAmbientSound("CASTLE/CGBSSNG.WAV");
+		else
+			_vm->_sound->setAmbientSound("CASTLE/CGMBSNG.WAV");
+	}
 
 	return true;
 }


Commit: 385948933cba28700c084b577248b28286aec3d3
    https://github.com/scummvm/scummvm/commit/385948933cba28700c084b577248b28286aec3d3
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix onSetCursor behavior

Fixes the burned letter cursors

Changed paths:
    engines/buried/window.cpp
    engines/buried/window.h


diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index feaed9eb14..f3c2700556 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -105,7 +105,7 @@ void Window::sendMessage(Message *message) {
 		onRButtonDown(((RButtonDownMessage *)message)->getPoint(), ((RButtonDownMessage *)message)->getFlags());
 		break;
 	case kMessageTypeSetCursor:
-		handleSetCursorMessage(((SetCursorMessage *)message)->getMessage());
+		onSetCursor(((SetCursorMessage *)message)->getMessage());
 		break;
 	case kMessageTypeEnable:
 		onEnable(((EnableMessage *)message)->getEnable());
@@ -276,15 +276,6 @@ Window *Window::childWindowAtPoint(const Common::Point &point) {
 	return this;
 }
 
-bool Window::handleSetCursorMessage(uint message) {
-	// SetCursor messages need special handling
-	// The parent has a chance to set a cursor first
-	if (_parent && _parent->handleSetCursorMessage(message))
-		return true;
-
-	return onSetCursor(message);
-}
-
 Window *Window::setCapture() {
 	Window *oldCapturedWindow = _vm->_captureWindow;
 	_vm->_captureWindow = this;
@@ -306,7 +297,11 @@ Common::Point Window::convertPointToWindow(const Common::Point &point, Window *d
 }
 
 bool Window::onSetCursor(uint message) {
-	// Default to the arrow
+	// The default implementation is to try the parent first
+	if (_parent && _parent->onSetCursor(message))
+		return true;
+
+	// Then otherwise default to the arrow
 	_vm->_gfx->setCursor(kCursorArrow);
 	return false;
 }
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 3519fd8e23..18c077b995 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -119,8 +119,6 @@ private:
 
 	typedef Common::List<Window *> WindowList;
 	WindowList _children, _topMostChildren;
-
-	bool handleSetCursorMessage(uint message);
 };
 
 // A subset of the special insert after Window handles


Commit: 360c7b2293f6cb678f5f2a011009354441eacc4a
    https://github.com/scummvm/scummvm/commit/360c7b2293f6cb678f5f2a011009354441eacc4a
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix the demo door open/close sound

Changed paths:
    engines/buried/scene_view.cpp
    engines/buried/scene_view.h
    engines/buried/sound.cpp
    engines/buried/sound.h


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index bba361ac31..a8ee94a4d3 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -55,7 +55,6 @@ SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_infoWindowDisplayed = false;
 	_bioChipWindowDisplayed = false;
 	_burnedLetterDisplayed = false;
-	_soundTimer = 0;
 	_asyncMovie = 0;
 	_asyncMovieStartFrame = 0;
 	_loopAsyncMovie = false;
@@ -63,6 +62,7 @@ SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_useWaitCursor = false;
 	_cycleEnabled = ((FrameWindow *)(_parent->getParent()))->isFrameCyclingDefault();
 	_disableArthur = false;
+	_demoSoundEffectHandle = -1;
 
 	_preBuffer = new Graphics::Surface();
 	_preBuffer->create(DIB_FRAME_WIDTH, DIB_FRAME_HEIGHT, g_system->getScreenFormat());
@@ -70,6 +70,7 @@ SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_rect = Common::Rect(64, 128, 496, 317);
 
 	_timer = setTimer(100);
+	_demoSoundTimer = _vm->isDemo() ? setTimer(10) : 0;
 	_curCursor = kCursorArrow;
 	_stillFrames = new AVIFrames();
 	_cycleFrames = new AVIFrames();
@@ -119,7 +120,7 @@ bool SceneViewWindow::startNewGame(bool walkthrough) {
 
 	if (_vm->isDemo()) {
 		displayLiveText("To return to the main menu, click the 'Menu' button on the Interface Biochip Display to the right, then click Quit.");
-		_vm->_sound->setAmbientSound("CASTLE/CGMBSNG.WAV");
+		startDemoAmbientSound();
 
 		// This is unlabeled in the original source, but it looks like a hidden feature
 		// to access a bonus puzzle in the demo. (Complete with a typo, but who's counting?)
@@ -658,12 +659,8 @@ bool SceneViewWindow::moveToDestination(const DestinationScene &destinationData)
 	((GameUIWindow *)_parent)->_navArrowWindow->enableWindow(true);
 
 	// Hardcoded demo ambient
-	if (_vm->isDemo() && newSceneStaticData.location.environment != oldLocation.environment) {
-		if (_currentScene->_staticData.location.environment == 5)
-			_vm->_sound->setAmbientSound("CASTLE/CGBSSNG.WAV");
-		else
-			_vm->_sound->setAmbientSound("CASTLE/CGMBSNG.WAV");
-	}
+	if (_vm->isDemo() && newSceneStaticData.location.environment != oldLocation.environment)
+		startDemoAmbientSound();
 
 	return true;
 }
@@ -952,7 +949,36 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 			}
 			return true;
 		} else {
-			return walkTransition(_currentScene->_staticData.location, destinationData, navFrame);
+			// The demo has a hardcoded door open sound
+			// This, and the code below the walkTransition call, are glue around the
+			// demo's sound implementation. The demo is based on an alpha which uses
+			// waveOut to play sounds, as opposed to the final which uses WAIL.
+			if (_vm->isDemo() && destinationData.destinationScene.depth == 1) {
+				// Stop the current ambient sound
+				// onTimer() will restart it
+				_vm->_sound->setAmbientSound();
+
+				if (_currentScene->_staticData.location.environment == 4)
+					_demoSoundEffectHandle = _vm->_sound->playSoundEffect("CASTLE/CGMBDO.WAV");
+				else
+					_demoSoundEffectHandle = _vm->_sound->playSoundEffect("CASTLE/CGBSDO.WAV");
+			}
+		
+			bool retVal = walkTransition(_currentScene->_staticData.location, destinationData, navFrame);
+
+			// And also a door close sound
+			if (_vm->isDemo() && destinationData.destinationScene.environment != _currentScene->_staticData.location.environment) {
+				// Stop the current ambient sound
+				// onTimer() will restart it
+				_vm->_sound->setAmbientSound();
+
+				if (_currentScene->_staticData.location.environment == 4)
+					_demoSoundEffectHandle = _vm->_sound->playSoundEffect("CASTLE/CGBSDC.WAV");
+				else
+					_demoSoundEffectHandle = _vm->_sound->playSoundEffect("CASTLE/CGMBDC.WAV");
+			}
+
+			return retVal;
 		}
 		break;
 	case TRANSITION_VIDEO:
@@ -2488,6 +2514,18 @@ void SceneViewWindow::onPaint() {
 }
 
 void SceneViewWindow::onTimer(uint timer) {
+	// Check first to see if this is the demo's sound timer
+	if (timer == _demoSoundTimer) {
+		// If no sound is playing, restart the ambient
+		if (!_vm->_sound->isAmbientSoundPlaying() && !_vm->_sound->isSoundEffectPlaying(_demoSoundEffectHandle)) {
+			// Reset the sound effect handle
+			_demoSoundEffectHandle = -1;
+			startDemoAmbientSound();
+		}
+
+		return;
+	}
+
 	SoundManager *sound = _vm->_sound; // Take a copy in case we die while in the timer
 	sound->timerCallback();
 
@@ -2650,4 +2688,13 @@ Common::Array<AIComment> SceneViewWindow::getAICommentDatabase(int timeZone, int
 	return comments;
 }
 
+void SceneViewWindow::startDemoAmbientSound() {
+	assert(_currentScene);
+
+	if (_currentScene->_staticData.location.environment == 5)
+		_vm->_sound->setAmbientSound("CASTLE/CGBSSNG.WAV", false, 127);
+	else
+		_vm->_sound->setAmbientSound("CASTLE/CGMBSNG.WAV", false, 127);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 24a29b4f30..c3cf6e6171 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -174,7 +174,6 @@ private:
 	bool _useSprite;
 	bool _cycleEnabled;
 	uint _timer;
-	uint _soundTimer;
 
 	bool _infoWindowDisplayed;
 	bool _bioChipWindowDisplayed;
@@ -191,6 +190,11 @@ private:
 	bool _useWaitCursor;
 	int _oldCursorForWait;
 
+	// Special sound handling for the demo
+	uint _demoSoundTimer;
+	int _demoSoundEffectHandle;
+	void startDemoAmbientSound();
+
 	bool initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment);
 	SceneBase *constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 
diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index fbcd563c4f..0983d7655d 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -211,6 +211,10 @@ bool SoundManager::adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte
 	return true;
 }
 
+bool SoundManager::isAmbientSoundPlaying() {
+	return _soundData[kAmbientIndexBase + _lastAmbient]->_handle != 0;
+}
+
 bool SoundManager::setSecondaryAmbientSound(const Common::String &fileName, bool fade, byte finalVolumeLevel) {
 	if (fileName.empty())
 		return false;
diff --git a/engines/buried/sound.h b/engines/buried/sound.h
index cbf2a7b3d7..c3b07aecfa 100644
--- a/engines/buried/sound.h
+++ b/engines/buried/sound.h
@@ -50,6 +50,7 @@ public:
 	bool setAmbientSound(const Common::String &fileName = "", bool fade = false, byte finalVolumeLevel = 64);
 	bool adjustAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);
 	uint32 getAmbientPosition();
+	bool isAmbientSoundPlaying();
 
 	bool setSecondaryAmbientSound(const Common::String &fileName = "", bool fade = false, byte finalVolumeLevel = 64);
 	bool adjustSecondaryAmbientSoundVolume(byte newVolumeLevel, bool fade, byte steps, uint32 fadeLength);


Commit: 91e21dd39e69643e0f7525d68642c50ef74cad6c
    https://github.com/scummvm/scummvm/commit/91e21dd39e69643e0f7525d68642c50ef74cad6c
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Stop sending messages if we're quitting

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 9232f7beef..c6ef0afaa2 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -280,7 +280,7 @@ void BuriedEngine::postMessageToWindow(Window *dest, Message *message) {
 }
 
 void BuriedEngine::sendAllMessages() {
-	while (!_messageQueue.empty()) {
+	while (!shouldQuit() && !_messageQueue.empty()) {
 		MessageInfo msg = _messageQueue.front();
 		_messageQueue.pop_front();
 


Commit: 3eaa2774bbf17ab828ead45482366b523211495b
    https://github.com/scummvm/scummvm/commit/3eaa2774bbf17ab828ead45482366b523211495b
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Ensure timers get removed upon window destruction

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/window.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index c6ef0afaa2..51291ad050 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -259,6 +259,12 @@ void BuriedEngine::updateTimers() {
 	}
 }
 
+void BuriedEngine::removeAllTimers(Window *window) {
+	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++)
+		if (it->_value.owner == window)
+			_timers.erase(it);
+}
+
 void BuriedEngine::addVideo(VideoWindow *window) {
 	_videos.push_back(window);
 }
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 6440268d01..777f52de11 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -105,6 +105,7 @@ public:
 	uint createTimer(Window *window, uint period);
 	bool killTimer(uint timer);
 	void updateTimers();
+	void removeAllTimers(Window *window);
 
 	// Video
 	void addVideo(VideoWindow *window);
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index f3c2700556..5ae6363cb5 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -51,6 +51,9 @@ Window::~Window() {
 	// Remove any of our messages from the queue
 	_vm->removeAllMessages(this);
 
+	// ...and any timers
+	_vm->removeAllTimers(this);
+
 	// Make sure we're not the focused window
 	if (_vm->_focusedWindow == this)
 		_vm->_focusedWindow = 0;


Commit: 73ea21163223b7ef1078e8c894d8af5cfa847c20
    https://github.com/scummvm/scummvm/commit/73ea21163223b7ef1078e8c894d8af5cfa847c20
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Start fixing the burned letter

Changed paths:
    engines/buried/inventory_info.cpp


diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index 0f0ffb64fd..5aa703e36b 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -171,19 +171,25 @@ void BurnedLetterViewWindow::onPaint() {
 			_preBuffer->free();
 			delete _preBuffer;
 		}
+		
+		_preBuffer = ((SceneViewWindow *)getParent())->getStillFrameCopy(_curSceneStaticData.navFrameIndex);
 
-		_preBuffer = _stillFrames->getFrameCopy(_curView);
+		if (!_preBuffer)
+			error("Failed to get scene frame %d", _curSceneStaticData.navFrameIndex);
+
+		const Graphics::Surface *frame = _stillFrames->getFrame(_curView);
+		_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 0, 432, 189, frame, 0, 0, 0, 0, 0, 0);
 		_rebuildPage = false;
 	}
 
 	Common::Rect absoluteRect = getAbsoluteRect();
-	byte transValue = _vm->isDemo() ? 2 : 0;
-	_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height(), _preBuffer, 0, 0, 0, transValue, transValue, transValue);
+	_vm->_gfx->blit(_preBuffer, absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height());
 
 	if (_curLineIndex >= 0 && ((SceneViewWindow *)_parent)->getGlobalFlags().bcTranslateEnabled == 1) {
 		int numLines = _viewLineCount[_curView];
 		uint32 boxColor = _vm->_gfx->getColor(255, 0, 0);
 		Common::Rect box(1, (187 / numLines) * _curLineIndex, 430, (187 / numLines) * (_curLineIndex + 1) - 1);
+		box.translate(absoluteRect.left, absoluteRect.top);
 		_vm->_gfx->getScreen()->frameRect(box, boxColor);
 	}
 }
@@ -262,8 +268,9 @@ void BurnedLetterViewWindow::onMouseMove(const Common::Point &point, uint flags)
 
 			Common::String translatedText = _vm->getString(_translatedTextResourceID + textLineNumber + _curLineIndex);
 			((SceneViewWindow *)_parent)->displayTranslationText(translatedText);
-			return;
 		}
+
+		return;
 	}
 
 	// Since translation was not enabled, check the current line flag


Commit: 52180e87bc5185a1d210895dac00eaca10660a94
    https://github.com/scummvm/scummvm/commit/52180e87bc5185a1d210895dac00eaca10660a94
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix push transitions

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index a8ee94a4d3..0c747acc1a 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1155,14 +1155,15 @@ bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics:
 
 	// Change the cursor to an hourglass
 	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	_useScenePaint = false;
 
 	switch (direction) {
 	case 0: // Push down
 		for (int i = 0; i < DIB_FRAME_HEIGHT; i += stripSize) {
-			curBackground->move(0, stripSize, curBackground->h - stripSize);
+			curBackground->move(0, stripSize, curBackground->h);
 
 			for (int j = 0; j < stripSize; j++)
-				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(0, i + j), newBackground->w * newBackground->format.bytesPerPixel);
+				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(0, curBackground->h - (i + stripSize) + j), newBackground->w * newBackground->format.bytesPerPixel);
 
 			invalidateWindow(false);
 			_vm->yield();
@@ -1173,7 +1174,7 @@ bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics:
 			curBackground->move(stripSize, 0, curBackground->h);
 
 			for (int j = 0; j < curBackground->h; j++)
-				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(i, j), stripSize * newBackground->format.bytesPerPixel);
+				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(newBackground->w - (i + stripSize), j), stripSize * newBackground->format.bytesPerPixel);
 
 			invalidateWindow(false);
 			_vm->yield();
@@ -1184,18 +1185,18 @@ bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics:
 			curBackground->move(-stripSize, 0, curBackground->h);
 
 			for (int j = 0; j < curBackground->h; j++)
-				memcpy(curBackground->getBasePtr(curBackground->w - stripSize, j), newBackground->getBasePtr(newBackground->w - i, j), stripSize * newBackground->format.bytesPerPixel);
+				memcpy(curBackground->getBasePtr(curBackground->w - stripSize, j), newBackground->getBasePtr(i, j), stripSize * newBackground->format.bytesPerPixel);
 
 			invalidateWindow(false);
 			_vm->yield();
 		}
 		break;
 	case 3: // Push up
-		for (int i = DIB_FRAME_HEIGHT - stripSize; i >= 0; i -= stripSize) {
-			curBackground->move(0, -stripSize, curBackground->h - stripSize);
+		for (int i = 0; i < DIB_FRAME_HEIGHT; i += stripSize) {
+			curBackground->move(0, -stripSize, curBackground->h);
 
 			for (int j = 0; j < stripSize; j++)
-				memcpy(curBackground->getBasePtr(0, j), newBackground->getBasePtr(0, i + j), newBackground->w * newBackground->format.bytesPerPixel);
+				memcpy(curBackground->getBasePtr(0, curBackground->h - stripSize + j), newBackground->getBasePtr(0, i + j), newBackground->w * newBackground->format.bytesPerPixel);
 
 			invalidateWindow(false);
 			_vm->yield();
@@ -1204,6 +1205,7 @@ bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics:
 	}
 
 	_vm->_gfx->setCursor(oldCursor);
+	_useScenePaint = true;
 	return true;
 }
 


Commit: 3fdd4080d3a3f23233a79cfbce5c3c26da6ff128
    https://github.com/scummvm/scummvm/commit/3fdd4080d3a3f23233a79cfbce5c3c26da6ff128
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix the burned letter transition

Changed paths:
    engines/buried/inventory_info.cpp


diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index 5aa703e36b..6d494ffb11 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -197,52 +197,84 @@ void BurnedLetterViewWindow::onPaint() {
 void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	if (_top.contains(point) && _curView > 0) {
 		_curView--;
-
-		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
-
-		Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
+		_curLineIndex = -1;
 
 		int offset = _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed());
-		for (int i = 0; i < 189; i += offset) {
-			_preBuffer->move(0, offset, _preBuffer->h - offset);
 
-			for (int j = 0; j < offset; j++)
-				memcpy(_preBuffer->getBasePtr(0, j), newFrame->getBasePtr(0, i + j), newFrame->w * newFrame->format.bytesPerPixel);
+		// Only draw if transitions are enabled
+		if (offset != 189) {
+			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
-			invalidateWindow(false);
-			_vm->yield();
+			Graphics::Surface *oldFrame = _stillFrames->getFrameCopy(_curView + 1);
+			Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
+			Graphics::Surface *background = ((SceneViewWindow *)getParent())->getStillFrameCopy(_curSceneStaticData.navFrameIndex);
+		
+			for (int i = 0; i < 189; i += offset) {
+				_preBuffer->copyFrom(*background);
+
+				// Blit the top portion (new frame)
+				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 0, _preBuffer->w, i, newFrame, 0, 189 - i, 0, 0, 0, 0);
+			
+				// Blit the bottom portion (old frame)
+				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, i, _preBuffer->w, 189 - i, oldFrame, 0, 0, 0, 0, 0, 0);
+
+				invalidateWindow(false);
+				_vm->yield();
+			}
+
+			oldFrame->free();
+			delete oldFrame;
+			newFrame->free();
+			delete newFrame;
+			background->free();
+			delete background;
+
+			_vm->_gfx->setCursor(oldCursor);
 		}
 
-		_curLineIndex = -1;
 		_rebuildPage = true;
 		invalidateWindow(false);
-
-		_vm->_gfx->setCursor(oldCursor);
 	}
 
 	if (_bottom.contains(point) && _curView < _viewCount - 1) {
 		_curView++;
+		_curLineIndex = -1;
 
-		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+		int offset = _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed());
 
-		Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
+		// Only draw if transitions are enabled
+		if (offset != 189) {
+			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
-		int offset = _vm->_gfx->computeVPushOffset(_vm->getTransitionSpeed());
-		for (int i = 189 - offset; i >= 0; i -= offset) {
-			_preBuffer->move(0, -offset, _preBuffer->h - offset);
+			Graphics::Surface *oldFrame = _stillFrames->getFrameCopy(_curView - 1);
+			Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
+			Graphics::Surface *background = ((SceneViewWindow *)getParent())->getStillFrameCopy(_curSceneStaticData.navFrameIndex);
 
-			for (int j = 0; j < offset; j++)
-				memcpy(_preBuffer->getBasePtr(0, j), newFrame->getBasePtr(0, i + j), newFrame->w * newFrame->format.bytesPerPixel);
+			for (int i = 0 ; i < 189; i += offset) {
+				_preBuffer->copyFrom(*background);
 
-			invalidateWindow(false);
-			_vm->yield();
+				// Blit the top portion (old frame)
+				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 0, _preBuffer->w, 189 - i, oldFrame, 0, i, 0, 0, 0, 0);
+			
+				// Blit the bottom portion (new frame)
+				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 189 - i, _preBuffer->w, i, newFrame, 0, 0, 0, 0, 0, 0);
+
+				invalidateWindow(false);
+				_vm->yield();
+			}
+
+			oldFrame->free();
+			delete oldFrame;
+			newFrame->free();
+			delete newFrame;
+			background->free();
+			delete background;
+
+			_vm->_gfx->setCursor(oldCursor);
 		}
 
-		_curLineIndex = -1;
 		_rebuildPage = true;
 		invalidateWindow(false);
-
-		_vm->_gfx->setCursor(oldCursor);
 	}
 
 	if (_putDown.contains(point))


Commit: 8f82da6e07d3ae205a57eb551d30c25f1bec2860
    https://github.com/scummvm/scummvm/commit/8f82da6e07d3ae205a57eb551d30c25f1bec2860
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Make the burned letter not use the scene background

It now draws over the window properly.

Changed paths:
    engines/buried/inventory_info.cpp
    engines/buried/scene_view.cpp


diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index 6d494ffb11..cde50abae9 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -171,19 +171,16 @@ void BurnedLetterViewWindow::onPaint() {
 			_preBuffer->free();
 			delete _preBuffer;
 		}
-		
-		_preBuffer = ((SceneViewWindow *)getParent())->getStillFrameCopy(_curSceneStaticData.navFrameIndex);
 
+		_preBuffer = _stillFrames->getFrameCopy(_curView);
 		if (!_preBuffer)
-			error("Failed to get scene frame %d", _curSceneStaticData.navFrameIndex);
+			error("Failed to get burned letter section");
 
-		const Graphics::Surface *frame = _stillFrames->getFrame(_curView);
-		_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 0, 432, 189, frame, 0, 0, 0, 0, 0, 0);
 		_rebuildPage = false;
 	}
 
 	Common::Rect absoluteRect = getAbsoluteRect();
-	_vm->_gfx->blit(_preBuffer, absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height());
+	_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left, absoluteRect.top, absoluteRect.width(), absoluteRect.height(), _preBuffer, 0, 0, 0, 0, 0, 0);
 
 	if (_curLineIndex >= 0 && ((SceneViewWindow *)_parent)->getGlobalFlags().bcTranslateEnabled == 1) {
 		int numLines = _viewLineCount[_curView];
@@ -205,29 +202,20 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 		if (offset != 189) {
 			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
-			Graphics::Surface *oldFrame = _stillFrames->getFrameCopy(_curView + 1);
 			Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
-			Graphics::Surface *background = ((SceneViewWindow *)getParent())->getStillFrameCopy(_curSceneStaticData.navFrameIndex);
 		
 			for (int i = 0; i < 189; i += offset) {
-				_preBuffer->copyFrom(*background);
+				_preBuffer->move(0, offset, _preBuffer->h);
 
-				// Blit the top portion (new frame)
-				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 0, _preBuffer->w, i, newFrame, 0, 189 - i, 0, 0, 0, 0);
-			
-				// Blit the bottom portion (old frame)
-				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, i, _preBuffer->w, 189 - i, oldFrame, 0, 0, 0, 0, 0, 0);
+				for (int j = 0; j < offset; j++)
+					memcpy(_preBuffer->getBasePtr(0, j), newFrame->getBasePtr(0, _preBuffer->h - (i + offset) + j), newFrame->w * newFrame->format.bytesPerPixel);
 
 				invalidateWindow(false);
 				_vm->yield();
 			}
 
-			oldFrame->free();
-			delete oldFrame;
 			newFrame->free();
 			delete newFrame;
-			background->free();
-			delete background;
 
 			_vm->_gfx->setCursor(oldCursor);
 		}
@@ -246,29 +234,20 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 		if (offset != 189) {
 			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
-			Graphics::Surface *oldFrame = _stillFrames->getFrameCopy(_curView - 1);
 			Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
-			Graphics::Surface *background = ((SceneViewWindow *)getParent())->getStillFrameCopy(_curSceneStaticData.navFrameIndex);
 
-			for (int i = 0 ; i < 189; i += offset) {
-				_preBuffer->copyFrom(*background);
+			for (int i = 0; i < 189; i += offset) {
+				_preBuffer->move(0, -offset, _preBuffer->h);
 
-				// Blit the top portion (old frame)
-				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 0, _preBuffer->w, 189 - i, oldFrame, 0, i, 0, 0, 0, 0);
-			
-				// Blit the bottom portion (new frame)
-				_vm->_gfx->opaqueTransparentBlit(_preBuffer, 0, 189 - i, _preBuffer->w, i, newFrame, 0, 0, 0, 0, 0, 0);
+				for (int j = 0; j < offset; j++)
+					memcpy(_preBuffer->getBasePtr(0, newFrame->h - offset + j), newFrame->getBasePtr(0, i + j), newFrame->w * newFrame->format.bytesPerPixel);
 
 				invalidateWindow(false);
 				_vm->yield();
 			}
 
-			oldFrame->free();
-			delete oldFrame;
 			newFrame->free();
 			delete newFrame;
-			background->free();
-			delete background;
 
 			_vm->_gfx->setCursor(oldCursor);
 		}
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 0c747acc1a..cd45f2a072 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -2493,9 +2493,8 @@ void SceneViewWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 }
 
 void SceneViewWindow::onPaint() {
-	// TODO: I think this should draw when the burned letter is displayed, since I modified that code
 	// Original didn't draw if the async movie was playing, but that doesn't seem right.
-	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed && !_burnedLetterDisplayed) {
+	if (_currentScene && !_infoWindowDisplayed && !_bioChipWindowDisplayed) {
 		if (_currentScene->_staticData.navFrameIndex >= -1) {
 			if (_useScenePaint)
 				_currentScene->paint(this, _preBuffer);


Commit: 810f006e9af99f95bee64b9b521948a50be08870
    https://github.com/scummvm/scummvm/commit/810f006e9af99f95bee64b9b521948a50be08870
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Use separate pause sound functions for pausing the game

Changed paths:
    engines/buried/buried.cpp
    engines/buried/sound.cpp
    engines/buried/sound.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 51291ad050..3a9115ee05 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -449,14 +449,14 @@ uint32 BuriedEngine::computeFileNameResourceID(int timeZone, int environment, in
 
 void BuriedEngine::pauseEngineIntern(bool pause) {
 	if (pause) {
-		_sound->stop();
+		_sound->pause(true);
 
 		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
 			(*it)->pauseVideo();
 
 		_pauseStartTime = g_system->getMillis();
 	} else {
-		_sound->restart();
+		_sound->pause(false);
 
 		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
 			(*it)->resumeVideo();
diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index 0983d7655d..eb27841fe7 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -76,6 +76,11 @@ void SoundManager::shutDown() {
 	}
 }
 
+void SoundManager::pause(bool shouldPause) {
+	for (int i = 0; i < kMaxSounds; i++)
+		_soundData[i]->pause(shouldPause);
+}
+
 bool SoundManager::setAmbientSound(const Common::String &fileName, bool fade, byte finalVolumeLevel) {
 	// Determine which of the two ambient tracks to use
 	int newAmbientTrack = (_lastAmbient == 0) ? 1 : 0;
@@ -748,4 +753,9 @@ bool SoundManager::Sound::stop() {
 	return true;
 }
 
+void SoundManager::Sound::pause(bool shouldPause) {
+	if (_soundData && _handle)
+		g_system->getMixer()->pauseHandle(*_handle, shouldPause);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/sound.h b/engines/buried/sound.h
index c3b07aecfa..7d70fe95b9 100644
--- a/engines/buried/sound.h
+++ b/engines/buried/sound.h
@@ -78,9 +78,14 @@ public:
 	bool startFootsteps(int footstepsID);
 	bool stopFootsteps();
 
-	// PAUSE FUNCTIONS
+	// Pause functions
+	// stop()/restart() do as they say on the tin and aren't true pause functions.
+	// This is what the original does for pausing, and it needs to be done this way.
+	// pause() is used for implementing pauseEngineIntern(). Since stop()/restart()
+	// are not re-entrant, they're not suitable for that purpose.
 	bool stop();
 	bool restart();
+	void pause(bool shouldPause);
 
 	// TIMER CALLBACK FUNCTION
 	void timerCallback();
@@ -113,6 +118,7 @@ private:
 		bool start();
 		bool isPlaying() const;
 		bool stop();
+		void pause(bool shouldPause);
 
 	protected:
 		Audio::RewindableAudioStream *_soundData; // Stream to the data


Commit: 85d64a510f798596f24300819fecc750771a2df5
    https://github.com/scummvm/scummvm/commit/85d64a510f798596f24300819fecc750771a2df5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix TurnDepthPreChange

Fixes weird behavior of turning around the exploded castle wall

Changed paths:
    engines/buried/environ/scene_common.cpp


diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index 88e5a424d3..af6fcb7148 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -99,16 +99,16 @@ TurnDepthPreChange::TurnDepthPreChange(BuriedEngine *vm, Window *viewWindow, con
 			_staticData.destUp.destinationScene.depth = upDepth;
 
 		if (leftDepth >= 0)
-			_staticData.destUp.destinationScene.depth = leftDepth;
+			_staticData.destLeft.destinationScene.depth = leftDepth;
 
 		if (rightDepth >= 0)
-			_staticData.destUp.destinationScene.depth = rightDepth;
+			_staticData.destRight.destinationScene.depth = rightDepth;
 
 		if (downDepth >= 0)
-			_staticData.destUp.destinationScene.depth = downDepth;
+			_staticData.destDown.destinationScene.depth = downDepth;
 
 		if (forwardDepth >= 0)
-			_staticData.destUp.destinationScene.depth = forwardDepth;
+			_staticData.destForward.destinationScene.depth = forwardDepth;
 	}
 }
 


Commit: 5583f97ebde50703c5cf1c63c0e99e05b75e8aa2
    https://github.com/scummvm/scummvm/commit/5583f97ebde50703c5cf1c63c0e99e05b75e8aa2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Clean up searching for fonts

Check the game directory for a user-overriding font. Remove broken MS Gothic check on OS X too: it doesn't have the bitmaps of the Windows version and looks like garbage.

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index e6439f5592..c185e2036e 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -583,16 +583,21 @@ Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *
 Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
 	Common::SeekableReadStream *stream = 0;
 
+	// Try to see if the user supplied a font
+	Common::String defaultBaseName = bold ? "arialbd.ttf" : "arial.ttf";
+	stream = SearchMan.createReadStreamForMember(defaultBaseName);
+	if (stream)
+		return stream;
+
 	// HACK: Try to load the system font
 #if defined(WIN32)
-	Common::String baseName = bold ? "arialbd.ttf" : "arial.ttf";
-	Common::FSNode fontPath("C:/WINDOWS/Fonts/" + baseName);
+	Common::FSNode fontPath("C:/WINDOWS/Fonts/" + defaultBaseName);
 
 	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
 		stream = fontPath.createReadStream();
 
 	if (!stream) {
-		Common::FSNode win2kFontPath("C:/WINNT/Fonts/" + baseName);
+		Common::FSNode win2kFontPath("C:/WINNT/Fonts/" + defaultBaseName);
 
 		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
 			stream = win2kFontPath.createReadStream();
@@ -720,6 +725,11 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size) const {
 Common::SeekableReadStream *GraphicsManager::findMSGothicStream() const {
 	Common::SeekableReadStream *stream = 0;
 
+	// Try to see if the user supplied a font
+	stream = SearchMan.createReadStreamForMember("msgothic.ttc");
+	if (stream)
+		return stream;
+
 	// HACK: Try to load the system font
 #if defined(WIN32)
 	Common::FSNode fontPath("C:/WINDOWS/Fonts/msgothic.ttc");
@@ -733,12 +743,6 @@ Common::SeekableReadStream *GraphicsManager::findMSGothicStream() const {
 		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
 			stream = win2kFontPath.createReadStream();
 	}
-#elif defined(MACOSX)
-	// Attempt to load the font from MS Gothic.ttf
-	Common::FSNode fontPath(Common::String::format("/Library/Fonts/Microsoft/MS Gothic.ttf"));
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
 #endif
 
 	if (!stream) {


Commit: facf690f29f044a1535bd2f9273ac640b2f62a71
    https://github.com/scummvm/scummvm/commit/facf690f29f044a1535bd2f9273ac640b2f62a71
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Add TODO for MS Gothic bold

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index c185e2036e..003c3f8ae2 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -153,7 +153,7 @@ Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
 	// MS Gothic for the Japanese version
 	// Arial or Arial Bold for everything else
 	if (_vm->getLanguage() == Common::JA_JPN)
-		return createMSGothicFont(size);
+		return createMSGothicFont(size, bold);
 
 	return createArialFont(size, bold);
 }
@@ -686,7 +686,7 @@ void GraphicsManager::crossBlit(Graphics::Surface *dst, int xDst, int yDst, int
 		memcpy(dst->getBasePtr(xDst, yDst + y), src->getBasePtr(xSrc, ySrc + y), w * src->format.bytesPerPixel);
 }
 
-Graphics::Font *GraphicsManager::createMSGothicFont(int size) const {
+Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 	Common::SeekableReadStream *stream = findMSGothicStream();
 
 	if (!stream)
@@ -713,6 +713,7 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size) const {
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
 	// TODO: shift-jis codepage (932) and mapping
+	// TODO: Retrieve the bold version from the TTC file
 	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 
 	if (!font)
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index e8af52a8e8..10638225c7 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -126,7 +126,7 @@ private:
 	Common::SeekableReadStream *findArialStream(bool bold) const;
 	Common::SeekableReadStream *getThemeFontStream(const Common::String &fileName) const;
 
-	Graphics::Font *createMSGothicFont(int size) const;
+	Graphics::Font *createMSGothicFont(int size, bool bold) const;
 	Common::SeekableReadStream *findMSGothicStream() const;
 };
 


Commit: f1ff0f59cf1141dd0670f7d4f803258f6d4c0bb2
    https://github.com/scummvm/scummvm/commit/f1ff0f59cf1141dd0670f7d4f803258f6d4c0bb2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:43+01:00

Commit Message:
BURIED: Fix size of the font used by the Japanese inventory

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 003c3f8ae2..d866dcc109 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -693,9 +693,7 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 		error("Failed to find MS Gothic font");
 
 	switch (size) {
-	case 10:
-		size = 7;
-		break;		
+	case 10:	
 	case 11:
 		size = 8;
 		break;


Commit: 18db1475a34384f1e3efd6c274984030c8f8bc12
    https://github.com/scummvm/scummvm/commit/18db1475a34384f1e3efd6c274984030c8f8bc12
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Force the monochrome version of MS Gothic since we need the bitmaps

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index d866dcc109..90977984ed 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -707,12 +707,11 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 		error("Unknown MS Gothic font size %d", size);
 	}
 
-	// TODO: Make the monochrome mode optional
-	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
-	// with the TrueType font on Win7/Win8 (at least)
 	// TODO: shift-jis codepage (932) and mapping
-	// TODO: Retrieve the bold version from the TTC file
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
+	// TODO: Fake a bold version
+
+	// Force monochrome, since the original uses the bitmap glyphs in the font
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, Graphics::kTTFRenderModeMonochrome, s_codePage1252);
 
 	if (!font)
 		error("Failed to load MS Gothic font");


Commit: 75760fa054536f9a9492edb9b4debd44022e899d
    https://github.com/scummvm/scummvm/commit/75760fa054536f9a9492edb9b4debd44022e899d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Use the render text function for the inventory window

Allows all text to be drawn from one place

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index fd16ea9f93..a472009bfc 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -308,12 +308,9 @@ void InventoryWindow::onPaint() {
 				textRect.bottom++;
 			}
 
-			// Shift another pixel to adjust for Windows
-			textRect.top++;
-
 			textRect.translate(absoluteRect.left, absoluteRect.top);
 			Common::String text = _vm->getString(IDES_ITEM_TITLE_BASE + _itemArray[_curItem + i]);
-			_textFont->drawString(_vm->_gfx->getScreen(), text, textRect.left, textRect.top, textRect.width(), textColor);
+			_vm->_gfx->renderText(_vm->_gfx->getScreen(), _textFont, text, textRect.left, textRect.top, textRect.width(), textRect.height(), textColor, _fontHeight);
 		}
 	}
 }


Commit: 7e57ba728ef0cdbfc41382a28ff393c5b8c85f97
    https://github.com/scummvm/scummvm/commit/7e57ba728ef0cdbfc41382a28ff393c5b8c85f97
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add support for displaying Japanese text

Changed paths:
    engines/buried/buried.cpp
    engines/buried/graphics.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 3a9115ee05..7a412378be 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -79,6 +79,12 @@ BuriedEngine::~BuriedEngine() {
 Common::Error BuriedEngine::run() {
 	_console = new BuriedConsole(this);
 
+#ifndef USE_ICONV
+	// The Japanese version needs iconv support
+	if (getLanguage() == Common::JA_JPN)
+		return Common::Error(Common::kUnknownError, "No iconv support available");
+#endif
+
 	if (isTrueColor()) {
 #ifndef USE_RGB_COLOR
 		// Can't play 24bpp version without support
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 90977984ed..90ede02685 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -25,6 +25,9 @@
 
 #include "common/config-manager.h"
 #include "common/fs.h"
+#ifdef USE_ICONV
+#include "common/iconv.h"
+#endif
 #ifdef MACOSX
 #include "common/macresman.h"
 #endif
@@ -76,6 +79,9 @@ GraphicsManager::~GraphicsManager() {
 	delete[] _palette;
 }
 
+// If we don't have iconv available, have a CP-1252 codepage mapping.
+#ifndef USE_ICONV
+
 #define REQUIRED(x) (((uint32)(x)) | 0x80000000)
 #define NOT_REQUIRED(x) (x)
 
@@ -149,6 +155,8 @@ static const uint32 s_codePage1252[256] = {
 #undef REQUIRED
 #undef NOT_REQUIRED
 
+#endif // USE_ICONV
+
 Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
 	// MS Gothic for the Japanese version
 	// Arial or Arial Bold for everything else
@@ -188,7 +196,16 @@ Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
 	// Win3.1 obviously only had raster fonts, but BIT Win3.1 will render
 	// with the TrueType font on Win7/Win8 (at least)
 	// FIXME: The font is slightly off from the original... need to check. Sizes are right though!
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, s_codePage1252);
+
+	// Enable code page mapping only if we don't have iconv. Otherwise, we'll
+	// let that handle mapping for us.
+#ifdef USE_ICONV
+	static const uint32 *codePageMapping = 0;
+#else
+	static const uint32 *codePageMapping = s_codePage1252;
+#endif
+
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, codePageMapping);
 
 	if (!font)
 		error("Failed to load Arial%s font", bold ? " Bold" : "");
@@ -707,11 +724,10 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 		error("Unknown MS Gothic font size %d", size);
 	}
 
-	// TODO: shift-jis codepage (932) and mapping
 	// TODO: Fake a bold version
 
 	// Force monochrome, since the original uses the bitmap glyphs in the font
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, Graphics::kTTFRenderModeMonochrome, s_codePage1252);
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, Graphics::kTTFRenderModeMonochrome);
 
 	if (!font)
 		error("Failed to load MS Gothic font");
@@ -786,8 +802,17 @@ void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, c
 	if (text.empty())
 		return;
 
+#ifdef USE_ICONV
+	// Convert to UTF-32 for drawing. Choose the codepage based on the language.
+	const char *srcFormat = (_vm->getLanguage() == Common::JA_JPN) ? "CP932" : "CP1252";
+	Common::U32String convString = Common::convertToU32String(srcFormat, text);
+	Common::Array<Common::U32String> lines;
+	font->wordWrapText(convString, w, lines);
+#else
+	// Assume we loaded the font with the correct mapping and draw it directly.
 	Common::StringArray lines;
 	font->wordWrapText(text, w, lines);
+#endif
 
 	Graphics::TextAlign align = Graphics::kTextAlignLeft;
 	switch (textAlign) {


Commit: 4270ea8fdd0eebe7862d53601e7d1e2d9432db57
    https://github.com/scummvm/scummvm/commit/4270ea8fdd0eebe7862d53601e7d1e2d9432db57
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix the date not showing in the intro

(An original game bug)

Changed paths:
    engines/buried/gameui.cpp


diff --git a/engines/buried/gameui.cpp b/engines/buried/gameui.cpp
index f05f5dae03..6a35abf325 100644
--- a/engines/buried/gameui.cpp
+++ b/engines/buried/gameui.cpp
@@ -151,6 +151,9 @@ bool GameUIWindow::changeCurrentDate(int timeZoneID) {
 	case 6:
 		_currentDateDisplay = 0;
 		break;
+	case 10:
+		_currentDateDisplay = 2;
+		break;
 	default:
 		_currentDateDisplay = -1;
 		break;


Commit: 8ff163af294b55b0eb867c08e0636dc6779ca9b5
    https://github.com/scummvm/scummvm/commit/8ff163af294b55b0eb867c08e0636dc6779ca9b5
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Don't bother loading the drag frame video in the full version

It's unused and isn't even present in later releases. Only the demo uses it.

Changed paths:
    engines/buried/inventory_window.cpp


diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index a472009bfc..a446786d69 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -84,18 +84,19 @@ InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_rect = Common::Rect(182, 375, 450, 454);
 	_curCursor = (int)kCursorNone;
 
-	Common::String dragFramesFileName;
-
 	if (_vm->isDemo()) {
+		// The demo uses a video for drag frames
+		Common::String dragFramesFileName;
 		if (_vm->isTrueColor())
 			dragFramesFileName = "COMMON/INVDRAG.BTV";
 		else
 			dragFramesFileName = "COMMON/INVDRAG8.BTV";
-	} else {
-		dragFramesFileName = _vm->getFilePath(IDS_INVENTORY_DRAG_FILENAME);
-	}
 
-	_dragFrames = new AVIFrames(dragFramesFileName);
+		_dragFrames = new AVIFrames(dragFramesFileName);
+	} else {
+		// The full version uses bitmaps
+		_dragFrames = NULL;
+	}	
 }
 
 InventoryWindow::~InventoryWindow() {


Commit: 98ef56ed53d6b6b87217880a288ad5d5f26705e0
    https://github.com/scummvm/scummvm/commit/98ef56ed53d6b6b87217880a288ad5d5f26705e0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix guard not being shot by the arrow when jumping from castle to castle

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index cd45f2a072..6ccea6f57c 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -807,7 +807,10 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 		oldLocation = _currentScene->_staticData.location;
 
 	// Create the new scene object
-	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, oldLocation);
+	// The original passed oldLocation, but that's wrong for jumping. I mean, that's
+	// why David made specOldLocation in the first place. This prevents the wrong location
+	// being passed for the castle intro with the guard getting shot by the arrow.
+	SceneBase *newScene = constructSceneObject(this, newSceneStaticData, specOldLocation);
 
 	if (_currentScene) {
 		// Post-transition function


Commit: 1cc30236a537115fe25fd991b59007d134253fce
    https://github.com/scummvm/scummvm/commit/1cc30236a537115fe25fd991b59007d134253fce
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add detection for the French version

Changed paths:
    engines/buried/detection.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 7b13592781..17120627fe 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -240,6 +240,44 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
+	// French Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "edea5331dc7cb0f3da7322691e12a18a", 1182720 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::FR_FRA,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// French Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "0adea8e1ad6fddad3b861be8a7bab340", 1177088 },
+				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::FR_FRA,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
 	// English Windows 95 8BPP
 	// v1.1
 	{


Commit: be2de373ae77098724cb1ff7a0cdc817d078905f
    https://github.com/scummvm/scummvm/commit/be2de373ae77098724cb1ff7a0cdc817d078905f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add detection for the trial version

Changed paths:
    engines/buried/buried.h
    engines/buried/detection.cpp


diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 777f52de11..4781dbaf6c 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -63,6 +63,7 @@ public:
 	// Detection related functions
 	const BuriedGameDescription *_gameDescription;
 	bool isDemo() const;
+	bool isTrial() const;
 	bool isTrueColor() const;
 	bool isWin95() const;
 	bool isCompressed() const;
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 17120627fe..4683a76f8d 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -39,7 +39,8 @@ struct BuriedGameDescription {
 enum {
 	GF_TRUECOLOR  = (1 << 1),
 	GF_WIN95      = (1 << 2),
-	GF_COMPRESSED = (1 << 3)
+	GF_COMPRESSED = (1 << 3),
+	GF_TRIAL      = (1 << 4)
 };
 
 bool BuriedEngine::hasFeature(EngineFeature f) const {
@@ -50,7 +51,12 @@ bool BuriedEngine::hasFeature(EngineFeature f) const {
 }
 
 bool BuriedEngine::isDemo() const {
-	return (_gameDescription->desc.flags & ADGF_DEMO) != 0;
+	// The trial is a demo for the user's sake, but not internally.
+	return (_gameDescription->desc.flags & ADGF_DEMO) != 0 && !isTrial();
+}
+
+bool BuriedEngine::isTrial() const {
+	return (_gameDescription->desc.flags & GF_TRIAL) != 0;
 }
 
 bool BuriedEngine::isTrueColor() const {
@@ -340,6 +346,42 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
+	// English Windows 3.11 Trial 8BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"Trial 8BPP",
+			{
+				{ "BTV816.EXE",  0, "a3551483329816d8ddc8fa877113762c", 1170432 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_DEMO | GF_TRIAL,
+			GUIO0()
+		},
+	},
+
+	// English Windows 3.11 Trial 24BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"Trial 24BPP",
+			{
+				{ "BTV2416.EXE",  0, "e0783c5eda09176d414d3df4ada8fe89", 1164288 },
+				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_DEMO | GF_TRUECOLOR | GF_TRIAL,
+			GUIO0()
+		},
+	},
+
 	{ AD_TABLE_END_MARKER }
 };
 


Commit: e05089621a6757965f62781089b0b76ec728688d
    https://github.com/scummvm/scummvm/commit/e05089621a6757965f62781089b0b76ec728688d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Push the default scene view down to each environ

Changed paths:
    engines/buried/environ/agent3_lair.cpp
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/alien.cpp
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_factory.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index cdaf243609..156eddcca4 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -970,6 +970,9 @@ bool SceneViewWindow::startAgent3LairAmbient(int oldTimeZone, int oldEnvironment
 
 SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 177, 96, 231, 184, kItemGeneratorCore, 15, offsetof(GlobalFlags, alRDTakenLiveCore));
 	case 2:
@@ -996,10 +999,11 @@ SceneBase *SceneViewWindow::constructAgent3LairSceneObject(Window *viewWindow, c
 		return new CompleteTransport(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 31:
 		return new PlayTransporterClosing(_vm, viewWindow, sceneStaticData, priorLocation);
+	default:
+		warning("Unknown Agent 3 lair scene object %d", sceneStaticData.classID);
+		break;
 	}
 
-	warning("Unknown Agent 3 lair scene object %d", sceneStaticData.classID);
-
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 6281fb8e0f..5a01158fde 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -3777,6 +3777,9 @@ bool SceneViewWindow::checkCustomSpaceStationAICommentDependencies(const Locatio
 
 SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new UseCheeseGirlPropellant(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 3:
diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index e2670f5229..648be2651a 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -1109,6 +1109,9 @@ bool SceneViewWindow::startAlienAmbient(int oldTimeZone, int oldEnvironment, int
 
 SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new ArmControls(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 2:
@@ -1167,9 +1170,11 @@ SceneBase *SceneViewWindow::constructAlienSceneObject(Window *viewWindow, const
 		return new NerveNavigation(_vm, viewWindow, sceneStaticData, priorLocation, 180, 160, 270, 189);
 	case 50:
 		return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 127, offsetof(GlobalFlags, asRBLastStingerID), offsetof(GlobalFlags, asRBStingerID), 10, 14);
+	default:
+		warning("Unknown Alien scene object %d", sceneStaticData.classID);
+		break;
 	}
 
-	warning("Unknown Alien scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 814801c232..c265d46587 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -1115,9 +1115,10 @@ bool SceneViewWindow::checkCustomCastleAICommentDependencies(const Location &com
 }
 
 SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// TODO
-
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new TopOfTowerGuardEncounter(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 3:
@@ -1266,7 +1267,7 @@ SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const
 	case 77:
 		return new ClickPlaySound(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, cgTSTriedDoorB), 14, kCursorFinger, 72, 0, 372, 189);
 	default:
-		warning("TODO: Castle scene object %d", sceneStaticData.classID);
+		warning("Unknown Castle scene object %d", sceneStaticData.classID);
 		break;
 	}
 
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 8e6dd7ad05..4aec6e87f7 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -2583,6 +2583,9 @@ bool SceneViewWindow::checkCustomDaVinciAICommentDependencies(const Location &co
 
 SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new SwapStillOnFlag(_vm, viewWindow, sceneStaticData, priorLocation, offsetof(GlobalFlags, dsPTElevatorPresent), 1);
 	case 2:
@@ -2737,9 +2740,11 @@ SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, cons
 		return new PlaySoundEnteringScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, offsetof(GlobalFlags, dsCTPlayedBallistaFalling));
 	case 77:
 		return new CodexFormulaeNotify(_vm, viewWindow, sceneStaticData, priorLocation);
+	default:
+		warning("Unknown Da Vinci scene object %d", sceneStaticData.classID);
+		break;
 	}
 
-	warning("Unknown Da Vinci scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 6873810c98..7806d47fe0 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -1958,6 +1958,9 @@ bool SceneViewWindow::startFutureApartmentAmbient(int oldTimeZone, int oldEnviro
 
 SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new ClickPlayVideoSwitchAI(_vm, viewWindow, sceneStaticData, priorLocation, 0, kCursorFinger, offsetof(GlobalFlags, faKICoffeeSpilled), 212, 114, 246, 160);
 	case 2:
@@ -2062,10 +2065,10 @@ SceneBase *SceneViewWindow::constructFutureApartmentSceneObject(Window *viewWind
 		return new MainEnvironSitDownClick(_vm, viewWindow, sceneStaticData, priorLocation);
 	case 59:
 		return new EnvironDoorExitSound(_vm, viewWindow, sceneStaticData, priorLocation);
+	default:
+		warning("Unknown Future apartment scene object %d", sceneStaticData.classID);
 	}
 
-	warning("Unknown Future apartment scene object %d", sceneStaticData.classID);
-
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 9cd153bdf2..515c40d7b5 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -2352,6 +2352,9 @@ bool SceneViewWindow::checkCustomMayanAICommentDependencies(const Location &comm
 
 SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
 	switch (sceneStaticData.classID) {
+	case 0:
+		// Default scene
+		break;
 	case 1:
 		return new VideoDeath(_vm, viewWindow, sceneStaticData, priorLocation, 10, IDS_HUMAN_PRESENCE_500METERS);
 	case 2:
@@ -2540,9 +2543,11 @@ SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WG_ALTAR_TEXT, 118, 14, 338, 44);
 	case 128:
 		return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WT_ALTAR_TEXT, 106, 128, 344, 162);
+	default:
+		warning("Unknown Mayan scene object %d", sceneStaticData.classID);
+		break;
 	}
 
-	warning("Unknown Mayan scene object %d", sceneStaticData.classID);
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
 }
 
diff --git a/engines/buried/environ/scene_factory.cpp b/engines/buried/environ/scene_factory.cpp
index ce3bb23fce..c62ba32086 100644
--- a/engines/buried/environ/scene_factory.cpp
+++ b/engines/buried/environ/scene_factory.cpp
@@ -113,10 +113,6 @@ bool SceneViewWindow::startEnvironmentAmbient(int oldTimeZone, int oldEnvironmen
 }
 
 SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
-	// If the class ID is zero, return the default base class
-	if (sceneStaticData.classID == 0)
-		return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
-
 	switch (sceneStaticData.location.timeZone) {
 	case 0: // Miscellaneous scenes
 		// This seems unused?
@@ -138,6 +134,8 @@ SceneBase *SceneViewWindow::constructSceneObject(Window *viewWindow, const Locat
 		return constructAlienSceneObject(viewWindow, sceneStaticData, priorLocation);
 	case 10: // Old Apartment
 		return new OldApartmentSuitCap(_vm, viewWindow, sceneStaticData, priorLocation);
+	default:
+		error("Unknown time zone %d", sceneStaticData.location.timeZone);
 	}
 
 	return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);


Commit: 18a7b010be586c73d5eacdfdaf68aed6c2b910ec
    https://github.com/scummvm/scummvm/commit/18a7b010be586c73d5eacdfdaf68aed6c2b910ec
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Implement the trial version's auto-recall

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp
    engines/buried/environ/scene_common.h


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 5a01158fde..8de87e289e 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -3776,6 +3776,10 @@ bool SceneViewWindow::checkCustomSpaceStationAICommentDependencies(const Locatio
 }
 
 SceneBase *SceneViewWindow::constructAILabSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// Special scene for the trial version
+	if (_vm->isTrial())
+		return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
+
 	switch (sceneStaticData.classID) {
 	case 0:
 		// Default scene
diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index c265d46587..ab854530ec 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -1115,6 +1115,10 @@ bool SceneViewWindow::checkCustomCastleAICommentDependencies(const Location &com
 }
 
 SceneBase *SceneViewWindow::constructCastleSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// Special scene for the trial version
+	if (_vm->isTrial())
+		return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
+
 	switch (sceneStaticData.classID) {
 	case 0:
 		// Default scene
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 4aec6e87f7..fcad1d2c5b 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -2582,6 +2582,10 @@ bool SceneViewWindow::checkCustomDaVinciAICommentDependencies(const Location &co
 }
 
 SceneBase *SceneViewWindow::constructDaVinciSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// Special scene for the trial version
+	if (_vm->isTrial())
+		return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
+
 	switch (sceneStaticData.classID) {
 	case 0:
 		// Default scene
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 515c40d7b5..0cb95812ef 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -2351,6 +2351,10 @@ bool SceneViewWindow::checkCustomMayanAICommentDependencies(const Location &comm
 }
 
 SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
+	// Special scene for the trial version
+	if (_vm->isTrial())
+		return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
+
 	switch (sceneStaticData.classID) {
 	case 0:
 		// Default scene
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index af6fcb7148..f10344d6d5 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -28,6 +28,7 @@
 #include "buried/gameui.h"
 #include "buried/graphics.h"
 #include "buried/inventory_window.h"
+#include "buried/message.h"
 #include "buried/navarrow.h"
 #include "buried/resources.h"
 #include "buried/sound.h"
@@ -35,6 +36,7 @@
 #include "buried/environ/scene_common.h"
 
 #include "common/stream.h"
+#include "common/system.h"
 #include "graphics/surface.h"
 
 namespace Buried {
@@ -1276,4 +1278,36 @@ int ClickPlaySoundSynchronous::specifyCursor(Window *viewWindow, const Common::P
 	return kCursorArrow;
 }
 
+TrialRecallScene::TrialRecallScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
+		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
+	// Disable all movement
+	_staticData.destUp.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destLeft.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destRight.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destDown.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+	_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
+}
+
+int TrialRecallScene::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Display the message
+	static const char *const message =
+		"This timezone is not available in this Trial Version.  "
+		"Call (800) 943-3664 to purchase the complete version of Buried in Time.\n"
+		"Initiating Auto-Recall to Future Apartment...";
+	((SceneViewWindow *)viewWindow)->displayLiveText(message, false);
+
+	// Wait about 10 seconds
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	uint32 start = g_system->getMillis();
+	while (g_system->getMillis() - start < 10000)
+		_vm->yield();
+	_vm->_gfx->setCursor(oldCursor);
+
+	// Force a recall
+	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipJump);
+	((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sendMessage(new LButtonUpMessage(Common::Point(50, 150), 0));
+
+	return SC_TRUE;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/environ/scene_common.h b/engines/buried/environ/scene_common.h
index efa41acfc5..c55fa2f843 100644
--- a/engines/buried/environ/scene_common.h
+++ b/engines/buried/environ/scene_common.h
@@ -408,6 +408,12 @@ private:
 	int _flagOffset;
 };
 
+class TrialRecallScene : public SceneBase {
+public:
+	TrialRecallScene(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+};
+
 } // End of namespace Buried
 
 #endif


Commit: 57920ae92d83169d411083dcc3352c514e1ca7da
    https://github.com/scummvm/scummvm/commit/57920ae92d83169d411083dcc3352c514e1ca7da
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Display a message when trying to load non-apartment saves in the trial

Changed paths:
    engines/buried/buried.cpp
    engines/buried/saveload.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 7a412378be..b23da68fd5 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -135,6 +135,11 @@ Common::Error BuriedEngine::run() {
 		if (ConfMan.hasKey("save_slot")) {
 			uint32 gameToLoad = ConfMan.getInt("save_slot");
 			doIntro = (loadGameState(gameToLoad).getCode() != Common::kNoError);
+
+			// If the trial version tries to load a game without a time
+			// zone that's part of the trial version, force the intro.
+			if (isTrial() && !((FrameWindow *)_mainWindow)->getMainChildWindow())
+				doIntro = true;
 		}
 
 		// Play the intro only if we're starting from scratch
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index f49cf53156..04a1de4612 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -30,6 +30,7 @@
 #include "common/serializer.h"
 #include "common/system.h"
 #include "common/translation.h"
+#include "gui/message.h"
 #include "gui/saveload.h"
 
 #include "buried/buried.h"
@@ -70,8 +71,22 @@ Common::Error BuriedEngine::loadGameState(int slot) {
 		return Common::kUnknownError;
 	}
 
-	((FrameWindow *)_mainWindow)->loadFromState(location, flags, inventoryItems);
+	// Done with the file
 	delete loadFile;
+
+	if (isTrial() && location.timeZone != 4) {
+		// Display a message preventing the user from loading a non-apartment
+		// saved game in the trial version
+		GUI::MessageDialog dialog("ERROR: The location in this saved game is not included in this version of Buried in Time");
+		dialog.runModal();
+
+		// Don't return an error. It's an "error" that we can't load,
+		// but we're still in a valid state. The message above will
+		// be displayed instead of the usual GUI load error.
+		return Common::kNoError;
+	}
+
+	((FrameWindow *)_mainWindow)->loadFromState(location, flags, inventoryItems);
 	return Common::kNoError;
 }
 


Commit: 0d04d75a3c9b300b04e8fecd6311e9dcfe20120e
    https://github.com/scummvm/scummvm/commit/0d04d75a3c9b300b04e8fecd6311e9dcfe20120e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add support for the Italian version

Changed paths:
    engines/buried/detection.cpp
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 4683a76f8d..043f4c75f3 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -284,6 +284,44 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
+	// Italian Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "fb3e5c9198503bbb45b79150b511af5e", 1175040 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::IT_ITA,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Italian Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "56bdd481b063c91b95c21f02faa450bb", 1169408 },
+				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::IT_ITA,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
 	// English Windows 95 8BPP
 	// v1.1
 	{
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 0cb95812ef..04b11092b2 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -1975,10 +1975,12 @@ int DeathGodPuzzleBox::specifyCursor(Window *viewWindow, const Common::Point &po
 
 bool DeathGodPuzzleBox::isPuzzleSolved() const {
 	// TODO: Ask players for solutions for other languages
-	// clone2727 only has the English, French, and Japanese source
+	// clone2727 has the English, French, and Japanese source.
+	// clone2727 has the Italian version and solved the puzzle manually.
 
 	switch (_vm->getLanguage()) {
 	case Common::DE_DEU:
+	case Common::IT_ITA:
 		return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 24;
 	case Common::EN_ANY:
 		return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;


Commit: c1c5ba7bb4799ee8185fcfaa69b134e7048d7f17
    https://github.com/scummvm/scummvm/commit/c1c5ba7bb4799ee8185fcfaa69b134e7048d7f17
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Switch to timer messages generated on-the-fly

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index b23da68fd5..44d797b669 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -148,7 +148,6 @@ Common::Error BuriedEngine::run() {
 	}
 
 	while (!shouldQuit()) {
-		updateTimers();
 		updateVideos();
 
 		pollForEvents();
@@ -261,15 +260,6 @@ bool BuriedEngine::killTimer(uint timer) {
 	return true;
 }
 
-void BuriedEngine::updateTimers() {
-	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++) {
-		if (g_system->getMillis() >= it->_value.nextTrigger) {
-			it->_value.nextTrigger += it->_value.period;
-			it->_value.owner->postMessage(new TimerMessage(it->_key));
-		}
-	}
-}
-
 void BuriedEngine::removeAllTimers(Window *window) {
 	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++)
 		if (it->_value.owner == window)
@@ -304,6 +294,22 @@ void BuriedEngine::sendAllMessages() {
 		msg.dest->sendMessage(msg.message);
 		// Control of the pointer is passed to the destination
 	}
+
+	// Generate a timer messages while they exist and there are no messages
+	// in the queue.
+	while (!shouldQuit() && _messageQueue.empty()) {
+		// Generate a timer message
+		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++) {
+			if (g_system->getMillis() >= it->_value.nextTrigger) {
+				it->_value.nextTrigger += it->_value.period;
+				it->_value.owner->sendMessage(new TimerMessage(it->_key));
+				continue;
+			}
+		}
+
+		// No timer messages to post
+		break;
+	}
 }
 
 void BuriedEngine::removeMessages(Window *window, int messageBegin, int messageEnd) {
@@ -337,6 +343,9 @@ void BuriedEngine::removeAllMessages(Window *window) {
 }
 
 bool BuriedEngine::hasMessage(Window *window, int messageBegin, int messageEnd) const {
+	// Implementation note: This doesn't currently handle timers, but would on real Windows.
+	// Buried doesn't check for timer messages being present, so it's skipped.
+
 	for (MessageQueue::const_iterator it = _messageQueue.begin(); it != _messageQueue.end(); it++)
 		if ((!window || it->dest == window) && it->message->getMessageType() >= messageBegin && it->message->getMessageType() <= messageEnd)
 			return true;
@@ -351,7 +360,6 @@ void BuriedEngine::yield() {
 	// Mark us that we're yielding so we can't save or load in a synchronous sequence
 	_yielding = true;
 
-	updateTimers();
 	updateVideos();
 
 	pollForEvents();
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 4781dbaf6c..4c1553032d 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -105,7 +105,6 @@ public:
 	// Timers
 	uint createTimer(Window *window, uint period);
 	bool killTimer(uint timer);
-	void updateTimers();
 	void removeAllTimers(Window *window);
 
 	// Video


Commit: d3f68fe216591642467a016b0a3dc803f6d36fbc
    https://github.com/scummvm/scummvm/commit/d3f68fe216591642467a016b0a3dc803f6d36fbc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Squash timers down to one if multiple are set to fire

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 44d797b669..08fc76f319 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -299,16 +299,25 @@ void BuriedEngine::sendAllMessages() {
 	// in the queue.
 	while (!shouldQuit() && _messageQueue.empty()) {
 		// Generate a timer message
+		bool ranTimer = false;
+
 		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++) {
-			if (g_system->getMillis() >= it->_value.nextTrigger) {
-				it->_value.nextTrigger += it->_value.period;
+			uint32 time = g_system->getMillis();
+
+			if (time >= it->_value.nextTrigger) {
+				// Adjust the trigger to be what the next one would be, after
+				// all the current triggers would be called.
+				uint32 triggerCount = (time - it->_value.nextTrigger + it->_value.period) / it->_value.period;
+				it->_value.nextTrigger += triggerCount * it->_value.period;
 				it->_value.owner->sendMessage(new TimerMessage(it->_key));
-				continue;
+				ranTimer = true;
+				break;
 			}
 		}
 
-		// No timer messages to post
-		break;
+		// If no timers were run, there's nothing to keep looking for
+		if (!ranTimer)
+			break;
 	}
 }
 


Commit: 67333fcc06868fa57650d58c466a3a3dac32a1f6
    https://github.com/scummvm/scummvm/commit/67333fcc06868fa57650d58c466a3a3dac32a1f6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix the wait cursor not appearing in synchronous scene movies

Changed paths:
    engines/buried/scene_view.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 6ccea6f57c..eb9aa6062d 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -59,7 +59,6 @@ SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_asyncMovieStartFrame = 0;
 	_loopAsyncMovie = false;
 	_paused = false;
-	_useWaitCursor = false;
 	_cycleEnabled = ((FrameWindow *)(_parent->getParent()))->isFrameCyclingDefault();
 	_disableArthur = false;
 	_demoSoundEffectHandle = -1;
@@ -1489,7 +1488,7 @@ bool SceneViewWindow::getCurrentSceneLocation(Location &location) {
 }
 
 bool SceneViewWindow::playSynchronousAnimation(int animationID) {
-	_useWaitCursor = true;
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
 	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
 
@@ -1556,12 +1555,12 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 		return false;
 
 	delete animationMovie;
-	_useWaitCursor = false;
+	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
 bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
-	_useWaitCursor = true;
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
 	VideoWindow *animationMovie = new VideoWindow(_vm, this);
 	Common::String fileName = _vm->getFilePath(animationID);
@@ -1603,12 +1602,12 @@ bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
 		return false;
 
 	delete animationMovie;
-	_useWaitCursor = false;
+	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
 bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left, int top) {
-	_useWaitCursor = true;
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
 	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
 
@@ -1677,12 +1676,12 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 		return false;
 
 	delete animationMovie;
-	_useWaitCursor = false;
+	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
 bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left, int top, int right, int bottom) {
-	_useWaitCursor = true;
+	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
 	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
 
@@ -1754,7 +1753,7 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 		return false;
 
 	delete animationMovie;
-	_useWaitCursor = false;
+	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
@@ -2546,11 +2545,6 @@ void SceneViewWindow::onTimer(uint timer) {
 }
 
 bool SceneViewWindow::onSetCursor(uint message) {
-	if (_useWaitCursor) {
-		_vm->_gfx->setCursor(kCursorWait);
-		return true;
-	}
-
 	// Check the scene cursor callback function to see if we need to change the cursor
 	int newCursor = (int)kCursorArrow;
 	if (_currentScene)
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index c3cf6e6171..89fade0618 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -187,9 +187,6 @@ private:
 
 	Common::String _lastAICommentFileName;
 
-	bool _useWaitCursor;
-	int _oldCursorForWait;
-
 	// Special sound handling for the demo
 	uint _demoSoundTimer;
 	int _demoSoundEffectHandle;


Commit: e484ec4f5da1319bff627b3d781c32bdc41c3e20
    https://github.com/scummvm/scummvm/commit/e484ec4f5da1319bff627b3d781c32bdc41c3e20
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Use a ScopedPtr for temporary VideoWindows

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index eb9aa6062d..ea66922436 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -38,6 +38,7 @@
 #include "buried/video_window.h"
 #include "buried/environ/scene_base.h"
 
+#include "common/ptr.h"
 #include "common/stream.h"
 #include "common/system.h"
 #include "graphics/surface.h"
@@ -714,7 +715,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	((GameUIWindow *)_parent)->_bioChipRightWindow->changeCurrentBioChip(kItemBioChipJump);
 
 	// Play the movie
-	VideoWindow *jumpMovie = new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow);
+	Common::ScopedPtr<VideoWindow> jumpMovie(new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow));
 	if (!jumpMovie->openVideo(_vm->getFilePath(IDS_BC_JUMP_MOVIE_FILENAME)))
 		error("Failed to play small jump movie");
 
@@ -746,9 +747,8 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	// Make sure the interface sound has stopped
 	_vm->_sound->stopInterfaceSound();
 
-	delete jumpMovie;
 	_vm->_sound->timerCallback();
-	jumpMovie = new VideoWindow(_vm, this);
+	jumpMovie.reset(new VideoWindow(_vm, this));
 
 	Common::String fileName;
 	switch (destination) {
@@ -790,7 +790,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 		return true;
 
 	_vm->_sound->restart();
-	delete jumpMovie;
+	jumpMovie.reset();
 
 	// Initialize the time zone and environment
 	initializeTimeZoneAndEnvironment(this, newLocation.timeZone, -1);
@@ -844,7 +844,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	_vm->_sound->timerCallback();
 
 	// Time to show and play the right-hand small movie to the mid point, with proper sound
-	jumpMovie = new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow);
+	jumpMovie.reset(new VideoWindow(_vm, ((GameUIWindow *)_parent)->_bioChipRightWindow));
 
 	if (!jumpMovie->openVideo(_vm->getFilePath(IDS_BC_JUMP_MOVIE_FILENAME)))
 		error("Failed to play small jump movie");
@@ -877,7 +877,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	_vm->_sound->stopInterfaceSound();
 
 	// Destroy the movie
-	delete jumpMovie;
+	jumpMovie.reset();
 
 	// Repaint the BioChip view window
 	((GameUIWindow *)_parent)->_bioChipRightWindow->invalidateWindow(false);
@@ -1052,7 +1052,7 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 		newBackground = getStillFrameCopy(navFrame);
 
 	// Open the movie
-	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::ScopedPtr<VideoWindow> animationMovie(new VideoWindow(_vm, this));
 
 	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, destinationData.transitionData);
 	if (!animationMovie->openVideo(fileName))
@@ -1073,7 +1073,7 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 	if (_vm->shouldQuit())
 		return true;
 
-	delete animationMovie;
+	animationMovie.reset();
 
 	if (audioStream)
 		_vm->_sound->restart();
@@ -1504,7 +1504,7 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	if (!found)
 		return false;
 
-	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::ScopedPtr<VideoWindow> animationMovie(new VideoWindow(_vm, this));
 	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animDatabase[i].fileNameID);
 	if (!animationMovie->openVideo(fileName))
 		error("Failed to open video '%s'", fileName.c_str());
@@ -1513,11 +1513,8 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	if (_globalFlags.bcTranslateEnabled == 1 && animDatabase[i].audioStreamCount > 1)
 		animationMovie->setAudioTrack(2);
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
-		// FIXME: Nah, why bother to free the movie
-		// (Probably, this is never hit)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_START) == SC_FALSE)
 		return false;
-	}
 
 	animationMovie->seekToFrame(animDatabase[i].startFrame);
 	animationMovie->enableWindow(false);
@@ -1539,10 +1536,8 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 		_vm->_sound->timerCallback();
 	}
 
-	if (_vm->shouldQuit()) {
-		delete animationMovie;
+	if (_vm->shouldQuit())
 		return true;
-	}
 
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
@@ -1551,10 +1546,9 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	if (animDatabase[i].audioStreamCount > 0)
 		_vm->_sound->restart();
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	delete animationMovie;
 	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
@@ -1562,16 +1556,13 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
 	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
 
-	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::ScopedPtr<VideoWindow> animationMovie(new VideoWindow(_vm, this));
 	Common::String fileName = _vm->getFilePath(animationID);
 	if (!animationMovie->openVideo(fileName))
 		error("Failed to open video '%s'", fileName.c_str());
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
-		// FIXME: Nah, why bother to free the movie
-		// (Probably, this is never hit)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_START) == SC_FALSE)
 		return false;
-	}
 
 	animationMovie->enableWindow(false);
 	animationMovie->showWindow(kWindowShow);
@@ -1589,19 +1580,16 @@ bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
 		_vm->_sound->timerCallback();
 	}
 
-	if (_vm->shouldQuit()) {
-		delete animationMovie;
+	if (_vm->shouldQuit())
 		return true;
-	}
 
 	_vm->_sound->restart();
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	delete animationMovie;
 	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
@@ -1623,7 +1611,7 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 	if (!found)
 		return false;
 
-	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::ScopedPtr<VideoWindow> animationMovie(new VideoWindow(_vm, this));
 	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animDatabase[i].fileNameID);
 	if (!animationMovie->openVideo(fileName))
 		error("Failed to open video '%s'", fileName.c_str());
@@ -1634,11 +1622,8 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 	if (_globalFlags.bcTranslateEnabled == 1 && animDatabase[i].audioStreamCount > 1)
 		animationMovie->setAudioTrack(2);
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
-		// FIXME: Nah, why bother to free the movie
-		// (Probably, this is never hit)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_START) == SC_FALSE)
 		return false;
-	}
 
 	animationMovie->seekToFrame(animDatabase[i].startFrame);
 	animationMovie->enableWindow(false);
@@ -1660,10 +1645,8 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 		_vm->_sound->timerCallback();
 	}
 
-	if (_vm->shouldQuit()) {
-		delete animationMovie;
+	if (_vm->shouldQuit())
 		return true;
-	}
 
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
@@ -1672,10 +1655,9 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 	if (animDatabase[i].audioStreamCount > 0)
 		_vm->_sound->restart();
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	delete animationMovie;
 	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
@@ -1697,7 +1679,7 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 	if (!found)
 		return false;
 
-	VideoWindow *animationMovie = new VideoWindow(_vm, this);
+	Common::ScopedPtr<VideoWindow> animationMovie(new VideoWindow(_vm, this));
 	Common::String fileName = _vm->getFilePath(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment, animDatabase[i].fileNameID);
 	if (!animationMovie->openVideo(fileName))
 		error("Failed to open video '%s'", fileName.c_str());
@@ -1711,11 +1693,8 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 	if (_globalFlags.bcTranslateEnabled == 1 && animDatabase[i].audioStreamCount > 1)
 		animationMovie->setAudioTrack(2);
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_START) == SC_FALSE) {
-		// FIXME: Nah, why bother to free the movie
-		// (Probably, this is never hit)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_START) == SC_FALSE)
 		return false;
-	}
 
 	animationMovie->seekToFrame(animDatabase[i].startFrame);
 	animationMovie->enableWindow(false);
@@ -1737,10 +1716,8 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 		_vm->_sound->timerCallback();
 	}
 
-	if (_vm->shouldQuit()) {
-		delete animationMovie;
+	if (_vm->shouldQuit())
 		return true;
-	}
 
 	_vm->removeMouseMessages(this);
 	_vm->removeKeyboardMessages(this);
@@ -1749,10 +1726,9 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 	if (animDatabase[i].audioStreamCount > 0)
 		_vm->_sound->restart();
 
-	if (_currentScene && _currentScene->movieCallback(this, animationMovie, animationID, MOVIE_STOPPED) == SC_FALSE)
+	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	delete animationMovie;
 	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }


Commit: 14d9738021aeeb25bfb388cd1848ae285d673366
    https://github.com/scummvm/scummvm/commit/14d9738021aeeb25bfb388cd1848ae285d673366
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Use an RAII class to handle temporary cursor changes

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h
    engines/buried/scene_view.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 90ede02685..0939b6a316 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -873,4 +873,12 @@ void GraphicsManager::drawEllipse(const Common::Rect &rect, uint32 color) {
 	}
 }
 
+TempCursorChange::TempCursorChange(Cursor cursor) {
+	_prevCursor = static_cast<BuriedEngine*>(g_engine)->_gfx->setCursor(cursor);
+}
+
+TempCursorChange::~TempCursorChange() {
+	static_cast<BuriedEngine*>(g_engine)->_gfx->setCursor(_prevCursor);
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 10638225c7..231872dd81 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -130,6 +130,19 @@ private:
 	Common::SeekableReadStream *findMSGothicStream() const;
 };
 
+/**
+ * RAII method of changing a cursor temporarily and reset
+ * to the previous one on destruction.
+ */
+class TempCursorChange {
+public:
+	TempCursorChange(Cursor cursor);
+	~TempCursorChange();
+
+private:
+	Cursor _prevCursor;
+};
+
 } // End of namespace Buried
 
 #endif
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index ea66922436..d3b722143b 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1008,7 +1008,7 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 }
 
 bool SceneViewWindow::videoTransition(const Location &location, DestinationScene destinationData, int navFrame) {
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	_paused = true;
 	bool audioStream = true;
@@ -1084,7 +1084,6 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 		delete newBackground;
 	}
 
-	_vm->_gfx->setCursor(oldCursor);
 	_paused = false;
 
 	return true;
@@ -1092,7 +1091,7 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 
 bool SceneViewWindow::walkTransition(const Location &location, const DestinationScene &destinationData, int navFrame) {
 	_paused = true;
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 	Graphics::Surface *newBackground = 0;
 
 	if (navFrame >= 0) {
@@ -1144,7 +1143,6 @@ bool SceneViewWindow::walkTransition(const Location &location, const Destination
 	delete newBackground;
 
 	_walkMovie->showWindow(kWindowHide);
-	_vm->_gfx->setCursor(oldCursor);
 	_paused = false;
 
 	return true;
@@ -1156,7 +1154,7 @@ bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics:
 		return false;
 
 	// Change the cursor to an hourglass
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 	_useScenePaint = false;
 
 	switch (direction) {
@@ -1206,7 +1204,6 @@ bool SceneViewWindow::pushTransition(Graphics::Surface *curBackground, Graphics:
 		break;
 	}
 
-	_vm->_gfx->setCursor(oldCursor);
 	_useScenePaint = true;
 	return true;
 }
@@ -1229,7 +1226,7 @@ bool SceneViewWindow::slideInTransition(Graphics::Surface *newBackground, int di
 		return false;
 
 	// Change the cursor to an hourglass
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	switch (direction) {
 	case 0: // Push down
@@ -1270,7 +1267,6 @@ bool SceneViewWindow::slideInTransition(Graphics::Surface *newBackground, int di
 		break;
 	}
 
-	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
@@ -1280,7 +1276,7 @@ bool SceneViewWindow::slideOutTransition(Graphics::Surface *newBackground, int d
 		return false;
 
 	// Change the cursor to an hourglass
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	Graphics::Surface curBackground;
 	curBackground.copyFrom(*_preBuffer);
@@ -1324,7 +1320,6 @@ bool SceneViewWindow::slideOutTransition(Graphics::Surface *newBackground, int d
 
 	curBackground.free();
 	_useScenePaint = true;
-	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
@@ -1488,7 +1483,7 @@ bool SceneViewWindow::getCurrentSceneLocation(Location &location) {
 }
 
 bool SceneViewWindow::playSynchronousAnimation(int animationID) {
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
 
@@ -1549,12 +1544,11 @@ bool SceneViewWindow::playSynchronousAnimation(int animationID) {
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
 bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	Common::ScopedPtr<VideoWindow> animationMovie(new VideoWindow(_vm, this));
 	Common::String fileName = _vm->getFilePath(animationID);
@@ -1590,12 +1584,11 @@ bool SceneViewWindow::playSynchronousAnimationExtern(int animationID) {
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
 bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left, int top) {
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
 
@@ -1658,12 +1651,11 @@ bool SceneViewWindow::playPlacedSynchronousAnimation(int animationID, int left,
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
 bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left, int top, int right, int bottom) {
-	Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+	TempCursorChange cursorChange(kCursorWait);
 
 	Common::Array<AnimEvent> animDatabase = getAnimationDatabase(_currentScene->_staticData.location.timeZone, _currentScene->_staticData.location.environment);
 
@@ -1729,7 +1721,6 @@ bool SceneViewWindow::playClippedSynchronousAnimation(int animationID, int left,
 	if (_currentScene && _currentScene->movieCallback(this, animationMovie.get(), animationID, MOVIE_STOPPED) == SC_FALSE)
 		return false;
 
-	_vm->_gfx->setCursor(oldCursor);
 	return true;
 }
 
@@ -2455,9 +2446,8 @@ void SceneViewWindow::onKeyUp(const Common::KeyState &key, uint flags) {
 	case Common::KEYCODE_SPACE:
 		if (((GameUIWindow *)_parent)->_inventoryWindow->isItemInInventory(kItemBioChipAI) && _globalFlags.bcCloakingEnabled != 1) {
 			if (!_lastAICommentFileName.empty() && !_vm->_sound->isAsynchronousAICommentPlaying()) {
-				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+				TempCursorChange cursorChange(kCursorWait);
 				_vm->_sound->playAsynchronousAIComment(_lastAICommentFileName);
-				_vm->_gfx->setCursor(oldCursor);
 			}
 			return;
 		}


Commit: 85ae8a95caf85951e91ee094f17e5bf67b13772e
    https://github.com/scummvm/scummvm/commit/85ae8a95caf85951e91ee094f17e5bf67b13772e
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Use TempCursorChange in a few more places

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/inventory_info.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index cbba3cabaa..8fd3e13a0b 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -227,15 +227,13 @@ void JumpBiochipViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 			break;
 		case REGION_JUMP:
 			if (_jumpButton.contains(point)) {
-				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+				TempCursorChange cursorChange(kCursorWait);
 
 				SceneViewWindow *sceneViewWindow = (SceneViewWindow *)getParent()->getParent();
 				int curSelection = _curSelection;
-				GraphicsManager *gfx = _vm->_gfx;
 
 				((GameUIWindow *)getParent()->getParent()->getParent())->_bioChipRightWindow->destroyBioChipViewWindow();
 				sceneViewWindow->timeSuitJump(curSelection);
-				gfx->setCursor(oldCursor);
 				return;
 			}
 			break;
diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 8de87e289e..1dc36dc357 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -643,8 +643,7 @@ IceteroidMineControls::IceteroidMineControls(BuriedEngine *vm, Window *viewWindo
 
 int IceteroidMineControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
 	if (_mineButton.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined < 255) {
-		GraphicsManager *gfx = _vm->_gfx;
-		Cursor oldCursor = gfx->setCursor(kCursorWait);
+		TempCursorChange cursorChange(kCursorWait);
 
 		// Update the amount of ice mined
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiIceMined++;
@@ -662,8 +661,6 @@ int IceteroidMineControls::mouseUp(Window *viewWindow, const Common::Point &poin
 		destinationData.transitionLength = -1;
 		((SceneViewWindow *)viewWindow)->moveToDestination(destinationData);
 
-		// Reset the cursor
-		gfx->setCursor(oldCursor);
 		return SC_TRUE;
 	}
 
@@ -812,7 +809,7 @@ int IceteroidDispenserControls::mouseDown(Window *viewWindow, const Common::Poin
 int IceteroidDispenserControls::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
 	if (_oxygenHandle.contains(pointLocation)) {
 		if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiOxygenReserves > 0 || ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICProcessedOxygen == 1) {
-			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+			TempCursorChange cursorChange(kCursorWait);
 
 			// Reset the flags
 			if (((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICProcessedOxygen == 0)
@@ -833,8 +830,6 @@ int IceteroidDispenserControls::mouseUp(Window *viewWindow, const Common::Point
 			else
 				text = "Emergency oxygen reserves refilled.";
 			((SceneViewWindow *)viewWindow)->displayLiveText(text, false);
-
-			_vm->_gfx->setCursor(oldCursor);
 		} else {
 			// Play voiceover informing the player the oxygen needs to be refilled
 			_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12));
@@ -844,10 +839,9 @@ int IceteroidDispenserControls::mouseUp(Window *viewWindow, const Common::Point
 	}
 
 	if (_fillHandle.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle > 0) {
-		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+		TempCursorChange cursorChange(kCursorWait);
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICWaterInFillHandle = 2;
 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(17);
-		_vm->_gfx->setCursor(oldCursor);
 		return SC_TRUE;
 	}
 
@@ -1600,7 +1594,7 @@ int NexusEnd::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
 
 		// Play Arthur's comments
 
-		Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+		TempCursorChange cursorChange(kCursorWait);
 
 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->_forceComment = true;
 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->invalidateWindow(false);
@@ -1615,7 +1609,6 @@ int NexusEnd::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
 		((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->invalidateWindow(false);
 		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 12));
 		_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13));
-		_vm->_gfx->setCursor(oldCursor);
 	}
 
 	return SC_TRUE;
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 04b11092b2..04c9f05b9c 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -1315,9 +1315,9 @@ int ArrowGodHead::timerCallback(Window *viewWindow) {
 		if (lastStartedTimer > 0 && g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE)) {
 			((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4, 0);
 
-			if (i == _headID) {
-				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+			TempCursorChange cursorChange(kCursorWait);
 
+			if (i == _headID) {
 				byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
 
 				if (status & 1) {
@@ -1366,10 +1366,7 @@ int ArrowGodHead::timerCallback(Window *viewWindow) {
 				}
 
 				((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
-				_vm->_gfx->setCursor(oldCursor);
 			} else {
-				Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
-
 				byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
 
 				if (status & 1) {
@@ -1407,8 +1404,6 @@ int ArrowGodHead::timerCallback(Window *viewWindow) {
 					else if (_staticData.location.node == 2)
 						_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
 				}
-
-				_vm->_gfx->setCursor(oldCursor);
 			}
 		}
 	}
@@ -1588,7 +1583,7 @@ int ArrowGodDepthChange::timerCallback(Window *viewWindow) {
 				i == 0 || (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && i == 1) ||
 				(((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i) == 2 && i == 3))) {
 			((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4, 0);
-			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+			TempCursorChange cursorChange(kCursorWait);
 			byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
 
 			if (status & 1) {
@@ -1600,7 +1595,6 @@ int ArrowGodDepthChange::timerCallback(Window *viewWindow) {
 			}
 
 			((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
-			_vm->_gfx->setCursor(oldCursor);
 		}
 	}
 
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index cde50abae9..8d3bb841fa 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -200,7 +200,7 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 
 		// Only draw if transitions are enabled
 		if (offset != 189) {
-			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+			TempCursorChange cursorChange(kCursorWait);
 
 			Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
 		
@@ -216,8 +216,6 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 
 			newFrame->free();
 			delete newFrame;
-
-			_vm->_gfx->setCursor(oldCursor);
 		}
 
 		_rebuildPage = true;
@@ -232,7 +230,7 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 
 		// Only draw if transitions are enabled
 		if (offset != 189) {
-			Cursor oldCursor = _vm->_gfx->setCursor(kCursorWait);
+			TempCursorChange cursorChange(kCursorWait);
 
 			Graphics::Surface *newFrame = _stillFrames->getFrameCopy(_curView);
 
@@ -248,8 +246,6 @@ void BurnedLetterViewWindow::onLButtonUp(const Common::Point &point, uint flags)
 
 			newFrame->free();
 			delete newFrame;
-
-			_vm->_gfx->setCursor(oldCursor);
 		}
 
 		_rebuildPage = true;


Commit: ceb1e3c3598c8695b8af89b3f22f3afdbb00b33d
    https://github.com/scummvm/scummvm/commit/ceb1e3c3598c8695b8af89b3f22f3afdbb00b33d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add debug location utilities to the console

In v1.01, these were all done in debug windows. This is a bit cleaner.

Changed paths:
    engines/buried/console.cpp
    engines/buried/console.h
    engines/buried/scene_view.h


diff --git a/engines/buried/console.cpp b/engines/buried/console.cpp
index 74acd0f12e..7f9bb574d4 100644
--- a/engines/buried/console.cpp
+++ b/engines/buried/console.cpp
@@ -25,12 +25,22 @@
 #include "buried/frame_window.h"
 #include "buried/gameui.h"
 #include "buried/inventory_window.h"
+#include "buried/resources.h"
+#include "buried/scene_view.h"
+#include "buried/environ/scene_base.h"
 
 namespace Buried {
 
 BuriedConsole::BuriedConsole(BuriedEngine *vm) : _vm(vm) {
 	registerCmd("giveitem", WRAP_METHOD(BuriedConsole, cmdGiveItem));
 	registerCmd("removeitem", WRAP_METHOD(BuriedConsole, cmdRemoveItem));
+
+	// This feature, while present in the demo and trial, has 99% bad
+	// entries and is generally useless.
+	if (!_vm->isDemo() && !_vm->isTrial())
+		registerCmd("jumpentry", WRAP_METHOD(BuriedConsole, cmdJumpEntry));
+
+	registerCmd("curloc", WRAP_METHOD(BuriedConsole, cmdCurLocation));
 }
 
 BuriedConsole::~BuriedConsole() {
@@ -49,17 +59,9 @@ bool BuriedConsole::cmdGiveItem(int argc, const char **argv) {
 		return true;
 	}
 
-	FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
-
-	if (!frameWindow) {
-		debugPrintf("Main window not yet created!\n");
-		return true;
-	}
-
-	if (!frameWindow->isGameInProgress()) {
-		debugPrintf("The game is currently not in progress!\n");
+	FrameWindow *frameWindow = getFrameWindow();
+	if (!frameWindow)
 		return true;
-	}
 
 	InventoryWindow *inventory = ((GameUIWindow *)frameWindow->getMainChildWindow())->_inventoryWindow;
 	if (inventory->isItemInInventory(itemID)) {
@@ -85,17 +87,9 @@ bool BuriedConsole::cmdRemoveItem(int argc, const char **argv) {
 		return true;
 	}
 
-	FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
-
-	if (!frameWindow) {
-		debugPrintf("Main window not yet created!\n");
+	FrameWindow *frameWindow = getFrameWindow();
+	if (!frameWindow)
 		return true;
-	}
-
-	if (!frameWindow->isGameInProgress()) {
-		debugPrintf("The game is currently not in progress!\n");
-		return true;
-	}
 
 	InventoryWindow *inventory = ((GameUIWindow *)frameWindow->getMainChildWindow())->_inventoryWindow;
 	if (!inventory->isItemInInventory(itemID)) {
@@ -108,4 +102,141 @@ bool BuriedConsole::cmdRemoveItem(int argc, const char **argv) {
 	return true;
 }
 
+bool BuriedConsole::cmdJumpEntry(int argc, const char **argv) {
+	loadJumpEntryList();
+
+	if (argc < 2) {
+		debugPrintf("Usage: %s <index>\n\nEntries:\n", argv[0]);
+		debugPrintf("# |Time Zone       |Environment            \n");
+		debugPrintf("--|----------------|-----------------------\n");
+
+		for (uint32 i = 0; i < _jumpEntryList.size(); i++) {
+			const JumpEntry &entry = _jumpEntryList[i];
+			debugPrintf("%2d|%-16s|%-23s\n", i + 1, entry.timeZoneName.c_str(), entry.locationName.c_str());
+		}
+
+		return true;
+	}
+
+	// Bail if not playing
+	if (!isPlaying())
+		return true;
+
+	int entry = atoi(argv[1]) - 1;
+	if (entry < 0 || entry >= (int)_jumpEntryList.size()) {
+		debugPrintf("Invalid entry!\n");
+		return true;
+	}
+
+	// Store the location to make the jump after we close the console
+	_jump = _jumpEntryList[entry].location;
+	return false;
+}
+
+bool BuriedConsole::cmdCurLocation(int argc, const char **argv) {
+	FrameWindow *frameWindow = getFrameWindow();
+	if (!frameWindow)
+		return true;
+
+	const SceneBase *scene = ((GameUIWindow *)frameWindow->getMainChildWindow())->_sceneViewWindow->getCurrentScene();
+	if (!scene) {
+		debugPrintf("No scene!\n");
+		return true;
+	}
+
+	const LocationStaticData &staticData = scene->_staticData;
+	debugPrintf("Time Zone: %d\n", staticData.location.timeZone);
+	debugPrintf("Environment: %d\n", staticData.location.environment);
+	debugPrintf("Node: %d\n", staticData.location.node);
+	debugPrintf("Facing: %d\n", staticData.location.facing);
+	debugPrintf("Orientation: %d\n", staticData.location.orientation);
+	debugPrintf("Depth: %d\n", staticData.location.depth);
+	debugPrintf("Class: %d\n", staticData.classID);
+
+	return true;
+}
+
+void BuriedConsole::postEnter() {
+	GUI::Debugger::postEnter();
+
+	if (_jump.timeZone >= 0) {
+		// Perform a requested jump
+		FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
+		SceneViewWindow *sceneView = ((GameUIWindow *)frameWindow->getMainChildWindow())->_sceneViewWindow;
+		if (!sceneView->jumpToScene(_jump))
+			error("Failed to jump to requested time zone");
+
+		_jump = Location();
+	}
+}
+
+static int getNextLocationInt(const char *&ptr) {
+	if (!ptr || *ptr == 0)
+		return -1;
+
+	int value = atoi(ptr);
+	ptr = strchr(ptr, ',');
+	if (ptr)
+		ptr++;
+
+	return value;
+}
+
+void BuriedConsole::loadJumpEntryList() {
+	// Check if loaded already
+	if (!_jumpEntryList.empty())
+		return;
+
+	for (uint32 i = IDS_MOVEMENT_DATA_BASE_ID; ; i++) {
+		Common::String text = _vm->getString(i);
+		if (text.empty())
+			break;
+
+		const char *pipeStr1 = strchr(text.c_str(), '|');
+		if (!pipeStr1)
+			break;
+
+		JumpEntry entry;
+		entry.timeZoneName = Common::String(text.c_str(), pipeStr1);
+
+		const char *pipeStr2 = strchr(pipeStr1 + 1, '|');
+		if (!pipeStr2)
+			break;
+
+		entry.locationName = Common::String(pipeStr1 + 1, pipeStr2);
+
+		pipeStr2++;
+		entry.location.timeZone = getNextLocationInt(pipeStr2);
+		entry.location.environment = getNextLocationInt(pipeStr2);
+		entry.location.node = getNextLocationInt(pipeStr2);
+		entry.location.facing = getNextLocationInt(pipeStr2);
+		entry.location.orientation = getNextLocationInt(pipeStr2);
+		entry.location.depth = getNextLocationInt(pipeStr2);
+
+		// Failed to parse
+		if (entry.location.timeZone < 0 || entry.location.environment < 0 ||
+				entry.location.node < 0 || entry.location.facing < 0 ||
+				entry.location.orientation < 0 || entry.location.depth < 0)
+			break;
+
+		_jumpEntryList.push_back(entry);
+	}
+}
+
+FrameWindow *BuriedConsole::getFrameWindow() {
+	FrameWindow *frameWindow = (FrameWindow *)_vm->_mainWindow;
+
+	if (!frameWindow) {
+		debugPrintf("Main window not yet created!\n");
+		return 0;
+	}
+
+	if (!frameWindow->isGameInProgress()) {
+		debugPrintf("The game is currently not in progress!\n");
+		return 0;
+	}
+
+	return frameWindow;
+}
+
 } // End of namespace Buried
diff --git a/engines/buried/console.h b/engines/buried/console.h
index 3811b58bd0..a717c86601 100644
--- a/engines/buried/console.h
+++ b/engines/buried/console.h
@@ -25,9 +25,12 @@
 
 #include "gui/debugger.h"
 
+#include "buried/navdata.h"
+
 namespace Buried {
 
 class BuriedEngine;
+class FrameWindow;
 
 class BuriedConsole : public GUI::Debugger {
 public:
@@ -36,9 +39,29 @@ public:
 
 	bool cmdGiveItem(int argc, const char **argv);
 	bool cmdRemoveItem(int argc, const char **argv);
+	bool cmdJumpEntry(int argc, const char **argv);
+	bool cmdCurLocation(int argc, const char **argv);
+
+protected:
+	void postEnter();
 
 private:
 	BuriedEngine *_vm;
+
+	struct JumpEntry {
+		Common::String timeZoneName;
+		Common::String locationName;
+		Location location;
+	};
+
+	typedef Common::Array<JumpEntry> JumpEntryList;
+	JumpEntryList _jumpEntryList;
+	void loadJumpEntryList();
+
+	FrameWindow *getFrameWindow();
+	bool isPlaying() { return getFrameWindow() != 0; }
+
+	Location _jump;
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index 89fade0618..c577743761 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -155,6 +155,8 @@ public:
 	bool startEnvironmentAmbient(int oldTimeZone = -1, int oldEnvironment = -1, int timeZone = -1, int environment = -1, bool fade = true);
 	bool checkCustomAICommentDependencies(const Location &commentLocation, const AIComment &commentData);
 
+	const SceneBase *getCurrentScene() const { return _currentScene; }
+
 private:
 	Graphics::Surface *_preBuffer;
 	SceneBase *_currentScene;


Commit: 7574c843a0956f3453bab4b70ab6d20e9b05afa9
    https://github.com/scummvm/scummvm/commit/7574c843a0956f3453bab4b70ab6d20e9b05afa9
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix re-enabling cycling

The original failed to, which meant that the cycles wouldn't come back immediately.

Changed paths:
    engines/buried/scene_view.cpp


diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index d3b722143b..8b8281e692 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -1376,13 +1376,25 @@ bool SceneViewWindow::flushCycleFrameCache() {
 }
 
 bool SceneViewWindow::enableCycling(bool enable) {
+	// Do nothing if nothing changed
+	if (_cycleEnabled == enable)
+		return true;
+
 	_cycleEnabled = enable;
 
-	if (!enable) {
+	if (enable) {
+		// Re-enabling -> set up the cycle movie again
+		if (_currentScene) {
+			const LocationStaticData &staticData = _currentScene->_staticData;
+			if (staticData.cycleStartFrame >= 0)
+				changeCycleFrameMovie(_vm->getFilePath(staticData.location.timeZone, staticData.location.environment, SF_CYCLES));
+		}
+	} else {
+		// Disabling -> close the cycle movie
 		flushCycleFrameCache();
 		_cycleFrames->close();
 	}
-	
+
 	return true;
 }
 


Commit: ef983ee568f3d57b45e7609fa7fac17e0d215dad
    https://github.com/scummvm/scummvm/commit/ef983ee568f3d57b45e7609fa7fac17e0d215dad
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix the lair scene affecting the flicker option

The original would force flicker to return after the scene unconditionally. The option was also incorrect and could be disabled again mid-scene. The scene requesting flicker and the flicker option are now separate.

Changed paths:
    engines/buried/environ/agent3_lair.cpp
    engines/buried/scene_view.cpp
    engines/buried/scene_view.h


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 156eddcca4..732e4134e0 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -43,6 +43,7 @@ class LairEntry : public SceneBase {
 public:
 	LairEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
 	int timerCallback(Window *viewWindow);
 	int onCharacter(Window *viewWindow, const Common::KeyState &character);
 
@@ -54,7 +55,6 @@ private:
 	int _passwordIndex;
 	uint32 _stepDelay;
 	uint32 _rawStepDelay;
-	bool _flickerOn;
 };
 
 LairEntry::LairEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
@@ -65,18 +65,19 @@ LairEntry::LairEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticD
 	_passwordIndex = 0;
 	_stepDelay = 0;
 	_rawStepDelay = 15000;
-	_flickerOn = ((SceneViewWindow *)viewWindow)->getCyclingStatus();
-	((SceneViewWindow *)viewWindow)->enableCycling(true);
-
-	// Force load the cycle file
-	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
 }
 
 int LairEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
-	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alRestoreSkipAgent3Initial == 1) {
-		// Disable frame caching
-		((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
+	// Force enable frame cycling
+	((SceneViewWindow *)viewWindow)->forceEnableCycling(true);
+
+	// Disable frame caching
+	((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
+
+	// Force open the video
+	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
 
+	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().alRestoreSkipAgent3Initial == 1) {
 		// Start new secondary ambient
 		_vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 64);
 
@@ -95,13 +96,6 @@ int LairEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation)
 		return SC_TRUE;
 	}
 
-	// Disable frame caching
-	((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
-
-	// Turn on flicker
-	_flickerOn = ((SceneViewWindow *)viewWindow)->getCyclingStatus();
-	((SceneViewWindow *)viewWindow)->enableCycling(true);
-
 	// Empty the input queue
 	_vm->removeMouseMessages(viewWindow);
 	_vm->removeKeyboardMessages(viewWindow);
@@ -199,6 +193,11 @@ int LairEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation)
 	return SC_TRUE;
 }
 
+int LairEntry::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	((SceneViewWindow *)viewWindow)->forceEnableCycling(false);
+	return SC_TRUE;
+}
+
 int LairEntry::timerCallback(Window *viewWindow) {
 	SceneBase::timerCallback(viewWindow);
 
@@ -251,7 +250,7 @@ int LairEntry::timerCallback(Window *viewWindow) {
 			_vm->_sound->setAmbientSound();
 			_vm->_sound->setSecondaryAmbientSound();
 			((SceneViewWindow *)viewWindow)->playSynchronousAnimation(13);
-			((SceneViewWindow *)viewWindow)->enableCycling(_flickerOn);
+			((SceneViewWindow *)viewWindow)->forceEnableCycling(false);
 			((SceneViewWindow *)viewWindow)->showDeathScene(20);
 			break;
 		case 5: {
@@ -273,9 +272,7 @@ int LairEntry::timerCallback(Window *viewWindow) {
 			newScene.transitionData = 15;
 			newScene.transitionStartFrame = -1;
 			newScene.transitionLength = -1;
-			bool flickerOn = _flickerOn;
 			((SceneViewWindow *)viewWindow)->moveToDestination(newScene);
-			((SceneViewWindow *)viewWindow)->enableCycling(flickerOn);
 			break;
 		}
 		}
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 8b8281e692..e10ca5e78e 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -61,6 +61,7 @@ SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_loopAsyncMovie = false;
 	_paused = false;
 	_cycleEnabled = ((FrameWindow *)(_parent->getParent()))->isFrameCyclingDefault();
+	_forceCycleEnabled = false;
 	_disableArthur = false;
 	_demoSoundEffectHandle = -1;
 
@@ -377,7 +378,7 @@ bool SceneViewWindow::jumpToScene(const Location &newLocation) {
 
 	_currentScene = newScene;
 
-	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+	if (isCyclingEnabled() && newSceneStaticData.cycleStartFrame == -1)
 		flushCycleFrameCache();
 
 	invalidateWindow(false);
@@ -458,7 +459,7 @@ bool SceneViewWindow::jumpToSceneRestore(const Location &newLocation) {
 
 	_currentScene = newScene;
 
-	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+	if (isCyclingEnabled() && newSceneStaticData.cycleStartFrame == -1)
 		flushCycleFrameCache();
 
 	if (_currentScene->preEnterRoom(this, passedLocation) == SC_END_PROCESSING)
@@ -624,7 +625,7 @@ bool SceneViewWindow::moveToDestination(const DestinationScene &destinationData)
 	_currentScene = newScene;
 
 	// If this scene has no cycle frames, flush the cycle frame cache
-	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+	if (isCyclingEnabled() && newSceneStaticData.cycleStartFrame == -1)
 		flushCycleFrameCache();
 
 	// Call the pre-enter function, exiting this function if SC_END_PROCESSING is returned
@@ -828,7 +829,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 	_currentScene = newScene;
 
 	// If this scene has no cycle frames, flush the cycle frame cache
-	if (_cycleEnabled && newSceneStaticData.cycleStartFrame == -1)
+	if (isCyclingEnabled() && newSceneStaticData.cycleStartFrame == -1)
 		flushCycleFrameCache();
 
 	// Update navigation buttons, if not cloaked
@@ -1329,8 +1330,9 @@ bool SceneViewWindow::changeStillFrameMovie(const Common::String &fileName) {
 
 bool SceneViewWindow::changeCycleFrameMovie(const Common::String &fileName) {
 	// Only continue if cycling is enabled
-	if (!_cycleEnabled)
+	if (!isCyclingEnabled()) {
 		return false;
+	}
 
 	if (((FrameWindow *)(_parent->getParent()))->isFrameCachingAllowed())
 		return _cycleFrames->open(fileName, 5);
@@ -1347,21 +1349,21 @@ const Graphics::Surface *SceneViewWindow::getStillFrame(int frameIndex) {
 }
 
 Graphics::Surface *SceneViewWindow::getCycleFrameCopy(int frameIndex) {
-	if (!_cycleEnabled)
+	if (!isCyclingEnabled())
 		return 0;
 
 	return _cycleFrames->getFrameCopy(frameIndex);
 }
 
 const Graphics::Surface *SceneViewWindow::getCycleFrame(int frameIndex) {
-	if (!_cycleEnabled)
+	if (!isCyclingEnabled())
 		return 0;
 
 	return _cycleFrames->getFrame(frameIndex);
 }
 
 bool SceneViewWindow::enableCycleFrameCache(bool enable) {
-	if (!_cycleEnabled)
+	if (!isCyclingEnabled())
 		return false;
 
 	_cycleFrames->enableFrameCache(enable);
@@ -1369,20 +1371,34 @@ bool SceneViewWindow::enableCycleFrameCache(bool enable) {
 }
 
 bool SceneViewWindow::flushCycleFrameCache() {
-	if (!_cycleEnabled)
+	if (!isCyclingEnabled())
 		return false;
 
 	return _cycleFrames->flushFrameCache();
 }
 
 bool SceneViewWindow::enableCycling(bool enable) {
-	// Do nothing if nothing changed
-	if (_cycleEnabled == enable)
-		return true;
-
+	bool oldStatus = isCyclingEnabled();
 	_cycleEnabled = enable;
 
-	if (enable) {
+	if (oldStatus != isCyclingEnabled())
+		handleCyclingChange();
+
+	return true;
+}
+
+bool SceneViewWindow::forceEnableCycling(bool enable) {
+	bool oldStatus = isCyclingEnabled();
+	_forceCycleEnabled = enable;
+
+	if (oldStatus != isCyclingEnabled())
+		handleCyclingChange();
+
+	return true;
+}
+
+void SceneViewWindow::handleCyclingChange() {
+	if (isCyclingEnabled()) {
 		// Re-enabling -> set up the cycle movie again
 		if (_currentScene) {
 			const LocationStaticData &staticData = _currentScene->_staticData;
@@ -1391,11 +1407,9 @@ bool SceneViewWindow::enableCycling(bool enable) {
 		}
 	} else {
 		// Disabling -> close the cycle movie
-		flushCycleFrameCache();
+		_cycleFrames->flushFrameCache();
 		_cycleFrames->close();
 	}
-
-	return true;
 }
 
 bool SceneViewWindow::closeCycleFrameMovie() {
diff --git a/engines/buried/scene_view.h b/engines/buried/scene_view.h
index c577743761..7210ae548d 100644
--- a/engines/buried/scene_view.h
+++ b/engines/buried/scene_view.h
@@ -86,7 +86,9 @@ public:
 	bool enableCycleFrameCache(bool enable);
 	bool flushCycleFrameCache();
 	bool enableCycling(bool enable);
-	bool getCyclingStatus() { return _cycleEnabled; }
+	bool forceEnableCycling(bool enable);
+	bool getCyclingStatus() const { return _cycleEnabled; }
+	bool isCyclingEnabled() const { return _cycleEnabled || _forceCycleEnabled; }
 	bool closeCycleFrameMovie();
 
 	int getGlobalFlag(int offset);
@@ -174,7 +176,7 @@ private:
 	int _currentAmbient;
 	bool _useScenePaint;
 	bool _useSprite;
-	bool _cycleEnabled;
+	bool _cycleEnabled, _forceCycleEnabled;
 	uint _timer;
 
 	bool _infoWindowDisplayed;
@@ -194,6 +196,8 @@ private:
 	int _demoSoundEffectHandle;
 	void startDemoAmbientSound();
 
+	void handleCyclingChange();
+
 	bool initializeTimeZoneAndEnvironment(Window *viewWindow, int timeZone, int environment);
 	SceneBase *constructSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 


Commit: 564598c0f5ee4a1a3770ac5c6a4bc24358400e28
    https://github.com/scummvm/scummvm/commit/564598c0f5ee4a1a3770ac5c6a4bc24358400e28
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Force frame cycling to be enabled for the two knight scenes as well

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index ab854530ec..de3bac1ef5 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -83,6 +83,8 @@ int TopOfTowerGuardEncounter::paint(Window *viewWindow, Graphics::Surface *preBu
 class TowerStairsGuardEncounter : public SceneBase {
 public:
 	TowerStairsGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &newLocation);
 	int timerCallback(Window *viewWindow);
 
 private:
@@ -116,6 +118,23 @@ int TowerStairsGuardEncounter::timerCallback(Window *viewWindow) {
 	return SC_TRUE;
 }
 
+int TowerStairsGuardEncounter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Force enable frame cycling
+	((SceneViewWindow *)viewWindow)->forceEnableCycling(true);
+
+	// Disable frame caching
+	((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
+
+	// Force open the video
+	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
+	return SC_TRUE;
+}
+
+int TowerStairsGuardEncounter::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	((SceneViewWindow *)viewWindow)->forceEnableCycling(false);
+	return SC_TRUE;
+}
+
 class WallSlideDeath : public SceneBase {
 public:
 	WallSlideDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
@@ -313,6 +332,7 @@ int KeepFinalWallClimb::timerCallback(Window *viewWindow) {
 class KingsStudyGuard : public SceneBase {
 public:
 	KingsStudyGuard(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &priorLocation);
 	int postExitRoom(Window *viewWindow, const Location &priorLocation);
 	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
 	int timerCallback(Window *viewWindow);
@@ -322,6 +342,11 @@ KingsStudyGuard::KingsStudyGuard(BuriedEngine *vm, Window *viewWindow, const Loc
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
 }
 
+int KingsStudyGuard::preExitRoom(Window *viewWindow, const Location &newLocation) {
+	((SceneViewWindow *)viewWindow)->forceEnableCycling(false);
+	return SC_TRUE;
+}
+
 int KingsStudyGuard::postExitRoom(Window *viewWindow, const Location &newLocation) {
 	if (_staticData.location.timeZone == newLocation.timeZone)
 		_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14));
@@ -329,6 +354,15 @@ int KingsStudyGuard::postExitRoom(Window *viewWindow, const Location &newLocatio
 }
 
 int KingsStudyGuard::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
+	// Force enable frame cycling
+	((SceneViewWindow *)viewWindow)->forceEnableCycling(true);
+
+	// Disable frame caching
+	((SceneViewWindow *)viewWindow)->enableCycleFrameCache(false);
+
+	// Force open the video
+	((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
+
 	// Display warning
 	((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_HUMAN_PRESENCE_3METERS));
 	return SC_TRUE;


Commit: 936cdc998a5eba18e6ead89fb16097e84d78f5c2
    https://github.com/scummvm/scummvm/commit/936cdc998a5eba18e6ead89fb16097e84d78f5c2
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add the path required by the Trilogy release

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 08fc76f319..0ec27fba7d 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -62,7 +62,8 @@ BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc)
 	_yielding = false;
 
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
-	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2);
+	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2); // v1.05 era
+	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN95/MANUAL", 0, 2); // v1.10 era (Trilogy release)
 }
 
 BuriedEngine::~BuriedEngine() {


Commit: 615247b5f849673e99a29b648c5ce9e2818b1672
    https://github.com/scummvm/scummvm/commit/615247b5f849673e99a29b648c5ce9e2818b1672
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Add support for the Spanish version

Some inventory text is incorrectly wrapped still, however

Changed paths:
    engines/buried/biochip_view.cpp
    engines/buried/detection.cpp
    engines/buried/environ/mayan.cpp


diff --git a/engines/buried/biochip_view.cpp b/engines/buried/biochip_view.cpp
index 8fd3e13a0b..58022cd519 100644
--- a/engines/buried/biochip_view.cpp
+++ b/engines/buried/biochip_view.cpp
@@ -529,7 +529,9 @@ InterfaceBioChipViewWindow::InterfaceBioChipViewWindow(BuriedEngine *vm, Window
 	_restore = Common::Rect(313, 37, 421, 74);
 	_quit = Common::Rect(313, 84, 421, 121);
 	_flicker = Common::Rect(14, 146, 164, 166);
-	_transitionSpeed = _vm->isDemo() ? Common::Rect(14, 117, 179, 140) : Common::Rect(14, 100, 125, 140);
+
+	// For whatever reason, the Spanish version uses the demo coordinates.
+	_transitionSpeed = (_vm->getLanguage() == Common::ES_ESP || _vm->isDemo()) ? Common::Rect(14, 117, 179, 140) : Common::Rect(14, 100, 125, 140);
 
 	_curRegion = REGION_NONE;
 	_soundLocation = 0;
@@ -561,10 +563,13 @@ void InterfaceBioChipViewWindow::onPaint() {
 		_vm->_gfx->blit(_cycleCheck, absoluteRect.left + 13, absoluteRect.top + 144);
 
 	if (_caret) {
-		if (_vm->isDemo())
+		if (_vm->isDemo()) {
 			_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 12, absoluteRect.top + 112, 20, 35, _caret, 0, 0, 0, 255, 255, 255);
-		else
-			_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 14, absoluteRect.top + 97, 15, 30, _caret, 0, 0, 0, 248, _vm->isTrueColor() ? 252 : 248, 248);
+		} else {
+			// For whatever reason, the Spanish version has to be different.
+			int dy = (_vm->getLanguage() == Common::ES_ESP) ? 115 : 97;
+			_vm->_gfx->opaqueTransparentBlit(_vm->_gfx->getScreen(), absoluteRect.left + _transLocation + 14, absoluteRect.top + dy, 15, 30, _caret, 0, 0, 0, 248, _vm->isTrueColor() ? 252 : 248, 248);
+		}
 	}
 }
 
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 043f4c75f3..418e509d8a 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -322,6 +322,44 @@ static const BuriedGameDescription gameDescriptions[] = {
 		},
 	},
 
+	// Spanish Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "f08c96347fcb83d92ae57de1fb578234", 1174528 },
+				{ "BIT8LIB.DLL", 0, "a80afdc20264e764e831ef5099cde623", 2420992 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::ES_ESP,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Spanish Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "d409b59f124babc9b423793e762b7e03", 1168896 },
+				{ "BIT24LIB.DLL", 0, "c864bcd69d05532e0066b8db173a939b", 6582784 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::ES_ESP,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
 	// English Windows 95 8BPP
 	// v1.1
 	{
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 04c9f05b9c..4be3cefba5 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -1970,10 +1970,12 @@ int DeathGodPuzzleBox::specifyCursor(Window *viewWindow, const Common::Point &po
 bool DeathGodPuzzleBox::isPuzzleSolved() const {
 	// TODO: Ask players for solutions for other languages
 	// clone2727 has the English, French, and Japanese source.
-	// clone2727 has the Italian version and solved the puzzle manually.
+	// clone2727 has the Italian and Spanish versions and solved the puzzle
+	// manually for those.
 
 	switch (_vm->getLanguage()) {
 	case Common::DE_DEU:
+	case Common::ES_ESP:
 	case Common::IT_ITA:
 		return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 24;
 	case Common::EN_ANY:


Commit: 45ff8fb04eaadee56f65fdbba5803c4f4239bd3f
    https://github.com/scummvm/scummvm/commit/45ff8fb04eaadee56f65fdbba5803c4f4239bd3f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Moved detection table to a separate file

Changed paths:
  A engines/buried/detection_tables.h
    engines/buried/detection.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 418e509d8a..61bb89715f 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -90,377 +90,10 @@ static const PlainGameDescriptor buriedGames[] = {
 	{0, 0}
 };
 
+#include "buried/detection_tables.h"
 
 namespace Buried {
 
-static const BuriedGameDescription gameDescriptions[] = {
-	// English Windows 3.11 8BPP
-	// Installed
-	// v1.01
-	{
-		{
-			"buried",
-			"v1.01 8BPP",
-			{
-				{ "BIT816.EXE",  0, "57a14461c77d9c77534bd418043db1ec", 1163776 },
-				{ "BIT8LIB.DLL", 0, "31bcd9e5cc32df00b09ce626e6d9106e", 2420480 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
-	},
-
-	// English Windows 3.11 24BPP
-	// Installed
-	// v1.01
-	{
-		{
-			"buried",
-			"v1.01 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "dcbfb3f2916ad902043942fc00d2017f", 1159680 },
-				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// Japanese Windows 3.11 8BPP
-	// Installed
-	// v1.051
-	{
-		{
-			"buried",
-			"v1.051 8BPP",
-			{
-				{ "BIT816.EXE",  0, "decbf9a7d91803525137ffd980d16708", 1163264 },
-				{ "BIT8LIB.DLL", 0, "f5ccde0efccb95afe902627a35262568", 2418816 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::JA_JPN,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
-	},
-
-	// Japanese Windows 3.11 24BPP
-	// Installed
-	// v1.051
-	{
-		{
-			"buried",
-			"v1.051 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "9435b9a40e3ac83e6fa1e83caaf57792", 1157632 },
-				{ "BIT24LIB.DLL", 0, "4d55802259d9648b9aa396461bfd53a3", 6576896 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::JA_JPN,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// English Windows 3.11 8BPP
-	// Not Installed
-	// v1.01
-	{
-		{
-			"buried",
-			"v1.01 8BPP",
-			{
-				{ "BIT816.EX_",  0, "166b44e53350c19bb25ef93d2c2b8f79", 364490 },
-				{ "BIT8LIB.DL_", 0, "8a345993f60f6bed7c17fa9e7f2bc37d", 908854 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_COMPRESSED,
-			GUIO0()
-		},
-	},
-
-	// English Windows 3.11 24BPP
-	// Not Installed
-	// v1.01
-	{
-		{
-			"buried",
-			"v1.01 24BPP",
-			{
-				{ "BIT2416.EX_",  0, "a9ac76610ba614b59235a7d5e00e4a62", 361816 },
-				{ "BIT24LIB.DL_", 0, "00e6eedbcef824988fbb01a87ca8f7fd", 2269314 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_COMPRESSED | GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// German Windows 3.11 8BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "a039e9f1c569acc1cf80f6b549ce1e37", 1178112 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::DE_DEU,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
-	},
-
-	// German Windows 3.11 24BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "fbfd453cced2b14069fa32e3c8dd69e2", 1172480 },
-				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::DE_DEU,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// French Windows 3.11 8BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "edea5331dc7cb0f3da7322691e12a18a", 1182720 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::FR_FRA,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
-	},
-
-	// French Windows 3.11 24BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "0adea8e1ad6fddad3b861be8a7bab340", 1177088 },
-				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::FR_FRA,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// Italian Windows 3.11 8BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "fb3e5c9198503bbb45b79150b511af5e", 1175040 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::IT_ITA,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
-	},
-
-	// Italian Windows 3.11 24BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "56bdd481b063c91b95c21f02faa450bb", 1169408 },
-				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::IT_ITA,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// Spanish Windows 3.11 8BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "f08c96347fcb83d92ae57de1fb578234", 1174528 },
-				{ "BIT8LIB.DLL", 0, "a80afdc20264e764e831ef5099cde623", 2420992 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::ES_ESP,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
-	},
-
-	// Spanish Windows 3.11 24BPP
-	// Installed
-	// v1.05
-	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "d409b59f124babc9b423793e762b7e03", 1168896 },
-				{ "BIT24LIB.DLL", 0, "c864bcd69d05532e0066b8db173a939b", 6582784 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::ES_ESP,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
-	},
-
-	// English Windows 95 8BPP
-	// v1.1
-	{
-		{
-			"buried",
-			"v1.1 8BPP",
-			{
-				{ "BIT832.EXE",  0, "f4f8007f49197ba40ea633eb113c0b6d", 1262592 },
-				{ "BIT8L32.DLL", 0, "addfef0420e1f41a7766ecc6baa58553", 2424832 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_WIN95,
-			GUIO0()
-		},
-	},
-
-	// English Windows 95 24BPP
-	// v1.1
-	{
-		{
-			"buried",
-			"v1.1 24BPP",
-			{
-				{ "BIT2432.EXE",  0, "4086a8200938eac3e72d238a84f65618", 1257472 },
-				{ "BIT24L32.DLL", 0, "198bfd476d5228c4a7a63c029cffadfc", 5216256 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR | GF_WIN95,
-			GUIO0()
-		},
-	},
-
-	// English Windows Demo 8BPP
-	{
-		{
-			"buried",
-			"Demo 8BPP",
-			AD_ENTRY1("BIT816.EXE", "a5bca831dac0903a304c29c320f881c5"),
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO,
-			GUIO1(GUIO_NOLAUNCHLOAD)
-		},
-	},
-
-	// English Windows Demo 24BPP
-	{
-		{
-			"buried",
-			"Demo 24BPP",
-			AD_ENTRY1("BIT2416.EXE", "9857e2d2b7a63b1304058dabc5098249"),
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO | GF_TRUECOLOR,
-			GUIO1(GUIO_NOLAUNCHLOAD)
-		},
-	},
-
-	// English Windows 3.11 Trial 8BPP
-	// v1.1
-	{
-		{
-			"buried",
-			"Trial 8BPP",
-			{
-				{ "BTV816.EXE",  0, "a3551483329816d8ddc8fa877113762c", 1170432 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO | GF_TRIAL,
-			GUIO0()
-		},
-	},
-
-	// English Windows 3.11 Trial 24BPP
-	// v1.1
-	{
-		{
-			"buried",
-			"Trial 24BPP",
-			{
-				{ "BTV2416.EXE",  0, "e0783c5eda09176d414d3df4ada8fe89", 1164288 },
-				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO | GF_TRUECOLOR | GF_TRIAL,
-			GUIO0()
-		},
-	},
-
-	{ AD_TABLE_END_MARKER }
-};
-
 static const char *directoryGlobs[] = {
 	"win31",
 	"manual",
@@ -540,4 +173,3 @@ bool BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGa
 #else
 	REGISTER_PLUGIN_STATIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
 #endif
-
diff --git a/engines/buried/detection_tables.h b/engines/buried/detection_tables.h
new file mode 100644
index 0000000000..7a1fcb3350
--- /dev/null
+++ b/engines/buried/detection_tables.h
@@ -0,0 +1,393 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+namespace Buried {
+
+static const BuriedGameDescription gameDescriptions[] = {
+	// English Windows 3.11 8BPP
+	// Installed
+	// v1.01
+	{
+		{
+			"buried",
+			"v1.01 8BPP",
+			{
+				{ "BIT816.EXE",  0, "57a14461c77d9c77534bd418043db1ec", 1163776 },
+				{ "BIT8LIB.DLL", 0, "31bcd9e5cc32df00b09ce626e6d9106e", 2420480 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// English Windows 3.11 24BPP
+	// Installed
+	// v1.01
+	{
+		{
+			"buried",
+			"v1.01 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "dcbfb3f2916ad902043942fc00d2017f", 1159680 },
+				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// Japanese Windows 3.11 8BPP
+	// Installed
+	// v1.051
+	{
+		{
+			"buried",
+			"v1.051 8BPP",
+			{
+				{ "BIT816.EXE",  0, "decbf9a7d91803525137ffd980d16708", 1163264 },
+				{ "BIT8LIB.DLL", 0, "f5ccde0efccb95afe902627a35262568", 2418816 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::JA_JPN,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Japanese Windows 3.11 24BPP
+	// Installed
+	// v1.051
+	{
+		{
+			"buried",
+			"v1.051 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "9435b9a40e3ac83e6fa1e83caaf57792", 1157632 },
+				{ "BIT24LIB.DLL", 0, "4d55802259d9648b9aa396461bfd53a3", 6576896 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::JA_JPN,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// English Windows 3.11 8BPP
+	// Not Installed
+	// v1.01
+	{
+		{
+			"buried",
+			"v1.01 8BPP",
+			{
+				{ "BIT816.EX_",  0, "166b44e53350c19bb25ef93d2c2b8f79", 364490 },
+				{ "BIT8LIB.DL_", 0, "8a345993f60f6bed7c17fa9e7f2bc37d", 908854 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_COMPRESSED,
+			GUIO0()
+		},
+	},
+
+	// English Windows 3.11 24BPP
+	// Not Installed
+	// v1.01
+	{
+		{
+			"buried",
+			"v1.01 24BPP",
+			{
+				{ "BIT2416.EX_",  0, "a9ac76610ba614b59235a7d5e00e4a62", 361816 },
+				{ "BIT24LIB.DL_", 0, "00e6eedbcef824988fbb01a87ca8f7fd", 2269314 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_COMPRESSED | GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// German Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "a039e9f1c569acc1cf80f6b549ce1e37", 1178112 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::DE_DEU,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// German Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "fbfd453cced2b14069fa32e3c8dd69e2", 1172480 },
+				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::DE_DEU,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// French Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "edea5331dc7cb0f3da7322691e12a18a", 1182720 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::FR_FRA,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// French Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "0adea8e1ad6fddad3b861be8a7bab340", 1177088 },
+				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::FR_FRA,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// Italian Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "fb3e5c9198503bbb45b79150b511af5e", 1175040 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::IT_ITA,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Italian Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "56bdd481b063c91b95c21f02faa450bb", 1169408 },
+				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::IT_ITA,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// Spanish Windows 3.11 8BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 8BPP",
+			{
+				{ "BIT816.EXE",  0, "f08c96347fcb83d92ae57de1fb578234", 1174528 },
+				{ "BIT8LIB.DLL", 0, "a80afdc20264e764e831ef5099cde623", 2420992 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::ES_ESP,
+			Common::kPlatformWindows,
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+	},
+
+	// Spanish Windows 3.11 24BPP
+	// Installed
+	// v1.05
+	{
+		{
+			"buried",
+			"v1.05 24BPP",
+			{
+				{ "BIT2416.EXE",  0, "d409b59f124babc9b423793e762b7e03", 1168896 },
+				{ "BIT24LIB.DLL", 0, "c864bcd69d05532e0066b8db173a939b", 6582784 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::ES_ESP,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR,
+			GUIO0()
+		},
+	},
+
+	// English Windows 95 8BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"v1.1 8BPP",
+			{
+				{ "BIT832.EXE",  0, "f4f8007f49197ba40ea633eb113c0b6d", 1262592 },
+				{ "BIT8L32.DLL", 0, "addfef0420e1f41a7766ecc6baa58553", 2424832 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_WIN95,
+			GUIO0()
+		},
+	},
+
+	// English Windows 95 24BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"v1.1 24BPP",
+			{
+				{ "BIT2432.EXE",  0, "4086a8200938eac3e72d238a84f65618", 1257472 },
+				{ "BIT24L32.DLL", 0, "198bfd476d5228c4a7a63c029cffadfc", 5216256 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			GF_TRUECOLOR | GF_WIN95,
+			GUIO0()
+		},
+	},
+
+	// English Windows Demo 8BPP
+	{
+		{
+			"buried",
+			"Demo 8BPP",
+			AD_ENTRY1("BIT816.EXE", "a5bca831dac0903a304c29c320f881c5"),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_DEMO,
+			GUIO1(GUIO_NOLAUNCHLOAD)
+		},
+	},
+
+	// English Windows Demo 24BPP
+	{
+		{
+			"buried",
+			"Demo 24BPP",
+			AD_ENTRY1("BIT2416.EXE", "9857e2d2b7a63b1304058dabc5098249"),
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_DEMO | GF_TRUECOLOR,
+			GUIO1(GUIO_NOLAUNCHLOAD)
+		},
+	},
+
+	// English Windows 3.11 Trial 8BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"Trial 8BPP",
+			{
+				{ "BTV816.EXE",  0, "a3551483329816d8ddc8fa877113762c", 1170432 },
+				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_DEMO | GF_TRIAL,
+			GUIO0()
+		},
+	},
+
+	// English Windows 3.11 Trial 24BPP
+	// v1.1
+	{
+		{
+			"buried",
+			"Trial 24BPP",
+			{
+				{ "BTV2416.EXE",  0, "e0783c5eda09176d414d3df4ada8fe89", 1164288 },
+				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
+				{ 0, 0, 0, 0 },
+			},
+			Common::EN_ANY,
+			Common::kPlatformWindows,
+			ADGF_DEMO | GF_TRUECOLOR | GF_TRIAL,
+			GUIO0()
+		},
+	},
+
+	{ AD_TABLE_END_MARKER }
+};
+
+} // End of namespace Buried


Commit: b44bc8fdb446271ae144d60657136d210b1a69e5
    https://github.com/scummvm/scummvm/commit/b44bc8fdb446271ae144d60657136d210b1a69e5
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fixes gor modern API

Changed paths:
    engines/buried/buried.cpp
    engines/buried/database.cpp
    engines/buried/database.h


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 0ec27fba7d..f79b410c62 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -91,13 +91,13 @@ Common::Error BuriedEngine::run() {
 		// Can't play 24bpp version without support
 		return Common::kUnsupportedColorMode;
 #else
-		initGraphics(640, 480, true, 0);
+		initGraphics(640, 480, 0);
 
 		if (_system->getScreenFormat().bytesPerPixel == 1)
 			return Common::kUnsupportedColorMode;
 #endif
 	} else {
-		initGraphics(640, 480, true);
+		initGraphics(640, 480);
 	}
 
 	if (isWin95()) {
@@ -465,7 +465,7 @@ uint32 BuriedEngine::computeNavDBResourceID(int timeZone, int environment) {
 }
 
 uint32 BuriedEngine::computeAnimDBResourceID(int timeZone, int environment) {
-	return RESID_ANIMDB_BASE + RESOFFSET_ANIMDB_TIMEZONE * timeZone + environment; 
+	return RESID_ANIMDB_BASE + RESOFFSET_ANIMDB_TIMEZONE * timeZone + environment;
 }
 
 uint32 BuriedEngine::computeAIDBResourceID(int timeZone, int environment) {
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index e6a1f9b57c..26078e1e9a 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "common/winexe.h"
 #include "common/winexe_ne.h"
 #include "common/winexe_pe.h"
 #include "graphics/wincursor.h"
@@ -77,7 +78,7 @@ Common::String DatabaseNE::loadString(uint32 stringID) {
 }
 
 Common::SeekableReadStream *DatabaseNE::getBitmapStream(uint32 bitmapID) {
-	return _exe->getResource(Common::kNEBitmap, bitmapID);
+	return _exe->getResource(Common::kWinBitmap, bitmapID);
 }
 
 Graphics::WinCursorGroup *DatabaseNE::getCursorGroup(uint32 cursorGroupID) {
@@ -142,7 +143,7 @@ Common::String DatabasePE::loadString(uint32 stringID) {
 }
 
 Common::SeekableReadStream *DatabasePE::getBitmapStream(uint32 bitmapID) {
-	return _exe->getResource(Common::kPEBitmap, bitmapID);
+	return _exe->getResource(Common::kWinBitmap, bitmapID);
 }
 
 Graphics::WinCursorGroup *DatabasePE::getCursorGroup(uint32 cursorGroupID) {
diff --git a/engines/buried/database.h b/engines/buried/database.h
index 355253177c..0559e3339e 100644
--- a/engines/buried/database.h
+++ b/engines/buried/database.h
@@ -24,13 +24,12 @@
 #define BURIED_DATABASE_H
 
 namespace Common {
-class NEResources;
-class PEResources;
+class WinResources;
 class String;
 }
 
 namespace Graphics {
-class WinCursorGroup;
+struct WinCursorGroup;
 }
 
 namespace Buried {
@@ -72,7 +71,7 @@ public:
 	uint32 getVersion();
 
 protected:
-	Common::NEResources *_exe;
+	Common::WinResources *_exe;
 };
 
 /**
@@ -98,7 +97,7 @@ public:
 	uint32 getVersion();
 
 private:
-	Common::PEResources *_exe;
+	Common::WinResources *_exe;
 };
 
 } // End of namespace Buried


Commit: 8e660ca581883b8ce12c6bcc9d673476fb535b81
    https://github.com/scummvm/scummvm/commit/8e660ca581883b8ce12c6bcc9d673476fb535b81
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: More API fixes

Changed paths:
    engines/buried/database.cpp


diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index 26078e1e9a..a6a153a3dc 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -82,7 +82,7 @@ Common::SeekableReadStream *DatabaseNE::getBitmapStream(uint32 bitmapID) {
 }
 
 Graphics::WinCursorGroup *DatabaseNE::getCursorGroup(uint32 cursorGroupID) {
-	return Graphics::WinCursorGroup::createCursorGroup(*_exe, cursorGroupID);
+	return Graphics::WinCursorGroup::createCursorGroup(_exe, cursorGroupID);
 }
 
 Common::SeekableReadStream *DatabaseNE::getResourceStream(const Common::String &resourceType, uint32 resourceID) {
@@ -147,7 +147,7 @@ Common::SeekableReadStream *DatabasePE::getBitmapStream(uint32 bitmapID) {
 }
 
 Graphics::WinCursorGroup *DatabasePE::getCursorGroup(uint32 cursorGroupID) {
-	return Graphics::WinCursorGroup::createCursorGroup(*_exe, cursorGroupID);
+	return Graphics::WinCursorGroup::createCursorGroup(_exe, cursorGroupID);
 }
 
 Common::SeekableReadStream *DatabasePE::getResourceStream(const Common::String &resourceType, uint32 resourceID) {


Commit: 3784b21a0caa7a329ff69862949f0876adcfaa26
    https://github.com/scummvm/scummvm/commit/3784b21a0caa7a329ff69862949f0876adcfaa26
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix warning

Changed paths:
    engines/buried/window.h


diff --git a/engines/buried/window.h b/engines/buried/window.h
index 18c077b995..7f6c781e05 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -33,7 +33,7 @@ struct KeyState;
 namespace Buried {
 
 class BuriedEngine;
-struct Message;
+class Message;
 
 class Window {
 public:


Commit: 88e5b10e3337adee3dbc6257ba80b96a3cd83103
    https://github.com/scummvm/scummvm/commit/88e5b10e3337adee3dbc6257ba80b96a3cd83103
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix overridden method

Changed paths:
    engines/buried/buried.h
    engines/buried/saveload.cpp


diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 4c1553032d..c7c52b0c20 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -133,7 +133,7 @@ public:
 	bool canLoadGameStateCurrently();
 	bool canSaveGameStateCurrently();
 	Common::Error loadGameState(int slot);
-	Common::Error saveGameState(int slot, const Common::String &desc);
+	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave);
 	static Common::StringArray listSaveFiles();
 	bool loadState(Common::SeekableReadStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems);
 	bool saveState(Common::WriteStream *saveFile, Location &location, GlobalFlags &flags, Common::Array<int> &inventoryItems);
diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index 04a1de4612..4eb7b13269 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -61,7 +61,7 @@ Common::Error BuriedEngine::loadGameState(int slot) {
 	Common::StringArray fileNames = listSaveFiles();
 	Common::InSaveFile *loadFile = _saveFileMan->openForLoading(fileNames[slot]);
 	if (!loadFile)
-		return Common::kUnknownError;	
+		return Common::kUnknownError;
 
 	Location location;
 	GlobalFlags flags;
@@ -103,7 +103,7 @@ static bool isValidSaveFileName(const Common::String &desc) {
 	return true;
 }
 
-Common::Error BuriedEngine::saveGameState(int slot, const Common::String &desc) {
+Common::Error BuriedEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
 	if (!isValidSaveFileName(desc))
 		return Common::Error(Common::kCreatingFileFailed, _("Invalid save file name"));
 
@@ -230,7 +230,7 @@ bool BuriedEngine::syncLocation(Common::Serializer &s, Location &location) {
 	s.syncAsSint16LE(location.orientation);
 	s.syncAsSint16LE(location.depth);
 	return s.bytesSynced() == 12;
-} 
+}
 
 bool BuriedEngine::syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags) {
 	uint32 startBytes = s.bytesSynced();


Commit: 7725f0ceed2e120a6a91694691c62be72a42ed13
    https://github.com/scummvm/scummvm/commit/7725f0ceed2e120a6a91694691c62be72a42ed13
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
COMMON: Make WinResource::getVersionInfo more universal

Changed paths:
    common/winexe.cpp
    common/winexe.h
    common/winexe_ne.cpp
    common/winexe_ne.h
    common/winexe_pe.cpp
    engines/buried/database.cpp
    engines/director/resource.cpp


diff --git a/common/winexe.cpp b/common/winexe.cpp
index d853df01cf..70de929245 100644
--- a/common/winexe.cpp
+++ b/common/winexe.cpp
@@ -184,8 +184,8 @@ WinResources *WinResources::createFromEXE(const String &fileName) {
 	return nullptr;
 }
 
-WinResources::VersionHash *WinResources::parseVersionInfo(SeekableReadStream *res) {
-	VersionHash *versionMap = new VersionHash;
+WinResources::VersionInfo *WinResources::parseVersionInfo(SeekableReadStream *res) {
+	VersionInfo *info = new VersionInfo;
 
 	while (res->pos() < res->size() && !res->eos()) {
 		while (res->pos() % 4 && !res->eos()) // Pad to 4
@@ -196,9 +196,9 @@ WinResources::VersionHash *WinResources::parseVersionInfo(SeekableReadStream *re
 		uint16 type = res->readUint16LE();
 		uint16 c;
 
-		Common::U32String info;
+		Common::U32String key;
 		while ((c = res->readUint16LE()) != 0 && !res->eos())
-			info += c;
+			key += c;
 
 		while (res->pos() % 4 && !res->eos()) // Pad to 4
 			res->readByte();
@@ -211,32 +211,51 @@ WinResources::VersionHash *WinResources::parseVersionInfo(SeekableReadStream *re
 			for (int j = 0; j < valLen; j++)
 				value += res->readUint16LE();
 
-			versionMap->setVal(info.encode(), value);
+			info->hash.setVal(key.encode(), value);
 		} else {
-			if (info == "VS_VERSION_INFO") {
-				uint16 pos2 = res->pos() + valLen;
-
-				res->readUint32LE();
-				res->readUint32LE();
-				uint16 fileB = res->readUint16LE();
-				uint16 fileA = res->readUint16LE();
-				uint16 fileD = res->readUint16LE();
-				uint16 fileC = res->readUint16LE();
-				uint16 prodB = res->readUint16LE();
-				uint16 prodA = res->readUint16LE();
-				uint16 prodD = res->readUint16LE();
-				uint16 prodC = res->readUint16LE();
-
-				versionMap->setVal("File:", Common::String::format("%d.%d.%d.%d", fileA, fileB, fileC, fileD));
-				versionMap->setVal("Prod:", Common::String::format("%d.%d.%d.%d", prodA, prodB, prodC, prodD));
-
-				while (res->pos() != pos2 && !res->eos())
-					res->readByte();
+			if (key == "VS_VERSION_INFO") {
+				// Signature check
+				if (res->readUint32LE() != 0xFEEF04BD)
+					return info;
+
+				res->readUint32LE(); // struct version
+
+				// The versions are stored a bit weird
+				info->fileVersion[1] = res->readUint16LE();
+				info->fileVersion[0] = res->readUint16LE();
+				info->fileVersion[3] = res->readUint16LE();
+				info->fileVersion[2] = res->readUint16LE();
+				info->productVersion[1] = res->readUint16LE();
+				info->productVersion[0] = res->readUint16LE();
+				info->productVersion[3] = res->readUint16LE();
+				info->productVersion[2] = res->readUint16LE();
+
+				info->fileFlagsMask = res->readUint32LE();
+				info->fileFlags = res->readUint32LE();
+				info->fileOS = res->readUint32LE();
+				info->fileType = res->readUint32LE();
+				info->fileSubtype = res->readUint32LE();
+				info->fileDate[0] = res->readUint32LE();
+				info->fileDate[1] = res->readUint32LE();
+
+				info->hash.setVal("File:", Common::String::format("%d.%d.%d.%d", info->fileVersion[0], info->fileVersion[1], info->fileVersion[2], info->fileVersion[3]));
+				info->hash.setVal("Prod:", Common::String::format("%d.%d.%d.%d", info->productVersion[0], info->productVersion[1], info->productVersion[2], info->productVersion[3]));
 			}
 		}
 	}
 
-	return versionMap;
+	return info;
+}
+
+WinResources::VersionInfo::VersionInfo() {
+	fileVersion[0] = fileVersion[1] = fileVersion[2] = fileVersion[3] = 0;
+	productVersion[0] = productVersion[1] = productVersion[2] = productVersion[3] = 0;
+	fileFlagsMask = 0;
+	fileFlags = 0;
+	fileOS = 0;
+	fileType = 0;
+	fileSubtype = 0;
+	fileDate[0] = fileDate[1] = 0;
 }
 
 } // End of namespace Common
diff --git a/common/winexe.h b/common/winexe.h
index b6c21cc543..c44a6b755e 100644
--- a/common/winexe.h
+++ b/common/winexe.h
@@ -142,7 +142,26 @@ public:
 
 	typedef Common::HashMap<Common::String, Common::U32String, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> VersionHash;
 
-	static VersionHash *parseVersionInfo(SeekableReadStream *stream);
+	/** The structure of the version resource inside an NE EXE */
+	struct VersionInfo {
+		VersionInfo();
+
+		uint16 fileVersion[4];
+		uint16 productVersion[4];
+		uint32 fileFlagsMask;
+		uint32 fileFlags;
+		uint32 fileOS;
+		uint32 fileType;
+		uint32 fileSubtype;
+		uint32 fileDate[2];
+
+		VersionHash hash;
+	};
+
+	static VersionInfo *parseVersionInfo(SeekableReadStream *stream);
+
+	/** Get a string from a string resource. */
+	virtual String loadString(uint32 stringID) = 0;
 };
 
 /** @} */
diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp
index 90dd090f81..b442b41960 100644
--- a/common/winexe_ne.cpp
+++ b/common/winexe_ne.cpp
@@ -64,82 +64,6 @@ bool NEResources::loadFromEXE(SeekableReadStream *stream) {
 	return true;
 }
 
-<<<<<<< HEAD
-=======
-bool NEResources::loadFromCompressedEXE(const String &fileName) {
-	// Based on http://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html
-
-	// TODO: Merge this with with loadFromEXE() so the handling of the compressed
-	// EXE's is transparent
-
-	File file;
-
-	if (!file.open(fileName))
-		return false;
-
-	// First part of the signature
-	if (file.readUint32BE() != MKTAG('S','Z','D','D'))
-		return false;
-
-	// Second part of the signature
-	if (file.readUint32BE() != 0x88F02733)
-		return false;
-
-	// Compression mode must be 'A'
-	if (file.readByte() != 'A')
-		return false;
-
-	file.readByte(); // file name character change
-	uint32 unpackedLength = file.readUint32LE();
-
-	byte *window = new byte[0x1000];
-	int pos = 0x1000 - 16;
-	memset(window, 0x20, 0x1000); // Initialize to all spaces
-
-	byte *unpackedData = (byte *)malloc(unpackedLength);
-	if (!unpackedData)
-		error("Failed to allocate uncompressed EXE");
-
-	byte *dataPos = unpackedData;
-	byte *endPos = unpackedData + unpackedLength;
-
-	// Apply simple LZSS decompression
-	while (dataPos < endPos) {
-		byte controlByte = file.readByte();
-
-		if (file.eos())
-			break;
-
-		for (byte i = 0; i < 8 && dataPos < endPos; i++) {
-			if (controlByte & (1 << i)) {
-				*dataPos++ = window[pos++] = file.readByte();
-				pos &= 0xFFF;
-			} else {
-				int matchPos = file.readByte();
-				int matchLen = file.readByte();
-				matchPos |= (matchLen & 0xF0) << 4;
-				matchLen = (matchLen & 0xF) + 3;
-
-				// Clip the length to the remaining size
-				matchLen = MIN<int>(matchLen, endPos - dataPos);
-
-				while (matchLen--) {
-					*dataPos++ = window[pos++] = window[matchPos++];
-					pos &= 0xFFF;
-					matchPos &= 0xFFF;
-				}
-			}
-
-		}
-	}
-
-	delete[] window;
-	SeekableReadStream *stream = new MemoryReadStream(unpackedData, unpackedLength, DisposeAfterUse::YES);
-
-	return loadFromEXE(stream);
-}
-
->>>>>>> 50fe418ac0 (COMMON: Fix out-of-bounds write in SZDD EXE decompression)
 uint32 NEResources::getResourceTableOffset() {
 	if (!_exe)
 		return 0xFFFFFFFF;
@@ -287,58 +211,10 @@ const Array<WinResourceID> NEResources::getIDList(const WinResourceID &type) con
 	return idArray;
 }
 
-NEResources::VersionInfo NEResources::getVersionInfo() {
-	VersionInfo info;
-	Common::ScopedPtr<Common::SeekableReadStream> stream(getResource(kNEVersion, 1));
-
-	if (!stream)
-		return info;
-
-	stream->readUint16LE(); // resource size
-
-	// Value size check
-	if (stream->readUint16LE() != 0x34)
-		return info;
-
-	char versionInfoString[16];
-	stream->read(versionInfoString, sizeof(versionInfoString));
-
-	if (memcmp(versionInfoString, "VS_VERSION_INFO", sizeof(versionInfoString) - 1) != 0)
-		return info;
-
-	// Signature check
-	if (stream->readUint32LE() != 0xFEEF04BD)
-		return info;
-
-	stream->readUint32LE(); // struct version
-
-	// The versions are stored a bit weird
-	info.fileVersion[1] = stream->readUint16LE();
-	info.fileVersion[0] = stream->readUint16LE();
-	info.fileVersion[3] = stream->readUint16LE();
-	info.fileVersion[2] = stream->readUint16LE();
-	info.productVersion[1] = stream->readUint16LE();
-	info.productVersion[0] = stream->readUint16LE();
-	info.productVersion[3] = stream->readUint16LE();
-	info.productVersion[2] = stream->readUint16LE();
-	
-	info.fileFlagsMask = stream->readUint32LE();
-	info.fileFlags = stream->readUint32LE();
-	info.fileOS = stream->readUint32LE();
-	info.fileType = stream->readUint32LE();
-	info.fileSubtype = stream->readUint32LE();
-	info.fileDate[0] = stream->readUint32LE();
-	info.fileDate[1] = stream->readUint32LE();
-
-	// TODO: Think about reading StringFileInfo and Translation parts
-
-	return info;
-}
-
 String NEResources::loadString(uint32 stringID) {
 	// This is how the resource ID is calculated
 	String string;
-	SeekableReadStream *stream = getResource(kNEString, (stringID >> 4) + 1);
+	SeekableReadStream *stream = getResource(kWinString, (stringID >> 4) + 1);
 
 	if (!stream)
 		return string;
@@ -357,19 +233,4 @@ String NEResources::loadString(uint32 stringID) {
 	return string;
 }
 
-NEResources::VersionInfo::VersionInfo() {
-	fileVersion[0] = fileVersion[1] = fileVersion[2] = fileVersion[3] = 0;
-	productVersion[0] = productVersion[1] = productVersion[2] = productVersion[3] = 0;
-	fileFlagsMask = 0;
-	fileFlags = 0;
-	fileOS = 0;
-	fileType = 0;
-	fileSubtype = 0;
-	fileDate[0] = fileDate[1] = 0;
-}
-
-bool NEResources::VersionInfo::isValid() const {
-	return fileOS != 0;
-}
-
 } // End of namespace Common
diff --git a/common/winexe_ne.h b/common/winexe_ne.h
index 169dced837..1dfb967816 100644
--- a/common/winexe_ne.h
+++ b/common/winexe_ne.h
@@ -67,26 +67,6 @@ public:
 	/** Return a stream to the specified resource (or 0 if non-existent). */
 	SeekableReadStream *getResource(const WinResourceID &type, const WinResourceID &id);
 
-	/** The structure of the version resource inside an NE EXE */
-	struct VersionInfo {
-		VersionInfo();
-
-		/** Is the version field valid? */
-		bool isValid() const;
-
-		uint16 fileVersion[4];
-		uint16 productVersion[4];
-		uint32 fileFlagsMask;
-		uint32 fileFlags;
-		uint32 fileOS;
-		uint32 fileType;
-		uint32 fileSubtype;
-		uint32 fileDate[2];		
-	};
-
-	/** Return the version of the EXE */
-	VersionInfo getVersionInfo();
-
 	/** Get a string from a string resource. */
 	String loadString(uint32 stringID);
 
diff --git a/common/winexe_pe.cpp b/common/winexe_pe.cpp
index 2d53ade23d..255aef25db 100644
--- a/common/winexe_pe.cpp
+++ b/common/winexe_pe.cpp
@@ -237,7 +237,7 @@ SeekableReadStream *PEResources::getResource(const WinResourceID &type, const Wi
 
 String PEResources::loadString(uint32 stringID) {
 	String string;
-	SeekableReadStream *stream = getResource(kPEString, (stringID >> 4) + 1);
+	SeekableReadStream *stream = getResource(kWinString, (stringID >> 4) + 1);
 
 	if (!stream)
 		return string;
diff --git a/engines/buried/database.cpp b/engines/buried/database.cpp
index a6a153a3dc..1fc3d7e918 100644
--- a/engines/buried/database.cpp
+++ b/engines/buried/database.cpp
@@ -23,6 +23,7 @@
  *
  */
 
+#include "common/stream.h"
 #include "common/winexe.h"
 #include "common/winexe_ne.h"
 #include "common/winexe_pe.h"
@@ -90,8 +91,14 @@ Common::SeekableReadStream *DatabaseNE::getResourceStream(const Common::String &
 }
 
 uint32 DatabaseNE::getVersion() {
-	Common::NEResources::VersionInfo versionInfo = _exe->getVersionInfo();
-	return MAKEVERSION(versionInfo.fileVersion[0], versionInfo.fileVersion[1], versionInfo.fileVersion[2], versionInfo.fileVersion[3]);
+	Common::SeekableReadStream *res = _exe->getResource(Common::kWinVersion, 1);
+	Common::WinResources::VersionInfo *versionInfo = _exe->parseVersionInfo(res);
+
+	uint32 result = MAKEVERSION(versionInfo->fileVersion[0], versionInfo->fileVersion[1], versionInfo->fileVersion[2], versionInfo->fileVersion[3]);
+	delete versionInfo;
+	delete res;
+
+	return result;
 }
 
 bool DatabaseNECompressed::load(const Common::String &fileName) {
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index a8f912de17..57972c0c31 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -199,12 +199,12 @@ void Window::loadEXE(const Common::String movie) {
 		for (uint i = 0; i < versions.size(); i++) {
 			Common::SeekableReadStream *res = exe->getResource(Common::kWinVersion, versions[i]);
 
-			Common::WinResources::VersionHash *versionMap = Common::WinResources::parseVersionInfo(res);
+			Common::WinResources::VersionInfo *info = Common::WinResources::parseVersionInfo(res);
 
-			for (Common::WinResources::VersionHash::const_iterator it = versionMap->begin(); it != versionMap->end(); ++it)
+			for (Common::WinResources::VersionHash::const_iterator it = info->hash.begin(); it != info->hash.end(); ++it)
 				warning("info <%s>: <%s>", it->_key.c_str(), it->_value.encode().c_str());
 
-			delete versionMap;
+			delete info;
 			delete res;
 
 		}


Commit: c529636463d442f2b60bd3f559b3c66af06e7215
    https://github.com/scummvm/scummvm/commit/c529636463d442f2b60bd3f559b3c66af06e7215
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Converted detection.cpp to the new plugin structure

Changed paths:
  A engines/buried/metaengine.cpp
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/detection.cpp
    engines/buried/detection_tables.h
    engines/buried/module.mk


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index f79b410c62..3130203a3e 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -48,7 +48,7 @@
 
 namespace Buried {
 
-BuriedEngine::BuriedEngine(OSystem *syst, const BuriedGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+BuriedEngine::BuriedEngine(OSystem *syst, const Common::ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
 	_gfx = 0;
 	_mainEXE = 0;
 	_library = 0;
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index c7c52b0c20..7cf5d68b08 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -34,6 +34,7 @@
 class OSystem;
 
 namespace Common {
+struct ADGameDescription;
 class SeekableReadStream;
 class Serializer;
 class WriteStream;
@@ -41,8 +42,14 @@ class WriteStream;
 
 namespace Buried {
 
+enum {
+	GF_TRUECOLOR  = (1 << 1),
+	GF_WIN95      = (1 << 2),
+	GF_COMPRESSED = (1 << 3),
+	GF_TRIAL      = (1 << 4)
+};
+
 class BuriedConsole;
-struct BuriedGameDescription;
 class Database;
 struct GlobalFlags;
 class GraphicsManager;
@@ -57,11 +64,11 @@ protected:
 	Common::Error run();
 
 public:
-	BuriedEngine(OSystem *syst, const BuriedGameDescription *gamedesc);
+	BuriedEngine(OSystem *syst, const Common::ADGameDescription *gamedesc);
 	virtual ~BuriedEngine();
 
 	// Detection related functions
-	const BuriedGameDescription *_gameDescription;
+	const Common::ADGameDescription *_gameDescription;
 	bool isDemo() const;
 	bool isTrial() const;
 	bool isTrueColor() const;
diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index 61bb89715f..bb5038b9f5 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -30,61 +30,6 @@
 
 #include "buried/buried.h"
 
-namespace Buried {
-
-struct BuriedGameDescription {
-	ADGameDescription desc;
-};
-
-enum {
-	GF_TRUECOLOR  = (1 << 1),
-	GF_WIN95      = (1 << 2),
-	GF_COMPRESSED = (1 << 3),
-	GF_TRIAL      = (1 << 4)
-};
-
-bool BuriedEngine::hasFeature(EngineFeature f) const {
-	return
-		(f == kSupportsRTL)
-		|| (f == kSupportsLoadingDuringRuntime)
-		|| (f == kSupportsSavingDuringRuntime);
-}
-
-bool BuriedEngine::isDemo() const {
-	// The trial is a demo for the user's sake, but not internally.
-	return (_gameDescription->desc.flags & ADGF_DEMO) != 0 && !isTrial();
-}
-
-bool BuriedEngine::isTrial() const {
-	return (_gameDescription->desc.flags & GF_TRIAL) != 0;
-}
-
-bool BuriedEngine::isTrueColor() const {
-	return (_gameDescription->desc.flags & GF_TRUECOLOR) != 0;
-}
-
-bool BuriedEngine::isWin95() const {
-	return (_gameDescription->desc.flags & GF_WIN95) != 0;
-}
-
-bool BuriedEngine::isCompressed() const {
-	return (_gameDescription->desc.flags & GF_COMPRESSED) != 0;
-}
-
-Common::String BuriedEngine::getEXEName() const {
-	return _gameDescription->desc.filesDescriptions[0].fileName;
-}
-
-Common::String BuriedEngine::getLibraryName() const {
-	return _gameDescription->desc.filesDescriptions[1].fileName;
-}
-
-Common::Language BuriedEngine::getLanguage() const {
-	return _gameDescription->desc.language;
-}
-
-} // End of namespace Buried
-
 static const PlainGameDescriptor buriedGames[] = {
 	{"buried", "The Journeyman Project 2: Buried in Time"},
 	{0, 0}
@@ -103,73 +48,25 @@ static const char *directoryGlobs[] = {
 } // End of namespace Buried
 
 
-class BuriedMetaEngine : public AdvancedMetaEngine {
+class BuriedMetaEngineDetection : public AdvancedMetaEngineDetection {
 public:
-	BuriedMetaEngine() : AdvancedMetaEngine(Buried::gameDescriptions, sizeof(Buried::BuriedGameDescription), buriedGames) {
-		_singleid = "buried";
+	BuriedMetaEngineDetection() : AdvancedMetaEngineDetection(Buried::gameDescriptions, sizeof(ADGameDescription), buriedGames) {
 		_flags = kADFlagUseExtraAsHint;
 		_maxScanDepth = 3;
 		_directoryGlobs = Buried::directoryGlobs;
 	}
 
-	virtual const char *getName() const {
+	const char *getEngineId() const override {
+		return "buried";
+	}
+
+	virtual const char *getName() const override {
 		return "The Journeyman Project 2: Buried in Time";
 	}
 
-	virtual const char *getOriginalCopyright() const {
+	virtual const char *getOriginalCopyright() const override {
 		return "The Journeyman Project 2: Buried in Time (C) Presto Studios";
 	}
-
-	virtual bool hasFeature(MetaEngineFeature f) const;
-	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-	virtual SaveStateList listSaves(const char *target) const;
-	virtual int getMaximumSaveSlot() const { return 999; }
-	virtual void removeSaveState(const char *target, int slot) const;
 };
 
-bool BuriedMetaEngine::hasFeature(MetaEngineFeature f) const {
-	return
-		(f == kSupportsListSaves)
-		|| (f == kSupportsLoadingDuringStartup)
-		|| (f == kSupportsDeleteSave);
-}
-
-SaveStateList BuriedMetaEngine::listSaves(const char *target) const {
-	// The original had no pattern, so the user must rename theirs
-	// Note that we ignore the target because saves are compatible between
-	// all versions
-	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
-
-	SaveStateList saveList;
-	for (uint32 i = 0; i < fileNames.size(); i++) {
-		// Isolate the description from the file name
-		Common::String desc = fileNames[i].c_str() + 7;
-		for (int j = 0; j < 4; j++)
-			desc.deleteLastChar();
-
-		saveList.push_back(SaveStateDescriptor(i, desc));
-	}
-
-	return saveList;
-}
-
-void BuriedMetaEngine::removeSaveState(const char *target, int slot) const {
-	// See listSaves() for info on the pattern
-	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
-	g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str());
-}
-
-bool BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
-	const Buried::BuriedGameDescription *gd = (const Buried::BuriedGameDescription *)desc;
-
-	if (gd)
-		*engine = new Buried::BuriedEngine(syst, gd);
-
-	return (gd != 0);
-}
-
-#if PLUGIN_ENABLED_DYNAMIC(BURIED)
-	REGISTER_PLUGIN_DYNAMIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
-#else
-	REGISTER_PLUGIN_STATIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
-#endif
+REGISTER_PLUGIN_STATIC(BURIED_DETEcTION, PLUGIN_TYPE_ENGINE_DETECTION, BuriedMetaEngineDetection);
diff --git a/engines/buried/detection_tables.h b/engines/buried/detection_tables.h
index 7a1fcb3350..032e713908 100644
--- a/engines/buried/detection_tables.h
+++ b/engines/buried/detection_tables.h
@@ -22,372 +22,278 @@
 
 namespace Buried {
 
-static const BuriedGameDescription gameDescriptions[] = {
+static const ADGameDescription gameDescriptions[] = {
 	// English Windows 3.11 8BPP
 	// Installed
 	// v1.01
 	{
-		{
-			"buried",
-			"v1.01 8BPP",
-			{
-				{ "BIT816.EXE",  0, "57a14461c77d9c77534bd418043db1ec", 1163776 },
-				{ "BIT8LIB.DLL", 0, "31bcd9e5cc32df00b09ce626e6d9106e", 2420480 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
+		"buried",
+		"v1.01 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "57a14461c77d9c77534bd418043db1ec", 1163776,
+				   "BIT8LIB.DLL","31bcd9e5cc32df00b09ce626e6d9106e", 2420480),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
 	},
 
 	// English Windows 3.11 24BPP
 	// Installed
 	// v1.01
 	{
-		{
-			"buried",
-			"v1.01 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "dcbfb3f2916ad902043942fc00d2017f", 1159680 },
-				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.01 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "dcbfb3f2916ad902043942fc00d2017f", 1159680,
+				   "BIT24LIB.DLL","74ac9dae92f415fea8cdbd220ba8795c", 5211648),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// Japanese Windows 3.11 8BPP
 	// Installed
 	// v1.051
 	{
-		{
-			"buried",
-			"v1.051 8BPP",
-			{
-				{ "BIT816.EXE",  0, "decbf9a7d91803525137ffd980d16708", 1163264 },
-				{ "BIT8LIB.DLL", 0, "f5ccde0efccb95afe902627a35262568", 2418816 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::JA_JPN,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
+		"buried",
+		"v1.051 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "decbf9a7d91803525137ffd980d16708", 1163264,
+				   "BIT8LIB.DLL","f5ccde0efccb95afe902627a35262568", 2418816),
+		Common::JA_JPN,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
 	},
 
 	// Japanese Windows 3.11 24BPP
 	// Installed
 	// v1.051
 	{
-		{
-			"buried",
-			"v1.051 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "9435b9a40e3ac83e6fa1e83caaf57792", 1157632 },
-				{ "BIT24LIB.DLL", 0, "4d55802259d9648b9aa396461bfd53a3", 6576896 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::JA_JPN,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.051 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "9435b9a40e3ac83e6fa1e83caaf57792", 1157632,
+				   "BIT24LIB.DLL","4d55802259d9648b9aa396461bfd53a3", 6576896),
+		Common::JA_JPN,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// English Windows 3.11 8BPP
 	// Not Installed
 	// v1.01
 	{
-		{
-			"buried",
-			"v1.01 8BPP",
-			{
-				{ "BIT816.EX_",  0, "166b44e53350c19bb25ef93d2c2b8f79", 364490 },
-				{ "BIT8LIB.DL_", 0, "8a345993f60f6bed7c17fa9e7f2bc37d", 908854 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_COMPRESSED,
-			GUIO0()
-		},
+		"buried",
+		"v1.01 8BPP",
+		AD_ENTRY2s("BIT816.EX_", "166b44e53350c19bb25ef93d2c2b8f79", 364490,
+				   "BIT8LIB.DL_","8a345993f60f6bed7c17fa9e7f2bc37d", 908854),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		GF_COMPRESSED,
+		GUIO0()
 	},
 
 	// English Windows 3.11 24BPP
 	// Not Installed
 	// v1.01
 	{
-		{
-			"buried",
-			"v1.01 24BPP",
-			{
-				{ "BIT2416.EX_",  0, "a9ac76610ba614b59235a7d5e00e4a62", 361816 },
-				{ "BIT24LIB.DL_", 0, "00e6eedbcef824988fbb01a87ca8f7fd", 2269314 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_COMPRESSED | GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.01 24BPP",
+		AD_ENTRY2s("BIT2416.EX_", "a9ac76610ba614b59235a7d5e00e4a62", 361816,
+				   "BIT24LIB.DL_","00e6eedbcef824988fbb01a87ca8f7fd", 2269314),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		GF_COMPRESSED | GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// German Windows 3.11 8BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "a039e9f1c569acc1cf80f6b549ce1e37", 1178112 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::DE_DEU,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "a039e9f1c569acc1cf80f6b549ce1e37", 1178112,
+				   "BIT8LIB.DLL","6b22f0b47efb29e45e9b2a336185d924", 2420608),
+		Common::DE_DEU,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
 	},
 
 	// German Windows 3.11 24BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "fbfd453cced2b14069fa32e3c8dd69e2", 1172480 },
-				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::DE_DEU,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "fbfd453cced2b14069fa32e3c8dd69e2", 1172480,
+				   "BIT24LIB.DLL","30e56210d3150b5fa41c9bd2c90754fe", 6581376),
+		Common::DE_DEU,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// French Windows 3.11 8BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "edea5331dc7cb0f3da7322691e12a18a", 1182720 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::FR_FRA,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "edea5331dc7cb0f3da7322691e12a18a", 1182720,
+				   "BIT8LIB.DLL","6b22f0b47efb29e45e9b2a336185d924", 2420608),
+		Common::FR_FRA,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
 	},
 
 	// French Windows 3.11 24BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "0adea8e1ad6fddad3b861be8a7bab340", 1177088 },
-				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::FR_FRA,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "0adea8e1ad6fddad3b861be8a7bab340", 1177088,
+				   "BIT24LIB.DLL","30e56210d3150b5fa41c9bd2c90754fe", 6581376),
+		Common::FR_FRA,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// Italian Windows 3.11 8BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "fb3e5c9198503bbb45b79150b511af5e", 1175040 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::IT_ITA,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "fb3e5c9198503bbb45b79150b511af5e", 1175040,
+				   "BIT8LIB.DLL","6b22f0b47efb29e45e9b2a336185d924", 2420608),
+		Common::IT_ITA,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
 	},
 
 	// Italian Windows 3.11 24BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "56bdd481b063c91b95c21f02faa450bb", 1169408 },
-				{ "BIT24LIB.DLL", 0, "30e56210d3150b5fa41c9bd2c90754fe", 6581376 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::IT_ITA,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "56bdd481b063c91b95c21f02faa450bb", 1169408,
+				   "BIT24LIB.DLL","30e56210d3150b5fa41c9bd2c90754fe", 6581376),
+		Common::IT_ITA,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// Spanish Windows 3.11 8BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 8BPP",
-			{
-				{ "BIT816.EXE",  0, "f08c96347fcb83d92ae57de1fb578234", 1174528 },
-				{ "BIT8LIB.DLL", 0, "a80afdc20264e764e831ef5099cde623", 2420992 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::ES_ESP,
-			Common::kPlatformWindows,
-			ADGF_NO_FLAGS,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "f08c96347fcb83d92ae57de1fb578234", 1174528,
+				   "BIT8LIB.DLL","a80afdc20264e764e831ef5099cde623", 2420992),
+		Common::ES_ESP,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
 	},
 
 	// Spanish Windows 3.11 24BPP
 	// Installed
 	// v1.05
 	{
-		{
-			"buried",
-			"v1.05 24BPP",
-			{
-				{ "BIT2416.EXE",  0, "d409b59f124babc9b423793e762b7e03", 1168896 },
-				{ "BIT24LIB.DLL", 0, "c864bcd69d05532e0066b8db173a939b", 6582784 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::ES_ESP,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR,
-			GUIO0()
-		},
+		"buried",
+		"v1.05 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "d409b59f124babc9b423793e762b7e03", 1168896,
+				   "BIT24LIB.DLL","c864bcd69d05532e0066b8db173a939b", 6582784),
+		Common::ES_ESP,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
 	},
 
 	// English Windows 95 8BPP
 	// v1.1
 	{
-		{
-			"buried",
-			"v1.1 8BPP",
-			{
-				{ "BIT832.EXE",  0, "f4f8007f49197ba40ea633eb113c0b6d", 1262592 },
-				{ "BIT8L32.DLL", 0, "addfef0420e1f41a7766ecc6baa58553", 2424832 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_WIN95,
-			GUIO0()
-		},
+		"buried",
+		"v1.1 8BPP",
+		AD_ENTRY2s("BIT832.EXE", "f4f8007f49197ba40ea633eb113c0b6d", 1262592,
+				   "BIT8L32.DLL","addfef0420e1f41a7766ecc6baa58553", 2424832),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		GF_WIN95,
+		GUIO0()
 	},
 
 	// English Windows 95 24BPP
 	// v1.1
 	{
-		{
-			"buried",
-			"v1.1 24BPP",
-			{
-				{ "BIT2432.EXE",  0, "4086a8200938eac3e72d238a84f65618", 1257472 },
-				{ "BIT24L32.DLL", 0, "198bfd476d5228c4a7a63c029cffadfc", 5216256 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			GF_TRUECOLOR | GF_WIN95,
-			GUIO0()
-		},
+		"buried",
+		"v1.1 24BPP",
+		AD_ENTRY2s("BIT2432.EXE", "4086a8200938eac3e72d238a84f65618", 1257472,
+				   "BIT24L32.DLL","198bfd476d5228c4a7a63c029cffadfc", 5216256),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR | GF_WIN95,
+		GUIO0()
 	},
 
 	// English Windows Demo 8BPP
 	{
-		{
-			"buried",
-			"Demo 8BPP",
-			AD_ENTRY1("BIT816.EXE", "a5bca831dac0903a304c29c320f881c5"),
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO,
-			GUIO1(GUIO_NOLAUNCHLOAD)
-		},
+		"buried",
+		"Demo 8BPP",
+		AD_ENTRY1("BIT816.EXE", "a5bca831dac0903a304c29c320f881c5"),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_DEMO,
+		GUIO1(GUIO_NOLAUNCHLOAD)
 	},
 
 	// English Windows Demo 24BPP
 	{
-		{
-			"buried",
-			"Demo 24BPP",
-			AD_ENTRY1("BIT2416.EXE", "9857e2d2b7a63b1304058dabc5098249"),
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO | GF_TRUECOLOR,
-			GUIO1(GUIO_NOLAUNCHLOAD)
-		},
+		"buried",
+		"Demo 24BPP",
+		AD_ENTRY1("BIT2416.EXE", "9857e2d2b7a63b1304058dabc5098249"),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_DEMO | GF_TRUECOLOR,
+		GUIO1(GUIO_NOLAUNCHLOAD)
 	},
 
 	// English Windows 3.11 Trial 8BPP
 	// v1.1
 	{
-		{
-			"buried",
-			"Trial 8BPP",
-			{
-				{ "BTV816.EXE",  0, "a3551483329816d8ddc8fa877113762c", 1170432 },
-				{ "BIT8LIB.DLL", 0, "6b22f0b47efb29e45e9b2a336185d924", 2420608 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO | GF_TRIAL,
-			GUIO0()
-		},
+		"buried",
+		"Trial 8BPP",
+		AD_ENTRY2s("BTV816.EXE", "a3551483329816d8ddc8fa877113762c", 1170432,
+				   "BIT8LIB.DLL","6b22f0b47efb29e45e9b2a336185d924", 2420608),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_DEMO | GF_TRIAL,
+		GUIO0()
 	},
 
 	// English Windows 3.11 Trial 24BPP
 	// v1.1
 	{
-		{
-			"buried",
-			"Trial 24BPP",
-			{
-				{ "BTV2416.EXE",  0, "e0783c5eda09176d414d3df4ada8fe89", 1164288 },
-				{ "BIT24LIB.DLL", 0, "74ac9dae92f415fea8cdbd220ba8795c", 5211648 },
-				{ 0, 0, 0, 0 },
-			},
-			Common::EN_ANY,
-			Common::kPlatformWindows,
-			ADGF_DEMO | GF_TRUECOLOR | GF_TRIAL,
-			GUIO0()
-		},
+		"buried",
+		"Trial 24BPP",
+		AD_ENTRY2s("BTV2416.EXE", "e0783c5eda09176d414d3df4ada8fe89", 1164288,
+				   "BIT24LIB.DLL","74ac9dae92f415fea8cdbd220ba8795c", 5211648),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_DEMO | GF_TRUECOLOR | GF_TRIAL,
+		GUIO0()
 	},
 
-	{ AD_TABLE_END_MARKER }
+	AD_TABLE_END_MARKER
 };
 
 } // End of namespace Buried
diff --git a/engines/buried/metaengine.cpp b/engines/buried/metaengine.cpp
new file mode 100644
index 0000000000..0b485eea8c
--- /dev/null
+++ b/engines/buried/metaengine.cpp
@@ -0,0 +1,132 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "base/plugins.h"
+
+#include "common/savefile.h"
+#include "common/system.h"
+
+#include "buried/buried.h"
+
+namespace Buried {
+
+bool BuriedEngine::hasFeature(EngineFeature f) const {
+	return
+		(f == kSupportsRTL)
+		|| (f == kSupportsLoadingDuringRuntime)
+		|| (f == kSupportsSavingDuringRuntime);
+}
+
+bool BuriedEngine::isDemo() const {
+	// The trial is a demo for the user's sake, but not internally.
+	return (_gameDescription->flags & ADGF_DEMO) != 0 && !isTrial();
+}
+
+bool BuriedEngine::isTrial() const {
+	return (_gameDescription->flags & GF_TRIAL) != 0;
+}
+
+bool BuriedEngine::isTrueColor() const {
+	return (_gameDescription->flags & GF_TRUECOLOR) != 0;
+}
+
+bool BuriedEngine::isWin95() const {
+	return (_gameDescription->flags & GF_WIN95) != 0;
+}
+
+bool BuriedEngine::isCompressed() const {
+	return (_gameDescription->flags & GF_COMPRESSED) != 0;
+}
+
+Common::String BuriedEngine::getEXEName() const {
+	return _gameDescription->filesDescriptions[0].fileName;
+}
+
+Common::String BuriedEngine::getLibraryName() const {
+	return _gameDescription->filesDescriptions[1].fileName;
+}
+
+Common::Language BuriedEngine::getLanguage() const {
+	return _gameDescription->language;
+}
+
+} // End of namespace Buried
+
+class BuriedMetaEngine : public AdvancedMetaEngine {
+public:
+	const char *getName() const {
+		return "buried";
+	}
+
+	virtual bool hasFeature(MetaEngineFeature f) const;
+	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual SaveStateList listSaves(const char *target) const;
+	virtual int getMaximumSaveSlot() const { return 999; }
+	virtual void removeSaveState(const char *target, int slot) const;
+};
+
+bool BuriedMetaEngine::hasFeature(MetaEngineFeature f) const {
+	return
+		(f == kSupportsListSaves)
+		|| (f == kSupportsLoadingDuringStartup)
+		|| (f == kSupportsDeleteSave);
+}
+
+SaveStateList BuriedMetaEngine::listSaves(const char *target) const {
+	// The original had no pattern, so the user must rename theirs
+	// Note that we ignore the target because saves are compatible between
+	// all versions
+	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
+
+	SaveStateList saveList;
+	for (uint32 i = 0; i < fileNames.size(); i++) {
+		// Isolate the description from the file name
+		Common::String desc = fileNames[i].c_str() + 7;
+		for (int j = 0; j < 4; j++)
+			desc.deleteLastChar();
+
+		saveList.push_back(SaveStateDescriptor(i, desc));
+	}
+
+	return saveList;
+}
+
+void BuriedMetaEngine::removeSaveState(const char *target, int slot) const {
+	// See listSaves() for info on the pattern
+	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
+	g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str());
+}
+
+bool BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	const Buried::BuriedGameDescription *gd = (const Buried::BuriedGameDescription *)desc;
+
+	if (gd)
+		*engine = new Buried::BuriedEngine(syst, gd);
+
+	return (gd != 0);
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(BURIED)
+	REGISTER_PLUGIN_DYNAMIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
+#else
+	REGISTER_PLUGIN_STATIC(BURIED, PLUGIN_TYPE_ENGINE, BuriedMetaEngine);
+#endif
diff --git a/engines/buried/module.mk b/engines/buried/module.mk
index c21123e2cb..e9ef3eda5b 100644
--- a/engines/buried/module.mk
+++ b/engines/buried/module.mk
@@ -10,7 +10,6 @@ MODULE_OBJS = \
 	credits.o \
 	database.o \
 	death.o \
-	detection.o \
 	frame_window.o \
 	gameui.o \
 	graphics.o \
@@ -18,6 +17,7 @@ MODULE_OBJS = \
 	inventory_window.o \
 	livetext.o \
 	main_menu.o \
+	metaengine.o \
 	navarrow.o \
 	overview.o \
 	saveload.o \
@@ -48,3 +48,6 @@ endif
 
 # Include common rules
 include $(srcdir)/rules.mk
+
+# Detection objects
+DETECT_OBJS += $(MODULE)/detection.o


Commit: 4ad07cd5f4b3aeab497de08281ece97279db6b22
    https://github.com/scummvm/scummvm/commit/4ad07cd5f4b3aeab497de08281ece97279db6b22
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Removed hacky loading of the system font and switch fallback to Liberation

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 0939b6a316..fbf78d7ae9 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -205,7 +205,7 @@ Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
 	static const uint32 *codePageMapping = s_codePage1252;
 #endif
 
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, codePageMapping);
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, codePageMapping);
 
 	if (!font)
 		error("Failed to load Arial%s font", bold ? " Bold" : "");
@@ -606,61 +606,14 @@ Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
 	if (stream)
 		return stream;
 
-	// HACK: Try to load the system font
-#if defined(WIN32)
-	Common::FSNode fontPath("C:/WINDOWS/Fonts/" + defaultBaseName);
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-
-	if (!stream) {
-		Common::FSNode win2kFontPath("C:/WINNT/Fonts/" + defaultBaseName);
-
-		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
-			stream = win2kFontPath.createReadStream();
-	}
-#elif defined(MACOSX)
-	// Attempt to load the font from the Arial.ttf font first
-	Common::String baseName = bold ? "Arial Bold" : "Arial";
-	Common::FSNode fontPath(Common::String::format("/Library/Fonts/%s.ttf", baseName.c_str()));
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-
-	if (!stream) {
-		// Try the suitcase on the system
-		Common::FSNode fontDirectory("/Library/Fonts");
-		Common::MacResManager resFork;
-
-		// DOUBLE HACK WARNING: Just assume it's 0x1000
-		// (it should always be this, the first font, but parsing the FOND would be better)
-		if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
-			stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), baseName);
-
-		// ...and one last try
-		if (!stream) {
-			Common::FSNode msFontDirectory("/Library/Fonts/Microsoft");
-			if (fontDirectory.exists() && fontDirectory.isDirectory() && resFork.open(fontPath, "Arial") && resFork.hasResFork())
-				stream = resFork.getResource(MKTAG('s', 'f', 'n', 't'), baseName);
-		}
-	}
-#elif defined(__linux__)
-	// TODO: Could also check for other fonts, other paths, etc.
-	Common::String baseName = bold ? "arialbd.ttf" : "arial.ttf";
-	Common::FSNode fontPath("/usr/share/fonts/truetype/msttcorefonts/" + baseName);
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-#endif
-
 	if (!stream) {
 		// TODO: It would really be nice to have "Liberation Sans", since it is metric
 		// compatible with Arial.
 
 		if (bold)
-			stream = getThemeFontStream("FreeSansBold.ttf");
+			stream = getThemeFontStream("LiberationSans-Bold.ttf");
 		else
-			stream = getThemeFontStream("FreeSans.ttf");
+			stream = getThemeFontStream("LiberationSans-Regular.ttf");
 	}
 
 	return stream;
@@ -710,7 +663,7 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 		error("Failed to find MS Gothic font");
 
 	switch (size) {
-	case 10:	
+	case 10:
 	case 11:
 		size = 8;
 		break;
@@ -727,7 +680,7 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 	// TODO: Fake a bold version
 
 	// Force monochrome, since the original uses the bitmap glyphs in the font
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, 96, Graphics::kTTFRenderModeMonochrome);
+	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, Graphics::kTTFRenderModeMonochrome);
 
 	if (!font)
 		error("Failed to load MS Gothic font");


Commit: 279acfd6bc0e4563a5b401bbce6a0c65d3f36bdd
    https://github.com/scummvm/scummvm/commit/279acfd6bc0e4563a5b401bbce6a0c65d3f36bdd
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Fix metaengine.cpp compilation

Changed paths:
    engines/buried/buried.cpp
    engines/buried/buried.h
    engines/buried/metaengine.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 3130203a3e..5c140f2fde 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -48,7 +48,7 @@
 
 namespace Buried {
 
-BuriedEngine::BuriedEngine(OSystem *syst, const Common::ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
+BuriedEngine::BuriedEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
 	_gfx = 0;
 	_mainEXE = 0;
 	_library = 0;
diff --git a/engines/buried/buried.h b/engines/buried/buried.h
index 7cf5d68b08..9a40c838b3 100644
--- a/engines/buried/buried.h
+++ b/engines/buried/buried.h
@@ -33,8 +33,9 @@
 
 class OSystem;
 
-namespace Common {
 struct ADGameDescription;
+
+namespace Common {
 class SeekableReadStream;
 class Serializer;
 class WriteStream;
@@ -64,11 +65,11 @@ protected:
 	Common::Error run();
 
 public:
-	BuriedEngine(OSystem *syst, const Common::ADGameDescription *gamedesc);
+	BuriedEngine(OSystem *syst, const ADGameDescription *gamedesc);
 	virtual ~BuriedEngine();
 
 	// Detection related functions
-	const Common::ADGameDescription *_gameDescription;
+	const ADGameDescription *_gameDescription;
 	bool isDemo() const;
 	bool isTrial() const;
 	bool isTrueColor() const;
diff --git a/engines/buried/metaengine.cpp b/engines/buried/metaengine.cpp
index 0b485eea8c..05a9c44e84 100644
--- a/engines/buried/metaengine.cpp
+++ b/engines/buried/metaengine.cpp
@@ -25,17 +25,12 @@
 #include "common/savefile.h"
 #include "common/system.h"
 
+#include "engines/advancedDetector.h"
+
 #include "buried/buried.h"
 
 namespace Buried {
 
-bool BuriedEngine::hasFeature(EngineFeature f) const {
-	return
-		(f == kSupportsRTL)
-		|| (f == kSupportsLoadingDuringRuntime)
-		|| (f == kSupportsSavingDuringRuntime);
-}
-
 bool BuriedEngine::isDemo() const {
 	// The trial is a demo for the user's sake, but not internally.
 	return (_gameDescription->flags & ADGF_DEMO) != 0 && !isTrial();
@@ -78,7 +73,7 @@ public:
 	}
 
 	virtual bool hasFeature(MetaEngineFeature f) const;
-	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
 	virtual SaveStateList listSaves(const char *target) const;
 	virtual int getMaximumSaveSlot() const { return 999; }
 	virtual void removeSaveState(const char *target, int slot) const;
@@ -116,13 +111,10 @@ void BuriedMetaEngine::removeSaveState(const char *target, int slot) const {
 	g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str());
 }
 
-bool BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
-	const Buried::BuriedGameDescription *gd = (const Buried::BuriedGameDescription *)desc;
-
-	if (gd)
-		*engine = new Buried::BuriedEngine(syst, gd);
+Common::Error BuriedMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	*engine = new Buried::BuriedEngine(syst, desc);
 
-	return (gd != 0);
+	return Common::kNoError;
 }
 
 #if PLUGIN_ENABLED_DYNAMIC(BURIED)


Commit: 1af920e3cfd74e49bd125b2811b3822c4f33aa49
    https://github.com/scummvm/scummvm/commit/1af920e3cfd74e49bd125b2811b3822c4f33aa49
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Use conventional methods of SaveLoadChooser instead of direct calls

Changed paths:
    engines/buried/saveload.cpp


diff --git a/engines/buried/saveload.cpp b/engines/buried/saveload.cpp
index 4eb7b13269..1c5304b238 100644
--- a/engines/buried/saveload.cpp
+++ b/engines/buried/saveload.cpp
@@ -514,12 +514,7 @@ bool BuriedEngine::syncGlobalFlags(Common::Serializer &s, GlobalFlags &flags) {
 Common::Error BuriedEngine::runLoadDialog() {
 	GUI::SaveLoadChooser slc(_("Load game:"), _("Load"), false);
 
-	Common::String gameId = ConfMan.get("gameid");
-
-	const EnginePlugin *plugin = 0;
-	EngineMan.findGame(gameId, &plugin);
-
-	int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+	int slot = slc.runModalWithCurrentTarget();
 
 	Common::Error result;
 
@@ -538,17 +533,12 @@ Common::Error BuriedEngine::runLoadDialog() {
 Common::Error BuriedEngine::runSaveDialog() {
 	GUI::SaveLoadChooser slc(_("Save game:"), _("Save"), true);
 
-	Common::String gameId = ConfMan.get("gameid");
-
-	const EnginePlugin *plugin = 0;
-	EngineMan.findGame(gameId, &plugin);
-
-	int slot = slc.runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
+	int slot = slc.runModalWithCurrentTarget();
 
 	Common::Error result;
 
 	if (slot >= 0) {
-		if (saveGameState(slot, slc.getResultString()).getCode() == Common::kNoError)
+		if (saveGameState(slot, slc.getResultString(), false).getCode() == Common::kNoError)
 			result = Common::kNoError;
 		else
 			result = Common::kUnknownError;


Commit: 26fe61bfb868988769d81786034ee7805c552f45
    https://github.com/scummvm/scummvm/commit/26fe61bfb868988769d81786034ee7805c552f45
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Re-add accidentally removed method

Changed paths:
    engines/buried/detection.cpp
    engines/buried/metaengine.cpp


diff --git a/engines/buried/detection.cpp b/engines/buried/detection.cpp
index bb5038b9f5..6341ea4633 100644
--- a/engines/buried/detection.cpp
+++ b/engines/buried/detection.cpp
@@ -69,4 +69,4 @@ public:
 	}
 };
 
-REGISTER_PLUGIN_STATIC(BURIED_DETEcTION, PLUGIN_TYPE_ENGINE_DETECTION, BuriedMetaEngineDetection);
+REGISTER_PLUGIN_STATIC(BURIED_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, BuriedMetaEngineDetection);
diff --git a/engines/buried/metaengine.cpp b/engines/buried/metaengine.cpp
index 05a9c44e84..fdda4525d3 100644
--- a/engines/buried/metaengine.cpp
+++ b/engines/buried/metaengine.cpp
@@ -31,6 +31,13 @@
 
 namespace Buried {
 
+bool BuriedEngine::hasFeature(EngineFeature f) const {
+	return
+		(f == kSupportsReturnToLauncher)
+		|| (f == kSupportsLoadingDuringRuntime)
+		|| (f == kSupportsSavingDuringRuntime);
+}
+
 bool BuriedEngine::isDemo() const {
 	// The trial is a demo for the user's sake, but not internally.
 	return (_gameDescription->flags & ADGF_DEMO) != 0 && !isTrial();


Commit: 622528796d86f8f44f08ca151000a1c319e61299
    https://github.com/scummvm/scummvm/commit/622528796d86f8f44f08ca151000a1c319e61299
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:44+01:00

Commit Message:
BURIED: Added support for GOG.com release

Changed paths:
    engines/buried/buried.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 5c140f2fde..195074fb5b 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -64,6 +64,11 @@ BuriedEngine::BuriedEngine(OSystem *syst, const ADGameDescription *gameDesc) : E
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN31/MANUAL", 0, 2); // v1.05 era
 	SearchMan.addSubDirectoryMatching(gameDataDir, "WIN95/MANUAL", 0, 2); // v1.10 era (Trilogy release)
+
+	// GOG.com release, plainly extracted files
+	SearchMan.addSubDirectoryMatching(gameDataDir, "data1", 0, 3);
+	SearchMan.addSubDirectoryMatching(gameDataDir, "data2", 0, 3);
+	SearchMan.addSubDirectoryMatching(gameDataDir, "data3", 0, 3);
 }
 
 BuriedEngine::~BuriedEngine() {


Commit: 7c47e67c49c63979681327b0bad238029366a1f5
    https://github.com/scummvm/scummvm/commit/7c47e67c49c63979681327b0bad238029366a1f5
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
GUI: Added VL Gothic regular font to fonts.dat

Changed paths:
  A gui/themes/fonts/VL-Gothic-Regular.ttf
    dists/engine-data/fonts.dat


diff --git a/dists/engine-data/fonts.dat b/dists/engine-data/fonts.dat
index 4632f9d88e..2c3c050700 100644
Binary files a/dists/engine-data/fonts.dat and b/dists/engine-data/fonts.dat differ
diff --git a/gui/themes/fonts/VL-Gothic-Regular.ttf b/gui/themes/fonts/VL-Gothic-Regular.ttf
new file mode 100644
index 0000000000..15549dc39a
Binary files /dev/null and b/gui/themes/fonts/VL-Gothic-Regular.ttf differ


Commit: 2c9cce70b29fe0353982b3746a989d8b68b525b4
    https://github.com/scummvm/scummvm/commit/2c9cce70b29fe0353982b3746a989d8b68b525b4
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Simplified font handling and added reliable font fallbacks

Changed paths:
    engines/buried/graphics.cpp
    engines/buried/graphics.h


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index fbf78d7ae9..70f428f2a6 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -167,10 +167,9 @@ Graphics::Font *GraphicsManager::createFont(int size, bool bold) const {
 }
 
 Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
-	Common::SeekableReadStream *stream = findArialStream(bold);
+	Common::String defaultBaseName = bold ? "arialbd.ttf" : "arial.ttf";
 
-	if (!stream)
-		error("Failed to find Arial%s font", bold ? " Bold" : "");
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(defaultBaseName);
 
 	// Map the heights needed to point sizes
 	if (bold) {
@@ -205,12 +204,25 @@ Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
 	static const uint32 *codePageMapping = s_codePage1252;
 #endif
 
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, codePageMapping);
+	Graphics::Font *font;
+
+	if (stream) {
+		font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, codePageMapping);
+
+		delete stream;
+	} else {
+		const char *fname;
+		if (bold)
+			fname = "LiberationSans-Bold.ttf";
+		else
+			fname = "LiberationSans-Regular.ttf";
+
+		font = Graphics::loadTTFFontFromArchive(fname, size, Graphics::kTTFSizeModeCharacter, 96, _vm->isTrueColor() ? Graphics::kTTFRenderModeLight : Graphics::kTTFRenderModeMonochrome, codePageMapping);
+	}
 
 	if (!font)
 		error("Failed to load Arial%s font", bold ? " Bold" : "");
 
-	delete stream;
 	return font;
 }
 
@@ -597,28 +609,6 @@ Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *
 	return convertedSurface;
 }
 
-Common::SeekableReadStream *GraphicsManager::findArialStream(bool bold) const {
-	Common::SeekableReadStream *stream = 0;
-
-	// Try to see if the user supplied a font
-	Common::String defaultBaseName = bold ? "arialbd.ttf" : "arial.ttf";
-	stream = SearchMan.createReadStreamForMember(defaultBaseName);
-	if (stream)
-		return stream;
-
-	if (!stream) {
-		// TODO: It would really be nice to have "Liberation Sans", since it is metric
-		// compatible with Arial.
-
-		if (bold)
-			stream = getThemeFontStream("LiberationSans-Bold.ttf");
-		else
-			stream = getThemeFontStream("LiberationSans-Regular.ttf");
-	}
-
-	return stream;
-}
-
 int GraphicsManager::computeHPushOffset(int speed) {
 	switch (speed) {
 	case 3:
@@ -657,11 +647,6 @@ void GraphicsManager::crossBlit(Graphics::Surface *dst, int xDst, int yDst, int
 }
 
 Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
-	Common::SeekableReadStream *stream = findMSGothicStream();
-
-	if (!stream)
-		error("Failed to find MS Gothic font");
-
 	switch (size) {
 	case 10:
 	case 11:
@@ -677,10 +662,18 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 		error("Unknown MS Gothic font size %d", size);
 	}
 
-	// TODO: Fake a bold version
+	Graphics::Font *font;
+
+	// Try to see if the user supplied a font
+	Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember("msgothic.ttc");
 
-	// Force monochrome, since the original uses the bitmap glyphs in the font
-	Graphics::Font *font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, Graphics::kTTFRenderModeMonochrome);
+	// TODO: Fake a bold version
+	if (stream) {
+		// Force monochrome, since the original uses the bitmap glyphs in the font
+		font = Graphics::loadTTFFont(*stream, size, Graphics::kTTFSizeModeCharacter, 96, Graphics::kTTFRenderModeMonochrome);
+	} else {
+		font = Graphics::loadTTFFontFromArchive("VL-Gothic-Regular.ttf", size, Graphics::kTTFSizeModeCharacter, 96, Graphics::kTTFRenderModeMonochrome);
+	}
 
 	if (!font)
 		error("Failed to load MS Gothic font");
@@ -689,68 +682,6 @@ Graphics::Font *GraphicsManager::createMSGothicFont(int size, bool bold) const {
 	return font;
 }
 
-Common::SeekableReadStream *GraphicsManager::findMSGothicStream() const {
-	Common::SeekableReadStream *stream = 0;
-
-	// Try to see if the user supplied a font
-	stream = SearchMan.createReadStreamForMember("msgothic.ttc");
-	if (stream)
-		return stream;
-
-	// HACK: Try to load the system font
-#if defined(WIN32)
-	Common::FSNode fontPath("C:/WINDOWS/Fonts/msgothic.ttc");
-
-	if (fontPath.exists() && !fontPath.isDirectory() && fontPath.isReadable())
-		stream = fontPath.createReadStream();
-
-	if (!stream) {
-		Common::FSNode win2kFontPath("C:/WINNT/Fonts/msgothic.ttc");
-
-		if (win2kFontPath.exists() && !win2kFontPath.isDirectory() && win2kFontPath.isReadable())
-			stream = win2kFontPath.createReadStream();
-	}
-#endif
-
-	if (!stream) {
-		// TODO: Find the equivalent free font (probably "VL Gothic", which is what Wine uses)
-		// "Ume Gothic" might be another alternative
-	}
-
-	return stream;
-}
-
-Common::SeekableReadStream *GraphicsManager::getThemeFontStream(const Common::String &fileName) const {
-	// Without needing to actually come out and say it, this is all one huge hack.
-	// OK, I said it anyway.
-
-	Common::SeekableReadStream *stream = 0;
-
-	// Code loosely based on the similar Wintermute code, minus the C++11 nullptr nonsense
-	// Attempt to load it from the theme
-
-	if (ConfMan.hasKey("themepath")) {
-		Common::SeekableReadStream *archiveStream = 0;
-		Common::FSNode themeFile(ConfMan.get("themepath") + "/scummmodern.zip");
-
-		if (themeFile.exists() && !themeFile.isDirectory() && themeFile.isReadable())
-			archiveStream = themeFile.createReadStream();
-
-		if (!archiveStream)
-			archiveStream = SearchMan.createReadStreamForMember("scummmodern.zip");
-
-		if (archiveStream) {
-			Common::Archive *archive = Common::makeZipArchive(archiveStream);
-			if (archive)
-				stream = archive->createReadStreamForMember(fileName);
-
-			delete archive;
-		}
-	}
-
-	return stream;
-}
-
 void GraphicsManager::renderText(Graphics::Surface *dst, Graphics::Font *font, const Common::String &text, int x, int y, int w, int h, uint32 color, int lineHeight, TextAlign textAlign, bool centerVertically) {
 	if (text.empty())
 		return;
diff --git a/engines/buried/graphics.h b/engines/buried/graphics.h
index 231872dd81..b00abb0ada 100644
--- a/engines/buried/graphics.h
+++ b/engines/buried/graphics.h
@@ -118,16 +118,13 @@ private:
 	Graphics::Surface *_screen;
 	byte *_palette;
 	bool _needsErase;
-	
+
 	byte *createDefaultPalette() const;
 	Graphics::Surface *getBitmap(Common::SeekableReadStream *stream);
 
 	Graphics::Font *createArialFont(int size, bool bold) const;
-	Common::SeekableReadStream *findArialStream(bool bold) const;
-	Common::SeekableReadStream *getThemeFontStream(const Common::String &fileName) const;
 
 	Graphics::Font *createMSGothicFont(int size, bool bold) const;
-	Common::SeekableReadStream *findMSGothicStream() const;
 };
 
 /**


Commit: 6dbb8d91341977e9e63fedfff2927a03fc8b7208
    https://github.com/scummvm/scummvm/commit/6dbb8d91341977e9e63fedfff2927a03fc8b7208
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Added detection entries for 1.04 release

Changed paths:
    engines/buried/detection_tables.h


diff --git a/engines/buried/detection_tables.h b/engines/buried/detection_tables.h
index 032e713908..496ec13b65 100644
--- a/engines/buried/detection_tables.h
+++ b/engines/buried/detection_tables.h
@@ -107,6 +107,34 @@ static const ADGameDescription gameDescriptions[] = {
 		GUIO0()
 	},
 
+	// English Windows 3.11 8BPP
+	// Not Installed
+	// v1.04
+	{
+		"buried",
+		"v1.04 8BPP",
+		AD_ENTRY2s("BIT816.EXE", "9055335a574d3b9418b8ddb9a5539829", 1168384,
+				   "BIT8LIB.DLL","31bcd9e5cc32df00b09ce626e6d9106e", 2420480),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		ADGF_NO_FLAGS,
+		GUIO0()
+	},
+
+	// English Windows 3.11 24BPP
+	// Not Installed
+	// v1.04
+	{
+		"buried",
+		"v1.04 24BPP",
+		AD_ENTRY2s("BIT2416.EXE", "782083ef765dcbe8e8ac11d025fba68d", 1163264,
+				   "BIT24LIB.DLL","74ac9dae92f415fea8cdbd220ba8795c", 5211648),
+		Common::EN_ANY,
+		Common::kPlatformWindows,
+		GF_TRUECOLOR,
+		GUIO0()
+	},
+
 	// German Windows 3.11 8BPP
 	// Installed
 	// v1.05


Commit: 97a2408677cdefbf1f1b85c9dc0c1fcad77edc3e
    https://github.com/scummvm/scummvm/commit/97a2408677cdefbf1f1b85c9dc0c1fcad77edc3e
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
CREDITS: Fix file after merge

Changed paths:
    devtools/credits.pl


diff --git a/devtools/credits.pl b/devtools/credits.pl
index 564d499903..271e2ae748 100755
--- a/devtools/credits.pl
+++ b/devtools/credits.pl
@@ -1700,7 +1700,6 @@ begin_credits("Credits");
 			add_person("Anton Yartsev", "Zidane", "For the original re-implementation of the Z-Vision engine");
 		end_persons();
 
-<<<<<<< HEAD
 		add_paragraph(
 			"Tony Warriner and everyone at Revolution Software Ltd. for sharing ".
 			"with us the source of some of their brilliant games, allowing us to ".
@@ -1757,8 +1756,9 @@ begin_credits("Credits");
 			"support while porting the engine to ScummVM.");
 
 		add_paragraph(
-			"Bob Bell, Michel Kripalani, Tommy Yune, from Presto Studios for ".
-			"providing the source code of The Journeyman Project: Pegasus Prime.");
+			"Bob Bell, David Black, Michel Kripalani, and Tommy Yune from Presto Studios ".
+			"for providing the source code of The Journeyman Project: Pegasus Prime ".
+			"and The Journeyman Project 2: Buried in Time.");
 
 		add_paragraph(
 			"Electronic Arts IP Preservation Team, particularly Stefan Serbicki, and Vasyl Tsvirkunov of ".
@@ -1785,68 +1785,6 @@ begin_credits("Credits");
 
 		add_paragraph(
 			"Benjamin Haisch, for emimeshviewer, which our EMI code borrows heavily from.");
-=======
-	add_paragraph(
-    "Tony Warriner and everyone at Revolution Software Ltd. for sharing ".
-    "with us the source of some of their brilliant games, allowing us to ".
-    "release Beneath a Steel Sky as freeware... and generally being ".
-    "supportive above and beyond the call of duty.");
-
-	add_paragraph(
-    "John Passfield and Steve Stamatiadis for sharing the source of their ".
-    "classic title, Flight of the Amazon Queen and also being incredibly ".
-    "supportive.");
-
-	add_paragraph(
-    "Joe Pearce from The Wyrmkeep Entertainment Co. for sharing the source ".
-    "of their famous title Inherit the Earth and always prompt replies to ".
-    "our questions.");
-
-	add_paragraph(
-    "Aric Wilmunder, Ron Gilbert, David Fox, Vince Lee, and all those at ".
-    "LucasFilm/LucasArts who made SCUMM the insane mess to reimplement ".
-    "that it is today. Feel free to drop us a line and tell us what you ".
-    "think, guys!");
-
-	add_paragraph(
-    "Alan Bridgman, Simon Woodroffe and everyone at Adventure Soft for ".
-    "sharing the source code of some of their games with us.");
-
-	add_paragraph(
-    "John Young, Colin Smythe and especially Terry Pratchett himself for ".
-    "sharing the source code of Discworld I & II with us.");
-
-	add_paragraph(
-    "Emilio de Paz Aragón from Alcachofa Soft for sharing the source code ".
-    "of Drascula: The Vampire Strikes Back with us and his generosity with ".
-    "freewaring the game.");
-
-	add_paragraph(
-    "David P. Gray from Gray Design Associates for sharing the source code ".
-    "of the Hugo trilogy.");
-
-	add_paragraph(
-    "Broken Sword 2.5 team for providing sources of their engine and their great ".
-    "support.");
-
-	add_paragraph(
-    "Neil Dodwell and David Dew from Creative Reality for providing the source ".
-    "of Dreamweb and for their tremendous support.");
-
-	add_paragraph(
-    "Janusz Wiśniewski and Miroslaw Liminowicz from Laboratorium Komputerowe Avalon ".
-    "for providing full source code for Sołtys and Sfinx and letting us redistribute the games.");
-
-	add_paragraph(
-    "Jan Nedoma for providing the sources to the Wintermute-engine, and for his ".
-    "support while porting the engine to ScummVM.");
-
-	add_paragraph(
-    "Bob Bell, David Black, Michel Kripalani, and Tommy Yune from Presto Studios ".
-    "for providing the source code of The Journeyman Project: Pegasus Prime ".
-    "and The Journeyman Project 2: Buried in Time.");
-
->>>>>>> 4fbf293bbf (CREDITS: Add credits for buried)
 	end_section();
 
 end_credits();


Commit: 5dfb0c592ca680358a3e0ca76386074366de41f5
    https://github.com/scummvm/scummvm/commit/5dfb0c592ca680358a3e0ca76386074366de41f5
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
COMMON: Remove duplicate include

Changed paths:
    common/scummsys.h


diff --git a/common/scummsys.h b/common/scummsys.h
index ec900fb5c9..19550a5930 100644
--- a/common/scummsys.h
+++ b/common/scummsys.h
@@ -123,7 +123,6 @@
 	#include <stddef.h>
 	#include <assert.h>
 	#include <ctype.h>
-	#include <stddef.h>
 	// MSVC does not define M_PI, M_SQRT2 and other math defines by default.
 	// _USE_MATH_DEFINES must be defined in order to have these defined, thus
 	// we enable it here. For more information, check:


Commit: 6e49bfd0ae0ce76b859209c7ef65da8b58edf370
    https://github.com/scummvm/scummvm/commit/6e49bfd0ae0ce76b859209c7ef65da8b58edf370
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Fix warnings

Changed paths:
    engines/buried/environ/mayan.cpp
    engines/buried/scene_view.cpp


diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index 4be3cefba5..b087436880 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -64,7 +64,7 @@ PlaceCeramicBowl::PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const L
 int PlaceCeramicBowl::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
 		return 0;
-	
+
 	if (itemID != kItemCeramicBowl)
 		return SIC_REJECT;
 
@@ -1914,8 +1914,6 @@ int DeathGodPuzzleBox::mouseUp(Window *viewWindow, const Common::Point &pointLoc
 			((SceneViewWindow *)viewWindow)->showDeathScene(12);
 			return SC_DEATH;
 		}
-
-		return SC_TRUE;
 	}
 
 	return SC_FALSE;
@@ -2222,7 +2220,7 @@ bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int
 		if (oldEnvironment == 2)
 			return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 64);
 
-		return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 16); 
+		return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 16);
 	} else if (environment == 4) {
 		if (oldTimeZone == -2)
 			_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index e10ca5e78e..7f8586e055 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -157,7 +157,7 @@ bool SceneViewWindow::startNewGameIntro(bool walkthrough) {
 	newLocation.depth = 0;
 
 	jumpToScene(newLocation);
-	
+
 	if (walkthrough) {
 		// Set the mode flag
 		_globalFlags.generalWalkthroughMode = 1;
@@ -240,7 +240,7 @@ bool SceneViewWindow::getSceneStaticData(const Location &location, LocationStati
 			locationStaticData.destUp.transitionData = resource->readSint16LE();
 			locationStaticData.destUp.transitionStartFrame = resource->readSint32LE();
 			locationStaticData.destUp.transitionLength = resource->readSint32LE();
-			
+
 			locationStaticData.destLeft.destinationScene.timeZone = resource->readSint16LE();
 			locationStaticData.destLeft.destinationScene.environment = resource->readSint16LE();
 			locationStaticData.destLeft.destinationScene.node = resource->readSint16LE();
@@ -251,7 +251,7 @@ bool SceneViewWindow::getSceneStaticData(const Location &location, LocationStati
 			locationStaticData.destLeft.transitionData = resource->readSint16LE();
 			locationStaticData.destLeft.transitionStartFrame = resource->readSint32LE();
 			locationStaticData.destLeft.transitionLength = resource->readSint32LE();
-			
+
 			locationStaticData.destRight.destinationScene.timeZone = resource->readSint16LE();
 			locationStaticData.destRight.destinationScene.environment = resource->readSint16LE();
 			locationStaticData.destRight.destinationScene.node = resource->readSint16LE();
@@ -262,7 +262,7 @@ bool SceneViewWindow::getSceneStaticData(const Location &location, LocationStati
 			locationStaticData.destRight.transitionData = resource->readSint16LE();
 			locationStaticData.destRight.transitionStartFrame = resource->readSint32LE();
 			locationStaticData.destRight.transitionLength = resource->readSint32LE();
-			
+
 			locationStaticData.destDown.destinationScene.timeZone = resource->readSint16LE();
 			locationStaticData.destDown.destinationScene.environment = resource->readSint16LE();
 			locationStaticData.destDown.destinationScene.node = resource->readSint16LE();
@@ -273,7 +273,7 @@ bool SceneViewWindow::getSceneStaticData(const Location &location, LocationStati
 			locationStaticData.destDown.transitionData = resource->readSint16LE();
 			locationStaticData.destDown.transitionStartFrame = resource->readSint32LE();
 			locationStaticData.destDown.transitionLength = resource->readSint32LE();
-			
+
 			locationStaticData.destForward.destinationScene.timeZone = resource->readSint16LE();
 			locationStaticData.destForward.destinationScene.environment = resource->readSint16LE();
 			locationStaticData.destForward.destinationScene.node = resource->readSint16LE();
@@ -885,7 +885,7 @@ bool SceneViewWindow::timeSuitJump(int destination) {
 
 	// Repaint the window
 	invalidateWindow(false);
-	
+
 	// Call the post-enter function
 	_currentScene->postEnterRoom(this, oldLocation);
 	_parent->invalidateWindow(false);
@@ -935,7 +935,6 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 			delete newBackground;
 			return retVal;
 		}
-		break;
 	case TRANSITION_WALK:
 		if (_vm->isControlDown()) {
 			if (navFrame >= 0) {
@@ -966,7 +965,7 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 				else
 					_demoSoundEffectHandle = _vm->_sound->playSoundEffect("CASTLE/CGBSDO.WAV");
 			}
-		
+
 			bool retVal = walkTransition(_currentScene->_staticData.location, destinationData, navFrame);
 
 			// And also a door close sound
@@ -983,7 +982,6 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 
 			return retVal;
 		}
-		break;
 	case TRANSITION_VIDEO:
 		if (_vm->isControlDown() && false) { // TODO: debug mode check (maybe?)
 			if (navFrame >= 0) {
@@ -1002,7 +1000,6 @@ bool SceneViewWindow::playTransition(const DestinationScene &destinationData, in
 		} else {
 			return videoTransition(_currentScene->_staticData.location, destinationData, navFrame);
 		}
-		break;
 	}
 
 	return false;
@@ -1045,7 +1042,7 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 		_paused = false;
 		return false;
 	}
-	
+
 	changeStillFrameMovie(_vm->getFilePath(destinationStaticData.location.timeZone, destinationStaticData.location.environment, SF_STILLS));
 
 	Graphics::Surface *newBackground = 0;
@@ -2624,7 +2621,7 @@ bool SceneViewWindow::displayLiveText(const Common::String &text, bool notifyUse
 bool SceneViewWindow::displayTranslationText(const Common::String &text) {
 	if (((GameUIWindow *)_parent)->_liveTextWindow)
 		return ((GameUIWindow *)_parent)->_liveTextWindow->updateTranslationText(text);
-	
+
 	return false;
 }
 
@@ -2655,7 +2652,7 @@ Common::Array<AIComment> SceneViewWindow::getAICommentDatabase(int timeZone, int
 		return comments;
 
 	uint16 count = stream->readUint16LE();
-	
+
 	for (uint16 i = 0; i < count; i++) {
 		AIComment comment;
 		comment.location.timeZone = stream->readSint16LE();


Commit: 077fe677a587f7d57746771ee5afc9252c9cae8b
    https://github.com/scummvm/scummvm/commit/077fe677a587f7d57746771ee5afc9252c9cae8b
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Fix warnings

Changed paths:
    engines/buried/demo/demo_menu.h
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/demo/demo_menu.h b/engines/buried/demo/demo_menu.h
index e04bfb0113..4ec331e2ab 100644
--- a/engines/buried/demo/demo_menu.h
+++ b/engines/buried/demo/demo_menu.h
@@ -53,7 +53,7 @@ private:
 	Common::Rect _gallery;
 	Common::Rect _quit;
 	int _curButton;
-	bool _buttonDrawnDown;
+	//bool _buttonDrawnDown;
 	Graphics::Surface *_background;
 };
 
diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 1dc36dc357..f53fd044f1 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -375,7 +375,7 @@ private:
 	int _firstStingerFileID;
 	int _lastStingerFileID;
 	int _stingerDelay;
-	int _timerFlagOffset;
+	//int _timerFlagOffset;
 };
 
 PlayArthurOffsetTimed::PlayArthurOffsetTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
@@ -924,7 +924,7 @@ public:
 
 private:
 	Common::Rect _canister;
-}; 
+};
 
 TakeWaterCanister::TakeWaterCanister(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
 		BaseOxygenTimer(vm, viewWindow, sceneStaticData, priorLocation) {
@@ -956,7 +956,7 @@ int TakeWaterCanister::mouseDown(Window *viewWindow, const Common::Point &pointL
 
 	return SC_FALSE;
 }
-	
+
 int TakeWaterCanister::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
 	if (_canister.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiICTakenWaterCanister == 0)
 		return kCursorOpenHand;
@@ -991,7 +991,7 @@ ScienceWingZoomIntoPanel::ScienceWingZoomIntoPanel(BuriedEngine *vm, Window *vie
 int ScienceWingZoomIntoPanel::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
 	if (_clickRegion.contains(pointLocation))
 		((SceneViewWindow *)viewWindow)->moveToDestination(_clickDestination);
-	
+
 	return SC_FALSE;
 }
 
@@ -1239,7 +1239,7 @@ public:
 	ScienceWingMachineRoomDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
-	
+
 private:
 	int _cursorID;
 	Common::Rect _clickRegion;
@@ -1310,9 +1310,9 @@ public:
 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
 
 private:
-	uint32 _entryStartTime;
+	//uint32 _entryStartTime;
 	Common::Rect _door;
-	bool _jumped;
+	//bool _jumped;
 };
 
 NexusDoor::NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
@@ -1448,7 +1448,7 @@ int NexusPuzzle::gdiPaint(Window *viewWindow) {
 
 	return SC_REPAINT;
 }
-	
+
 int NexusPuzzle::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
 	// Puzzle is only in adventure mode
 	if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1)
diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index de3bac1ef5..a75907f698 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -55,7 +55,7 @@ TopOfTowerGuardEncounter::TopOfTowerGuardEncounter(BuriedEngine *vm, Window *vie
 	_showGuard = _staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment;
 
 	if (((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBloodyArrow))
-		_staticData.destForward.destinationScene.depth = 1;		
+		_staticData.destForward.destinationScene.depth = 1;
 }
 
 int TopOfTowerGuardEncounter::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
@@ -138,7 +138,7 @@ int TowerStairsGuardEncounter::preExitRoom(Window *viewWindow, const Location &n
 class WallSlideDeath : public SceneBase {
 public:
 	WallSlideDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
-	int postExitRoom(Window *viewWindow, const Location &newLocation);	
+	int postExitRoom(Window *viewWindow, const Location &newLocation);
 };
 
 WallSlideDeath::WallSlideDeath(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
@@ -171,7 +171,7 @@ public:
 
 private:
 	bool _timerStarted;
-	uint32 _startTime;
+	//uint32 _startTime;
 	bool _walkthrough;
 };
 
@@ -981,7 +981,7 @@ public:
 
 private:
 	uint32 _startingTime;
-	bool _finished;
+	//bool _finished;
 };
 
 KingsChamberGuardEncounter::KingsChamberGuardEncounter(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :


Commit: 7fac27c72823adcbbed39e1909c17ab0cb68beff
    https://github.com/scummvm/scummvm/commit/7fac27c72823adcbbed39e1909c17ab0cb68beff
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Fix some CppCheck warnings

Changed paths:
    engines/buried/avi_frames.cpp
    engines/buried/buried.cpp
    engines/buried/window.cpp


diff --git a/engines/buried/avi_frames.cpp b/engines/buried/avi_frames.cpp
index 11eb26b9d4..5b7b9d5566 100644
--- a/engines/buried/avi_frames.cpp
+++ b/engines/buried/avi_frames.cpp
@@ -35,11 +35,11 @@ namespace Buried {
 
 AVIFrames::AVIFrames(const Common::String &fileName, uint cachedFrames) {
 	_maxCachedFrames = 0;
-	_video = 0;
+	_video = nullptr;
 	_cacheEnabled = false;
-	_lastFrame = 0;
+	_lastFrame = nullptr;
 	_lastFrameIndex = -1;
-	_tempFrame = 0;
+	_tempFrame = nullptr;
 
 	if (!fileName.empty())
 		open(fileName, cachedFrames);
@@ -85,25 +85,25 @@ bool AVIFrames::open(const Common::String &fileName, uint cachedFrames) {
 
 void AVIFrames::close() {
 	delete _video;
-	_video = 0;
+	_video = nullptr;
 
 	_fileName.clear();
 
 	flushFrameCache();
 
 	_lastFrameIndex = -1;
-	_lastFrame = 0;
+	_lastFrame = nullptr;
 
 	if (_tempFrame) {
 		_tempFrame->free();
 		delete _tempFrame;
-		_tempFrame = 0;
+		_tempFrame = nullptr;
 	}
 }
 
 const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
 	if (!_video)
-		return 0;
+		return nullptr;
 
 	if (frameIndex < 0 || frameIndex == _lastFrameIndex)
 		return _lastFrame;
@@ -115,11 +115,11 @@ const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
 	}
 
 	if (!_video->seekToFrame(frameIndex))
-		return 0;
+		return nullptr;
 
 	const Graphics::Surface *frame = _video->decodeNextFrame();
 	if (!frame)
-		return 0;
+		return nullptr;
 
 	Graphics::Surface *copy;
 	if (frame->format == g_system->getScreenFormat()) {
@@ -146,7 +146,7 @@ const Graphics::Surface *AVIFrames::getFrame(int frameIndex) {
 Graphics::Surface *AVIFrames::getFrameCopy(int frameIndex) {
 	const Graphics::Surface *frame = getFrame(frameIndex);
 	if (!frame)
-		return 0;
+		return nullptr;
 
 	Graphics::Surface *copy = new Graphics::Surface();
 	copy->copyFrom(*frame);
@@ -164,7 +164,7 @@ bool AVIFrames::flushFrameCache() {
 	if (_cachedFrames.empty())
 		return false;
 
-	for (FrameList::iterator it = _cachedFrames.begin(); it != _cachedFrames.end(); it++) {
+	for (FrameList::iterator it = _cachedFrames.begin(); it != _cachedFrames.end(); ++it) {
 		if (it->frame) {
 			it->frame->free();
 			delete it->frame;
@@ -175,11 +175,11 @@ bool AVIFrames::flushFrameCache() {
 }
 
 const Graphics::Surface *AVIFrames::retrieveFrameFromCache(int frameIndex) const {
-	for (FrameList::const_iterator it = _cachedFrames.begin(); it != _cachedFrames.end(); it++)
+	for (FrameList::const_iterator it = _cachedFrames.begin(); it != _cachedFrames.end(); ++it)
 		if (it->index == frameIndex)
 			return it->frame;
 
-	return 0;
+	return nullptr;
 }
 
 void AVIFrames::addFrameToCache(int frameIndex, Graphics::Surface *frame) {
diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 195074fb5b..4eb0dfeef2 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -267,9 +267,10 @@ bool BuriedEngine::killTimer(uint timer) {
 }
 
 void BuriedEngine::removeAllTimers(Window *window) {
-	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++)
+	for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); ++it) {
 		if (it->_value.owner == window)
 			_timers.erase(it);
+	}
 }
 
 void BuriedEngine::addVideo(VideoWindow *window) {
@@ -281,7 +282,7 @@ void BuriedEngine::removeVideo(VideoWindow *window) {
 }
 
 void BuriedEngine::updateVideos() {
-	for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+	for (VideoList::iterator it = _videos.begin(); it != _videos.end(); ++it)
 		(*it)->updateVideo();
 }
 
@@ -307,7 +308,7 @@ void BuriedEngine::sendAllMessages() {
 		// Generate a timer message
 		bool ranTimer = false;
 
-		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++) {
+		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); ++it) {
 			uint32 time = g_system->getMillis();
 
 			if (time >= it->_value.nextTrigger) {
@@ -333,7 +334,7 @@ void BuriedEngine::removeMessages(Window *window, int messageBegin, int messageE
 			delete it->message;
 			it = _messageQueue.erase(it);
 		} else {
-			it++;
+			++it;
 		}
 	}
 }
@@ -352,7 +353,7 @@ void BuriedEngine::removeAllMessages(Window *window) {
 			delete it->message;
 			it = _messageQueue.erase(it);
 		} else {
-			it++;
+			++it;
 		}
 	}
 }
@@ -361,7 +362,7 @@ bool BuriedEngine::hasMessage(Window *window, int messageBegin, int messageEnd)
 	// Implementation note: This doesn't currently handle timers, but would on real Windows.
 	// Buried doesn't check for timer messages being present, so it's skipped.
 
-	for (MessageQueue::const_iterator it = _messageQueue.begin(); it != _messageQueue.end(); it++)
+	for (MessageQueue::const_iterator it = _messageQueue.begin(); it != _messageQueue.end(); ++it)
 		if ((!window || it->dest == window) && it->message->getMessageType() >= messageBegin && it->message->getMessageType() <= messageEnd)
 			return true;
 
@@ -485,19 +486,19 @@ void BuriedEngine::pauseEngineIntern(bool pause) {
 	if (pause) {
 		_sound->pause(true);
 
-		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); ++it)
 			(*it)->pauseVideo();
 
 		_pauseStartTime = g_system->getMillis();
 	} else {
 		_sound->pause(false);
 
-		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++)
+		for (VideoList::iterator it = _videos.begin(); it != _videos.end(); ++it)
 			(*it)->resumeVideo();
 
 		uint32 timeDiff = g_system->getMillis() - _pauseStartTime;
 
-		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); it++)
+		for (TimerMap::iterator it = _timers.begin(); it != _timers.end(); ++it)
 			it->_value.nextTrigger += timeDiff;
 	}
 }
diff --git a/engines/buried/window.cpp b/engines/buried/window.cpp
index 5ae6363cb5..fc4605b9c2 100644
--- a/engines/buried/window.cpp
+++ b/engines/buried/window.cpp
@@ -30,7 +30,7 @@
 
 namespace Buried {
 
-const Window *kWindowPosTop = (const Window *)0;
+const Window *kWindowPosTop = (const Window *)nullptr;
 const Window *kWindowPosTopMost = (const Window *)-1;
 
 Window::Window(BuriedEngine *vm, Window *parent, bool visible) : _vm(vm), _parent(parent), _visible(visible) {
@@ -56,11 +56,11 @@ Window::~Window() {
 
 	// Make sure we're not the focused window
 	if (_vm->_focusedWindow == this)
-		_vm->_focusedWindow = 0;
+		_vm->_focusedWindow = nullptr;
 
 	// And also not captured
 	if (_vm->_captureWindow == this)
-		_vm->_captureWindow = 0;
+		_vm->_captureWindow = nullptr;
 
 	// Invalidate this window's rect as well
 	_vm->_gfx->invalidateRect(getAbsoluteRect());
@@ -142,11 +142,11 @@ void Window::updateWindow() {
 	onPaint();
 
 	// Draw children
-	for (WindowList::iterator it = _children.begin(); it != _children.end(); it++)
+	for (WindowList::iterator it = _children.begin(); it != _children.end(); ++it)
 		(*it)->updateWindow();
 
 	// Draw top-most children
-	for (WindowList::iterator it = _topMostChildren.begin(); it != _topMostChildren.end(); it++)
+	for (WindowList::iterator it = _topMostChildren.begin(); it != _topMostChildren.end(); ++it)
 		(*it)->updateWindow();
 }
 
@@ -252,9 +252,9 @@ Common::Rect Window::makeAbsoluteRect(const Common::Rect &rect) const {
 Window *Window::setFocus() {
 	// Don't allow focus to be acquired if the window is disabled
 	if (!isWindowEnabled())
-		return 0;
+		return nullptr;
 
-	Window *oldWindow = 0;
+	Window *oldWindow = nullptr;
 
 	// Notify the old window we just took its focus
 	if (_vm->_focusedWindow) {
@@ -268,11 +268,11 @@ Window *Window::setFocus() {
 }
 
 Window *Window::childWindowAtPoint(const Common::Point &point) {
-	for (WindowList::iterator it = _topMostChildren.reverse_begin(); it != _topMostChildren.end(); it--)
+	for (WindowList::iterator it = _topMostChildren.reverse_begin(); it != _topMostChildren.end(); --it)
 		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
 			return (*it)->childWindowAtPoint(point);
 
-	for (WindowList::iterator it = _children.reverse_begin(); it != _children.end(); it--)
+	for (WindowList::iterator it = _children.reverse_begin(); it != _children.end(); --it)
 		if ((*it)->getAbsoluteRect().contains(point) && (*it)->isWindowEnabled())
 			return (*it)->childWindowAtPoint(point);
 


Commit: 6e7e2f8be93ac2b90d26fe07a59b08de88fd9355
    https://github.com/scummvm/scummvm/commit/6e7e2f8be93ac2b90d26fe07a59b08de88fd9355
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Remove some useless includes

Changed paths:
    engines/buried/demo/demo_menu.cpp
    engines/buried/demo/features.cpp


diff --git a/engines/buried/demo/demo_menu.cpp b/engines/buried/demo/demo_menu.cpp
index ed4286051d..e7cb5171f5 100644
--- a/engines/buried/demo/demo_menu.cpp
+++ b/engines/buried/demo/demo_menu.cpp
@@ -27,11 +27,9 @@
 #include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/message.h"
-#include "buried/resources.h"
 #include "buried/sound.h"
 #include "buried/demo/demo_menu.h"
 
-#include "common/events.h"
 #include "common/system.h"
 #include "graphics/surface.h"
 
diff --git a/engines/buried/demo/features.cpp b/engines/buried/demo/features.cpp
index 35273ee91e..24c570275d 100644
--- a/engines/buried/demo/features.cpp
+++ b/engines/buried/demo/features.cpp
@@ -24,15 +24,10 @@
  */
 
 #include "buried/buried.h"
-#include "buried/frame_window.h"
 #include "buried/graphics.h"
 #include "buried/message.h"
-#include "buried/resources.h"
-#include "buried/sound.h"
 #include "buried/demo/features.h"
 
-#include "common/events.h"
-#include "common/system.h"
 #include "graphics/surface.h"
 
 namespace Buried {
@@ -72,7 +67,7 @@ void FeaturesDisplayWindow::onLButtonUp(const Common::Point &point, uint flags)
 	if (_background) {
 		_background->free();
 		delete _background;
-		_background = 0;
+		_background = nullptr;
 	}
 
 	switch (_curBackground) {


Commit: 1a0b3ce3097c983fecaa19a713b204f401700c9b
    https://github.com/scummvm/scummvm/commit/1a0b3ce3097c983fecaa19a713b204f401700c9b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Add some missing 'override' keywords

Changed paths:
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/alien.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index f53fd044f1..c03a78ee59 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -298,7 +298,7 @@ int SpaceDoorTimer::specifyCursor(Window *viewWindow, const Common::Point &point
 class UseCheeseGirlPropellant : public BaseOxygenTimer {
 public:
 	UseCheeseGirlPropellant(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
-	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
 	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
 	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
 
@@ -366,7 +366,7 @@ public:
 	PlayArthurOffsetTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 			int stingerVolume = 127, int lastStingerFlagOffset = -1, int effectIDFlagOffset = -1, int firstStingerFileID = -1,
 			int lastStingerFileID = -1, int stingerDelay = 1);
-	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
 
 private:
 	int _stingerVolume;
@@ -745,7 +745,7 @@ int IceteroidZoomInDispenser::specifyCursor(Window *viewWindow, const Common::Po
 class IceteroidDispenserControls : public BaseOxygenTimer {
 public:
 	IceteroidDispenserControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
-	int preExitRoom(Window *viewWindow, const Location &priorLocation);
+	int preExitRoom(Window *viewWindow, const Location &priorLocation) override;
 	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
@@ -1274,7 +1274,7 @@ int ScienceWingMachineRoomDoor::specifyCursor(Window *viewWindow, const Common::
 class ScienceWingStingersTimed : public BaseOxygenTimer {
 public:
 	ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
-	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
 };
 
 ScienceWingStingersTimed::ScienceWingStingersTimed(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
@@ -1305,7 +1305,7 @@ int ScienceWingStingersTimed::postEnterRoom(Window *viewWindow, const Location &
 class NexusDoor : public BaseOxygenTimer {
 public:
 	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
-	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
 	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
 
@@ -2303,7 +2303,7 @@ public:
 	PlayArthurOffsetCapacitance(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
 			int stingerVolume = 127, int lastStingerFlagOffset = -1, int effectIDFlagOffset = -1, int firstStingerFileID = -1,
 			int lastStingerFileID = -1, int stingerDelay = 1, int flagOffset = -1, int newStill = -1, int newNavStart = -1, int newNavLength = -1);
-	int postEnterRoom(Window *viewWindow, const Location &priorLocation);
+	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
 
 private:
 	int _stingerVolume;
diff --git a/engines/buried/environ/alien.cpp b/engines/buried/environ/alien.cpp
index 648be2651a..343da2e092 100644
--- a/engines/buried/environ/alien.cpp
+++ b/engines/buried/environ/alien.cpp
@@ -977,8 +977,8 @@ int InorganicPodTransDeath::specifyCursor(Window *viewWindow, const Common::Poin
 class CheeseGirlPod : public RetrieveFromPods {
 public:
 	CheeseGirlPod(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
-	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
-	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation) override;
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
 };
 
 CheeseGirlPod::CheeseGirlPod(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :


Commit: 0b49d9d43dff58d378172668cfe645b97e23993f
    https://github.com/scummvm/scummvm/commit/0b49d9d43dff58d378172668cfe645b97e23993f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Review includes

Changed paths:
    engines/buried/livetext.cpp
    engines/buried/window.h


diff --git a/engines/buried/livetext.cpp b/engines/buried/livetext.cpp
index 5698d9c862..c8cd082e68 100644
--- a/engines/buried/livetext.cpp
+++ b/engines/buried/livetext.cpp
@@ -23,8 +23,8 @@
  *
  */
 
-#include "graphics/font.h"
 #include "graphics/surface.h"
+#include "graphics/font.h"
 
 #include "buried/buried.h"
 #include "buried/gameui.h"
diff --git a/engines/buried/window.h b/engines/buried/window.h
index 7f6c781e05..d25c526675 100644
--- a/engines/buried/window.h
+++ b/engines/buried/window.h
@@ -24,7 +24,7 @@
 #define BURIED_WINDOW_H
 
 #include "common/rect.h"
-#include "common/queue.h"
+#include "common/list.h"
 
 namespace Common {
 struct KeyState;


Commit: d9d0205affadb02e8b7932406ec0aae2c8fe6e59
    https://github.com/scummvm/scummvm/commit/d9d0205affadb02e8b7932406ec0aae2c8fe6e59
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Remove or reword passive-aggressive or insulting comments

Changed paths:
    engines/buried/environ/castle.cpp
    engines/buried/global_flags.h


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index a75907f698..be97ea6579 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -171,7 +171,6 @@ public:
 
 private:
 	bool _timerStarted;
-	//uint32 _startTime;
 	bool _walkthrough;
 };
 
@@ -1141,7 +1140,7 @@ bool SceneViewWindow::checkCustomCastleAICommentDependencies(const Location &com
 		return _globalFlags.cgTRFoundSword == 0;
 	case 36: // If we do not have the key
 		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCopperKey);
-	case 37: // If we have not been in the keep and the hook is in our inventory (clone2727: ????????)
+	case 37: // If we have not been in the keep and the hook is in our inventory
 		return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBloodyArrow);
 	}
 
diff --git a/engines/buried/global_flags.h b/engines/buried/global_flags.h
index 87462223aa..b5ee833b4b 100644
--- a/engines/buried/global_flags.h
+++ b/engines/buried/global_flags.h
@@ -283,16 +283,14 @@ struct GlobalFlags {
 	byte scoreGotRainGodPiece;          // 313
 	byte scoreGotWarGodPiece;           // 314
 	byte scoreCompletedDeathGod;        // 315
-	byte scoreEliminatedAgent3;         // 316 (clone2727 refrains from commenting here)
+	byte scoreEliminatedAgent3;         // 316
 	byte scoreTransportToKrynn;         // 317
 	byte scoreGotKrynnArtifacts;        // 318
 	byte scoreDefeatedIcarus;           // 319
 
-	// clone2727 would like to take time away from his busy schedule
-	// to describe how broken this next section is. This data was modified
-	// between 1.01 and 1.03, without changing the saved game version
-	// field -- just to add the Louvre research boolean. That's really
-	// unacceptable. I'll have the 1.01 offsets in parentheses.
+	// This data was modified between 1.01 and 1.03, without changing
+	// the saved game version field just to add the Louvre research
+	// boolean. The 1.01 offsets are in parentheses.
 	byte scoreResearchINNLouvreReport;  // 320 (---)
 	byte scoreResearchINNHighBidder;    // 321 (320)
 	byte scoreResearchINNAppeal;        // 322 (321)


Commit: 5f3f279f77e9b07678523d165715b96c10276689
    https://github.com/scummvm/scummvm/commit/5f3f279f77e9b07678523d165715b96c10276689
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Added POTFILES

Changed paths:
  A engines/buried/POTFILES


diff --git a/engines/buried/POTFILES b/engines/buried/POTFILES
new file mode 100644
index 0000000000..e0c53f64d2
--- /dev/null
+++ b/engines/buried/POTFILES
@@ -0,0 +1,3 @@
+engines/buried/biochip_view.cpp
+engines/buried/buried.cpp
+engines/buried/saveload.cpp


Commit: 5c7cc7aee812fea554b4d6c4c42c49ad72352eb9
    https://github.com/scummvm/scummvm/commit/5c7cc7aee812fea554b4d6c4c42c49ad72352eb9
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Remove accidentally removed commented out unused class variable

Changed paths:
    engines/buried/environ/castle.cpp


diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index be97ea6579..02adeea789 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -171,6 +171,7 @@ public:
 
 private:
 	bool _timerStarted;
+	//uint32 _startTime;
 	bool _walkthrough;
 };
 


Commit: d1373e86912bb35b5597c514c046e58baa9807b5
    https://github.com/scummvm/scummvm/commit/d1373e86912bb35b5597c514c046e58baa9807b5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Use more consistently SIC_REJECT in inventory item related functions

Changed paths:
    engines/buried/environ/agent3_lair.cpp
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/castle.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/mayan.cpp
    engines/buried/environ/scene_common.cpp


diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index 732e4134e0..bd403e689c 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -788,7 +788,7 @@ int GeneratorCoreAcquire::draggingItem(Window *viewWindow, int itemID, const Com
 
 int GeneratorCoreAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (_currentStatus == 2 && (itemID == kItemGeneratorCore || itemID == kItemBurnedOutCore) && _closedEmpty.contains(pointLocation)) {
 		if (itemID == kItemBurnedOutCore) {
diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index c03a78ee59..7d81d18707 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -1925,7 +1925,7 @@ int CapacitanceToHabitatDoorClosed::draggingItem(Window *viewWindow, int itemID,
 
 int CapacitanceToHabitatDoorClosed::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0; // ???
+		return SIC_REJECT;
 
 	return SIC_REJECT;
 }
@@ -1999,7 +1999,7 @@ int CapacitanceToHabitatDoorOpen::draggingItem(Window *viewWindow, int itemID, c
 
 int CapacitanceToHabitatDoorOpen::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0; // ???
+		return SIC_REJECT;
 
 	if (itemID == kItemMetalBar && ((SceneViewWindow *)viewWindow)->getGlobalFlags().aiCRGrabbedMetalBar == 1) {
 		_staticData.navFrameIndex = 100;
diff --git a/engines/buried/environ/castle.cpp b/engines/buried/environ/castle.cpp
index 02adeea789..d0eaf0811f 100644
--- a/engines/buried/environ/castle.cpp
+++ b/engines/buried/environ/castle.cpp
@@ -251,7 +251,7 @@ KeepInitialWallClimb::KeepInitialWallClimb(BuriedEngine *vm, Window *viewWindow,
 
 int KeepInitialWallClimb::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (_windowRect.contains(pointLocation) && itemID == kItemGrapplingHook) {
 		((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_vm->isDemo() ? 3 : 1);
@@ -509,7 +509,7 @@ int SmithyBench::draggingItem(Window *viewWindow, int itemID, const Common::Poin
 
 int SmithyBench::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (_pan.contains(pointLocation) && itemID == kItemCopperMedallion && _status < 2) {
 		// Did we drop the medallion in the pan?
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index fcad1d2c5b..3107069bd4 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -541,7 +541,7 @@ int WheelAssemblyItemAcquire::mouseUp(Window *viewWindow, const Common::Point &p
 
 int WheelAssemblyItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (_itemID == itemID && !_itemPresent && pointLocation.x >= 0 && pointLocation.y >= 0) {
 		_itemPresent = true;
@@ -660,7 +660,7 @@ int AssembleSiegeCycle::draggingItem(Window *viewWindow, int itemID, const Commo
 
 int AssembleSiegeCycle::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	switch (itemID) {
 	case kItemDriveAssembly:
@@ -787,7 +787,7 @@ int UnlockCodexTowerDoor::draggingItem(Window *viewWindow, int itemID, const Com
 
 int UnlockCodexTowerDoor::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID == kItemBalconyKey && _dropRect.contains(pointLocation)) {
 		// Play the unlocking animation
@@ -868,7 +868,7 @@ int CodexTowerOutsideDoor::draggingItem(Window *viewWindow, int itemID, const Co
 
 int CodexTowerOutsideDoor::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID == kItemMetalBar && _dropRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTUnlockedDoor == 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCTViewedAgent3 == 0) {
 		// Move to the next scene
@@ -1128,7 +1128,7 @@ int CodexTowerGrabHeart::mouseUp(Window *viewWindow, const Common::Point &pointL
 
 int CodexTowerGrabHeart::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID == _itemID && !_itemPresent) {
 		// Redraw the background
@@ -1670,7 +1670,7 @@ int PlaceSiegeCycleOnTrack::draggingItem(Window *viewWindow, int itemID, const C
 
 int PlaceSiegeCycleOnTrack::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID == kItemSiegeCycle && _cycleRect.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().dsCYPlacedSiegeCycle == 0) {
 		_staticData.navFrameIndex = 229;
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 7806d47fe0..54546fe971 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -974,7 +974,7 @@ int EnvironSystemControls::draggingItem(Window *viewWindow, int itemID, const Co
 
 int EnvironSystemControls::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if ((itemID == kItemGenoSingleCart || itemID == kItemEnvironCart || itemID == kItemClassicGamesCart) &&
 			((SceneViewWindow *)viewWindow)->getGlobalFlags().faERCurrentCartridge == 0) {
diff --git a/engines/buried/environ/mayan.cpp b/engines/buried/environ/mayan.cpp
index b087436880..98422b3078 100644
--- a/engines/buried/environ/mayan.cpp
+++ b/engines/buried/environ/mayan.cpp
@@ -63,7 +63,7 @@ PlaceCeramicBowl::PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const L
 
 int PlaceCeramicBowl::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID != kItemCeramicBowl)
 		return SIC_REJECT;
@@ -604,7 +604,7 @@ int GenericCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID,
 
 int GenericCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (!isValidItemToDrop(viewWindow, itemID))
 		return SIC_REJECT;
@@ -832,7 +832,7 @@ int DeathGodCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID,
 
 int DeathGodCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
 		byte &offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
@@ -932,7 +932,7 @@ int WealthGodRopeDrop::draggingItem(Window *viewWindow, int itemID, const Common
 
 int WealthGodRopeDrop::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook)) {
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope = 1;
@@ -1254,7 +1254,7 @@ int ArrowGodHead::droppedItem(Window *viewWindow, int itemID, const Common::Poin
 		return SIC_REJECT;
 
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 1 && _skullRegion.contains(pointLocation)) {
 		((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, 2);
@@ -1694,7 +1694,7 @@ int DeathGodAltar::draggingItem(Window *viewWindow, int itemID, const Common::Po
 
 int DeathGodAltar::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID == kItemPreservedHeart && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 0 && _heartPool.contains(pointLocation)) {
 		((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart = 1;
diff --git a/engines/buried/environ/scene_common.cpp b/engines/buried/environ/scene_common.cpp
index f10344d6d5..230754c03e 100644
--- a/engines/buried/environ/scene_common.cpp
+++ b/engines/buried/environ/scene_common.cpp
@@ -154,7 +154,7 @@ int GenericItemAcquire::mouseDown(Window *viewWindow, const Common::Point &point
 
 int GenericItemAcquire::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
 	if (pointLocation.x == -1 && pointLocation.y == -1)
-		return 0;
+		return SIC_REJECT;
 
 	if (itemID == _itemID && !_itemPresent) {
 		// Redraw the background


Commit: e798795ceef0fbb3ce5e34551a7dce5d6327fca1
    https://github.com/scummvm/scummvm/commit/e798795ceef0fbb3ce5e34551a7dce5d6327fca1
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Make more consistent use of nullptr

Changed paths:
    engines/buried/biochip_right.cpp
    engines/buried/buried.cpp
    engines/buried/complete.cpp
    engines/buried/environ/agent3_lair.cpp
    engines/buried/environ/ai_lab.cpp
    engines/buried/environ/da_vinci.cpp
    engines/buried/environ/future_apartment.cpp
    engines/buried/environ/scene_base.cpp
    engines/buried/frame_window.cpp
    engines/buried/graphics.cpp
    engines/buried/inventory_info.cpp
    engines/buried/inventory_window.cpp
    engines/buried/overview.cpp
    engines/buried/scene_view.cpp
    engines/buried/sound.cpp
    engines/buried/title_sequence.cpp
    engines/buried/video_window.cpp


diff --git a/engines/buried/biochip_right.cpp b/engines/buried/biochip_right.cpp
index e925ed3c81..4b569a2909 100644
--- a/engines/buried/biochip_right.cpp
+++ b/engines/buried/biochip_right.cpp
@@ -44,7 +44,7 @@ namespace Buried {
 BioChipRightWindow::BioChipRightWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
 	_curBioChip = kItemBioChipInterface;
 	_status = 0;
-	_bioChipViewWindow = 0;
+	_bioChipViewWindow = nullptr;
 	_forceHelp = false;
 	_forceComment = false;
 	_jumpInProgress = false;
@@ -103,7 +103,7 @@ bool BioChipRightWindow::destroyBioChipViewWindow() {
 
 	_vm->_sound->timerCallback();
 	delete _bioChipViewWindow;
-	_bioChipViewWindow = 0;
+	_bioChipViewWindow = nullptr;
 	_vm->_sound->timerCallback();
 
 	((GameUIWindow *)_parent)->_sceneViewWindow->bioChipWindowDisplayed(false);
diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 4eb0dfeef2..6379fcbba2 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -49,15 +49,15 @@
 namespace Buried {
 
 BuriedEngine::BuriedEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
-	_gfx = 0;
-	_mainEXE = 0;
-	_library = 0;
-	_sound = 0;
+	_gfx = nullptr;
+	_mainEXE = nullptr;
+	_library = nullptr;
+	_sound = nullptr;
 	_timerSeed = 0;
-	_mainWindow = 0;
-	_focusedWindow = 0;
-	_captureWindow = 0;
-	_console = 0;
+	_mainWindow = nullptr;
+	_focusedWindow = nullptr;
+	_captureWindow = nullptr;
+	_console = nullptr;
 	_pauseStartTime = 0;
 	_yielding = false;
 
diff --git a/engines/buried/complete.cpp b/engines/buried/complete.cpp
index 9a9716fa0b..7f30647f66 100644
--- a/engines/buried/complete.cpp
+++ b/engines/buried/complete.cpp
@@ -57,9 +57,9 @@ CompletionWindow::CompletionWindow(BuriedEngine *vm, Window *parent, GlobalFlags
 	_vm->_sound->setAmbientSound();
 
 	_status = 0;
-	_background = 0;
+	_background = nullptr;
 	_currentSoundEffectID = -1;
-	_gageVideo = 0;
+	_gageVideo = nullptr;
 
 	_rect = Common::Rect(0, 0, 640, 480);
 
@@ -238,7 +238,7 @@ void CompletionWindow::onTimer(uint timer) {
 	case 2:
 		if (!_gageVideo || _gageVideo->getMode() == VideoWindow::kModeStopped) {
 			delete _gageVideo;
-			_gageVideo = 0;
+			_gageVideo = nullptr;
 
 			_status = 3;
 			_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "BITDATA/FUTAPT/ENDING24.BTS" : "BITDATA/FUTAPT/ENDING8.BTS");
@@ -259,7 +259,7 @@ void CompletionWindow::onLButtonUp(const Common::Point &point, uint flags) {
 		if (_background) {
 			_background->free();
 			delete _background;
-			_background = 0;
+			_background = nullptr;
 		}
 
 		invalidateWindow(false);
@@ -277,7 +277,7 @@ void CompletionWindow::onLButtonUp(const Common::Point &point, uint flags) {
 	case 2:
 		if (!_gageVideo || _gageVideo->getMode() == VideoWindow::kModeStopped) {
 			delete _gageVideo;
-			_gageVideo = 0;
+			_gageVideo = nullptr;
 
 			_status = 4;
 			_background = _vm->_gfx->getBitmap(_vm->isTrueColor() ? "BITDATA/FUTAPT/ENDING24.BTS" : "BITDATA/FUTAPT/ENDING8.BTS");
diff --git a/engines/buried/environ/agent3_lair.cpp b/engines/buried/environ/agent3_lair.cpp
index bd403e689c..d27a6f177b 100644
--- a/engines/buried/environ/agent3_lair.cpp
+++ b/engines/buried/environ/agent3_lair.cpp
@@ -514,7 +514,7 @@ TransporterControls::~TransporterControls() {
 
 void TransporterControls::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int TransporterControls::postExitRoom(Window *viewWindow, const Location &newLocation) {
diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 7d81d18707..63ed1e35b6 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -1052,7 +1052,7 @@ ScienceWingPanelInterface::~ScienceWingPanelInterface() {
 
 void ScienceWingPanelInterface::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int ScienceWingPanelInterface::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
@@ -2065,7 +2065,7 @@ CapacitancePanelInterface::~CapacitancePanelInterface() {
 
 void CapacitancePanelInterface::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int CapacitancePanelInterface::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
@@ -2947,7 +2947,7 @@ ScanningRoomNexusDoorCodePad::~ScanningRoomNexusDoorCodePad() {
 
 void ScanningRoomNexusDoorCodePad::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int ScanningRoomNexusDoorCodePad::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
diff --git a/engines/buried/environ/da_vinci.cpp b/engines/buried/environ/da_vinci.cpp
index 3107069bd4..058adf019c 100644
--- a/engines/buried/environ/da_vinci.cpp
+++ b/engines/buried/environ/da_vinci.cpp
@@ -1753,7 +1753,7 @@ AimBallistaAwayFromTower::~AimBallistaAwayFromTower() {
 
 void AimBallistaAwayFromTower::preDestructor() {
 	delete _viewFrameExtractor;
-	_viewFrameExtractor = 0;
+	_viewFrameExtractor = nullptr;
 }
 
 int AimBallistaAwayFromTower::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
@@ -2130,7 +2130,7 @@ AimBallistaToTower::~AimBallistaToTower() {
 
 void AimBallistaToTower::preDestructor() {
 	delete _viewFrameExtractor;
-	_viewFrameExtractor = 0;
+	_viewFrameExtractor = nullptr;
 }
 
 int AimBallistaToTower::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 54546fe971..99d49886b8 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -301,7 +301,7 @@ KitchenUnitAutoChef::~KitchenUnitAutoChef() {
 
 void KitchenUnitAutoChef::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int KitchenUnitAutoChef::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
@@ -400,7 +400,7 @@ KitchenUnitShopNet::~KitchenUnitShopNet() {
 
 void KitchenUnitShopNet::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int KitchenUnitShopNet::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
@@ -672,7 +672,7 @@ KitchenUnitPostBox::~KitchenUnitPostBox() {
 
 void KitchenUnitPostBox::preDestructor() {
 	delete _textFont;
-	_textFont = 0;
+	_textFont = nullptr;
 }
 
 int KitchenUnitPostBox::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
diff --git a/engines/buried/environ/scene_base.cpp b/engines/buried/environ/scene_base.cpp
index eccf8f084c..d7c963c35a 100644
--- a/engines/buried/environ/scene_base.cpp
+++ b/engines/buried/environ/scene_base.cpp
@@ -41,7 +41,7 @@ SceneBase::SceneBase(BuriedEngine *vm, Window *viewWindow, const LocationStaticD
 }
 
 int SceneBase::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
-	const Graphics::Surface *newFrame = 0;
+	const Graphics::Surface *newFrame = nullptr;
 
 	if (_frameCycleCount >= 0) {
 		newFrame = ((SceneViewWindow *)viewWindow)->getCycleFrame(_frameCycleCount);
diff --git a/engines/buried/frame_window.cpp b/engines/buried/frame_window.cpp
index 10d005d208..9466924fd7 100644
--- a/engines/buried/frame_window.cpp
+++ b/engines/buried/frame_window.cpp
@@ -52,7 +52,7 @@ namespace Buried {
 
 FrameWindow::FrameWindow(BuriedEngine *vm) : Window(vm, 0) {
 	// Initialize member variables
-	_mainChildWindow = 0;
+	_mainChildWindow = nullptr;
 	_controlDown = false;
 	_cacheFrames = false;
 	_cycleDefault = true;
@@ -132,7 +132,7 @@ bool FrameWindow::showMainMenu() {
 
 	// If we still have a child window, delete it now
 	delete _mainChildWindow;
-	_mainChildWindow = 0;
+	_mainChildWindow = nullptr;
 
 	_vm->_sound->restart();
 
@@ -161,7 +161,7 @@ bool FrameWindow::returnToMainMenu() {
 
 	// If we still have a child window, delete it now
 	delete _mainChildWindow;
-	_mainChildWindow = 0;
+	_mainChildWindow = nullptr;
 
 	// Create and show the main menu window
 	if (_vm->isDemo()) {
@@ -205,7 +205,7 @@ bool FrameWindow::showClosingScreen() {
 
 	// If we still have a child window, delete it now
 	delete _mainChildWindow;
-	_mainChildWindow = 0;
+	_mainChildWindow = nullptr;
 
 	// Create the window
 	_mainChildWindow = new TitleSequenceWindow(_vm, this);
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 70f428f2a6..b9899f6c45 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -62,7 +62,7 @@ GraphicsManager::GraphicsManager(BuriedEngine *vm) : _vm(vm) {
 
 	if (_vm->isTrueColor()) {
 		// No palette to deal with
-		_palette = 0;
+		_palette = nullptr;
 	} else {
 		// Grab the palette from our EXE bitmap
 		_palette = createDefaultPalette();
@@ -199,7 +199,7 @@ Graphics::Font *GraphicsManager::createArialFont(int size, bool bold) const {
 	// Enable code page mapping only if we don't have iconv. Otherwise, we'll
 	// let that handle mapping for us.
 #ifdef USE_ICONV
-	static const uint32 *codePageMapping = 0;
+	static const uint32 *codePageMapping = nullptr;
 #else
 	static const uint32 *codePageMapping = s_codePage1252;
 #endif
@@ -232,8 +232,8 @@ Cursor GraphicsManager::setCursor(Cursor newCursor) {
 		return _curCursor;
 
 	Cursor oldCursor = _curCursor;
-	Graphics::Cursor *cursor = 0;
-	Graphics::WinCursorGroup *cursorGroup = 0;
+	Graphics::Cursor *cursor = nullptr;
+	Graphics::WinCursorGroup *cursorGroup = nullptr;
 
 	if (newCursor == kCursorArrow) {
 		cursor = Graphics::makeDefaultWinCursor();
@@ -602,10 +602,11 @@ Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *
 	Graphics::Surface *convertedSurface = new Graphics::Surface();
 	convertedSurface->create(frame->w, frame->h, frame->format);
 
-	for (int y = 0; y < frame->h; y++)
+	for (int y = 0; y < frame->h; y++) {
 		for (int x = 0; x < frame->w; x++)
 			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((const byte *)frame->getBasePtr(x, y))];
-
+	}
+	
 	return convertedSurface;
 }
 
@@ -732,7 +733,7 @@ void GraphicsManager::drawEllipse(const Common::Rect &rect, uint32 color) {
 	static const int rows12[12] = { 7, 11, 13, 13, 15, 15, 15, 15, 13, 13, 11, 7 };
 	static const int rows15[15] = { 5, 9, 11, 13, 13, 15, 15, 15, 15, 15, 13, 13, 11, 9, 5 };
 
-	const int *table = 0;
+	const int *table = nullptr;
 	switch (rect.height()) {
 	case 7:
 		table = rows7;
diff --git a/engines/buried/inventory_info.cpp b/engines/buried/inventory_info.cpp
index 8d3bb841fa..c0b493272d 100644
--- a/engines/buried/inventory_info.cpp
+++ b/engines/buried/inventory_info.cpp
@@ -133,7 +133,7 @@ BurnedLetterViewWindow::BurnedLetterViewWindow(BuriedEngine *vm, Window *parent,
 	_curView = 0;
 	_translatedTextResourceID = IDBD_BLETTER_TRANS_TEXT_BASE;
 	_curLineIndex = -1;
-	_preBuffer = 0;
+	_preBuffer = nullptr;
 
 	_rect = Common::Rect(0, 0, 432, 189);
 
diff --git a/engines/buried/inventory_window.cpp b/engines/buried/inventory_window.cpp
index a446786d69..289a9a5721 100644
--- a/engines/buried/inventory_window.cpp
+++ b/engines/buried/inventory_window.cpp
@@ -43,7 +43,7 @@
 namespace Buried {
 
 InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
-	_background = 0;
+	_background = nullptr;
 	_magSelected = false;
 	_upSelected = false;
 	_downSelected = false;
@@ -51,7 +51,7 @@ InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 	_itemComesFromInventory = false;
 	_draggingObject = false;
 	_draggingItemID = -1;
-	_draggingItemSpriteData.image = 0;
+	_draggingItemSpriteData.image = nullptr;
 	_draggingIconIndex = 0;
 	_draggingItemInInventory = false;
 
@@ -71,8 +71,8 @@ InventoryWindow::InventoryWindow(BuriedEngine *vm, Window *parent) : Window(vm,
 
 	_curItem = 0;
 
-	_infoWindow = 0;
-	_letterViewWindow = 0;
+	_infoWindow = nullptr;
+	_letterViewWindow = nullptr;
 
 	_scrollTimer = 0;
 
@@ -285,7 +285,7 @@ bool InventoryWindow::destroyBurnedLetterWindow() {
 		return false;
 
 	delete _letterViewWindow;
-	_letterViewWindow = 0;
+	_letterViewWindow = nullptr;
 
 	((GameUIWindow *)_parent)->_sceneViewWindow->burnedLetterWindowDisplayed(false);
 
@@ -589,7 +589,7 @@ void InventoryWindow::onLButtonUp(const Common::Point &point, uint flags) {
 				addItem(_draggingItemID);
 		}
 
-		_draggingItemSpriteData.image = 0;
+		_draggingItemSpriteData.image = nullptr;
 		((GameUIWindow *)getParent())->_sceneViewWindow->updatePrebufferWithSprite(_draggingItemSpriteData);
 		_itemComesFromInventory = false;
 
@@ -758,7 +758,7 @@ bool InventoryWindow::destroyInfoWindow() {
 		return false;
 
 	delete _infoWindow;
-	_infoWindow = 0;
+	_infoWindow = nullptr;
 
 	((GameUIWindow *)_parent)->_sceneViewWindow->infoWindowDisplayed(false);
 
diff --git a/engines/buried/overview.cpp b/engines/buried/overview.cpp
index 1fedef87d4..9830be75a0 100644
--- a/engines/buried/overview.cpp
+++ b/engines/buried/overview.cpp
@@ -35,7 +35,7 @@
 namespace Buried {
 
 OverviewWindow::OverviewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
-	_currentImage = 0;
+	_currentImage = nullptr;
 	_currentStatus = -1;
 	_timer = 0xFFFFFFFF;
 
@@ -119,7 +119,7 @@ void OverviewWindow::onTimer(uint timer) {
 	if (_currentImage) {
 		_currentImage->free();
 		delete _currentImage;
-		_currentImage = 0;
+		_currentImage = nullptr;
 	}
 
 	// Switch on the current status in order to determine which action to take next
diff --git a/engines/buried/scene_view.cpp b/engines/buried/scene_view.cpp
index 7f8586e055..016029764b 100644
--- a/engines/buried/scene_view.cpp
+++ b/engines/buried/scene_view.cpp
@@ -46,17 +46,17 @@
 namespace Buried {
 
 SceneViewWindow::SceneViewWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
-	_currentScene = 0;
-	_preBuffer = 0;
-	_walkMovie = 0;
+	_currentScene = nullptr;
+	_preBuffer = nullptr;
+	_walkMovie = nullptr;
 	_useScenePaint = true;
 	_timer = 0;
-	_currentSprite.image = 0;
+	_currentSprite.image = nullptr;
 	_useSprite = true;
 	_infoWindowDisplayed = false;
 	_bioChipWindowDisplayed = false;
 	_burnedLetterDisplayed = false;
-	_asyncMovie = 0;
+	_asyncMovie = nullptr;
 	_asyncMovieStartFrame = 0;
 	_loopAsyncMovie = false;
 	_paused = false;
@@ -370,7 +370,7 @@ bool SceneViewWindow::jumpToScene(const Location &newLocation) {
 	if (_currentScene) {
 		_currentScene->preDestructor();
 		delete _currentScene;
-		_currentScene = 0;
+		_currentScene = nullptr;
 	}
 
 	if (newLocation.timeZone != oldLocation.timeZone || newLocation.environment != oldLocation.environment || oldLocation.timeZone < 0)
@@ -450,7 +450,7 @@ bool SceneViewWindow::jumpToSceneRestore(const Location &newLocation) {
 	if (_currentScene) {
 		_currentScene->preDestructor();
 		delete _currentScene;
-		_currentScene = 0;
+		_currentScene = nullptr;
 	}
 
 	// Change the ambient music
@@ -1045,7 +1045,7 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 
 	changeStillFrameMovie(_vm->getFilePath(destinationStaticData.location.timeZone, destinationStaticData.location.environment, SF_STILLS));
 
-	Graphics::Surface *newBackground = 0;
+	Graphics::Surface *newBackground = nullptr;
 	if (destinationStaticData.navFrameIndex >= 0)
 		newBackground = getStillFrameCopy(navFrame);
 
@@ -1090,7 +1090,7 @@ bool SceneViewWindow::videoTransition(const Location &location, DestinationScene
 bool SceneViewWindow::walkTransition(const Location &location, const DestinationScene &destinationData, int navFrame) {
 	_paused = true;
 	TempCursorChange cursorChange(kCursorWait);
-	Graphics::Surface *newBackground = 0;
+	Graphics::Surface *newBackground = nullptr;
 
 	if (navFrame >= 0) {
 		changeStillFrameMovie(_vm->getFilePath(destinationData.destinationScene.timeZone, destinationData.destinationScene.environment, SF_STILLS));
@@ -1771,7 +1771,7 @@ bool SceneViewWindow::stopAsynchronousAnimation() {
 	_currentScene->movieCallback(this, _asyncMovie, 0, MOVIE_STOPPED);
 
 	delete _asyncMovie;
-	_asyncMovie = 0;
+	_asyncMovie = nullptr;
 	_asyncMovieFileName.clear();
 	_asyncMovieStartFrame = 0;
 	_asyncMovieFrameCount = 0;
@@ -1828,7 +1828,7 @@ bool SceneViewWindow::startPlacedAsynchronousAnimation(int left, int top, int wi
 
 	if (_walkMovie) {
 		delete _walkMovie;
-		_walkMovie = 0;
+		_walkMovie = nullptr;
 		_walkMovieFileName.clear();
 	}
 
@@ -1837,7 +1837,7 @@ bool SceneViewWindow::startPlacedAsynchronousAnimation(int left, int top, int wi
 	if (animDatabase.empty())
 		return false;
 
-	const AnimEvent *animData = 0;
+	const AnimEvent *animData = nullptr;
 
 	for (uint i = 0; i < animDatabase.size() && !animData; i++)
 		if (animDatabase[i].animationID == animationID)
@@ -1887,7 +1887,7 @@ bool SceneViewWindow::startPlacedAsynchronousAnimation(int left, int top, int wi
 
 	if (_walkMovie) {
 		delete _walkMovie;
-		_walkMovie = 0;
+		_walkMovie = nullptr;
 		_walkMovieFileName.clear();
 	}
 
@@ -1932,7 +1932,7 @@ bool SceneViewWindow::startPlacedAsynchronousAnimationExtern(int left, int top,
 
 	if (_walkMovie) {
 		delete _walkMovie;
-		_walkMovie = 0;
+		_walkMovie = nullptr;
 		_walkMovieFileName.clear();
 	}
 
@@ -2315,7 +2315,7 @@ bool SceneViewWindow::checkForAIComment(const Location &commentLocation, int com
 bool SceneViewWindow::infoWindowDisplayed(bool flag) {
 	if (flag && !_walkMovie) {
 		delete _walkMovie;
-		_walkMovie = 0;
+		_walkMovie = nullptr;
 		_walkMovieFileName.clear();
 		changeCycleFrameMovie();
 	}
@@ -2337,7 +2337,7 @@ bool SceneViewWindow::infoWindowDisplayed(bool flag) {
 bool SceneViewWindow::bioChipWindowDisplayed(bool flag) {
 	if (flag && !_walkMovie) {
 		delete _walkMovie;
-		_walkMovie = 0;
+		_walkMovie = nullptr;
 		_walkMovieFileName.clear();
 		changeCycleFrameMovie();
 	}
@@ -2359,7 +2359,7 @@ bool SceneViewWindow::bioChipWindowDisplayed(bool flag) {
 bool SceneViewWindow::burnedLetterWindowDisplayed(bool flag) {
 	if (flag && !_walkMovie) {
 		delete _walkMovie;
-		_walkMovie = 0;
+		_walkMovie = nullptr;
 		_walkMovieFileName.clear();
 		changeCycleFrameMovie();
 	}
diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index eb27841fe7..defdab64f6 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -680,8 +680,8 @@ void SoundManager::timerCallback() {
 }
 
 SoundManager::Sound::Sound() {
-	_soundData = 0;
-	_handle = 0;
+	_soundData = nullptr;
+	_handle = nullptr;
 
 	_volume = 127;
 	_loop = false;
@@ -749,7 +749,7 @@ bool SoundManager::Sound::stop() {
 
 	g_system->getMixer()->stopHandle(*_handle);
 	delete _handle;
-	_handle = 0;
+	_handle = nullptr;
 	return true;
 }
 
diff --git a/engines/buried/title_sequence.cpp b/engines/buried/title_sequence.cpp
index 77d2fe43c4..b67e8a5479 100644
--- a/engines/buried/title_sequence.cpp
+++ b/engines/buried/title_sequence.cpp
@@ -36,8 +36,8 @@ namespace Buried {
 
 TitleSequenceWindow::TitleSequenceWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent) {
 	// Initialize member variables
-	_currentBackground = 0;
-	_currentMovie = 0;
+	_currentBackground = nullptr;
+	_currentMovie = nullptr;
 	_exitNow = false;
 	_currentAnimation = 0;
 
@@ -72,7 +72,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 
 		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_SW_LOGO_FILENAME))) {
 			delete _currentMovie;
-			_currentMovie = 0;
+			_currentMovie = nullptr;
 			((FrameWindow *)_parent)->returnToMainMenu();
 			return false;
 		}
@@ -91,7 +91,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 
 		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_PRESTO_LOGO_FILENAME))) {
 			delete _currentMovie;
-			_currentMovie = 0;
+			_currentMovie = nullptr;
 			((FrameWindow *)_parent)->returnToMainMenu();
 			return false;
 		}
@@ -109,7 +109,7 @@ bool TitleSequenceWindow::playTitleSequence() {
 
 		if (!_currentMovie->openVideo(_vm->getFilePath(IDS_TITLE_MOVIE_FILENAME))) {
 			delete _currentMovie;
-			_currentMovie = 0;
+			_currentMovie = nullptr;
 			((FrameWindow *)_parent)->returnToMainMenu();
 			return false;
 		}
@@ -161,11 +161,11 @@ void TitleSequenceWindow::onTimer(uint timer) {
 		if (_currentBackground) {
 			_currentBackground->free();
 			delete _currentBackground;
-			_currentBackground = 0;
+			_currentBackground = nullptr;
 		}
 
 		delete _currentMovie;
-		_currentMovie = 0;
+		_currentMovie = nullptr;
 
 		// Clean out the input queue
 		_exitNow = false;
diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index ed42f11572..cb581c2a46 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -33,7 +33,7 @@ namespace Buried {
 VideoWindow::VideoWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent), _video(0), _mode(kModeClosed), _lastFrame(0) {
 	_vm->addVideo(this);
 	_needsPalConversion = false;
-	_ownedFrame = 0;
+	_ownedFrame = nullptr;
 }
 
 VideoWindow::~VideoWindow() {
@@ -125,14 +125,14 @@ bool VideoWindow::openVideo(const Common::String &fileName) {
 void VideoWindow::closeVideo() {
 	if (_video) {
 		delete _video;
-		_video = 0;
+		_video = nullptr;
 		_mode = kModeClosed;
-		_lastFrame = 0;
+		_lastFrame = nullptr;
 
 		if (_ownedFrame) {
 			_ownedFrame->free();
 			delete _ownedFrame;
-			_ownedFrame = 0;
+			_ownedFrame = nullptr;
 		}
 	}
 }
@@ -146,7 +146,7 @@ void VideoWindow::updateVideo() {
 				if (_ownedFrame) {
 					_ownedFrame->free();
 					delete _ownedFrame;
-					_ownedFrame = 0;
+					_ownedFrame = nullptr;
 				}
 
 				if (_vm->isTrueColor()) {


Commit: 0acfe12ca333727fc5489407b7f575cd44da8ce4
    https://github.com/scummvm/scummvm/commit/0acfe12ca333727fc5489407b7f575cd44da8ce4
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Remove another aggressive comment

Changed paths:
    engines/buried/environ/future_apartment.cpp


diff --git a/engines/buried/environ/future_apartment.cpp b/engines/buried/environ/future_apartment.cpp
index 99d49886b8..7358e1180f 100644
--- a/engines/buried/environ/future_apartment.cpp
+++ b/engines/buried/environ/future_apartment.cpp
@@ -36,13 +36,6 @@
 
 #include "graphics/font.h"
 
-// For some reason, the Win32 API thinks it's OK to define "_environ" in stdlib.h.
-// I refuse to give in and rename a variable on grounds that Windows is completely
-// wrong, so this shall remain.
-#ifdef WIN32
-#undef _environ
-#endif
-
 namespace Buried {
 
 class OvenDoor : public SceneBase {
@@ -1902,16 +1895,16 @@ public:
 	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
 
 private:
-	Common::Rect _environ;
+	Common::Rect _environRect;
 };
 
 MainEnvironSitDownClick::MainEnvironSitDownClick(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
 		SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
-	_environ = Common::Rect(120, 0, 302, 189);
+	_environRect = Common::Rect(120, 0, 302, 189);
 }
 
 int MainEnvironSitDownClick::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
-	if (_environ.contains(pointLocation)) {
+	if (_environRect.contains(pointLocation)) {
 		DestinationScene newScene;
 		newScene.destinationScene = _staticData.location;
 		newScene.destinationScene.orientation = 1;
@@ -1928,7 +1921,7 @@ int MainEnvironSitDownClick::mouseUp(Window *viewWindow, const Common::Point &po
 }
 
 int MainEnvironSitDownClick::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
-	if (_environ.contains(pointLocation))
+	if (_environRect.contains(pointLocation))
 		return kCursorFinger;
 
 	return kCursorArrow;


Commit: fd3856d4dd5ae3f8ae5f82eb8c15afa3fdce3a4a
    https://github.com/scummvm/scummvm/commit/fd3856d4dd5ae3f8ae5f82eb8c15afa3fdce3a4a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Set pointers to nullptr where applicable

Changed paths:
    engines/buried/video_window.cpp


diff --git a/engines/buried/video_window.cpp b/engines/buried/video_window.cpp
index cb581c2a46..5019dc7a12 100644
--- a/engines/buried/video_window.cpp
+++ b/engines/buried/video_window.cpp
@@ -30,7 +30,7 @@
 
 namespace Buried {
 
-VideoWindow::VideoWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent), _video(0), _mode(kModeClosed), _lastFrame(0) {
+VideoWindow::VideoWindow(BuriedEngine *vm, Window *parent) : Window(vm, parent), _video(nullptr), _mode(kModeClosed), _lastFrame(0) {
 	_vm->addVideo(this);
 	_needsPalConversion = false;
 	_ownedFrame = nullptr;


Commit: 5aab3da1bf5643b90df279dbf4474abdce0cf1a0
    https://github.com/scummvm/scummvm/commit/5aab3da1bf5643b90df279dbf4474abdce0cf1a0
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Added missing override keywords

Changed paths:
    engines/buried/environ/ai_lab.cpp


diff --git a/engines/buried/environ/ai_lab.cpp b/engines/buried/environ/ai_lab.cpp
index 63ed1e35b6..dc27949316 100644
--- a/engines/buried/environ/ai_lab.cpp
+++ b/engines/buried/environ/ai_lab.cpp
@@ -299,8 +299,8 @@ class UseCheeseGirlPropellant : public BaseOxygenTimer {
 public:
 	UseCheeseGirlPropellant(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
-	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
-	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
 
 private:
 	Common::Rect _badPos;
@@ -746,11 +746,11 @@ class IceteroidDispenserControls : public BaseOxygenTimer {
 public:
 	IceteroidDispenserControls(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 	int preExitRoom(Window *viewWindow, const Location &priorLocation) override;
-	int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
-	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
-	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
-	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
-	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
+	int mouseDown(Window *viewWindow, const Common::Point &pointLocation) override;
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
+	int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
+	int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
 
 private:
 	Common::Rect _oxygenHandle;
@@ -1306,8 +1306,8 @@ class NexusDoor : public BaseOxygenTimer {
 public:
 	NexusDoor(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
 	int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
-	int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
-	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
+	int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
+	int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
 
 private:
 	//uint32 _entryStartTime;


Commit: 9c68ab2f43809c4a6d734f5749cac1c6bdddcb6b
    https://github.com/scummvm/scummvm/commit/9c68ab2f43809c4a6d734f5749cac1c6bdddcb6b
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: const'ness

Changed paths:
    engines/buried/metaengine.cpp


diff --git a/engines/buried/metaengine.cpp b/engines/buried/metaengine.cpp
index fdda4525d3..47f07c0326 100644
--- a/engines/buried/metaengine.cpp
+++ b/engines/buried/metaengine.cpp
@@ -114,7 +114,7 @@ SaveStateList BuriedMetaEngine::listSaves(const char *target) const {
 
 void BuriedMetaEngine::removeSaveState(const char *target, int slot) const {
 	// See listSaves() for info on the pattern
-	Common::StringArray fileNames = Buried::BuriedEngine::listSaveFiles();
+	const Common::StringArray &fileNames = Buried::BuriedEngine::listSaveFiles();
 	g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str());
 }
 


Commit: c2d4a39c98866446ab65f128c92d27114b6b76ec
    https://github.com/scummvm/scummvm/commit/c2d4a39c98866446ab65f128c92d27114b6b76ec
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
JANITORIAL: Whitespace fixes

Changed paths:
    engines/buried/sound.cpp


diff --git a/engines/buried/sound.cpp b/engines/buried/sound.cpp
index defdab64f6..8d0c1e47e8 100644
--- a/engines/buried/sound.cpp
+++ b/engines/buried/sound.cpp
@@ -127,7 +127,7 @@ bool SoundManager::setAmbientSound(const Common::String &fileName, bool fade, by
 			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectDelta = -(_soundData[kAmbientIndexBase + _lastAmbient]->_volume / 16);
 			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectStart = g_system->getMillis();
 			_soundData[kAmbientIndexBase + _lastAmbient]->_timedEffectRemaining = 2000;
-	
+
 			// Reset parameters for the current ambient
 			g_system->getMixer()->setChannelVolume(*_soundData[kAmbientIndexBase + _lastAmbient]->_handle,
 					clipVolume(_soundData[kAmbientIndexBase + _lastAmbient]->_volume << 1));
@@ -323,7 +323,7 @@ uint32 SoundManager::getSecondaryAmbientPosition() {
 	// Here's the magic. We're assuming everything is 8-bit, mono.
 	return time.totalNumberOfFrames();
 }
-		
+
 bool SoundManager::restartSecondaryAmbientSound() {
 	int ambientTrack = (_lastAmbient == 0) ? 1 : 0;
 
@@ -514,7 +514,7 @@ bool SoundManager::adjustSoundEffectSoundVolume(int effectID, byte newVolumeLeve
 	// Return success
 	return true;
 }
-	
+
 bool SoundManager::playInterfaceSound(const Common::String &fileName) {
 	if (_paused)
 		return false;
@@ -538,7 +538,7 @@ bool SoundManager::playInterfaceSound(const Common::String &fileName) {
 bool SoundManager::stopInterfaceSound() {
 	if (_paused)
 		return false;
-			
+
 	// Stop the sound
 	delete _soundData[kInterfaceIndex];
 	_soundData[kInterfaceIndex] = new Sound();
@@ -571,7 +571,7 @@ bool SoundManager::startFootsteps(int footstepsID) {
 
 		// Load the footsteps sample data and modify the internal flags
 		_soundData[kFootstepsIndex]->load(_vm->getFilePath(IDS_FOOTSTEPS_FILENAME_BASE + footstepsID));
-    	_soundData[kFootstepsIndex]->_loop = true;
+		_soundData[kFootstepsIndex]->_loop = true;
 	}
 
 	// Play the footsteps
@@ -591,7 +591,7 @@ bool SoundManager::stopFootsteps() {
 	// Return success
 	return true;
 }
-	
+
 bool SoundManager::stop() {
 	if (_paused)
 		return true;
@@ -611,7 +611,7 @@ bool SoundManager::stop() {
 	_paused = true;
 	return true;
 }
-	
+
 bool SoundManager::restart() {
 	if (!_paused)
 		return true;
@@ -648,8 +648,8 @@ void SoundManager::timerCallback() {
 
 					// Update the start time, step counter, and remaining time
 					_soundData[i]->_timedEffectRemaining -= (_soundData[i]->_timedEffectRemaining / _soundData[i]->_timedEffectSteps);
-	                _soundData[i]->_timedEffectStart = g_system->getMillis();
-	                _soundData[i]->_timedEffectSteps--;
+					_soundData[i]->_timedEffectStart = g_system->getMillis();
+					_soundData[i]->_timedEffectSteps--;
 
 					// If the effect has finished, then remove the transition type
 					if (_soundData[i]->_timedEffectSteps == 0) {
@@ -658,7 +658,7 @@ void SoundManager::timerCallback() {
 							delete _soundData[i];
 							_soundData[i] = new Sound();
 						}
-	
+
 						// Reset effect data
 						_soundData[i]->_timedEffectIndex = TIMED_EFFECT_NONE;
 						_soundData[i]->_flags = 0;


Commit: 78c7324f92ee79d5bdf1b3ab9782ed7ba2e71130
    https://github.com/scummvm/scummvm/commit/78c7324f92ee79d5bdf1b3ab9782ed7ba2e71130
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Marked engine as highres

Changed paths:
    engines/buried/configure.engine


diff --git a/engines/buried/configure.engine b/engines/buried/configure.engine
index 1cf7cbdad0..77bde3cdeb 100644
--- a/engines/buried/configure.engine
+++ b/engines/buried/configure.engine
@@ -1,3 +1,3 @@
 # This file is included from the main "configure" script
 # add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
-add_engine buried "The Journeyman Project 2: Buried in Time" no "" "" "freetype2"
+add_engine buried "The Journeyman Project 2: Buried in Time" no "" "" "highres freetype2"


Commit: 048950f73b8964a99f82783aa92637d00a2ec51f
    https://github.com/scummvm/scummvm/commit/048950f73b8964a99f82783aa92637d00a2ec51f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Remove unneeded includes

Changed paths:
    engines/buried/graphics.cpp


diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index b9899f6c45..4fc4ba46c4 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -28,9 +28,6 @@
 #ifdef USE_ICONV
 #include "common/iconv.h"
 #endif
-#ifdef MACOSX
-#include "common/macresman.h"
-#endif
 #include "common/str-array.h"
 #include "common/system.h"
 #include "common/unzip.h"
@@ -606,7 +603,7 @@ Graphics::Surface *GraphicsManager::remapPalettedFrame(const Graphics::Surface *
 		for (int x = 0; x < frame->w; x++)
 			*((byte *)convertedSurface->getBasePtr(x, y)) = palMap[*((const byte *)frame->getBasePtr(x, y))];
 	}
-	
+
 	return convertedSurface;
 }
 


Commit: 9903913859120b0d0595ad82a093b87fc6e400d5
    https://github.com/scummvm/scummvm/commit/9903913859120b0d0595ad82a093b87fc6e400d5
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-03-22T00:07:45+01:00

Commit Message:
BURIED: Remove obsolete comment

Changed paths:
    engines/buried/buried.cpp
    engines/buried/graphics.cpp


diff --git a/engines/buried/buried.cpp b/engines/buried/buried.cpp
index 6379fcbba2..5f7e37da47 100644
--- a/engines/buried/buried.cpp
+++ b/engines/buried/buried.cpp
@@ -92,15 +92,10 @@ Common::Error BuriedEngine::run() {
 #endif
 
 	if (isTrueColor()) {
-#ifndef USE_RGB_COLOR
-		// Can't play 24bpp version without support
-		return Common::kUnsupportedColorMode;
-#else
 		initGraphics(640, 480, 0);
 
 		if (_system->getScreenFormat().bytesPerPixel == 1)
 			return Common::kUnsupportedColorMode;
-#endif
 	} else {
 		initGraphics(640, 480);
 	}
diff --git a/engines/buried/graphics.cpp b/engines/buried/graphics.cpp
index 4fc4ba46c4..8fe21ee730 100644
--- a/engines/buried/graphics.cpp
+++ b/engines/buried/graphics.cpp
@@ -248,8 +248,6 @@ Cursor GraphicsManager::setCursor(Cursor newCursor) {
 	if (!cursor)
 		error("Failed to find cursor %d", newCursor);
 
-	// TODO: Fallback mode for platforms without cursor palettes in 8bpp mode?
-
 	CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(),
 			cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
 	CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());




More information about the Scummvm-git-logs mailing list