[Scummvm-cvs-logs] scummvm master -> c6033e046751c1699c600252d756218220ff484a

sev- sev at scummvm.org
Tue Aug 12 08:20:51 CEST 2014


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

Summary:
2141c99b59 CGE2: Initial commit, implement detection.
b429e746a7 CGE2: Remove detection of Sfinx from CGE1.
aad77304a8 CGE2: Add copyright comments to the source files.
b58965e4e6 CGE2: Add file I/O.
d9e0e882b7 CGE2: Deallocate _resman in destructor.
258d7ea535 CGE2: Implement deinitialization properly.
ec71f93628 CGE2: Add parts of the graphics code.
5b105566a5 Merge remote-tracking branch 'origin/master' into cge2
8e3bbbea7c CGE2: Add sound code with working MIDI parts.
b595d9ee0a CGE2: Add Text and a reduced skeleton of cge2_main.
a0c5805c8e CGE2: Read identifiers properly in Text::load().
0cbed1f53b CGE2: Start implementation of movie() and connected functions.
e3c4caabfa CGE2: Make number() static, add token() to File I/O.
a3b274ba62 CGE2: Add new types: V2D and V3D.
5c8d9241aa CGE2: Use nullptrs instead of NULLs.
42f3dd6d2b CGE2: Some renaming in V3D and V2D.
fbb1a8da93 CGE2: Rework loadScript(), start implementation of loadSprite().
72cccb8000 CGE2: Add Hero.
12a9d0a759 CGE2: Add kIdTab and _lineCount to EncryptedStream.
d12e25ccd0 CGE2: Remove unnecessary whitespaces.
9ffdff5392 CGE2: Implement EncryptedStream::ident().
b674ab2a09 CGE2: Further implement loadSprite(), fix compilation error.
cb65489197 CGE2: Implement CGE2Engine::loadSprite().
09b4092d53 CGE2: Remove Polish comments form SNCom.
c75c026df8 CGE2: Reimplement constructors of Sprite.
724899fc19 CGE2: Rework Sprite a bit, make _eye an engine variable.
3af6ff5457 CGE2: Implement Sprite::gotoxyz().
89bece4b42 CGE2: Implement ~Sprite().
49d7852792 CGE2: Add Spare.
18182d5d2b CGE2: Spare: store pointers instead of objects.
631e9ef37e CGE2: Fix Spare.
6aead2cb03 CGE2: Add destructor to Spare.
0fbdbd8272 CGE2: Rename take() to locate().
d7c5465309 CGE2: Rename make() to store().
6e50915254 CGE2: Finish implementation of loadScript().
86c4e8336d CGE2: Add caveUp() and showBak().
2f404690e7 CGE2: Rename Snail to CommandHandler, expand it.
e30296976c CGE2: Instantiate CommandHandler.
c108a18306 CGE2: Make some static functions non-static.
e8148cf1de CGE2: Rework SprExt, stub more functions of Sprite.
78429a7238 CGE2: More revision and stubbing in Sprite.
4ee1ab07ae CGE2: Add a self-not warning to Bitmap.
c202328ecf CGE2: Implement Sprite::setShapeList().
945f12f2ad CGE2: Move setEye()s to CGE2Engine.
b2cbc7cdd1 CGE2: Partially implement loadTab(), then use it.
99c15216c7 CGE2: Add Bitmap::xLatPos().
4e7bcb5f36 CGE2: Fix ShowTitle().
6d7becb1da CGE2: Add newRandom().
365bad47ae CGE2: Move showTitle() from cge2.cpp to cge2_main.cpp.
dc370d4994 CGE2: Partially implement Sprite::expand().
45714a12f1 CGE2: Implement showBak().
b3cdf9ca38 CGE2: Implement loadTab().
cb72489106 CGE2: Fix deinit().
f121349503 CGE2: Further implement caveUp(), add stubbed loadMap().
bb4679672c CGE2: Revise Queue.
997564d1f6 CGE2: Reimplement backShow().
e0d8715306 CGE2: Further implement caveUp(), implement openPocket().
28357ab6cb CGE2: Remove unnecessary call of loadTab(), add TODO to caveUp().
3e97ade388 CGE2: Revise takeCave().
938a2e66c2 CGE2: Implement Spare::dispose(), add Spare::update().
412d30ca33 CGE2: Add release() to BitMap.
47e55f1664 CGE2: Initialize _actions[] in SprExt's constructor.
122db40530 CGE2: Implement Sprite::contract():
5d2f7cd3fd CGE2: Stub openPocket() for now.
6bcbe5e8ba CGE2: Further implement caveUp(), add stub for selectPocket().
57b9a31ac2 CGE2: Add stubbed Font and Talk.
b5931e2050 CGE2: Further implement caveUp(), add stub for busy().
e6229a2596 CGE2: Add Mouse in events.h to further implement caveUp().
63e57b2eb6 CGE2: Fix formatting in general.h.
06ed289509 CGE2: Revise Spare::takeCave().
36534403e3 CGE2: Further implement caveUp().
bf820481b7 CGE2: Implement feedSnail().
8a1b90acaf CGE2: Fix loadSprite().
ba8e801ada CGE2: Implement Sprite::expand().
afa15dd74f CGE2: Add explanation to comment in caveUp().
e98554309d CGE2: Add mainLoop() and handleFrame().
7777a48dab CGE2: Fix caveUp().
c734aa08b1 CGE2: Implement Sprite::show().
02817a7bd5 CGE2: Implement Sprite::hide().
4dcfe4d785 CGE2: Start implementation of CommandHandler.
e2ca4382d8 CGE2: Implement CommandHandler::idle().
947f4b8607 CGE2: Partially implement CommandHandler::runCommand().
eb80080784 CGE2: Some refactoring and fixing regarding runCommand().
0566d095bb CGE2: Partially implement Sprite::step().
9c8c734a3c CGE2: Revise CGE2Engine::tick().
b82a0fa3e5 CGE2: Add isHero().
4cf5c28fee CGE2: Implement snRSeq() and snSeq().
3c86aa288b CGE2: Implement snSound().
0986347b93 CGE2: Adjust the delay times to DOSBox's output.
921385b30c CGE2: Add stub for keyboard handling.
14e3df21ef CGE2: Add stub for System.
54956d8a81 CGE2: Move things around to fix broken compilation of cross-includes.
4e232814d5 CGE2: Implement runGame().
8fa31d1168 CGE2: Comment out calling of the intro animation during testing.
75546134c8 CGE2: Implement loadUser() and loadPos().
43ce991b84 CGE2: Rework loadUser().
62e36f9279 CGE2: Rework EncryptedStream::readLine().
8af90ab6b7 CGE2: Stub out actual use of _infoLine in runGame().
06ae8de156 CGE2: Fix movie().
8f28501e3c CGE2: Remove unnecessary comment from vga13h.cpp.
e6e0847b7b CGE2: Finish implementation of Sprite::setSeq().
566419f3ad CGE2: Implement snHide().
7c73ce5d8b CGE2: Implement snSend().
60825760fd CGE2: Implement snGhost().
2c453f8f66 CGE2: Fix some warnings.
6275f50d80 CGE2: Fix commandStat initialization
8654042d05 CGE2: Silence a warning by adding a safeguard in step()
3035903f6f CGE2: Clarify a STUB warning
7ecb734a6a CGE2: Fix eyetab initialization
bea9e0532e CGE2: Move an unused variable in a STUB clock, initialize it (in the comment). That fixes a warning
8a712c840d CGE2: Fix several signed/unsigned comparisons
5ad4e157e5 CGE2: Silence a warning in runCommand
bb2f8dd68e Merge branch 'master' of https://github.com/scummvm/scummvm into cge2
e34113a94c CGE2: Fix assignments and deinitialization of _eye and _eyeTab.
7e8923f757 CGE2: Add detection for the WIP English translation
82898716cf CGE2: Reimplement Vga::show().
8eb6a4db8b CGE2: Add display of mouse cursor.
ff21b2d5c8 CGE2: Implement Hero::expand(), move Sprite::works()'s stub to hero.cpp.
219f4f6695 CGE2: Implement Hero::setCurrent().
562644db48 CGE2: Remove unnecessary void parameters in Hero.
79ef03801d CGE2: Implement CGE2Eninge::switchHero().
0e62716038 CGE2: Add and use Spare::take().
21513b448f CGE2: Partially implement and use loadGame().
87db3d2d75 CGE2: Add _blinkSprite.
6d73870431 CGE2: Move then implement Sprite::touch().
5d9e31c708 CGE2: Fix rounding error, remove (original) debug code
41f9195f56 CGE2: Fix flags synchronization
46d93eb780 CGE2: Rework style in touch()
7ef509608e CGE2: USe an int for sex instead of a boolean
de8affdec5 CGE2: Silence some gcc warnings
11ebdcb5e0 CGE2: nullify some pointers
160edae77a CGE2: Silence some gcc and cppcheck warnings
aabe883dc2 CGE2: Fix some more GCC warnings
516ad6e843 CGE2: Reduce the scope of some variables
c5072db8fb CGE2: Fix remaining shadowed variables
b6d8e2b247 CGE2: Unstub some code used to move sprites
8d00ce68d5 CGE2: Remove 2 useless stubs
a0aa7df19c CGE2: Remove useless 'void'
58ee44ceb2 CGE2: Remove unnecessary check from Sprite::step().
26b7ecd2ee CGE2: Get rid of _spareQ.
7838852f94 CGE2: Stub buggy part of loadTab().
85d9e9238c CGE2: Remove _m and xShow() from Bitmap, makeXlat() and killXlat() from Sprite.
c6fd9bf8ce CGE2: Remove stub from Vga::update().
f2c0069765 CGE2: Change BitmapPtr *_shpList -> BitmapPtr _shpList.
63a153165a CGE2: Implement Font.
9efb2ef1a9 CGE2: Implement Talk.
152d795b45 CGE2: Implement InfoLine.
97bb1370a3 CGE2: Reimplement the way of handling y coord.
968f24af47 CGE2: Fix coord conversion in EventManager::poll().
23d40712c6 CGE2: Refine implementation of Queue::insert().
acb81c5e74 CGE2: Fully implement caveUp().
bb216eba2f CGE2: Implement System::touch().
0cad1988e4 CGE2: Remove unnecessary variable from System::touch().
f2a1d4f1c8 CGE2: Implement walkTo() and snap() in Hero.
a62e044174 CGE2: Keep on implementing Hero.
9aa80d6d05 CGE2: Implement helper functions connected to Hero.
8c3e63e471 CGE2: Reduce number of unhandled commands (seemingly).
5a7924678a CGE2: Further implement Hero's functions.
5fca8c328c CGE2: Fix stub message in CGE2Engine::mapCross().
cfe03245fa CGE2: Handle kCmdNop correctly.
9afe6bd570 CGE2: Add, implement and use Map.
1d8536e6df CGE2: Replace tab with space.
acbd19bec4 CGE2: Some rework in Map.
ba8bc2e40b CGE2: Rework empty-checks of strings.
93010a8407 CGE2: Implement CGE2Engine::mapCross().
5d80601c06 CGE2: Reduce the scope of a couple of variables, fix style
76fa66fc8c CGE2: Fix endless loop regarding kCmdWait.
63fa2d4906 CGE2: Simplify if-statements.
12c531284b CGE2: Implement a couple of command handling functions.
e10f22b62f CGE2: Move kLineMax to cge2.h.
71b0a4cc69 CGE2: Implement Sprite::labVal().
85c55333b3 CGE2: Handle kCmdSetRef.
5a5fe344a0 CGE2: Implement display of speech bubbles.
45f8bd755c CGE2: Fix code computing distance
207f3c8be2 CGE2: Implement FXP code. Still WIP, loadTab to be fixed
dfc94267d5 CGE2: Get somewhat better values
162c840937 CGE2: Fix FXP initialiation and division operator
6ac5e2cfcf CGE2: Fix initialization of HeroTab.
95c844a035 CGE2: Implement snKill().
2ad2be370e CGE2: Implement Hero::tick().
bad8e7ea26 CGE2: Fix Sprite::ghost and snGhost().
235d0fffbd CGE2: Reimplement Hero::setCave().
3aae5cfa06 CGE2: Implement Hero::hStep().
95e3f240d6 CGE2: Implement Hero::turn().
0bd781a3dc CGE2: Implement releasePocket().
52fb03fc97 CGE2: Fix Sprite::touch().
63c0cb40fe CGE2: Stub snSay again.
2b5eec4427 CGE2: Implement snCover and snUncover.
a2c3a11708 CGE2: Rename setCave() to setScene().
28717ff056 CGE2: Fix vertical screen clipping in Bitmap::show and Bitmap::hide
3d63184fee CGE2: Rethink Spare::dispose().
58c312d9e9 CGE2: Implement snReach() and connected functions.
600c32adf9 CGE2: Implement snWalk().
c48c585f88 CGE2: Fix loading of fixed-point integer values
0f923c7e98 CGE2: Change the Flags structure to make use of booleans
c82246ee55 CGE2: remove useless code related to boolean values
ae96463036 CGE2: Rework EventManager::handleEvents().
baffdd97e2 CGE2: Fix coordinates of mouse handling.
e3b5686c43 CGE2: Rename caves to scenes.
7f4af90777 CGE2: Fix compilation broken by previous commit.
c488c15289 CGE2: Rework Sprite::touch to use V2D for coords.
9023240545 CGE2: Rework show() and hide() in Bitmap to use V2Ds as parameters.
40262bad98 CGE: Remove (broken) variable length specification
186d90e5b5 CGE2: Implement switching between scenes.
26901479d3 CGE2: Fix initialization of _posTab.
fb97e24a5a CGE2: Fix coords of misplaced speech bubbles.
d85d3229e6 CGE2: Implement functions connected to inventory handling.
ea5697d5a0 CGE2: Implement snKeep().
7a549f2693 CGE2: Implement offUse().
d7e70eb5fa CGE2: Implement inf().
535b70934e CGE2: Comment out code and add TODO in switchScene().
56c7df46d3 CGE2: Implement showing the selected item in the inventory.
ff99cb9658 CGE2: Implement Sprite::works().
ea9b4d0729 CGE2: Implement snMouse().
76846bf4f5 CGE2: Implement Hero::fun().
fcd387553f CGE2: Implement optionTouch().
e708c1e5cd CGE2: Implement "quit menu".
7faa95bfdd CGE2: Avoid some signed/unsigned comparisons
f1b14c6d31 CGE2: Reduce the scope of some variables
fc5c92b5d0 CGE2: Implement snGive() and snRmNear().
f36cfb629c CGE2: Fix mapCross().
8ae41648f9 CGE2: Implement snSwap().
af646247f3 CGE2: Remove useless variable declarations
cb3dce698c CGE2: Rework Hero::len().
6015eddc41 CGE2: Remove double definition kMaxTry.
7b628c7ffc CGE2: Fix some formatting in Hero.
c8ed838c05 CGE2: Fix formatting in FXP.
19bc151939 CGE2: Some more formatting fix in FXP.
2226eb0789 CGE2: Implement snSay(), reimplement some parts of the sound code.
23adc159ef CGE2: Implement busy() and revise connected parts of the engine.
0eece817eb CGE2: Fix releasePocket().
840eef8eb1 CGE2: Add a big hack to work around the coordinates issue
3dd6c9f7aa CGE2: Implement a couple of stubs
2bc35f6f6d CGE2: Add a work around for missing VBM in scene 4
384f1b664b CGE2: Implement snMidi()
00c867f8ea CGE2: Add a safeguard in Sprite::show()
014d6bd9f0 CGE2: Hopefully fix compilation for GCC
e9396f8d10 CGE2: Fix some GCC warnings
b08b3eac33 CGE2: Add a virtual destructor in Choice, some minor cleanup
723bdc12ad CGE2: Make Hero's expand() and contract() virtual.
2514d86630 CGE2: Implement Sprite::step() fully.
6f2e4a76cc CGE2: Add workaround for badly named VBM file in room 11
69c8871c3f CGE2: Silence GCC warning in Hero::tick().
f69ee470ed CGE2: Rework FXP::Joined().
2f80cf6faf CGE2: Fix formatting of FXP's operators.
160212c8e3 CGE2: Add fallback detection for the currently WIP English translation.
38a59bee3e CGE2: Add skeleton for save/load system.
b6d4281917 CGE2: Call loadPos() from loadHero() instead of loadUser().
ade740de10 CGE2: Implement saving.
7810df976b CGE2: Rework Hero::expand() so it won't modify Text's content.
b48c94a541 CGE2: Fix GCC warning
1305bc8aa8 CGE2: Add, implement and use saveHeroPos().
b9dc93c451 CGE2: Heavily rework memory management of Sprites.
aeaac02332 CGE2: Silence warning.
f155546ecb CGE2: Partially working save/load system.
927be46c87 CGE2: Remove unnecessary parameter from Spare::sync().
ddf4f4598d CGE2: Rename saveHeroPos() to storeHeroPos().
dbbafb5d89 CGE2: Rename and heavily rework Bitmap::forceExt().
a3071a00f9 CGE2: Replace addExt() wit setExtension().
07fa483142 CGE2: Fix broken compilation by previous commit.
8b8216bf2c CGE2: Fully implement the save/load system.
31bba2e38c CGE2: Remove unnecessary warning and debug info from showTitle().
e15f40978a CGE2: Implement loading from the Launcher.
21a4c44bea CGE2: Add extra clipping to Bitmap::hide
c5855b4293 CGE2: Add workaround for the missing dialogs in room 21 (concert)
c7aa91019b CGE2: Replace NULL with nullptr everywhere.
1335247f82 CGE2: Hopefully fix memory leak problems regarding _ext.
10a37ea478 CGE2: Fix Hero::setCurrent().
be5ec466b3 CGE2: Fix another probable memory-leak source.
3935a427f9 CGE2: Add extra clipping to Bitmap::hide
a73aea1ce8 CGE2: Fix GCC warning, rewrite Text::clear()
b75d308697 CGE2: Rework CGE2Engine::locate().
ffbed9f86d CGE2: Comment out Hero::contract() for now.
d0a6fa4ce2 CGE2: Implement switchColorMode().
45da1e7c74 CGE2: Implement switchVox() and switchCap().
5a1383343f CGE2: Rework number().
c1bda3c973 CGE2: Remove unnecessary stub from run().
8f869c74c0 CGE2: Add option for enabling color blind mode from the Launcher.
2f8abb06c3 CGE2: Implement Sound::open(), add stub for checkSaySwitch().
3dc79442c9 CGE2: Fix Sound::open().
ec88528080 CGE2: Remove unnecessary stub from cge2_main().
55f91da1ee CGE2: Remove unused local variable from loadScript().
dbea97b7c4 CGE2: Remove unnecessary stub from loadHeroes().
dc2330a3b1 CGE2: Implement the keyboard handler
1be1ce6117 CGE2: Set widespace for Inf text, update first line of info text in CGE.SAY
f57d2ff4d6 CGE2: Remove unnecessary stub from Keyboard's constructor.
fcce50e6fe CGE2: Hook handling of F10 into the Keyboard::getKey().
4d2c1315ac CGE2: Silence a GCC warning, reduce the scope of a variable
89295b7895 CGE2: Remove unnecessary comment from ~Vga().
b941fe226d CGE2: Unstub movie().
807f354cba CGE2: Remove unused classes from vga13h.
2f8967d959 CGE2: Unstub showTitle().
753b5f89ba CGE2: Unstub CommandHandler::reset().
035fb6ad1c CGE2: Hopefully fix a memory leak problem regarding Hero::_dim;
470736b9c4 CGE2: Remove unnecessary comment from sceneUp().
8861b0b583 CGE2: Get rid of _mode.
d947167931 CGE2: Fix the intro animation.
8fae34df05 CGE2: Implement snRoom().
fbd8f2c390 CGE2: Some rework in snail
0b0f998aac CGE2: Try a different approach regarding _dim.
7d6c02ce3f CGE2: Add Hero::contract().
20eb951b3a CGE2: Rework getText() so it works nicely with offUse().
a82bd2d9c6 CGE2: Fix memory leak regarding Sprite::ghost().
d9e82f8f8e CGE2: Get rid of _sprite.
2203b7df8c CGE2: Smaller revision regarding Spare.
5e780d3d97 CGE2: Use locate() instead of take() where possible.
49cea2d927 CGE2: Initialize _wideSpace in InfoLine's constructor.
5963a540ef CGE2: Add destructor to Hero().
f3345f296f CGE2: Use locate instead() of take() in CGE2Eninge::locate().
c285d3299c CGE2: Silence GCC warnings.
db9e503cfc CGE2: Rework snSetRef().
1176721034 CGE2: Fix the issue of loading sprites with changed _ref.
6e26422468 CGE2: Rework loading of sprites from file.
bac952917f CGE2: Remove Spare::locate(char *file), since it's not used anymore.
77b5c7e4ad CGE2: Rename _commandStat to _soundStat.
e261886d92 CGE2: Fix snSound().
2f19de9ebe CGE2: Fix error introduced by previous commit.
def6b4fc3e CGE2: Add and use Sound::checkSoundHandle().
aa6b4601d7 CGE2: Change call order of checkSoundHandle().
848b2650e9 CGE2: Unstub CommandHandler::runCommand().
49f68a8913 CGE2: Reimplement checkSaySwitch().
93b8f101c3 CGE2: Implement switchMusic():
2f5e115e9a CGE2: Use nullptr instead of NULL in switchColorMode().
71a9ead967 CGE2: Add and implement checkSounds() and checkMusicSwitch().
b15b1043f9 CGE2: Updgrade checkSaySwitch().
4c3bd3e0f5 CGE2: Add MidiPlayer::syncVolume() call to checkSounds().
6336ddb3ce CGE2: Keep music setting in sync with the Launcher.
014b734c98 CGE2: Increase readability of code connected to music switch.
cd8b7c0d15 CGE2: Move toolbar's functions from cge2_main.cpp to toolbar.cpp.
a6eb089033 CGE2: Move inventory system's functions from cge2_main.cpp to inventory.cpp.
755fedcceb CGE2: Set speech only/text only/both modes according to Launcher options.
24cc8a8762 CGE2: Implement checkSaySwitch() and add/fix connected code.
ff97d52d72 CGE2: Distinguish SFX from speech when playing sounds.
6743b8b6a3 CGE2: Remove redundant default labels.
7c65aa7aec CGE2: Repair/rename checkSoundHandle().
15a2256972 CGE2: Implement snTrans() and snPort().
c843898132 CGE2: Remove handling of unused opcodes.
12210ecf27 CGE2: Remove the unused opcodes.
6caee925df CGE2: Fix typo in SETREF's comment.
42f0440127 CGE2: Remove more unused opcodes.
b85e5dcfdb CGE2: Remove kCmdDim and kCmdStep and connected code.
8a1d046187 CGE2: Fix kCmdWalk's comment.
737fc953a4 CGE2: Rearrange _commandText[]'s content.
d83a8162bb CGE2: Remove unused constant in Talk, fix a warning
72c8dbaf66 CGE2: Update another warning
3c0665edfa CGE2: Rework loadUser().
aaf1f6a1a0 CGE2: Fix initialization of sound switches on the toolbar.
22f1207cff CGE2: Rename kSoundSwtichRate  to kVolumeSwitchRate.
98c6bfa0f5 CGE2: Fix broken compilation by previous commit.
9524f1d128 CGE2: Remove useless TODO comment.
668b133dab CGE2: Implement the music volume button on the toolbar.
944465431a CGE2: Implement the sfx volume button on the toolbar.
eaddafdea7 CGE2: Get rid of unnecessary variables.
ac178b6013 CGE2: Fix optionTouch().
62e0a32a90 CGE2: Repair checkVolumeSwitches().
8a9a088b31 CGE2: Fix optionTouch().
870349078e CGE2: Refactor optionTouch().
85909a52e4 CGE2: Refactor optionTouch().
266f1c7dee Revert "CGE2: Refactor optionTouch()."
5861b963ed CGE2: Now refactor optionTouch() the right way.
56da652e8f CGE2: Rearrange things a bit in cge2.h.
88286115c8 CGE2: More refactoring in cge2.h and cge2.cpp.
6ac879270f CGE2: Repair display of version and translation strings.
8d21a21b63 CGE2: Change random source.
c78596a80e CGE2: Remove another unused opcode.
0bfde974cd CGE2: Implement debug console and add a debug channel for opcodes.
8e28a2c0d0 CGE2: Make the debug channel of the opcodes more verbose.
c394a68589 CGE2: Fix misleading tabulation, improve warning
73784c26b7 CGE2: Add work around for piram_/pirami issue
ab2f720f37 CGE2: Remove commas at the end of enumerator lists.
cc7a70d967 CGE2: Use if-else instead of switch-case with boolean values.
b9d13ae41d CGE2: Get rid of unused variables in Bitmap.
fe77bfecf7 CGE2: Rename Bitmap::paint() to makeSpeechBubleTail().
ae4adf4a9f CGE2: Move implementation of Console into a .cpp file.
fca11e77f8 CGE2: Get rid of more unused variables.
b911b66cc4 CGE2: Keep in sync the in-game color blind option with the Launcher's.
db6cab7a6f CGE2: Repair loading from savestate.
dd1637af9f CGE2: Fix initialization of Mouse.
f538660c15 CGE2: Fix graphic glitch at closing the game.
d95a4c5f72 CGE2: Get rid of _flag.
5016e09acf CGE2: Don't bother with  saving/loading sound options.
d4e14253c4 CGE2: Implement snFlash().
df59c0d0f6 CGE2: Remove not useful comment from switchScene().
77610ad993 CGE2: Get rid of kCrackedText.
3d69c67f99 CGE2: Get rid of kExitOkText.
70f54c6609 CGE2: Remove unused code.
375a7c3b15 CGE2: Implement snCycle, add stub for Vga::rotate().
e828be1bf9 CGE2: Initialize Vga::_rot properly.
6e00d80b4b CGE2: Implement Vga::rotate().
95854c3a57 CGE2: Get rid of sndSetVolume() and connected code.
cee669e763 CGE2: Implement setAutoColors().
800ff40219 CGE2: Move ColorBank and kColorNum to one place.
02c0b419d6 CGE2: Remove unnecessary CHECKME comment.
2c5af2ae54 CGE2: Remove unused functions from EncryptedStream.
e51888d9ce CGE2: Refactor Hero::expand() and Sprite::expand().
b33653000d CGE2: Fix saving of moving heroes.
fc8f6d9cfe CGE2: Fix initialization of volume switches.
4e32736e44 CGE2: Prevent the engine from entering an endless loop when loading.
0b8a727a0e CGE2: Repair computation of save checksum.
e5139cdd9c CGE2: Fix loading during gameplay.
4139e79fcc CGE2: Fixes for the FXP class
6b48172ae1 CGE2: Disable checking the sound options while the intro animation is running.
06144cee4b CGE2: Remove dummies from save header and change save checksum.
733f72d810 CGE2: Fix sunset() and sunrise().
6a38671cc2 CGE2: Rearrange showTitle() and add some delay to the display.
6d278157e1 CGE2: Comment out delay in the splash screen during testing.
0d662566bd CGE2: Further fixes to FXP operators to fix pathfinding
c012c762d0 CGE2: Remove moveHi() and moveLo() from bitmap
1a49887855 CGE2: Some cosmetic changes
96ab1d5d83 CGE2: Further FXP multiply fix to fix hero scaling
0eb7e52490 CGE2: Update comment concerning a workaround for a non-fixable issue
3376ab4f62 CGE2: Update the comment about another non-fixable workaround
f2de89c7bc CGE2: Fix CppCheck warnings by reducing variable scope
d44ff54912 CGE2: Fix error message in makeSpeechBubbleTail().
9dc06870e7 CGE2: Start removing the checks on the return value of new
2b60bb9cc3 CGE2: Fix possible null pointer dereference.
6558581d68 CGE2: Remove more checks on the return value of new
239fa2a5cf CGE2: Rename classes representing quit menu choices.
8eae09afca CGE2: Fix memory leak concerning the quit menu.
241d07ff07 CGE2: Silence GCC warning concerning destructors of Choice's children.
00bb645e54 CGE2: Fix mismatched new/delete pair in Sprite::ghost() and snGhost().
61083e5cab CGE2: Add RTL support.
60a77ae6d7 CGE2: Add autosave functionality.
2697c71301 CGE2: Misc cleanup
7dfb2b01f1 CGE2: Rearrange content of saveload.cpp and cge2.h a bit.
41fece6487 CGE2: Remove #if 0-s.
b8b3e5af04 CGE2: Some more minor cleanup
07fc3fb3c3 CGE2: Some repair in Bitmap::code().
11d2cf66b6 CGE2: Rework the handling of the sound buttons on the toolbar.
69b9a3fdff CGE2: Properly fade out if the player exits during the intro too.
010a806a19 CGE2: Rework canSaveGameStateCurrently().
59bc45e79f CGE2: Get rid of _keyAlt.
895f8a5e59 CGE2: Remove commented out code from text.cpp.
58822b47a7 CGE2: Use spaces instead of tabs.
0ea1268940 CGE2: Fix canSaveGameStateCurrently().
01950e1b1c CGE2: Remove unused function from vga13h.cpp.
e709be446c CGE2: Remove unnecessary #pragma before Sprite::touch().
1224d79e53 CGE2: Fix typo in detection.cpp.
411e8ac5c8 CGE2: Change return type of readSint16LE().
eb13d6ece1 CGE2: Add necessary tabs in detection.cpp.
854849f57a CGE2: Get rid of detection.h, move things to detection.cpp.
8510152545 CGE2: Rename XCrpyt() to xCrypt().
c3a5a9177b CGE2: Fix comment in runGame().
f8e60e467f CGE2: Make movie() safer.
0d47893d51 CGE2: Make matrixes static constants in makeSpeechBubbleTail().
25ebfe461f CGE2: Remove unnecessary comments from vga13h.h.
7dfd108f68 CGE2: Remove unused functions from V2D.
b3fed6c369 CGE2: Return value instead of reference in FXP's operator=.
5e375d0796 CGE2: Fix formatting of operators' return values in vga13h.h.
9c5bdc6dde CGE2: Fix formatting in bitmap.h.
235e3d396e CGE2: Fix formatting in events.cpp.
3e3430ed5d CGE2: Fix EncryptedStream::err().
02f3418d6f CGE2: Fix some more formatting in vga13h.h.
e488da5757 CGE2: Remove unnecessary commented out code.
ae037b2315 CGE2: Use snprintf() instead of sprintf().
c6033e0467 Merge pull request #488 from urukgit/cge2


Commit: 2141c99b59945401508628bd2701beb08aeb7cf5
    https://github.com/scummvm/scummvm/commit/2141c99b59945401508628bd2701beb08aeb7cf5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-25T16:55:41+02:00

Commit Message:
CGE2: Initial commit, implement detection.

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



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
new file mode 100644
index 0000000..488076f
--- /dev/null
+++ b/engines/cge2/cge2.cpp
@@ -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.
+ *
+ * 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 "cge2/cge2.h"
+
+namespace CGE2 {
+
+CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
+	: Engine(syst), _gameDescription(gameDescription) {
+}
+
+CGE2Engine::~CGE2Engine() {
+}
+
+bool CGE2Engine::hasFeature(EngineFeature f) const {
+	return false;
+}
+
+bool CGE2Engine::canLoadGameStateCurrently() {
+	return false;
+}
+bool CGE2Engine::canSaveGameStateCurrently() {
+	return false;
+}
+
+Common::Error CGE2Engine::loadGameState(int slot) {
+	warning("STUB: CGE2Engine::loadGameState()");
+	return Common::kNoError;
+}
+
+Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
+	warning("STUB: CGE2Engine::saveGameState()");
+	return Common::kNoError;
+}
+
+Common::Error CGE2Engine::run() {
+	warning("STUB: CGE2Engine::run()");
+	return Common::kNoError;
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
new file mode 100644
index 0000000..46aa4a3
--- /dev/null
+++ b/engines/cge2/cge2.h
@@ -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.
+ *
+ * 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 CGE2_H
+#define CGE2_H
+
+#include "engines/engine.h"
+#include "engines/advancedDetector.h"
+
+namespace CGE2 {
+
+class CGE2Engine : public Engine {
+public:
+	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
+	~CGE2Engine();
+	virtual bool hasFeature(EngineFeature f) const;
+	virtual bool canLoadGameStateCurrently();
+	virtual bool canSaveGameStateCurrently();
+	virtual Common::Error loadGameState(int slot);
+	virtual Common::Error saveGameState(int slot, const Common::String &desc);
+	virtual Common::Error run();
+
+	const ADGameDescription *_gameDescription;
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_H
diff --git a/engines/cge2/configure.engine b/engines/cge2/configure.engine
new file mode 100644
index 0000000..6ccbfee
--- /dev/null
+++ b/engines/cge2/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 cge2 "CGE2" no
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
new file mode 100644
index 0000000..96ec1ed
--- /dev/null
+++ b/engines/cge2/detection.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.
+*
+* 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 "cge2/cge2.h"
+#include "engines/advancedDetector.h"
+
+namespace CGE2 {
+
+static const PlainGameDescriptor CGE2Games[] = {
+	{ "sfinx2", "Sfinx" }, // TODO: Remove Sfinx from CGE1 completely, so the two gameIDs won't collide.
+	{ 0, 0 }
+};
+
+static const ADGameDescription gameDescriptions[] = { // TODO: Add ENG version too.
+	{
+		"sfinx", "Sfinx Freeware",
+		{
+			{ "vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024 },
+			{ "vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844 },
+			AD_LISTEND
+		},
+		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+	},
+	
+	AD_TABLE_END_MARKER
+};
+
+class CGE2MetaEngine : public AdvancedMetaEngine {
+public:
+	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games) {
+		_singleid = "sfinx";
+	}
+
+	virtual const char *getName() const {
+		return "CGE2";
+	}
+
+	virtual const char *getOriginalCopyright() const {
+		return "Sfinx (c) 1997 L.K. Avalon";
+	}
+
+	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual bool hasFeature(MetaEngineFeature f) const;
+};
+
+bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	if (desc) {
+		*engine = new CGE2::CGE2Engine(syst, desc);
+	}
+	return desc != 0;
+}
+
+bool CGE2MetaEngine::hasFeature(MetaEngineFeature f) const {
+	return false;
+}
+
+} // End of namespace CGE2
+
+#if PLUGIN_ENABLED_DYNAMIC(CGE2)
+	REGISTER_PLUGIN_DYNAMIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
+#else
+	REGISTER_PLUGIN_STATIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
+#endif
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
new file mode 100644
index 0000000..75f2743
--- /dev/null
+++ b/engines/cge2/module.mk
@@ -0,0 +1,13 @@
+MODULE := engines/cge2
+
+MODULE_OBJS = \
+	cge2.o \
+	detection.o
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk


Commit: b429e746a7ba8f745225952b8a632c5cd9b2f8f0
    https://github.com/scummvm/scummvm/commit/b429e746a7ba8f745225952b8a632c5cd9b2f8f0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-25T17:34:38+02:00

Commit Message:
CGE2: Remove detection of Sfinx from CGE1.

Changed paths:
    engines/cge/cge.h
    engines/cge/detection.cpp
    engines/cge2/detection.cpp



diff --git a/engines/cge/cge.h b/engines/cge/cge.h
index a65069f..c43358f 100644
--- a/engines/cge/cge.h
+++ b/engines/cge/cge.h
@@ -80,12 +80,6 @@ class Talk;
 
 #define kSayTheEnd  41
 
-enum GameType {
-	kGameTypeNone = 0,
-	kGameTypeSoltys,
-	kGameTypeSfinx
-};
-
 // our engine debug channels
 enum {
 	kCGEDebugBitmap = 1 << 0,
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index 4c2f81c..60558f1 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -33,7 +33,6 @@ namespace CGE {
 
 struct CgeGameDescription {
 	ADGameDescription desc;
-	GameType gameType;
 };
 
 #define GAMEOPTION_COLOR_BLIND_DEFAULT_OFF  GUIO_GAMEOPTIONS1
@@ -42,117 +41,81 @@ struct CgeGameDescription {
 
 static const PlainGameDescriptor CGEGames[] = {
 	{ "soltys", "Soltys" },
-	{ "sfinx", "Sfinx" },
 	{ 0, 0 }
 };
 
 namespace CGE {
 
-static const CgeGameDescription gameDescriptions[] = {
-
-	{
-		{
-			"soltys", "",
-			{
-				{"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
-				{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572},
-				AD_LISTEND
-			},
-			Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
-		},
-		kGameTypeSoltys
-	},
+static const ADGameDescription gameDescriptions[] = {
 	{
+		"soltys", "",
 		{
-			"soltys", "Soltys Freeware",
-			{
-				{"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
-				{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676},
-				AD_LISTEND
-			},
-			Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
+			{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437572},
+			AD_LISTEND
 		},
-		kGameTypeSoltys
+		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
 	},
 	{
+		"soltys", "Soltys Freeware",
 		{
-			"soltys", "Soltys Demo (not supported)",
-			{
-				{"vol.cat", 0, "1e077c8ff58109a187f07ac54b0c873a", 18788},
-				{"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710},
-				AD_LISTEND
-			},
-			Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "0c33e2c304821a2444d297fc5e2d67c6", 50176},
+			{"vol.dat", 0, "f9ae2e7f8f7cac91378cdafca43faf1e", 8437676},
+			AD_LISTEND
 		},
-		kGameTypeSoltys
+		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 	{
+		"soltys", "Soltys Demo (not supported)",
 		{
-			"soltys", "Soltys Demo (not supported)",
-			{
-				{"vol.cat", 0, "f17987487fab1ebddd781d8d02fedecc", 7168},
-				{"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272},
-				AD_LISTEND
-			},
-			Common::PL_POL, Common::kPlatformDOS, ADGF_DEMO , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "1e077c8ff58109a187f07ac54b0c873a", 18788},
+			{"vol.dat", 0, "75d385a6074c58b69f7730481f256051", 1796710},
+			AD_LISTEND
 		},
-		kGameTypeSoltys
+		Common::EN_ANY, Common::kPlatformDOS, ADGF_DEMO , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 	{
+		"soltys", "Soltys Demo (not supported)",
 		{
-			"soltys", "Soltys Freeware v1.0",
-			{
-				{"vol.cat", 0, "f1675684c68ab90272f5776f8f2c3974", 50176},
-				{"vol.dat", 0, "4ffeff4abc99ac5999b55ccfc56ab1df", 8430868},
-				AD_LISTEND
-			},
-			Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "f17987487fab1ebddd781d8d02fedecc", 7168},
+			{"vol.dat", 0, "c5d9b15863cab61dc125551576dece04", 1075272},
+			AD_LISTEND
 		},
-		kGameTypeSoltys
+		Common::PL_POL, Common::kPlatformDOS, ADGF_DEMO , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 	{
+		"soltys", "Soltys Freeware v1.0",
 		{
-			"soltys", "Soltys Freeware v1.0",
-			{
-				{"vol.cat", 0, "20fdce799adb618100ef9ee2362be875", 50176},
-				{"vol.dat", 0, "0e43331c846094d77f5dd201827e0a3b", 8439339},
-				AD_LISTEND
-			},
-			Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "f1675684c68ab90272f5776f8f2c3974", 50176},
+			{"vol.dat", 0, "4ffeff4abc99ac5999b55ccfc56ab1df", 8430868},
+			AD_LISTEND
 		},
-		kGameTypeSoltys
+		Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 	{
+		"soltys", "Soltys Freeware v1.0",
 		{
-			"soltys", "Soltys Freeware v1.0",
-			{
-				{"vol.cat", 0, "fcae86b20eaa5cedec17b24fa5e85eb4", 50176},
-				{"vol.dat", 0, "ff10d54acc2c95696c57e05819b6906f", 8450151},
-				AD_LISTEND
-			},
-			Common::ES_ESP, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "20fdce799adb618100ef9ee2362be875", 50176},
+			{"vol.dat", 0, "0e43331c846094d77f5dd201827e0a3b", 8439339},
+			AD_LISTEND
 		},
-		kGameTypeSoltys
+		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 	{
+		"soltys", "Soltys Freeware v1.0",
 		{
-			// Polish version, provided by Strangerke
-			"sfinx", "Sfinx Freeware",
-			{
-				{"vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024},
-				{"vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844},
-				AD_LISTEND
-			},
-			Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+			{"vol.cat", 0, "fcae86b20eaa5cedec17b24fa5e85eb4", 50176},
+			{"vol.dat", 0, "ff10d54acc2c95696c57e05819b6906f", 8450151},
+			AD_LISTEND
 		},
-		kGameTypeSfinx
+		Common::ES_ESP, Common::kPlatformDOS, ADGF_NO_FLAGS , GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 
-	{AD_TABLE_END_MARKER, kGameTypeNone}
+	AD_TABLE_END_MARKER
 };
 
 static const ADFileBasedFallback fileBasedFallback[] = {
-	{ &gameDescriptions[0].desc, { "vol.cat", "vol.dat", 0 } },
+	{ &gameDescriptions[0], { "vol.cat", "vol.dat", 0 } },
 	{ 0, { 0 } }
 };
 } // End of namespace CGE
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 96ec1ed..1243078 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -26,7 +26,7 @@
 namespace CGE2 {
 
 static const PlainGameDescriptor CGE2Games[] = {
-	{ "sfinx2", "Sfinx" }, // TODO: Remove Sfinx from CGE1 completely, so the two gameIDs won't collide.
+	{ "sfinx", "Sfinx" },
 	{ 0, 0 }
 };
 


Commit: aad77304a8727ba1d2a1b802a95c7f8085d50853
    https://github.com/scummvm/scummvm/commit/aad77304a8727ba1d2a1b802a95c7f8085d50853
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-25T20:11:32+02:00

Commit Message:
CGE2: Add copyright comments to the source files.

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



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 488076f..0b06cd0 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -20,6 +20,11 @@
  *
  */
 
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
 #include "cge2/cge2.h"
 
 namespace CGE2 {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 46aa4a3..ee4ecf6 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -20,6 +20,11 @@
  *
  */
 
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
 #ifndef CGE2_H
 #define CGE2_H
 
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 1243078..9c63af1 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -20,6 +20,11 @@
 *
 */
 
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
 #include "cge2/cge2.h"
 #include "engines/advancedDetector.h"
 
@@ -55,7 +60,7 @@ public:
 	}
 
 	virtual const char *getOriginalCopyright() const {
-		return "Sfinx (c) 1997 L.K. Avalon";
+		return "Sfinx (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon";
 	}
 
 	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;


Commit: b58965e4e62259fc000dd731f694a24244268983
    https://github.com/scummvm/scummvm/commit/b58965e4e62259fc000dd731f694a24244268983
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-26T08:02:00+02:00

Commit Message:
CGE2: Add file I/O.

Changed paths:
  A engines/cge2/fileio.cpp
  A engines/cge2/fileio.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 0b06cd0..8f84f5e 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -31,11 +31,16 @@ namespace CGE2 {
 
 CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	: Engine(syst), _gameDescription(gameDescription) {
+	_resman = nullptr;
 }
 
 CGE2Engine::~CGE2Engine() {
 }
 
+void CGE2Engine::init() {
+	_resman = new ResourceManager();
+}
+
 bool CGE2Engine::hasFeature(EngineFeature f) const {
 	return false;
 }
@@ -58,6 +63,7 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 }
 
 Common::Error CGE2Engine::run() {
+	init();
 	warning("STUB: CGE2Engine::run()");
 	return Common::kNoError;
 }
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index ee4ecf6..068b371 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -30,6 +30,7 @@
 
 #include "engines/engine.h"
 #include "engines/advancedDetector.h"
+#include "cge2/fileio.h"
 
 namespace CGE2 {
 
@@ -45,6 +46,10 @@ public:
 	virtual Common::Error run();
 
 	const ADGameDescription *_gameDescription;
+
+	ResourceManager *_resman;
+private:
+	void init();
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
new file mode 100644
index 0000000..4da2c52
--- /dev/null
+++ b/engines/cge2/fileio.cpp
@@ -0,0 +1,247 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "common/system.h"
+#include "common/str.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/memstream.h"
+#include "cge2/cge2.h"
+#include "cge2/fileio.h"
+
+namespace CGE2 {
+
+/*-----------------------------------------------------------------------
+ * BtPage
+ *-----------------------------------------------------------------------*/
+void BtPage::readBTree(Common::ReadStream &s) {
+	_header._count = s.readUint16LE();
+	_header._down = s.readUint16LE();
+
+	if (_header._down == kBtValNone) {
+		// Leaf list
+		for (int i = 0; i < kBtLeafCount; ++i) {
+			s.read(_leaf[i]._key, kBtKeySize);
+			_leaf[i]._pos = s.readUint32LE();
+			_leaf[i]._size = s.readUint32LE();
+		}
+	} else {
+		// Root index
+		for (int i = 0; i < kBtInnerCount; ++i) {
+			s.read(_inner[i]._key, kBtKeySize);
+			_inner[i]._down = s.readUint16LE();
+		}
+	}
+}
+
+/*-----------------------------------------------------------------------
+ * ResourceManager
+ *-----------------------------------------------------------------------*/
+ResourceManager::ResourceManager() {
+	_datFile = new Common::File();
+	_datFile->open(kDatName);
+
+	_catFile = new Common::File();
+	_catFile->open(kCatName);
+
+	if (!_datFile->isOpen() || !_catFile->isOpen())
+		error("Unable to open data files");
+
+	for (int i = 0; i < kBtLevel; i++) {
+		_buff[i]._page = new BtPage;
+		_buff[i]._pageNo = kBtValNone;
+		_buff[i]._index = -1;
+		assert(_buff[i]._page != NULL);
+	}
+}
+
+ResourceManager::~ResourceManager() {
+	_datFile->close();
+	delete _datFile;
+
+	_catFile->close();
+	delete _catFile;
+
+	for (int i = 0; i < kBtLevel; i++)
+		delete _buff[i]._page;
+}
+
+void ResourceManager::XCrypt(byte *buf, uint16 length) {
+	byte *b = buf;
+
+	for (uint16 i = 0; i < length; i++)
+		*b++ ^= kCryptSeed;
+}
+
+bool ResourceManager::seek(int32 offs, int whence) {
+	return _datFile->seek(offs, whence);
+}
+
+uint16 ResourceManager::read(byte *buf, uint16 length) {
+	if (!_datFile->isOpen())
+		return 0;
+
+	uint16 bytesRead = _datFile->read(buf, length);
+	if (!bytesRead)
+		error("Read %s - %d bytes", _datFile->getName(), length);
+	XCrypt(buf, length);
+	return bytesRead;
+}
+
+BtPage *ResourceManager::getPage(int level, uint16 pageId) {
+	if (_buff[level]._pageNo != pageId) {
+		int32 pos = pageId * kBtSize;
+		_buff[level]._pageNo = pageId;
+		assert(_catFile->size() > pos);
+		// In the original, there was a check verifying if the
+		// purpose was to write a new file. This should only be
+		// to create a new file, thus it was removed.
+		_catFile->seek(pageId * kBtSize, SEEK_SET);
+
+		// Read in the page
+		byte buffer[kBtSize];
+		int bytesRead = catRead(buffer, kBtSize);
+
+		// Unpack it into the page structure
+		Common::MemoryReadStream stream(buffer, bytesRead, DisposeAfterUse::NO);
+		_buff[level]._page->readBTree(stream);
+		_buff[level]._index = -1;
+	}
+	return _buff[level]._page;
+}
+
+BtKeypack *ResourceManager::find(const char *key) {
+	int lev = 0;
+	uint16 nxt = kBtValRoot;
+	while (!_catFile->eos()) {
+		BtPage *pg = getPage(lev, nxt);
+		// search
+		if (pg->_header._down != kBtValNone) {
+			int i;
+			for (i = 0; i < pg->_header._count; i++) {
+				// Does this work, or does it have to compare the entire buffer?
+				if (scumm_strnicmp((const char *)key, (const char*)pg->_inner[i]._key, kBtKeySize) < 0)
+					break;
+			}
+			nxt = (i) ? pg->_inner[i - 1]._down : pg->_header._down;
+			_buff[lev]._index = i - 1;
+			lev++;
+		} else {
+			int i;
+			for (i = 0; i < pg->_header._count - 1; i++) {
+				if (scumm_stricmp((const char *)key, (const char *)pg->_leaf[i]._key) <= 0)
+					break;
+			}
+			_buff[lev]._index = i;
+			return &pg->_leaf[i];
+		}
+	}
+	return NULL;
+}
+
+bool ResourceManager::exist(const char *name) {
+	return scumm_stricmp(find(name)->_key, name) == 0;
+}
+
+uint16 ResourceManager::catRead(byte *buf, uint16 length) {
+	if (!_catFile->isOpen())
+		return 0;
+
+	uint16 bytesRead = _catFile->read(buf, length);
+	if (!bytesRead)
+		error("Read %s - %d bytes", _catFile->getName(), length);
+	XCrypt(buf, length);
+	return bytesRead;
+}
+
+/*-----------------------------------------------------------------------
+ * EncryptedStream
+ *-----------------------------------------------------------------------*/
+EncryptedStream::EncryptedStream(CGE2Engine *vm, const char *name) : _vm(vm) {
+	_error = false;
+	BtKeypack *kp = _vm->_resman->find(name);
+	if (scumm_stricmp(kp->_key, name) != 0)
+		_error = true;
+
+	_vm->_resman->seek(kp->_pos);
+	byte *dataBuffer;
+	int bufSize;
+
+	if ((strlen(name) > 4) && (scumm_stricmp(name + strlen(name) - 4, ".SPR") == 0)) {
+		// SPR files have some inconsistencies. Some have extra 0x1A at the end, some others
+		// do not have a carriage return at the end of the last line
+		// Therefore, we remove this ending 0x1A and add extra new lines.
+		// This fixes bug #3537527
+		dataBuffer = (byte *)malloc(kp->_size + 2);
+		_vm->_resman->read(dataBuffer, kp->_size);
+		if (dataBuffer[kp->_size - 1] == 0x1A)
+			dataBuffer[kp->_size - 1] = '\n';
+		dataBuffer[kp->_size] = '\n';
+		dataBuffer[kp->_size + 1] = '\n';
+		bufSize = kp->_size + 2;
+	} else {
+		dataBuffer = (byte *)malloc(kp->_size);
+		_vm->_resman->read(dataBuffer, kp->_size);
+		bufSize = kp->_size;
+	}
+
+	_readStream = new Common::MemoryReadStream(dataBuffer, bufSize, DisposeAfterUse::YES);
+}
+
+uint32 EncryptedStream::read(byte *dataPtr, uint32 dataSize) {
+	return _readStream->read(dataPtr, dataSize);
+}
+
+bool EncryptedStream::err() {
+	return (_error & _readStream->err());
+}
+
+bool EncryptedStream::eos() {
+	return _readStream->eos();
+}
+
+bool EncryptedStream::seek(int32 offset) {
+	return _readStream->seek(offset);
+}
+
+Common::String EncryptedStream::readLine() {
+	return _readStream->readLine();
+}
+
+int32 EncryptedStream::size() {
+	return _readStream->size();
+}
+
+int32 EncryptedStream::pos() {
+	return _readStream->pos();
+}
+
+EncryptedStream::~EncryptedStream() {
+	delete _readStream;
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
new file mode 100644
index 0000000..42bb2ee
--- /dev/null
+++ b/engines/cge2/fileio.h
@@ -0,0 +1,120 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_FILEIO_H
+#define CGE2_FILEIO_H
+
+#include "common/file.h"
+
+namespace CGE2 {
+
+class CGE2Engine;
+
+#define kBtSize       2048
+#define kBtKeySize    13
+#define kBtLevel      2
+#define kBtInnerCount ((kBtSize - 4 /*sizeof(Header) */) / (kBtKeySize + 2 /*sizeof(Inner) */))
+#define kBtLeafCount  ((kBtSize - 4 /*sizeof(Header) */) / (kBtKeySize + 4 + 4 /*sizeof(BtKeypack) */))
+#define kBtValNone    0xFFFF
+#define kBtValRoot    0
+#define kCatName      "VOL.CAT"
+#define kDatName      "VOL.DAT"
+#define kCryptSeed    0xA5
+
+struct BtKeypack {
+	char _key[kBtKeySize];
+	uint32 _pos;
+	uint32 _size;
+};
+
+struct Inner {
+	uint8  _key[kBtKeySize];
+	uint16 _down;
+};
+
+struct Header {
+	uint16 _count;
+	uint16 _down;
+};
+
+struct BtPage {
+	Header _header;
+	union {
+		// dummy filler to make proper size of union
+		uint8 _data[kBtSize - 4]; /* 4 is the size of struct Header */
+		// inner version of data: key + word-sized page link
+		Inner _inner[kBtInnerCount];
+		// leaf version of data: key + all user data
+		BtKeypack _leaf[kBtLeafCount];
+	};
+
+	void readBTree(Common::ReadStream &s);
+};
+
+class ResourceManager {
+private:
+	struct {
+		BtPage *_page;
+		uint16 _pageNo;
+		int _index;
+	} _buff[kBtLevel];
+
+	BtPage *getPage(int level, uint16 pageId);
+	uint16 catRead(byte *buf, uint16 length);
+	Common::File *_catFile;
+	Common::File *_datFile;
+	void XCrypt(byte *buf, uint16 length);
+public:
+	ResourceManager();
+	~ResourceManager();
+	uint16 read(byte *buf, uint16 length);
+	bool seek(int32 offs, int whence = SEEK_SET);
+
+	BtKeypack *find(const char *key);
+	bool exist(const char *name);
+};
+
+class EncryptedStream {
+private:
+	CGE2Engine *_vm;
+	Common::SeekableReadStream *_readStream;
+	bool _error;
+public:
+	EncryptedStream(CGE2Engine *vm, const char *name);
+	~EncryptedStream();
+	bool err();
+	bool eos();
+	bool seek(int32 offset);
+	int32 pos();
+	int32 size();
+	uint32 read(byte *dataPtr, uint32 dataSize);
+	Common::String readLine();
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_FILEIO_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 75f2743..fc710b6 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -2,7 +2,8 @@ MODULE := engines/cge2
 
 MODULE_OBJS = \
 	cge2.o \
-	detection.o
+	detection.o \
+	fileio.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)


Commit: d9e0e882b7bb1e2d32e80334b434c0d6962a84d7
    https://github.com/scummvm/scummvm/commit/d9e0e882b7bb1e2d32e80334b434c0d6962a84d7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-28T09:34:34+02:00

Commit Message:
CGE2: Deallocate _resman in destructor.

Changed paths:
    engines/cge2/cge2.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 8f84f5e..41b6249 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -35,6 +35,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 }
 
 CGE2Engine::~CGE2Engine() {
+	delete _resman;
 }
 
 void CGE2Engine::init() {


Commit: 258d7ea535c2891bed4132e649c66fb86967a2a0
    https://github.com/scummvm/scummvm/commit/258d7ea535c2891bed4132e649c66fb86967a2a0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-28T10:24:35+02:00

Commit Message:
CGE2: Implement deinitialization properly.

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



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 41b6249..56393d2 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -34,14 +34,14 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_resman = nullptr;
 }
 
-CGE2Engine::~CGE2Engine() {
-	delete _resman;
-}
-
 void CGE2Engine::init() {
 	_resman = new ResourceManager();
 }
 
+void CGE2Engine::deinit() {
+	delete _resman;
+}
+
 bool CGE2Engine::hasFeature(EngineFeature f) const {
 	return false;
 }
@@ -66,6 +66,7 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 Common::Error CGE2Engine::run() {
 	init();
 	warning("STUB: CGE2Engine::run()");
+	deinit();
 	return Common::kNoError;
 }
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 068b371..f84c9a8 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -37,7 +37,6 @@ namespace CGE2 {
 class CGE2Engine : public Engine {
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
-	~CGE2Engine();
 	virtual bool hasFeature(EngineFeature f) const;
 	virtual bool canLoadGameStateCurrently();
 	virtual bool canSaveGameStateCurrently();
@@ -50,6 +49,7 @@ public:
 	ResourceManager *_resman;
 private:
 	void init();
+	void deinit();
 };
 
 } // End of namespace CGE2


Commit: ec71f936280496d349310ea0091dbe26b90ae540
    https://github.com/scummvm/scummvm/commit/ec71f936280496d349310ea0091dbe26b90ae540
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-29T09:50:40+02:00

Commit Message:
CGE2: Add parts of the graphics code.

Changed paths:
  A engines/cge2/bitmap.cpp
  A engines/cge2/bitmap.h
  A engines/cge2/general.h
  A engines/cge2/vga13h.cpp
  A engines/cge2/vga13h.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/module.mk



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
new file mode 100644
index 0000000..77c7eb9
--- /dev/null
+++ b/engines/cge2/bitmap.cpp
@@ -0,0 +1,369 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/bitmap.h"
+#include "cge2/cge2.h"
+#include "cge2/vga13h.h"
+//#include "cge/cge_main.h"
+#include "common/system.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+
+namespace CGE2 {
+
+Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(NULL), _v(NULL), _map(0), _vm(vm) {
+	char pat[kMaxPath];
+	forceExt(pat, fname, ".VBM");
+
+	if (_vm->_resman->exist(pat)) {
+		EncryptedStream file(_vm, pat);
+		if (file.err())
+			error("Unable to find VBM [%s]", fname);
+		if (!loadVBM(&file))
+			error("Bad VBM [%s]", fname);
+	} else {
+		error("Bad VBM [%s]", fname);
+	}
+}
+
+Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _m(map), _v(NULL), _map(0), _b(NULL), _vm(vm) {
+	if (map)
+		code();
+}
+
+// following routine creates filled rectangle
+// immediately as VGA video chunks, in near memory as fast as possible,
+// especially for text line real time display
+Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
+	: _w((w + 3) & ~3),                              // only full uint32 allowed!
+	  _h(h), _m(NULL), _map(0), _b(NULL), _vm(vm) {
+
+	uint16 dsiz = _w >> 2;                           // data size (1 plane line size)
+	uint16 lsiz = 2 + dsiz + 2;                     // uint16 for line header, uint16 for gap
+	uint16 psiz = _h * lsiz;                         // - last gape, but + plane trailer
+	uint8 *v = new uint8[4 * psiz + _h * sizeof(*_b)];// the same for 4 planes
+	                                                // + room for wash table
+	assert(v != NULL);
+
+	WRITE_LE_UINT16(v, (kBmpCPY | dsiz));                 // data chunk hader
+	memset(v + 2, fill, dsiz);                      // data bytes
+	WRITE_LE_UINT16(v + lsiz - 2, (kBmpSKP | ((kScrWidth / 4) - dsiz)));  // gap
+
+	// Replicate lines
+	byte *destP;
+	for (destP = v + lsiz; destP < (v + psiz); destP += lsiz)
+		Common::copy(v, v + lsiz, destP);
+
+	WRITE_LE_UINT16(v + psiz - 2, kBmpEOI);            // plane trailer uint16
+
+	// Replicate planes
+	for (destP = v + psiz; destP < (v + 4 * psiz); destP += psiz)
+		Common::copy(v, v + psiz, destP);
+
+	HideDesc *b = (HideDesc *)(v + 4 * psiz);
+	b->_skip = (kScrWidth - _w) >> 2;
+	b->_hide = _w >> 2;
+
+	// Replicate across the entire table
+	for (HideDesc *hdP = b + 1; hdP < (b + _h); hdP++)
+		*hdP = *b;
+
+	b->_skip = 0;                                    // fix the first entry
+	_v = v;
+	_b = b;
+}
+
+Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(NULL), _v(NULL), _map(0), _b(NULL), _vm(vm) {
+	uint8 *v0 = bmp._v;
+	if (!v0)
+		return;
+
+	uint16 vsiz = (uint8 *)(bmp._b) - (uint8 *)(v0);
+	uint16 siz = vsiz + _h * sizeof(HideDesc);
+	uint8 *v1 = new uint8[siz];
+	assert(v1 != NULL);
+	memcpy(v1, v0, siz);
+	_b = (HideDesc *)((_v = v1) + vsiz);
+}
+
+Bitmap::~Bitmap() {
+	free(_m);
+	delete[] _v;
+}
+
+Bitmap &Bitmap::operator=(const Bitmap &bmp) {
+	if (this == &bmp)
+		return *this;
+
+	uint8 *v0 = bmp._v;
+	_w = bmp._w;
+	_h = bmp._h;
+	_m = NULL;
+	_map = 0;
+	_vm = bmp._vm;
+	delete[] _v;
+
+	if (v0 == NULL) {
+		_v = NULL;
+	} else {
+		uint16 vsiz = (uint8 *)bmp._b - (uint8 *)v0;
+		uint16 siz = vsiz + _h * sizeof(HideDesc);
+		uint8 *v1 = new uint8[siz];
+		assert(v1 != NULL);
+		memcpy(v1, v0, siz);
+		_b = (HideDesc *)((_v = v1) + vsiz);
+	}
+	return *this;
+}
+
+char *Bitmap::forceExt(char *buf, const char *name, const char *ext) {
+	strcpy(buf, name);
+	char *dot = strrchr(buf, '.');
+	if (dot)
+		*dot = '\0';
+	strcat(buf, ext);
+
+	return buf;
+}
+
+BitmapPtr Bitmap::code() {
+	if (!_m)
+		return NULL;
+
+	uint16 cnt;
+
+	if (_v) {                                        // old X-map exists, so remove it
+		delete[] _v;
+		_v = NULL;
+	}
+
+	while (true) {                                  // at most 2 times: for (V == NULL) & for allocated block;
+		uint8 *im = _v + 2;
+		uint16 *cp = (uint16 *) _v;
+		int bpl;
+
+		if (_v) {                                      // 2nd pass - fill the hide table
+			for (uint16 i = 0; i < _h; i++) {
+				_b[i]._skip = 0xFFFF;
+				_b[i]._hide = 0x0000;
+			}
+		}
+		for (bpl = 0; bpl < 4; bpl++) {              // once per each bitplane
+			uint8 *bm = _m;
+			bool skip = (bm[bpl] == kPixelTransp);
+			uint16 j;
+
+			cnt = 0;
+			for (uint16 i = 0; i < _h; i++) {                  // once per each line
+				uint8 pix;
+				for (j = bpl; j < _w; j += 4) {
+					pix = bm[j];
+					if (_v && pix != kPixelTransp) {
+						if (j < _b[i]._skip)
+							_b[i]._skip = j;
+
+						if (j >= _b[i]._hide)
+							_b[i]._hide = j + 1;
+					}
+					if ((pix == kPixelTransp) != skip || cnt >= 0x3FF0) { // end of block
+						cnt |= (skip) ? kBmpSKP : kBmpCPY;
+						if (_v)
+							WRITE_LE_UINT16(cp, cnt); // store block description uint16
+
+						cp = (uint16 *) im;
+						im += 2;
+						skip = (pix == kPixelTransp);
+						cnt = 0;
+					}
+					if (!skip) {
+						if (_v)
+							*im = pix;
+						im++;
+					}
+					cnt++;
+				}
+
+				bm += _w;
+				if (_w < kScrWidth) {
+					if (skip) {
+						cnt += (kScrWidth - j + 3) / 4;
+					} else {
+						cnt |= kBmpCPY;
+						if (_v)
+							WRITE_LE_UINT16(cp, cnt);
+
+						cp = (uint16 *) im;
+						im += 2;
+						skip = true;
+						cnt = (kScrWidth - j + 3) / 4;
+					}
+				}
+			}
+			if (cnt && ! skip) {
+				cnt |= kBmpCPY;
+				if (_v)
+					WRITE_LE_UINT16(cp, cnt);
+
+				cp = (uint16 *) im;
+				im += 2;
+			}
+			if (_v)
+				WRITE_LE_UINT16(cp, kBmpEOI);
+			cp = (uint16 *) im;
+			im += 2;
+		}
+		if (_v)
+			break;
+
+		uint16 sizV = (uint16)(im - 2 - _v);
+		_v = new uint8[sizV + _h * sizeof(*_b)];
+		assert(_v != NULL);
+
+		_b = (HideDesc *)(_v + sizV);
+	}
+	cnt = 0;
+	for (uint16 i = 0; i < _h; i++) {
+		if (_b[i]._skip == 0xFFFF) {                    // whole line is skipped
+			_b[i]._skip = (cnt + kScrWidth) >> 2;
+			cnt = 0;
+		} else {
+			uint16 s = _b[i]._skip & ~3;
+			uint16 h = (_b[i]._hide + 3) & ~3;
+			_b[i]._skip = (cnt + s) >> 2;
+			_b[i]._hide = (h - s) >> 2;
+			cnt = kScrWidth - h;
+		}
+	}
+
+	return this;
+}
+
+bool Bitmap::solidAt(int16 x, int16 y) {
+	if ((x >= _w) || (y >= _h))
+		return false;
+
+	uint8 *m = _v;
+	uint16 r = static_cast<uint16>(x) % 4;
+	uint16 n0 = (kScrWidth * y + x) / 4;
+	uint16 n = 0;
+
+	while (r) {
+		uint16 w, t;
+
+		w = READ_LE_UINT16(m);
+		m += 2;
+		t = w & 0xC000;
+		w &= 0x3FFF;
+
+		switch (t) {
+		case kBmpEOI:
+			r--;
+			// No break on purpose
+		case kBmpSKP:
+			w = 0;
+			break;
+		case kBmpREP:
+			w = 1;
+			break;
+		}
+		m += w;
+	}
+
+	while (true) {
+		uint16 w, t;
+
+		w = READ_LE_UINT16(m);
+		m += 2;
+		t = w & 0xC000;
+		w &= 0x3FFF;
+
+		if (n > n0)
+			return false;
+
+		n += w;
+		switch (t) {
+		case kBmpEOI:
+			return false;
+		case kBmpSKP:
+			w = 0;
+			break;
+		case kBmpREP:
+		case kBmpCPY:
+			if (n - w <= n0 && n > n0)
+				return true;
+			break;
+		}
+		m += ((t == kBmpREP) ? 1 : w);
+	}
+}
+
+bool Bitmap::loadVBM(EncryptedStream *f) {
+	uint16 p = 0, n = 0;
+	if (!f->err())
+		f->read((uint8 *)&p, sizeof(p));
+	p = FROM_LE_16(p);
+
+	if (!f->err())
+		f->read((uint8 *)&n, sizeof(n));
+	n = FROM_LE_16(n);
+
+	if (!f->err())
+		f->read((uint8 *)&_w, sizeof(_w));
+	_w = FROM_LE_16(_w);
+
+	if (!f->err())
+		f->read((uint8 *)&_h, sizeof(_h));
+	_h = FROM_LE_16(_h);
+
+	if (!f->err()) {
+		if (p) {
+			if (_vm->_bitmapPalette) {
+				// Read in the palette
+				byte palData[kPalSize];
+				f->read(palData, kPalSize);
+
+				const byte *srcP = palData;
+				for (int idx = 0; idx < kPalCount; idx++, srcP += 3) {
+					_vm->_bitmapPalette[idx]._r = *srcP;
+					_vm->_bitmapPalette[idx]._g = *(srcP + 1);
+					_vm->_bitmapPalette[idx]._b = *(srcP + 2);
+				}
+			} else
+				f->seek(f->pos() + kPalSize);
+		}
+	}
+	if ((_v = new uint8[n]) == NULL)
+		return false;
+
+	if (!f->err())
+		f->read(_v, n);
+
+	_b = (HideDesc *)(_v + n - _h * sizeof(HideDesc));
+	return (!f->err());
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
new file mode 100644
index 0000000..3d3c27f
--- /dev/null
+++ b/engines/cge2/bitmap.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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_BITMAP_H
+#define CGE2_BITMAP_H
+
+#include "cge/general.h"
+#include "common/file.h"
+
+namespace CGE2 {
+
+class CGE2Engine;
+class EncryptedStream;
+
+#define kMaxPath  128
+enum {
+	kBmpEOI = 0x0000,
+	kBmpSKP = 0x4000,
+	kBmpREP = 0x8000,
+	kBmpCPY = 0xC000
+};
+
+#include "common/pack-start.h"
+
+struct HideDesc {
+	uint16 _skip;
+	uint16 _hide;
+} PACKED_STRUCT;
+
+#include "common/pack-end.h"
+
+class Bitmap {
+	CGE2Engine *_vm;
+	char *forceExt(char *buf, const char *name, const char *ext);
+	bool loadVBM(EncryptedStream *f);
+public:
+	uint16 _w;
+	uint16 _h;
+	uint8 *_m;
+	uint8 *_v;
+	int32 _map;
+	HideDesc *_b;
+
+	Bitmap(CGE2Engine *vm, const char *fname);
+	Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map);
+	Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill);
+	Bitmap(CGE2Engine *vm, const Bitmap &bmp);
+	~Bitmap();
+
+	Bitmap *code();
+	Bitmap &operator=(const Bitmap &bmp);
+	void hide(int16 x, int16 y);
+	void show(int16 x, int16 y);
+	void xShow(int16 x, int16 y);
+	bool solidAt(int16 x, int16 y);
+};
+
+
+typedef Bitmap *BitmapPtr;
+
+} // End of namespace CGE2
+
+#endif // CGE2_BITMAP_H
diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 56393d2..955c5eb 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -25,21 +25,34 @@
  * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
  */
 
+#include "engines/util.h"
+
 #include "cge2/cge2.h"
+#include "cge2/bitmap.h"
+#include "cge2/vga13h.h"
 
 namespace CGE2 {
 
 CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	: Engine(syst), _gameDescription(gameDescription) {
 	_resman = nullptr;
+	_vga = nullptr;
+	_sprite = nullptr;
+	
+	_quitFlag = false;
+	_bitmapPalette = nullptr;
+	_mode = 0;
 }
 
 void CGE2Engine::init() {
 	_resman = new ResourceManager();
+	_vga = new Vga(this);
 }
 
 void CGE2Engine::deinit() {
 	delete _resman;
+	delete _vga;
+	delete _sprite;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
@@ -64,10 +77,41 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 }
 
 Common::Error CGE2Engine::run() {
+	initGraphics(kScrWidth, kScrHeight, false);
+
 	init();
 	warning("STUB: CGE2Engine::run()");
+	showTitle("WELCOME");
 	deinit();
 	return Common::kNoError;
 }
 
+bool CGE2Engine::showTitle(const char *name) {
+	if (_quitFlag)
+		return false;
+
+	_bitmapPalette = _vga->_sysPal;
+	BitmapPtr *LB = new BitmapPtr[2];
+	LB[0] = new Bitmap(this, name);
+	LB[1] = NULL;
+	_bitmapPalette = NULL;
+
+	Sprite D(this, LB);
+	D._flags._kill = true;
+	D._flags._bDel = true;
+	D.center();
+	D.show(2);
+
+	_vga->sunset();
+	_vga->copyPage(1, 2);
+	_vga->copyPage(0, 1);
+	_vga->sunrise(_vga->_sysPal);
+
+	_vga->update();
+	
+	warning("STUB: CGE2Engine::showTitle()");
+
+	return true;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index f84c9a8..814c607 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -30,10 +30,20 @@
 
 #include "engines/engine.h"
 #include "engines/advancedDetector.h"
+#include "common/system.h"
 #include "cge2/fileio.h"
+#include "cge2/general.h"
 
 namespace CGE2 {
 
+class Vga;
+class Sprite;
+
+#define kScrWidth      320
+#define kScrHeight     240
+#define kMaxFile       128
+#define kPathMax       128
+
 class CGE2Engine : public Engine {
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
@@ -44,9 +54,17 @@ public:
 	virtual Common::Error saveGameState(int slot, const Common::String &desc);
 	virtual Common::Error run();
 
+	bool showTitle(const char *name);
+
 	const ADGameDescription *_gameDescription;
 
+	bool _quitFlag;
+	Dac *_bitmapPalette;
+	int _mode;
+
 	ResourceManager *_resman;
+	Vga *_vga;
+	Sprite *_sprite;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
new file mode 100644
index 0000000..7d5c60f
--- /dev/null
+++ b/engines/cge2/general.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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_GENERAL_H
+#define CGE2_GENERAL_H
+
+#include "common/file.h"
+
+namespace CGE2 {
+
+struct Dac {
+	uint8 _r;
+	uint8 _g;
+	uint8 _b;
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_GENERAL_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index fc710b6..493488f 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -3,7 +3,9 @@ MODULE := engines/cge2
 MODULE_OBJS = \
 	cge2.o \
 	detection.o \
-	fileio.o
+	fileio.o \
+	vga13h.o \
+	bitmap.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
new file mode 100644
index 0000000..26fba8b
--- /dev/null
+++ b/engines/cge2/vga13h.cpp
@@ -0,0 +1,1016 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "common/array.h"
+#include "common/config-manager.h"
+#include "common/rect.h"
+#include "graphics/palette.h"
+#include "cge2/general.h"
+#include "cge2/vga13h.h"
+#include "cge2/bitmap.h"
+//#include "cge/text.h"
+//#include "cge/cge_main.h"
+#include "cge2/cge2.h"
+#include "cge2/vga13h.h"
+
+namespace CGE2 {
+
+Seq *getConstantSeq(bool seqFlag) {
+	const Seq seq1[] = { { 0, 0, 0, 0, 0 } };
+	const Seq seq2[] = { { 0, 1, 0, 0, 0 }, { 1, 0, 0, 0, 0 } };
+
+	Seq *seq;
+	if (seqFlag) {
+		seq = (Seq *)malloc(1 * sizeof(Seq));
+		*seq = seq1[0];
+	} else {
+		seq = (Seq *)malloc(2 * sizeof(Seq));
+		seq[0] = seq2[0];
+		seq[1] = seq2[1];
+	}
+
+	return seq;
+}
+
+Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
+	: _x(0), _y(0), _z(0), _nearPtr(0), _takePtr(0),
+	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
+	  _ext(NULL), _ref(-1), _scene(0), _vm(vm) {
+	memset(_file, 0, sizeof(_file));
+	memset(&_flags, 0, sizeof(_flags));
+	_ref = 0;
+	_x = _y = 0;
+	_w = _h = 0;
+	_time = 0;
+	_seqPtr = 0;
+	_shpCnt = 0;
+	_prev = _next = NULL;
+
+	setShapeList(shpP);
+}
+
+Sprite::~Sprite() {
+	if (_vm->_sprite == this)
+		_vm->_sprite = NULL;
+
+	contract();
+}
+
+BitmapPtr Sprite::shp() {
+	SprExt *e = _ext;
+	if (!e || !e->_seq)
+		return NULL;
+
+	int i = e->_seq[_seqPtr]._now;
+	if (i >= _shpCnt)
+		error("Invalid PHASE in SPRITE::Shp() %s", _file);
+	return e->_shpList[i];
+}
+
+BitmapPtr *Sprite::setShapeList(BitmapPtr *shpP) {
+	BitmapPtr *r = (_ext) ? _ext->_shpList : NULL;
+
+	_shpCnt = 0;
+	_w = 0;
+	_h = 0;
+
+	if (shpP) {
+		BitmapPtr *p;
+		for (p = shpP; *p; p++) {
+			BitmapPtr b = (*p); // ->Code();
+			if (b->_w > _w)
+				_w = b->_w;
+			if (b->_h > _h)
+				_h = b->_h;
+			_shpCnt++;
+		}
+		expand();
+		_ext->_shpList = shpP;
+		_flags._bDel = true;
+		if (!_ext->_seq)
+			setSeq(getConstantSeq(_shpCnt < 2));
+	}
+	return r;
+}
+
+bool Sprite::works(Sprite *spr) {
+	//if (!spr || !spr->_ext)
+	//	return false;
+
+	//CommandHandler::Command *c = spr->_ext->_take;
+	//if (c != NULL) {
+	//	c += spr->_takePtr;
+	//	if (c->_ref == _ref)
+	//		if (c->_commandType != kCmdLabel || (c->_val == 0 || c->_val == _vm->_now))
+	//			return true;
+	//}
+
+	warning("STUB: Sprite::works()");
+
+	return false;
+}
+
+Seq *Sprite::setSeq(Seq *seq) {
+	if (_ext) {
+		free(_ext->_seq);
+		_ext->_seq = NULL;
+	}
+
+//	expand();
+	warning("STUB: Sprite::setSeq()");
+
+	Seq *s = _ext->_seq;
+	_ext->_seq = seq;
+	if (_seqPtr == kNoSeq)
+		step(0);
+	else if (_time == 0)
+		step(_seqPtr);
+	return s;
+}
+
+bool Sprite::seqTest(int n) {
+	if (n >= 0)
+		return (_seqPtr == n);
+	if (_ext)
+		return (_ext->_seq[_seqPtr]._next == _seqPtr);
+	return true;
+}
+
+//CommandHandler::Command *Sprite::snList(SnList type) {
+//	SprExt *e = _ext;
+//	if (e)
+//		return (type == kNear) ? e->_near : e->_take;
+//	return NULL;
+//}
+
+void Sprite::setName(char *newName) {
+	if (!_ext)
+		return;
+
+	if (_ext->_name) {
+		delete[] _ext->_name;
+		_ext->_name = NULL;
+	}
+	if (newName) {
+		_ext->_name = new char[strlen(newName) + 1];
+		assert(_ext->_name != NULL);
+		strcpy(_ext->_name, newName);
+	}
+}
+
+Sprite *Sprite::expand() {
+	if (_ext)
+		return this;
+
+	_ext = new SprExt;
+	assert(_ext != NULL);
+	if (!*_file)
+		return this;
+
+	static const char *Comd[] = { "Name", "Phase", "Seq", "Near", "Take", NULL };
+	char fname[kPathMax];
+
+	Common::Array<BitmapPtr> shplist;
+	for (int i = 0; i < _shpCnt + 1; ++i)
+		shplist.push_back(NULL);
+
+	Seq *seq = NULL;
+	int shapeCount = 0,
+		seqCount = 0,
+		nearCount = 0,
+		takeCount = 0,
+		maxnow = 0,
+		maxnxt = 0;
+
+	warning("STUB: Sprite::expand()");
+
+	//CommandHandler::Command *nearList = NULL;
+	//CommandHandler::Command *takeList = NULL;
+	//_vm->mergeExt(fname, _file, kSprExt);
+	//if (_vm->_resman->exist(fname)) { // sprite description file exist
+	//	EncryptedStream sprf(_vm, fname);
+	//	if (sprf.err())
+	//		error("Bad SPR [%s]", fname);
+	//	Common::String line;
+	//	char tmpStr[kLineMax + 1];
+	//	int lcnt = 0;
+
+	//	for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
+	//		int len = line.size();
+	//		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+	//		lcnt++;
+	//		if (len == 0 || *tmpStr == '.')
+	//			continue;
+
+	//		CommandHandler::Command *c;
+	//		switch (_vm->takeEnum(Comd, strtok(tmpStr, " =\t"))) {
+	//		case 0:
+	//			// Name
+	//			setName(strtok(NULL, ""));
+	//			break;
+	//		case 1:
+	//			// Phase
+	//			// In case the shape index gets too high, increase the array size
+	//			while ((shapeCount + 1) >= (int)shplist.size()) {
+	//				shplist.push_back(NULL);
+	//				++_shpCnt;
+	//			}
+	//			shplist[shapeCount++] = new Bitmap(_vm, strtok(NULL, " \t,;/"));
+	//			break;
+	//		case 2:
+	//			// Seq
+	//			seq = (Seq *)realloc(seq, (seqCount + 1) * sizeof(*seq));
+	//			assert(seq != NULL);
+	//			Seq *s;
+	//			s = &seq[seqCount++];
+	//			s->_now = atoi(strtok(NULL, " \t,;/"));
+	//			if (s->_now > maxnow)
+	//				maxnow = s->_now;
+	//			s->_next = atoi(strtok(NULL, " \t,;/"));
+	//			switch (s->_next) {
+	//			case 0xFF:
+	//				s->_next = seqCount;
+	//				break;
+	//			case 0xFE:
+	//				s->_next = seqCount - 1;
+	//				break;
+	//			}
+	//			if (s->_next > maxnxt)
+	//				maxnxt = s->_next;
+	//			s->_dx = atoi(strtok(NULL, " \t,;/"));
+	//			s->_dy = atoi(strtok(NULL, " \t,;/"));
+	//			s->_dly = atoi(strtok(NULL, " \t,;/"));
+	//			break;
+	//		case 3:
+	//			// Near
+	//			if (_nearPtr == kNoPtr)
+	//				break;
+	//			nearList = (CommandHandler::Command *)realloc(nearList, (nearCount + 1) * sizeof(*nearList));
+	//			assert(nearList != NULL);
+	//			c = &nearList[nearCount++];
+	//			if ((c->_commandType = (CommandType)_vm->takeEnum(CommandHandler::_commandText, strtok(NULL, " \t,;/"))) < 0)
+	//				error("Bad NEAR in %d [%s]", lcnt, fname);
+	//			c->_ref = atoi(strtok(NULL, " \t,;/"));
+	//			c->_val = atoi(strtok(NULL, " \t,;/"));
+	//			c->_spritePtr = NULL;
+	//			break;
+	//		case 4:
+	//			// Take
+	//			if (_takePtr == kNoPtr)
+	//				break;
+	//			takeList = (CommandHandler::Command *)realloc(takeList, (takeCount + 1) * sizeof(*takeList));
+	//			assert(takeList != NULL);
+	//			c = &takeList[takeCount++];
+	//			if ((c->_commandType = (CommandType)_vm->takeEnum(CommandHandler::_commandText, strtok(NULL, " \t,;/"))) < 0)
+	//				error("Bad NEAR in %d [%s]", lcnt, fname);
+	//			c->_ref = atoi(strtok(NULL, " \t,;/"));
+	//			c->_val = atoi(strtok(NULL, " \t,;/"));
+	//			c->_spritePtr = NULL;
+	//			break;
+	//		}
+	//	}
+	//} else {
+	//	// no sprite description: try to read immediately from .BMP
+	//	shplist[shapeCount++] = new Bitmap(_vm, _file);
+	//}
+
+	//shplist[shapeCount] = NULL;
+	//if (seq) {
+	//	if (maxnow >= shapeCount)
+	//		error("Bad PHASE in SEQ [%s]", fname);
+	//	if (maxnxt >= seqCount)
+	//		error("Bad JUMP in SEQ [%s]", fname);
+	//	setSeq(seq);
+	//} else
+	//	setSeq(getConstantSeq(_shpCnt == 1));
+
+	//// Set the shape list
+	//BitmapPtr *shapeList = new BitmapPtr[shplist.size()];
+	//for (uint i = 0; i < shplist.size(); ++i)
+	//	shapeList[i] = shplist[i];
+
+	//setShapeList(shapeList);
+
+	//if (nearList)
+	//	nearList[nearCount - 1]._spritePtr = _ext->_near = nearList;
+	//else
+	//	_nearPtr = kNoPtr;
+	//if (takeList)
+	//	takeList[takeCount - 1]._spritePtr = _ext->_take = takeList;
+	//else
+	//	_takePtr = kNoPtr;
+
+	return this;
+}
+
+Sprite *Sprite::contract() {
+	//SprExt *e = _ext;
+	//if (!e)
+	//	return this;
+
+	//if (e->_name)
+	//	delete[] e->_name;
+	//if (_flags._bDel && e->_shpList) {
+	//	for (int i = 0; e->_shpList[i]; i++)
+	//		delete e->_shpList[i];
+	//	delete[] e->_shpList;
+	//}
+
+	//free(e->_seq);
+	//free(e->_near);
+	//free(e->_take);
+
+	//delete e;
+	//_ext = NULL;
+
+	warning("STUB: Sprite::contract()");
+
+	return this;
+}
+
+Sprite *Sprite::backShow(bool fast) {
+	expand();
+	show(2);
+	show(1);
+	if (fast)
+		show(0);
+	contract();
+	return this;
+}
+
+void Sprite::step(int nr) {
+	if (nr >= 0)
+		_seqPtr = nr;
+	if (_ext) {
+		Seq *seq;
+		if (nr < 0)
+			_seqPtr = _ext->_seq[_seqPtr]._next;
+		seq = _ext->_seq + _seqPtr;
+		if (seq->_dly >= 0) {
+			gotoxy(_x + (seq->_dx), _y + (seq->_dy));
+			_time = seq->_dly;
+		}
+	}
+}
+
+//void Sprite::tick() {
+//	step();
+//}
+
+void Sprite::makeXlat(uint8 *x) {
+	if (!_ext)
+		return;
+
+	if (_flags._xlat)
+		killXlat();
+	for (BitmapPtr *b = _ext->_shpList; *b; b++)
+		(*b)->_m = x;
+	_flags._xlat = true;
+}
+
+void Sprite::killXlat() {
+	if (!_flags._xlat || !_ext)
+		return;
+
+	uint8 *m = (*_ext->_shpList)->_m;
+	free(m);
+
+	for (BitmapPtr *b = _ext->_shpList; *b; b++)
+		(*b)->_m = NULL;
+	_flags._xlat = false;
+}
+
+void Sprite::gotoxy(int x, int y) {
+	int xo = _x, yo = _y;
+	if (_x < kScrWidth) {
+		if (x < 0)
+			x = 0;
+		if (x + _w > kScrWidth)
+			x = (kScrWidth - _w);
+		_x = x;
+	}
+	if (_h < kScrHeight) {
+		if (y < 0)
+			y = 0;
+		if (y + _h > kScrHeight)
+			y = (kScrHeight - _h);
+		_y = y;
+	}
+	if (_next)
+		if (_next->_flags._slav)
+			_next->gotoxy(_next->_x - xo + _x, _next->_y - yo + _y);
+	if (_flags._shad)
+		_prev->gotoxy(_prev->_x - xo + _x, _prev->_y - yo + _y);
+}
+
+void Sprite::center() {
+	gotoxy((kScrWidth - _w) / 2, (kScrHeight - _h) / 2);
+}
+
+void Sprite::show() {
+	SprExt *e;
+	e = _ext;
+	e->_x0 = e->_x1;
+	e->_y0 = e->_y1;
+	e->_b0 = e->_b1;
+	e->_x1 = _x;
+	e->_y1 = _y;
+	e->_b1 = shp();
+	if (!_flags._hide) {
+		if (_flags._xlat)
+			e->_b1->xShow(e->_x1, e->_y1);
+		else
+			e->_b1->show(e->_x1, e->_y1);
+	}
+}
+
+void Sprite::show(uint16 pg) {
+	Graphics::Surface *a = _vm->_vga->_page[1];
+	_vm->_vga->_page[1] = _vm->_vga->_page[pg & 3];
+	shp()->show(_x, _y);
+	_vm->_vga->_page[1] = a;
+}
+
+void Sprite::hide() {
+	SprExt *e = _ext;
+	if (e->_b0)
+		e->_b0->hide(e->_x0, e->_y0);
+}
+
+BitmapPtr Sprite::ghost() {
+	SprExt *e = _ext;
+	if (!e->_b1)
+		return NULL;
+
+	BitmapPtr bmp = new Bitmap(_vm, 0, 0, (uint8 *)NULL);
+	assert(bmp != NULL);
+	bmp->_w = e->_b1->_w;
+	bmp->_h = e->_b1->_h;
+	bmp->_b = new HideDesc[bmp->_h];
+	assert(bmp->_b != NULL);
+	bmp->_v = (uint8 *) memcpy(bmp->_b, e->_b1->_b, sizeof(HideDesc) * bmp->_h);
+	bmp->_map = (e->_y1 << 16) + e->_x1;
+	return bmp;
+}
+
+void Sprite::sync(Common::Serializer &s) {
+	uint16 unused = 0;
+
+	s.syncAsUint16LE(unused);
+	s.syncAsUint16LE(unused);	// _ext
+	s.syncAsUint16LE(_ref);
+	s.syncAsByte(_scene);
+
+	// bitfield in-memory storage is unpredictable, so to avoid
+	// any issues, pack/unpack everything manually
+	uint16 flags = 0;
+	if (s.isLoading()) {
+		s.syncAsUint16LE(flags);
+		_flags._hide = flags & 0x0001 ? true : false;
+		_flags._near = flags & 0x0002 ? true : false;
+		_flags._drag = flags & 0x0004 ? true : false;
+		_flags._hold = flags & 0x0008 ? true : false;
+		_flags._dummy = flags & 0x0010 ? true : false;
+		_flags._slav = flags & 0x0020 ? true : false;
+		_flags._syst = flags & 0x0040 ? true : false;
+		_flags._kill = flags & 0x0080 ? true : false;
+		_flags._xlat = flags & 0x0100 ? true : false;
+		_flags._port = flags & 0x0200 ? true : false;
+		_flags._kept = flags & 0x0400 ? true : false;
+		_flags._east = flags & 0x0800 ? true : false;
+		_flags._shad = flags & 0x1000 ? true : false;
+		_flags._back = flags & 0x2000 ? true : false;
+		_flags._bDel = flags & 0x4000 ? true : false;
+		_flags._tran = flags & 0x8000 ? true : false;
+	} else {
+		flags = (flags << 1) | _flags._tran;
+		flags = (flags << 1) | _flags._bDel;
+		flags = (flags << 1) | _flags._back;
+		flags = (flags << 1) | _flags._shad;
+		flags = (flags << 1) | _flags._east;
+		flags = (flags << 1) | _flags._kept;
+		flags = (flags << 1) | _flags._port;
+		flags = (flags << 1) | _flags._xlat;
+		flags = (flags << 1) | _flags._kill;
+		flags = (flags << 1) | _flags._syst;
+		flags = (flags << 1) | _flags._slav;
+		flags = (flags << 1) | _flags._dummy;
+		flags = (flags << 1) | _flags._hold;
+		flags = (flags << 1) | _flags._drag;
+		flags = (flags << 1) | _flags._near;
+		flags = (flags << 1) | _flags._hide;
+		s.syncAsUint16LE(flags);
+	}
+
+	s.syncAsUint16LE(_x);
+	s.syncAsUint16LE(_y);
+	s.syncAsByte(_z);
+	s.syncAsUint16LE(_w);
+	s.syncAsUint16LE(_h);
+	s.syncAsUint16LE(_time);
+	s.syncAsByte(_nearPtr);
+	s.syncAsByte(_takePtr);
+	s.syncAsSint16LE(_seqPtr);
+	s.syncAsUint16LE(_shpCnt);
+	s.syncBytes((byte *)&_file[0], 9);
+	_file[8] = '\0';
+
+	s.syncAsUint16LE(unused);	// _prev
+	s.syncAsUint16LE(unused);	// _next
+}
+
+Queue::Queue(bool show) : _head(NULL), _tail(NULL), _show(show) {
+}
+
+Queue::~Queue() {
+	clear();
+}
+
+void Queue::clear() {
+	while (_head) {
+		Sprite *s = remove(_head);
+		if (s->_flags._kill)
+			delete s;
+	}
+}
+
+void Queue::append(Sprite *spr) {
+	if (_tail) {
+		spr->_prev = _tail;
+		_tail->_next = spr;
+	} else
+		_head = spr;
+	_tail = spr;
+	if (_show)
+		spr->expand();
+	else
+		spr->contract();
+}
+
+void Queue::insert(Sprite *spr, Sprite *nxt) {
+	if (nxt == _head) {
+		spr->_next = _head;
+		_head = spr;
+		if (!_tail)
+			_tail = spr;
+	} else {
+		assert(nxt);
+		spr->_next = nxt;
+		spr->_prev = nxt->_prev;
+		if (spr->_prev)
+			spr->_prev->_next = spr;
+	}
+	if (spr->_next)
+		spr->_next->_prev = spr;
+	if (_show)
+		spr->expand();
+	else
+		spr->contract();
+}
+
+void Queue::insert(Sprite *spr) {
+	Sprite *s;
+	for (s = _head; s; s = s->_next)
+		if (s->_z > spr->_z)
+			break;
+	if (s)
+		insert(spr, s);
+	else
+		append(spr);
+	if (_show)
+		spr->expand();
+	else
+		spr->contract();
+}
+
+template<typename T>
+inline bool contains(const Common::List<T> &l, const T &v) {
+	return (Common::find(l.begin(), l.end(), v) != l.end());
+}
+
+Sprite *Queue::remove(Sprite *spr) {
+	if (spr == _head)
+		_head = spr->_next;
+	if (spr == _tail)
+		_tail = spr->_prev;
+	if (spr->_next)
+		spr->_next->_prev = spr->_prev;
+	if (spr->_prev)
+		spr->_prev->_next = spr->_next;
+	spr->_prev = NULL;
+	spr->_next = NULL;
+	return spr;
+}
+
+Sprite *Queue::locate(int ref) {
+	for (Sprite *spr = _head; spr; spr = spr->_next) {
+		if (spr->_ref == ref)
+			return spr;
+	}
+	return NULL;
+}
+
+Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _mono(0), _vm(vm) {
+	_oldColors = NULL;
+	_newColors = NULL;
+	_showQ = new Queue(true);
+	_spareQ = new Queue(false);
+	_sysPal = new Dac[kPalCount];
+
+	for (int idx = 0; idx < 4; idx++) {
+		_page[idx] = new Graphics::Surface();
+		_page[idx]->create(kScrWidth, kScrHeight, Graphics::PixelFormat::createFormatCLUT8());
+	}
+
+	/*if (ConfMan.getBool("enable_color_blind"))
+		_mono = 1;*/
+	
+	warning("STUB: Vga::Vga()");
+
+	_oldColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
+	_newColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
+	getColors(_oldColors);
+	sunset();
+	setColors();
+	clear(0);
+}
+
+Vga::~Vga() {
+	_mono = 0;
+
+	Common::String buffer = "";
+/*
+	clear(0);
+	setMode(_oldMode);
+	setColors();
+	restoreScreen(_oldScreen);
+	sunrise(_oldColors);
+*/
+	warning("STUB: Vga::~Vga()");
+
+	free(_oldColors);
+	free(_newColors);
+	if (_msg)
+		buffer = Common::String(_msg);
+	if (_name)
+		buffer = buffer + " [" + _name + "]";
+
+	debugN("%s", buffer.c_str());
+
+	delete _showQ;
+	delete _spareQ;
+	delete[] _sysPal;
+
+	for (int idx = 0; idx < 4; idx++) {
+		_page[idx]->free();
+		delete _page[idx];
+	}
+}
+
+void Vga::waitVR() {
+	// Since some of the game parts rely on using vertical sync as a delay mechanism,
+	// we're introducing a short delay to simulate it
+	g_system->delayMillis(5);
+}
+
+void Vga::getColors(Dac *tab) {
+	byte palData[kPalSize];
+	g_system->getPaletteManager()->grabPalette(palData, 0, kPalCount);
+	palToDac(palData, tab);
+}
+
+uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB) {
+#define f(col, lum) ((((uint16)(col)) << 8) / lum)
+	uint16 i, dif = 0xFFFF, found = 0;
+	uint16 L = colR + colG + colB;
+	if (!L)
+		L++;
+	uint16 R = f(colR, L), G = f(colG, L), B = f(colB, L);
+	for (i = 0; i < 256; i++) {
+		uint16 l = pal[i]._r + pal[i]._g + pal[i]._b;
+		if (!l)
+			l++;
+		int  r = f(pal[i]._r, l), g = f(pal[i]._g, l), b = f(pal[i]._b, l);
+		uint16 D = ((r > R) ? (r - R) : (R - r)) +
+		           ((g > G) ? (g - G) : (G - g)) +
+		           ((b > B) ? (b - B) : (B - b)) +
+		           ((l > L) ? (l - L) : (L - l)) * 10 ;
+
+		if (D < dif) {
+			found = i;
+			dif = D;
+			if (D == 0)
+				break;    // exact!
+		}
+	}
+	return found;
+#undef f
+}
+
+uint8 *Vga::glass(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB) {
+	uint8 *x = (uint8 *)malloc(256);
+	if (x) {
+		uint16 i;
+		for (i = 0; i < 256; i++) {
+			x[i] = closest(pal, ((uint16)(pal[i]._r) * colR) / 255,
+			                    ((uint16)(pal[i]._g) * colG) / 255,
+			                    ((uint16)(pal[i]._b) * colB) / 255);
+		}
+	}
+	return x;
+}
+
+void Vga::palToDac(const byte *palData, Dac *tab) {
+	const byte *colP = palData;
+	for (int idx = 0; idx < kPalCount; idx++, colP += 3) {
+		tab[idx]._r = *colP >> 2;
+		tab[idx]._g = *(colP + 1) >> 2;
+		tab[idx]._b = *(colP + 2) >> 2;
+	}
+}
+
+void Vga::dacToPal(const Dac *tab, byte *palData) {
+	for (int idx = 0; idx < kPalCount; idx++, palData += 3) {
+		*palData = tab[idx]._r << 2;
+		*(palData + 1) = tab[idx]._g << 2;
+		*(palData + 2) = tab[idx]._b << 2;
+	}
+}
+
+void Vga::setColors(Dac *tab, int lum) {
+	Dac *palP = tab, *destP = _newColors;
+	for (int idx = 0; idx < kPalCount; idx++, palP++, destP++) {
+		destP->_r = (palP->_r * lum) >> 6;
+		destP->_g = (palP->_g * lum) >> 6;
+		destP->_b = (palP->_b * lum) >> 6;
+	}
+
+	if (_mono) {
+		destP = _newColors;
+		for (int idx = 0; idx < kPalCount; idx++, destP++) {
+			// Form a greyscalce color from 30% R, 59% G, 11% B
+			uint8 intensity = (((int)destP->_r * 77) + ((int)destP->_g * 151) + ((int)destP->_b * 28)) >> 8;
+			destP->_r = intensity;
+			destP->_g = intensity;
+			destP->_b = intensity;
+		}
+	}
+
+	_setPal = true;
+}
+
+void Vga::setColors() {
+	memset(_newColors, 0, kPalSize);
+	updateColors();
+}
+
+void Vga::sunrise(Dac *tab) {
+	for (int i = 0; i <= 64; i += kFadeStep) {
+		setColors(tab, i);
+		waitVR();
+		updateColors();
+	}
+}
+
+void Vga::sunset() {
+	Dac tab[256];
+	getColors(tab);
+	for (int i = 64; i >= 0; i -= kFadeStep) {
+		setColors(tab, i);
+		waitVR();
+		updateColors();
+	}
+}
+
+void Vga::show() {
+	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next)
+		spr->show();
+	update();
+	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next)
+		spr->hide();
+
+	_frmCnt++;
+}
+
+void Vga::updateColors() {
+	byte palData[kPalSize];
+	dacToPal(_newColors, palData);
+	g_system->getPaletteManager()->setPalette(palData, 0, 256);
+}
+
+void Vga::update() {
+	SWAP(Vga::_page[0], Vga::_page[1]);
+
+	if (_setPal) {
+		updateColors();
+		_setPal = false;
+	}
+	/*if (_vm->_showBoundariesFl) {
+		Vga::_page[0]->hLine(0, 200 - kPanHeight, 320, 0xee);
+		if (_vm->_barriers[_vm->_now]._horz != 255) {
+		for (int i = 0; i < 8; i++)
+		Vga::_page[0]->vLine((_vm->_barriers[_vm->_now]._horz * 8) + i, 0, 200, 0xff);
+		}
+		if (_vm->_barriers[_vm->_now]._vert != 255) {
+		for (int i = 0; i < 4; i++)
+		Vga::_page[0]->hLine(0, 80 + (_vm->_barriers[_vm->_now]._vert * 4) + i, 320, 0xff);
+		}
+		}*/
+
+	warning("STUB: Vga::update()");
+
+	g_system->copyRectToScreen(Vga::_page[0]->getPixels(), kScrWidth, 0, 0, kScrWidth, kScrHeight);
+	g_system->updateScreen();
+}
+
+void Vga::clear(uint8 color) {
+	for (int paneNum = 0; paneNum < 4; paneNum++)
+		_page[paneNum]->fillRect(Common::Rect(0, 0, kScrWidth, kScrHeight), color);
+}
+
+void Vga::copyPage(uint16 d, uint16 s) {
+	_page[d]->copyFrom(*_page[s]);
+}
+
+//--------------------------------------------------------------------------
+
+void Bitmap::xShow(int16 x, int16 y) {
+	const byte *srcP = (const byte *)_v;
+	byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
+	byte *lookupTable = _m;
+
+	// Loop through processing data for each plane. The game originally ran in plane mapped mode, where a
+	// given plane holds each fourth pixel sequentially. So to handle an entire picture, each plane's data
+	// must be decompressed and inserted into the surface
+	for (int planeCtr = 0; planeCtr < 4; planeCtr++) {
+		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x + planeCtr, y);
+
+		for (;;) {
+			uint16 v = READ_LE_UINT16(srcP);
+			srcP += 2;
+			int cmd = v >> 14;
+			int count = v & 0x3FFF;
+
+			if (cmd == 0) {
+				// End of image
+				break;
+			}
+
+			assert(destP < destEndP);
+
+			if (cmd == 2)
+				srcP++;
+			else if (cmd == 3)
+				srcP += count;
+
+			// Handle a set of pixels
+			while (count-- > 0) {
+				// Transfer operation
+				switch (cmd) {
+				case 1:
+					// SKIP
+					break;
+				case 2:
+				case 3:
+					// TINT
+					*destP = lookupTable[*destP];
+					break;
+				}
+
+				// Move to next dest position
+				destP += 4;
+			}
+		}
+	}
+}
+
+
+void Bitmap::show(int16 x, int16 y) {
+	const byte *srcP = (const byte *)_v;
+	byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
+
+	// Loop through processing data for each plane. The game originally ran in plane mapped mode, where a
+	// given plane holds each fourth pixel sequentially. So to handle an entire picture, each plane's data
+	// must be decompressed and inserted into the surface
+	for (int planeCtr = 0; planeCtr < 4; planeCtr++) {
+		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x + planeCtr, y);
+
+		for (;;) {
+			uint16 v = READ_LE_UINT16(srcP);
+			srcP += 2;
+			int cmd = v >> 14;
+			int count = v & 0x3FFF;
+
+			if (cmd == 0) {
+				// End of image
+				break;
+			}
+
+			assert(destP < destEndP);
+
+			// Handle a set of pixels
+			while (count-- > 0) {
+				// Transfer operation
+				switch (cmd) {
+				case 1:
+					// SKIP
+					break;
+				case 2:
+					// REPEAT
+					*destP = *srcP;
+					break;
+				case 3:
+					// COPY
+					*destP = *srcP++;
+					break;
+				}
+
+				// Move to next dest position
+				destP += 4;
+			}
+
+			if (cmd == 2)
+				srcP++;
+		}
+	}
+}
+
+
+void Bitmap::hide(int16 x, int16 y) {
+	for (int yp = y; yp < y + _h; yp++) {
+		const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(x, yp);
+		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x, yp);
+
+		Common::copy(srcP, srcP + _w, destP);
+	}
+}
+
+/*--------------------------------------------------------------------------*/
+
+HorizLine::HorizLine(CGE2Engine *vm) : Sprite(vm, NULL), _vm(vm) {
+	// Set the sprite list
+	BitmapPtr *HL = new BitmapPtr[2];
+	HL[0] = new Bitmap(_vm, "HLINE");
+	HL[1] = NULL;
+
+	setShapeList(HL);
+}
+
+SceneLight::SceneLight(CGE2Engine *vm) : Sprite(vm, NULL), _vm(vm) {
+	// Set the sprite list
+	BitmapPtr *PR = new BitmapPtr[2];
+	PR[0] = new Bitmap(_vm, "PRESS");
+	PR[1] = NULL;
+
+	setShapeList(PR);
+}
+
+Speaker::Speaker(CGE2Engine *vm): Sprite(vm, NULL), _vm(vm) {
+	// Set the sprite list
+	BitmapPtr *SP = new BitmapPtr[3];
+	SP[0] = new Bitmap(_vm, "SPK_L");
+	SP[1] = new Bitmap(_vm, "SPK_R");
+	SP[2] = NULL;
+
+	setShapeList(SP);
+}
+
+PocLight::PocLight(CGE2Engine *vm): Sprite(vm, NULL), _vm(vm) {
+	// Set the sprite list
+	BitmapPtr *LI = new BitmapPtr[5];
+	LI[0] = new Bitmap(_vm, "LITE0");
+	LI[1] = new Bitmap(_vm, "LITE1");
+	LI[2] = new Bitmap(_vm, "LITE2");
+	LI[3] = new Bitmap(_vm, "LITE3");
+	LI[4] = NULL;
+
+	setShapeList(LI);
+
+	_flags._kill = false;
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
new file mode 100644
index 0000000..e761c5c
--- /dev/null
+++ b/engines/cge2/vga13h.h
@@ -0,0 +1,243 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_VGA13H_H
+#define CGE2_VGA13H_H
+
+#include "common/serializer.h"
+#include "common/events.h"
+#include "graphics/surface.h"
+#include "cge2/general.h"
+#include "cge2/bitmap.h"
+//#include "cge/snail.h"
+#include "cge2/cge2.h"
+
+namespace CGE2 {
+
+#define kFadeStep        2
+#define kVgaColDark      207
+#define kVgaColDarkGray  225 /*219*/
+#define kVgaColGray      231
+#define kVgaColLightGray 237
+#define kPixelTransp     0xFE
+#define kNoSeq           (-1)
+#define kNoPtr           ((uint8)-1)
+#define kSprExt          ".SPR"
+#define kPalCount        256
+#define kPalSize         (kPalCount * 3)
+
+struct Seq {
+	uint8 _now;
+	uint8 _next;
+	int8 _dx;
+	int8 _dy;
+	int _dly;
+};
+
+class SprExt {
+public:
+	int _x0;
+	int _y0;
+	int _x1;
+	int _y1;
+	BitmapPtr _b0;
+	BitmapPtr _b1;
+	BitmapPtr *_shpList;
+	Seq *_seq;
+	char *_name;
+	/*CommandHandler::Command *_near;
+	CommandHandler::Command *_take;*/
+	SprExt() :
+		_x0(0), _y0(0),
+		_x1(0), _y1(0),
+		_b0(NULL), _b1(NULL),
+		_shpList(NULL), _seq(NULL),
+		_name(NULL)/*, _near(NULL), _take(NULL)*/
+	{}
+};
+
+class Sprite {
+protected:
+	SprExt *_ext;
+public:
+	int _ref;
+	signed char _scene;
+	struct Flags {
+		uint16 _hide : 1;       // general visibility switch
+		uint16 _near : 1;       // Near action lock
+		uint16 _drag : 1;       // sprite is moveable
+		uint16 _hold : 1;       // sprite is held with mouse
+		uint16 _dummy : 1;       // intrrupt driven animation
+		uint16 _slav : 1;       // slave object
+		uint16 _syst : 1;       // system object
+		uint16 _kill : 1;       // dispose memory after remove
+		uint16 _xlat : 1;       // 2nd way display: xlat table
+		uint16 _port : 1;       // portable
+		uint16 _kept : 1;       // kept in pocket
+		uint16 _east : 1;       // talk to east (in opposite to west)
+		uint16 _shad : 1;       // shadow
+		uint16 _back : 1;       // 'send to background' request
+		uint16 _bDel : 1;       // delete bitmaps in ~SPRITE
+		uint16 _tran : 1;       // transparent (untouchable)
+	} _flags;
+	int _x;
+	int _y;
+	signed char _z;
+	uint16 _w;
+	uint16 _h;
+	uint16 _time;
+	uint8 _nearPtr;
+	uint8 _takePtr;
+	int _seqPtr;
+	int _shpCnt;
+	char _file[kMaxFile];
+	Sprite *_prev;
+	Sprite *_next;
+
+	bool works(Sprite *spr);
+	bool seqTest(int n);
+	inline bool active() {
+		return _ext != NULL;
+	}
+
+	Sprite(CGE2Engine *vm, BitmapPtr *shp);
+	virtual ~Sprite();
+	BitmapPtr shp();
+	BitmapPtr *setShapeList(BitmapPtr *shp);
+	Sprite *expand();
+	Sprite *contract();
+	Sprite *backShow(bool fast = false);
+	void setName(char *newName);
+	inline char *name() {
+		return (_ext) ? _ext->_name : NULL;
+	}
+	void gotoxy(int x, int y);
+	void center();
+	void show();
+	void hide();
+	BitmapPtr ghost();
+	void show(uint16 pg);
+	void makeXlat(uint8 *x);
+	void killXlat();
+	void step(int nr = -1);
+	Seq *setSeq(Seq *seq);
+	//CommandHandler::Command *snList(SnList type);
+	/*virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
+	virtual void tick();*/
+	void sync(Common::Serializer &s);
+private:
+	CGE2Engine *_vm;
+};
+
+class Queue {
+	Sprite *_head;
+	Sprite *_tail;
+public:
+	Queue(bool show);
+	~Queue();
+
+	bool _show;
+
+	void append(Sprite *spr);
+	void insert(Sprite *spr, Sprite *nxt);
+	void insert(Sprite *spr);
+	Sprite *remove(Sprite *spr);
+	Sprite *first() {
+		return _head;
+	}
+	Sprite *last() {
+		return _tail;
+	}
+	Sprite *locate(int ref);
+	void clear();
+};
+
+class Vga {
+	CGE2Engine *_vm;
+	bool _setPal;
+	Dac *_oldColors;
+	Dac *_newColors;
+	const char *_msg;
+	const char *_name;
+
+	void updateColors();
+	void setColors();
+	void waitVR();
+	uint8 closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB);
+
+public:
+	uint32 _frmCnt;
+	Queue *_showQ;
+	Queue *_spareQ;
+	int _mono;
+	Graphics::Surface *_page[4];
+	Dac *_sysPal;
+
+	Vga(CGE2Engine *vm);
+	~Vga();
+
+	uint8 *glass(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB);
+	void getColors(Dac *tab);
+	void setColors(Dac *tab, int lum);
+	void clear(uint8 color);
+	void copyPage(uint16 d, uint16 s);
+	void sunrise(Dac *tab);
+	void sunset();
+	void show();
+	void update();
+
+	void palToDac(const byte *palData, Dac *tab);
+	void dacToPal(const Dac *tab, byte *palData);
+};
+
+class HorizLine: public Sprite {
+	CGE2Engine *_vm;
+public:
+	HorizLine(CGE2Engine *vm);
+};
+
+class SceneLight: public Sprite {
+	CGE2Engine *_vm;
+public:
+	SceneLight(CGE2Engine *vm);
+};
+
+class Speaker: public Sprite {
+	CGE2Engine *_vm;
+public:
+	Speaker(CGE2Engine *vm);
+};
+
+class PocLight: public Sprite {
+	CGE2Engine *_vm;
+public:
+	PocLight(CGE2Engine *vm);
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_VGA13H_H


Commit: 5b105566a5637edcf73fd6cbc690c1b3b958ff2a
    https://github.com/scummvm/scummvm/commit/5b105566a5637edcf73fd6cbc690c1b3b958ff2a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-04-29T11:26:39+02:00

Commit Message:
Merge remote-tracking branch 'origin/master' into cge2

Changed paths:
  A backends/platform/ps2/Makefile.ps2.dev
  A backends/platform/ps2/README.PS2
  R backends/platform/ps2/Makefile.gdb
    Makefile.common
    backends/fs/ps2/ps2-fs.cpp
    backends/fs/ps2/ps2-fs.h
    backends/platform/ps2/DmaPipe.cpp
    backends/platform/ps2/Gs2dScreen.cpp
    backends/platform/ps2/Gs2dScreen.h
    backends/platform/ps2/GsDefs.h
    backends/platform/ps2/Makefile.ps2
    backends/platform/ps2/asyncfio.cpp
    backends/platform/ps2/asyncfio.h
    backends/platform/ps2/cd.c
    backends/platform/ps2/eecodyvdfs.h
    backends/platform/ps2/fileio.cpp
    backends/platform/ps2/fileio.h
    backends/platform/ps2/icon.cpp
    backends/platform/ps2/iop/CoDyVDfs/common/codyvdirx.h
    backends/platform/ps2/iop/CoDyVDfs/iop/cdtypes.h
    backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c
    backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.h
    backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c
    backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c
    backends/platform/ps2/iop/rpckbd/include/ps2kbd.h
    backends/platform/ps2/iop/rpckbd/src/ps2kbd.c
    backends/platform/ps2/irxboot.cpp
    backends/platform/ps2/irxboot.h
    backends/platform/ps2/module.mk
    backends/platform/ps2/ps2debug.cpp
    backends/platform/ps2/ps2debug.h
    backends/platform/ps2/ps2input.cpp
    backends/platform/ps2/ps2input.h
    backends/platform/ps2/ps2pad.cpp
    backends/platform/ps2/ps2time.cpp
    backends/platform/ps2/rpckbd.c
    backends/platform/ps2/savefilemgr.cpp
    backends/platform/ps2/sysdefs.h
    backends/platform/ps2/systemps2.cpp
    backends/platform/ps2/systemps2.h
    backends/plugins/elf/version.cpp
    base/version.cpp
    common/scummsys.h
    configure
    engines/cge/cge.cpp
    engines/cge/vga13h.cpp
    engines/dialogs.cpp
    engines/draci/game.cpp
    engines/draci/game.h
    engines/draci/saveload.cpp
    engines/draci/saveload.h
    engines/draci/script.cpp
    engines/draci/walking.cpp
    engines/draci/walking.h
    engines/fullpipe/constants.h
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/input.cpp
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/messages.cpp
    engines/fullpipe/messages.h
    engines/fullpipe/modal.cpp
    engines/fullpipe/modal.h
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h
    engines/fullpipe/scenes.cpp
    engines/fullpipe/sound.cpp
    engines/fullpipe/sound.h
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h
    engines/pegasus/menu.cpp
    engines/pegasus/neighborhood/caldoria/caldoria.cpp
    engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
    engines/pegasus/neighborhood/caldoria/caldoriabomb.h
    engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp
    engines/pegasus/neighborhood/caldoria/caldoriamessages.h
    engines/pegasus/neighborhood/mars/mars.cpp
    engines/pegasus/neighborhood/neighborhood.cpp
    engines/pegasus/neighborhood/neighborhood.h
    engines/pegasus/neighborhood/norad/delta/globegame.cpp
    engines/pegasus/neighborhood/norad/delta/globegame.h
    engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
    engines/pegasus/neighborhood/norad/delta/noraddelta.h
    engines/pegasus/pegasus.cpp
    engines/sci/detection_tables.h
    engines/sword25/util/lua/loslib.cpp
    gui/dialog.cpp
    gui/widgets/tab.cpp
    gui/widgets/tab.h





Commit: 8e3bbbea7c97ac222a7f061b68fe161b455bf0f8
    https://github.com/scummvm/scummvm/commit/8e3bbbea7c97ac222a7f061b68fe161b455bf0f8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-01T22:52:20+02:00

Commit Message:
CGE2: Add sound code with working MIDI parts.

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



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 955c5eb..370846f 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -30,6 +30,7 @@
 #include "cge2/cge2.h"
 #include "cge2/bitmap.h"
 #include "cge2/vga13h.h"
+#include "cge2/sound.h"
 
 namespace CGE2 {
 
@@ -38,21 +39,31 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_resman = nullptr;
 	_vga = nullptr;
 	_sprite = nullptr;
+	_midiPlayer = nullptr;
+	_fx = nullptr;
+	_sound = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_mode = 0;
+	_music = true;
 }
 
 void CGE2Engine::init() {
 	_resman = new ResourceManager();
 	_vga = new Vga(this);
+	_fx = new Fx(this, 16);
+	_sound = new Sound(this);
+	_midiPlayer = new MusicPlayer(this);
 }
 
 void CGE2Engine::deinit() {
 	delete _resman;
 	delete _vga;
 	delete _sprite;
+	delete _fx;
+	delete _sound;
+	delete _midiPlayer;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
@@ -77,11 +88,18 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 }
 
 Common::Error CGE2Engine::run() {
+	warning("STUB: CGE2Engine::run()");
+
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();
-	warning("STUB: CGE2Engine::run()");
+	
 	showTitle("WELCOME");
+
+	// Temporary code to test the midi player.
+	_midiPlayer->loadMidi(1);
+	g_system->delayMillis(100000);
+	
 	deinit();
 	return Common::kNoError;
 }
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 814c607..9f7fcf6 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -38,6 +38,9 @@ namespace CGE2 {
 
 class Vga;
 class Sprite;
+class MusicPlayer;
+class Fx;
+class Sound;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -61,10 +64,14 @@ public:
 	bool _quitFlag;
 	Dac *_bitmapPalette;
 	int _mode;
+	bool _music;
 
 	ResourceManager *_resman;
 	Vga *_vga;
 	Sprite *_sprite;
+	MusicPlayer *_midiPlayer;
+	Fx *_fx;
+	Sound *_sound;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 493488f..f885933 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS = \
 	detection.o \
 	fileio.o \
 	vga13h.o \
-	bitmap.o
+	bitmap.o \
+	sound.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
new file mode 100644
index 0000000..a3e866f
--- /dev/null
+++ b/engines/cge2/sound.cpp
@@ -0,0 +1,290 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/sound.h"
+//#include "cge/text.h"
+//#include "cge/cge_main.h"
+#include "common/config-manager.h"
+#include "common/memstream.h"
+#include "audio/decoders/raw.h"
+#include "audio/audiostream.h"
+#include "cge2/cge2.h"
+
+namespace CGE2 {
+
+DataCk::DataCk(byte *buf, int bufSize) {
+	_buf = buf;
+	_ckSize = bufSize;
+}
+
+DataCk::~DataCk() {
+	free(_buf);
+}
+
+Sound::Sound(CGE2Engine *vm) : _vm(vm) {
+	_audioStream = NULL;
+	_soundRepeatCount = 1;
+	open();
+}
+
+Sound::~Sound() {
+	close();
+}
+
+void Sound::close() {
+	_vm->_midiPlayer->killMidi();
+}
+
+void Sound::open() {
+	setRepeat(1);
+	play((*_vm->_fx)[30000], 8);
+}
+
+void Sound::setRepeat(int16 count) {
+	_soundRepeatCount = count;
+}
+
+int16 Sound::getRepeat() {
+	return _soundRepeatCount;
+}
+
+void Sound::play(DataCk *wav, int pan) {
+	if (wav) {
+		stop();
+		_smpinf._saddr = &*(wav->addr());
+		_smpinf._slen = (uint16)wav->size();
+		_smpinf._span = pan;
+		_smpinf._counter = getRepeat();
+		sndDigiStart(&_smpinf);
+	}
+}
+
+void Sound::sndDigiStart(SmpInfo *PSmpInfo) {
+	// Create an audio stream wrapper for sound
+	Common::MemoryReadStream *stream = new Common::MemoryReadStream(PSmpInfo->_saddr,
+		PSmpInfo->_slen, DisposeAfterUse::NO);
+	_audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
+
+	// Start the new sound
+	_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle,
+		Audio::makeLoopingAudioStream(_audioStream, (uint)PSmpInfo->_counter));
+
+	// CGE pan:
+	// 8 = Center
+	// Less = Left
+	// More = Right
+	_vm->_mixer->setChannelBalance(_soundHandle, (int8)CLIP(((PSmpInfo->_span - 8) * 16), -127, 127));
+}
+
+void Sound::stop() {
+	sndDigiStop(&_smpinf);
+}
+
+void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
+	if (_vm->_mixer->isSoundHandleActive(_soundHandle))
+		_vm->_mixer->stopHandle(_soundHandle);
+	_audioStream = NULL;
+}
+
+Fx::Fx(CGE2Engine *vm, int size) : _current(NULL), _vm(vm) {
+	_cache = new Handler[size];
+	for (_size = 0; _size < size; _size++) {
+		_cache[_size]._ref = 0;
+		_cache[_size]._wav = NULL;
+	}
+}
+
+Fx::~Fx() {
+	clear();
+	delete[] _cache;
+}
+
+void Fx::clear() {
+	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
+		if (p->_ref) {
+			p->_ref = 0;
+			delete p->_wav;
+			p->_wav = NULL;
+		}
+	}
+	_current = NULL;
+}
+
+int Fx::find(int ref) {
+	int i = 0;
+	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
+		if (p->_ref == ref)
+			break;
+		else
+			++i;
+	}
+	return i;
+}
+
+void Fx::name(int ref, int sub) {
+	warning("STUB:  Fx::name()");
+}
+
+DataCk *Fx::load(int idx, int ref) {
+	char filename[12];
+	warning("TODO: Implement Fx::load() with the use of Fx::name() properly in paralell with Snail! It just won't work this way.");
+	sprintf(filename, "FX%05d.WAV", ref);
+
+	EncryptedStream file(_vm, filename);
+	DataCk *wav = loadWave(&file);
+	if (wav) {
+		Handler *p = &_cache[idx];
+		delete p->_wav;
+		p->_wav = wav;
+		p->_ref = ref;
+	} else {
+		warning("Unable to load %s", filename);
+	}
+	return wav;
+}
+
+DataCk *Fx::loadWave(EncryptedStream *file) {
+	byte *data = (byte *)malloc(file->size());
+
+	if (!data)
+		return 0;
+
+	file->read(data, file->size());
+
+	return new DataCk(data, file->size());
+}
+
+DataCk *Fx::operator[](int ref) {
+	int i;
+	if ((i = find(ref)) < _size)
+		_current = _cache[i]._wav;
+	else {
+		if ((i = find(0)) >= _size) {
+			clear();
+			i = 0;
+		}
+		_current = load(i, ref);
+	}
+	return _current;
+}
+
+MusicPlayer::MusicPlayer(CGE2Engine *vm) : _vm(vm) {
+	_data = NULL;
+	_isGM = false;
+
+	MidiPlayer::createDriver();
+
+	int ret = _driver->open();
+	if (ret == 0) {
+		if (_nativeMT32)
+			_driver->sendMT32Reset();
+		else
+			_driver->sendGMReset();
+
+		// TODO: Load cmf.ins with the instrument table.  It seems that an
+		// interface for such an operation is supported for AdLib.  Maybe for
+		// this card, setting instruments is necessary.
+
+		_driver->setTimerCallback(this, &timerCallback);
+	}
+	_dataSize = -1;
+}
+
+MusicPlayer::~MusicPlayer() {
+	killMidi();
+}
+
+void MusicPlayer::killMidi() {
+	Audio::MidiPlayer::stop();
+
+	free(_data);
+	_data = NULL;
+}
+
+void MusicPlayer::loadMidi(int ref) {
+	warning("STUB: MusicPlayer::loadMidi()"); // if (MidiNotify) MidiNotify();
+
+	// Work out the filename and check the given MIDI file exists
+	Common::String filename = Common::String::format("%.2dSG%.2d.MID", ref >> 8, ref & 0xFF);
+	if (!_vm->_resman->exist(filename.c_str()))
+		return;
+
+	// Stop any currently playing MIDI file
+	killMidi();
+
+	// Read in the data for the file
+	EncryptedStream mid(_vm, filename.c_str());
+	_dataSize = mid.size();
+	_data = (byte *)malloc(_dataSize);
+	mid.read(_data, _dataSize);
+
+	// Start playing the music
+	sndMidiStart();
+}
+
+void MusicPlayer::sndMidiStart() {
+	_isGM = true;
+
+	MidiParser *parser = MidiParser::createParser_SMF();
+	if (parser->loadMusic(_data, _dataSize)) {
+		parser->setTrack(0);
+		parser->setMidiDriver(this);
+		parser->setTimerRate(_driver->getBaseTempo());
+		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
+
+		_parser = parser;
+
+		syncVolume();
+
+		// Al the tracks are supposed to loop
+		_isLooping = true;
+		_isPlaying = true;
+	}
+}
+
+void MusicPlayer::send(uint32 b) {
+	if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+		b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+	}
+
+	Audio::MidiPlayer::send(b);
+}
+
+void MusicPlayer::sendToChannel(byte channel, uint32 b) {
+	if (!_channelsTable[channel]) {
+		_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
+		// If a new channel is allocated during the playback, make sure
+		// its volume is correctly initialized.
+		if (_channelsTable[channel])
+			_channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255);
+	}
+
+	if (_channelsTable[channel])
+		_channelsTable[channel]->send(b);
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
new file mode 100644
index 0000000..c488c3f
--- /dev/null
+++ b/engines/cge2/sound.h
@@ -0,0 +1,135 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_SOUND_H
+#define CGE2_SOUND_H
+
+#include "cge2/fileio.h"
+#include "audio/audiostream.h"
+#include "audio/decoders/wave.h"
+#include "audio/fmopl.h"
+#include "audio/mididrv.h"
+#include "audio/midiparser.h"
+#include "audio/midiplayer.h"
+#include "audio/mixer.h"
+#include "common/memstream.h"
+
+namespace CGE2 {
+
+class CGE2Engine;
+
+// sample info
+struct SmpInfo {
+	const uint8  *_saddr;                              // address
+	uint16  _slen;                                     // length
+	uint16  _span;                                     // left/right pan (0-15)
+	int     _counter;                                  // number of time the sample should be played
+};
+
+class DataCk {
+	byte *_buf;
+	int _ckSize;
+public:
+	DataCk(byte *buf, int bufSize);
+	~DataCk();
+	inline const byte *addr() {
+		return _buf;
+	}
+	inline int size() {
+		return _ckSize;
+	}
+};
+
+class Sound {
+public:
+	SmpInfo _smpinf;
+
+	Sound(CGE2Engine *vm);
+	~Sound();
+	void open();
+	void close();
+	void play(DataCk *wav, int pan);
+	int16 getRepeat();
+	void setRepeat(int16 count);
+	void stop();
+private:
+	int _soundRepeatCount;
+	CGE2Engine *_vm;
+	Audio::SoundHandle _soundHandle;
+	Audio::RewindableAudioStream *_audioStream;
+
+	void sndDigiStart(SmpInfo *PSmpInfo);
+	void sndDigiStop(SmpInfo *PSmpInfo);
+};
+
+class Fx {
+	CGE2Engine *_vm;
+	struct Handler {
+		int _ref;
+		DataCk *_wav;
+	} *_cache;
+	int _size;
+
+	DataCk *load(int idx, int ref);
+	DataCk *loadWave(EncryptedStream *file);
+	int find(int ref);
+public:
+	DataCk *_current;
+
+	Fx(CGE2Engine *vm, int size);
+	~Fx();
+	void clear();
+	void name(int ref, int sub);
+	DataCk *operator[](int ref);
+};
+
+class MusicPlayer: public Audio::MidiPlayer {
+private:
+	CGE2Engine *_vm;
+	byte *_data;
+	int _dataSize;
+	bool _isGM;
+
+	// Start MIDI File
+	void sndMidiStart();
+
+	// Stop MIDI File
+	void sndMidiStop();
+public:
+	MusicPlayer(CGE2Engine *vm);
+	~MusicPlayer();
+
+	void loadMidi(int ref);
+	void killMidi();
+
+	virtual void send(uint32 b);
+	virtual void sendToChannel(byte channel, uint32 b);
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_SOUND_H


Commit: b595d9ee0a66c3a8980b0c513529bd0ff0ffe5b5
    https://github.com/scummvm/scummvm/commit/b595d9ee0a66c3a8980b0c513529bd0ff0ffe5b5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-05T18:59:17+02:00

Commit Message:
CGE2: Add Text and a reduced skeleton of cge2_main.

Changed paths:
  A engines/cge2/cge2_main.cpp
  A engines/cge2/cge2_main.h
  A engines/cge2/text.cpp
  A engines/cge2/text.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 370846f..bc2ce56 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -31,6 +31,7 @@
 #include "cge2/bitmap.h"
 #include "cge2/vga13h.h"
 #include "cge2/sound.h"
+#include "cge2/text.h"
 
 namespace CGE2 {
 
@@ -42,11 +43,13 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_midiPlayer = nullptr;
 	_fx = nullptr;
 	_sound = nullptr;
+	_text = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_mode = 0;
 	_music = true;
+	_startupMode = 1;
 }
 
 void CGE2Engine::init() {
@@ -55,6 +58,7 @@ void CGE2Engine::init() {
 	_fx = new Fx(this, 16);
 	_sound = new Sound(this);
 	_midiPlayer = new MusicPlayer(this);
+	_text = new Text(this, "CGE");
 }
 
 void CGE2Engine::deinit() {
@@ -64,6 +68,7 @@ void CGE2Engine::deinit() {
 	delete _fx;
 	delete _sound;
 	delete _midiPlayer;
+	delete _text;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
@@ -93,12 +98,8 @@ Common::Error CGE2Engine::run() {
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();
-	
-	showTitle("WELCOME");
 
-	// Temporary code to test the midi player.
-	_midiPlayer->loadMidi(1);
-	g_system->delayMillis(100000);
+	cge2_main();
 	
 	deinit();
 	return Common::kNoError;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 9f7fcf6..2c06832 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -41,6 +41,7 @@ class Sprite;
 class MusicPlayer;
 class Fx;
 class Sound;
+class Text;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -58,6 +59,11 @@ public:
 	virtual Common::Error run();
 
 	bool showTitle(const char *name);
+	void cge2_main();
+	char *mergeExt(char *buf, const char *name, const char *ext);
+	void inf(const char *text, bool wideSpace = false);
+	void movie(const char *ext);
+	void runGame();
 
 	const ADGameDescription *_gameDescription;
 
@@ -65,6 +71,7 @@ public:
 	Dac *_bitmapPalette;
 	int _mode;
 	bool _music;
+	int _startupMode;
 
 	ResourceManager *_resman;
 	Vga *_vga;
@@ -72,6 +79,7 @@ public:
 	MusicPlayer *_midiPlayer;
 	Fx *_fx;
 	Sound *_sound;
+	Text *_text;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
new file mode 100644
index 0000000..d3feb0a
--- /dev/null
+++ b/engines/cge2/cge2_main.cpp
@@ -0,0 +1,70 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "sound.h"
+#include "cge2/cge2_main.h"
+#include "cge2/cge2.h"
+#include "cge2/vga13h.h"
+#include "cge2/text.h"
+
+namespace CGE2 {
+
+void CGE2Engine::movie(const char *ext) {
+	warning("STUB: CGE2Engine::movie()");
+}
+
+void CGE2Engine::runGame() {
+	warning("STUB: CGE2Engine::runGame()");
+}
+
+void CGE2Engine::cge2_main() {
+	warning("STUB: CGE2Engine::cge2_main()");
+
+	_mode++;
+
+	if (showTitle("WELCOME")) {
+		if (_mode == 1)
+			movie(kIntroExt);
+		if (_text->getText(255) != NULL) {
+			runGame();
+			_startupMode = 2;
+		} else
+			_vga->sunset();
+	} else
+		_vga->sunset();
+}
+
+char *CGE2Engine::mergeExt(char *buf, const char *name, const char *ext) {
+	strcpy(buf, name);
+	char *dot = strrchr(buf, '.');
+	if (!dot)
+		strcat(buf, ext);
+
+	return buf;
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
new file mode 100644
index 0000000..a1fb071
--- /dev/null
+++ b/engines/cge2/cge2_main.h
@@ -0,0 +1,38 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_MAIN_H
+#define CGE2_MAIN_H
+
+namespace CGE2 {
+
+#define kLineMax       512
+#define kIntroExt      ".I80"
+
+} // End of namespace CGE2
+
+#endif // CGE2_MAIN_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index f885933..4fb9156 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -6,7 +6,9 @@ MODULE_OBJS = \
 	fileio.o \
 	vga13h.o \
 	bitmap.o \
-	sound.o
+	sound.o \
+	cge2_main.o \
+	text.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
new file mode 100644
index 0000000..e65c19f
--- /dev/null
+++ b/engines/cge2/text.cpp
@@ -0,0 +1,152 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+//#include "cge/general.h"
+#include "cge2/text.h"
+//#include "cge/talk.h"
+//#include "cge/game.h"
+//#include "cge/snail.h"
+#include "cge2/cge2_main.h"
+#include "common/str.h"
+
+namespace CGE2 {
+
+Text::Text(CGE2Engine *vm, const char *fname) : _vm(vm) {
+	_vm->mergeExt(_fileName, fname, kSayExt);
+	if (!_vm->_resman->exist(_fileName))
+		error("No talk (%s)", _fileName);
+	int16 txtCount = count() + 1;
+	if (!txtCount)
+		error("Unable to read dialog file %s", _fileName);
+
+	_cache = new Handler[txtCount];
+	for (_size = 0; _size < txtCount; _size++) {
+		_cache[_size]._ref = 0;
+		_cache[_size]._text = NULL;
+	}
+	load();
+}
+
+Text::~Text() {
+	clear();
+	delete[] _cache;
+}
+
+int16 Text::count() {
+	EncryptedStream tf(_vm, _fileName);
+	if (tf.err())
+		return -1;
+
+	Common::String line;
+	char tmpStr[kLineMax + 1];
+
+	int counter = 0;
+
+	for (line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
+		char *s;
+		assert(line.size() <= 513);
+		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+		if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
+			continue;
+		if (!Common::isDigit(*s))
+			continue;
+
+		counter++;
+	}
+	return counter;
+}
+
+void Text::clear() {
+	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
+		if (p->_ref) {
+			p->_ref = 0;
+			delete[] p->_text;
+			p->_text = NULL;
+		}
+	}
+}
+
+void Text::load() {
+	EncryptedStream tf(_vm, _fileName);
+	assert(!tf.err());
+
+	Common::String line;
+	char tmpStr[kLineMax + 1];
+	int idx;
+
+	for (idx = 0, line = tf.readLine(); !tf.eos(); line = tf.readLine()) {
+		int n = line.size();
+		char *s;
+		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+		if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
+			continue;
+		if (!Common::isDigit(*s))
+			continue;
+
+		int r = atoi(s);
+
+		s += strlen(s);
+		if (s < tmpStr + n)
+			++s;
+
+		_cache[idx]._ref = r;
+		_cache[idx]._text = new char[strlen(s) + 1];
+		strcpy(_cache[idx]._text, s);
+		idx++;
+	}
+}
+
+char *Text::getText(int ref) {
+	int i;
+	for (i = 0; (i < _size) && (_cache[i]._ref != ref); i++)
+		;
+
+	if (i < _size)
+		return _cache[i]._text;
+
+	warning("getText: Unable to find ref %d", ref);
+	return NULL;
+}
+
+void Text::say(const char *text, Sprite *spr) {
+	warning("STUB: Text::say()");
+}
+
+void CGE2Engine::inf(const char *text, bool wideSpace) {
+	warning("STUB: CGE2Engine::inf()");
+}
+
+void Text::sayTime(Sprite *spr) {
+	TimeDate curTime;
+	_vm->_system->getTimeAndDate(curTime);
+
+	char t[6];
+	sprintf(t, "%d:%02d", curTime.tm_hour, curTime.tm_min);
+	say(t, spr);
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/text.h b/engines/cge2/text.h
new file mode 100644
index 0000000..634a3c8
--- /dev/null
+++ b/engines/cge2/text.h
@@ -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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_TEXT_H
+#define CGE2_TEXT_H
+
+//#include "cge/talk.h"
+#include "cge2/cge2.h"
+
+namespace CGE2 {
+
+#define kSayExt         ".SAY"
+#define kSysTextMax     1000
+#define kTextNoMouse    95
+#define kInfName        101
+#define kSayName        102
+#define kInfRef         301
+#define kSayRef         302
+
+
+class Text {
+	struct Handler {
+		int _ref;
+		char *_text;
+	} *_cache;
+	int _size;
+	char _fileName[kPathMax];
+	void load();
+	int16 count();
+public:
+	Text(CGE2Engine *vm, const char *fname);
+	~Text();
+	void clear();
+	char *getText(int ref);
+	void say(const char *text, Sprite *spr);
+	void sayTime(Sprite *spr);
+private:
+	CGE2Engine *_vm;
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_TEXT_H


Commit: a0c5805c8efba2e184b737dc7869092318743004
    https://github.com/scummvm/scummvm/commit/a0c5805c8efba2e184b737dc7869092318743004
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-05T20:31:21+02:00

Commit Message:
CGE2: Read identifiers properly in Text::load().

Changed paths:
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h
    engines/cge2/text.cpp



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 4da2c52..fb39cd3 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -232,6 +232,14 @@ Common::String EncryptedStream::readLine() {
 	return _readStream->readLine();
 }
 
+int EncryptedStream::number(char *s) {
+	int r = atoi(s);
+	char *pp = strchr(s, ':');
+	if (pp)
+		r = (r << 8) + atoi(pp + 1);
+	return r;
+}
+
 int32 EncryptedStream::size() {
 	return _readStream->size();
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 42bb2ee..0597c6a 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -113,6 +113,7 @@ public:
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
 	Common::String readLine();
+	int number(char *s);
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index e65c19f..de33717 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -107,7 +107,7 @@ void Text::load() {
 		if (!Common::isDigit(*s))
 			continue;
 
-		int r = atoi(s);
+		int r = tf.number(s);
 
 		s += strlen(s);
 		if (s < tmpStr + n)


Commit: 0cbed1f53bc5caf936b21fc65080479f4be22c32
    https://github.com/scummvm/scummvm/commit/0cbed1f53bc5caf936b21fc65080479f4be22c32
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-06T21:02:58+02:00

Commit Message:
CGE2: Start implementation of movie() and connected functions.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index bc2ce56..853f84f 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -50,6 +50,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_mode = 0;
 	_music = true;
 	_startupMode = 1;
+	_now = 1;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 2c06832..01c38fa 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -64,6 +64,8 @@ public:
 	void inf(const char *text, bool wideSpace = false);
 	void movie(const char *ext);
 	void runGame();
+	void loadScript(const char *fname);
+	void loadSprite(const char *fname, int ref, int scene, int col, int row, int pos);
 
 	const ADGameDescription *_gameDescription;
 
@@ -72,6 +74,7 @@ public:
 	int _mode;
 	bool _music;
 	int _startupMode;
+	int _now;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d3feb0a..34946c7 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -33,8 +33,103 @@
 
 namespace CGE2 {
 
+void CGE2Engine::loadSprite(const char *fname, int ref, int scene, int col = 0, int row = 0, int pos = 0) {
+	warning("STUB: CGE2Engine::loadSprite");
+}
+
+void CGE2Engine::loadScript(const char *fname) {
+	EncryptedStream scrf(this, fname);
+
+	if (scrf.err())
+		return;
+
+	bool ok = true;
+	int lcnt = 0;
+
+	char tmpStr[kLineMax + 1];
+	Common::String line;
+
+	int lineNum = 0;
+	for (line = scrf.readLine(); !scrf.eos(); line = scrf.readLine()) {
+		lineNum++;
+
+		char *p;
+
+		lcnt++;
+		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+		if ((line.size() == 0) || (*tmpStr == ';')) // Comments start with ';' - don't bother with them.
+			continue;
+
+		ok = false; // not OK if break
+
+		// sprite ident number
+		if ((p = strtok(tmpStr, " \t\n")) == NULL)
+			break;
+		int SpI = scrf.number(p);
+
+		// sprite file name
+		char *SpN;
+		if ((SpN = strtok(NULL, " ,;/\t\n")) == NULL)
+			break;
+
+		// sprite scene
+		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+			break;
+		int SpA = scrf.number(p);
+
+		// sprite column
+		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+			break;
+		int SpX = scrf.number(p);
+
+		// sprite row
+		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+			break;
+		int SpY = scrf.number(p);
+
+		// sprite Z pos
+		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+			break;
+		int SpZ = scrf.number(p);
+
+		// sprite life
+		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+			break;
+		bool BkG = scrf.number(p) == 0;
+
+		ok = true; // no break: OK
+
+		_sprite = NULL;
+		loadSprite(SpN, SpI, SpA, SpX, SpY, SpZ);
+		if (_sprite) {
+			warning("STUB: CGE2Engine::loadScript - SPARE:: thing");
+			if (BkG)
+				_sprite->_flags._back = true;
+		}
+	}
+
+	if (!ok)
+		error("Bad INI line %d [%s]", lineNum, fname); // Counting starts from 0!
+}
+
 void CGE2Engine::movie(const char *ext) {
-	warning("STUB: CGE2Engine::movie()");
+	assert(ext);
+
+	if (_quitFlag)
+		return;
+
+	char fn[12];
+	sprintf(fn, "CGE.%s", (*ext == '.') ? ext + 1 : ext);
+
+	if (_resman->exist(fn)) {
+		int now = _now;
+		_now = atoi(ext + 1);
+		loadScript(fn);
+
+		warning("STUB:  CGE2Engine::movie()");
+
+		_now = now;
+	}
 }
 
 void CGE2Engine::runGame() {


Commit: e3c4caabfaed1c91f16e05157af3555fc2ccc018
    https://github.com/scummvm/scummvm/commit/e3c4caabfaed1c91f16e05157af3555fc2ccc018
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T10:45:38+02:00

Commit Message:
CGE2: Make number() static, add token() to File I/O.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 34946c7..40dd985 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -63,39 +63,39 @@ void CGE2Engine::loadScript(const char *fname) {
 		ok = false; // not OK if break
 
 		// sprite ident number
-		if ((p = strtok(tmpStr, " \t\n")) == NULL)
+		if ((p = EncryptedStream::token(tmpStr)) == NULL)
 			break;
-		int SpI = scrf.number(p);
+		int SpI = EncryptedStream::number(p);
 
 		// sprite file name
 		char *SpN;
-		if ((SpN = strtok(NULL, " ,;/\t\n")) == NULL)
+		if ((SpN = EncryptedStream::token(NULL)) == NULL)
 			break;
 
 		// sprite scene
-		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+		if ((p = EncryptedStream::token(NULL)) == NULL)
 			break;
-		int SpA = scrf.number(p);
+		int SpA = EncryptedStream::number(p);
 
 		// sprite column
-		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+		if ((p = EncryptedStream::token(NULL)) == NULL)
 			break;
-		int SpX = scrf.number(p);
+		int SpX = EncryptedStream::number(p);
 
 		// sprite row
-		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+		if ((p = EncryptedStream::token(NULL)) == NULL)
 			break;
-		int SpY = scrf.number(p);
+		int SpY = EncryptedStream::number(p);
 
 		// sprite Z pos
-		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+		if ((p = EncryptedStream::token(NULL)) == NULL)
 			break;
-		int SpZ = scrf.number(p);
+		int SpZ = EncryptedStream::number(p);
 
 		// sprite life
-		if ((p = strtok(NULL, " ,;/\t\n")) == NULL)
+		if ((p = EncryptedStream::token(NULL)) == NULL)
 			break;
-		bool BkG = scrf.number(p) == 0;
+		bool BkG = EncryptedStream::number(p) == 0;
 
 		ok = true; // no break: OK
 
@@ -126,7 +126,7 @@ void CGE2Engine::movie(const char *ext) {
 		_now = atoi(ext + 1);
 		loadScript(fn);
 
-		warning("STUB:  CGE2Engine::movie()");
+		warning("STUB: CGE2Engine::movie()");
 
 		_now = now;
 	}
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index fb39cd3..7677699 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -240,6 +240,10 @@ int EncryptedStream::number(char *s) {
 	return r;
 }
 
+char *EncryptedStream::token(char *s) {
+	return strtok(s, " =\t,;/()");
+}
+
 int32 EncryptedStream::size() {
 	return _readStream->size();
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 0597c6a..a596d71 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -113,7 +113,8 @@ public:
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
 	Common::String readLine();
-	int number(char *s);
+	static int number(char *s);
+	static char *token(char *s);
 };
 
 } // End of namespace CGE2


Commit: a3b274ba622c67cb597fa9b49b55ff416dc34236
    https://github.com/scummvm/scummvm/commit/a3b274ba622c67cb597fa9b49b55ff416dc34236
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T10:46:18+02:00

Commit Message:
CGE2: Add new types: V2D and V3D.

Changed paths:
    engines/cge2/general.h



diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 7d5c60f..5564cd0 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -29,15 +29,77 @@
 #define CGE2_GENERAL_H
 
 #include "common/file.h"
+#include "common/rect.h"
+#include "cge2/fileio.h"
 
 namespace CGE2 {
 
+#define SCR_WID_ 320
+
 struct Dac {
 	uint8 _r;
 	uint8 _g;
 	uint8 _b;
 };
 
+// From CGETYPE.H:
+class V3D {
+public:
+	double X, Y, Z;
+	V3D(void) { }
+	V3D(double x, double y, double z = 0) : X(x), Y(y), Z(z) { }
+	V3D(const V3D &p) : X(p.X), Y(p.Y), Z(p.Z) { }
+	V3D operator + (const V3D& p) const { return V3D(X + p.X, Y + p.Y, Z + p.Z); }
+	V3D operator - (const V3D& p) const { return V3D(X - p.X, Y - p.Y, Z - p.Z); }
+	V3D operator * (long n) const { return V3D(X * n, Y * n, Z * n); }
+	V3D operator / (long n) const { return V3D(X / n, Y / n, Z / n); }
+	bool operator == (V3D& p) const { return X == p.X && Y == p.Y && Z == p.Z; }
+	bool operator != (V3D& p) const { return X != p.X || Y != p.Y || Z != p.Z; }
+	V3D& operator += (const V3D& x) { return *this = *this + x; }
+	V3D& operator -= (const V3D& x) { return *this = *this - x; }
+};
+
+class V2D : public Common::Point {
+	double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
+	double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
+public:
+	V2D& operator = (const V3D& p3) {
+		double m = Eye.Z / (p3.Z - Eye.Z);
+		x = round((Eye.X + (Eye.X - p3.X) * m));
+		y = round((Eye.Y + (Eye.Y - p3.Y) * m));
+		return *this;
+	}
+	V2D(void) { }
+	V2D(const V3D& p3) { *this = p3; }
+	V2D(int x, int y) : Common::Point(x, y) { }
+	static V3D Eye;
+	static void SetEye(const V3D &e) { Eye = e; }
+	static void SetEye(const V2D& e2, int z = -SCR_WID_) {
+		Eye.X = e2.x; Eye.Y = e2.y; Eye.Z = z;
+	}
+	static void SetEye(const char *s) {
+		char *tempStr;
+		strcpy(tempStr, s);
+		Eye.X = atoi(EncryptedStream::token(tempStr));
+		Eye.Y = atoi(EncryptedStream::token(tempStr));
+		Eye.Z = atoi(EncryptedStream::token(tempStr));
+	}
+	bool operator <  (const V2D& p) const { return (x <  p.x) && (y <  p.y); }
+	bool operator <= (const V2D& p) const { return (x <= p.x) && (y <= p.y); }
+	bool operator >(const V2D& p) const { return (x >  p.x) && (y >  p.y); }
+	bool operator >= (const V2D& p) const { return (x >= p.x) && (y >= p.y); }
+	V2D operator + (const V2D& p) const { return V2D(x + p.x, y + p.y); }
+	V2D operator - (const V2D& p) const { return V2D(x - p.x, y - p.y); }
+	uint16 Area(void) { return x * y; }
+	bool Limited(const V2D& p) {
+		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
+	}
+	V2D Scale(int z) {
+		double m = Eye.Z / (Eye.Z - z);
+		return V2D(trunc(m * x), trunc(m * y));
+	}
+};
+
 } // End of namespace CGE2
 
 #endif // CGE2_GENERAL_H


Commit: 5c8d9241aa119c60313cb9d74c033a690fd57fa0
    https://github.com/scummvm/scummvm/commit/5c8d9241aa119c60313cb9d74c033a690fd57fa0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T13:43:02+02:00

Commit Message:
CGE2: Use nullptrs instead of NULLs.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 40dd985..4907dd3 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -69,31 +69,31 @@ void CGE2Engine::loadScript(const char *fname) {
 
 		// sprite file name
 		char *SpN;
-		if ((SpN = EncryptedStream::token(NULL)) == NULL)
+		if ((SpN = EncryptedStream::token(nullptr)) == NULL)
 			break;
 
 		// sprite scene
-		if ((p = EncryptedStream::token(NULL)) == NULL)
+		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
 		int SpA = EncryptedStream::number(p);
 
 		// sprite column
-		if ((p = EncryptedStream::token(NULL)) == NULL)
+		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
 		int SpX = EncryptedStream::number(p);
 
 		// sprite row
-		if ((p = EncryptedStream::token(NULL)) == NULL)
+		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
 		int SpY = EncryptedStream::number(p);
 
 		// sprite Z pos
-		if ((p = EncryptedStream::token(NULL)) == NULL)
+		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
 		int SpZ = EncryptedStream::number(p);
 
 		// sprite life
-		if ((p = EncryptedStream::token(NULL)) == NULL)
+		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
 		bool BkG = EncryptedStream::number(p) == 0;
 


Commit: 42f3dd6d2b0adf0822066e5e1cf2c83e553094d5
    https://github.com/scummvm/scummvm/commit/42f3dd6d2b0adf0822066e5e1cf2c83e553094d5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T14:31:12+02:00

Commit Message:
CGE2: Some renaming in V3D and V2D.

Changed paths:
    engines/cge2/general.h



diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 5564cd0..a9b7002 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -45,16 +45,16 @@ struct Dac {
 // From CGETYPE.H:
 class V3D {
 public:
-	double X, Y, Z;
+	double _x, _y, _z;
 	V3D(void) { }
-	V3D(double x, double y, double z = 0) : X(x), Y(y), Z(z) { }
-	V3D(const V3D &p) : X(p.X), Y(p.Y), Z(p.Z) { }
-	V3D operator + (const V3D& p) const { return V3D(X + p.X, Y + p.Y, Z + p.Z); }
-	V3D operator - (const V3D& p) const { return V3D(X - p.X, Y - p.Y, Z - p.Z); }
-	V3D operator * (long n) const { return V3D(X * n, Y * n, Z * n); }
-	V3D operator / (long n) const { return V3D(X / n, Y / n, Z / n); }
-	bool operator == (V3D& p) const { return X == p.X && Y == p.Y && Z == p.Z; }
-	bool operator != (V3D& p) const { return X != p.X || Y != p.Y || Z != p.Z; }
+	V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
+	V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
+	V3D operator + (const V3D& p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
+	V3D operator - (const V3D& p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
+	V3D operator * (long n) const { return V3D(_x * n, _y * n, _z * n); }
+	V3D operator / (long n) const { return V3D(_x / n, _y / n, _z / n); }
+	bool operator == (V3D& p) const { return _x == p._x && _y == p._y && _z == p._z; }
+	bool operator != (V3D& p) const { return _x != p._x || _y != p._y || _z != p._z; }
 	V3D& operator += (const V3D& x) { return *this = *this + x; }
 	V3D& operator -= (const V3D& x) { return *this = *this - x; }
 };
@@ -64,25 +64,25 @@ class V2D : public Common::Point {
 	double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
 public:
 	V2D& operator = (const V3D& p3) {
-		double m = Eye.Z / (p3.Z - Eye.Z);
-		x = round((Eye.X + (Eye.X - p3.X) * m));
-		y = round((Eye.Y + (Eye.Y - p3.Y) * m));
+		double m = Eye._z / (p3._z - Eye._z);
+		x = round((Eye._x + (Eye._x - p3._x) * m));
+		y = round((Eye._y + (Eye._y - p3._y) * m));
 		return *this;
 	}
 	V2D(void) { }
 	V2D(const V3D& p3) { *this = p3; }
 	V2D(int x, int y) : Common::Point(x, y) { }
 	static V3D Eye;
-	static void SetEye(const V3D &e) { Eye = e; }
-	static void SetEye(const V2D& e2, int z = -SCR_WID_) {
-		Eye.X = e2.x; Eye.Y = e2.y; Eye.Z = z;
+	static void setEye(const V3D &e) { Eye = e; }
+	static void setEye(const V2D& e2, int z = -SCR_WID_) {
+		Eye._x = e2.x; Eye._y = e2.y; Eye._z = z;
 	}
-	static void SetEye(const char *s) {
+	static void setEye(const char *s) {
 		char *tempStr;
 		strcpy(tempStr, s);
-		Eye.X = atoi(EncryptedStream::token(tempStr));
-		Eye.Y = atoi(EncryptedStream::token(tempStr));
-		Eye.Z = atoi(EncryptedStream::token(tempStr));
+		Eye._x = atoi(EncryptedStream::token(tempStr));
+		Eye._y = atoi(EncryptedStream::token(tempStr));
+		Eye._z = atoi(EncryptedStream::token(tempStr));
 	}
 	bool operator <  (const V2D& p) const { return (x <  p.x) && (y <  p.y); }
 	bool operator <= (const V2D& p) const { return (x <= p.x) && (y <= p.y); }
@@ -90,14 +90,19 @@ public:
 	bool operator >= (const V2D& p) const { return (x >= p.x) && (y >= p.y); }
 	V2D operator + (const V2D& p) const { return V2D(x + p.x, y + p.y); }
 	V2D operator - (const V2D& p) const { return V2D(x - p.x, y - p.y); }
-	uint16 Area(void) { return x * y; }
-	bool Limited(const V2D& p) {
+	uint16 area(void) { return x * y; }
+	bool limited(const V2D& p) {
 		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
 	}
-	V2D Scale(int z) {
-		double m = Eye.Z / (Eye.Z - z);
+	V2D scale(int z) {
+		double m = Eye._z / (Eye._z - z);
 		return V2D(trunc(m * x), trunc(m * y));
 	}
+	static V3D screenToGround(V2D pos) {
+		double z = V2D::Eye._z + (V2D::Eye._y*V2D::Eye._z) / (double(pos.y) - V2D::Eye._y);
+		double x = V2D::Eye._x - ((double(pos.x) - V2D::Eye._x) * (z - V2D::Eye._z)) / V2D::Eye._z;
+		return V3D(round(x), 0, round(z));
+	}
 };
 
 } // End of namespace CGE2


Commit: fbb1a8da93a1d4efcf75df3379c3ecaa3235672b
    https://github.com/scummvm/scummvm/commit/fbb1a8da93a1d4efcf75df3379c3ecaa3235672b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T14:32:51+02:00

Commit Message:
CGE2: Rework loadScript(), start implementation of loadSprite().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 01c38fa..e442643 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -65,7 +65,7 @@ public:
 	void movie(const char *ext);
 	void runGame();
 	void loadScript(const char *fname);
-	void loadSprite(const char *fname, int ref, int scene, int col, int row, int pos);
+	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 
 	const ADGameDescription *_gameDescription;
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 4907dd3..f5d6943 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -30,11 +30,22 @@
 #include "cge2/cge2.h"
 #include "cge2/vga13h.h"
 #include "cge2/text.h"
+#include "cge2/snail.h"
 
 namespace CGE2 {
 
-void CGE2Engine::loadSprite(const char *fname, int ref, int scene, int col = 0, int row = 0, int pos = 0) {
-	warning("STUB: CGE2Engine::loadSprite");
+void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
+	char pat[kLineMax];
+	int shpcnt = 0;
+	int seqcnt = 0;
+	int cnt[kActions];
+	int section = idPHASE;
+	bool frnt = true;
+	bool east = false;
+	bool port = false;
+	bool tran = false;
+	warning("STUB: CGE2Engine::loadSprite()");
+	
 }
 
 void CGE2Engine::loadScript(const char *fname) {
@@ -62,6 +73,8 @@ void CGE2Engine::loadScript(const char *fname) {
 
 		ok = false; // not OK if break
 
+		V3D P;
+
 		// sprite ident number
 		if ((p = EncryptedStream::token(tmpStr)) == NULL)
 			break;
@@ -80,17 +93,17 @@ void CGE2Engine::loadScript(const char *fname) {
 		// sprite column
 		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
-		int SpX = EncryptedStream::number(p);
+		P._x = EncryptedStream::number(p);
 
 		// sprite row
 		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
-		int SpY = EncryptedStream::number(p);
+		P._y = EncryptedStream::number(p);
 
 		// sprite Z pos
 		if ((p = EncryptedStream::token(nullptr)) == NULL)
 			break;
-		int SpZ = EncryptedStream::number(p);
+		P._z = EncryptedStream::number(p);
 
 		// sprite life
 		if ((p = EncryptedStream::token(nullptr)) == NULL)
@@ -100,7 +113,7 @@ void CGE2Engine::loadScript(const char *fname) {
 		ok = true; // no break: OK
 
 		_sprite = NULL;
-		loadSprite(SpN, SpI, SpA, SpX, SpY, SpZ);
+		loadSprite(SpN, SpI, SpA, P);
 		if (_sprite) {
 			warning("STUB: CGE2Engine::loadScript - SPARE:: thing");
 			if (BkG)


Commit: 72cccb80008979ed4f23404681df173d007f34ed
    https://github.com/scummvm/scummvm/commit/72cccb80008979ed4f23404681df173d007f34ed
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T16:51:03+02:00

Commit Message:
CGE2: Add Hero.

Changed paths:
  A engines/cge2/hero.cpp
  A engines/cge2/hero.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/general.h
    engines/cge2/module.mk
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 853f84f..cf52190 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -32,6 +32,7 @@
 #include "cge2/vga13h.h"
 #include "cge2/sound.h"
 #include "cge2/text.h"
+#include "cge2/hero.h"
 
 namespace CGE2 {
 
@@ -44,6 +45,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_fx = nullptr;
 	_sound = nullptr;
 	_text = nullptr;
+	for (int i = 0; i < 2; i++)
+		_heroTab[i] = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -51,6 +54,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_music = true;
 	_startupMode = 1;
 	_now = 1;
+	_sex = true;
 }
 
 void CGE2Engine::init() {
@@ -60,6 +64,8 @@ void CGE2Engine::init() {
 	_sound = new Sound(this);
 	_midiPlayer = new MusicPlayer(this);
 	_text = new Text(this, "CGE");
+	for (int i = 0; i < 2; i++)
+		_heroTab[i] = new HeroTab();
 }
 
 void CGE2Engine::deinit() {
@@ -70,6 +76,8 @@ void CGE2Engine::deinit() {
 	delete _sound;
 	delete _midiPlayer;
 	delete _text;
+	for (int i = 0; i < 2; i++)
+		delete _heroTab[i];
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index e442643..c0a7d4a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -42,11 +42,16 @@ class MusicPlayer;
 class Fx;
 class Sound;
 class Text;
+struct HeroTab;
 
 #define kScrWidth      320
 #define kScrHeight     240
 #define kMaxFile       128
 #define kPathMax       128
+#define kDimMax          8
+#define kWayMax         10
+#define kPocketMax       4
+#define kCaveMax       100
 
 class CGE2Engine : public Engine {
 public:
@@ -75,6 +80,7 @@ public:
 	bool _music;
 	int _startupMode;
 	int _now;
+	bool _sex;
 
 	ResourceManager *_resman;
 	Vga *_vga;
@@ -83,6 +89,7 @@ public:
 	Fx *_fx;
 	Sound *_sound;
 	Text *_text;
+	HeroTab *_heroTab[2];
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index a9b7002..9da00be 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -60,8 +60,8 @@ public:
 };
 
 class V2D : public Common::Point {
-	double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
-	double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
+	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
+	static double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
 public:
 	V2D& operator = (const V3D& p3) {
 		double m = Eye._z / (p3._z - Eye._z);
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
new file mode 100644
index 0000000..8f5c44d
--- /dev/null
+++ b/engines/cge2/hero.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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/hero.h"
+
+namespace CGE2 {
+
+Sprite *Hero::expand(void) {
+	warning("STUB: Hero::expand()");
+	return this;
+}
+
+void Hero::setCurrent(void) {
+	warning("STUB: Hero::setCurrent()");
+}
+
+void Hero::hStep(void) {
+	warning("STUB: Hero::hStep()");
+}
+
+Sprite *Hero::setContact(void) {
+	warning("STUB: Hero::setContact()");
+	return this;
+}
+
+void Hero::tick(void) {
+	warning("STUB: Hero::tick()");
+}
+
+int Hero::distance(V3D pos) {
+	warning("STUB: Hero::distance()");
+	return 0;
+}
+
+int Hero::distance(Sprite *spr) {
+	warning("STUB: Hero::distance()");
+	return 0;
+}
+
+void Hero::turn(Dir d) {
+	warning("STUB: Hero::turn()");
+}
+
+void Hero::park(void) {
+	warning("STUB: Hero::park()");
+}
+
+bool Hero::lower(Sprite * spr) {
+		warning("STUB: Hero::lower()");
+		return false;
+}
+
+void Hero::reach(int mode) {
+	warning("STUB: Hero::reach()");
+}
+
+void Hero::fun(void) {
+	warning("STUB: Hero::fun()");
+}
+
+void Hero::operator ++ (void) {
+	warning("STUB: Hero::operator ++()");
+}
+
+void Hero::operator -- (void) {
+	warning("STUB: Hero::operator --()");
+}
+
+bool Sprite::works(Sprite *spr) {
+	warning("STUB: Hero::works()");
+	return false;
+}
+
+uint32 Hero::len(V2D v) {
+	warning("STUB: Hero::works()");
+	return 0;
+}
+
+bool Hero::findWay(void){
+	warning("STUB: Hero::findWay()");
+	return false;
+}
+
+int Hero::snap(int p, int q, int grid) {
+	warning("STUB: Hero::findWay()");
+	return 0;
+}
+
+void Hero::walkTo(V3D pos) {
+	warning("STUB: Hero::walkTo()");
+}
+
+void Hero::walkTo(Sprite *spr) {
+	warning("STUB: Hero::walkTo()");
+}
+
+int Hero::cross(const V2D &a, const V2D &b) {
+	warning("STUB: Hero::cross()");
+	return 0;
+}
+
+int Hero::mapCross(const V2D &a, const V2D &b) {
+	warning("STUB: Hero::mapCross()");
+	return 0;
+}
+
+int Hero::mapCross(const V3D &a, const V3D &b) {
+	warning("STUB: Hero::mapCross()");
+	return 0;
+}
+
+void Hero::setCave(int c) {
+	warning("STUB: Hero::mapCross()");
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
new file mode 100644
index 0000000..50020da
--- /dev/null
+++ b/engines/cge2/hero.h
@@ -0,0 +1,98 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_HERO_H
+#define CGE2_HERO_H
+
+#include "cge2/cge2.h"
+#include "cge2/vga13h.h"
+#include "cge2/snail.h"
+
+namespace CGE2 {
+
+#define kMaxTry 400
+
+class Hero;
+
+struct HeroTab {
+	Hero *_ptr;
+	Sprite *_face;
+	Sprite *_pocket[kPocketMax + 1];
+	int _pocPtr;
+	V2D _posTab[kCaveMax];
+};
+
+class Hero : public Sprite {
+	int _hig[kDimMax];
+	Sprite *_contact;
+public:
+	BitmapPtr _dim[kDimMax];
+	V3D _trace[kWayMax];
+	enum Dir { kNoDir = -1, kSS, kWW, kNN, kEE } _dir;
+	int _curDim;
+	int _tracePtr;
+	int _reachStart, _reachCycle, _sayStart, _funStart;
+	int _funDel0, _funDel;
+	int _maxDist;
+	bool _ignoreMap;
+	Hero(void);
+	void tick(void);
+	Sprite *expand(void);
+	Sprite *contract(void) { return this; }
+	Sprite *setContact(void);
+	int stepSize(void) { return _ext->_seq[7]._dx; }
+	int distance(V3D pos);
+	int distance(Sprite * spr);
+	void turn(Dir d);
+	void park(void);
+	static uint32 len(V2D v);
+	bool findWay(void);
+	static int snap(int p, int q, int grid);
+	void walkTo(V3D pos);
+	void walkTo(V2D pos) { walkTo(V2D::screenToGround(pos)); }
+	void walkTo(Sprite *spr);
+	void say(void) { step(_sayStart); }
+	void fun(void);
+	void resetFun(void) { _funDel = _funDel0; }
+	void hStep(void);
+	bool lower(Sprite * spr);
+	int cross(const V2D &a, const V2D &b);
+	int mapCross(const V2D &a, const V2D &b);
+	int mapCross(const V3D &a, const V3D &b);
+	Hero *other(void) { return _vm->_heroTab[!(_ref & 1)]->_ptr;}
+	Action action(void) { return (Action)(_ref % 10); }
+	void reach(int mode);
+	void setCurrent(void);
+	void setCave(int c);
+	void operator ++ (void);
+	void operator -- (void);
+};
+
+
+
+} // End of namespace CGE2
+
+#endif // CGE2_HERO_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 4fb9156..62ce51e 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -8,7 +8,8 @@ MODULE_OBJS = \
 	bitmap.o \
 	sound.o \
 	cge2_main.o \
-	text.o
+	text.o \
+	hero.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index e761c5c..b7325d8 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -83,6 +83,7 @@ public:
 class Sprite {
 protected:
 	SprExt *_ext;
+	CGE2Engine *_vm;
 public:
 	int _ref;
 	signed char _scene;
@@ -149,8 +150,6 @@ public:
 	/*virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
 	virtual void tick();*/
 	void sync(Common::Serializer &s);
-private:
-	CGE2Engine *_vm;
 };
 
 class Queue {


Commit: 12a9d0a759fd0129ced1f8815d1da569cd4378c2
    https://github.com/scummvm/scummvm/commit/12a9d0a759fd0129ced1f8815d1da569cd4378c2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T18:32:29+02:00

Commit Message:
CGE2: Add kIdTab and _lineCount to EncryptedStream.

Changed paths:
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 7677699..6cc9f8b 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -181,7 +181,7 @@ uint16 ResourceManager::catRead(byte *buf, uint16 length) {
 /*-----------------------------------------------------------------------
  * EncryptedStream
  *-----------------------------------------------------------------------*/
-EncryptedStream::EncryptedStream(CGE2Engine *vm, const char *name) : _vm(vm) {
+EncryptedStream::EncryptedStream(CGE2Engine *vm, const char *name) : _vm(vm), _lineCount(0) {
 	_error = false;
 	BtKeypack *kp = _vm->_resman->find(name);
 	if (scumm_stricmp(kp->_key, name) != 0)
@@ -229,6 +229,7 @@ bool EncryptedStream::seek(int32 offset) {
 }
 
 Common::String EncryptedStream::readLine() {
+	_lineCount++;
 	return _readStream->readLine();
 }
 
@@ -256,4 +257,10 @@ EncryptedStream::~EncryptedStream() {
 	delete _readStream;
 }
 
+const char *EncryptedStream::kIdTab[] = {
+	"[near]", "[mtake]", "[ftake]", "[phase]", "[seq]",
+	"Name", "Type", "Front", "East",
+	"Portable", "Transparent",
+	NULL };
+
 } // End of namespace CGE2
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index a596d71..0d32cab 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -102,7 +102,11 @@ class EncryptedStream {
 private:
 	CGE2Engine *_vm;
 	Common::SeekableReadStream *_readStream;
+	const char **_tab;
+	int _lineCount;
 	bool _error;
+
+	static const char *kIdTab[];
 public:
 	EncryptedStream(CGE2Engine *vm, const char *name);
 	~EncryptedStream();
@@ -115,6 +119,7 @@ public:
 	Common::String readLine();
 	static int number(char *s);
 	static char *token(char *s);
+	int getLineCount() { return _lineCount; }
 };
 
 } // End of namespace CGE2


Commit: d12e25ccd0114726a3cf04324f06cbbb14e8fa48
    https://github.com/scummvm/scummvm/commit/d12e25ccd0114726a3cf04324f06cbbb14e8fa48
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T18:32:56+02:00

Commit Message:
CGE2: Remove unnecessary whitespaces.

Changed paths:
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 50020da..893c36b 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -91,8 +91,6 @@ public:
 	void operator -- (void);
 };
 
-
-
 } // End of namespace CGE2
 
 #endif // CGE2_HERO_H


Commit: 9ffdff539203cf2774317bd274ae606a47148037
    https://github.com/scummvm/scummvm/commit/9ffdff539203cf2774317bd274ae606a47148037
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T19:04:52+02:00

Commit Message:
CGE2: Implement EncryptedStream::ident().

Changed paths:
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 6cc9f8b..91a9954 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -245,6 +245,17 @@ char *EncryptedStream::token(char *s) {
 	return strtok(s, " =\t,;/()");
 }
 
+ID EncryptedStream::ident(const char *s) {
+	if (s) {
+		for (const char **e = kIdTab; *e; e++) {
+			if (scumm_stricmp(s, *e) == 0) {
+				return ID(e - kIdTab);
+			}
+		}
+	}
+	return kIdNone;
+}
+
 int32 EncryptedStream::size() {
 	return _readStream->size();
 }
@@ -261,6 +272,7 @@ const char *EncryptedStream::kIdTab[] = {
 	"[near]", "[mtake]", "[ftake]", "[phase]", "[seq]",
 	"Name", "Type", "Front", "East",
 	"Portable", "Transparent",
-	NULL };
+	NULL
+};
 
 } // End of namespace CGE2
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 0d32cab..fdf1b83 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -45,6 +45,13 @@ class CGE2Engine;
 #define kDatName      "VOL.DAT"
 #define kCryptSeed    0xA5
 
+enum ID {
+	kIdNear, kIdMTake, kIdFTake, kIdPhase, kIdSeq,
+	kIdName, kIdType, kIdFront, kIdEast,
+	kIdPortable, kIdTransparent,
+	kIdNone
+};
+
 struct BtKeypack {
 	char _key[kBtKeySize];
 	uint32 _pos;
@@ -119,6 +126,7 @@ public:
 	Common::String readLine();
 	static int number(char *s);
 	static char *token(char *s);
+	static ID ident(const char *s);
 	int getLineCount() { return _lineCount; }
 };
 


Commit: b674ab2a09bec35b27583d8c463d137ded285e52
    https://github.com/scummvm/scummvm/commit/b674ab2a09bec35b27583d8c463d137ded285e52
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-08T19:23:36+02:00

Commit Message:
CGE2: Further implement loadSprite(), fix compilation error.

Changed paths:
  A engines/cge2/snail.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f5d6943..117385a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -31,21 +31,34 @@
 #include "cge2/vga13h.h"
 #include "cge2/text.h"
 #include "cge2/snail.h"
+#include "cge2/hero.h"
 
 namespace CGE2 {
 
 void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
-	char pat[kLineMax];
 	int shpcnt = 0;
 	int seqcnt = 0;
 	int cnt[kActions];
-	int section = idPHASE;
+	for (int i = 0; i < kActions; i++)
+		cnt[i] = 0;
+	int section = kIdPhase;
 	bool frnt = true;
 	bool east = false;
 	bool port = false;
 	bool tran = false;
+	Hero *h;
+
+	char tmpStr[kLineMax];
+	mergeExt(tmpStr, fname, kSprExt);
+
+	if (_resman->exist(tmpStr)) { // sprite description file exist
+		EncryptedStream sprf(this, tmpStr);
+		if (sprf.err())
+			error("Bad SPR [%s]", tmpStr);
+
+	}
+
 	warning("STUB: CGE2Engine::loadSprite()");
-	
 }
 
 void CGE2Engine::loadScript(const char *fname) {
@@ -60,10 +73,7 @@ void CGE2Engine::loadScript(const char *fname) {
 	char tmpStr[kLineMax + 1];
 	Common::String line;
 
-	int lineNum = 0;
 	for (line = scrf.readLine(); !scrf.eos(); line = scrf.readLine()) {
-		lineNum++;
-
 		char *p;
 
 		lcnt++;
@@ -122,7 +132,7 @@ void CGE2Engine::loadScript(const char *fname) {
 	}
 
 	if (!ok)
-		error("Bad INI line %d [%s]", lineNum, fname); // Counting starts from 0!
+		error("Bad INI line %d [%s]", scrf.getLineCount(), fname);
 }
 
 void CGE2Engine::movie(const char *ext) {
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
new file mode 100644
index 0000000..cc60882
--- /dev/null
+++ b/engines/cge2/snail.h
@@ -0,0 +1,37 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_SNAIL_H
+#define CGE2_SNAIL_H
+
+namespace CGE2 {
+
+enum Action { kNear, kMTake, kFTake, kActions };
+
+} // End of namespace CGE2
+
+#endif


Commit: cb6548919712d91ae4cfbdefd20f6f0f147ced6c
    https://github.com/scummvm/scummvm/commit/cb6548919712d91ae4cfbdefd20f6f0f147ced6c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-09T13:11:50+02:00

Commit Message:
CGE2: Implement CGE2Engine::loadSprite().

Add Snail during the process and revise or expand a lot of other parts of the engine.

Changed paths:
  A engines/cge2/snail.cpp
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h
    engines/cge2/hero.cpp
    engines/cge2/hero.h
    engines/cge2/module.mk
    engines/cge2/snail.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index cf52190..c3ec6a9 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -126,7 +126,8 @@ bool CGE2Engine::showTitle(const char *name) {
 
 	Sprite D(this, LB);
 	D._flags._kill = true;
-	D._flags._bDel = true;
+	// D._flags._bDel = true;
+	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
 	D.center();
 	D.show(2);
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c0a7d4a..79ac2c7 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -71,6 +71,7 @@ public:
 	void runGame();
 	void loadScript(const char *fname);
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
+	void badLab(const char *fn);
 
 	const ADGameDescription *_gameDescription;
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 117385a..23fe4cb 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -35,20 +35,25 @@
 
 namespace CGE2 {
 
+void CGE2Engine::badLab(const char *fn) {
+	error("Misplaced label in %s!", fn);
+}
+
 void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 	int shpcnt = 0;
 	int seqcnt = 0;
 	int cnt[kActions];
 	for (int i = 0; i < kActions; i++)
 		cnt[i] = 0;
-	int section = kIdPhase;
+	ID section = kIdPhase;
 	bool frnt = true;
 	bool east = false;
 	bool port = false;
 	bool tran = false;
 	Hero *h;
+	ID id;
 
-	char tmpStr[kLineMax];
+	char tmpStr[kLineMax + 1];
 	mergeExt(tmpStr, fname, kSprExt);
 
 	if (_resman->exist(tmpStr)) { // sprite description file exist
@@ -56,9 +61,137 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 		if (sprf.err())
 			error("Bad SPR [%s]", tmpStr);
 
+		int label = kNoByte;
+		Common::String line;
+
+		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
+			int len = line.size();
+			if (len == 0 || *tmpStr == ';')
+				continue;
+			
+			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+			
+			char *p;
+			p = EncryptedStream::token(tmpStr);
+			if (*p == '@') {
+				if (label != kNoByte)
+					badLab(fname);
+				label = atoi(p + 1);
+				continue;
+			}
+
+			id = EncryptedStream::ident(p);
+			switch (id) {
+			case kIdName: // will be taken in Expand routine
+				if (label != kNoByte)
+					badLab(fname);
+				break;
+			case kIdType:
+				if (label != kNoByte)
+					badLab(fname);
+				break;
+			case kIdNear:
+			case kIdMTake:
+			case kIdFTake:
+			case kIdPhase:
+			case kIdSeq:
+				if (label != kNoByte)
+					badLab(fname);
+				section = id;
+				break;
+			case kIdFront:
+				if (label != kNoByte)
+					badLab(fname);
+				p = EncryptedStream::token(nullptr);
+				frnt = EncryptedStream::testBool(p);
+				break;
+			case kIdEast:
+				if (label != kNoByte)
+					badLab(fname);
+				p = EncryptedStream::token(nullptr);
+				east = EncryptedStream::testBool(p);
+				break;
+			case kIdPortable:
+				if (label != kNoByte)
+					badLab(fname);
+				p = EncryptedStream::token(nullptr);
+				port = EncryptedStream::testBool(p);
+				break;
+			case kIdTransparent:
+				if (label != kNoByte)
+					badLab(fname);
+				p = EncryptedStream::token(nullptr);
+				tran = EncryptedStream::testBool(p);
+				break;
+			default:
+				if (id >= kIdNear)
+					break;
+				switch (section) {
+				case kIdNear:
+				case kIdMTake:
+				case kIdFTake:
+					if (Snail::com(p) >= 0)
+						++cnt[section];
+					else
+						error("Bad line %d [%s]", sprf.getLineCount(), tmpStr);
+					break;
+				case kIdPhase:
+					if (label != kNoByte)
+						badLab(fname);
+					++shpcnt;
+					break;
+				case kIdSeq:
+					if (label != kNoByte)
+						badLab(fname);
+					++seqcnt;
+					break;
+				}
+				break;
+			}
+			label = kNoByte;
+		}
+
+		if (!shpcnt) {
+			error("No shapes - %s", fname);
+		}
+	} else // No sprite description: mono-shaped sprite with only .BMP file.
+		++shpcnt;
+
+	// Make sprite of choosen type:
+	char c = *fname | 0x20;
+	if (c >= 'a' && c <= 'z' && fname[1] == '0' && fname[2] == '\0') {
+		h = new Hero(this);
+		if (h) {
+			h->gotoxyz(pos);
+			_sprite = h;
+		}
+	} else {
+		if (_sprite)
+			delete _sprite;
+		_sprite = new Sprite(this);
+		if (_sprite)
+			_sprite->gotoxyz(pos);
 	}
 
-	warning("STUB: CGE2Engine::loadSprite()");
+	if (_sprite) {
+		_sprite->_flags._frnt = frnt;
+		_sprite->_flags._east = east;
+		_sprite->_flags._port = port;
+		_sprite->_flags._tran = tran;
+		_sprite->_flags._kill = true;
+
+		// Extract the filename, without the extension
+		Common::strlcpy(_sprite->_file, fname, sizeof(_sprite->_file));
+		char *p = strchr(_sprite->_file, '.');
+		if (p)
+			*p = '\0';
+
+		_sprite->_shpCnt = shpcnt;
+		_sprite->_seqPtr = seqcnt;
+
+		for (int i = 0; i < kActions; i++)
+			_sprite->_actionCtrl[i]._cnt = cnt[i];
+	}
 }
 
 void CGE2Engine::loadScript(const char *fname) {
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index a1fb071..8420a2d 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -30,8 +30,9 @@
 
 namespace CGE2 {
 
-#define kLineMax       512
+#define kLineMax          512
 #define kIntroExt      ".I80"
+#define kNoByte            -1
 
 } // End of namespace CGE2
 
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 91a9954..6a20b6b 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -245,15 +245,23 @@ char *EncryptedStream::token(char *s) {
 	return strtok(s, " =\t,;/()");
 }
 
-ID EncryptedStream::ident(const char *s) {
-	if (s) {
-		for (const char **e = kIdTab; *e; e++) {
-			if (scumm_stricmp(s, *e) == 0) {
-				return ID(e - kIdTab);
+int EncryptedStream::takeEnum(const char **tab, const char *text) {
+	if (text) {
+		for (const char **e = tab; *e; e++) {
+			if (scumm_stricmp(text, *e) == 0) {
+				return e - tab;
 			}
 		}
 	}
-	return kIdNone;
+	return -1;
+}
+
+ID EncryptedStream::ident(const char *s) {
+	return ID(takeEnum(kIdTab, s));
+}
+
+bool EncryptedStream::testBool(char *s) {
+	return number(s) != 0;
 }
 
 int32 EncryptedStream::size() {
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index fdf1b83..758d841 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -49,7 +49,7 @@ enum ID {
 	kIdNear, kIdMTake, kIdFTake, kIdPhase, kIdSeq,
 	kIdName, kIdType, kIdFront, kIdEast,
 	kIdPortable, kIdTransparent,
-	kIdNone
+	kIdNone = -1
 };
 
 struct BtKeypack {
@@ -126,7 +126,9 @@ public:
 	Common::String readLine();
 	static int number(char *s);
 	static char *token(char *s);
+	static int takeEnum(const char **tab, const char *text);
 	static ID ident(const char *s);
+	static bool testBool(char *s);
 	int getLineCount() { return _lineCount; }
 };
 
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 8f5c44d..44ff850 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -29,6 +29,10 @@
 
 namespace CGE2 {
 
+Hero::Hero(CGE2Engine *vm) : Sprite(vm) {
+	warning("STUB: Hero::Hero()");
+}
+
 Sprite *Hero::expand(void) {
 	warning("STUB: Hero::expand()");
 	return this;
@@ -90,11 +94,6 @@ void Hero::operator -- (void) {
 	warning("STUB: Hero::operator --()");
 }
 
-bool Sprite::works(Sprite *spr) {
-	warning("STUB: Hero::works()");
-	return false;
-}
-
 uint32 Hero::len(V2D v) {
 	warning("STUB: Hero::works()");
 	return 0;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 893c36b..21f4ec3 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -58,7 +58,7 @@ public:
 	int _funDel0, _funDel;
 	int _maxDist;
 	bool _ignoreMap;
-	Hero(void);
+	Hero(CGE2Engine *vm);
 	void tick(void);
 	Sprite *expand(void);
 	Sprite *contract(void) { return this; }
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 62ce51e..4a7a412 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -9,7 +9,8 @@ MODULE_OBJS = \
 	sound.o \
 	cge2_main.o \
 	text.o \
-	hero.o
+	hero.o \
+	snail.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
new file mode 100644
index 0000000..245da99
--- /dev/null
+++ b/engines/cge2/snail.cpp
@@ -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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/snail.h"
+#include "cge2/fileio.h"
+
+namespace CGE2 {
+
+const char *Snail::comTxt[] = {
+	"NOP", "USE", "PAUSE", "INF", "CAVE",
+	"SLAVE", "FOCUS", "SETX", "SETY", "SETZ",
+	"ADD", "SUB", "MUL", "DIV", "IF", "FLAG",
+	"FLASH", "LIGHT", "CYCLE",
+	"CLEAR", "TALK", "MOUSE",
+	"MAP", "COUNT", "MIDI",
+	"SETDLG", "MSKDLG",
+	".DUMMY.",
+	"WAIT", "HIDE", "ROOM",
+	"SAY", "SOUND", "TIME", "KILL",
+	"RSEQ", "SEQ", "SEND", "SWAP",
+	"KEEP", "GIVE",
+	"GETPOS", "GOTO", "MOVEX", "MOVEY",
+	"MOVEZ", "TRANS", "PORT",
+	"NEXT", "NNEXT", "MTNEXT", "FTNEXT",
+	"RNNEXT", "RMTNEXT", "RFTNEXT",
+	"RMNEAR", "RMMTAKE", "RMFTAKE",
+	"SETREF", "BACKPT",
+	"WALKTO", "REACH", "COVER", "UNCOVER",
+	NULL };
+
+int Snail::com(const char *com) {
+	int i = EncryptedStream::takeEnum(comTxt, com);
+	return (i < 0) ? i : i + kSNCom0 + 1;
+}
+
+} // End of namespace CGE2.
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index cc60882..5cdb221 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -28,10 +28,95 @@
 #ifndef CGE2_SNAIL_H
 #define CGE2_SNAIL_H
 
+#include "cge2/cge2_main.h"
+
 namespace CGE2 {
 
 enum Action { kNear, kMTake, kFTake, kActions };
 
+enum SNCom {
+	kSNCom0 = 128,
+	kSNNop,     // NOP                  instrukcja "pusta"                        :: do nothing
+	kSNUse,     // USE <spr> <cav>|<lab> hint for using
+	kSNPause,   // PAUSE -1 <dly>       oczekiwanie <dly>/72 sekund               :: delay <dly>/72 seconds
+	kSNInf,     // INF -1 <ref>         prezentacja tekstu o numerze <ref>        :: show text referrenced by <ref>
+	kSNCave,    // CAVE -1 <cav>        przejœcie na planszê <cav>                :: go to board <cav>
+	kSNSlave,   // SLAVE
+	kSNFocus,   // FOCUS                zmiana aktywnego bohatera (-1 cyklicznie) :: change active hero
+	kSNSetX,    // SETX <x> <idx>       ustawienie przesuniêcia sprajtu           :: set sprite shift in x axis
+	kSNSetY,    // SETX <y> <idx>       ustawienie przesuniêcia sprajtu           :: set sprite shift in y axis
+	kSNSetZ,    // SETX <z> <idx>       ustawienie przesuniêcia sprajtu           :: set sprite shift in z axis
+	kSNAdd,     // ADD <idx1> <idx2>    suma dwóch wektorów                       :: sum vectors
+	kSNSub,     // SUB <idx1> <idx2>    ró¿nica dwóch wektorów                    :: subtract vectors
+	kSNMul,     // MUL <idx> <nr>       iloczyn wektora przez liczbê              :: multiply vector by number
+	kSNDiv,     // DIV <idx> <nr>       iloraz wektora przez liczbê               :: divide vector by number
+	kSNIf,      // IF
+	kSNFlag,    // FLAG <nr> <val>      nadanie wartoœci znacznikowi <nr>         :: set flag <nr> to <val>
+	kSNFlash,   // FLASH -1 0|1         rozjaœnienie ca³ego obrazu (tak/nie)      :: lighten whole image (on/off)
+	kSNLight,   // LIGHT
+	kSNCycle,   // CYCLE <cnt>          cykliczne przesuwanie <cnt> kolorow od 1  :: rotate <cnt> colors from 1
+	kSNClear,   // CLEAR -1 0           wyzerowanie kolejki kSNAIL                 :: clear kSNAIL queue
+	kSNTalk,    // TALK -1 0|1          zezwolenie na dialogi (tak/nie)           :: enable speach (on/off)
+	kSNMouse,   // MOUSE -1 0|1         zezwolenie na mysz (tak/nie)              :: enable mouse (on/off)
+	kSNMap,     // MAP  0|1 0           chwilowe wylaczenie mapy dla bohatera     :: temporarily turn off map for hero
+	kSNCount,   // COUNT
+	kSNMidi,    // MIDI -1 <midi>       muzyka MIDI nr <midi> (-1 = cisza)        :: play MIDI referenced by <midi> (-1 = off)
+	kSNSetDlg,  // SETDLG 0..3 0..3     przelaczenie trybu mowy                   :: switch of speach mode
+	kSNMskDlg,  // MSKDLG 0..3 0..3     przelaczenie maski trybu mowy             :: switch of speach mode mask
+
+	kSNSpr,
+
+	kSNWait,    // WAIT <spr> <seq>|-1  oczekiwanie na SEQ <seq> (-1 = stoi)      :: wait for SEQ <seq> (-1 = freeze)
+	kSNHide,    // HIDE <spr> 0|1       widzialnoϾ sprajtu                       :: visibility of sprite
+	kSNRoom,    // ROOM <hero> 0|1      dodatkowe miejsce w kieszeni (nie/tak)    :: additional room in pocket (no/yes)
+	kSNSay,     // SAY <spr> <ref>      wyg³oszenie tekstu o numerze <ref>        :: say text referenced by <ref>
+	kSNSound,   // SOUND <spr> <ref>    wyemitowanie efektu <ref>                 :: play sound effect referenced by <ref>
+	kSNTime,    // TIME <spr> 0         wyg³oszenie bie¿¹cego czasu               :: say current time
+	kSNKill,    // KILL <spr> 0         usuniêcie sprajtu                         :: remove sprite
+	kSNRSeq,    // RSEQ <spr> <nr>      wzglêdny skok SEQ o <nr>                  :: relative jump SEQ <nr> lines
+	kSNSeq,     // SEQ <spr> <seq>      skok do SEQ <seq>                         :: jump to certain SEQ
+	kSNSend,    // SEND <spr> <cav>     przeniesienie sprajtu na planszê <cav>    :: move sprite to board <cav>
+	kSNSwap,    // SWAP <spr1> spr2>    zamiana sprajtów                          :: sprite exchange
+	kSNKeep,    // KEEP <spr> <seq>     sprajt do kieszeni ze skokiem do <seq>    :: take sprite into pocket and jump to <seq>
+	kSNGive,    // GIVE <spr> <seq>     sprajt z kieszeni ze skokiem do <seq>     :: remove sprite from pocket and jump to <seq>
+	kSNGetPos,  // GETPOS <spr> <idx>   pobranie pozycji sprajtu                  :: take sprite's position
+	kSNGoto,    // GOTO <spr> <idx>     przesuniêcie sprajtu na dana pozycje      :: move sprite to position
+	kSNMoveX,   // MOVEX <spr> <dx>     przesuniêcie wzglêdne po osi X            :: relative move along X axis
+	kSNMoveY,   // MOVEY <spr> <dy>     przesuniêcie wzglêdne po osi Y            :: relative move along Y axis
+	kSNMoveZ,   // MOVEZ <spr> <dz>     przesuniêcie wzglêdne po osi Z            :: relative move along Z axis
+	kSNTrans,   // TRANS <spr> 0|1      ustalenie przezroczystoœci logicznej      :: clear/set logical transparency
+	kSNPort,    // PORT <spr> 0|1       ustalenie "bralnoœci" sprajtu             :: clear/set "takeability" of sprite
+	kSNNext,    // NEXT <spr> <nr>      skok do <nr> - NEAR lub TAKE              :: jump to <nr> - NEAR or TAKE
+	kSNNNext,   // NNEXT <spr> <nr>     skok do <nr> - NEAR                       :: jump to <nr> - NEAR
+	kSNMTNext,  // MTNEXT <spr> <nr>    skok do <nr> - TAKE                       :: jump to <nr> - TAKE
+	kSNFTNext,  // FTNEXT <spr> <nr>    skok do <nr> - TAKE                       :: jump to <nr> - TAKE
+	kSNRNNext,  // RNNEXT <spr> <nr>    skok wzglêdny do <nr> - NEAR              :: relative jump to <nr> - NEAR
+	kSNRMTNext, // RMTNEXT <spr> <nr>   skok wzglêdny do <nr> - TAKE              :: relative jump to <nr> - TAKE
+	kSNRFTNext, // RFTNEXT <spr> <nr>   skok wzglêdny do <nr> - TAKE              :: relative jump to <nr> - TAKE
+	kSNRMNear,  // RMNEAR <spr> 0       usuniêcie listy NEAR                      :: remove NEAR list
+	kSNRMMTake, // RMMTAKE <spr> 0      usuniêcie listy TAKE                      :: remove TAKE list
+	kSNRMFTake, // RMFTAKE <spr> 0      usuniêcie listy TAKE                      :: remove TAKE list
+	kSNSetRef,  // RETREF <spr> <ref>   zmiana numeru <ref> sprajta <spr>         :: change reference of sprite <spr> to <ref> 
+	kSNBackPt,  // BACKPT <spr> 0       wmalowanie sprajtu w t³o                  :: paint sprite onto the background
+	kSNWalk,    // WALK <hero> <ref>|<point> podejd¿ do sprajtu lub punktu        :: go close to the sprite or point
+	kSNReach,   // REACH <hero> <ref>|<m> siêgnij do <ref> lub sposobem <m>       :: reach the sprite or point with <m> method
+	kSNCover,   // COVER <sp1> <sp2>    przykrycie sprajtu <sp1> sprajtem <sp2>   :: cover sprite <sp1> with sprite <sp2>
+	kSNUncover, // UNCOVER <sp1> <sp2>  odtworzenie sytuacji sprzed COVER         :: restore the state before COVER
+
+	kSNDim,
+	kSNExec,
+	kSNStep,
+	kSNGhost,
+	
+	kSNNOne = kNoByte
+};
+
+class Snail {
+	static const char *comTxt[];
+public:
+	static int com(const char *com);
+};
+
 } // End of namespace CGE2
 
 #endif
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 26fba8b..1d757ff 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -56,6 +56,10 @@ Seq *getConstantSeq(bool seqFlag) {
 	return seq;
 }
 
+Sprite::Sprite(CGE2Engine *vm) {
+	warning("STUB: Sprite::Sprite()");
+}
+
 Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
 	: _x(0), _y(0), _z(0), _nearPtr(0), _takePtr(0),
 	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
@@ -74,10 +78,7 @@ Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
 }
 
 Sprite::~Sprite() {
-	if (_vm->_sprite == this)
-		_vm->_sprite = NULL;
-
-	contract();
+	warning("STUB: Sprite::~Sprite()");
 }
 
 BitmapPtr Sprite::shp() {
@@ -110,7 +111,10 @@ BitmapPtr *Sprite::setShapeList(BitmapPtr *shpP) {
 		}
 		expand();
 		_ext->_shpList = shpP;
-		_flags._bDel = true;
+
+		//_flags._bDel = true;
+		warning("STUB: Sprite::sync() - Flags changed compared to CGE1's Sprite type.");
+
 		if (!_ext->_seq)
 			setSeq(getConstantSeq(_shpCnt < 2));
 	}
@@ -371,7 +375,7 @@ void Sprite::step(int nr) {
 			_seqPtr = _ext->_seq[_seqPtr]._next;
 		seq = _ext->_seq + _seqPtr;
 		if (seq->_dly >= 0) {
-			gotoxy(_x + (seq->_dx), _y + (seq->_dy));
+			gotoxyz(_x + (seq->_dx), _y + (seq->_dy));
 			_time = seq->_dly;
 		}
 	}
@@ -404,31 +408,28 @@ void Sprite::killXlat() {
 	_flags._xlat = false;
 }
 
-void Sprite::gotoxy(int x, int y) {
-	int xo = _x, yo = _y;
-	if (_x < kScrWidth) {
-		if (x < 0)
-			x = 0;
-		if (x + _w > kScrWidth)
-			x = (kScrWidth - _w);
-		_x = x;
-	}
-	if (_h < kScrHeight) {
-		if (y < 0)
-			y = 0;
-		if (y + _h > kScrHeight)
-			y = (kScrHeight - _h);
-		_y = y;
-	}
-	if (_next)
-		if (_next->_flags._slav)
-			_next->gotoxy(_next->_x - xo + _x, _next->_y - yo + _y);
-	if (_flags._shad)
-		_prev->gotoxy(_prev->_x - xo + _x, _prev->_y - yo + _y);
+void Sprite::gotoxyz(int x, int y, int z) {
+	warning("STUB: Sprite::gotoxyz()");
+}
+
+void Sprite::gotoxyz(void) {
+	warning("STUB: Sprite::gotoxyz()");
+}
+
+void Sprite::gotoxyz(V2D pos) {
+	warning("STUB: Sprite::gotoxyz()");
+}
+
+void Sprite::gotoxyz_(V2D pos) {
+	warning("STUB: Sprite::gotoxyz()");
+}
+
+void Sprite::gotoxyz(V3D pos) {
+	warning("STUB: Sprite::gotoxyz()");
 }
 
 void Sprite::center() {
-	gotoxy((kScrWidth - _w) / 2, (kScrHeight - _h) / 2);
+	gotoxyz((kScrWidth - _w) / 2, (kScrHeight - _h) / 2);
 }
 
 void Sprite::show() {
@@ -494,9 +495,9 @@ void Sprite::sync(Common::Serializer &s) {
 		_flags._near = flags & 0x0002 ? true : false;
 		_flags._drag = flags & 0x0004 ? true : false;
 		_flags._hold = flags & 0x0008 ? true : false;
-		_flags._dummy = flags & 0x0010 ? true : false;
+		//_flags._dummy = flags & 0x0010 ? true : false;
 		_flags._slav = flags & 0x0020 ? true : false;
-		_flags._syst = flags & 0x0040 ? true : false;
+		//_flags._syst = flags & 0x0040 ? true : false;
 		_flags._kill = flags & 0x0080 ? true : false;
 		_flags._xlat = flags & 0x0100 ? true : false;
 		_flags._port = flags & 0x0200 ? true : false;
@@ -504,11 +505,11 @@ void Sprite::sync(Common::Serializer &s) {
 		_flags._east = flags & 0x0800 ? true : false;
 		_flags._shad = flags & 0x1000 ? true : false;
 		_flags._back = flags & 0x2000 ? true : false;
-		_flags._bDel = flags & 0x4000 ? true : false;
+		//_flags._bDel = flags & 0x4000 ? true : false;
 		_flags._tran = flags & 0x8000 ? true : false;
 	} else {
 		flags = (flags << 1) | _flags._tran;
-		flags = (flags << 1) | _flags._bDel;
+		//flags = (flags << 1) | _flags._bDel;
 		flags = (flags << 1) | _flags._back;
 		flags = (flags << 1) | _flags._shad;
 		flags = (flags << 1) | _flags._east;
@@ -516,9 +517,9 @@ void Sprite::sync(Common::Serializer &s) {
 		flags = (flags << 1) | _flags._port;
 		flags = (flags << 1) | _flags._xlat;
 		flags = (flags << 1) | _flags._kill;
-		flags = (flags << 1) | _flags._syst;
+		//flags = (flags << 1) | _flags._syst;
 		flags = (flags << 1) | _flags._slav;
-		flags = (flags << 1) | _flags._dummy;
+		//flags = (flags << 1) | _flags._dummy;
 		flags = (flags << 1) | _flags._hold;
 		flags = (flags << 1) | _flags._drag;
 		flags = (flags << 1) | _flags._near;
@@ -526,6 +527,8 @@ void Sprite::sync(Common::Serializer &s) {
 		s.syncAsUint16LE(flags);
 	}
 
+	warning("STUB: Sprite::sync() - Flags changed compared to CGE1's Sprite type.");
+
 	s.syncAsUint16LE(_x);
 	s.syncAsUint16LE(_y);
 	s.syncAsByte(_z);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index b7325d8..8061acf 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -33,7 +33,7 @@
 #include "graphics/surface.h"
 #include "cge2/general.h"
 #include "cge2/bitmap.h"
-//#include "cge/snail.h"
+#include "cge2/snail.h"
 #include "cge2/cge2.h"
 
 namespace CGE2 {
@@ -89,20 +89,20 @@ public:
 	signed char _scene;
 	struct Flags {
 		uint16 _hide : 1;       // general visibility switch
-		uint16 _near : 1;       // Near action lock
 		uint16 _drag : 1;       // sprite is moveable
 		uint16 _hold : 1;       // sprite is held with mouse
-		uint16 _dummy : 1;       // intrrupt driven animation
+		uint16 _trim : 1;       // Trim flag
 		uint16 _slav : 1;       // slave object
-		uint16 _syst : 1;       // system object
 		uint16 _kill : 1;       // dispose memory after remove
 		uint16 _xlat : 1;       // 2nd way display: xlat table
 		uint16 _port : 1;       // portable
 		uint16 _kept : 1;       // kept in pocket
+		uint16 _frnt : 1;       // stay in front of sprite
 		uint16 _east : 1;       // talk to east (in opposite to west)
+		uint16 _near : 1;       // Near action lock
 		uint16 _shad : 1;       // shadow
 		uint16 _back : 1;       // 'send to background' request
-		uint16 _bDel : 1;       // delete bitmaps in ~SPRITE
+		uint16 _zmov : 1;       // sprite needs Z-update in queue
 		uint16 _tran : 1;       // transparent (untouchable)
 	} _flags;
 	int _x;
@@ -118,6 +118,7 @@ public:
 	char _file[kMaxFile];
 	Sprite *_prev;
 	Sprite *_next;
+	struct { byte _ptr, _cnt; } _actionCtrl[kActions];
 
 	bool works(Sprite *spr);
 	bool seqTest(int n);
@@ -125,6 +126,7 @@ public:
 		return _ext != NULL;
 	}
 
+	Sprite(CGE2Engine *vm);
 	Sprite(CGE2Engine *vm, BitmapPtr *shp);
 	virtual ~Sprite();
 	BitmapPtr shp();
@@ -136,7 +138,11 @@ public:
 	inline char *name() {
 		return (_ext) ? _ext->_name : NULL;
 	}
-	void gotoxy(int x, int y);
+	void gotoxyz(int x, int y, int z = 0);
+	void gotoxyz(void);
+	void gotoxyz(V2D pos);
+	void gotoxyz_(V2D pos);
+	void gotoxyz(V3D pos);
 	void center();
 	void show();
 	void hide();


Commit: 09b4092d530d99ba6b7c1aba9a009b39591a95dd
    https://github.com/scummvm/scummvm/commit/09b4092d530d99ba6b7c1aba9a009b39591a95dd
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-09T13:25:11+02:00

Commit Message:
CGE2: Remove Polish comments form SNCom.

Changed paths:
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 5cdb221..80aa33f 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -36,72 +36,72 @@ enum Action { kNear, kMTake, kFTake, kActions };
 
 enum SNCom {
 	kSNCom0 = 128,
-	kSNNop,     // NOP                  instrukcja "pusta"                        :: do nothing
-	kSNUse,     // USE <spr> <cav>|<lab> hint for using
-	kSNPause,   // PAUSE -1 <dly>       oczekiwanie <dly>/72 sekund               :: delay <dly>/72 seconds
-	kSNInf,     // INF -1 <ref>         prezentacja tekstu o numerze <ref>        :: show text referrenced by <ref>
-	kSNCave,    // CAVE -1 <cav>        przejœcie na planszê <cav>                :: go to board <cav>
+	kSNNop,     // NOP                       :: do nothing
+	kSNUse,     // USE <spr> <cav>|<lab>     :: hint for using
+	kSNPause,   // PAUSE -1 <dly>            :: delay <dly>/72 seconds
+	kSNInf,     // INF -1 <ref>              :: show text referrenced by <ref>
+	kSNCave,    // CAVE -1 <cav>             :: go to board <cav>
 	kSNSlave,   // SLAVE
-	kSNFocus,   // FOCUS                zmiana aktywnego bohatera (-1 cyklicznie) :: change active hero
-	kSNSetX,    // SETX <x> <idx>       ustawienie przesuniêcia sprajtu           :: set sprite shift in x axis
-	kSNSetY,    // SETX <y> <idx>       ustawienie przesuniêcia sprajtu           :: set sprite shift in y axis
-	kSNSetZ,    // SETX <z> <idx>       ustawienie przesuniêcia sprajtu           :: set sprite shift in z axis
-	kSNAdd,     // ADD <idx1> <idx2>    suma dwóch wektorów                       :: sum vectors
-	kSNSub,     // SUB <idx1> <idx2>    ró¿nica dwóch wektorów                    :: subtract vectors
-	kSNMul,     // MUL <idx> <nr>       iloczyn wektora przez liczbê              :: multiply vector by number
-	kSNDiv,     // DIV <idx> <nr>       iloraz wektora przez liczbê               :: divide vector by number
+	kSNFocus,   // FOCUS                     :: change active hero
+	kSNSetX,    // SETX <x> <idx>            :: set sprite shift in x axis
+	kSNSetY,    // SETX <y> <idx>            :: set sprite shift in y axis
+	kSNSetZ,    // SETX <z> <idx>            :: set sprite shift in z axis
+	kSNAdd,     // ADD <idx1> <idx2>         :: sum vectors
+	kSNSub,     // SUB <idx1> <idx2>         :: subtract vectors
+	kSNMul,     // MUL <idx> <nr>            :: multiply vector by number
+	kSNDiv,     // DIV <idx> <nr>            :: divide vector by number
 	kSNIf,      // IF
-	kSNFlag,    // FLAG <nr> <val>      nadanie wartoœci znacznikowi <nr>         :: set flag <nr> to <val>
-	kSNFlash,   // FLASH -1 0|1         rozjaœnienie ca³ego obrazu (tak/nie)      :: lighten whole image (on/off)
+	kSNFlag,    // FLAG <nr> <val>           :: set flag <nr> to <val>
+	kSNFlash,   // FLASH -1 0|1              :: lighten whole image (on/off)
 	kSNLight,   // LIGHT
-	kSNCycle,   // CYCLE <cnt>          cykliczne przesuwanie <cnt> kolorow od 1  :: rotate <cnt> colors from 1
-	kSNClear,   // CLEAR -1 0           wyzerowanie kolejki kSNAIL                 :: clear kSNAIL queue
-	kSNTalk,    // TALK -1 0|1          zezwolenie na dialogi (tak/nie)           :: enable speach (on/off)
-	kSNMouse,   // MOUSE -1 0|1         zezwolenie na mysz (tak/nie)              :: enable mouse (on/off)
-	kSNMap,     // MAP  0|1 0           chwilowe wylaczenie mapy dla bohatera     :: temporarily turn off map for hero
+	kSNCycle,   // CYCLE <cnt>               :: rotate <cnt> colors from 1
+	kSNClear,   // CLEAR -1 0                :: clear kSNAIL queue
+	kSNTalk,    // TALK -1 0|1               :: enable speach (on/off)
+	kSNMouse,   // MOUSE -1 0|1              :: enable mouse (on/off)
+	kSNMap,     // MAP  0|1 0                :: temporarily turn off map for hero
 	kSNCount,   // COUNT
-	kSNMidi,    // MIDI -1 <midi>       muzyka MIDI nr <midi> (-1 = cisza)        :: play MIDI referenced by <midi> (-1 = off)
-	kSNSetDlg,  // SETDLG 0..3 0..3     przelaczenie trybu mowy                   :: switch of speach mode
-	kSNMskDlg,  // MSKDLG 0..3 0..3     przelaczenie maski trybu mowy             :: switch of speach mode mask
+	kSNMidi,    // MIDI -1 <midi>            :: play MIDI referenced by <midi> (-1 = off)
+	kSNSetDlg,  // SETDLG 0..3 0..3          :: switch of speach mode
+	kSNMskDlg,  // MSKDLG 0..3 0..3          :: switch of speach mode mask
 
 	kSNSpr,
 
-	kSNWait,    // WAIT <spr> <seq>|-1  oczekiwanie na SEQ <seq> (-1 = stoi)      :: wait for SEQ <seq> (-1 = freeze)
-	kSNHide,    // HIDE <spr> 0|1       widzialnoϾ sprajtu                       :: visibility of sprite
-	kSNRoom,    // ROOM <hero> 0|1      dodatkowe miejsce w kieszeni (nie/tak)    :: additional room in pocket (no/yes)
-	kSNSay,     // SAY <spr> <ref>      wyg³oszenie tekstu o numerze <ref>        :: say text referenced by <ref>
-	kSNSound,   // SOUND <spr> <ref>    wyemitowanie efektu <ref>                 :: play sound effect referenced by <ref>
-	kSNTime,    // TIME <spr> 0         wyg³oszenie bie¿¹cego czasu               :: say current time
-	kSNKill,    // KILL <spr> 0         usuniêcie sprajtu                         :: remove sprite
-	kSNRSeq,    // RSEQ <spr> <nr>      wzglêdny skok SEQ o <nr>                  :: relative jump SEQ <nr> lines
-	kSNSeq,     // SEQ <spr> <seq>      skok do SEQ <seq>                         :: jump to certain SEQ
-	kSNSend,    // SEND <spr> <cav>     przeniesienie sprajtu na planszê <cav>    :: move sprite to board <cav>
-	kSNSwap,    // SWAP <spr1> spr2>    zamiana sprajtów                          :: sprite exchange
-	kSNKeep,    // KEEP <spr> <seq>     sprajt do kieszeni ze skokiem do <seq>    :: take sprite into pocket and jump to <seq>
-	kSNGive,    // GIVE <spr> <seq>     sprajt z kieszeni ze skokiem do <seq>     :: remove sprite from pocket and jump to <seq>
-	kSNGetPos,  // GETPOS <spr> <idx>   pobranie pozycji sprajtu                  :: take sprite's position
-	kSNGoto,    // GOTO <spr> <idx>     przesuniêcie sprajtu na dana pozycje      :: move sprite to position
-	kSNMoveX,   // MOVEX <spr> <dx>     przesuniêcie wzglêdne po osi X            :: relative move along X axis
-	kSNMoveY,   // MOVEY <spr> <dy>     przesuniêcie wzglêdne po osi Y            :: relative move along Y axis
-	kSNMoveZ,   // MOVEZ <spr> <dz>     przesuniêcie wzglêdne po osi Z            :: relative move along Z axis
-	kSNTrans,   // TRANS <spr> 0|1      ustalenie przezroczystoœci logicznej      :: clear/set logical transparency
-	kSNPort,    // PORT <spr> 0|1       ustalenie "bralnoœci" sprajtu             :: clear/set "takeability" of sprite
-	kSNNext,    // NEXT <spr> <nr>      skok do <nr> - NEAR lub TAKE              :: jump to <nr> - NEAR or TAKE
-	kSNNNext,   // NNEXT <spr> <nr>     skok do <nr> - NEAR                       :: jump to <nr> - NEAR
-	kSNMTNext,  // MTNEXT <spr> <nr>    skok do <nr> - TAKE                       :: jump to <nr> - TAKE
-	kSNFTNext,  // FTNEXT <spr> <nr>    skok do <nr> - TAKE                       :: jump to <nr> - TAKE
-	kSNRNNext,  // RNNEXT <spr> <nr>    skok wzglêdny do <nr> - NEAR              :: relative jump to <nr> - NEAR
-	kSNRMTNext, // RMTNEXT <spr> <nr>   skok wzglêdny do <nr> - TAKE              :: relative jump to <nr> - TAKE
-	kSNRFTNext, // RFTNEXT <spr> <nr>   skok wzglêdny do <nr> - TAKE              :: relative jump to <nr> - TAKE
-	kSNRMNear,  // RMNEAR <spr> 0       usuniêcie listy NEAR                      :: remove NEAR list
-	kSNRMMTake, // RMMTAKE <spr> 0      usuniêcie listy TAKE                      :: remove TAKE list
-	kSNRMFTake, // RMFTAKE <spr> 0      usuniêcie listy TAKE                      :: remove TAKE list
-	kSNSetRef,  // RETREF <spr> <ref>   zmiana numeru <ref> sprajta <spr>         :: change reference of sprite <spr> to <ref> 
-	kSNBackPt,  // BACKPT <spr> 0       wmalowanie sprajtu w t³o                  :: paint sprite onto the background
-	kSNWalk,    // WALK <hero> <ref>|<point> podejd¿ do sprajtu lub punktu        :: go close to the sprite or point
-	kSNReach,   // REACH <hero> <ref>|<m> siêgnij do <ref> lub sposobem <m>       :: reach the sprite or point with <m> method
-	kSNCover,   // COVER <sp1> <sp2>    przykrycie sprajtu <sp1> sprajtem <sp2>   :: cover sprite <sp1> with sprite <sp2>
-	kSNUncover, // UNCOVER <sp1> <sp2>  odtworzenie sytuacji sprzed COVER         :: restore the state before COVER
+	kSNWait,    // WAIT <spr> <seq>|-1       :: wait for SEQ <seq> (-1 = freeze)
+	kSNHide,    // HIDE <spr> 0|1            :: visibility of sprite
+	kSNRoom,    // ROOM <hero> 0|1           :: additional room in pocket (no/yes)
+	kSNSay,     // SAY <spr> <ref>           :: say text referenced by <ref>
+	kSNSound,   // SOUND <spr> <ref>         :: play sound effect referenced by <ref>
+	kSNTime,    // TIME <spr> 0              :: say current time
+	kSNKill,    // KILL <spr> 0              :: remove sprite
+	kSNRSeq,    // RSEQ <spr> <nr>           :: relative jump SEQ <nr> lines
+	kSNSeq,     // SEQ <spr> <seq>           :: jump to certain SEQ
+	kSNSend,    // SEND <spr> <cav>          :: move sprite to board <cav>
+	kSNSwap,    // SWAP <spr1> spr2>         :: sprite exchange
+	kSNKeep,    // KEEP <spr> <seq>          :: take sprite into pocket and jump to <seq>
+	kSNGive,    // GIVE <spr> <seq>          :: remove sprite from pocket and jump to <seq>
+	kSNGetPos,  // GETPOS <spr> <idx>        :: take sprite's position
+	kSNGoto,    // GOTO <spr> <idx>          :: move sprite to position
+	kSNMoveX,   // MOVEX <spr> <dx>          :: relative move along X axis
+	kSNMoveY,   // MOVEY <spr> <dy>          :: relative move along Y axis
+	kSNMoveZ,   // MOVEZ <spr> <dz>          :: relative move along Z axis
+	kSNTrans,   // TRANS <spr> 0|1           :: clear/set logical transparency
+	kSNPort,    // PORT <spr> 0|1            :: clear/set "takeability" of sprite
+	kSNNext,    // NEXT <spr> <nr>           :: jump to <nr> - NEAR or TAKE
+	kSNNNext,   // NNEXT <spr> <nr>          :: jump to <nr> - NEAR
+	kSNMTNext,  // MTNEXT <spr> <nr>         :: jump to <nr> - TAKE
+	kSNFTNext,  // FTNEXT <spr> <nr>         :: jump to <nr> - TAKE
+	kSNRNNext,  // RNNEXT <spr> <nr>         :: relative jump to <nr> - NEAR
+	kSNRMTNext, // RMTNEXT <spr> <nr>        :: relative jump to <nr> - TAKE
+	kSNRFTNext, // RFTNEXT <spr> <nr>        :: relative jump to <nr> - TAKE
+	kSNRMNear,  // RMNEAR <spr> 0            :: remove NEAR list
+	kSNRMMTake, // RMMTAKE <spr> 0           :: remove TAKE list
+	kSNRMFTake, // RMFTAKE <spr> 0           :: remove TAKE list
+	kSNSetRef,  // RETREF <spr> <ref>        :: change reference of sprite <spr> to <ref> 
+	kSNBackPt,  // BACKPT <spr> 0            :: paint sprite onto the background
+	kSNWalk,    // WALK <hero> <ref>|<point> :: go close to the sprite or point
+	kSNReach,   // REACH <hero> <ref>|<m>    :: reach the sprite or point with <m> method
+	kSNCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>
+	kSNUncover, // UNCOVER <sp1> <sp2>       :: restore the state before COVER
 
 	kSNDim,
 	kSNExec,


Commit: c75c026df8897c3a7aa4721a4e8f204e92f08daf
    https://github.com/scummvm/scummvm/commit/c75c026df8897c3a7aa4721a4e8f204e92f08daf
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-10T10:11:02+02:00

Commit Message:
CGE2: Reimplement constructors of Sprite.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 1d757ff..a696cad 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -56,23 +56,39 @@ Seq *getConstantSeq(bool seqFlag) {
 	return seq;
 }
 
-Sprite::Sprite(CGE2Engine *vm) {
-	warning("STUB: Sprite::Sprite()");
+byte Sprite::_constY = 0;
+byte Sprite::_follow = 0;
+
+Sprite::Sprite(CGE2Engine *vm)
+	: _siz(0, 0), _nearPtr(0), _takePtr(0),
+	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
+	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
+	  _pos2D(kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
+	memset(_actionCtrl, 0, sizeof(_actionCtrl));
+	memset(_file, 0, sizeof(_file));
+	memset(&_flags, 0, sizeof(_flags));
+	_flags._frnt = 1;
+
+	_ref = 0;
+	_w = _h = 0;
+	_seqPtr = 0;
+	_shpCnt = 0;
 }
 
 Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
-	: _x(0), _y(0), _z(0), _nearPtr(0), _takePtr(0),
+	: _siz(0, 0), _nearPtr(0), _takePtr(0),
 	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
-	  _ext(NULL), _ref(-1), _scene(0), _vm(vm) {
+	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
+	  _pos2D(kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
+	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
 	memset(&_flags, 0, sizeof(_flags));
+	_flags._frnt = 1;
+
 	_ref = 0;
-	_x = _y = 0;
 	_w = _h = 0;
-	_time = 0;
 	_seqPtr = 0;
 	_shpCnt = 0;
-	_prev = _next = NULL;
 
 	setShapeList(shpP);
 }


Commit: 724899fc1939e26b1805deb9f9c9c7fc19c9a5ee
    https://github.com/scummvm/scummvm/commit/724899fc1939e26b1805deb9f9c9c7fc19c9a5ee
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-10T11:12:30+02:00

Commit Message:
CGE2: Rework Sprite a bit, make _eye an engine variable.

Also move screenToGround() during the process.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/general.h
    engines/cge2/hero.cpp
    engines/cge2/hero.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index c3ec6a9..986c616 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -33,6 +33,7 @@
 #include "cge2/sound.h"
 #include "cge2/text.h"
 #include "cge2/hero.h"
+#include "cge2/general.h"
 
 namespace CGE2 {
 
@@ -47,6 +48,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_text = nullptr;
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = nullptr;
+	_eye = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -65,7 +67,8 @@ void CGE2Engine::init() {
 	_midiPlayer = new MusicPlayer(this);
 	_text = new Text(this, "CGE");
 	for (int i = 0; i < 2; i++)
-		_heroTab[i] = new HeroTab();
+		_heroTab[i] = new HeroTab(this);
+	_eye = new V3D();
 }
 
 void CGE2Engine::deinit() {
@@ -78,6 +81,7 @@ void CGE2Engine::deinit() {
 	delete _text;
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
+	delete _eye;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 79ac2c7..e4a4042 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -32,7 +32,6 @@
 #include "engines/advancedDetector.h"
 #include "common/system.h"
 #include "cge2/fileio.h"
-#include "cge2/general.h"
 
 namespace CGE2 {
 
@@ -43,6 +42,9 @@ class Fx;
 class Sound;
 class Text;
 struct HeroTab;
+class V3D;
+class V2D;
+class Dac;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -91,6 +93,7 @@ public:
 	Sound *_sound;
 	Text *_text;
 	HeroTab *_heroTab[2];
+	V3D *_eye;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 9da00be..9c89f52 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -31,6 +31,7 @@
 #include "common/file.h"
 #include "common/rect.h"
 #include "cge2/fileio.h"
+#include "cge2/cge2.h"
 
 namespace CGE2 {
 
@@ -60,49 +61,44 @@ public:
 };
 
 class V2D : public Common::Point {
-	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
-	static double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
+	CGE2Engine *_vm;
 public:
 	V2D& operator = (const V3D& p3) {
-		double m = Eye._z / (p3._z - Eye._z);
-		x = round((Eye._x + (Eye._x - p3._x) * m));
-		y = round((Eye._y + (Eye._y - p3._y) * m));
+		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
+		x = round((_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m));
+		y = round((_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m));
 		return *this;
 	}
-	V2D(void) { }
-	V2D(const V3D& p3) { *this = p3; }
-	V2D(int x, int y) : Common::Point(x, y) { }
-	static V3D Eye;
-	static void setEye(const V3D &e) { Eye = e; }
-	static void setEye(const V2D& e2, int z = -SCR_WID_) {
-		Eye._x = e2.x; Eye._y = e2.y; Eye._z = z;
+	V2D(CGE2Engine *vm) : _vm(vm) { }
+	V2D(CGE2Engine *vm, const V3D& p3) : _vm(vm) { *this = p3; }
+	V2D(CGE2Engine *vm, int x, int y) : _vm(vm), Common::Point(x, y) { }
+	void setEye(V3D &e) { _vm->_eye = &e; }
+	void setEye(const V2D& e2, int z = -SCR_WID_) {
+		_vm->_eye->_x = e2.x; _vm->_eye->_y = e2.y; _vm->_eye->_z = z;
 	}
-	static void setEye(const char *s) {
+	void setEye(const char *s) {
 		char *tempStr;
 		strcpy(tempStr, s);
-		Eye._x = atoi(EncryptedStream::token(tempStr));
-		Eye._y = atoi(EncryptedStream::token(tempStr));
-		Eye._z = atoi(EncryptedStream::token(tempStr));
+		_vm->_eye->_x = atoi(EncryptedStream::token(tempStr));
+		_vm->_eye->_y = atoi(EncryptedStream::token(tempStr));
+		_vm->_eye->_z = atoi(EncryptedStream::token(tempStr));
 	}
 	bool operator <  (const V2D& p) const { return (x <  p.x) && (y <  p.y); }
 	bool operator <= (const V2D& p) const { return (x <= p.x) && (y <= p.y); }
 	bool operator >(const V2D& p) const { return (x >  p.x) && (y >  p.y); }
 	bool operator >= (const V2D& p) const { return (x >= p.x) && (y >= p.y); }
-	V2D operator + (const V2D& p) const { return V2D(x + p.x, y + p.y); }
-	V2D operator - (const V2D& p) const { return V2D(x - p.x, y - p.y); }
+	V2D operator + (const V2D& p) const { return V2D(_vm, x + p.x, y + p.y); }
+	V2D operator - (const V2D& p) const { return V2D(_vm, x - p.x, y - p.y); }
 	uint16 area(void) { return x * y; }
 	bool limited(const V2D& p) {
 		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
 	}
 	V2D scale(int z) {
-		double m = Eye._z / (Eye._z - z);
-		return V2D(trunc(m * x), trunc(m * y));
-	}
-	static V3D screenToGround(V2D pos) {
-		double z = V2D::Eye._z + (V2D::Eye._y*V2D::Eye._z) / (double(pos.y) - V2D::Eye._y);
-		double x = V2D::Eye._x - ((double(pos.x) - V2D::Eye._x) * (z - V2D::Eye._z)) / V2D::Eye._z;
-		return V3D(round(x), 0, round(z));
+		double m = _vm->_eye->_z / (_vm->_eye->_z - z);
+		return V2D(_vm, trunc(m * x), trunc(m * y));
 	}
+	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
+	static double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 44ff850..3a6d1d2 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -117,6 +117,13 @@ void Hero::walkTo(Sprite *spr) {
 	warning("STUB: Hero::walkTo()");
 }
 
+V3D Hero::screenToGround(V2D pos) {
+	double z = _vm->_eye->_z + (_vm->_eye->_y * _vm->_eye->_z) / (double(pos.y) - _vm->_eye->_y);
+	double x = _vm->_eye->_x - ((double(pos.x) - _vm->_eye->_x) * (z - _vm->_eye->_z)) / _vm->_eye->_z;
+	return V3D(V2D::round(x), 0, V2D::round(z));
+}
+
+
 int Hero::cross(const V2D &a, const V2D &b) {
 	warning("STUB: Hero::cross()");
 	return 0;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 21f4ec3..032a46d 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -42,7 +42,15 @@ struct HeroTab {
 	Sprite *_face;
 	Sprite *_pocket[kPocketMax + 1];
 	int _pocPtr;
-	V2D _posTab[kCaveMax];
+	V2D *_posTab[kCaveMax];
+	HeroTab(CGE2Engine *vm) {
+		for (int i = 0; i < kCaveMax; i++)
+			_posTab[i] = new V2D(vm);
+	}
+	~HeroTab() {
+		for (int i = 0; i < kCaveMax; i++)
+			delete _posTab[i];
+	}
 };
 
 class Hero : public Sprite {
@@ -72,7 +80,8 @@ public:
 	bool findWay(void);
 	static int snap(int p, int q, int grid);
 	void walkTo(V3D pos);
-	void walkTo(V2D pos) { walkTo(V2D::screenToGround(pos)); }
+	void walkTo(V2D pos) { walkTo(screenToGround(pos)); }
+	V3D screenToGround(V2D pos);
 	void walkTo(Sprite *spr);
 	void say(void) { step(_sayStart); }
 	void fun(void);
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index a696cad..0a9add0 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -60,10 +60,10 @@ byte Sprite::_constY = 0;
 byte Sprite::_follow = 0;
 
 Sprite::Sprite(CGE2Engine *vm)
-	: _siz(0, 0), _nearPtr(0), _takePtr(0),
+	: _siz(_vm, 0, 0), _nearPtr(0), _takePtr(0),
 	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
 	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
-	  _pos2D(kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
+	  _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
 	memset(&_flags, 0, sizeof(_flags));
@@ -76,10 +76,10 @@ Sprite::Sprite(CGE2Engine *vm)
 }
 
 Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
-	: _siz(0, 0), _nearPtr(0), _takePtr(0),
+	: _siz(_vm, 0, 0), _nearPtr(0), _takePtr(0),
 	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
 	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
-	  _pos2D(kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
+	  _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
 	memset(&_flags, 0, sizeof(_flags));
@@ -383,18 +383,7 @@ Sprite *Sprite::backShow(bool fast) {
 }
 
 void Sprite::step(int nr) {
-	if (nr >= 0)
-		_seqPtr = nr;
-	if (_ext) {
-		Seq *seq;
-		if (nr < 0)
-			_seqPtr = _ext->_seq[_seqPtr]._next;
-		seq = _ext->_seq + _seqPtr;
-		if (seq->_dly >= 0) {
-			gotoxyz(_x + (seq->_dx), _y + (seq->_dy));
-			_time = seq->_dly;
-		}
-	}
+	warning("STUB: Sprite::step()");
 }
 
 //void Sprite::tick() {
@@ -449,26 +438,13 @@ void Sprite::center() {
 }
 
 void Sprite::show() {
-	SprExt *e;
-	e = _ext;
-	e->_x0 = e->_x1;
-	e->_y0 = e->_y1;
-	e->_b0 = e->_b1;
-	e->_x1 = _x;
-	e->_y1 = _y;
-	e->_b1 = shp();
-	if (!_flags._hide) {
-		if (_flags._xlat)
-			e->_b1->xShow(e->_x1, e->_y1);
-		else
-			e->_b1->show(e->_x1, e->_y1);
-	}
+	warning("STUB: Sprite::show()");
 }
 
 void Sprite::show(uint16 pg) {
 	Graphics::Surface *a = _vm->_vga->_page[1];
 	_vm->_vga->_page[1] = _vm->_vga->_page[pg & 3];
-	shp()->show(_x, _y);
+	shp()->show(_pos2D.x, _pos2D.y);
 	_vm->_vga->_page[1] = a;
 }
 
@@ -545,9 +521,9 @@ void Sprite::sync(Common::Serializer &s) {
 
 	warning("STUB: Sprite::sync() - Flags changed compared to CGE1's Sprite type.");
 
-	s.syncAsUint16LE(_x);
-	s.syncAsUint16LE(_y);
-	s.syncAsByte(_z);
+	s.syncAsUint16LE(_pos3D._x);
+	s.syncAsUint16LE(_pos3D._y);
+	s.syncAsByte(_pos3D._z);
 	s.syncAsUint16LE(_w);
 	s.syncAsUint16LE(_h);
 	s.syncAsUint16LE(_time);
@@ -614,7 +590,7 @@ void Queue::insert(Sprite *spr, Sprite *nxt) {
 void Queue::insert(Sprite *spr) {
 	Sprite *s;
 	for (s = _head; s; s = s->_next)
-		if (s->_z > spr->_z)
+		if (s->_pos3D._z > spr->_pos3D._z)
 			break;
 	if (s)
 		insert(spr, s);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 8061acf..487df10 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -105,9 +105,6 @@ public:
 		uint16 _zmov : 1;       // sprite needs Z-update in queue
 		uint16 _tran : 1;       // transparent (untouchable)
 	} _flags;
-	int _x;
-	int _y;
-	signed char _z;
 	uint16 _w;
 	uint16 _h;
 	uint16 _time;
@@ -119,6 +116,11 @@ public:
 	Sprite *_prev;
 	Sprite *_next;
 	struct { byte _ptr, _cnt; } _actionCtrl[kActions];
+	V2D _pos2D;
+	V3D _pos3D;
+	V2D _siz;
+	static byte _constY;
+	static byte _follow;
 
 	bool works(Sprite *spr);
 	bool seqTest(int n);


Commit: 3af6ff54570d290e80f4cf77b1beab071a39b026
    https://github.com/scummvm/scummvm/commit/3af6ff54570d290e80f4cf77b1beab071a39b026
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-10T14:03:27+02:00

Commit Message:
CGE2: Implement Sprite::gotoxyz().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index e4a4042..f3cf574 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -48,6 +48,8 @@ class Dac;
 
 #define kScrWidth      320
 #define kScrHeight     240
+#define kPanHeight     40
+#define kWorldHeight   (kScrHeight - kPanHeight)
 #define kMaxFile       128
 #define kPathMax       128
 #define kDimMax          8
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 0a9add0..22bd4f4 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -414,23 +414,78 @@ void Sprite::killXlat() {
 }
 
 void Sprite::gotoxyz(int x, int y, int z) {
-	warning("STUB: Sprite::gotoxyz()");
+	gotoxyz(V3D(x, y, z));
 }
 
 void Sprite::gotoxyz(void) {
-	warning("STUB: Sprite::gotoxyz()");
+	gotoxyz(_pos3D);
 }
 
 void Sprite::gotoxyz(V2D pos) {
-	warning("STUB: Sprite::gotoxyz()");
+	V2D o = _pos2D;
+	int ctr = _siz.x >> 1;
+	int rem = _siz.x - ctr;
+	byte trim = 0;
+
+	if (_ref / 10 == 14) { // HERO
+		int z = V2D::trunc(_pos3D._z);
+		ctr = (ctr * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
+		rem = (rem * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
+		ctr = (ctr * 3) / 4;
+		rem = (rem * 3) / 4;
+ 	}
+
+	if (pos.x - ctr < 0) {
+		pos.x = ctr;
+		++trim;
+	}
+	if (pos.x + rem > kScrWidth) {
+		pos.x = kScrWidth - rem;
+		++trim;
+	}
+	_pos2D.x = pos.x;
+
+	if (pos.y < -kPanHeight) {
+		pos.y = -kPanHeight;
+		++trim;
+	}
+	if (pos.y + _siz.y > kWorldHeight) {
+		pos.y = kWorldHeight - _siz.y;
+		++trim;
+	}
+	_pos2D.y = pos.y;
+
+	_flags._trim = (trim != 0);
+
+	if (!_follow) {
+		double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
+		_pos3D._x = (_vm->_eye->_x + V2D::round(_vm->_eye->_x - _pos2D.x) / m);
+		if (!_constY)
+			_pos3D._y = (_vm->_eye->_y + V2D::round(_vm->_eye->_y - _pos2D.y) / m);
+	}
+
+	if (_next && _next->_flags._slav)
+		_next->gotoxyz(_next->_pos2D - o + _pos2D);
+
+	if (_flags._shad)
+		_prev->gotoxyz(_prev->_pos2D - o + _pos2D);
+
+	if (_ref == 141 && _pos3D._y >= 5)
+		warning("Sprite::gotoxyz - asm nop");
 }
 
 void Sprite::gotoxyz_(V2D pos) {
-	warning("STUB: Sprite::gotoxyz()");
+	_constY++;
+	gotoxyz(pos);
+	--_constY;
 }
 
 void Sprite::gotoxyz(V3D pos) {
-	warning("STUB: Sprite::gotoxyz()");
+	_follow++;
+	if (pos._z != _pos3D._z)
+		_flags._zmov = true;
+	gotoxyz(V2D(_vm, _pos3D = pos));
+	--_follow;
 }
 
 void Sprite::center() {


Commit: 89bece4b420f90c1fd3adc6b63fe05a9815f5957
    https://github.com/scummvm/scummvm/commit/89bece4b420f90c1fd3adc6b63fe05a9815f5957
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-10T14:45:02+02:00

Commit Message:
CGE2: Implement ~Sprite().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 22bd4f4..ada6642 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -94,7 +94,10 @@ Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
 }
 
 Sprite::~Sprite() {
-	warning("STUB: Sprite::~Sprite()");
+	if (_vm->_sprite == this)
+		_vm->_sprite = NULL;
+
+	contract();
 }
 
 BitmapPtr Sprite::shp() {


Commit: 49d78527922f65c400056f0b4f98c26ee9d3a9c5
    https://github.com/scummvm/scummvm/commit/49d78527922f65c400056f0b4f98c26ee9d3a9c5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-12T22:24:21+02:00

Commit Message:
CGE2: Add Spare.

Changed paths:
  A engines/cge2/spare.cpp
  A engines/cge2/spare.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 986c616..c9fb590 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -34,6 +34,7 @@
 #include "cge2/text.h"
 #include "cge2/hero.h"
 #include "cge2/general.h"
+#include "cge2/spare.h"
 
 namespace CGE2 {
 
@@ -49,6 +50,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = nullptr;
 	_eye = nullptr;
+	_spare = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -69,6 +71,7 @@ void CGE2Engine::init() {
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = new HeroTab(this);
 	_eye = new V3D();
+	_spare = new Spare(this);
 }
 
 void CGE2Engine::deinit() {
@@ -82,6 +85,7 @@ void CGE2Engine::deinit() {
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
 	delete _eye;
+	delete _spare;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index f3cf574..bca5d1a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -45,6 +45,7 @@ struct HeroTab;
 class V3D;
 class V2D;
 class Dac;
+class Spare;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -96,6 +97,7 @@ public:
 	Text *_text;
 	HeroTab *_heroTab[2];
 	V3D *_eye;
+	Spare *_spare;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 4a7a412..60b7db5 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -10,7 +10,8 @@ MODULE_OBJS = \
 	cge2_main.o \
 	text.o \
 	hero.o \
-	snail.o
+	snail.o \
+	spare.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
new file mode 100644
index 0000000..c1e536a
--- /dev/null
+++ b/engines/cge2/spare.cpp
@@ -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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/spare.h"
+
+namespace CGE2 {
+
+void Spare::synchronize() {
+	warning("STUB: Spare::Load");
+}
+
+void Spare::clear() {
+	_container.clear();
+}
+
+Spare::Spare(CGE2Engine *vm) : _vm(vm) {}
+
+Sprite *Spare::take(int ref) {
+	for (int i = 0; i < _container.size(); i++) {
+		if (_container[i]._ref == ref) {
+			return &_container[i];
+		}
+	}
+	return nullptr;
+}
+
+void Spare::takeCave(int cav) {
+	int ref = cav << 8;
+	Sprite *spr = take(ref);
+	_vm->_vga->_showQ->insert(spr);
+}
+
+void Spare::make(Sprite *spr) {
+	_container.insert_at(_container.size(), *spr);
+}
+
+void Spare::dispose(Sprite *spr) {
+	warning("STUB: Spare::Dispose()");
+
+	if (spr) {
+		_vm->_vga->_showQ->remove(spr);
+
+		for (int i = 0; i < _container.size(); i++) {
+			if (spr == &_container[i]) {
+				_container.remove_at(i);
+			}
+		}
+	}
+}
+
+void Spare::dispose(int ref) {
+	dispose(_vm->_vga->_showQ->locate(ref));
+}
+
+void Spare::dispose() {
+	for (int i = 0; i < _container.size(); i++) {
+		if (_container[i]._ref > 255) {
+			dispose(&_container[i]);
+		}
+	}
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
new file mode 100644
index 0000000..8cfb65b
--- /dev/null
+++ b/engines/cge2/spare.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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_SPARE_H
+#define CGE2_SPARE_H
+
+#include "cge2/vga13h.h"
+
+namespace CGE2 {
+
+class Spare {
+	CGE2Engine *_vm;
+	Common::Array<Sprite> _container;
+public:
+	void make(Sprite *spr);
+	Spare(CGE2Engine *vm);
+	Sprite *take(int ref);
+	void takeCave(int cav);
+	void dispose(Sprite *spr);
+	void dispose(int ref);
+	void dispose();
+	void synchronize();
+	uint16 count() { _container.size(); }
+	void clear();
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_SPARE_H


Commit: 18182d5d2b75a42ff453aaa9ad6f60eb54bc898c
    https://github.com/scummvm/scummvm/commit/18182d5d2b75a42ff453aaa9ad6f60eb54bc898c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T07:46:13+02:00

Commit Message:
CGE2: Spare: store pointers instead of objects.

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index c1e536a..9a50f51 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -41,8 +41,8 @@ Spare::Spare(CGE2Engine *vm) : _vm(vm) {}
 
 Sprite *Spare::take(int ref) {
 	for (int i = 0; i < _container.size(); i++) {
-		if (_container[i]._ref == ref) {
-			return &_container[i];
+		if (_container[i]->_ref == ref) {
+			return _container[i];
 		}
 	}
 	return nullptr;
@@ -55,7 +55,7 @@ void Spare::takeCave(int cav) {
 }
 
 void Spare::make(Sprite *spr) {
-	_container.insert_at(_container.size(), *spr);
+	_container.insert_at(_container.size(), spr);
 }
 
 void Spare::dispose(Sprite *spr) {
@@ -65,7 +65,7 @@ void Spare::dispose(Sprite *spr) {
 		_vm->_vga->_showQ->remove(spr);
 
 		for (int i = 0; i < _container.size(); i++) {
-			if (spr == &_container[i]) {
+			if (spr == _container[i]) {
 				_container.remove_at(i);
 			}
 		}
@@ -78,8 +78,8 @@ void Spare::dispose(int ref) {
 
 void Spare::dispose() {
 	for (int i = 0; i < _container.size(); i++) {
-		if (_container[i]._ref > 255) {
-			dispose(&_container[i]);
+		if (_container[i]->_ref > 255) {
+			dispose(_container[i]);
 		}
 	}
 }
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 8cfb65b..3fc7ecf 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -34,7 +34,7 @@ namespace CGE2 {
 
 class Spare {
 	CGE2Engine *_vm;
-	Common::Array<Sprite> _container;
+	Common::Array<Sprite*> _container;
 public:
 	void make(Sprite *spr);
 	Spare(CGE2Engine *vm);


Commit: 631e9ef37e0bfd40deca4ee95a4a2186695434eb
    https://github.com/scummvm/scummvm/commit/631e9ef37e0bfd40deca4ee95a4a2186695434eb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T07:49:28+02:00

Commit Message:
CGE2: Fix Spare.

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 9a50f51..1bc4f47 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -34,11 +34,11 @@ void Spare::synchronize() {
 }
 
 void Spare::clear() {
+	for (int i = 0; i < _container.size(); i++)
+		delete _container[i];
 	_container.clear();
 }
 
-Spare::Spare(CGE2Engine *vm) : _vm(vm) {}
-
 Sprite *Spare::take(int ref) {
 	for (int i = 0; i < _container.size(); i++) {
 		if (_container[i]->_ref == ref) {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 3fc7ecf..cf0c29b 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -37,14 +37,14 @@ class Spare {
 	Common::Array<Sprite*> _container;
 public:
 	void make(Sprite *spr);
-	Spare(CGE2Engine *vm);
+	Spare(CGE2Engine *vm) : _vm(vm) {}
 	Sprite *take(int ref);
 	void takeCave(int cav);
 	void dispose(Sprite *spr);
 	void dispose(int ref);
 	void dispose();
 	void synchronize();
-	uint16 count() { _container.size(); }
+	uint16 count() { return _container.size(); }
 	void clear();
 };
 


Commit: 6aead2cb0345f7bef3221f7aab042d1e6ba1cbc9
    https://github.com/scummvm/scummvm/commit/6aead2cb0345f7bef3221f7aab042d1e6ba1cbc9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T08:48:48+02:00

Commit Message:
CGE2: Add destructor to Spare.

Changed paths:
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index cf0c29b..2fd235b 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -36,8 +36,9 @@ class Spare {
 	CGE2Engine *_vm;
 	Common::Array<Sprite*> _container;
 public:
-	void make(Sprite *spr);
 	Spare(CGE2Engine *vm) : _vm(vm) {}
+	~Spare() { clear(); }
+	void make(Sprite *spr);	
 	Sprite *take(int ref);
 	void takeCave(int cav);
 	void dispose(Sprite *spr);


Commit: 0fbdbd82720750779363b43e3a81c2bd9106b105
    https://github.com/scummvm/scummvm/commit/0fbdbd82720750779363b43e3a81c2bd9106b105
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T09:03:29+02:00

Commit Message:
CGE2: Rename take() to locate().

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 1bc4f47..5553e1d 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -39,7 +39,7 @@ void Spare::clear() {
 	_container.clear();
 }
 
-Sprite *Spare::take(int ref) {
+Sprite *Spare::locate(int ref) {
 	for (int i = 0; i < _container.size(); i++) {
 		if (_container[i]->_ref == ref) {
 			return _container[i];
@@ -50,7 +50,7 @@ Sprite *Spare::take(int ref) {
 
 void Spare::takeCave(int cav) {
 	int ref = cav << 8;
-	Sprite *spr = take(ref);
+	Sprite *spr = locate(ref);
 	_vm->_vga->_showQ->insert(spr);
 }
 
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 2fd235b..c89a968 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -39,7 +39,7 @@ public:
 	Spare(CGE2Engine *vm) : _vm(vm) {}
 	~Spare() { clear(); }
 	void make(Sprite *spr);	
-	Sprite *take(int ref);
+	Sprite *locate(int ref);
 	void takeCave(int cav);
 	void dispose(Sprite *spr);
 	void dispose(int ref);


Commit: d7c54653092bc4ed24011a88a6748a98a0a99312
    https://github.com/scummvm/scummvm/commit/d7c54653092bc4ed24011a88a6748a98a0a99312
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T09:07:06+02:00

Commit Message:
CGE2: Rename make() to store().

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 5553e1d..451cf21 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -54,7 +54,7 @@ void Spare::takeCave(int cav) {
 	_vm->_vga->_showQ->insert(spr);
 }
 
-void Spare::make(Sprite *spr) {
+void Spare::store(Sprite *spr) {
 	_container.insert_at(_container.size(), spr);
 }
 
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index c89a968..e1689c3 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -38,7 +38,7 @@ class Spare {
 public:
 	Spare(CGE2Engine *vm) : _vm(vm) {}
 	~Spare() { clear(); }
-	void make(Sprite *spr);	
+	void store(Sprite *spr);	
 	Sprite *locate(int ref);
 	void takeCave(int cav);
 	void dispose(Sprite *spr);


Commit: 6e509152544cd895da1b63923bbc2adf890e6d5f
    https://github.com/scummvm/scummvm/commit/6e509152544cd895da1b63923bbc2adf890e6d5f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T09:07:32+02:00

Commit Message:
CGE2: Finish implementation of loadScript().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 23fe4cb..38320c4 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -32,6 +32,7 @@
 #include "cge2/text.h"
 #include "cge2/snail.h"
 #include "cge2/hero.h"
+#include "cge2/spare.h"
 
 namespace CGE2 {
 
@@ -174,6 +175,8 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 	}
 
 	if (_sprite) {
+		_sprite->_ref = ref;
+
 		_sprite->_flags._frnt = frnt;
 		_sprite->_flags._east = east;
 		_sprite->_flags._port = port;
@@ -258,9 +261,15 @@ void CGE2Engine::loadScript(const char *fname) {
 		_sprite = NULL;
 		loadSprite(SpN, SpI, SpA, P);
 		if (_sprite) {
-			warning("STUB: CGE2Engine::loadScript - SPARE:: thing");
 			if (BkG)
 				_sprite->_flags._back = true;
+
+			int n = _spare->count();
+			if (_spare->locate(_sprite->_ref) == nullptr)
+				_spare->store(_sprite);
+			_sprite = nullptr;
+			if (_spare->count() == n)
+				error("Durplicated reference! %s", SpN);
 		}
 	}
 


Commit: 86c4e8336d1e84f53c6a4ec4dcbb57274ae662ec
    https://github.com/scummvm/scummvm/commit/86c4e8336d1e84f53c6a4ec4dcbb57274ae662ec
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T09:27:50+02:00

Commit Message:
CGE2: Add caveUp() and showBak().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index bca5d1a..82f0faf 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -77,6 +77,8 @@ public:
 	void loadScript(const char *fname);
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
+	void caveUp(int cav);
+	void showBak(int ref);
 
 	const ADGameDescription *_gameDescription;
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 38320c4..dbf9afe 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -288,8 +288,9 @@ void CGE2Engine::movie(const char *ext) {
 
 	if (_resman->exist(fn)) {
 		int now = _now;
-		_now = atoi(ext + 1);
+		_now = atoi(ext + 2);
 		loadScript(fn);
+		caveUp(_now);
 
 		warning("STUB: CGE2Engine::movie()");
 
@@ -297,6 +298,31 @@ void CGE2Engine::movie(const char *ext) {
 	}
 }
 
+void CGE2Engine::caveUp(int cav) {
+	_now = cav;
+	int bakRef = _now << 8;
+	if (_music)
+		_midiPlayer->loadMidi(bakRef);
+	showBak(bakRef);
+
+	warning("STUB: CGE2Engine::caveUp()");
+}
+
+void CGE2Engine::showBak(int ref) {
+	Sprite *spr = _spare->locate(ref);
+	if (spr != nullptr) {
+		_bitmapPalette = _vga->_sysPal;
+		warning("Check again this ^ !");
+		spr->expand();
+		_bitmapPalette = NULL;
+		//spr->show(2);
+		_vga->copyPage(1, 2);
+		_spare->dispose(spr);
+
+		warning("STUB: CGE2Engine::showBak()");
+	}
+}
+
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }


Commit: 2f404690e79377eb960d0acba36f09441c4693fd
    https://github.com/scummvm/scummvm/commit/2f404690e79377eb960d0acba36f09441c4693fd
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T09:51:22+02:00

Commit Message:
CGE2: Rename Snail to CommandHandler, expand it.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 82f0faf..cfa783e 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -58,6 +58,10 @@ class Spare;
 #define kPocketMax       4
 #define kCaveMax       100
 
+enum CallbackType {
+	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
+};
+
 class CGE2Engine : public Engine {
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index dbf9afe..be50327 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -131,7 +131,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 				case kIdNear:
 				case kIdMTake:
 				case kIdFTake:
-					if (Snail::com(p) >= 0)
+					if (CommandHandler::com(p) >= 0)
 						++cnt[section];
 					else
 						error("Bad line %d [%s]", sprf.getLineCount(), tmpStr);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 245da99..68cccea 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -30,7 +30,7 @@
 
 namespace CGE2 {
 
-const char *Snail::comTxt[] = {
+const char *CommandHandler::_commandText[] = {
 	"NOP", "USE", "PAUSE", "INF", "CAVE",
 	"SLAVE", "FOCUS", "SETX", "SETY", "SETZ",
 	"ADD", "SUB", "MUL", "DIV", "IF", "FLAG",
@@ -52,9 +52,34 @@ const char *Snail::comTxt[] = {
 	"WALKTO", "REACH", "COVER", "UNCOVER",
 	NULL };
 
-int Snail::com(const char *com) {
-	int i = EncryptedStream::takeEnum(comTxt, com);
-	return (i < 0) ? i : i + kSNCom0 + 1;
+void CommandHandler::runCommand() {
+	warning("STUB: CommandHandler::runCommand()");
+}
+
+void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
+	warning("STUB: CommandHandler::addCommand()");
+}
+
+void CommandHandler::addCallback(CommandType com, int ref, int val, CallbackType cbType) {
+	warning("STUB: CommandHandler::addCallback()");
+}
+
+void CommandHandler::insertCommand(CommandType com, int ref, int val, void *ptr) {
+	warning("STUB: CommandHandler::insertCommand()");
+}
+
+bool CommandHandler::idle() {
+	warning("STUB: CommandHandler::idle()");
+	return false;
+}
+
+void CommandHandler::reset() {
+	warning("STUB: CommandHandler::reset()");
+}
+
+int CommandHandler::com(const char *com) {
+	int i = EncryptedStream::takeEnum(_commandText, com);
+	return (i < 0) ? i : i + kCmdCom0 + 1;
 }
 
 } // End of namespace CGE2.
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 80aa33f..c8dea19 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -28,93 +28,119 @@
 #ifndef CGE2_SNAIL_H
 #define CGE2_SNAIL_H
 
+#include "cge2/cge2.h"
 #include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
 enum Action { kNear, kMTake, kFTake, kActions };
 
-enum SNCom {
-	kSNCom0 = 128,
-	kSNNop,     // NOP                       :: do nothing
-	kSNUse,     // USE <spr> <cav>|<lab>     :: hint for using
-	kSNPause,   // PAUSE -1 <dly>            :: delay <dly>/72 seconds
-	kSNInf,     // INF -1 <ref>              :: show text referrenced by <ref>
-	kSNCave,    // CAVE -1 <cav>             :: go to board <cav>
-	kSNSlave,   // SLAVE
-	kSNFocus,   // FOCUS                     :: change active hero
-	kSNSetX,    // SETX <x> <idx>            :: set sprite shift in x axis
-	kSNSetY,    // SETX <y> <idx>            :: set sprite shift in y axis
-	kSNSetZ,    // SETX <z> <idx>            :: set sprite shift in z axis
-	kSNAdd,     // ADD <idx1> <idx2>         :: sum vectors
-	kSNSub,     // SUB <idx1> <idx2>         :: subtract vectors
-	kSNMul,     // MUL <idx> <nr>            :: multiply vector by number
-	kSNDiv,     // DIV <idx> <nr>            :: divide vector by number
-	kSNIf,      // IF
-	kSNFlag,    // FLAG <nr> <val>           :: set flag <nr> to <val>
-	kSNFlash,   // FLASH -1 0|1              :: lighten whole image (on/off)
-	kSNLight,   // LIGHT
-	kSNCycle,   // CYCLE <cnt>               :: rotate <cnt> colors from 1
-	kSNClear,   // CLEAR -1 0                :: clear kSNAIL queue
-	kSNTalk,    // TALK -1 0|1               :: enable speach (on/off)
-	kSNMouse,   // MOUSE -1 0|1              :: enable mouse (on/off)
-	kSNMap,     // MAP  0|1 0                :: temporarily turn off map for hero
-	kSNCount,   // COUNT
-	kSNMidi,    // MIDI -1 <midi>            :: play MIDI referenced by <midi> (-1 = off)
-	kSNSetDlg,  // SETDLG 0..3 0..3          :: switch of speach mode
-	kSNMskDlg,  // MSKDLG 0..3 0..3          :: switch of speach mode mask
+enum CommandType {
+	kCmdCom0 = 128,
+	kCmdNop,     // NOP                       :: do nothing
+	kCmdUse,     // USE <spr> <cav>|<lab>     :: hint for using
+	kCmdPause,   // PAUSE -1 <dly>            :: delay <dly>/72 seconds
+	kCmdInf,     // INF -1 <ref>              :: show text referrenced by <ref>
+	kCmdCave,    // CAVE -1 <cav>             :: go to board <cav>
+	kCmdSlave,   // SLAVE
+	kCmdFocus,   // FOCUS                     :: change active hero
+	kCmdSetX,    // SETX <x> <idx>            :: set sprite shift in x axis
+	kCmdSetY,    // SETX <y> <idx>            :: set sprite shift in y axis
+	kCmdSetZ,    // SETX <z> <idx>            :: set sprite shift in z axis
+	kCmdAdd,     // ADD <idx1> <idx2>         :: sum vectors
+	kCmdSub,     // SUB <idx1> <idx2>         :: subtract vectors
+	kCmdMul,     // MUL <idx> <nr>            :: multiply vector by number
+	kCmdDiv,     // DIV <idx> <nr>            :: divide vector by number
+	kCmdIf,      // IF
+	kCmdFlag,    // FLAG <nr> <val>           :: set flag <nr> to <val>
+	kCmdFlash,   // FLASH -1 0|1              :: lighten whole image (on/off)
+	kCmdLight,   // LIGHT
+	kCmdCycle,   // CYCLE <cnt>               :: rotate <cnt> colors from 1
+	kCmdClear,   // CLEAR -1 0                :: clear kCmdAIL queue
+	kCmdTalk,    // TALK -1 0|1               :: enable speach (on/off)
+	kCmdMouse,   // MOUSE -1 0|1              :: enable mouse (on/off)
+	kCmdMap,     // MAP  0|1 0                :: temporarily turn off map for hero
+	kCmdCount,   // COUNT
+	kCmdMidi,    // MIDI -1 <midi>            :: play MIDI referenced by <midi> (-1 = off)
+	kCmdSetDlg,  // SETDLG 0..3 0..3          :: switch of speach mode
+	kCmdMskDlg,  // MSKDLG 0..3 0..3          :: switch of speach mode mask
 
-	kSNSpr,
+	kCmdSpr,
 
-	kSNWait,    // WAIT <spr> <seq>|-1       :: wait for SEQ <seq> (-1 = freeze)
-	kSNHide,    // HIDE <spr> 0|1            :: visibility of sprite
-	kSNRoom,    // ROOM <hero> 0|1           :: additional room in pocket (no/yes)
-	kSNSay,     // SAY <spr> <ref>           :: say text referenced by <ref>
-	kSNSound,   // SOUND <spr> <ref>         :: play sound effect referenced by <ref>
-	kSNTime,    // TIME <spr> 0              :: say current time
-	kSNKill,    // KILL <spr> 0              :: remove sprite
-	kSNRSeq,    // RSEQ <spr> <nr>           :: relative jump SEQ <nr> lines
-	kSNSeq,     // SEQ <spr> <seq>           :: jump to certain SEQ
-	kSNSend,    // SEND <spr> <cav>          :: move sprite to board <cav>
-	kSNSwap,    // SWAP <spr1> spr2>         :: sprite exchange
-	kSNKeep,    // KEEP <spr> <seq>          :: take sprite into pocket and jump to <seq>
-	kSNGive,    // GIVE <spr> <seq>          :: remove sprite from pocket and jump to <seq>
-	kSNGetPos,  // GETPOS <spr> <idx>        :: take sprite's position
-	kSNGoto,    // GOTO <spr> <idx>          :: move sprite to position
-	kSNMoveX,   // MOVEX <spr> <dx>          :: relative move along X axis
-	kSNMoveY,   // MOVEY <spr> <dy>          :: relative move along Y axis
-	kSNMoveZ,   // MOVEZ <spr> <dz>          :: relative move along Z axis
-	kSNTrans,   // TRANS <spr> 0|1           :: clear/set logical transparency
-	kSNPort,    // PORT <spr> 0|1            :: clear/set "takeability" of sprite
-	kSNNext,    // NEXT <spr> <nr>           :: jump to <nr> - NEAR or TAKE
-	kSNNNext,   // NNEXT <spr> <nr>          :: jump to <nr> - NEAR
-	kSNMTNext,  // MTNEXT <spr> <nr>         :: jump to <nr> - TAKE
-	kSNFTNext,  // FTNEXT <spr> <nr>         :: jump to <nr> - TAKE
-	kSNRNNext,  // RNNEXT <spr> <nr>         :: relative jump to <nr> - NEAR
-	kSNRMTNext, // RMTNEXT <spr> <nr>        :: relative jump to <nr> - TAKE
-	kSNRFTNext, // RFTNEXT <spr> <nr>        :: relative jump to <nr> - TAKE
-	kSNRMNear,  // RMNEAR <spr> 0            :: remove NEAR list
-	kSNRMMTake, // RMMTAKE <spr> 0           :: remove TAKE list
-	kSNRMFTake, // RMFTAKE <spr> 0           :: remove TAKE list
-	kSNSetRef,  // RETREF <spr> <ref>        :: change reference of sprite <spr> to <ref> 
-	kSNBackPt,  // BACKPT <spr> 0            :: paint sprite onto the background
-	kSNWalk,    // WALK <hero> <ref>|<point> :: go close to the sprite or point
-	kSNReach,   // REACH <hero> <ref>|<m>    :: reach the sprite or point with <m> method
-	kSNCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>
-	kSNUncover, // UNCOVER <sp1> <sp2>       :: restore the state before COVER
+	kCmdWait,    // WAIT <spr> <seq>|-1       :: wait for SEQ <seq> (-1 = freeze)
+	kCmdHide,    // HIDE <spr> 0|1            :: visibility of sprite
+	kCmdRoom,    // ROOM <hero> 0|1           :: additional room in pocket (no/yes)
+	kCmdSay,     // SAY <spr> <ref>           :: say text referenced by <ref>
+	kCmdSound,   // SOUND <spr> <ref>         :: play sound effect referenced by <ref>
+	kCmdTime,    // TIME <spr> 0              :: say current time
+	kCmdKill,    // KILL <spr> 0              :: remove sprite
+	kCmdRSeq,    // RSEQ <spr> <nr>           :: relative jump SEQ <nr> lines
+	kCmdSeq,     // SEQ <spr> <seq>           :: jump to certain SEQ
+	kCmdSend,    // SEND <spr> <cav>          :: move sprite to board <cav>
+	kCmdSwap,    // SWAP <spr1> spr2>         :: sprite exchange
+	kCmdKeep,    // KEEP <spr> <seq>          :: take sprite into pocket and jump to <seq>
+	kCmdGive,    // GIVE <spr> <seq>          :: remove sprite from pocket and jump to <seq>
+	kCmdGetPos,  // GETPOS <spr> <idx>        :: take sprite's position
+	kCmdGoto,    // GOTO <spr> <idx>          :: move sprite to position
+	kCmdMoveX,   // MOVEX <spr> <dx>          :: relative move along X axis
+	kCmdMoveY,   // MOVEY <spr> <dy>          :: relative move along Y axis
+	kCmdMoveZ,   // MOVEZ <spr> <dz>          :: relative move along Z axis
+	kCmdTrans,   // TRANS <spr> 0|1           :: clear/set logical transparency
+	kCmdPort,    // PORT <spr> 0|1            :: clear/set "takeability" of sprite
+	kCmdNext,    // NEXT <spr> <nr>           :: jump to <nr> - NEAR or TAKE
+	kCmdNNext,   // NNEXT <spr> <nr>          :: jump to <nr> - NEAR
+	kCmdMTNext,  // MTNEXT <spr> <nr>         :: jump to <nr> - TAKE
+	kCmdFTNext,  // FTNEXT <spr> <nr>         :: jump to <nr> - TAKE
+	kCmdRNNext,  // RNNEXT <spr> <nr>         :: relative jump to <nr> - NEAR
+	kCmdRMTNext, // RMTNEXT <spr> <nr>        :: relative jump to <nr> - TAKE
+	kCmdRFTNext, // RFTNEXT <spr> <nr>        :: relative jump to <nr> - TAKE
+	kCmdRMNear,  // RMNEAR <spr> 0            :: remove NEAR list
+	kCmdRMMTake, // RMMTAKE <spr> 0           :: remove TAKE list
+	kCmdRMFTake, // RMFTAKE <spr> 0           :: remove TAKE list
+	kCmdSetRef,  // RETREF <spr> <ref>        :: change reference of sprite <spr> to <ref> 
+	kCmdBackPt,  // BACKPT <spr> 0            :: paint sprite onto the background
+	kCmdWalk,    // WALK <hero> <ref>|<point> :: go close to the sprite or point
+	kCmdReach,   // REACH <hero> <ref>|<m>    :: reach the sprite or point with <m> method
+	kCmdCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>
+	kCmdUncover, // UNCOVER <sp1> <sp2>       :: restore the state before COVER
 
-	kSNDim,
-	kSNExec,
-	kSNStep,
-	kSNGhost,
+	kCmdDim,
+	kCmdExec,
+	kCmdStep,
+	kCmdGhost,
 	
-	kSNNOne = kNoByte
+	kCmdNOne = kNoByte
 };
 
-class Snail {
-	static const char *comTxt[];
+class CommandHandler {
 public:
+	struct Command {
+		CommandType _commandType;
+		int _ref;
+		int _val;
+		void *_spritePtr;
+		CallbackType _cbType;
+	} *_commandList;
+	static const char *_commandText[];
+	bool _talkEnable;
+
+	CommandHandler(CGE2Engine *vm, bool turbo);
+	~CommandHandler();
+	void runCommand();
+	void addCommand(CommandType com, int ref, int val, void *ptr);
+	void addCallback(CommandType com, int ref, int val, CallbackType cbType);
+	void insertCommand(CommandType com, int ref, int val, void *ptr);
+	bool idle();
+	void reset();
 	static int com(const char *com);
+private:
+	CGE2Engine *_vm;
+	bool _turbo;
+	uint8 _head;
+	uint8 _tail;
+	bool _busy;
+	bool _textDelay;
+	uint32 _timerExpiry;
 };
 
 } // End of namespace CGE2


Commit: e30296976c56301f7d4f90868b6f95af87d2de4a
    https://github.com/scummvm/scummvm/commit/e30296976c56301f7d4f90868b6f95af87d2de4a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T10:33:15+02:00

Commit Message:
CGE2: Instantiate CommandHandler.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index c9fb590..0c8318a 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -51,6 +51,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_heroTab[i] = nullptr;
 	_eye = nullptr;
 	_spare = nullptr;
+	_commandHandler = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -72,6 +73,7 @@ void CGE2Engine::init() {
 		_heroTab[i] = new HeroTab(this);
 	_eye = new V3D();
 	_spare = new Spare(this);
+	_commandHandler = new CommandHandler(this, false);
 }
 
 void CGE2Engine::deinit() {
@@ -86,6 +88,7 @@ void CGE2Engine::deinit() {
 		delete _heroTab[i];
 	delete _eye;
 	delete _spare;
+	delete _commandHandler;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index cfa783e..b288408 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -46,6 +46,7 @@ class V3D;
 class V2D;
 class Dac;
 class Spare;
+class CommandHandler;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -104,6 +105,7 @@ public:
 	HeroTab *_heroTab[2];
 	V3D *_eye;
 	Spare *_spare;
+	CommandHandler *_commandHandler;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 68cccea..52aefe2 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -52,6 +52,14 @@ const char *CommandHandler::_commandText[] = {
 	"WALKTO", "REACH", "COVER", "UNCOVER",
 	NULL };
 
+CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo) : _vm(vm) {
+	warning("STUB: CommandHandler::CommandHandler()");
+}
+
+CommandHandler::~CommandHandler() {
+	warning("STUB: CommandHandler::~CommandHandler()");
+}
+
 void CommandHandler::runCommand() {
 	warning("STUB: CommandHandler::runCommand()");
 }
@@ -78,7 +86,7 @@ void CommandHandler::reset() {
 }
 
 int CommandHandler::com(const char *com) {
-	int i = EncryptedStream::takeEnum(_commandText, com);
+	int i = _vm->takeEnum(_commandText, com);
 	return (i < 0) ? i : i + kCmdCom0 + 1;
 }
 


Commit: c108a1830600b3ae45d69b0b48a4747ba4b54819
    https://github.com/scummvm/scummvm/commit/c108a1830600b3ae45d69b0b48a4747ba4b54819
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T10:37:23+02:00

Commit Message:
CGE2: Make some static functions non-static.

EncryptedStream -> CGE2Engine
Namely:
* CGE2Engine::number(char *s)
* char *CGE2Engine::token(char *s)
* int CGE2Engine::takeEnum(const char **tab, const char *text)
* ID CGE2Engine::ident(const char *s)
* bool CGE2Engine::testBool(char *s)
* int CommandHandler::com(const char *com)

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h
    engines/cge2/general.h
    engines/cge2/snail.h
    engines/cge2/text.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index b288408..be2c129 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -85,6 +85,12 @@ public:
 	void caveUp(int cav);
 	void showBak(int ref);
 
+	int number(char *s);
+	char *token(char *s);
+	int takeEnum(const char **tab, const char *text);
+	ID ident(const char *s);
+	bool testBool(char *s);
+
 	const ADGameDescription *_gameDescription;
 
 	bool _quitFlag;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index be50327..352c62c 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -36,6 +36,37 @@
 
 namespace CGE2 {
 
+int CGE2Engine::number(char *s) {
+	int r = atoi(s);
+	char *pp = strchr(s, ':');
+	if (pp)
+		r = (r << 8) + atoi(pp + 1);
+	return r;
+}
+
+char *CGE2Engine::token(char *s) {
+	return strtok(s, " =\t,;/()");
+}
+
+int CGE2Engine::takeEnum(const char **tab, const char *text) {
+	if (text) {
+		for (const char **e = tab; *e; e++) {
+			if (scumm_stricmp(text, *e) == 0) {
+				return e - tab;
+			}
+		}
+	}
+	return -1;
+}
+
+ID CGE2Engine::ident(const char *s) {
+	return ID(takeEnum(EncryptedStream::kIdTab, s));
+}
+
+bool CGE2Engine::testBool(char *s) {
+	return number(s) != 0;
+}
+
 void CGE2Engine::badLab(const char *fn) {
 	error("Misplaced label in %s!", fn);
 }
@@ -73,7 +104,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 			
 			char *p;
-			p = EncryptedStream::token(tmpStr);
+			p = token(tmpStr);
 			if (*p == '@') {
 				if (label != kNoByte)
 					badLab(fname);
@@ -81,7 +112,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 				continue;
 			}
 
-			id = EncryptedStream::ident(p);
+			id = ident(p);
 			switch (id) {
 			case kIdName: // will be taken in Expand routine
 				if (label != kNoByte)
@@ -103,26 +134,26 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 			case kIdFront:
 				if (label != kNoByte)
 					badLab(fname);
-				p = EncryptedStream::token(nullptr);
-				frnt = EncryptedStream::testBool(p);
+				p = token(nullptr);
+				frnt = testBool(p);
 				break;
 			case kIdEast:
 				if (label != kNoByte)
 					badLab(fname);
-				p = EncryptedStream::token(nullptr);
-				east = EncryptedStream::testBool(p);
+				p = token(nullptr);
+				east = testBool(p);
 				break;
 			case kIdPortable:
 				if (label != kNoByte)
 					badLab(fname);
-				p = EncryptedStream::token(nullptr);
-				port = EncryptedStream::testBool(p);
+				p = token(nullptr);
+				port = testBool(p);
 				break;
 			case kIdTransparent:
 				if (label != kNoByte)
 					badLab(fname);
-				p = EncryptedStream::token(nullptr);
-				tran = EncryptedStream::testBool(p);
+				p = token(nullptr);
+				tran = testBool(p);
 				break;
 			default:
 				if (id >= kIdNear)
@@ -131,7 +162,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 				case kIdNear:
 				case kIdMTake:
 				case kIdFTake:
-					if (CommandHandler::com(p) >= 0)
+					if (_commandHandler->com(p) >= 0)
 						++cnt[section];
 					else
 						error("Bad line %d [%s]", sprf.getLineCount(), tmpStr);
@@ -222,39 +253,39 @@ void CGE2Engine::loadScript(const char *fname) {
 		V3D P;
 
 		// sprite ident number
-		if ((p = EncryptedStream::token(tmpStr)) == NULL)
+		if ((p = token(tmpStr)) == NULL)
 			break;
-		int SpI = EncryptedStream::number(p);
+		int SpI = number(p);
 
 		// sprite file name
 		char *SpN;
-		if ((SpN = EncryptedStream::token(nullptr)) == NULL)
+		if ((SpN = token(nullptr)) == NULL)
 			break;
 
 		// sprite scene
-		if ((p = EncryptedStream::token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == NULL)
 			break;
-		int SpA = EncryptedStream::number(p);
+		int SpA = number(p);
 
 		// sprite column
-		if ((p = EncryptedStream::token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == NULL)
 			break;
-		P._x = EncryptedStream::number(p);
+		P._x = number(p);
 
 		// sprite row
-		if ((p = EncryptedStream::token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == NULL)
 			break;
-		P._y = EncryptedStream::number(p);
+		P._y = number(p);
 
 		// sprite Z pos
-		if ((p = EncryptedStream::token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == NULL)
 			break;
-		P._z = EncryptedStream::number(p);
+		P._z = number(p);
 
 		// sprite life
-		if ((p = EncryptedStream::token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == NULL)
 			break;
-		bool BkG = EncryptedStream::number(p) == 0;
+		bool BkG = number(p) == 0;
 
 		ok = true; // no break: OK
 
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 6a20b6b..a9e9563 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -233,37 +233,6 @@ Common::String EncryptedStream::readLine() {
 	return _readStream->readLine();
 }
 
-int EncryptedStream::number(char *s) {
-	int r = atoi(s);
-	char *pp = strchr(s, ':');
-	if (pp)
-		r = (r << 8) + atoi(pp + 1);
-	return r;
-}
-
-char *EncryptedStream::token(char *s) {
-	return strtok(s, " =\t,;/()");
-}
-
-int EncryptedStream::takeEnum(const char **tab, const char *text) {
-	if (text) {
-		for (const char **e = tab; *e; e++) {
-			if (scumm_stricmp(text, *e) == 0) {
-				return e - tab;
-			}
-		}
-	}
-	return -1;
-}
-
-ID EncryptedStream::ident(const char *s) {
-	return ID(takeEnum(kIdTab, s));
-}
-
-bool EncryptedStream::testBool(char *s) {
-	return number(s) != 0;
-}
-
 int32 EncryptedStream::size() {
 	return _readStream->size();
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 758d841..3150022 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -112,8 +112,6 @@ private:
 	const char **_tab;
 	int _lineCount;
 	bool _error;
-
-	static const char *kIdTab[];
 public:
 	EncryptedStream(CGE2Engine *vm, const char *name);
 	~EncryptedStream();
@@ -124,12 +122,9 @@ public:
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
 	Common::String readLine();
-	static int number(char *s);
-	static char *token(char *s);
-	static int takeEnum(const char **tab, const char *text);
-	static ID ident(const char *s);
-	static bool testBool(char *s);
 	int getLineCount() { return _lineCount; }
+
+	static const char *kIdTab[];
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 9c89f52..62b41a9 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -79,9 +79,9 @@ public:
 	void setEye(const char *s) {
 		char *tempStr;
 		strcpy(tempStr, s);
-		_vm->_eye->_x = atoi(EncryptedStream::token(tempStr));
-		_vm->_eye->_y = atoi(EncryptedStream::token(tempStr));
-		_vm->_eye->_z = atoi(EncryptedStream::token(tempStr));
+		_vm->_eye->_x = atoi(_vm->token(tempStr));
+		_vm->_eye->_y = atoi(_vm->token(tempStr));
+		_vm->_eye->_z = atoi(_vm->token(tempStr));
 	}
 	bool operator <  (const V2D& p) const { return (x <  p.x) && (y <  p.y); }
 	bool operator <= (const V2D& p) const { return (x <= p.x) && (y <= p.y); }
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index c8dea19..b364aa9 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -132,7 +132,7 @@ public:
 	void insertCommand(CommandType com, int ref, int val, void *ptr);
 	bool idle();
 	void reset();
-	static int com(const char *com);
+	int com(const char *com);
 private:
 	CGE2Engine *_vm;
 	bool _turbo;
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index de33717..2f8e9b4 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -107,7 +107,7 @@ void Text::load() {
 		if (!Common::isDigit(*s))
 			continue;
 
-		int r = tf.number(s);
+		int r = _vm->number(s);
 
 		s += strlen(s);
 		if (s < tmpStr + n)


Commit: e8148cf1deafc0300ea758ab06e7a95d382c0fc6
    https://github.com/scummvm/scummvm/commit/e8148cf1deafc0300ea758ab06e7a95d382c0fc6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T11:58:42+02:00

Commit Message:
CGE2: Rework SprExt, stub more functions of Sprite.

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index ada6642..79c4861 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -209,7 +209,7 @@ Sprite *Sprite::expand() {
 	if (_ext)
 		return this;
 
-	_ext = new SprExt;
+	_ext = new SprExt(_vm);
 	assert(_ext != NULL);
 	if (!*_file)
 		return this;
@@ -507,9 +507,7 @@ void Sprite::show(uint16 pg) {
 }
 
 void Sprite::hide() {
-	SprExt *e = _ext;
-	if (e->_b0)
-		e->_b0->hide(e->_x0, e->_y0);
+	warning("STUB: Sprite::hide()");
 }
 
 BitmapPtr Sprite::ghost() {
@@ -519,12 +517,9 @@ BitmapPtr Sprite::ghost() {
 
 	BitmapPtr bmp = new Bitmap(_vm, 0, 0, (uint8 *)NULL);
 	assert(bmp != NULL);
-	bmp->_w = e->_b1->_w;
-	bmp->_h = e->_b1->_h;
-	bmp->_b = new HideDesc[bmp->_h];
-	assert(bmp->_b != NULL);
-	bmp->_v = (uint8 *) memcpy(bmp->_b, e->_b1->_b, sizeof(HideDesc) * bmp->_h);
-	bmp->_map = (e->_y1 << 16) + e->_x1;
+
+	warning("STUB: Sprite::ghost()");
+
 	return bmp;
 }
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 487df10..d2fb198 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -60,23 +60,18 @@ struct Seq {
 
 class SprExt {
 public:
-	int _x0;
-	int _y0;
-	int _x1;
-	int _y1;
+	V2D _p0;
+	V2D _p1;
 	BitmapPtr _b0;
 	BitmapPtr _b1;
 	BitmapPtr *_shpList;
+	int _location;
 	Seq *_seq;
 	char *_name;
-	/*CommandHandler::Command *_near;
-	CommandHandler::Command *_take;*/
-	SprExt() :
-		_x0(0), _y0(0),
-		_x1(0), _y1(0),
-		_b0(NULL), _b1(NULL),
-		_shpList(NULL), _seq(NULL),
-		_name(NULL)/*, _near(NULL), _take(NULL)*/
+	CommandHandler::Command *_actions[kActions];
+	SprExt(CGE2Engine *vm) : _p0(vm, 0, 0), _p1(vm, 0, 0),
+		_b0(NULL), _b1(NULL),_shpList(NULL), _location(0),
+		_seq(NULL), _name(NULL)
 	{}
 };
 


Commit: 78429a723863728b2c95f286a1c313cc6f17d010
    https://github.com/scummvm/scummvm/commit/78429a723863728b2c95f286a1c313cc6f17d010
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T16:47:55+02:00

Commit Message:
CGE2: More revision and stubbing in Sprite.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 0c8318a..4afafdc 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -135,7 +135,7 @@ bool CGE2Engine::showTitle(const char *name) {
 	LB[1] = NULL;
 	_bitmapPalette = NULL;
 
-	Sprite D(this, LB);
+	Sprite D(this, LB, 2);
 	D._flags._kill = true;
 	// D._flags._bDel = true;
 	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 79c4861..47b0d6f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -56,41 +56,33 @@ Seq *getConstantSeq(bool seqFlag) {
 	return seq;
 }
 
+void(*Sprite::notify) (void) = nullptr;
+
 byte Sprite::_constY = 0;
 byte Sprite::_follow = 0;
 
 Sprite::Sprite(CGE2Engine *vm)
-	: _siz(_vm, 0, 0), _nearPtr(0), _takePtr(0),
-	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
+	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
+      _next(NULL), _prev(NULL), _time(0),
 	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
 	  _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
 	memset(&_flags, 0, sizeof(_flags));
 	_flags._frnt = 1;
-
-	_ref = 0;
-	_w = _h = 0;
-	_seqPtr = 0;
-	_shpCnt = 0;
 }
 
-Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP)
-	: _siz(_vm, 0, 0), _nearPtr(0), _takePtr(0),
-	  _next(NULL), _prev(NULL), _seqPtr(kNoSeq), _time(0),
-	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
-	  _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
+Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP, int cnt)
+	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
+     _next(NULL), _prev(NULL), _time(0),
+     _ext(NULL), _ref(-1), _scene(0), _vm(vm),
+     _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
 	memset(&_flags, 0, sizeof(_flags));
 	_flags._frnt = 1;
 
-	_ref = 0;
-	_w = _h = 0;
-	_seqPtr = 0;
-	_shpCnt = 0;
-
-	setShapeList(shpP);
+	setShapeList(shpP, cnt);
 }
 
 Sprite::~Sprite() {
@@ -111,33 +103,8 @@ BitmapPtr Sprite::shp() {
 	return e->_shpList[i];
 }
 
-BitmapPtr *Sprite::setShapeList(BitmapPtr *shpP) {
-	BitmapPtr *r = (_ext) ? _ext->_shpList : NULL;
-
-	_shpCnt = 0;
-	_w = 0;
-	_h = 0;
-
-	if (shpP) {
-		BitmapPtr *p;
-		for (p = shpP; *p; p++) {
-			BitmapPtr b = (*p); // ->Code();
-			if (b->_w > _w)
-				_w = b->_w;
-			if (b->_h > _h)
-				_h = b->_h;
-			_shpCnt++;
-		}
-		expand();
-		_ext->_shpList = shpP;
-
-		//_flags._bDel = true;
-		warning("STUB: Sprite::sync() - Flags changed compared to CGE1's Sprite type.");
-
-		if (!_ext->_seq)
-			setSeq(getConstantSeq(_shpCnt < 2));
-	}
-	return r;
+void Sprite::setShapeList(BitmapPtr *shp, int cnt) {
+	warning("STUB: Sprite::setShapeList()");
 }
 
 bool Sprite::works(Sprite *spr) {
@@ -492,7 +459,7 @@ void Sprite::gotoxyz(V3D pos) {
 }
 
 void Sprite::center() {
-	gotoxyz((kScrWidth - _w) / 2, (kScrHeight - _h) / 2);
+	gotoxyz(kScrWidth >> 1, (kWorldHeight - _siz.y) >> 1, 0);
 }
 
 void Sprite::show() {
@@ -577,11 +544,7 @@ void Sprite::sync(Common::Serializer &s) {
 	s.syncAsUint16LE(_pos3D._x);
 	s.syncAsUint16LE(_pos3D._y);
 	s.syncAsByte(_pos3D._z);
-	s.syncAsUint16LE(_w);
-	s.syncAsUint16LE(_h);
 	s.syncAsUint16LE(_time);
-	s.syncAsByte(_nearPtr);
-	s.syncAsByte(_takePtr);
 	s.syncAsSint16LE(_seqPtr);
 	s.syncAsUint16LE(_shpCnt);
 	s.syncBytes((byte *)&_file[0], 9);
@@ -1019,35 +982,41 @@ void Bitmap::hide(int16 x, int16 y) {
 
 /*--------------------------------------------------------------------------*/
 
-HorizLine::HorizLine(CGE2Engine *vm) : Sprite(vm, NULL), _vm(vm) {
+HorizLine::HorizLine(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
 	// Set the sprite list
 	BitmapPtr *HL = new BitmapPtr[2];
 	HL[0] = new Bitmap(_vm, "HLINE");
 	HL[1] = NULL;
 
-	setShapeList(HL);
+	setShapeList(HL, 1);
+
+	warning("HorizLine::HorizLine() - Recheck this!");
 }
 
-SceneLight::SceneLight(CGE2Engine *vm) : Sprite(vm, NULL), _vm(vm) {
+SceneLight::SceneLight(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
 	// Set the sprite list
 	BitmapPtr *PR = new BitmapPtr[2];
 	PR[0] = new Bitmap(_vm, "PRESS");
 	PR[1] = NULL;
 
-	setShapeList(PR);
+	setShapeList(PR, 1);
+
+	warning("SceneLight::SceneLight() - Recheck this!");
 }
 
-Speaker::Speaker(CGE2Engine *vm): Sprite(vm, NULL), _vm(vm) {
+Speaker::Speaker(CGE2Engine *vm): Sprite(vm), _vm(vm) {
 	// Set the sprite list
 	BitmapPtr *SP = new BitmapPtr[3];
 	SP[0] = new Bitmap(_vm, "SPK_L");
 	SP[1] = new Bitmap(_vm, "SPK_R");
 	SP[2] = NULL;
 
-	setShapeList(SP);
+	setShapeList(SP, 2);
+
+	warning("Speaker::Speaker() - Recheck this!");
 }
 
-PocLight::PocLight(CGE2Engine *vm): Sprite(vm, NULL), _vm(vm) {
+PocLight::PocLight(CGE2Engine *vm): Sprite(vm), _vm(vm) {
 	// Set the sprite list
 	BitmapPtr *LI = new BitmapPtr[5];
 	LI[0] = new Bitmap(_vm, "LITE0");
@@ -1056,9 +1025,11 @@ PocLight::PocLight(CGE2Engine *vm): Sprite(vm, NULL), _vm(vm) {
 	LI[3] = new Bitmap(_vm, "LITE3");
 	LI[4] = NULL;
 
-	setShapeList(LI);
+	setShapeList(LI, 4);
 
 	_flags._kill = false;
+
+	warning("PocLight::PocLight() - Recheck this!");
 }
 
 } // End of namespace CGE2
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index d2fb198..437cba0 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -100,20 +100,18 @@ public:
 		uint16 _zmov : 1;       // sprite needs Z-update in queue
 		uint16 _tran : 1;       // transparent (untouchable)
 	} _flags;
-	uint16 _w;
-	uint16 _h;
+	V2D _pos2D;
+	V3D _pos3D;
+	V2D _siz;
 	uint16 _time;
-	uint8 _nearPtr;
-	uint8 _takePtr;
+	struct { byte _ptr, _cnt; } _actionCtrl[kActions];
 	int _seqPtr;
+	int _seqCnt;
 	int _shpCnt;
 	char _file[kMaxFile];
+	// Following trailer is not saved with the game:
 	Sprite *_prev;
 	Sprite *_next;
-	struct { byte _ptr, _cnt; } _actionCtrl[kActions];
-	V2D _pos2D;
-	V3D _pos3D;
-	V2D _siz;
 	static byte _constY;
 	static byte _follow;
 
@@ -122,12 +120,14 @@ public:
 	inline bool active() {
 		return _ext != NULL;
 	}
-
 	Sprite(CGE2Engine *vm);
-	Sprite(CGE2Engine *vm, BitmapPtr *shp);
+	Sprite(CGE2Engine *vm, BitmapPtr *shp, int cnt);
 	virtual ~Sprite();
 	BitmapPtr shp();
-	BitmapPtr *setShapeList(BitmapPtr *shp);
+	void setShapeList(BitmapPtr *shp, int cnt);
+	void moveShapesHi(void);
+	void moveShapesLo(void);
+	int LabVal(Action snq, int lab);
 	Sprite *expand();
 	Sprite *contract();
 	Sprite *backShow(bool fast = false);
@@ -141,18 +141,22 @@ public:
 	void gotoxyz_(V2D pos);
 	void gotoxyz(V3D pos);
 	void center();
+	void show(uint16 pg);
+	void hide(uint16 pg);
 	void show();
 	void hide();
 	BitmapPtr ghost();
-	void show(uint16 pg);
 	void makeXlat(uint8 *x);
 	void killXlat();
 	void step(int nr = -1);
 	Seq *setSeq(Seq *seq);
-	//CommandHandler::Command *snList(SnList type);
-	/*virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
-	virtual void tick();*/
+	CommandHandler::Command *snList(Action type);
+	//virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
+	//virtual void tick();
+	void clrHide(void) { if (_ext) _ext->_b0 = NULL; }
 	void sync(Common::Serializer &s);
+
+	static void (*notify) (void);
 };
 
 class Queue {


Commit: 4ee1ab07aea7d07a661b58770721f6edce4d5f18
    https://github.com/scummvm/scummvm/commit/4ee1ab07aea7d07a661b58770721f6edce4d5f18
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T17:04:51+02:00

Commit Message:
CGE2: Add a self-not warning to Bitmap.

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 77c7eb9..6237fea 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -113,6 +113,8 @@ Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(N
 Bitmap::~Bitmap() {
 	free(_m);
 	delete[] _v;
+
+	warning("Bitmap: Don't forget to review the whole implemenation!");
 }
 
 Bitmap &Bitmap::operator=(const Bitmap &bmp) {


Commit: c202328ecf9fc244e0e3974c303056b811726af7
    https://github.com/scummvm/scummvm/commit/c202328ecf9fc244e0e3974c303056b811726af7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-13T17:27:12+02:00

Commit Message:
CGE2: Implement Sprite::setShapeList().

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 47b0d6f..054769e 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -61,6 +61,17 @@ void(*Sprite::notify) (void) = nullptr;
 byte Sprite::_constY = 0;
 byte Sprite::_follow = 0;
 
+Seq Sprite::_stdSeq8[] =
+{ { 0, 0, 0, 0, 0, 0 },
+  { 1, 1, 0, 0, 0, 0 },
+  { 2, 2, 0, 0, 0, 0 },
+  { 3, 3, 0, 0, 0, 0 },
+  { 4, 4, 0, 0, 0, 0 },
+  { 5, 5, 0, 0, 0, 0 },
+  { 6, 6, 0, 0, 0, 0 },
+  { 7, 7, 0, 0, 0, 0 },
+};
+
 Sprite::Sprite(CGE2Engine *vm)
 	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
       _next(NULL), _prev(NULL), _time(0),
@@ -104,7 +115,25 @@ BitmapPtr Sprite::shp() {
 }
 
 void Sprite::setShapeList(BitmapPtr *shp, int cnt) {
-	warning("STUB: Sprite::setShapeList()");
+	_shpCnt = cnt;
+	_siz.x = 0;
+	_siz.y = 0;
+
+	if (shp) {
+		for (int i = 0; i < cnt; i++) {
+			BitmapPtr p = *shp + i;
+			if (p->_w > _siz.x)
+				_siz.x = p->_w;
+			if (p->_h > _siz.y)
+				_siz.y = p->_w;
+		}
+		expand();
+		_ext->_shpList = shp;
+		if (!_ext->_seq) {
+			setSeq(_stdSeq8);
+			_seqCnt = (cnt < ARRAYSIZE(_stdSeq8)) ? cnt : ARRAYSIZE(_stdSeq8);
+		}
+	}
 }
 
 bool Sprite::works(Sprite *spr) {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 437cba0..f8c7bf4 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -55,6 +55,7 @@ struct Seq {
 	uint8 _next;
 	int8 _dx;
 	int8 _dy;
+	int8 _dz;
 	int _dly;
 };
 
@@ -114,6 +115,7 @@ public:
 	Sprite *_next;
 	static byte _constY;
 	static byte _follow;
+	static Seq _stdSeq8[];
 
 	bool works(Sprite *spr);
 	bool seqTest(int n);


Commit: 945f12f2ad04ce60d2d072548799a440ebb32da6
    https://github.com/scummvm/scummvm/commit/945f12f2ad04ce60d2d072548799a440ebb32da6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T10:58:59+02:00

Commit Message:
CGE2: Move setEye()s to CGE2Engine.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/general.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 4afafdc..85e8e88 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -50,6 +50,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = nullptr;
 	_eye = nullptr;
+	for (int i = 0; i < kCaveMax; i++)
+		_eyeTab[i] = nullptr;
 	_spare = nullptr;
 	_commandHandler = nullptr;
 	
@@ -72,6 +74,8 @@ void CGE2Engine::init() {
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = new HeroTab(this);
 	_eye = new V3D();
+	for (int i = 0; i < kCaveMax; i++)
+		_eyeTab[i] = new V3D();
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
 }
@@ -87,6 +91,8 @@ void CGE2Engine::deinit() {
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
 	delete _eye;
+	for (int i = 0; i < kCaveMax; i++)
+		delete _eyeTab[i];
 	delete _spare;
 	delete _commandHandler;
 }
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index be2c129..fa161f3 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -84,6 +84,11 @@ public:
 	void badLab(const char *fn);
 	void caveUp(int cav);
 	void showBak(int ref);
+	void loadTab();
+
+	void setEye(V3D &e);
+	void setEye(const V2D& e2, int z = -kScrWidth);
+	void setEye(const char *s);
 
 	int number(char *s);
 	char *token(char *s);
@@ -110,6 +115,7 @@ public:
 	Text *_text;
 	HeroTab *_heroTab[2];
 	V3D *_eye;
+	V3D *_eyeTab[kCaveMax];
 	Spare *_spare;
 	CommandHandler *_commandHandler;
 private:
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 352c62c..a0717a3 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -384,4 +384,22 @@ char *CGE2Engine::mergeExt(char *buf, const char *name, const char *ext) {
 	return buf;
 }
 
+void CGE2Engine::setEye(V3D &e) { 
+	_eye = &e;
+}
+
+void CGE2Engine::setEye(const V2D& e2, int z) {
+	_eye->_x = e2.x;
+	_eye->_y = e2.y;
+	_eye->_z = z;
+}
+
+void CGE2Engine::setEye(const char *s) {
+	char tempStr[kLineMax];
+	strcpy(tempStr, s);
+	_eye->_x = atoi(token(tempStr));
+	_eye->_y = atoi(token(NULL));
+	_eye->_z = atoi(token(NULL));
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 62b41a9..747fb84 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -72,17 +72,6 @@ public:
 	V2D(CGE2Engine *vm) : _vm(vm) { }
 	V2D(CGE2Engine *vm, const V3D& p3) : _vm(vm) { *this = p3; }
 	V2D(CGE2Engine *vm, int x, int y) : _vm(vm), Common::Point(x, y) { }
-	void setEye(V3D &e) { _vm->_eye = &e; }
-	void setEye(const V2D& e2, int z = -SCR_WID_) {
-		_vm->_eye->_x = e2.x; _vm->_eye->_y = e2.y; _vm->_eye->_z = z;
-	}
-	void setEye(const char *s) {
-		char *tempStr;
-		strcpy(tempStr, s);
-		_vm->_eye->_x = atoi(_vm->token(tempStr));
-		_vm->_eye->_y = atoi(_vm->token(tempStr));
-		_vm->_eye->_z = atoi(_vm->token(tempStr));
-	}
 	bool operator <  (const V2D& p) const { return (x <  p.x) && (y <  p.y); }
 	bool operator <= (const V2D& p) const { return (x <= p.x) && (y <= p.y); }
 	bool operator >(const V2D& p) const { return (x >  p.x) && (y >  p.y); }


Commit: b2cbc7cdd17d2e998cc2dd4273ec8966fbe8e58f
    https://github.com/scummvm/scummvm/commit/b2cbc7cdd17d2e998cc2dd4273ec8966fbe8e58f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T10:59:46+02:00

Commit Message:
CGE2: Partially implement loadTab(), then use it.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a0717a3..9ee9459 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -358,9 +358,20 @@ void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }
 
+void CGE2Engine::loadTab() {
+	char *n = _text->getText(240);
+	setEye(_text->getText(240));
+	for (int i = 0; i < kCaveMax; i++)
+		_eyeTab[i] == _eye;
+
+	warning("STUB: CGE2Engine::loadTab()");
+}
+
 void CGE2Engine::cge2_main() {
 	warning("STUB: CGE2Engine::cge2_main()");
 
+	loadTab();
+
 	_mode++;
 
 	if (showTitle("WELCOME")) {
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 8420a2d..ee622dc 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -33,6 +33,7 @@ namespace CGE2 {
 #define kLineMax          512
 #define kIntroExt      ".I80"
 #define kNoByte            -1
+#define kTabName    "CGE.TAB"
 
 } // End of namespace CGE2
 


Commit: 99c15216c71f5f75632a7e38573a2387be39fed9
    https://github.com/scummvm/scummvm/commit/99c15216c71f5f75632a7e38573a2387be39fed9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T11:16:35+02:00

Commit Message:
CGE2: Add Bitmap::xLatPos().

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 6237fea..39483b0 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -368,4 +368,9 @@ bool Bitmap::loadVBM(EncryptedStream *f) {
 	return (!f->err());
 }
 
+void Bitmap::xLatPos(V2D& p) {
+	p.x -= (_w >> 1);
+	p.y = kWorldHeight - p.y - _h;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 3d3c27f..ea7146f 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -28,7 +28,7 @@
 #ifndef CGE2_BITMAP_H
 #define CGE2_BITMAP_H
 
-#include "cge/general.h"
+#include "cge2/general.h"
 #include "common/file.h"
 
 namespace CGE2 {
@@ -77,6 +77,7 @@ public:
 	void show(int16 x, int16 y);
 	void xShow(int16 x, int16 y);
 	bool solidAt(int16 x, int16 y);
+	void xLatPos(V2D& p);
 };
 
 


Commit: 4e7bcb5f36c6abd07413323573670b140523f9b0
    https://github.com/scummvm/scummvm/commit/4e7bcb5f36c6abd07413323573670b140523f9b0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T11:20:13+02:00

Commit Message:
CGE2: Fix ShowTitle().

Now it REALLY puts the picture to the middle of the screen.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 85e8e88..8d7f58f 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -141,16 +141,17 @@ bool CGE2Engine::showTitle(const char *name) {
 	LB[1] = NULL;
 	_bitmapPalette = NULL;
 
-	Sprite D(this, LB, 2);
+	Sprite D(this, LB, 1);
 	D._flags._kill = true;
-	// D._flags._bDel = true;
 	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
-	D.center();
+	D.gotoxyz(kScrWidth >> 1, -(kPanHeight >> 1));
+	_vga->sunset();
+	
 	D.show(2);
 
-	_vga->sunset();
 	_vga->copyPage(1, 2);
 	_vga->copyPage(0, 1);
+	
 	_vga->sunrise(_vga->_sysPal);
 
 	_vga->update();
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 054769e..6fc2238 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -125,7 +125,7 @@ void Sprite::setShapeList(BitmapPtr *shp, int cnt) {
 			if (p->_w > _siz.x)
 				_siz.x = p->_w;
 			if (p->_h > _siz.y)
-				_siz.y = p->_w;
+				_siz.y = p->_h;
 		}
 		expand();
 		_ext->_shpList = shp;
@@ -497,7 +497,7 @@ void Sprite::show() {
 
 void Sprite::show(uint16 pg) {
 	Graphics::Surface *a = _vm->_vga->_page[1];
-	_vm->_vga->_page[1] = _vm->_vga->_page[pg & 3];
+	_vm->_vga->_page[1] = _vm->_vga->_page[pg];
 	shp()->show(_pos2D.x, _pos2D.y);
 	_vm->_vga->_page[1] = a;
 }
@@ -950,6 +950,10 @@ void Bitmap::xShow(int16 x, int16 y) {
 
 
 void Bitmap::show(int16 x, int16 y) {
+	V2D pos(_vm, x, y);
+	xLatPos(pos);
+	x = pos.x;
+	y = pos.y;
 	const byte *srcP = (const byte *)_v;
 	byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
 


Commit: 6d7becb1daf00938b904dd482ce3a7a72e0d5945
    https://github.com/scummvm/scummvm/commit/6d7becb1daf00938b904dd482ce3a7a72e0d5945
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T12:21:24+02:00

Commit Message:
CGE2: Add newRandom().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 8d7f58f..bd93ed2 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -39,7 +39,7 @@
 namespace CGE2 {
 
 CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
-	: Engine(syst), _gameDescription(gameDescription) {
+	: Engine(syst), _gameDescription(gameDescription), _randomSource("cge") {
 	_resman = nullptr;
 	_vga = nullptr;
 	_sprite = nullptr;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index fa161f3..bbd7090 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -28,6 +28,7 @@
 #ifndef CGE2_H
 #define CGE2_H
 
+#include "common/random.h"
 #include "engines/engine.h"
 #include "engines/advancedDetector.h"
 #include "common/system.h"
@@ -85,6 +86,7 @@ public:
 	void caveUp(int cav);
 	void showBak(int ref);
 	void loadTab();
+	int newRandom(int range);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -98,6 +100,8 @@ public:
 
 	const ADGameDescription *_gameDescription;
 
+	Common::RandomSource _randomSource;
+
 	bool _quitFlag;
 	Dac *_bitmapPalette;
 	int _mode;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9ee9459..6d59cc8 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -413,4 +413,11 @@ void CGE2Engine::setEye(const char *s) {
 	_eye->_z = atoi(token(NULL));
 }
 
+int CGE2Engine::newRandom(int range) {
+	if (!range)
+		return 0;
+
+	return _randomSource.getRandomNumber(range - 1);
+}
+
 } // End of namespace CGE2


Commit: 365bad47aec09be62da92cd6dae228ebcc896bf8
    https://github.com/scummvm/scummvm/commit/365bad47aec09be62da92cd6dae228ebcc896bf8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T12:23:27+02:00

Commit Message:
CGE2: Move showTitle() from cge2.cpp to cge2_main.cpp.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index bd93ed2..158ac7c 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -131,34 +131,4 @@ Common::Error CGE2Engine::run() {
 	return Common::kNoError;
 }
 
-bool CGE2Engine::showTitle(const char *name) {
-	if (_quitFlag)
-		return false;
-
-	_bitmapPalette = _vga->_sysPal;
-	BitmapPtr *LB = new BitmapPtr[2];
-	LB[0] = new Bitmap(this, name);
-	LB[1] = NULL;
-	_bitmapPalette = NULL;
-
-	Sprite D(this, LB, 1);
-	D._flags._kill = true;
-	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
-	D.gotoxyz(kScrWidth >> 1, -(kPanHeight >> 1));
-	_vga->sunset();
-	
-	D.show(2);
-
-	_vga->copyPage(1, 2);
-	_vga->copyPage(0, 1);
-	
-	_vga->sunrise(_vga->_sysPal);
-
-	_vga->update();
-	
-	warning("STUB: CGE2Engine::showTitle()");
-
-	return true;
-}
-
 } // End of namespace CGE2
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 6d59cc8..9647eeb 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -420,4 +420,34 @@ int CGE2Engine::newRandom(int range) {
 	return _randomSource.getRandomNumber(range - 1);
 }
 
+bool CGE2Engine::showTitle(const char *name) {
+	if (_quitFlag)
+		return false;
+
+	_bitmapPalette = _vga->_sysPal;
+	BitmapPtr *LB = new BitmapPtr[2];
+	LB[0] = new Bitmap(this, name);
+	LB[1] = NULL;
+	_bitmapPalette = NULL;
+
+	Sprite D(this, LB, 1);
+	D._flags._kill = true;
+	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
+	D.gotoxyz(kScrWidth >> 1, -(kPanHeight >> 1));
+	_vga->sunset();
+
+	D.show(2);
+
+	_vga->copyPage(1, 2);
+	_vga->copyPage(0, 1);
+
+	_vga->sunrise(_vga->_sysPal);
+
+	_vga->update();
+
+	warning("STUB: CGE2Engine::showTitle()");
+
+	return true;
+}
+
 } // End of namespace CGE2


Commit: dc370d49949ceae0b8aa519ee5a73c00ccac2d34
    https://github.com/scummvm/scummvm/commit/dc370d49949ceae0b8aa519ee5a73c00ccac2d34
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T14:56:26+02:00

Commit Message:
CGE2: Partially implement Sprite::expand().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 6fc2238..08a5a6b 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -205,143 +205,85 @@ Sprite *Sprite::expand() {
 	if (_ext)
 		return this;
 
+	if (notify != nullptr)
+		notify();
+
 	_ext = new SprExt(_vm);
 	assert(_ext != NULL);
+
 	if (!*_file)
 		return this;
 
-	static const char *Comd[] = { "Name", "Phase", "Seq", "Near", "Take", NULL };
 	char fname[kPathMax];
 
 	Common::Array<BitmapPtr> shplist;
-	for (int i = 0; i < _shpCnt + 1; ++i)
+	for (int i = 0; i < _shpCnt; ++i)
 		shplist.push_back(NULL);
 
-	Seq *seq = NULL;
-	int shapeCount = 0,
-		seqCount = 0,
-		nearCount = 0,
-		takeCount = 0,
+	int cnt[kActions],
+		shpcnt = 0,
+		seqcnt = 0,
 		maxnow = 0,
 		maxnxt = 0;
 
-	warning("STUB: Sprite::expand()");
-
-	//CommandHandler::Command *nearList = NULL;
-	//CommandHandler::Command *takeList = NULL;
-	//_vm->mergeExt(fname, _file, kSprExt);
-	//if (_vm->_resman->exist(fname)) { // sprite description file exist
-	//	EncryptedStream sprf(_vm, fname);
-	//	if (sprf.err())
-	//		error("Bad SPR [%s]", fname);
-	//	Common::String line;
-	//	char tmpStr[kLineMax + 1];
-	//	int lcnt = 0;
-
-	//	for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
-	//		int len = line.size();
-	//		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-	//		lcnt++;
-	//		if (len == 0 || *tmpStr == '.')
-	//			continue;
-
-	//		CommandHandler::Command *c;
-	//		switch (_vm->takeEnum(Comd, strtok(tmpStr, " =\t"))) {
-	//		case 0:
-	//			// Name
-	//			setName(strtok(NULL, ""));
-	//			break;
-	//		case 1:
-	//			// Phase
-	//			// In case the shape index gets too high, increase the array size
-	//			while ((shapeCount + 1) >= (int)shplist.size()) {
-	//				shplist.push_back(NULL);
-	//				++_shpCnt;
-	//			}
-	//			shplist[shapeCount++] = new Bitmap(_vm, strtok(NULL, " \t,;/"));
-	//			break;
-	//		case 2:
-	//			// Seq
-	//			seq = (Seq *)realloc(seq, (seqCount + 1) * sizeof(*seq));
-	//			assert(seq != NULL);
-	//			Seq *s;
-	//			s = &seq[seqCount++];
-	//			s->_now = atoi(strtok(NULL, " \t,;/"));
-	//			if (s->_now > maxnow)
-	//				maxnow = s->_now;
-	//			s->_next = atoi(strtok(NULL, " \t,;/"));
-	//			switch (s->_next) {
-	//			case 0xFF:
-	//				s->_next = seqCount;
-	//				break;
-	//			case 0xFE:
-	//				s->_next = seqCount - 1;
-	//				break;
-	//			}
-	//			if (s->_next > maxnxt)
-	//				maxnxt = s->_next;
-	//			s->_dx = atoi(strtok(NULL, " \t,;/"));
-	//			s->_dy = atoi(strtok(NULL, " \t,;/"));
-	//			s->_dly = atoi(strtok(NULL, " \t,;/"));
-	//			break;
-	//		case 3:
-	//			// Near
-	//			if (_nearPtr == kNoPtr)
-	//				break;
-	//			nearList = (CommandHandler::Command *)realloc(nearList, (nearCount + 1) * sizeof(*nearList));
-	//			assert(nearList != NULL);
-	//			c = &nearList[nearCount++];
-	//			if ((c->_commandType = (CommandType)_vm->takeEnum(CommandHandler::_commandText, strtok(NULL, " \t,;/"))) < 0)
-	//				error("Bad NEAR in %d [%s]", lcnt, fname);
-	//			c->_ref = atoi(strtok(NULL, " \t,;/"));
-	//			c->_val = atoi(strtok(NULL, " \t,;/"));
-	//			c->_spritePtr = NULL;
-	//			break;
-	//		case 4:
-	//			// Take
-	//			if (_takePtr == kNoPtr)
-	//				break;
-	//			takeList = (CommandHandler::Command *)realloc(takeList, (takeCount + 1) * sizeof(*takeList));
-	//			assert(takeList != NULL);
-	//			c = &takeList[takeCount++];
-	//			if ((c->_commandType = (CommandType)_vm->takeEnum(CommandHandler::_commandText, strtok(NULL, " \t,;/"))) < 0)
-	//				error("Bad NEAR in %d [%s]", lcnt, fname);
-	//			c->_ref = atoi(strtok(NULL, " \t,;/"));
-	//			c->_val = atoi(strtok(NULL, " \t,;/"));
-	//			c->_spritePtr = NULL;
-	//			break;
-	//		}
-	//	}
-	//} else {
-	//	// no sprite description: try to read immediately from .BMP
-	//	shplist[shapeCount++] = new Bitmap(_vm, _file);
-	//}
+	Seq *seq;
+	if (_seqCnt) {
+		seq = new Seq[_seqCnt];
+		if (seq == NULL)
+			error("No core %s", fname);
+	} else
+		seq = nullptr;
+
+	for (int i = 0; i < kActions; i++)
+		cnt[i] = 0;
+
+	for (int i = 0; i < kActions; i++){
+		byte n = _actionCtrl[i]._cnt;
+		if (n) {
+			_ext->_actions[i] = new CommandHandler::Command[n];
+			if (_ext->_actions[i] == nullptr)
+				error("No core %s", fname);
+		} else
+			_ext->_actions[i] = nullptr;
+	}
+
+	int section = kIdPhase;
 
-	//shplist[shapeCount] = NULL;
-	//if (seq) {
-	//	if (maxnow >= shapeCount)
-	//		error("Bad PHASE in SEQ [%s]", fname);
-	//	if (maxnxt >= seqCount)
-	//		error("Bad JUMP in SEQ [%s]", fname);
-	//	setSeq(seq);
-	//} else
-	//	setSeq(getConstantSeq(_shpCnt == 1));
-
-	//// Set the shape list
-	//BitmapPtr *shapeList = new BitmapPtr[shplist.size()];
-	//for (uint i = 0; i < shplist.size(); ++i)
-	//	shapeList[i] = shplist[i];
-
-	//setShapeList(shapeList);
-
-	//if (nearList)
-	//	nearList[nearCount - 1]._spritePtr = _ext->_near = nearList;
-	//else
-	//	_nearPtr = kNoPtr;
-	//if (takeList)
-	//	takeList[takeCount - 1]._spritePtr = _ext->_take = takeList;
-	//else
-	//	_takePtr = kNoPtr;
+	_vm->mergeExt(fname, _file, kSprExt);
+	if (_vm->_resman->exist(fname)) { // sprite description file exist
+
+		warning("STUB: Sprite::expand()");
+
+	} else // no sprite description: try to read immediately from .BMP
+		shplist[shpcnt++] = new Bitmap (_vm, _file);
+
+	if (seq) {
+		if (maxnow >= shpcnt)
+			error("Bad PHASE in SEQ %s", fname);
+		if (maxnxt && maxnxt >= seqcnt)
+			error("Bad JUMP in SEQ %s", fname);
+		setSeq(seq);
+	} else {
+		setSeq(_stdSeq8);
+		_seqCnt = (shpcnt < ARRAYSIZE(_stdSeq8)) ? shpcnt : ARRAYSIZE(_stdSeq8);
+	}
+
+	// Set the shape list
+	BitmapPtr *shapeList = new BitmapPtr[shplist.size()];
+	for (uint i = 0; i < shplist.size(); ++i)
+		shapeList[i] = shplist[i];
+
+	setShapeList(shapeList, shpcnt);
+
+	if (_file[2] == '~') { // FLY-type sprite
+		Seq *seq = _ext->_seq;
+		int x = (seq + 1)->_dx, y = (seq + 1)->_dy, z = (seq + 1)->_dz;
+		// random position
+		seq->_dx = _vm->newRandom(x + x) - x;
+		seq->_dy = _vm->newRandom(y + y) - y;
+		seq->_dz = _vm->newRandom(z + z) - z;
+		gotoxyz(_pos3D + V3D(seq->_dx, seq->_dy, seq->_dz));
+	}
 
 	return this;
 }


Commit: 45714a12f1b522f302fc06ec5c8fd1412a05e3f4
    https://github.com/scummvm/scummvm/commit/45714a12f1b522f302fc06ec5c8fd1412a05e3f4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-15T15:03:59+02:00

Commit Message:
CGE2: Implement showBak().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9647eeb..941f2b8 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -343,14 +343,11 @@ void CGE2Engine::showBak(int ref) {
 	Sprite *spr = _spare->locate(ref);
 	if (spr != nullptr) {
 		_bitmapPalette = _vga->_sysPal;
-		warning("Check again this ^ !");
 		spr->expand();
 		_bitmapPalette = NULL;
-		//spr->show(2);
+		spr->show(2);
 		_vga->copyPage(1, 2);
 		_spare->dispose(spr);
-
-		warning("STUB: CGE2Engine::showBak()");
 	}
 }
 


Commit: b3cdf9ca3883072d33ca59e1e274eacc57fae4c1
    https://github.com/scummvm/scummvm/commit/b3cdf9ca3883072d33ca59e1e274eacc57fae4c1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-16T01:04:01+02:00

Commit Message:
CGE2: Implement loadTab().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 941f2b8..ce84b23 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -356,12 +356,39 @@ void CGE2Engine::runGame() {
 }
 
 void CGE2Engine::loadTab() {
-	char *n = _text->getText(240);
 	setEye(_text->getText(240));
 	for (int i = 0; i < kCaveMax; i++)
 		_eyeTab[i] == _eye;
 
-	warning("STUB: CGE2Engine::loadTab()");
+	if (_resman->exist(kTabName)) {
+		EncryptedStream f(this, kTabName);
+		Common::File output;
+		for (int i = 0; i < kCaveMax; i++) {
+			for (int j = 0; j < 3; j++) {
+				signed b = f.readSigned();
+				unsigned a = f.readUnsigned();
+				uint16 round = uint16((long(a) << 16) / 100);
+				
+				if (round > 0x7FFF)
+					b++;
+			
+				switch (j) {
+				case 0:
+					_eyeTab[i]->_x = b;
+					break;
+				case 1:
+					_eyeTab[i]->_y = b;
+					break;
+				case 2:
+					_eyeTab[i]->_z = b;
+					break;
+				}
+				
+			}
+		}
+	}
+
+	warning("STUB: CGE2Engine::loadTab() - Recheck this");
 }
 
 void CGE2Engine::cge2_main() {
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index a9e9563..5885871 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -216,6 +216,14 @@ uint32 EncryptedStream::read(byte *dataPtr, uint32 dataSize) {
 	return _readStream->read(dataPtr, dataSize);
 }
 
+unsigned EncryptedStream::readUnsigned() {
+	return _readStream->readUint16BE();
+}
+
+signed EncryptedStream::readSigned() {
+	return _readStream->readSint16BE();
+}
+
 bool EncryptedStream::err() {
 	return (_error & _readStream->err());
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 3150022..a35b014 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -121,6 +121,8 @@ public:
 	int32 pos();
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
+	unsigned readUnsigned();
+	signed readSigned();
 	Common::String readLine();
 	int getLineCount() { return _lineCount; }
 


Commit: cb72489106881afb9a9f509d8bad4345ad2f78a6
    https://github.com/scummvm/scummvm/commit/cb72489106881afb9a9f509d8bad4345ad2f78a6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-17T22:18:57+02:00

Commit Message:
CGE2: Fix deinit().

Changed paths:
    engines/cge2/cge2.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 158ac7c..907ef9a 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -90,9 +90,13 @@ void CGE2Engine::deinit() {
 	delete _text;
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
-	delete _eye;
-	for (int i = 0; i < kCaveMax; i++)
+	for (int i = 0; i < kCaveMax; i++) {
+		if (_eye == _eyeTab[i])
+			_eye = nullptr;
 		delete _eyeTab[i];
+	}
+	if (_eye != nullptr)
+		delete _eye;
 	delete _spare;
 	delete _commandHandler;
 }


Commit: f121349503bdd3076574d11465d7b7acf3d93142
    https://github.com/scummvm/scummvm/commit/f121349503bdd3076574d11465d7b7acf3d93142
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-17T22:34:31+02:00

Commit Message:
CGE2: Further implement caveUp(), add stubbed loadMap().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 907ef9a..7bb861d 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -62,6 +62,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_startupMode = 1;
 	_now = 1;
 	_sex = true;
+	_mouseTop = kWorldHeight / 3;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index bbd7090..7e92664 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -51,6 +51,7 @@ class CommandHandler;
 
 #define kScrWidth      320
 #define kScrHeight     240
+#define kScrDepth      480
 #define kPanHeight     40
 #define kWorldHeight   (kScrHeight - kPanHeight)
 #define kMaxFile       128
@@ -87,6 +88,7 @@ public:
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
+	void loadMap(int cav);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -109,6 +111,7 @@ public:
 	int _startupMode;
 	int _now;
 	bool _sex;
+	int _mouseTop;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ce84b23..9a84220 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -335,6 +335,11 @@ void CGE2Engine::caveUp(int cav) {
 	if (_music)
 		_midiPlayer->loadMidi(bakRef);
 	showBak(bakRef);
+	_eye = _eyeTab[_now];
+	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
+	loadTab();
+
+	_vga->update();
 
 	warning("STUB: CGE2Engine::caveUp()");
 }
@@ -351,6 +356,10 @@ void CGE2Engine::showBak(int ref) {
 	}
 }
 
+void CGE2Engine::loadMap(int cav) {
+	warning("STUB:  CGE2Engine::loadMap()");
+}
+
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }


Commit: bb4679672c721dc58ec81eee1a22ae2727b1a4fc
    https://github.com/scummvm/scummvm/commit/bb4679672c721dc58ec81eee1a22ae2727b1a4fc
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-17T23:14:19+02:00

Commit Message:
CGE2: Revise Queue.

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 08a5a6b..a52b8e6 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -314,12 +314,7 @@ Sprite *Sprite::contract() {
 }
 
 Sprite *Sprite::backShow(bool fast) {
-	expand();
-	show(2);
-	show(1);
-	if (fast)
-		show(0);
-	contract();
+	warning("STUB: Sprite::backShow()");
 	return this;
 }
 
@@ -525,7 +520,7 @@ void Sprite::sync(Common::Serializer &s) {
 	s.syncAsUint16LE(unused);	// _next
 }
 
-Queue::Queue(bool show) : _head(NULL), _tail(NULL), _show(show) {
+Queue::Queue(bool show) : _head(NULL), _tail(NULL) {
 }
 
 Queue::~Queue() {
@@ -541,52 +536,51 @@ void Queue::clear() {
 }
 
 void Queue::append(Sprite *spr) {
-	if (_tail) {
-		spr->_prev = _tail;
-		_tail->_next = spr;
-	} else
-		_head = spr;
-	_tail = spr;
-	if (_show)
+	if (spr->_flags._back)
+		spr->backShow();
+	else {
 		spr->expand();
-	else
-		spr->contract();
+		if (_tail) {
+			spr->_prev = _tail;
+			_tail->_next = spr;
+		} else
+			_head = spr;
+
+		_tail = spr;
+	}
 }
 
 void Queue::insert(Sprite *spr, Sprite *nxt) {
-	if (nxt == _head) {
-		spr->_next = _head;
-		_head = spr;
-		if (!_tail)
-			_tail = spr;
-	} else {
-		assert(nxt);
-		spr->_next = nxt;
-		spr->_prev = nxt->_prev;
-		if (spr->_prev)
-			spr->_prev->_next = spr;
-	}
-	if (spr->_next)
-		spr->_next->_prev = spr;
-	if (_show)
+	if (spr->_flags._back)
+		spr->backShow();
+	else {
 		spr->expand();
-	else
-		spr->contract();
+		if (nxt == _head) {
+			spr->_next = _head;
+			_head = spr;
+			if (!_tail)
+				_tail = spr;
+		} else {
+			spr->_next = nxt;
+			spr->_prev = nxt->_prev;
+			if (spr->_prev)
+				spr->_prev->_next = spr;
+		}
+		if (spr->_next)
+			spr->_next->_prev = spr;
+	}
 }
 
 void Queue::insert(Sprite *spr) {
 	Sprite *s;
 	for (s = _head; s; s = s->_next)
-		if (s->_pos3D._z > spr->_pos3D._z)
+		if (s->_pos3D._z < spr->_pos3D._z)
 			break;
+
 	if (s)
 		insert(spr, s);
 	else
 		append(spr);
-	if (_show)
-		spr->expand();
-	else
-		spr->contract();
 }
 
 template<typename T>
@@ -616,6 +610,14 @@ Sprite *Queue::locate(int ref) {
 	return NULL;
 }
 
+bool Queue::locate(Sprite *spr) {
+	Sprite *s;
+	for (s = _head; s; s = s->_next)
+		if (s == spr)
+			return true;
+	return false;
+}
+
 Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _mono(0), _vm(vm) {
 	_oldColors = NULL;
 	_newColors = NULL;
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index f8c7bf4..e517a75 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -168,8 +168,6 @@ public:
 	Queue(bool show);
 	~Queue();
 
-	bool _show;
-
 	void append(Sprite *spr);
 	void insert(Sprite *spr, Sprite *nxt);
 	void insert(Sprite *spr);
@@ -181,6 +179,7 @@ public:
 		return _tail;
 	}
 	Sprite *locate(int ref);
+	bool locate(Sprite *spr);
 	void clear();
 };
 


Commit: 997564d1f64559276b496b34be87ab947b0e1f1c
    https://github.com/scummvm/scummvm/commit/997564d1f64559276b496b34be87ab947b0e1f1c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-17T23:20:21+02:00

Commit Message:
CGE2: Reimplement backShow().

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index a52b8e6..fc5f9b4 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -313,9 +313,11 @@ Sprite *Sprite::contract() {
 	return this;
 }
 
-Sprite *Sprite::backShow(bool fast) {
-	warning("STUB: Sprite::backShow()");
-	return this;
+void Sprite::backShow(void) {
+	expand();
+	show(2);
+	show(1);
+	_vm->_spare->dispose(this);
 }
 
 void Sprite::step(int nr) {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index e517a75..894f7b7 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -35,6 +35,7 @@
 #include "cge2/bitmap.h"
 #include "cge2/snail.h"
 #include "cge2/cge2.h"
+#include "cge2/spare.h"
 
 namespace CGE2 {
 
@@ -132,7 +133,7 @@ public:
 	int LabVal(Action snq, int lab);
 	Sprite *expand();
 	Sprite *contract();
-	Sprite *backShow(bool fast = false);
+	void backShow(void);
 	void setName(char *newName);
 	inline char *name() {
 		return (_ext) ? _ext->_name : NULL;


Commit: e0d871530622c0618c9ef350fa63d6039b223f0e
    https://github.com/scummvm/scummvm/commit/e0d871530622c0618c9ef350fa63d6039b223f0e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-17T23:33:46+02:00

Commit Message:
CGE2: Further implement caveUp(), implement openPocket().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 7e92664..bb49d0a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -89,6 +89,7 @@ public:
 	void loadTab();
 	int newRandom(int range);
 	void loadMap(int cav);
+	void openPocket();
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9a84220..07873c6 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -338,6 +338,9 @@ void CGE2Engine::caveUp(int cav) {
 	_eye = _eyeTab[_now];
 	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
 	loadTab();
+	_spare->takeCave(bakRef);
+	openPocket();
+	
 
 	_vga->update();
 
@@ -360,6 +363,15 @@ void CGE2Engine::loadMap(int cav) {
 	warning("STUB:  CGE2Engine::loadMap()");
 }
 
+void CGE2Engine::openPocket() {
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax + 1; j++) {
+			int ref = (_heroTab[i])->_pocket[j]->_ref;
+			_heroTab[i]->_pocket[j] = (ref == -1) ? nullptr : _vga->_showQ->locate(ref);
+		}
+	}
+}
+
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }


Commit: 28357ab6cb4cf432baa7e5c26af76e79c6c7abde
    https://github.com/scummvm/scummvm/commit/28357ab6cb4cf432baa7e5c26af76e79c6c7abde
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-18T10:57:26+02:00

Commit Message:
CGE2: Remove unnecessary call of loadTab(), add TODO to caveUp().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 07873c6..d2188d7 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -337,14 +337,17 @@ void CGE2Engine::caveUp(int cav) {
 	showBak(bakRef);
 	_eye = _eyeTab[_now];
 	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
-	loadTab();
 	_spare->takeCave(bakRef);
 	openPocket();
 	
+	warning("STUB: CGE2Engine::caveUp()");
+	// TODO: Implement "Hero" things here!
+
+
 
 	_vga->update();
 
-	warning("STUB: CGE2Engine::caveUp()");
+	
 }
 
 void CGE2Engine::showBak(int ref) {


Commit: 3e97ade38842b29e01692c00c452c30afe4ea67f
    https://github.com/scummvm/scummvm/commit/3e97ade38842b29e01692c00c452c30afe4ea67f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-18T11:04:30+02:00

Commit Message:
CGE2: Revise takeCave().

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 451cf21..aff61b3 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -48,10 +48,10 @@ Sprite *Spare::locate(int ref) {
 	return nullptr;
 }
 
-void Spare::takeCave(int cav) {
-	int ref = cav << 8;
+void Spare::takeCave(int ref) {
 	Sprite *spr = locate(ref);
-	_vm->_vga->_showQ->insert(spr);
+	if (spr != nullptr)
+		_vm->_vga->_showQ->insert(spr);
 }
 
 void Spare::store(Sprite *spr) {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index e1689c3..54683b9 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -40,7 +40,7 @@ public:
 	~Spare() { clear(); }
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
-	void takeCave(int cav);
+	void takeCave(int ref); // Note that it takes the ref of the sprite now, not the number of the scene, like the original!
 	void dispose(Sprite *spr);
 	void dispose(int ref);
 	void dispose();


Commit: 938a2e66c214b9db4de563061639c74265e70fdb
    https://github.com/scummvm/scummvm/commit/938a2e66c214b9db4de563061639c74265e70fdb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-18T11:37:06+02:00

Commit Message:
CGE2: Implement Spare::dispose(), add Spare::update().

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index aff61b3..4c66e96 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -58,16 +58,24 @@ void Spare::store(Sprite *spr) {
 	_container.insert_at(_container.size(), spr);
 }
 
-void Spare::dispose(Sprite *spr) {
-	warning("STUB: Spare::Dispose()");
+void Spare::update(Sprite *spr) {
+	Sprite *sp = locate(spr->_ref);
+	if (sp == nullptr)
+		store(spr);
+}
 
+void Spare::dispose(Sprite *spr) {
 	if (spr) {
 		_vm->_vga->_showQ->remove(spr);
-
-		for (int i = 0; i < _container.size(); i++) {
-			if (spr == _container[i]) {
-				_container.remove_at(i);
+		update(spr->contract());
+		if (spr->_ref / 10 != 14) { // IIRC if it's == 14, it's the sprite of a Hero. No idea yet why it shouldn't be deleted then.
+			for (int i = 0; i < _container.size(); i++) {
+				if (spr == _container[i]) {
+					_container.remove_at(i);
+				}
 			}
+
+			delete spr;
 		}
 	}
 }
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 54683b9..6e8f8c5 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -41,6 +41,7 @@ public:
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
 	void takeCave(int ref); // Note that it takes the ref of the sprite now, not the number of the scene, like the original!
+	void update(Sprite *spr);
 	void dispose(Sprite *spr);
 	void dispose(int ref);
 	void dispose();


Commit: 412d30ca33adce079ed8ce0768f7662f5b055dc3
    https://github.com/scummvm/scummvm/commit/412d30ca33adce079ed8ce0768f7662f5b055dc3
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-18T14:01:25+02:00

Commit Message:
CGE2: Add release() to BitMap.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 39483b0..4bde584 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -111,10 +111,12 @@ Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(N
 }
 
 Bitmap::~Bitmap() {
+	release();
+}
+
+void Bitmap::release() {
 	free(_m);
 	delete[] _v;
-
-	warning("Bitmap: Don't forget to review the whole implemenation!");
 }
 
 Bitmap &Bitmap::operator=(const Bitmap &bmp) {
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index ea7146f..7f46790 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -73,6 +73,7 @@ public:
 
 	Bitmap *code();
 	Bitmap &operator=(const Bitmap &bmp);
+	void release();
 	void hide(int16 x, int16 y);
 	void show(int16 x, int16 y);
 	void xShow(int16 x, int16 y);


Commit: 47e55f16646403a1dea870231e4f294c0858b9a7
    https://github.com/scummvm/scummvm/commit/47e55f16646403a1dea870231e4f294c0858b9a7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-18T14:15:13+02:00

Commit Message:
CGE2: Initialize _actions[] in SprExt's constructor.

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index fc5f9b4..51a8c10 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -72,6 +72,14 @@ Seq Sprite::_stdSeq8[] =
   { 7, 7, 0, 0, 0, 0 },
 };
 
+SprExt::SprExt(CGE2Engine *vm)
+	: _p0(vm, 0, 0), _p1(vm, 0, 0),
+     _b0(NULL), _b1(NULL), _shpList(NULL),
+	 _location(0), _seq(NULL), _name(NULL) {
+	for (int i = 0; i < kActions; i++)
+		_actions[i] = nullptr;
+}
+
 Sprite::Sprite(CGE2Engine *vm)
 	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
       _next(NULL), _prev(NULL), _time(0),
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 894f7b7..8f73f42 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -71,10 +71,7 @@ public:
 	Seq *_seq;
 	char *_name;
 	CommandHandler::Command *_actions[kActions];
-	SprExt(CGE2Engine *vm) : _p0(vm, 0, 0), _p1(vm, 0, 0),
-		_b0(NULL), _b1(NULL),_shpList(NULL), _location(0),
-		_seq(NULL), _name(NULL)
-	{}
+	SprExt(CGE2Engine *vm);
 };
 
 class Sprite {


Commit: 122db4053023ab18ef957585fa31361a0dec8922
    https://github.com/scummvm/scummvm/commit/122db4053023ab18ef957585fa31361a0dec8922
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-18T14:18:45+02:00

Commit Message:
CGE2: Implement Sprite::contract():

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 51a8c10..57c84e0 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -297,26 +297,41 @@ Sprite *Sprite::expand() {
 }
 
 Sprite *Sprite::contract() {
-	//SprExt *e = _ext;
-	//if (!e)
-	//	return this;
-
-	//if (e->_name)
-	//	delete[] e->_name;
-	//if (_flags._bDel && e->_shpList) {
-	//	for (int i = 0; e->_shpList[i]; i++)
-	//		delete e->_shpList[i];
-	//	delete[] e->_shpList;
-	//}
+	SprExt *e = _ext;
+	if (!e)
+		return this;
 
-	//free(e->_seq);
-	//free(e->_near);
-	//free(e->_take);
+	if (_file[2] == '~') { // FLY-type sprite
+		Seq *seq = _ext->_seq;
+		// return to middle
+		gotoxyz(_pos3D - V3D(seq->_dx, seq->_dy, seq->_dz));
+		seq->_dx = seq->_dy = seq->_dz = 0;
+	}
 
-	//delete e;
-	//_ext = NULL;
+	if (notify)
+		notify();
 
-	warning("STUB: Sprite::contract()");
+	if (e->_name)
+		delete[] e->_name;
+
+	if (e->_shpList) {
+		for (int i = 0; i < _shpCnt; i++)
+			e->_shpList[i]->release();
+		delete[] e->_shpList;
+	}
+
+	if (e->_seq) {
+		if (e->_seq == _stdSeq8)
+			_seqCnt = 0;
+		else
+			delete[] e->_seq;
+	}
+
+	for (int i = 0; i < kActions; i++)
+		if (e->_actions[i])
+			delete[] e->_actions[i];
+
+	_ext = nullptr;
 
 	return this;
 }
@@ -379,7 +394,7 @@ void Sprite::gotoxyz(V2D pos) {
 		rem = (rem * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
 		ctr = (ctr * 3) / 4;
 		rem = (rem * 3) / 4;
- 	}
+	}
 
 	if (pos.x - ctr < 0) {
 		pos.x = ctr;


Commit: 5d2f7cd3fd6b33fa9465817682fb8380dc25587d
    https://github.com/scummvm/scummvm/commit/5d2f7cd3fd6b33fa9465817682fb8380dc25587d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T16:08:24+02:00

Commit Message:
CGE2: Stub openPocket() for now.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d2188d7..e9674c1 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -367,12 +367,7 @@ void CGE2Engine::loadMap(int cav) {
 }
 
 void CGE2Engine::openPocket() {
-	for (int i = 0; i < 2; i++) {
-		for (int j = 0; j < kPocketMax + 1; j++) {
-			int ref = (_heroTab[i])->_pocket[j]->_ref;
-			_heroTab[i]->_pocket[j] = (ref == -1) ? nullptr : _vga->_showQ->locate(ref);
-		}
-	}
+	warning("STUB: CGE2Engine::openPocket()");
 }
 
 void CGE2Engine::runGame() {


Commit: 6bcbe5e8baca1b5607308039d42f20e9a7d03632
    https://github.com/scummvm/scummvm/commit/6bcbe5e8baca1b5607308039d42f20e9a7d03632
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T16:16:24+02:00

Commit Message:
CGE2: Further implement caveUp(), add stub for selectPocket().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index bb49d0a..4b505cb 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -90,6 +90,7 @@ public:
 	int newRandom(int range);
 	void loadMap(int cav);
 	void openPocket();
+	void selectPocket(int n);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e9674c1..1ce8ea4 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -343,6 +343,10 @@ void CGE2Engine::caveUp(int cav) {
 	warning("STUB: CGE2Engine::caveUp()");
 	// TODO: Implement "Hero" things here!
 
+	_sound->stop();
+	_fx->clear();
+
+	selectPocket(-1);
 
 
 	_vga->update();
@@ -370,6 +374,10 @@ void CGE2Engine::openPocket() {
 	warning("STUB: CGE2Engine::openPocket()");
 }
 
+void CGE2Engine::selectPocket(int n) {
+	warning("STUB: CGE2Engine::selectPocket()");
+}
+
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }


Commit: 57b9a31ac2b027dc4ddf41ad05c85bae808d4537
    https://github.com/scummvm/scummvm/commit/57b9a31ac2b027dc4ddf41ad05c85bae808d4537
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T16:32:53+02:00

Commit Message:
CGE2: Add stubbed Font and Talk.

All to further implement caveUp().

Changed paths:
  A engines/cge2/talk.cpp
  A engines/cge2/talk.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/module.mk
    engines/cge2/text.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 7bb861d..54d3ee4 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -54,6 +54,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_eyeTab[i] = nullptr;
 	_spare = nullptr;
 	_commandHandler = nullptr;
+	_infoLine = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -79,6 +80,7 @@ void CGE2Engine::init() {
 		_eyeTab[i] = new V3D();
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
+	_infoLine = new InfoLine(this, kInfoW);
 }
 
 void CGE2Engine::deinit() {
@@ -100,6 +102,7 @@ void CGE2Engine::deinit() {
 		delete _eye;
 	delete _spare;
 	delete _commandHandler;
+	delete _infoLine;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 4b505cb..59eef76 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -48,6 +48,7 @@ class V2D;
 class Dac;
 class Spare;
 class CommandHandler;
+class InfoLine;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -65,6 +66,20 @@ enum CallbackType {
 	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
 };
 
+class Font {
+	char _path[kPathMax];
+	void load();
+	CGE2Engine *_vm;
+public:
+	uint8  *_widthArr;
+	uint16 *_pos;
+	uint8  *_map;
+	Font(CGE2Engine *vm, const char *name);
+	~Font();
+	uint16 width(const char *text);
+	void save();
+};
+
 class CGE2Engine : public Engine {
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
@@ -127,6 +142,7 @@ public:
 	V3D *_eyeTab[kCaveMax];
 	Spare *_spare;
 	CommandHandler *_commandHandler;
+	InfoLine *_infoLine;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 1ce8ea4..2a979a0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -347,6 +347,7 @@ void CGE2Engine::caveUp(int cav) {
 	_fx->clear();
 
 	selectPocket(-1);
+	_infoLine->setText(nullptr);
 
 
 	_vga->update();
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index ee622dc..9e9dca0 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -34,6 +34,7 @@ namespace CGE2 {
 #define kIntroExt      ".I80"
 #define kNoByte            -1
 #define kTabName    "CGE.TAB"
+#define kInfoW            140
 
 } // End of namespace CGE2
 
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 60b7db5..4347dba 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -11,7 +11,8 @@ MODULE_OBJS = \
 	text.o \
 	hero.o \
 	snail.o \
-	spare.o
+	spare.o \
+	talk.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
new file mode 100644
index 0000000..2913327
--- /dev/null
+++ b/engines/cge2/talk.cpp
@@ -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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/general.h"
+#include "cge2/talk.h"
+//#include "cge2/game.h"
+//#include "cge2/events.h"
+#include "cge2/cge2_main.h"
+
+namespace CGE2 {
+
+Font::Font(CGE2Engine *vm, const char *name) : _vm(vm) {
+	warning("STUB: Font::Font()");
+}
+
+Font::~Font() {
+	warning("STUB: Font::~Font()");
+}
+
+void Font::load() {
+	warning("STUB: Font::load()");
+}
+
+uint16 Font::width(const char *text) {
+	warning("STUB: Font::width()");
+	return 0;
+}
+
+Talk::Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, bool wideSpace)
+	: Sprite(vm), _mode(mode), _wideSpace(wideSpace), _vm(vm) {
+	warning("STUB: Talk::Talk()");
+}
+
+Talk::Talk(CGE2Engine *vm)
+	: Sprite(vm), _mode(kTBPure), _vm(vm) {
+	warning("STUB: Talk::Talk()");
+}
+
+void Talk::update(const char *text) {
+	warning("STUB: Talk::update()");
+}
+
+Bitmap *Talk::box(uint16 w, uint16 h) {
+	warning("STUB: Talk::box()");
+	return *_ts;
+}
+
+InfoLine::InfoLine(CGE2Engine *vm, uint16 w) : Talk(vm), _oldText(NULL), _vm(vm) {
+	warning("STUB: InfoLine::InfoLine()");
+}
+
+void InfoLine::update(const char *text) {
+	warning("STUB: InfoLine::update()");
+}
+
+void InfoLine::update() {
+	warning("STUB: InfoLine::update()");
+}
+
+void InfoLine::setText(const char *txt) {
+	warning("STUB: InfoLine::setText()");
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
new file mode 100644
index 0000000..2d4c235
--- /dev/null
+++ b/engines/cge2/talk.h
@@ -0,0 +1,78 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_TALK_H
+#define CGE2_TALK_H
+
+#include "cge2/general.h"
+#include "cge2/vga13h.h"
+
+namespace CGE2 {
+
+#define kTextColFG         kVgaColDark              // foreground color
+#define kTextColBG         kVgaColGray              // background color
+#define kTextHMargin      (6&~1)                    // EVEN horizontal margins!
+#define kTextVMargin       5                        // vertical margins
+#define kTextLineSpace     2                        // line spacing
+#define kTextRoundCorner   3                        // rounded corners
+#define kWidSize           256
+#define kPosSize           256
+#define kMapSize          (256*8)
+#define kFontHigh          8
+#define kFontExt           ".CFT"
+
+enum TextBoxStyle { kTBPure, kTBRect, kTBRound };
+
+class Talk : public Sprite {
+protected:
+	TextBoxStyle _mode;
+	BitmapPtr *_ts;
+	Bitmap *box(uint16 w, uint16 h);
+	bool _wideSpace;
+public:
+	Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, bool wideSpace = false);
+	Talk(CGE2Engine *vm);
+
+	virtual void update(const char *text);
+private:
+	CGE2Engine *_vm;
+};
+
+class InfoLine : public Talk {
+	const char *_oldText;
+public:
+	InfoLine(CGE2Engine *vm, uint16 wid);
+	void update(const char *text);
+	void update();
+	void setText(const char *txt);
+private:
+	CGE2Engine *_vm;
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_TALK_H
diff --git a/engines/cge2/text.h b/engines/cge2/text.h
index 634a3c8..bca7743 100644
--- a/engines/cge2/text.h
+++ b/engines/cge2/text.h
@@ -28,7 +28,7 @@
 #ifndef CGE2_TEXT_H
 #define CGE2_TEXT_H
 
-//#include "cge/talk.h"
+#include "cge2/talk.h"
 #include "cge2/cge2.h"
 
 namespace CGE2 {


Commit: b5931e205063c71ec82c7d80287b9228b2852cdc
    https://github.com/scummvm/scummvm/commit/b5931e205063c71ec82c7d80287b9228b2852cdc
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T16:38:26+02:00

Commit Message:
CGE2: Further implement caveUp(), add stub for busy().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 59eef76..d5015c2 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -106,6 +106,7 @@ public:
 	void loadMap(int cav);
 	void openPocket();
 	void selectPocket(int n);
+	void busy(bool on);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2a979a0..4a0076d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -348,7 +348,7 @@ void CGE2Engine::caveUp(int cav) {
 
 	selectPocket(-1);
 	_infoLine->setText(nullptr);
-
+	busy(false);
 
 	_vga->update();
 
@@ -379,6 +379,10 @@ void CGE2Engine::selectPocket(int n) {
 	warning("STUB: CGE2Engine::selectPocket()");
 }
 
+void CGE2Engine::busy(bool on) {
+	warning("STUB: CGE2Engine::selectPocket()");
+}
+
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }


Commit: e6229a259608de6bf1c9f81d2e66101addef1339
    https://github.com/scummvm/scummvm/commit/e6229a259608de6bf1c9f81d2e66101addef1339
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T17:10:18+02:00

Commit Message:
CGE2: Add Mouse in events.h to further implement caveUp().

Changed paths:
  A engines/cge2/events.cpp
  A engines/cge2/events.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 54d3ee4..385fe4e 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -35,6 +35,7 @@
 #include "cge2/hero.h"
 #include "cge2/general.h"
 #include "cge2/spare.h"
+#include "cge2/events.h"
 
 namespace CGE2 {
 
@@ -55,6 +56,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_spare = nullptr;
 	_commandHandler = nullptr;
 	_infoLine = nullptr;
+	_mouse = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -64,6 +66,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_now = 1;
 	_sex = true;
 	_mouseTop = kWorldHeight / 3;
+	_dark = false;
 }
 
 void CGE2Engine::init() {
@@ -81,6 +84,7 @@ void CGE2Engine::init() {
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
 	_infoLine = new InfoLine(this, kInfoW);
+	_mouse = new Mouse(this);
 }
 
 void CGE2Engine::deinit() {
@@ -103,6 +107,7 @@ void CGE2Engine::deinit() {
 	delete _spare;
 	delete _commandHandler;
 	delete _infoLine;
+	delete _mouse;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index d5015c2..f3a9a28 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -49,6 +49,7 @@ class Dac;
 class Spare;
 class CommandHandler;
 class InfoLine;
+class Mouse;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -107,6 +108,7 @@ public:
 	void openPocket();
 	void selectPocket(int n);
 	void busy(bool on);
+	void show();
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -130,6 +132,7 @@ public:
 	int _now;
 	bool _sex;
 	int _mouseTop;
+	bool _dark;
 
 	ResourceManager *_resman;
 	Vga *_vga;
@@ -144,6 +147,7 @@ public:
 	Spare *_spare;
 	CommandHandler *_commandHandler;
 	InfoLine *_infoLine;
+	Mouse *_mouse;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 4a0076d..a20dbb6 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -33,6 +33,7 @@
 #include "cge2/snail.h"
 #include "cge2/hero.h"
 #include "cge2/spare.h"
+#include "cge2/events.h"
 
 namespace CGE2 {
 
@@ -350,9 +351,13 @@ void CGE2Engine::caveUp(int cav) {
 	_infoLine->setText(nullptr);
 	busy(false);
 
-	_vga->update();
+	if (!_dark)
+		_vga->sunset();
+	show();
+	_vga->copyPage(1, 0);
+	show();
 
-	
+	_vga->update();
 }
 
 void CGE2Engine::showBak(int ref) {
@@ -383,6 +388,10 @@ void CGE2Engine::busy(bool on) {
 	warning("STUB: CGE2Engine::selectPocket()");
 }
 
+void CGE2Engine::show() {
+	warning("STUB: CGE2Engine::show()");
+}
+
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
new file mode 100644
index 0000000..3675909
--- /dev/null
+++ b/engines/cge2/events.cpp
@@ -0,0 +1,61 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "gui/saveload.h"
+#include "gui/about.h"
+#include "gui/message.h"
+#include "common/config-manager.h"
+#include "common/events.h"
+#include "engines/advancedDetector.h"
+#include "cge2/events.h"
+#include "cge2/text.h"
+#include "cge2/cge2_main.h"
+
+namespace CGE2 {
+/*----------------- MOUSE interface -----------------*/
+
+Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
+	warning("STUB: Mouse::Mouse() - Recheck the whole implementation!!!");
+}
+
+Mouse::~Mouse() {
+	warning("STUB: Mouse::~Mouse()");
+}
+
+void Mouse::on() {
+	warning("STUB: Mouse::on()");
+}
+
+void Mouse::off() {
+	warning("STUB: Mouse::off()");
+}
+
+void Mouse::newMouse(Common::Event &event) {
+	warning("STUB: Mouse::newMouse()");
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/events.h b/engines/cge2/events.h
new file mode 100644
index 0000000..1442d85
--- /dev/null
+++ b/engines/cge2/events.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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_EVENTS_H
+#define CGE2_EVENTS_H
+
+#include "common/events.h"
+#include "cge2/talk.h"
+#include "cge2/vga13h.h"
+
+namespace CGE2 {
+
+/*----------------- MOUSE interface -----------------*/
+
+class Mouse : public Sprite {
+public:
+	Sprite *_hold;
+	bool _active;
+	int _hx;
+	int _hy;
+	bool _exist;
+	int _buttons;
+	Sprite *_busy;
+	Mouse(CGE2Engine *vm);
+	~Mouse();
+	void on();
+	void off();
+	void newMouse(Common::Event &event);
+private:
+	CGE2Engine *_vm;
+};
+
+} // End of namespace CGE
+
+#endif // #define CGE2_EVENTS_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 4347dba..7272ed3 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -12,7 +12,8 @@ MODULE_OBJS = \
 	hero.o \
 	snail.o \
 	spare.o \
-	talk.o
+	talk.o \
+	events.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)


Commit: 63e57b2eb62c7c3fe2a1b4d878da5941648b6603
    https://github.com/scummvm/scummvm/commit/63e57b2eb62c7c3fe2a1b4d878da5941648b6603
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T17:23:50+02:00

Commit Message:
CGE2: Fix formatting in general.h.

Changed paths:
    engines/cge2/general.h



diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 747fb84..bd145e1 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -50,36 +50,36 @@ public:
 	V3D(void) { }
 	V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
 	V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
-	V3D operator + (const V3D& p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
-	V3D operator - (const V3D& p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
-	V3D operator * (long n) const { return V3D(_x * n, _y * n, _z * n); }
-	V3D operator / (long n) const { return V3D(_x / n, _y / n, _z / n); }
-	bool operator == (V3D& p) const { return _x == p._x && _y == p._y && _z == p._z; }
-	bool operator != (V3D& p) const { return _x != p._x || _y != p._y || _z != p._z; }
-	V3D& operator += (const V3D& x) { return *this = *this + x; }
-	V3D& operator -= (const V3D& x) { return *this = *this - x; }
+	V3D operator+(const V3D &p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
+	V3D operator-(const V3D &p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
+	V3D operator*(long n) const { return V3D(_x * n, _y * n, _z * n); }
+	V3D operator/ (long n) const { return V3D(_x / n, _y / n, _z / n); }
+	bool operator==(V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
+	bool operator!=(V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
+	V3D& operator+=(const V3D &x) { return *this = *this + x; }
+	V3D& operator-=(const V3D &x) { return *this = *this - x; }
 };
 
 class V2D : public Common::Point {
 	CGE2Engine *_vm;
 public:
-	V2D& operator = (const V3D& p3) {
+	V2D& operator=(const V3D &p3) {
 		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
 		x = round((_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m));
 		y = round((_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m));
 		return *this;
 	}
 	V2D(CGE2Engine *vm) : _vm(vm) { }
-	V2D(CGE2Engine *vm, const V3D& p3) : _vm(vm) { *this = p3; }
+	V2D(CGE2Engine *vm, const V3D &p3) : _vm(vm) { *this = p3; }
 	V2D(CGE2Engine *vm, int x, int y) : _vm(vm), Common::Point(x, y) { }
-	bool operator <  (const V2D& p) const { return (x <  p.x) && (y <  p.y); }
-	bool operator <= (const V2D& p) const { return (x <= p.x) && (y <= p.y); }
-	bool operator >(const V2D& p) const { return (x >  p.x) && (y >  p.y); }
-	bool operator >= (const V2D& p) const { return (x >= p.x) && (y >= p.y); }
-	V2D operator + (const V2D& p) const { return V2D(_vm, x + p.x, y + p.y); }
-	V2D operator - (const V2D& p) const { return V2D(_vm, x - p.x, y - p.y); }
+	bool operator<(const V2D &p) const { return (x <  p.x) && (y <  p.y); }
+	bool operator<=(const V2D &p) const { return (x <= p.x) && (y <= p.y); }
+	bool operator>(const V2D &p) const { return (x >  p.x) && (y >  p.y); }
+	bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
+	V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
+	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
 	uint16 area(void) { return x * y; }
-	bool limited(const V2D& p) {
+	bool limited(const V2D &p) {
 		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
 	}
 	V2D scale(int z) {


Commit: 06ed289509f7d9d164bddebee0c1ef85b864deef
    https://github.com/scummvm/scummvm/commit/06ed289509f7d9d164bddebee0c1ef85b864deef
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T17:56:19+02:00

Commit Message:
CGE2: Revise Spare::takeCave().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a20dbb6..4ea069a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -208,6 +208,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 
 	if (_sprite) {
 		_sprite->_ref = ref;
+		_sprite->_scene = scene;
 
 		_sprite->_flags._frnt = frnt;
 		_sprite->_flags._east = east;
@@ -338,7 +339,7 @@ void CGE2Engine::caveUp(int cav) {
 	showBak(bakRef);
 	_eye = _eyeTab[_now];
 	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
-	_spare->takeCave(bakRef);
+	_spare->takeCave(_now);
 	openPocket();
 	
 	warning("STUB: CGE2Engine::caveUp()");
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 4c66e96..dbd8425 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -48,10 +48,16 @@ Sprite *Spare::locate(int ref) {
 	return nullptr;
 }
 
-void Spare::takeCave(int ref) {
-	Sprite *spr = locate(ref);
-	if (spr != nullptr)
-		_vm->_vga->_showQ->insert(spr);
+void Spare::takeCave(int cav) {
+	int bakRef = cav << 8;
+	Common::Array<Sprite*> tempCont = _container;
+	for (int i = 0; i < tempCont.size(); i++) {
+		Sprite *spr = tempCont[i];
+		int c = spr->_scene;
+		if ((c == _vm->_now || c == 0) && spr->_ref != bakRef) {
+			_vm->_vga->_showQ->insert(spr);
+		}
+	}
 }
 
 void Spare::store(Sprite *spr) {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 6e8f8c5..7bd520d 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -40,7 +40,7 @@ public:
 	~Spare() { clear(); }
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
-	void takeCave(int ref); // Note that it takes the ref of the sprite now, not the number of the scene, like the original!
+	void takeCave(int cav);
 	void update(Sprite *spr);
 	void dispose(Sprite *spr);
 	void dispose(int ref);


Commit: 36534403e3f49cf8eee8de17d0de9bc36ff6464b
    https://github.com/scummvm/scummvm/commit/36534403e3f49cf8eee8de17d0de9bc36ff6464b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T18:02:30+02:00

Commit Message:
CGE2: Further implement caveUp().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 4ea069a..ed9f37a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -358,7 +358,9 @@ void CGE2Engine::caveUp(int cav) {
 	_vga->copyPage(1, 0);
 	show();
 
-	_vga->update();
+	_sprite = _vga->_showQ->first();
+	if (_startupMode)
+		_vga->sunrise(_vga->_sysPal);
 }
 
 void CGE2Engine::showBak(int ref) {


Commit: bf820481b7077ed3c6dc0599377bbbc4655ff8a7
    https://github.com/scummvm/scummvm/commit/bf820481b7077ed3c6dc0599377bbbc4655ff8a7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-19T23:24:23+02:00

Commit Message:
CGE2: Implement feedSnail().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/snail.cpp
    engines/cge2/snail.h
    engines/cge2/spare.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 385fe4e..fe94e16 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -36,6 +36,7 @@
 #include "cge2/general.h"
 #include "cge2/spare.h"
 #include "cge2/events.h"
+#include "cge2/talk.h"
 
 namespace CGE2 {
 
@@ -55,8 +56,10 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_eyeTab[i] = nullptr;
 	_spare = nullptr;
 	_commandHandler = nullptr;
+	_commandHandlerTurbo = nullptr;
 	_infoLine = nullptr;
 	_mouse = nullptr;
+	_talk = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -83,14 +86,15 @@ void CGE2Engine::init() {
 		_eyeTab[i] = new V3D();
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
+	_commandHandlerTurbo = new CommandHandler(this, true);
 	_infoLine = new InfoLine(this, kInfoW);
 	_mouse = new Mouse(this);
+	_talk = new Talk(this);
 }
 
 void CGE2Engine::deinit() {
 	delete _resman;
 	delete _vga;
-	delete _sprite;
 	delete _fx;
 	delete _sound;
 	delete _midiPlayer;
@@ -105,9 +109,12 @@ void CGE2Engine::deinit() {
 	if (_eye != nullptr)
 		delete _eye;
 	delete _spare;
+	delete _sprite;
 	delete _commandHandler;
+	delete _commandHandlerTurbo;
 	delete _infoLine;
 	delete _mouse;
+	delete _talk;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index f3a9a28..0a275d5 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -50,6 +50,8 @@ class Spare;
 class CommandHandler;
 class InfoLine;
 class Mouse;
+class Talk;
+class Hero;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -67,6 +69,8 @@ enum CallbackType {
 	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
 };
 
+enum Action { kNear, kMTake, kFTake, kActions };
+
 class Font {
 	char _path[kPathMax];
 	void load();
@@ -109,6 +113,11 @@ public:
 	void selectPocket(int n);
 	void busy(bool on);
 	void show();
+	void feedSnail(Sprite *spr, Action snq, Hero *hero);
+	int freePockets(int sx);
+	int findActivePocket(int ref);
+	void pocFul();
+	void killText();
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -146,8 +155,10 @@ public:
 	V3D *_eyeTab[kCaveMax];
 	Spare *_spare;
 	CommandHandler *_commandHandler;
+	CommandHandler *_commandHandlerTurbo;
 	InfoLine *_infoLine;
 	Mouse *_mouse;
+	Talk *_talk;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ed9f37a..591f28a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -361,6 +361,9 @@ void CGE2Engine::caveUp(int cav) {
 	_sprite = _vga->_showQ->first();
 	if (_startupMode)
 		_vga->sunrise(_vga->_sysPal);
+
+	feedSnail(_vga->_showQ->locate(bakRef + 255), kNear, _heroTab[_sex]->_ptr);
+	//setDrawColors();
 }
 
 void CGE2Engine::showBak(int ref) {
@@ -518,4 +521,41 @@ bool CGE2Engine::showTitle(const char *name) {
 	return true;
 }
 
+int CGE2Engine::freePockets(int sx) {
+	int n = 0;
+	for (int i = 0; i < kPocketMax; i++){
+		if (_heroTab[sx]->_pocket[i] == nullptr)
+			++n;
+	}
+	return n;
+}
+
+int CGE2Engine::findActivePocket(int ref) {
+	for (int i = 0; i < kPocketMax; i++) {
+		Sprite *spr = _heroTab[_sex]->_pocket[i];
+		if (ref >= 0) {
+			if (spr && spr->_ref == ref)
+				return i;
+		} else if (!spr)
+			return i;
+	}
+	return -1;
+}
+
+void CGE2Engine::pocFul() {
+	Hero *h = _heroTab[_sex]->_ptr;
+	h->park();
+	_commandHandler->addCommand(kCmdWait, -1, -1, h);
+	_commandHandler->addCommand(kCmdSound, -1, 2, h);
+	_commandHandler->addCommand(kCmdSay, -1, kPocketFull + _sex, h);
+}
+
+void CGE2Engine::killText() {
+	if (!_talk)
+		return;
+
+	_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, _talk);
+	_talk = NULL;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 9e9dca0..432a6a4 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -35,6 +35,7 @@ namespace CGE2 {
 #define kNoByte            -1
 #define kTabName    "CGE.TAB"
 #define kInfoW            140
+#define kPocketFull       170
 
 } // End of namespace CGE2
 
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 52aefe2..c883606 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -27,6 +27,7 @@
 
 #include "cge2/snail.h"
 #include "cge2/fileio.h"
+#include "cge2/hero.h"
 
 namespace CGE2 {
 
@@ -90,4 +91,116 @@ int CommandHandler::com(const char *com) {
 	return (i < 0) ? i : i + kCmdCom0 + 1;
 }
 
+void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
+	if (!spr || !spr->active())
+		return;
+
+	int cnt = spr->_actionCtrl[snq]._cnt;
+	if (cnt) {
+		byte ptr = spr->_actionCtrl[snq]._ptr;
+		CommandHandler::Command *comtab = spr->snList(snq);
+		CommandHandler::Command *c = &comtab[ptr];
+		CommandHandler::Command *p;
+		CommandHandler::Command *q = &comtab[cnt];
+
+		warning("STUB: CGE2Engine::feedSnail()");
+		// Dont bother with pockets (inventory system) for now... TODO: Implement it later!!!
+		/*
+		int pocFre = freePockets(hero->_ref & 1);
+		int pocReq = 0;
+		for (p = c; p < q && p->_commandType != kCmdNext; p++) { // scan commands
+			// drop from pocket?
+			if ((p->_commandType == kCmdSend && p->_val != _now)
+				|| p->_commandType == kCmdGive) {
+				int ref = p->_ref;
+				if (ref < 0)
+					ref = spr->_ref;
+				if (findActivePocket(ref) >= 0)
+					--pocReq;
+			}
+			// make/dispose additional room?
+			if (p->_commandType == kCmdRoom) {
+				if (p->_val == 0)
+					++pocReq;
+				else
+					--pocReq;
+			}
+			// put into pocket?
+			if (p->_commandType == kCmdKeep)
+				++pocReq;
+			// overloaded?
+			if (pocReq > pocFre) {
+				pocFul();
+				return;
+			}
+		}*/
+
+		while (c < q) {
+			if (c->_commandType == kCmdTalk) {
+				if ((_commandHandler->_talkEnable = (c->_val != 0)) == false)
+					killText();
+			}
+			if (c->_commandType == kCmdWalk || c->_commandType == kCmdReach) {
+				if (c->_val == -1)
+					c->_val = spr->_ref;
+			}
+			if (c->_commandType == kCmdNext) {
+				Sprite *s;
+
+				switch (c->_ref) {
+				case -2:
+					s = hero;
+					break;
+				case -1:
+					s = spr;
+					break;
+				default:
+					s = _vga->_showQ->locate(c->_ref);
+					break;
+				}
+
+				if (s) {
+					if (s->_actionCtrl[snq]._cnt) {
+						int v;
+						switch (c->_val) {
+						case -1:
+							v = int(c - comtab + 1);
+							break;
+						case -2:
+							v = int(c - comtab);
+							break;
+						case -3:
+							v = -1;
+							break;
+						default:
+							v = c->_val;
+							if ((v > 255) && s)
+								v = s->labVal(snq, v >> 8);
+							break;
+						}
+						if (v >= 0)
+							s->_actionCtrl[snq]._ptr = v;
+					}
+				}
+				if (s == spr)
+					break;
+			}
+			if (c->_commandType == kCmdIf) {
+				Sprite *s = (c->_ref < 0) ? spr : _vga->_showQ->locate(c->_ref);
+				if (s) { // sprite extsts 
+					if (!s->seqTest(-1)) { // not parked
+						int v = c->_val;
+						if (v > 255) if (s) v = s->labVal(snq, v >> 8);
+						c = comtab + (v - 1);
+					}
+				}
+			} else
+				_commandHandler->addCommand(c->_commandType, c->_ref, c->_val, spr);
+
+			++c;
+		}
+	}
+	
+}
+
 } // End of namespace CGE2.
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index b364aa9..00e0d09 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -33,8 +33,6 @@
 
 namespace CGE2 {
 
-enum Action { kNear, kMTake, kFTake, kActions };
-
 enum CommandType {
 	kCmdCom0 = 128,
 	kCmdNop,     // NOP                       :: do nothing
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index dbd8425..2f7a138 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -34,8 +34,6 @@ void Spare::synchronize() {
 }
 
 void Spare::clear() {
-	for (int i = 0; i < _container.size(); i++)
-		delete _container[i];
 	_container.clear();
 }
 
@@ -78,10 +76,10 @@ void Spare::dispose(Sprite *spr) {
 			for (int i = 0; i < _container.size(); i++) {
 				if (spr == _container[i]) {
 					_container.remove_at(i);
+					delete spr;
+					break;
 				}
 			}
-
-			delete spr;
 		}
 	}
 }
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 57c84e0..d11e71f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -209,6 +209,16 @@ void Sprite::setName(char *newName) {
 	}
 }
 
+int Sprite::labVal(Action snq, int lab) {
+	warning("STUB: Sprite::labVal()");
+	return 0;
+}
+
+CommandHandler::Command *Sprite::snList(Action type) {
+	SprExt *e = _ext;
+	return (e) ? e->_actions[type] : NULL;
+}
+
 Sprite *Sprite::expand() {
 	if (_ext)
 		return this;
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 8f73f42..6750aee 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -127,7 +127,7 @@ public:
 	void setShapeList(BitmapPtr *shp, int cnt);
 	void moveShapesHi(void);
 	void moveShapesLo(void);
-	int LabVal(Action snq, int lab);
+	int labVal(Action snq, int lab);
 	Sprite *expand();
 	Sprite *contract();
 	void backShow(void);


Commit: 8a1b90acaf85166200e84f823471fbc497f9711e
    https://github.com/scummvm/scummvm/commit/8a1b90acaf85166200e84f823471fbc497f9711e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-22T14:01:05+02:00

Commit Message:
CGE2: Fix loadSprite().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 591f28a..3a4ff18 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -99,11 +99,10 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 
 		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
 			int len = line.size();
+			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 			if (len == 0 || *tmpStr == ';')
 				continue;
-			
-			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-			
+					
 			char *p;
 			p = token(tmpStr);
 			if (*p == '@') {


Commit: ba8e801ada1be7dbf7329ca444e20a24f7dca166
    https://github.com/scummvm/scummvm/commit/ba8e801ada1be7dbf7329ca444e20a24f7dca166
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T10:05:02+02:00

Commit Message:
CGE2: Implement Sprite::expand().

Add functions:
*Bitmap::moveHi()
*Bitmap::moveLo()
*CGE2Engine::tail()
and warning comments to various places during the process.
Also add _lab data member to CommandHandler::Command.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/snail.h
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 4bde584..10fd6f1 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -375,4 +375,14 @@ void Bitmap::xLatPos(V2D& p) {
 	p.y = kWorldHeight - p.y - _h;
 }
 
+bool Bitmap::moveHi(void) {
+	warning("STUB: Bitmap::moveHi()");
+	return true;
+}
+
+bool Bitmap::moveLo(void) {
+	warning("STUB: Bitmap::moveLo()");
+	return true;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 7f46790..07f83b8 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -79,6 +79,8 @@ public:
 	void xShow(int16 x, int16 y);
 	bool solidAt(int16 x, int16 y);
 	void xLatPos(V2D& p);
+	bool moveHi(void);
+	bool moveLo(void);
 };
 
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 0a275d5..5e16864 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -125,6 +125,7 @@ public:
 
 	int number(char *s);
 	char *token(char *s);
+	char *tail(char *s);
 	int takeEnum(const char **tab, const char *text);
 	ID ident(const char *s);
 	bool testBool(char *s);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 3a4ff18..f11965c 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -37,7 +37,7 @@
 
 namespace CGE2 {
 
-int CGE2Engine::number(char *s) {
+int CGE2Engine::number(char *s) { // TODO: Rework it later to include the preceding token() call!
 	int r = atoi(s);
 	char *pp = strchr(s, ':');
 	if (pp)
@@ -49,6 +49,12 @@ char *CGE2Engine::token(char *s) {
 	return strtok(s, " =\t,;/()");
 }
 
+char *CGE2Engine::tail(char *s) {
+	if (s && (*s == '='))
+		s++;
+	return s;
+}
+
 int CGE2Engine::takeEnum(const char **tab, const char *text) {
 	if (text) {
 		for (const char **e = tab; *e; e++) {
@@ -222,7 +228,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 			*p = '\0';
 
 		_sprite->_shpCnt = shpcnt;
-		_sprite->_seqPtr = seqcnt;
+		_sprite->_seqCnt = seqcnt;
 
 		for (int i = 0; i < kActions; i++)
 			_sprite->_actionCtrl[i]._cnt = cnt[i];
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 432a6a4..1472e2e 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -32,7 +32,7 @@ namespace CGE2 {
 
 #define kLineMax          512
 #define kIntroExt      ".I80"
-#define kNoByte            -1
+#define kNoByte            -1 // Recheck this! We have no proof for it's original value.
 #define kTabName    "CGE.TAB"
 #define kInfoW            140
 #define kPocketFull       170
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 00e0d09..a2f4bec 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -114,6 +114,7 @@ class CommandHandler {
 public:
 	struct Command {
 		CommandType _commandType;
+		byte _lab;
 		int _ref;
 		int _val;
 		void *_spritePtr;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index d11e71f..992d0c0 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -232,8 +232,6 @@ Sprite *Sprite::expand() {
 	if (!*_file)
 		return this;
 
-	char fname[kPathMax];
-
 	Common::Array<BitmapPtr> shplist;
 	for (int i = 0; i < _shpCnt; ++i)
 		shplist.push_back(NULL);
@@ -244,6 +242,9 @@ Sprite *Sprite::expand() {
 		maxnow = 0,
 		maxnxt = 0;
 
+	char fname[kPathMax];
+	_vm->mergeExt(fname, _file, kSprExt);
+
 	Seq *seq;
 	if (_seqCnt) {
 		seq = new Seq[_seqCnt];
@@ -265,14 +266,114 @@ Sprite *Sprite::expand() {
 			_ext->_actions[i] = nullptr;
 	}
 
-	int section = kIdPhase;
-
-	_vm->mergeExt(fname, _file, kSprExt);
 	if (_vm->_resman->exist(fname)) { // sprite description file exist
+		EncryptedStream sprf(_vm, fname);
+		if (sprf.err())
+			error("Bad SPR [%s]", fname);
+
+		int label = kNoByte;
+		ID section = kIdPhase;
+		ID id;
+		Common::String line;
+		char tmpStr[kLineMax + 1];
+
+		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
+			int len = line.size();
+			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+			if (len == 0 || *tmpStr == ';')
+				continue;
+
+			char *p = _vm->token(tmpStr);
+			if (*p == '@') {
+				label = atoi(p + 1);
+				continue;
+			}
 
-		warning("STUB: Sprite::expand()");
+			id = _vm->ident(p);
+			switch (id) {
+			case kIdType:
+				break;
+			case kIdNear:
+			case kIdMTake:
+			case kIdFTake:
+			case kIdPhase:
+			case kIdSeq:
+				section = id;
+				break;
+			case kIdName:
+				Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+				for (p = tmpStr; *p != '='; p++); // We search for the =
+				setName(_vm->tail(p));
+				break;
+			default:
+				if (id >= kIdNear)
+					break;
+				Seq *s;
+				switch (section) {
+				case kIdNear:
+				case kIdMTake:
+				case kIdFTake:
+					id = (ID)_vm->_commandHandler->com(p);
+					if (_actionCtrl[section]._cnt) {
+						CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
+						c->_commandType = CommandType(id);
+						c->_lab = label;
+						if ((p = _vm->token(nullptr)) == NULL)
+							error("Unexpected end of file! %s", fname);
+						c->_ref = _vm->number(p);
+						if ((p = _vm->token(nullptr)) == NULL)
+							error("Unexpected end of file! %s", fname);
+						c->_val = _vm->number(p);
+						c->_spritePtr = nullptr;
+					}
+					break;
+				case kIdSeq:
+					s = &seq[seqcnt++];
+					s->_now = atoi(p);
+					if (s->_now > maxnow)
+						maxnow = s->_now;
+					if ((p = _vm->token(nullptr)) == NULL)
+						break;
+					s->_next = _vm->number(p);
+					switch (s->_next) {
+					case 0xFF:
+						s->_next = seqcnt;
+						break;
+					case 0xFE:
+						s->_next = seqcnt - 1;
+						break;
+					}
+					if (s->_next > maxnxt)
+						maxnxt = s->_next;
+					if ((p = _vm->token(nullptr)) == NULL)
+						error("Unexpected end of file! %s", fname);
+					s->_dx = _vm->number(p);
+					if ((p = _vm->token(nullptr)) == NULL)
+						error("Unexpected end of file! %s", fname);
+					s->_dy = _vm->number(p);
+					if ((p = _vm->token(nullptr)) == NULL)
+						error("Unexpected end of file! %s", fname);
+					s->_dz = _vm->number(p);
+					if ((p = _vm->token(nullptr)) == NULL)
+						error("Unexpected end of file! %s", fname);
+					s->_dly = _vm->number(p);
+					break;
+				case kIdPhase:
+					BitmapPtr bmp = new Bitmap(_vm, p);
+					shplist[shpcnt] = bmp;
+					if (!shplist[shpcnt]->moveHi())
+						error("No EMS");
+					shpcnt++;
+					break;
+				}
+				break;
+			}
+			label = kNoByte;
+		}
 
-	} else // no sprite description: try to read immediately from .BMP
+		if (!shpcnt)
+			error("No shapes - %s", fname);
+		} else // no sprite description: try to read immediately from .BMP
 		shplist[shpcnt++] = new Bitmap (_vm, _file);
 
 	if (seq) {


Commit: afa15dd74f0a97d373409bb39333b5f25e7f507a
    https://github.com/scummvm/scummvm/commit/afa15dd74f0a97d373409bb39333b5f25e7f507a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T10:12:48+02:00

Commit Message:
CGE2: Add explanation to comment in caveUp().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f11965c..05dcc80 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -368,7 +368,7 @@ void CGE2Engine::caveUp(int cav) {
 		_vga->sunrise(_vga->_sysPal);
 
 	feedSnail(_vga->_showQ->locate(bakRef + 255), kNear, _heroTab[_sex]->_ptr);
-	//setDrawColors();
+	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.
 }
 
 void CGE2Engine::showBak(int ref) {


Commit: e98554309d85578826001d9305b0e4c4df658450
    https://github.com/scummvm/scummvm/commit/e98554309d85578826001d9305b0e4c4df658450
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T10:55:58+02:00

Commit Message:
CGE2: Add mainLoop() and handleFrame().

Also implement connecting things.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index fe94e16..89ec3b0 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -70,6 +70,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_sex = true;
 	_mouseTop = kWorldHeight / 3;
 	_dark = false;
+	_lastFrame = 0;
+	_lastTick = 0;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 5e16864..0c3670f 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -86,6 +86,9 @@ public:
 };
 
 class CGE2Engine : public Engine {
+private:
+	uint32 _lastFrame, _lastTick;
+	void tick();
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
 	virtual bool hasFeature(EngineFeature f) const;
@@ -118,6 +121,8 @@ public:
 	int findActivePocket(int ref);
 	void pocFul();
 	void killText();
+	void mainLoop();
+	void handleFrame();
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 05dcc80..ad1d3a6 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -330,8 +330,15 @@ void CGE2Engine::movie(const char *ext) {
 		loadScript(fn);
 		caveUp(_now);
 
+		while (!_commandHandler->idle() && !_quitFlag)
+			mainLoop();
+
 		warning("STUB: CGE2Engine::movie()");
 
+		_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
+		_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
+		_vga->_showQ->clear();
+		_spare->clear();
 		_now = now;
 	}
 }
@@ -383,8 +390,62 @@ void CGE2Engine::showBak(int ref) {
 	}
 }
 
+void CGE2Engine::mainLoop() {
+	_vga->show();
+	_commandHandlerTurbo->runCommand();
+	_commandHandler->runCommand();
+
+	// Handle a delay between game frames
+	handleFrame();
+
+	// Handle any pending events
+	//_eventManager->poll();
+	warning("STUB: CGE2Engine::mainLoop() - Event handling is missing!");
+
+	// Check shouldQuit()
+	_quitFlag = shouldQuit();
+}
+
+void CGE2Engine::handleFrame() {
+	// Game frame delay
+	uint32 millis = g_system->getMillis();
+	while (!_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) {
+		// Handle any pending events
+		//_eventManager->poll();
+		warning("STUB: CGE2Engine::handleFrame() - Event handling is missing!");
+
+		if (millis >= (_lastTick + kGameTickDelay)) {
+			// Dispatch the tick to any active objects
+			tick();
+			_lastTick = millis;
+		}
+
+		// Slight delay
+		g_system->delayMillis(5);
+		millis = g_system->getMillis();
+	}
+	_lastFrame = millis;
+
+	if (millis >= (_lastTick + kGameTickDelay)) {
+		// Dispatch the tick to any active objects
+		tick();
+		_lastTick = millis;
+	}
+}
+
+void CGE2Engine::tick() {
+	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
+		if (spr->_time) {
+			if (!spr->_flags._hide) {
+				if (--spr->_time == 0)
+					spr->tick();
+			}
+		}
+	}
+}
+
 void CGE2Engine::loadMap(int cav) {
-	warning("STUB:  CGE2Engine::loadMap()");
+	warning("STUB: CGE2Engine::loadMap()");
 }
 
 void CGE2Engine::openPocket() {
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 1472e2e..a0a8bd1 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -31,11 +31,13 @@
 namespace CGE2 {
 
 #define kLineMax          512
-#define kIntroExt      ".I80"
-#define kNoByte            -1 // Recheck this! We have no proof for it's original value.
-#define kTabName    "CGE.TAB"
+#define kIntroExt         ".I80"
+#define kNoByte           -1 // Recheck this! We have no proof for it's original value.
+#define kTabName          "CGE.TAB"
 #define kInfoW            140
 #define kPocketFull       170
+#define kGameFrameDelay   (1000 / 50)
+#define kGameTickDelay    (1000 / 62)
 
 } // End of namespace CGE2
 
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 992d0c0..46515e7 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -458,9 +458,9 @@ void Sprite::step(int nr) {
 	warning("STUB: Sprite::step()");
 }
 
-//void Sprite::tick() {
-//	step();
-//}
+void Sprite::tick() {
+	step();
+}
 
 void Sprite::makeXlat(uint8 *x) {
 	if (!_ext)
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 6750aee..77a2fd3 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -152,7 +152,7 @@ public:
 	Seq *setSeq(Seq *seq);
 	CommandHandler::Command *snList(Action type);
 	//virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
-	//virtual void tick();
+	virtual void tick();
 	void clrHide(void) { if (_ext) _ext->_b0 = NULL; }
 	void sync(Common::Serializer &s);
 


Commit: 7777a48dabefbd03c0ca986056b3ae81322de4c1
    https://github.com/scummvm/scummvm/commit/7777a48dabefbd03c0ca986056b3ae81322de4c1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T11:19:42+02:00

Commit Message:
CGE2: Fix caveUp().

Remove CGE2Engine::show() to do so.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 0c3670f..2ffc212 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -115,7 +115,6 @@ public:
 	void openPocket();
 	void selectPocket(int n);
 	void busy(bool on);
-	void show();
 	void feedSnail(Sprite *spr, Action snq, Hero *hero);
 	int freePockets(int sx);
 	int findActivePocket(int ref);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ad1d3a6..2b3ab44 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -366,9 +366,9 @@ void CGE2Engine::caveUp(int cav) {
 
 	if (!_dark)
 		_vga->sunset();
-	show();
+	_vga->show();
 	_vga->copyPage(1, 0);
-	show();
+	_vga->show();
 
 	_sprite = _vga->_showQ->first();
 	if (_startupMode)
@@ -460,10 +460,6 @@ void CGE2Engine::busy(bool on) {
 	warning("STUB: CGE2Engine::selectPocket()");
 }
 
-void CGE2Engine::show() {
-	warning("STUB: CGE2Engine::show()");
-}
-
 void CGE2Engine::runGame() {
 	warning("STUB: CGE2Engine::runGame()");
 }


Commit: c734aa08b1c564e724c8ec2a60719221bb07cff1
    https://github.com/scummvm/scummvm/commit/c734aa08b1c564e724c8ec2a60719221bb07cff1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T11:22:43+02:00

Commit Message:
CGE2: Implement Sprite::show().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 46515e7..b258ae7 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -565,7 +565,15 @@ void Sprite::center() {
 }
 
 void Sprite::show() {
-	warning("STUB: Sprite::show()");
+	SprExt *e = _ext;
+	if (e) {
+		e->_p0 = e->_p1;
+		e->_b0 = e->_b1;
+		e->_p1 = _pos2D;
+		e->_b1 = shp();
+	}
+	if (!_flags._hide)
+		e->_b1->show(e->_p1.x, e->_p1.y);
 }
 
 void Sprite::show(uint16 pg) {


Commit: 02817a7bd5b5ade5afb51f2ea545238d284b2fd8
    https://github.com/scummvm/scummvm/commit/02817a7bd5b5ade5afb51f2ea545238d284b2fd8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T11:40:56+02:00

Commit Message:
CGE2: Implement Sprite::hide().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index b258ae7..662ea44 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -584,7 +584,9 @@ void Sprite::show(uint16 pg) {
 }
 
 void Sprite::hide() {
-	warning("STUB: Sprite::hide()");
+	SprExt *e = _ext;
+	if (e->_b0)
+		e->_b0->hide(e->_p0.x, e->_p0.y);
 }
 
 BitmapPtr Sprite::ghost() {
@@ -1093,6 +1095,10 @@ void Bitmap::show(int16 x, int16 y) {
 
 
 void Bitmap::hide(int16 x, int16 y) {
+	V2D pos(_vm, x, y);
+	xLatPos(pos);
+	x = pos.x;
+	y = pos.y;
 	for (int yp = y; yp < y + _h; yp++) {
 		const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(x, yp);
 		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x, yp);


Commit: 4dcfe4d7853cc59b0c93f43115dc13d17470386f
    https://github.com/scummvm/scummvm/commit/4dcfe4d7853cc59b0c93f43115dc13d17470386f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T12:56:48+02:00

Commit Message:
CGE2: Start implementation of CommandHandler.

Implement constructor, destructor, addCommand() and add clear() ant _count.

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index c883606..5b61d1f 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -53,12 +53,14 @@ const char *CommandHandler::_commandText[] = {
 	"WALKTO", "REACH", "COVER", "UNCOVER",
 	NULL };
 
-CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo) : _vm(vm) {
-	warning("STUB: CommandHandler::CommandHandler()");
+CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo)
+	: _turbo(turbo), _textDelay(false), _timerExpiry(0), _talkEnable(true),
+      _head(0), _tail(0), _commandList((Command *)malloc(sizeof(Command)* 256)),
+      _count(1), _vm(vm) {
 }
 
 CommandHandler::~CommandHandler() {
-	warning("STUB: CommandHandler::~CommandHandler()");
+	free(_commandList);
 }
 
 void CommandHandler::runCommand() {
@@ -66,7 +68,17 @@ void CommandHandler::runCommand() {
 }
 
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
-	warning("STUB: CommandHandler::addCommand()");
+	if (ref == 2)
+		ref = 142 - _vm->_sex;
+	Command *headCmd = &_commandList[_head++];
+	headCmd->_commandType = com;
+	headCmd->_ref = ref;
+	headCmd->_val = val;
+	headCmd->_spritePtr = ptr;
+	headCmd->_cbType = kNullCB;
+	if (headCmd->_commandType == kCmdClear) {
+		clear();
+	}
 }
 
 void CommandHandler::addCallback(CommandType com, int ref, int val, CallbackType cbType) {
@@ -86,6 +98,12 @@ void CommandHandler::reset() {
 	warning("STUB: CommandHandler::reset()");
 }
 
+void CommandHandler::clear() {
+	_tail = _head;
+	_vm->killText();
+	_timerExpiry = 0;
+}
+
 int CommandHandler::com(const char *com) {
 	int i = _vm->takeEnum(_commandText, com);
 	return (i < 0) ? i : i + kCmdCom0 + 1;
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index a2f4bec..889b16c 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -131,6 +131,7 @@ public:
 	void insertCommand(CommandType com, int ref, int val, void *ptr);
 	bool idle();
 	void reset();
+	void clear();
 	int com(const char *com);
 private:
 	CGE2Engine *_vm;
@@ -139,7 +140,8 @@ private:
 	uint8 _tail;
 	bool _busy;
 	bool _textDelay;
-	uint32 _timerExpiry;
+	uint32 _timerExpiry; // "pause" in the original.
+	int _count;
 };
 
 } // End of namespace CGE2


Commit: e2ca4382d86ac869f8628441924cc7f19a0b7b4e
    https://github.com/scummvm/scummvm/commit/e2ca4382d86ac869f8628441924cc7f19a0b7b4e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T13:06:50+02:00

Commit Message:
CGE2: Implement CommandHandler::idle().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 89ec3b0..2f9cf1a 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -72,6 +72,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_dark = false;
 	_lastFrame = 0;
 	_lastTick = 0;
+	_waitRef = 0;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 2ffc212..f1982f7 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -147,6 +147,7 @@ public:
 	bool _sex;
 	int _mouseTop;
 	bool _dark;
+	int _waitRef;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 5b61d1f..1eafd61 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -90,8 +90,7 @@ void CommandHandler::insertCommand(CommandType com, int ref, int val, void *ptr)
 }
 
 bool CommandHandler::idle() {
-	warning("STUB: CommandHandler::idle()");
-	return false;
+	return (!_vm->_waitRef && _head == _tail);
 }
 
 void CommandHandler::reset() {


Commit: 947f4b860759940dfc6420ca84870b210b1253c5
    https://github.com/scummvm/scummvm/commit/947f4b860759940dfc6420ca84870b210b1253c5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-23T15:23:19+02:00

Commit Message:
CGE2: Partially implement CommandHandler::runCommand().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 2f9cf1a..e15e096 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -60,6 +60,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_infoLine = nullptr;
 	_mouse = nullptr;
 	_talk = nullptr;
+	for (int i = 0; i < kMaxPoint; i++)
+		_point[i] = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -72,7 +74,10 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_dark = false;
 	_lastFrame = 0;
 	_lastTick = 0;
+	_waitSeq = 0;
 	_waitRef = 0;
+	_commandStat = { nullptr, { 0 , 0 } };
+	_taken = false;
 }
 
 void CGE2Engine::init() {
@@ -93,6 +98,8 @@ void CGE2Engine::init() {
 	_infoLine = new InfoLine(this, kInfoW);
 	_mouse = new Mouse(this);
 	_talk = new Talk(this);
+	for (int i = 0; i < kMaxPoint; i++)
+		_point[i] = new V3D();
 }
 
 void CGE2Engine::deinit() {
@@ -118,6 +125,9 @@ void CGE2Engine::deinit() {
 	delete _infoLine;
 	delete _mouse;
 	delete _talk;
+	for (int i = 0; i < kMaxPoint; i++) {
+		delete _point[i];
+	}
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index f1982f7..4e5adde 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -52,6 +52,7 @@ class InfoLine;
 class Mouse;
 class Talk;
 class Hero;
+class Bitmap;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -64,6 +65,7 @@ class Hero;
 #define kWayMax         10
 #define kPocketMax       4
 #define kCaveMax       100
+#define kMaxPoint        4
 
 enum CallbackType {
 	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
@@ -108,6 +110,7 @@ public:
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
 	void caveUp(int cav);
+	void switchCave(int cav);
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
@@ -122,6 +125,7 @@ public:
 	void killText();
 	void mainLoop();
 	void handleFrame();
+	Sprite *locate(int ref);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -134,6 +138,44 @@ public:
 	ID ident(const char *s);
 	bool testBool(char *s);
 
+	void snKill(Sprite *spr);
+	void snHide(Sprite *spr, int val);
+	void snMidi(int val);
+	void snSetDlg(int clr, int set);
+	void snMskDlg(int clr, int set);
+	void snSeq(Sprite *spr, int val);
+	void snRSeq(Sprite *spr, int val);
+	void snSend(Sprite *spr, int val);
+	void snSwap(Sprite *spr, int val);
+	void snCover(Sprite *spr, int val);
+	void snUncover(Sprite *spr, Sprite *spr2);
+	void snFocus(int val);
+	void snKeep(Sprite *spr, int val);
+	void snGive(Sprite *spr, int val);
+	void snGoto(Sprite *spr, int val);
+	void snMove(Sprite *spr, V3D pos);
+	void snSlave(Sprite *spr, int val);
+	void snTrans(Sprite *spr, int val);
+	void snPort(Sprite *spr, int val);
+	void snMouse(int val);
+	void snNNext(Sprite *spr, Action act, int val);
+	void snRNNext(Sprite *spr, int val);
+	void snRMTNext(Sprite *spr, int val);
+	void snRFTNext(Sprite *spr, int val);
+	void snRmNear(Sprite *spr);
+	void snRmMTake(Sprite *spr);
+	void snRmFTake(Sprite *spr);
+	void snFlag(int ref, int val);
+	void snSetRef(Sprite *spr, int val);
+	void snBackPt(Sprite *spr, int val);
+	void snFlash(int val);
+	void snLight(int val);
+	void snWalk(Sprite *spr, int val);
+	void snReach(Sprite *spr, int val);
+	void snSound(Sprite *spr, int val, int cnt);
+	void snRoom(Sprite *spr, int val);
+	void snGhost(Bitmap *bmp);
+
 	const ADGameDescription *_gameDescription;
 
 	Common::RandomSource _randomSource;
@@ -147,7 +189,13 @@ public:
 	bool _sex;
 	int _mouseTop;
 	bool _dark;
+	int _waitSeq;
 	int _waitRef;
+	struct CommandStat {
+		int *_wait;
+		int _ref[2];
+	} _commandStat;
+	bool _taken;
 
 	ResourceManager *_resman;
 	Vga *_vga;
@@ -165,6 +213,7 @@ public:
 	InfoLine *_infoLine;
 	Mouse *_mouse;
 	Talk *_talk;
+	V3D *_point[kMaxPoint];
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2b3ab44..fba0cd0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -378,6 +378,10 @@ void CGE2Engine::caveUp(int cav) {
 	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.
 }
 
+void CGE2Engine::switchCave(int cav) {
+	warning("STUB: CGE2Engine::switchCave()");
+}
+
 void CGE2Engine::showBak(int ref) {
 	Sprite *spr = _spare->locate(ref);
 	if (spr != nullptr) {
@@ -433,6 +437,17 @@ void CGE2Engine::handleFrame() {
 	}
 }
 
+Sprite *CGE2Engine::locate(int ref) {
+	_taken = false;
+	Sprite *spr = _vga->_showQ->locate(ref);
+	if (!spr) {
+		spr = _spare->locate(ref);
+		if (spr)
+			_taken = true;
+	}
+	return spr;
+}
+
 void CGE2Engine::tick() {
 	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
 		if (spr->_time) {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 1eafd61..052188c 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -28,6 +28,7 @@
 #include "cge2/snail.h"
 #include "cge2/fileio.h"
 #include "cge2/hero.h"
+#include "cge2/text.h"
 
 namespace CGE2 {
 
@@ -64,7 +65,408 @@ CommandHandler::~CommandHandler() {
 }
 
 void CommandHandler::runCommand() {
-	warning("STUB: CommandHandler::runCommand()");
+	if (!_turbo && _vm->_commandStat._wait) {
+		if (*(_vm->_commandStat._wait))
+			return;
+		else {
+			++_vm->_commandStat._ref[0];
+			warning("STUB: CommandHandler::runCommand() - Sound code missing!");
+			_vm->_commandStat._wait = nullptr;
+		}
+	}
+
+	uint8 tmpHead = _head;
+	while (_tail != tmpHead) {
+		Command tailCmd = _commandList[_tail];
+
+		if (!_turbo) { // only for the slower one
+			if (_vm->_waitRef)
+				break;
+			if (_timerExpiry) {
+				// Delay in progress
+				if (_timerExpiry > g_system->getMillis())
+					// Delay not yet ended
+					break;
+
+				// Delay is finished
+				_timerExpiry = 0;
+			} else {
+				if (_textDelay) {
+					if (_vm->_talk) {
+						_vm->snKill((Sprite *)_vm->_talk);
+						_vm->_talk = nullptr;
+					}
+					_textDelay = false;
+				}
+			}
+			if (_vm->_talk && tailCmd._commandType != kCmdPause)
+				break;
+		}
+		++_tail;
+		_vm->_taken = false;
+		Sprite *spr;
+		if (tailCmd._commandType > kCmdSpr)
+			spr = (tailCmd._ref < 0) ? ((Sprite *)tailCmd._spritePtr) : _vm->locate(tailCmd._ref);
+
+		switch (tailCmd._commandType) {
+		case kCmdUse:
+			break;
+		case kCmdPause:
+			_timerExpiry = g_system->getMillis() + tailCmd._val * kCommandFrameDelay;
+			if (_vm->_talk)
+				_textDelay = true;
+			break;
+		case kCmdWait:
+			if (spr && spr->active() && (spr->_scene == _vm->_now || spr->_scene == 0)) {
+				_vm->_waitSeq = tailCmd._val;
+				_vm->_waitRef = spr->_ref;
+			}
+			break;
+		case kCmdHide:
+			_vm->snHide(spr, tailCmd._val);
+			break;
+		case kCmdSay:
+			if (spr && spr->active() && _talkEnable) //-- mouth animation
+				warning("STUB: CommandHandler::runCommand() - Mouth animation missing!");
+			break;
+		case kCmdInf:
+			if (_talkEnable)
+				_vm->inf(((tailCmd._val) >= 0) ? _vm->_text->getText(tailCmd._val) : (const char *)tailCmd._spritePtr);
+			break;
+		case kCmdTime:
+			warning("STUB: CommandHandler::runCommand() - Something missing connected to kCmdTime!");
+			break;
+		case kCmdCave:
+			_vm->switchCave(tailCmd._val);
+			break;
+		case kCmdMidi:
+			_vm->snMidi(tailCmd._val);
+			break;
+		case kCmdSetDlg:
+			_vm->snSetDlg(tailCmd._ref, tailCmd._val);
+			break;
+		case kCmdMskDlg:
+			_vm->snMskDlg(tailCmd._ref, tailCmd._val);
+			break;
+		case kCmdKill:
+			_vm->snKill(spr);
+			break;
+		case kCmdSeq:
+			_vm->snSeq(spr, tailCmd._val);
+			break;
+		case kCmdRSeq:
+			_vm->snRSeq(spr, tailCmd._val);
+			break;
+		case kCmdSend:
+			_vm->snSend(spr, tailCmd._val);
+			break;
+		case kCmdSwap:
+			_vm->snSwap(spr, tailCmd._val);
+			break;
+		case kCmdCover:
+			_vm->snCover(spr, tailCmd._val);
+			break;
+		case kCmdUncover:
+			_vm->snUncover(spr, (tailCmd._val >= 0) ? _vm->locate(tailCmd._val) : ((Sprite *)tailCmd._spritePtr));
+			break;
+		case kCmdFocus:
+			_vm->snFocus(tailCmd._val);
+			break;
+		case kCmdKeep:
+			_vm->snKeep(spr, tailCmd._val);
+			break;
+		case kCmdGive:
+			_vm->snGive(spr, tailCmd._val);
+			break;
+		case kCmdSetX:
+			_vm->_point[tailCmd._val]->_x = tailCmd._ref;
+			break;
+		case kCmdSetY:
+			_vm->_point[tailCmd._val]->_y = tailCmd._ref;
+			break;
+		case kCmdSetZ:
+			_vm->_point[tailCmd._val]->_z = tailCmd._ref;
+			break;
+		case kCmdAdd:
+			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) + *(_vm->_point[tailCmd._val]);
+			break;
+		case kCmdSub:
+			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) - *(_vm->_point[tailCmd._val]);
+			break;
+		case kCmdMul:
+			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) * tailCmd._val;
+			break;
+		case kCmdDiv:
+			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) / tailCmd._val;
+			break;
+		case kCmdGetPos:
+			if (spr)
+				*(_vm->_point[tailCmd._val]) = spr->_pos3D;
+			break;
+		case kCmdGoto:
+			_vm->snGoto(spr, tailCmd._val);
+			break;
+		case kCmdMoveX:
+			_vm->snMove(spr, V3D(tailCmd._val, 0, 0));
+			break;
+		case kCmdMoveY:
+			_vm->snMove(spr, V3D(0, tailCmd._val, 0));
+			break;
+		case kCmdMoveZ:
+			_vm->snMove(spr, V3D(0, 0, tailCmd._val));
+			break;
+		case kCmdSlave:
+			_vm->snSlave(spr, tailCmd._val);
+			break;
+		case kCmdTrans:
+			_vm->snTrans(spr, tailCmd._val);
+			break;
+		case kCmdPort:
+			_vm->snPort(spr, tailCmd._val);
+			break;
+		case kCmdNext:
+			break;
+		case kCmdIf:
+			break;
+		case kCmdTalk:
+			break;
+		case kCmdMouse:
+			_vm->snMouse(tailCmd._val != 0);
+			break;
+		case kCmdNNext:
+			_vm->snNNext(spr, kNear, tailCmd._val);
+			break;
+		case kCmdMTNext:
+			_vm->snNNext(spr, kMTake, tailCmd._val);
+			break;
+		case kCmdFTNext:
+			_vm->snNNext(spr, kFTake, tailCmd._val);
+			break;
+		case kCmdRNNext:
+			_vm->snRNNext(spr, tailCmd._val);
+			break;
+		case kCmdRMTNext:
+			_vm->snRMTNext(spr, tailCmd._val);
+			break;
+		case kCmdRFTNext:
+			_vm->snRFTNext(spr, tailCmd._val);
+			break;
+		case kCmdRMNear:
+			_vm->snRmNear(spr);
+			break;
+		case kCmdRMMTake:
+			_vm->snRmMTake(spr);
+			break;
+		case kCmdRMFTake:
+			_vm->snRmFTake(spr);
+			break;
+		case kCmdFlag:
+			_vm->snFlag(tailCmd._ref & 3, tailCmd._val);
+			break;
+		case kCmdSetRef:
+			_vm->snSetRef(spr, tailCmd._val);
+			break;
+		case kCmdBackPt:
+			_vm->snBackPt(spr, tailCmd._val);
+			break;
+		case kCmdFlash:
+			_vm->snFlash(tailCmd._val != 0);
+			break;
+		case kCmdLight:
+			_vm->snLight(tailCmd._val != 0);
+			break;
+		case kCmdCycle:
+			warning("Unhandled command - kCmdCycle");
+			break;
+		case kCmdWalk:
+			_vm->snWalk(spr, tailCmd._val);
+			break;
+		case kCmdReach:
+			_vm->snReach(spr, tailCmd._val);
+			break;
+		case kCmdSound:
+			_vm->snSound(spr, tailCmd._val, _count);
+			_count = 1;
+			break;
+		case kCmdMap:
+			_vm->_heroTab[tailCmd._ref & 1]->_ptr->_ignoreMap = tailCmd._val == 0;
+			break;
+		case kCmdCount:
+			_count = tailCmd._val;
+			break;
+		case kCmdRoom:
+			_vm->snRoom(spr, tailCmd._val);
+			break;
+		case kCmdDim:
+			warning("Unhandled command - kCmdDim");
+			break;
+		case kCmdExec:
+			warning("Unhandled command - kCmdExec");
+			break;
+		case kCmdStep:
+			spr->step();
+			break;
+		case kCmdGhost:
+			_vm->snGhost((Bitmap *)tailCmd._spritePtr);
+			break;
+		default:
+			warning("Unhandled command");
+			break;
+		}
+
+		if (_vm->_taken)
+			_vm->_spare->dispose(spr);
+
+		if (!_turbo)
+			break;
+	}
+}
+
+void CGE2Engine::snKill(Sprite *spr) {
+	warning("STUB: CGE2Engine::snKill()");
+}
+
+void CGE2Engine::snHide(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snHide()");
+}
+
+void CGE2Engine::snMidi(int val) {
+	warning("STUB: CGE2Engine::snMidi()");
+}
+
+void CGE2Engine::snSetDlg(int clr, int set) {
+	warning("STUB: CGE2Engine::snSetDlg()");
+}
+
+void CGE2Engine::snMskDlg(int clr, int set) {
+	warning("STUB: CGE2Engine::snMskDlg()");
+}
+
+void CGE2Engine::snSeq(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snSeq()");
+}
+
+void CGE2Engine::snRSeq(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snRSeq()");
+}
+
+void CGE2Engine::snSend(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snSend()");
+}
+
+void CGE2Engine::snSwap(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snSwap()");
+}
+void CGE2Engine::snCover(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snCover()");
+}
+
+void CGE2Engine::snUncover(Sprite *spr, Sprite *spr2) {
+	warning("STUB: CGE2Engine::snUncover()");
+}
+
+void CGE2Engine::snFocus(int val) {
+	warning("STUB: CGE2Engine::snFocus()");
+}
+
+void CGE2Engine::snKeep(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snKeep()");
+}
+
+void CGE2Engine::snGive(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snGive()");
+}
+
+void CGE2Engine::snGoto(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snGoto()");
+}
+
+void CGE2Engine::snMove(Sprite *spr, V3D pos) {
+	warning("STUB: CGE2Engine::snMove()");
+}
+
+void CGE2Engine::snSlave(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snSlave()");
+}
+
+void CGE2Engine::snTrans(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snTrans()");
+}
+
+void CGE2Engine::snPort(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snPort()");
+}
+
+void CGE2Engine::snMouse(int val) {
+	warning("STUB: CGE2Engine::snMouse()");
+}
+
+void CGE2Engine::snNNext(Sprite *spr, Action act, int val) {
+	warning("STUB: CGE2Engine::snNNext()");
+}
+
+void CGE2Engine::snRNNext(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snRNNext()");
+}
+
+void CGE2Engine::snRMTNext(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snRMTNext()");
+}
+
+void CGE2Engine::snRFTNext(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snRFTNext()");
+}
+
+void CGE2Engine::snRmNear(Sprite *spr) {
+	warning("STUB: CGE2Engine::snRmNear()");
+}
+
+void CGE2Engine::snRmMTake(Sprite *spr) {
+	warning("STUB: CGE2Engine::snRmMTake()");
+}
+
+void CGE2Engine::snRmFTake(Sprite *spr) {
+	warning("STUB: CGE2Engine::snRmFTake()");
+}
+
+void CGE2Engine::snFlag(int ref, int val) {
+	warning("STUB: CGE2Engine::snFlag()");
+}
+
+void CGE2Engine::snSetRef(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snSetRef()");
+}
+
+void CGE2Engine::snBackPt(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snBackPt()");
+}
+
+void CGE2Engine::snFlash(int val) {
+	warning("STUB: CGE2Engine::snFlash()");
+}
+
+void CGE2Engine::snLight(int val) {
+	warning("STUB: CGE2Engine::snLight()");
+}
+
+void CGE2Engine::snWalk(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snWalk()");
+}
+
+void CGE2Engine::snReach(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snReach()");
+}
+
+void CGE2Engine::snSound(Sprite *spr, int val, int cnt) {
+	warning("STUB: CGE2Engine::snSound()");
+}
+
+void CGE2Engine::snRoom(Sprite *spr, int val) {
+	warning("STUB: CGE2Engine::snRoom()");
+}
+
+void CGE2Engine::snGhost(Bitmap *bmp) {
+	warning("STUB: CGE2Engine::snGhost()");
 }
 
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 889b16c..e3c2315 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -33,6 +33,9 @@
 
 namespace CGE2 {
 
+#define kCommandFrameRate  80
+#define kCommandFrameDelay (1000 / kCommandFrameRate)
+
 enum CommandType {
 	kCmdCom0 = 128,
 	kCmdNop,     // NOP                       :: do nothing


Commit: eb800807849989fc44f85ec2113520e868c4f7a8
    https://github.com/scummvm/scummvm/commit/eb800807849989fc44f85ec2113520e868c4f7a8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-24T00:11:43+02:00

Commit Message:
CGE2: Some refactoring and fixing regarding runCommand().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index e15e096..ef46461 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -97,7 +97,6 @@ void CGE2Engine::init() {
 	_commandHandlerTurbo = new CommandHandler(this, true);
 	_infoLine = new InfoLine(this, kInfoW);
 	_mouse = new Mouse(this);
-	_talk = new Talk(this);
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = new V3D();
 }
@@ -124,7 +123,8 @@ void CGE2Engine::deinit() {
 	delete _commandHandlerTurbo;
 	delete _infoLine;
 	delete _mouse;
-	delete _talk;
+	if (_talk != nullptr)
+		delete _talk;
 	for (int i = 0; i < kMaxPoint; i++) {
 		delete _point[i];
 	}
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 052188c..ad643ac 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -90,15 +90,14 @@ void CommandHandler::runCommand() {
 
 				// Delay is finished
 				_timerExpiry = 0;
-			} else {
-				if (_textDelay) {
-					if (_vm->_talk) {
-						_vm->snKill((Sprite *)_vm->_talk);
-						_vm->_talk = nullptr;
-					}
-					_textDelay = false;
+			} else if (_textDelay) {
+				if (_vm->_talk) {
+					_vm->snKill((Sprite *)_vm->_talk);
+					_vm->_talk = nullptr;
 				}
+				_textDelay = false;
 			}
+			
 			if (_vm->_talk && tailCmd._commandType != kCmdPause)
 				break;
 		}


Commit: 0566d095bbb6bc02d24b90bb3e7ac3b1bf42561b
    https://github.com/scummvm/scummvm/commit/0566d095bbb6bc02d24b90bb3e7ac3b1bf42561b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-24T08:57:55+02:00

Commit Message:
CGE2: Partially implement Sprite::step().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 662ea44..14bf97b 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -455,7 +455,35 @@ void Sprite::backShow(void) {
 }
 
 void Sprite::step(int nr) {
-	warning("STUB: Sprite::step()");
+	if (nr >= 0)
+		_seqPtr = nr;
+
+	if (_ext) {
+		V3D p = _pos3D;
+		Seq *seq;
+
+		if (nr < 0)
+			_seqPtr = _ext->_seq[_seqPtr]._next;
+
+		if (_file[2] == '~') { // FLY-type sprite
+			warning("STUB: Sprite::step() - FLY-type sprite");
+		} else {
+			seq = _ext->_seq + _seqPtr;
+			if (seq->_dz == 127 && seq->_dx != 0) {
+				_vm->_commandHandlerTurbo->addCommand(kCmdSound, -1, 256 * seq->_dy + seq->_dx, this);
+			} else {
+				p._x += seq->_dx;
+				p._y += seq->_dy;
+				p._z += seq->_dz;
+				//if (!_flags._kept)
+				//	gotoxyz(p);
+				warning("Sprite::step()");
+			}
+		}
+		if (seq->_dly >= 0)
+			_time = seq->_dly;
+	} else if (_vm->_waitRef && _vm->_waitRef == _ref)
+		_vm->_waitRef = 0;
 }
 
 void Sprite::tick() {


Commit: 9c8c734a3c6c5e1af9436a08cde39fe5474e42ac
    https://github.com/scummvm/scummvm/commit/9c8c734a3c6c5e1af9436a08cde39fe5474e42ac
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-24T08:59:06+02:00

Commit Message:
CGE2: Revise CGE2Engine::tick().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index fba0cd0..5dcec22 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -451,12 +451,18 @@ Sprite *CGE2Engine::locate(int ref) {
 void CGE2Engine::tick() {
 	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
 		if (spr->_time) {
-			if (!spr->_flags._hide) {
-				if (--spr->_time == 0)
-					spr->tick();
-			}
+			if (--spr->_time == 0)
+				spr->tick();
+		}
+		if (_waitRef) {
+			if (_waitRef == _sprite->_ref)
+				if (spr->seqTest(_waitSeq))
+					_waitRef = 0;
 		}
 	}
+
+	//Mouse->Tick();
+	warning("STUB: CGE2Engine::tick() - Mouse");
 }
 
 void CGE2Engine::loadMap(int cav) {


Commit: b82a0fa3e5f36e8b0b47ff129ad18fe93bdac225
    https://github.com/scummvm/scummvm/commit/b82a0fa3e5f36e8b0b47ff129ad18fe93bdac225
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-24T09:04:41+02:00

Commit Message:
CGE2: Add isHero().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 4e5adde..8e45ba3 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -126,6 +126,7 @@ public:
 	void mainLoop();
 	void handleFrame();
 	Sprite *locate(int ref);
+	bool isHero(Sprite *spr);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 5dcec22..cf4b4fd 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -448,6 +448,10 @@ Sprite *CGE2Engine::locate(int ref) {
 	return spr;
 }
 
+bool CGE2Engine::isHero(Sprite *spr) {
+	return spr && spr->_ref / 10 == 14;
+}
+
 void CGE2Engine::tick() {
 	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
 		if (spr->_time) {
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 2f7a138..650af7b 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -72,7 +72,7 @@ void Spare::dispose(Sprite *spr) {
 	if (spr) {
 		_vm->_vga->_showQ->remove(spr);
 		update(spr->contract());
-		if (spr->_ref / 10 != 14) { // IIRC if it's == 14, it's the sprite of a Hero. No idea yet why it shouldn't be deleted then.
+		if (!_vm->isHero(spr)) {
 			for (int i = 0; i < _container.size(); i++) {
 				if (spr == _container[i]) {
 					_container.remove_at(i);


Commit: 4cf5c28fee6d71277a7ca2bea5663aa12e387a68
    https://github.com/scummvm/scummvm/commit/4cf5c28fee6d71277a7ca2bea5663aa12e387a68
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-24T09:06:22+02:00

Commit Message:
CGE2: Implement snRSeq() and snSeq().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index ad643ac..edbc78c 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -342,11 +342,17 @@ void CGE2Engine::snMskDlg(int clr, int set) {
 }
 
 void CGE2Engine::snSeq(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snSeq()");
+	if (spr) {
+		if (isHero(spr) && val == 0)
+			((Hero*)spr)->park();
+		else
+			spr->step(val);
+	}
 }
 
 void CGE2Engine::snRSeq(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snRSeq()");
+	if (spr)
+		snSeq(spr, spr->_seqPtr + val);
 }
 
 void CGE2Engine::snSend(Sprite *spr, int val) {


Commit: 3c86aa288b532ddf9370fdcf33f144b43ffab5cc
    https://github.com/scummvm/scummvm/commit/3c86aa288b532ddf9370fdcf33f144b43ffab5cc
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-24T10:47:07+02:00

Commit Message:
CGE2: Implement snSound().

Rework the whole Fx class during the process.
The intro animation is working now.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp
    engines/cge2/sound.cpp
    engines/cge2/sound.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 8e45ba3..d40d417 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -173,7 +173,7 @@ public:
 	void snLight(int val);
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
-	void snSound(Sprite *spr, int val, int cnt);
+	void snSound(Sprite *spr, int wav);
 	void snRoom(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
 
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index edbc78c..3de42dd 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -29,6 +29,7 @@
 #include "cge2/fileio.h"
 #include "cge2/hero.h"
 #include "cge2/text.h"
+#include "cge2/sound.h"
 
 namespace CGE2 {
 
@@ -284,7 +285,7 @@ void CommandHandler::runCommand() {
 			_vm->snReach(spr, tailCmd._val);
 			break;
 		case kCmdSound:
-			_vm->snSound(spr, tailCmd._val, _count);
+			_vm->snSound(spr, tailCmd._val);
 			_count = 1;
 			break;
 		case kCmdMap:
@@ -462,8 +463,21 @@ void CGE2Engine::snReach(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snReach()");
 }
 
-void CGE2Engine::snSound(Sprite *spr, int val, int cnt) {
-	warning("STUB: CGE2Engine::snSound()");
+void CGE2Engine::snSound(Sprite *spr, int wav) {
+	if (wav == -1)
+		_sound->stop();
+	else {
+		if (_sound->_smpinf._counter && wav < 20)
+			return;
+		if (_commandStat._wait && ((wav & 255) > 80))
+			return;
+
+		_commandStat._ref[1] = wav;
+		_commandStat._ref[0] = !_fx->exist(_commandStat._ref[1]);
+		_sound->play(_fx->load(_commandStat._ref[1], _commandStat._ref[0]),
+			(spr) ? (spr->_pos2D.x / (kScrWidth / 16)) : 8);
+	}
+	
 }
 
 void CGE2Engine::snRoom(Sprite *spr, int val) {
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index a3e866f..9f5ec2b 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -61,7 +61,8 @@ void Sound::close() {
 
 void Sound::open() {
 	setRepeat(1);
-	play((*_vm->_fx)[30000], 8);
+	warning("STUB: Sound::open()");
+	play(_vm->_fx->load(99, 99));
 }
 
 void Sound::setRepeat(int16 count) {
@@ -111,60 +112,37 @@ void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
 }
 
 Fx::Fx(CGE2Engine *vm, int size) : _current(NULL), _vm(vm) {
-	_cache = new Handler[size];
-	for (_size = 0; _size < size; _size++) {
-		_cache[_size]._ref = 0;
-		_cache[_size]._wav = NULL;
-	}
 }
 
 Fx::~Fx() {
 	clear();
-	delete[] _cache;
 }
 
 void Fx::clear() {
-	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
-		if (p->_ref) {
-			p->_ref = 0;
-			delete p->_wav;
-			p->_wav = NULL;
-		}
-	}
+	if (_current)
+		delete _current;
 	_current = NULL;
 }
 
-int Fx::find(int ref) {
-	int i = 0;
-	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
-		if (p->_ref == ref)
-			break;
-		else
-			++i;
-	}
-	return i;
+Common::String Fx::name(int ref, int sub) {
+	char name[] = "%.2dfx%.2d.WAV\0";
+	char subn[] = "%.2dfx%.2d?.WAV\0";
+	char *p = (sub) ? subn : name;
+	Common::String filename = Common::String::format(p, ref >> 8, ref & 0xFF);
+	if (sub)
+		filename.setChar('@' + sub, 6);
+	return filename;
 }
 
-void Fx::name(int ref, int sub) {
-	warning("STUB:  Fx::name()");
+bool Fx::exist(int ref, int sub) {
+	return _vm->_resman->exist(name(ref, sub).c_str());
 }
 
-DataCk *Fx::load(int idx, int ref) {
-	char filename[12];
-	warning("TODO: Implement Fx::load() with the use of Fx::name() properly in paralell with Snail! It just won't work this way.");
-	sprintf(filename, "FX%05d.WAV", ref);
-
-	EncryptedStream file(_vm, filename);
-	DataCk *wav = loadWave(&file);
-	if (wav) {
-		Handler *p = &_cache[idx];
-		delete p->_wav;
-		p->_wav = wav;
-		p->_ref = ref;
-	} else {
-		warning("Unable to load %s", filename);
-	}
-	return wav;
+DataCk *Fx::load(int ref, int sub) {
+	Common::String filename = name(ref, sub);
+	EncryptedStream file(_vm, filename.c_str());
+	clear();
+	return (_current = loadWave(&file));
 }
 
 DataCk *Fx::loadWave(EncryptedStream *file) {
@@ -178,20 +156,6 @@ DataCk *Fx::loadWave(EncryptedStream *file) {
 	return new DataCk(data, file->size());
 }
 
-DataCk *Fx::operator[](int ref) {
-	int i;
-	if ((i = find(ref)) < _size)
-		_current = _cache[i]._wav;
-	else {
-		if ((i = find(0)) >= _size) {
-			clear();
-			i = 0;
-		}
-		_current = load(i, ref);
-	}
-	return _current;
-}
-
 MusicPlayer::MusicPlayer(CGE2Engine *vm) : _vm(vm) {
 	_data = NULL;
 	_isGM = false;
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
index c488c3f..6fa2b2a 100644
--- a/engines/cge2/sound.h
+++ b/engines/cge2/sound.h
@@ -72,7 +72,7 @@ public:
 	~Sound();
 	void open();
 	void close();
-	void play(DataCk *wav, int pan);
+	void play(DataCk *wav, int pan = 8);
 	int16 getRepeat();
 	void setRepeat(int16 count);
 	void stop();
@@ -88,23 +88,18 @@ private:
 
 class Fx {
 	CGE2Engine *_vm;
-	struct Handler {
-		int _ref;
-		DataCk *_wav;
-	} *_cache;
 	int _size;
 
-	DataCk *load(int idx, int ref);
 	DataCk *loadWave(EncryptedStream *file);
-	int find(int ref);
+	Common::String name(int ref, int sub);
 public:
 	DataCk *_current;
 
 	Fx(CGE2Engine *vm, int size);
 	~Fx();
 	void clear();
-	void name(int ref, int sub);
-	DataCk *operator[](int ref);
+	bool exist(int ref, int sub = 0);
+	DataCk *load(int ref, int sub = 0);
 };
 
 class MusicPlayer: public Audio::MidiPlayer {


Commit: 0986347b9366cd27b5c41fa878a702beae781e6a
    https://github.com/scummvm/scummvm/commit/0986347b9366cd27b5c41fa878a702beae781e6a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-25T15:59:49+02:00

Commit Message:
CGE2: Adjust the delay times to DOSBox's output.

Changed paths:
    engines/cge2/cge2_main.h



diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index a0a8bd1..9696697 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -36,8 +36,8 @@ namespace CGE2 {
 #define kTabName          "CGE.TAB"
 #define kInfoW            140
 #define kPocketFull       170
-#define kGameFrameDelay   (1000 / 50)
-#define kGameTickDelay    (1000 / 62)
+#define kGameFrameDelay   (750 / 50)
+#define kGameTickDelay    (750 / 62)
 
 } // End of namespace CGE2
 


Commit: 921385b30c53eed03143e25509a28e079cbdc34d
    https://github.com/scummvm/scummvm/commit/921385b30c53eed03143e25509a28e079cbdc34d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T09:23:31+02:00

Commit Message:
CGE2: Add stub for keyboard handling.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/events.cpp
    engines/cge2/events.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index ef46461..7c4d1f1 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -59,6 +59,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_commandHandlerTurbo = nullptr;
 	_infoLine = nullptr;
 	_mouse = nullptr;
+	_keyboard = nullptr;
 	_talk = nullptr;
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = nullptr;
@@ -97,6 +98,7 @@ void CGE2Engine::init() {
 	_commandHandlerTurbo = new CommandHandler(this, true);
 	_infoLine = new InfoLine(this, kInfoW);
 	_mouse = new Mouse(this);
+	_keyboard = new Keyboard(this);
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = new V3D();
 }
@@ -123,6 +125,7 @@ void CGE2Engine::deinit() {
 	delete _commandHandlerTurbo;
 	delete _infoLine;
 	delete _mouse;
+	delete _keyboard;
 	if (_talk != nullptr)
 		delete _talk;
 	for (int i = 0; i < kMaxPoint; i++) {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index d40d417..d067e40 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -50,6 +50,7 @@ class Spare;
 class CommandHandler;
 class InfoLine;
 class Mouse;
+class Keyboard;
 class Talk;
 class Hero;
 class Bitmap;
@@ -213,6 +214,7 @@ public:
 	CommandHandler *_commandHandlerTurbo;
 	InfoLine *_infoLine;
 	Mouse *_mouse;
+	Keyboard *_keyboard;
 	Talk *_talk;
 	V3D *_point[kMaxPoint];
 private:
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 3675909..670ea61 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -36,6 +36,30 @@
 #include "cge2/cge2_main.h"
 
 namespace CGE2 {
+
+/*----------------- KEYBOARD interface -----------------*/
+
+Keyboard::Keyboard(CGE2Engine *vm) : _client(NULL), _vm(vm) {
+	warning("STUB: Keyboard::Keyboard() - Recheck the whole implementation!!!");
+}
+
+Keyboard::~Keyboard() {
+}
+
+Sprite *Keyboard::setClient(Sprite *spr) {
+	warning("STUB: Keyboard::setClient()");
+	return spr;
+}
+
+bool Keyboard::getKey(Common::Event &event) {
+	warning("STUB: Keyboard::getKey()");
+	return false;
+}
+
+void Keyboard::newKeyboard(Common::Event &event) {
+	warning("STUB: Keyboard::newKeyboard()");
+}
+
 /*----------------- MOUSE interface -----------------*/
 
 Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
diff --git a/engines/cge2/events.h b/engines/cge2/events.h
index 1442d85..99f017b 100644
--- a/engines/cge2/events.h
+++ b/engines/cge2/events.h
@@ -34,6 +34,35 @@
 
 namespace CGE2 {
 
+/*----------------- KEYBOARD interface -----------------*/
+
+#define kEventMax   256
+
+enum EventMask {
+	kMouseRoll = 1 << 0,
+	kMouseLeftDown = 1 << 1,
+	kMouseLeftUp = 1 << 2,
+	kMouseRightDown = 1 << 3,
+	kMouseRightUp = 1 << 4,
+	kEventAttn = 1 << 5,
+	kEventKeyb = 1 << 7
+};
+
+class Keyboard {
+private:
+	bool getKey(Common::Event &event);
+	CGE2Engine *_vm;
+public:
+	Sprite *_client;
+	bool _keyAlt;
+
+	void newKeyboard(Common::Event &event);
+	Sprite *setClient(Sprite *spr);
+
+	Keyboard(CGE2Engine *vm);
+	~Keyboard();
+};
+
 /*----------------- MOUSE interface -----------------*/
 
 class Mouse : public Sprite {


Commit: 14e3df21ef1a1cc3e3c599605cd84faf353a2e6f
    https://github.com/scummvm/scummvm/commit/14e3df21ef1a1cc3e3c599605cd84faf353a2e6f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T09:37:52+02:00

Commit Message:
CGE2: Add stub for System.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 7c4d1f1..18016ec 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -63,6 +63,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_talk = nullptr;
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = nullptr;
+	_sys = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -101,6 +102,7 @@ void CGE2Engine::init() {
 	_keyboard = new Keyboard(this);
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = new V3D();
+	_sys = new System(this);
 }
 
 void CGE2Engine::deinit() {
@@ -131,6 +133,7 @@ void CGE2Engine::deinit() {
 	for (int i = 0; i < kMaxPoint; i++) {
 		delete _point[i];
 	}
+	delete _sys;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index d067e40..5275fa7 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -54,6 +54,7 @@ class Keyboard;
 class Talk;
 class Hero;
 class Bitmap;
+class System;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -217,6 +218,7 @@ public:
 	Keyboard *_keyboard;
 	Talk *_talk;
 	V3D *_point[kMaxPoint];
+	System *_sys;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index cf4b4fd..501fa59 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -37,6 +37,18 @@
 
 namespace CGE2 {
 
+System::System(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
+	warning("STUB: System::System()");
+}
+
+void System::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
+	warning("STUB: System::touch()");
+}
+
+void System::tick() {
+	warning("STUB: System::tick()");
+}
+
 int CGE2Engine::number(char *s) { // TODO: Rework it later to include the preceding token() call!
 	int r = atoi(s);
 	char *pp = strchr(s, ':');
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 9696697..7146e43 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -39,6 +39,20 @@ namespace CGE2 {
 #define kGameFrameDelay   (750 / 50)
 #define kGameTickDelay    (750 / 62)
 
+class System : public Sprite {
+public:
+	int _funDel;
+	int _blinkCounter;
+	Sprite *_blinkSprite;
+
+	System(CGE2Engine *vm);
+	
+	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
+	void tick();
+private:
+	CGE2Engine *_vm;
+};
+
 } // End of namespace CGE2
 
 #endif // CGE2_MAIN_H


Commit: 54956d8a810e111f42731487743d5c9221dee42a
    https://github.com/scummvm/scummvm/commit/54956d8a810e111f42731487743d5c9221dee42a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T09:57:41+02:00

Commit Message:
CGE2: Move things around to fix broken compilation of cross-includes.

V2D and V3D are moved to vga13h.h

Changed paths:
    engines/cge2/bitmap.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2_main.h
    engines/cge2/general.h
    engines/cge2/snail.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 07f83b8..e5f38a0 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -35,6 +35,7 @@ namespace CGE2 {
 
 class CGE2Engine;
 class EncryptedStream;
+class V2D;
 
 #define kMaxPath  128
 enum {
diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 18016ec..88fdfbb 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -37,6 +37,7 @@
 #include "cge2/spare.h"
 #include "cge2/events.h"
 #include "cge2/talk.h"
+#include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 7146e43..a373705 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -28,11 +28,12 @@
 #ifndef CGE2_MAIN_H
 #define CGE2_MAIN_H
 
+#include "cge2/events.h"
+
 namespace CGE2 {
 
 #define kLineMax          512
 #define kIntroExt         ".I80"
-#define kNoByte           -1 // Recheck this! We have no proof for it's original value.
 #define kTabName          "CGE.TAB"
 #define kInfoW            140
 #define kPocketFull       170
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index bd145e1..0239402 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -29,67 +29,19 @@
 #define CGE2_GENERAL_H
 
 #include "common/file.h"
-#include "common/rect.h"
-#include "cge2/fileio.h"
-#include "cge2/cge2.h"
 
 namespace CGE2 {
 
 #define SCR_WID_ 320
 
+class CGE2Engine;
+
 struct Dac {
 	uint8 _r;
 	uint8 _g;
 	uint8 _b;
 };
 
-// From CGETYPE.H:
-class V3D {
-public:
-	double _x, _y, _z;
-	V3D(void) { }
-	V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
-	V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
-	V3D operator+(const V3D &p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
-	V3D operator-(const V3D &p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
-	V3D operator*(long n) const { return V3D(_x * n, _y * n, _z * n); }
-	V3D operator/ (long n) const { return V3D(_x / n, _y / n, _z / n); }
-	bool operator==(V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
-	bool operator!=(V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
-	V3D& operator+=(const V3D &x) { return *this = *this + x; }
-	V3D& operator-=(const V3D &x) { return *this = *this - x; }
-};
-
-class V2D : public Common::Point {
-	CGE2Engine *_vm;
-public:
-	V2D& operator=(const V3D &p3) {
-		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
-		x = round((_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m));
-		y = round((_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m));
-		return *this;
-	}
-	V2D(CGE2Engine *vm) : _vm(vm) { }
-	V2D(CGE2Engine *vm, const V3D &p3) : _vm(vm) { *this = p3; }
-	V2D(CGE2Engine *vm, int x, int y) : _vm(vm), Common::Point(x, y) { }
-	bool operator<(const V2D &p) const { return (x <  p.x) && (y <  p.y); }
-	bool operator<=(const V2D &p) const { return (x <= p.x) && (y <= p.y); }
-	bool operator>(const V2D &p) const { return (x >  p.x) && (y >  p.y); }
-	bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
-	V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
-	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
-	uint16 area(void) { return x * y; }
-	bool limited(const V2D &p) {
-		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
-	}
-	V2D scale(int z) {
-		double m = _vm->_eye->_z / (_vm->_eye->_z - z);
-		return V2D(_vm, trunc(m * x), trunc(m * y));
-	}
-	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
-	static double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
-};
-
 } // End of namespace CGE2
 
 #endif // CGE2_GENERAL_H
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index e3c2315..afd52df 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -29,12 +29,13 @@
 #define CGE2_SNAIL_H
 
 #include "cge2/cge2.h"
-#include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
 #define kCommandFrameRate  80
 #define kCommandFrameDelay (1000 / kCommandFrameRate)
+#define kNoByte            -1 // Recheck this! We have no proof for it's original value.
+
 
 enum CommandType {
 	kCmdCom0 = 128,
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 14bf97b..bbfd6c4 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -32,8 +32,8 @@
 #include "cge2/general.h"
 #include "cge2/vga13h.h"
 #include "cge2/bitmap.h"
-//#include "cge/text.h"
-//#include "cge/cge_main.h"
+#include "cge2/text.h"
+#include "cge2/cge2_main.h"
 #include "cge2/cge2.h"
 #include "cge2/vga13h.h"
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 77a2fd3..20d97ee 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -34,8 +34,8 @@
 #include "cge2/general.h"
 #include "cge2/bitmap.h"
 #include "cge2/snail.h"
-#include "cge2/cge2.h"
 #include "cge2/spare.h"
+#include "cge2/cge2.h"
 
 namespace CGE2 {
 
@@ -51,6 +51,53 @@ namespace CGE2 {
 #define kPalCount        256
 #define kPalSize         (kPalCount * 3)
 
+// From CGETYPE.H:
+class V3D {
+public:
+	double _x, _y, _z;
+	V3D(void) { }
+	V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
+	V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
+	V3D operator+(const V3D &p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
+	V3D operator-(const V3D &p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
+	V3D operator*(long n) const { return V3D(_x * n, _y * n, _z * n); }
+	V3D operator/ (long n) const { return V3D(_x / n, _y / n, _z / n); }
+	bool operator==(V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
+	bool operator!=(V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
+	V3D& operator+=(const V3D &x) { return *this = *this + x; }
+	V3D& operator-=(const V3D &x) { return *this = *this - x; }
+};
+
+class V2D : public Common::Point {
+	CGE2Engine *_vm;
+public:
+	V2D& operator=(const V3D &p3) {
+		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
+		x = round((_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m));
+		y = round((_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m));
+		return *this;
+	}
+	V2D(CGE2Engine *vm) : _vm(vm) { }
+	V2D(CGE2Engine *vm, const V3D &p3) : _vm(vm) { *this = p3; }
+	V2D(CGE2Engine *vm, int x, int y) : _vm(vm), Common::Point(x, y) { }
+	bool operator<(const V2D &p) const { return (x <  p.x) && (y <  p.y); }
+	bool operator<=(const V2D &p) const { return (x <= p.x) && (y <= p.y); }
+	bool operator>(const V2D &p) const { return (x >  p.x) && (y >  p.y); }
+	bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
+	V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
+	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
+	uint16 area(void) { return x * y; }
+	bool limited(const V2D &p) {
+		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
+	}
+	V2D scale(int z) {
+		double m = _vm->_eye->_z / (_vm->_eye->_z - z);
+		return V2D(_vm, trunc(m * x), trunc(m * y));
+	}
+	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
+	static double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
+};
+
 struct Seq {
 	uint8 _now;
 	uint8 _next;


Commit: 4e232814d5f96a7a0ed8aa2e249497c0d63dbace
    https://github.com/scummvm/scummvm/commit/4e232814d5f96a7a0ed8aa2e249497c0d63dbace
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T10:33:47+02:00

Commit Message:
CGE2: Implement runGame().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 88fdfbb..dd2ca16 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -65,6 +65,9 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = nullptr;
 	_sys = nullptr;
+	_busyPtr = nullptr;
+	for (int i = 0; i < 2; i++)
+		_vol[i] = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -81,6 +84,9 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_waitRef = 0;
 	_commandStat = { nullptr, { 0 , 0 } };
 	_taken = false;
+	_endGame = false;
+	for (int i = 0; i < 4; i++)
+		_flag[i] = false;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 5275fa7..8520424 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -68,6 +68,9 @@ class System;
 #define kPocketMax       4
 #define kCaveMax       100
 #define kMaxPoint        4
+#define kInfoX         160
+#define kInfoY         -11
+#define kInfoW         180
 
 enum CallbackType {
 	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
@@ -129,6 +132,9 @@ public:
 	void handleFrame();
 	Sprite *locate(int ref);
 	bool isHero(Sprite *spr);
+	void loadUser();
+	void checkSaySwitch();
+	void qGame();
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -199,6 +205,8 @@ public:
 		int _ref[2];
 	} _commandStat;
 	bool _taken;
+	bool _endGame;
+	bool _flag[4];
 
 	ResourceManager *_resman;
 	Vga *_vga;
@@ -219,6 +227,8 @@ public:
 	Talk *_talk;
 	V3D *_point[kMaxPoint];
 	System *_sys;
+	Sprite *_busyPtr;
+	Sprite *_vol[2];
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 501fa59..ff80c59 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -498,7 +498,74 @@ void CGE2Engine::busy(bool on) {
 }
 
 void CGE2Engine::runGame() {
-	warning("STUB: CGE2Engine::runGame()");
+	if (_quitFlag)
+		return;
+
+	selectPocket(-1);
+
+	loadUser();
+
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, _music, nullptr);
+	if (!_music)
+		_midiPlayer->killMidi();
+
+	checkSaySwitch();
+		
+	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
+	_infoLine->setText(nullptr);
+	_vga->_showQ->insert(_infoLine);
+
+	caveUp(_now);
+	_startupMode = 0;
+	_mouse->center();
+	_mouse->off();
+	_mouse->on();
+
+	_keyboard->setClient(_sys);
+	_commandHandler->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
+
+	_busyPtr = _vga->_showQ->locate(kBusyRef);
+
+	_vol[0] = _vga->_showQ->locate(kDvolRef);
+	_vol[1] = _vga->_showQ->locate(kMvolRef);
+
+	// these sprites are loaded with SeqPtr==0 (why?!)
+	if (_vol[0])
+		_vol[0]->step((/*(int)SNDDrvInfo.VOL4.DL * */ _vol[0]->_seqCnt + _vol[0]->_seqCnt / 2) >> 4);
+	if (_vol[1])
+		_vol[1]->step((/*(int)SNDDrvInfo.VOL4.ML * */ _vol[1]->_seqCnt + _vol[1]->_seqCnt / 2) >> 4);
+	// TODO: Recheck these! ^
+
+	// main loop
+	while (!_endGame && !_quitFlag) {
+		if (_flag[3]) // Flag FINIS
+			_commandHandler->addCallback(kCmdExec, -1, 0, kQGame);
+		mainLoop();
+	}
+
+	// If finishing game due to closing ScummVM window, explicitly save the game
+	if (!_endGame && canSaveGameStateCurrently())
+		qGame();
+
+	_keyboard->setClient(nullptr);
+	_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
+	_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
+	_mouse->off();
+	_vga->_showQ->clear();
+	_vga->_spareQ->clear();
+}
+
+void CGE2Engine::loadUser() {
+	warning("STUB: CGE2Engine::loadUser()");
+}
+
+void CGE2Engine::checkSaySwitch() {
+	warning("STUB: CGE2Engine::checkSaySwitch()");
+}
+
+void CGE2Engine::qGame() {
+	warning("STUB: CGE2Engine::qGame()");
+	_endGame = true;
 }
 
 void CGE2Engine::loadTab() {
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index a373705..98e7fbb 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -40,6 +40,15 @@ namespace CGE2 {
 #define kGameFrameDelay   (750 / 50)
 #define kGameTickDelay    (750 / 62)
 
+#define kMusicRef         122
+#define kPowerRef         123
+#define kDvolRef          124
+#define kMvolRef	      125
+#define kRef              126
+#define kBusyRef	      127
+#define kCapRef           128
+#define kVoxRef           129
+
 class System : public Sprite {
 public:
 	int _funDel;


Commit: 8fa31d1168ab6b361125a001fb3a38f0f7389129
    https://github.com/scummvm/scummvm/commit/8fa31d1168ab6b361125a001fb3a38f0f7389129
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T15:57:23+02:00

Commit Message:
CGE2: Comment out calling of the intro animation during testing.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ff80c59..a2ebc34 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -612,8 +612,10 @@ void CGE2Engine::cge2_main() {
 	_mode++;
 
 	if (showTitle("WELCOME")) {
+#if 0
 		if (_mode == 1)
 			movie(kIntroExt);
+#endif
 		if (_text->getText(255) != NULL) {
 			runGame();
 			_startupMode = 2;


Commit: 75546134c817a2f267c4ffff13b822ccf7e5e923
    https://github.com/scummvm/scummvm/commit/75546134c817a2f267c4ffff13b822ccf7e5e923
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T15:58:07+02:00

Commit Message:
CGE2: Implement loadUser() and loadPos().

Revise File I/O a bit to do so.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 8520424..c2e0dab 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -135,6 +135,7 @@ public:
 	void loadUser();
 	void checkSaySwitch();
 	void qGame();
+	void loadPos();
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a2ebc34..83569cc 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -556,7 +556,35 @@ void CGE2Engine::runGame() {
 }
 
 void CGE2Engine::loadUser() {
-	warning("STUB: CGE2Engine::loadUser()");
+	// set scene
+	if (_mode == 0) { // user .SVG file found
+		warning("STUB: CGE2Engine::loadUser()");
+		// Missing loading from save file. TODO: Implement it with the saving/loading!
+	} else if (_mode == 1) {
+		loadScript("CGE.INI");
+		loadPos();
+		// Missing saving to save file. TODO: Implement it with the saving/loading!
+	}
+}
+
+void CGE2Engine::loadPos() {
+	if (_resman->exist("CGE.HXY")) {
+		for (int cav = 0; cav < kCaveMax; cav++)
+			_heroTab[1]->_posTab[cav] = new V2D(this, 180, 10);
+		
+		EncryptedStream file(this, "CGE.HXY");
+
+		for (int cav = 0; cav < kCaveMax; cav++) {
+			_heroTab[0]->_posTab[cav]->x = file.readSint16LE();
+			_heroTab[0]->_posTab[cav]->y = file.readSint16LE();
+		}
+
+		for (int cav = 0; cav < 41; cav++) { // (564 - 400) / 4 = 41
+			_heroTab[1]->_posTab[cav]->x = file.readSint16LE();
+			_heroTab[1]->_posTab[cav]->y = file.readSint16LE();
+		}
+	} else
+		error("Missing file: CGE.HXY");
 }
 
 void CGE2Engine::checkSaySwitch() {
@@ -575,11 +603,10 @@ void CGE2Engine::loadTab() {
 
 	if (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
-		Common::File output;
 		for (int i = 0; i < kCaveMax; i++) {
 			for (int j = 0; j < 3; j++) {
-				signed b = f.readSigned();
-				unsigned a = f.readUnsigned();
+				signed b = f.readSint16BE();
+				unsigned a = f.readUint16BE();
 				uint16 round = uint16((long(a) << 16) / 100);
 				
 				if (round > 0x7FFF)
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 5885871..fc6303b 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -216,14 +216,18 @@ uint32 EncryptedStream::read(byte *dataPtr, uint32 dataSize) {
 	return _readStream->read(dataPtr, dataSize);
 }
 
-unsigned EncryptedStream::readUnsigned() {
+unsigned EncryptedStream::readUint16BE() {
 	return _readStream->readUint16BE();
 }
 
-signed EncryptedStream::readSigned() {
+signed EncryptedStream::readSint16BE() {
 	return _readStream->readSint16BE();
 }
 
+signed EncryptedStream::readSint16LE() {
+	return _readStream->readSint16LE();
+}
+
 bool EncryptedStream::err() {
 	return (_error & _readStream->err());
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index a35b014..ab5de22 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -121,8 +121,9 @@ public:
 	int32 pos();
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
-	unsigned readUnsigned();
-	signed readSigned();
+	unsigned readUint16BE();
+	signed readSint16BE();
+	signed readSint16LE();
 	Common::String readLine();
 	int getLineCount() { return _lineCount; }
 


Commit: 43ce991b84b75b290a9098c940a3d5294ff3eb66
    https://github.com/scummvm/scummvm/commit/43ce991b84b75b290a9098c940a3d5294ff3eb66
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T16:09:49+02:00

Commit Message:
CGE2: Rework loadUser().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 83569cc..3f8f862 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -556,15 +556,10 @@ void CGE2Engine::runGame() {
 }
 
 void CGE2Engine::loadUser() {
-	// set scene
-	if (_mode == 0) { // user .SVG file found
-		warning("STUB: CGE2Engine::loadUser()");
-		// Missing loading from save file. TODO: Implement it with the saving/loading!
-	} else if (_mode == 1) {
-		loadScript("CGE.INI");
-		loadPos();
-		// Missing saving to save file. TODO: Implement it with the saving/loading!
-	}
+	warning("STUB: CGE2Engine::loadUser()");
+	// Missing loading from file. TODO: Implement it with the saving/loading!
+	loadScript("CGE.INI");
+	loadPos();
 }
 
 void CGE2Engine::loadPos() {


Commit: 62e36f92793efea211715f65c7845baa95c16135
    https://github.com/scummvm/scummvm/commit/62e36f92793efea211715f65c7845baa95c16135
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T16:30:32+02:00

Commit Message:
CGE2: Rework EncryptedStream::readLine().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 3f8f862..eea59a4 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -116,11 +116,10 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 		Common::String line;
 
 		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
-			int len = line.size();
-			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-			if (len == 0 || *tmpStr == ';')
+			if (line.size() == 0)
 				continue;
-					
+			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+				
 			char *p;
 			p = token(tmpStr);
 			if (*p == '@') {
@@ -260,13 +259,14 @@ void CGE2Engine::loadScript(const char *fname) {
 	Common::String line;
 
 	for (line = scrf.readLine(); !scrf.eos(); line = scrf.readLine()) {
+		if (line.size() == 0)
+			continue;
+
 		char *p;
 
 		lcnt++;
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-		if ((line.size() == 0) || (*tmpStr == ';')) // Comments start with ';' - don't bother with them.
-			continue;
-
+		
 		ok = false; // not OK if break
 
 		V3D P;
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index fc6303b..4fec4a6 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -242,7 +242,10 @@ bool EncryptedStream::seek(int32 offset) {
 
 Common::String EncryptedStream::readLine() {
 	_lineCount++;
-	return _readStream->readLine();
+	Common::String line = _readStream->readLine();
+	if (!line.empty() && (line[0] == ';' || line[0] == '.' || line[0] == '*'))
+		line.clear(); // Returns an empty string, if the line is invalid.
+	return line;
 }
 
 int32 EncryptedStream::size() {
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index ab5de22..83a1456 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -105,6 +105,7 @@ public:
 	bool exist(const char *name);
 };
 
+// TODO: Revise the whole class!
 class EncryptedStream {
 private:
 	CGE2Engine *_vm;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index bbfd6c4..d428a10 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -278,10 +278,9 @@ Sprite *Sprite::expand() {
 		char tmpStr[kLineMax + 1];
 
 		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
-			int len = line.size();
-			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-			if (len == 0 || *tmpStr == ';')
+			if (line.size() == 0)
 				continue;
+			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 
 			char *p = _vm->token(tmpStr);
 			if (*p == '@') {


Commit: 8af90ab6b7311601b7889a16ff7014e7184dde51
    https://github.com/scummvm/scummvm/commit/8af90ab6b7311601b7889a16ff7014e7184dde51
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-26T17:40:09+02:00

Commit Message:
CGE2: Stub out actual use of _infoLine in runGame().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index eea59a4..8709157 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -513,7 +513,8 @@ void CGE2Engine::runGame() {
 		
 	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
 	_infoLine->setText(nullptr);
-	_vga->_showQ->insert(_infoLine);
+	//_vga->_showQ->insert(_infoLine);
+	warning("STUB: CGE2Engine::runGame() - Info Line is missing!");
 
 	caveUp(_now);
 	_startupMode = 0;


Commit: 06ae8de1561bfe392019cd3ce2f1bba498e4a607
    https://github.com/scummvm/scummvm/commit/06ae8de1561bfe392019cd3ce2f1bba498e4a607
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-29T18:19:01+02:00

Commit Message:
CGE2: Fix movie().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 8709157..e1641b9 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -383,8 +383,7 @@ void CGE2Engine::caveUp(int cav) {
 	_vga->show();
 
 	_sprite = _vga->_showQ->first();
-	if (_startupMode)
-		_vga->sunrise(_vga->_sysPal);
+	_vga->sunrise(_vga->_sysPal);
 
 	feedSnail(_vga->_showQ->locate(bakRef + 255), kNear, _heroTab[_sex]->_ptr);
 	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.


Commit: 8f28501e3cf78d666796a467b700bbc6c60e68a2
    https://github.com/scummvm/scummvm/commit/8f28501e3cf78d666796a467b700bbc6c60e68a2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-29T18:22:26+02:00

Commit Message:
CGE2: Remove unnecessary comment from vga13h.cpp.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index d428a10..695789f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -187,13 +187,6 @@ bool Sprite::seqTest(int n) {
 	return true;
 }
 
-//CommandHandler::Command *Sprite::snList(SnList type) {
-//	SprExt *e = _ext;
-//	if (e)
-//		return (type == kNear) ? e->_near : e->_take;
-//	return NULL;
-//}
-
 void Sprite::setName(char *newName) {
 	if (!_ext)
 		return;


Commit: e6e0847b7bbbbfee4ff6d4bac997c31a2c32b7b2
    https://github.com/scummvm/scummvm/commit/e6e0847b7bbbbfee4ff6d4bac997c31a2c32b7b2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-29T18:24:55+02:00

Commit Message:
CGE2: Finish implementation of Sprite::setSeq().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 695789f..97a31bb 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -162,13 +162,7 @@ bool Sprite::works(Sprite *spr) {
 }
 
 Seq *Sprite::setSeq(Seq *seq) {
-	if (_ext) {
-		free(_ext->_seq);
-		_ext->_seq = NULL;
-	}
-
-//	expand();
-	warning("STUB: Sprite::setSeq()");
+	expand();
 
 	Seq *s = _ext->_seq;
 	_ext->_seq = seq;


Commit: 566419f3ad868272df5bce837558592668c5aff6
    https://github.com/scummvm/scummvm/commit/566419f3ad868272df5bce837558592668c5aff6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-29T18:49:45+02:00

Commit Message:
CGE2: Implement snHide().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 3de42dd..45ca715 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -327,7 +327,11 @@ void CGE2Engine::snKill(Sprite *spr) {
 }
 
 void CGE2Engine::snHide(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snHide()");
+	if (spr) {
+		spr->_flags._hide = (val >= 0) ? (val != 0) : (!spr->_flags._hide);
+		if (spr->_flags._shad)
+			spr->_prev->_flags._hide = spr->_flags._hide;
+	}
 }
 
 void CGE2Engine::snMidi(int val) {


Commit: 7c73ce5d8b516976180aa38e76f75e88b1cbc474
    https://github.com/scummvm/scummvm/commit/7c73ce5d8b516976180aa38e76f75e88b1cbc474
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-29T19:58:38+02:00

Commit Message:
CGE2: Implement snSend().

Changed paths:
    engines/cge2/bitmap.h
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index e5f38a0..82c3b07 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -50,7 +50,7 @@ enum {
 struct HideDesc {
 	uint16 _skip;
 	uint16 _hide;
-} PACKED_STRUCT;
+};
 
 #include "common/pack-end.h"
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c2e0dab..cac5a08 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -136,6 +136,8 @@ public:
 	void checkSaySwitch();
 	void qGame();
 	void loadPos();
+	void releasePocket(Sprite *spr);
+	void switchHero(bool sex);
 
 	void setEye(V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
@@ -185,6 +187,8 @@ public:
 	void snSound(Sprite *spr, int wav);
 	void snRoom(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
+	
+	void hide1(Sprite *spr);
 
 	const ADGameDescription *_gameDescription;
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e1641b9..d4cee68 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -582,6 +582,10 @@ void CGE2Engine::loadPos() {
 		error("Missing file: CGE.HXY");
 }
 
+void CGE2Engine::releasePocket(Sprite *spr) {
+	warning("STUB: CGE2Engine::releasePocket()");
+}
+
 void CGE2Engine::checkSaySwitch() {
 	warning("STUB: CGE2Engine::checkSaySwitch()");
 }
@@ -748,4 +752,8 @@ void CGE2Engine::killText() {
 	_talk = NULL;
 }
 
+void CGE2Engine::switchHero(bool sex) {
+	warning("STUB: CGE2Engine::switchHero()");
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 45ca715..d92862a 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -361,7 +361,39 @@ void CGE2Engine::snRSeq(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snSend(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snSend()");
+	if (!spr)
+		return;
+	
+	// Sending", spr->File
+	// from cave", spr->Cave
+	// to cave", val
+	bool was1 = (_vga->_showQ->locate(spr->_ref) != nullptr);
+	bool val1 = (val == 0 || val == _now);
+	spr->_scene = val;
+	releasePocket(spr);
+	if (val1 != was1) {
+		if (was1) {
+			// deactivating
+			hide1(spr);
+			spr->_flags._slav = false;
+			if (spr == _heroTab[_sex]->_ptr)
+				if (_heroTab[!_sex]->_ptr->_scene == _now)
+					switchHero(!_sex);
+			_spare->dispose(spr);
+		} else {
+			// activating
+			if (byte(spr->_ref) == 0)
+				_bitmapPalette = _vga->_sysPal;
+			_vga->_showQ->insert(spr);
+			if (isHero(spr)) {
+				V2D p = *_heroTab[spr->_ref & 1]->_posTab[val];
+				spr->gotoxyz(V3D(p.x, 0, p.y));
+				((Hero*)spr)->setCurrent();
+			}
+			_taken = false;
+			_bitmapPalette = NULL;
+		}
+	}
 }
 
 void CGE2Engine::snSwap(Sprite *spr, int val) {
@@ -492,6 +524,10 @@ void CGE2Engine::snGhost(Bitmap *bmp) {
 	warning("STUB: CGE2Engine::snGhost()");
 }
 
+void CGE2Engine::hide1(Sprite *spr) {
+	_commandHandlerTurbo->addCommand(kCmdGhost, -1, 0, spr->ghost());
+}
+
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
 	if (ref == 2)
 		ref = 142 - _vm->_sex;


Commit: 60825760fd6eaa4a50c9a9e0bd9a2a5b0380d95c
    https://github.com/scummvm/scummvm/commit/60825760fd6eaa4a50c9a9e0bd9a2a5b0380d95c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-29T20:05:51+02:00

Commit Message:
CGE2: Implement snGhost().

Also implement Sprite::ghost().

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index d92862a..ede6206 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -521,7 +521,12 @@ void CGE2Engine::snRoom(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snGhost(Bitmap *bmp) {
-	warning("STUB: CGE2Engine::snGhost()");
+	V2D p(this, *bmp->_v & 0xFFFF, *bmp->_v >> 16);
+	bmp->hide(p.x, p.y);
+	delete bmp->_b;
+	bmp->_v = nullptr;
+	bmp->_b = nullptr;
+	delete bmp;
 }
 
 void CGE2Engine::hide1(Sprite *spr) {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 97a31bb..98daf56 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -606,12 +606,18 @@ void Sprite::hide() {
 BitmapPtr Sprite::ghost() {
 	SprExt *e = _ext;
 	if (!e->_b1)
-		return NULL;
-
-	BitmapPtr bmp = new Bitmap(_vm, 0, 0, (uint8 *)NULL);
-	assert(bmp != NULL);
-
-	warning("STUB: Sprite::ghost()");
+		return nullptr;
+
+	BitmapPtr bmp = new Bitmap(_vm, 0, 0, (uint8 *)nullptr);
+	assert(bmp != nullptr);
+	bmp->_w = e->_b1->_w;
+	bmp->_h = e->_b1->_h;
+	bmp->_b = new HideDesc[bmp->_h];
+	assert(bmp->_b != nullptr);
+	memcpy(bmp->_b, e->_b1->_b, sizeof(HideDesc)* bmp->_h);
+	uint8 *v = new uint8;
+	*v = (e->_p1.y << 16) + e->_p1.x;
+	bmp->_v = v;
 
 	return bmp;
 }


Commit: 2c453f8f662e65b3b85593d6a00a85c347852e4b
    https://github.com/scummvm/scummvm/commit/2c453f8f662e65b3b85593d6a00a85c347852e4b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-30T10:30:16+02:00

Commit Message:
CGE2: Fix some warnings.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index cac5a08..66bcd91 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -45,7 +45,7 @@ class Text;
 struct HeroTab;
 class V3D;
 class V2D;
-class Dac;
+struct Dac;
 class Spare;
 class CommandHandler;
 class InfoLine;
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 98e7fbb..272cdf7 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -35,7 +35,6 @@ namespace CGE2 {
 #define kLineMax          512
 #define kIntroExt         ".I80"
 #define kTabName          "CGE.TAB"
-#define kInfoW            140
 #define kPocketFull       170
 #define kGameFrameDelay   (750 / 50)
 #define kGameTickDelay    (750 / 62)


Commit: 6275f50d8052e480dd279f103e472e37a90493a8
    https://github.com/scummvm/scummvm/commit/6275f50d8052e480dd279f103e472e37a90493a8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:33:57+02:00

Commit Message:
CGE2: Fix commandStat initialization

Changed paths:
    engines/cge2/cge2.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index dd2ca16..273c9da 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -82,7 +82,9 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_lastTick = 0;
 	_waitSeq = 0;
 	_waitRef = 0;
-	_commandStat = { nullptr, { 0 , 0 } };
+	_commandStat._wait = nullptr;
+	_commandStat._ref[0] = 0;
+	_commandStat._ref[1] = 0;
 	_taken = false;
 	_endGame = false;
 	for (int i = 0; i < 4; i++)


Commit: 8654042d05117cd5c435b2aeb8cdaffa50545e8e
    https://github.com/scummvm/scummvm/commit/8654042d05117cd5c435b2aeb8cdaffa50545e8e
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:38:36+02:00

Commit Message:
CGE2: Silence a warning by adding a safeguard in step()

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 98daf56..09e8acc 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -446,7 +446,7 @@ void Sprite::step(int nr) {
 
 	if (_ext) {
 		V3D p = _pos3D;
-		Seq *seq;
+		Seq *seq = nullptr;
 
 		if (nr < 0)
 			_seqPtr = _ext->_seq[_seqPtr]._next;
@@ -466,7 +466,7 @@ void Sprite::step(int nr) {
 				warning("Sprite::step()");
 			}
 		}
-		if (seq->_dly >= 0)
+		if (seq && (seq->_dly >= 0))
 			_time = seq->_dly;
 	} else if (_vm->_waitRef && _vm->_waitRef == _ref)
 		_vm->_waitRef = 0;


Commit: 3035903f6f957569a88d904bc7b36c21aa97f546
    https://github.com/scummvm/scummvm/commit/3035903f6f957569a88d904bc7b36c21aa97f546
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:41:14+02:00

Commit Message:
CGE2: Clarify a STUB warning

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 09e8acc..618fb8a 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -463,7 +463,7 @@ void Sprite::step(int nr) {
 				p._z += seq->_dz;
 				//if (!_flags._kept)
 				//	gotoxyz(p);
-				warning("Sprite::step()");
+				warning("STUB: Sprite::step()");
 			}
 		}
 		if (seq && (seq->_dly >= 0))


Commit: 7ecb734a6ad6c276c725dbec84c173e9b6a26e0d
    https://github.com/scummvm/scummvm/commit/7ecb734a6ad6c276c725dbec84c173e9b6a26e0d
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:41:32+02:00

Commit Message:
CGE2: Fix eyetab initialization

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d4cee68..9e9d6da 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -598,7 +598,7 @@ void CGE2Engine::qGame() {
 void CGE2Engine::loadTab() {
 	setEye(_text->getText(240));
 	for (int i = 0; i < kCaveMax; i++)
-		_eyeTab[i] == _eye;
+		_eyeTab[i] = _eye;
 
 	if (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);


Commit: bea9e0532ec230c89cf76656ed4be0db3eb4bc13
    https://github.com/scummvm/scummvm/commit/bea9e0532ec230c89cf76656ed4be0db3eb4bc13
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:44:56+02:00

Commit Message:
CGE2: Move an unused variable in a STUB clock, initialize it (in the comment). That fixes a warning

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index ede6206..73d29cd 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -583,7 +583,6 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 		byte ptr = spr->_actionCtrl[snq]._ptr;
 		CommandHandler::Command *comtab = spr->snList(snq);
 		CommandHandler::Command *c = &comtab[ptr];
-		CommandHandler::Command *p;
 		CommandHandler::Command *q = &comtab[cnt];
 
 		warning("STUB: CGE2Engine::feedSnail()");
@@ -591,7 +590,8 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 		/*
 		int pocFre = freePockets(hero->_ref & 1);
 		int pocReq = 0;
-		for (p = c; p < q && p->_commandType != kCmdNext; p++) { // scan commands
+		CommandHandler::Command *p = c;
+		for (; p < q && p->_commandType != kCmdNext; p++) { // scan commands
 			// drop from pocket?
 			if ((p->_commandType == kCmdSend && p->_val != _now)
 				|| p->_commandType == kCmdGive) {


Commit: 8a712c840d4c65edf4c1f51273d77c6c38ca80a6
    https://github.com/scummvm/scummvm/commit/8a712c840d4c65edf4c1f51273d77c6c38ca80a6
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:52:10+02:00

Commit Message:
CGE2: Fix several signed/unsigned comparisons

Changed paths:
    engines/cge2/spare.cpp



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 650af7b..be2fc64 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -38,10 +38,9 @@ void Spare::clear() {
 }
 
 Sprite *Spare::locate(int ref) {
-	for (int i = 0; i < _container.size(); i++) {
-		if (_container[i]->_ref == ref) {
+	for (uint i = 0; i < _container.size(); ++i) {
+		if (_container[i]->_ref == ref)
 			return _container[i];
-		}
 	}
 	return nullptr;
 }
@@ -49,7 +48,7 @@ Sprite *Spare::locate(int ref) {
 void Spare::takeCave(int cav) {
 	int bakRef = cav << 8;
 	Common::Array<Sprite*> tempCont = _container;
-	for (int i = 0; i < tempCont.size(); i++) {
+	for (uint i = 0; i < tempCont.size(); ++i) {
 		Sprite *spr = tempCont[i];
 		int c = spr->_scene;
 		if ((c == _vm->_now || c == 0) && spr->_ref != bakRef) {
@@ -73,7 +72,7 @@ void Spare::dispose(Sprite *spr) {
 		_vm->_vga->_showQ->remove(spr);
 		update(spr->contract());
 		if (!_vm->isHero(spr)) {
-			for (int i = 0; i < _container.size(); i++) {
+			for (uint i = 0; i < _container.size(); ++i) {
 				if (spr == _container[i]) {
 					_container.remove_at(i);
 					delete spr;
@@ -89,10 +88,9 @@ void Spare::dispose(int ref) {
 }
 
 void Spare::dispose() {
-	for (int i = 0; i < _container.size(); i++) {
-		if (_container[i]->_ref > 255) {
+	for (uint i = 0; i < _container.size(); ++i) {
+		if (_container[i]->_ref > 255)
 			dispose(_container[i]);
-		}
 	}
 }
 


Commit: 5ad4e157e5398347651a0da0db07f9daf01bf373
    https://github.com/scummvm/scummvm/commit/5ad4e157e5398347651a0da0db07f9daf01bf373
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T10:56:02+02:00

Commit Message:
CGE2: Silence a warning in runCommand

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 73d29cd..f00b02c 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -104,7 +104,7 @@ void CommandHandler::runCommand() {
 		}
 		++_tail;
 		_vm->_taken = false;
-		Sprite *spr;
+		Sprite *spr = nullptr;
 		if (tailCmd._commandType > kCmdSpr)
 			spr = (tailCmd._ref < 0) ? ((Sprite *)tailCmd._spritePtr) : _vm->locate(tailCmd._ref);
 
@@ -314,7 +314,7 @@ void CommandHandler::runCommand() {
 			break;
 		}
 
-		if (_vm->_taken)
+		if (_vm->_taken && spr)
 			_vm->_spare->dispose(spr);
 
 		if (!_turbo)


Commit: bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d
    https://github.com/scummvm/scummvm/commit/bb2f8dd68e1d6b2b30b07f60c0cd4e125b47ea4d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-30T11:14:47+02:00

Commit Message:
Merge branch 'master' of https://github.com/scummvm/scummvm into cge2

Changed paths:
  A engines/mads/action.cpp
  A engines/mads/action.h
  A engines/mads/animation.cpp
  A engines/mads/animation.h
  A engines/mads/assets.cpp
  A engines/mads/assets.h
  A engines/mads/audio.cpp
  A engines/mads/audio.h
  A engines/mads/compression.cpp
  A engines/mads/compression.h
  A engines/mads/configure.engine
  A engines/mads/debugger.cpp
  A engines/mads/debugger.h
  A engines/mads/detection.cpp
  A engines/mads/detection_tables.h
  A engines/mads/dialogs.cpp
  A engines/mads/dialogs.h
  A engines/mads/dragonsphere/dragonsphere_scenes.cpp
  A engines/mads/dragonsphere/dragonsphere_scenes.h
  A engines/mads/dragonsphere/game_dragonsphere.cpp
  A engines/mads/dragonsphere/game_dragonsphere.h
  A engines/mads/events.cpp
  A engines/mads/events.h
  A engines/mads/font.cpp
  A engines/mads/font.h
  A engines/mads/game.cpp
  A engines/mads/game.h
  A engines/mads/game_data.cpp
  A engines/mads/game_data.h
  A engines/mads/globals.cpp
  A engines/mads/globals.h
  A engines/mads/hotspots.cpp
  A engines/mads/hotspots.h
  A engines/mads/inventory.cpp
  A engines/mads/inventory.h
  A engines/mads/mads.cpp
  A engines/mads/mads.h
  A engines/mads/messages.cpp
  A engines/mads/messages.h
  A engines/mads/module.mk
  A engines/mads/msurface.cpp
  A engines/mads/msurface.h
  A engines/mads/nebular/dialogs_nebular.cpp
  A engines/mads/nebular/dialogs_nebular.h
  A engines/mads/nebular/game_nebular.cpp
  A engines/mads/nebular/game_nebular.h
  A engines/mads/nebular/globals_nebular.cpp
  A engines/mads/nebular/globals_nebular.h
  A engines/mads/nebular/nebular_scenes.cpp
  A engines/mads/nebular/nebular_scenes.h
  A engines/mads/nebular/nebular_scenes1.cpp
  A engines/mads/nebular/nebular_scenes1.h
  A engines/mads/nebular/nebular_scenes2.cpp
  A engines/mads/nebular/nebular_scenes2.h
  A engines/mads/nebular/nebular_scenes3.cpp
  A engines/mads/nebular/nebular_scenes3.h
  A engines/mads/nebular/nebular_scenes4.cpp
  A engines/mads/nebular/nebular_scenes4.h
  A engines/mads/nebular/nebular_scenes5.cpp
  A engines/mads/nebular/nebular_scenes5.h
  A engines/mads/nebular/nebular_scenes6.cpp
  A engines/mads/nebular/nebular_scenes6.h
  A engines/mads/nebular/nebular_scenes7.cpp
  A engines/mads/nebular/nebular_scenes7.h
  A engines/mads/nebular/nebular_scenes8.cpp
  A engines/mads/nebular/nebular_scenes8.h
  A engines/mads/nebular/sound_nebular.cpp
  A engines/mads/nebular/sound_nebular.h
  A engines/mads/palette.cpp
  A engines/mads/palette.h
  A engines/mads/phantom/game_phantom.cpp
  A engines/mads/phantom/game_phantom.h
  A engines/mads/phantom/phantom_scenes.cpp
  A engines/mads/phantom/phantom_scenes.h
  A engines/mads/player.cpp
  A engines/mads/player.h
  A engines/mads/rails.cpp
  A engines/mads/rails.h
  A engines/mads/resources.cpp
  A engines/mads/resources.h
  A engines/mads/scene.cpp
  A engines/mads/scene.h
  A engines/mads/scene_data.cpp
  A engines/mads/scene_data.h
  A engines/mads/screen.cpp
  A engines/mads/screen.h
  A engines/mads/sequence.cpp
  A engines/mads/sequence.h
  A engines/mads/sound.cpp
  A engines/mads/sound.h
  A engines/mads/sprites.cpp
  A engines/mads/sprites.h
  A engines/mads/staticres.cpp
  A engines/mads/staticres.h
  A engines/mads/user_interface.cpp
  A engines/mads/user_interface.h
    AUTHORS
    backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in
    backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in
    backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3.pkg
    backends/platform/symbian/S60v3/scummvm-CVS-SymbianS60v3_split.pkg
    backends/platform/symbian/help/ScummVM.rtf
    backends/platform/symbian/mmp/scummvm_agi.mmp.in
    backends/platform/symbian/mmp/scummvm_agos.mmp.in
    backends/platform/symbian/mmp/scummvm_avalanche.mmp.in
    backends/platform/symbian/mmp/scummvm_base.mmp.in
    backends/platform/symbian/mmp/scummvm_cge.mmp.in
    backends/platform/symbian/mmp/scummvm_cine.mmp.in
    backends/platform/symbian/mmp/scummvm_composer.mmp.in
    backends/platform/symbian/mmp/scummvm_cruise.mmp.in
    backends/platform/symbian/mmp/scummvm_draci.mmp.in
    backends/platform/symbian/mmp/scummvm_drascula.mmp.in
    backends/platform/symbian/mmp/scummvm_dreamweb.mmp.in
    backends/platform/symbian/mmp/scummvm_fullpipe.mmp.in
    backends/platform/symbian/mmp/scummvm_gob.mmp.in
    backends/platform/symbian/mmp/scummvm_groovie.mmp.in
    backends/platform/symbian/mmp/scummvm_hopkins.mmp.in
    backends/platform/symbian/mmp/scummvm_hugo.mmp.in
    backends/platform/symbian/mmp/scummvm_kyra.mmp.in
    backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in
    backends/platform/symbian/mmp/scummvm_lure.mmp.in
    backends/platform/symbian/mmp/scummvm_m4.mmp.in
    backends/platform/symbian/mmp/scummvm_made.mmp.in
    backends/platform/symbian/mmp/scummvm_mohawk.mmp.in
    backends/platform/symbian/mmp/scummvm_mortevielle.mmp.in
    backends/platform/symbian/mmp/scummvm_neverhood.mmp.in
    backends/platform/symbian/mmp/scummvm_parallaction.mmp.in
    backends/platform/symbian/mmp/scummvm_pegasus.mmp.in
    backends/platform/symbian/mmp/scummvm_queen.mmp.in
    backends/platform/symbian/mmp/scummvm_saga.mmp.in
    backends/platform/symbian/mmp/scummvm_sci.mmp.in
    backends/platform/symbian/mmp/scummvm_scumm.mmp.in
    backends/platform/symbian/mmp/scummvm_sky.mmp.in
    backends/platform/symbian/mmp/scummvm_sword1.mmp.in
    backends/platform/symbian/mmp/scummvm_sword2.mmp.in
    backends/platform/symbian/mmp/scummvm_sword25.mmp.in
    backends/platform/symbian/mmp/scummvm_teenagent.mmp.in
    backends/platform/symbian/mmp/scummvm_testbed.mmp.in
    backends/platform/symbian/mmp/scummvm_tinsel.mmp.in
    backends/platform/symbian/mmp/scummvm_toltecs.mmp.in
    backends/platform/symbian/mmp/scummvm_tony.mmp.in
    backends/platform/symbian/mmp/scummvm_toon.mmp.in
    backends/platform/symbian/mmp/scummvm_touche.mmp.in
    backends/platform/symbian/mmp/scummvm_tsage.mmp.in
    backends/platform/symbian/mmp/scummvm_tucker.mmp.in
    backends/platform/symbian/mmp/scummvm_wintermute.mmp.in
    backends/platform/symbian/mmp/scummvm_zvision.mmp.in
    configure
    devtools/credits.pl
    engines/agi/console.cpp
    engines/agi/preagi_mickey.cpp
    engines/agi/preagi_winnie.cpp
    engines/agos/agos.cpp
    engines/agos/agos.h
    engines/agos/debugger.cpp
    engines/agos/debugger.h
    engines/agos/gfx.cpp
    engines/agos/script.cpp
    engines/agos/subroutine.cpp
    engines/agos/vga.cpp
    engines/avalanche/console.cpp
    engines/avalanche/ghostroom.cpp
    engines/cge/console.cpp
    engines/cine/console.cpp
    engines/cine/gfx.cpp
    engines/cine/pal.cpp
    engines/cruise/debugger.cpp
    engines/draci/game.cpp
    engines/draci/walking.cpp
    engines/drascula/console.cpp
    engines/fullpipe/console.cpp
    engines/fullpipe/detection.cpp
    engines/fullpipe/fullpipe.cpp
    engines/fullpipe/fullpipe.h
    engines/fullpipe/gameloader.cpp
    engines/fullpipe/gameloader.h
    engines/fullpipe/gfx.cpp
    engines/fullpipe/gfx.h
    engines/fullpipe/messagehandlers.cpp
    engines/fullpipe/messages.cpp
    engines/fullpipe/modal.cpp
    engines/fullpipe/modal.h
    engines/fullpipe/motion.cpp
    engines/fullpipe/motion.h
    engines/fullpipe/scene.cpp
    engines/fullpipe/scene.h
    engines/fullpipe/scenes.cpp
    engines/fullpipe/sound.cpp
    engines/fullpipe/stateloader.cpp
    engines/fullpipe/statics.cpp
    engines/fullpipe/statics.h
    engines/fullpipe/utils.h
    engines/gob/cheater_geisha.cpp
    engines/gob/console.cpp
    engines/groovie/debug.cpp
    engines/hopkins/computer.cpp
    engines/hopkins/computer.h
    engines/hopkins/debugger.cpp
    engines/hopkins/files.cpp
    engines/hugo/console.cpp
    engines/kyra/debugger.cpp
    engines/kyra/debugger.h
    engines/lastexpress/debug.cpp
    engines/lure/debugger.cpp





Commit: e34113a94cf3762880fc33694b61af4d18f5fb8c
    https://github.com/scummvm/scummvm/commit/e34113a94cf3762880fc33694b61af4d18f5fb8c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-30T12:48:58+02:00

Commit Message:
CGE2: Fix assignments and deinitialization of _eye and _eyeTab.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 273c9da..d0d5740 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -124,12 +124,9 @@ void CGE2Engine::deinit() {
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
 	for (int i = 0; i < kCaveMax; i++) {
-		if (_eye == _eyeTab[i])
-			_eye = nullptr;
 		delete _eyeTab[i];
 	}
-	if (_eye != nullptr)
-		delete _eye;
+	delete _eye;
 	delete _spare;
 	delete _sprite;
 	delete _commandHandler;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 66bcd91..c7c16d4 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -139,7 +139,7 @@ public:
 	void releasePocket(Sprite *spr);
 	void switchHero(bool sex);
 
-	void setEye(V3D &e);
+	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
 	void setEye(const char *s);
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9e9d6da..f468d15 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -361,7 +361,7 @@ void CGE2Engine::caveUp(int cav) {
 	if (_music)
 		_midiPlayer->loadMidi(bakRef);
 	showBak(bakRef);
-	_eye = _eyeTab[_now];
+	*_eye = *(_eyeTab[_now]);
 	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
 	_spare->takeCave(_now);
 	openPocket();
@@ -598,7 +598,7 @@ void CGE2Engine::qGame() {
 void CGE2Engine::loadTab() {
 	setEye(_text->getText(240));
 	for (int i = 0; i < kCaveMax; i++)
-		_eyeTab[i] = _eye;
+		*(_eyeTab[i]) = *_eye;
 
 	if (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
@@ -660,8 +660,8 @@ char *CGE2Engine::mergeExt(char *buf, const char *name, const char *ext) {
 	return buf;
 }
 
-void CGE2Engine::setEye(V3D &e) { 
-	_eye = &e;
+void CGE2Engine::setEye(const V3D &e) { 
+	*_eye = e;
 }
 
 void CGE2Engine::setEye(const V2D& e2, int z) {


Commit: 7e8923f757d990972f2bc5ff995c98c0243b7fba
    https://github.com/scummvm/scummvm/commit/7e8923f757d990972f2bc5ff995c98c0243b7fba
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-05-30T16:10:51+02:00

Commit Message:
CGE2: Add detection for the WIP English translation

Changed paths:
    engines/cge2/detection.cpp



diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 9c63af1..e417a13 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -35,7 +35,7 @@ static const PlainGameDescriptor CGE2Games[] = {
 	{ 0, 0 }
 };
 
-static const ADGameDescription gameDescriptions[] = { // TODO: Add ENG version too.
+static const ADGameDescription gameDescriptions[] = {
 	{
 		"sfinx", "Sfinx Freeware",
 		{
@@ -45,7 +45,15 @@ static const ADGameDescription gameDescriptions[] = { // TODO: Add ENG version t
 		},
 		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
 	},
-	
+	{
+		"sfinx", "Sfinx English Alfa v0.1",
+		{
+			{"vol.cat", 0, "41a61030468e33828f3531fd53ef0319", 129024},
+			{"vol.dat", 0, "978ebe56442c111d193fdb4d960cc58d", 34382498},	
+			AD_LISTEND
+		},
+		Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+	},
 	AD_TABLE_END_MARKER
 };
 


Commit: 82898716cf24098e664211a5e2f904f9fe98d2d5
    https://github.com/scummvm/scummvm/commit/82898716cf24098e664211a5e2f904f9fe98d2d5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-05-31T15:22:29+02:00

Commit Message:
CGE2: Reimplement Vga::show().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 618fb8a..bc042a5 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -957,13 +957,41 @@ void Vga::sunset() {
 }
 
 void Vga::show() {
-	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next)
+	_vm->_infoLine->update();
+
+	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next) {
 		spr->show();
+	}
+
+	//_vm->_mouse->show();
 	update();
-	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next)
+
+	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next) {
 		spr->hide();
+		if (spr->_flags._zmov) {
+			Sprite *s = nullptr;
+			Sprite *p = spr->_prev;
+			Sprite *n = spr->_next;
+
+			if (spr->_flags._shad) {
+				s = p;
+				p = s->_prev;
+			}
 
-	_frmCnt++;
+			if ((p && spr->_pos3D._z > p->_pos3D._z) ||
+				(n && spr->_pos3D._z < n->_pos3D._z)) {
+				_showQ->insert(_showQ->remove(spr));
+				if (s) {
+					//s->gotoxyz(V3D(s->_pos3D._x, s->_pos3D._y, spr->_pos3D._z));
+					//_showQ->insert(_showQ->remove(s), spr);
+					// These two lines are also commented out in the original.
+				}
+			}
+			spr->_flags._zmov = false;
+		}
+	}
+	//_vm->_mouse->hide();
+	warning("STUB: Vga::show() - Mouse handling is missing!");
 }
 
 void Vga::updateColors() {


Commit: 8eb6a4db8bb73df76c5cc1d90775d0925a5a6adb
    https://github.com/scummvm/scummvm/commit/8eb6a4db8bb73df76c5cc1d90775d0925a5a6adb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-01T21:44:07+02:00

Commit Message:
CGE2: Add display of mouse cursor.

The actual click-handling is not working yet.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/events.cpp
    engines/cge2/events.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index d0d5740..c4ae027 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -68,6 +68,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_busyPtr = nullptr;
 	for (int i = 0; i < 2; i++)
 		_vol[i] = nullptr;
+	_eventManager = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -112,6 +113,7 @@ void CGE2Engine::init() {
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = new V3D();
 	_sys = new System(this);
+	_eventManager = new EventManager(this);
 }
 
 void CGE2Engine::deinit() {
@@ -140,6 +142,7 @@ void CGE2Engine::deinit() {
 		delete _point[i];
 	}
 	delete _sys;
+	delete _eventManager;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c7c16d4..925cb67 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -55,6 +55,7 @@ class Talk;
 class Hero;
 class Bitmap;
 class System;
+class EventManager;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -131,6 +132,7 @@ public:
 	void mainLoop();
 	void handleFrame();
 	Sprite *locate(int ref);
+	Sprite *spriteAt(int x, int y);
 	bool isHero(Sprite *spr);
 	void loadUser();
 	void checkSaySwitch();
@@ -234,6 +236,7 @@ public:
 	System *_sys;
 	Sprite *_busyPtr;
 	Sprite *_vol[2];
+	EventManager *_eventManager;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f468d15..e9fc11b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -385,6 +385,11 @@ void CGE2Engine::caveUp(int cav) {
 	_sprite = _vga->_showQ->first();
 	_vga->sunrise(_vga->_sysPal);
 
+	_dark = false;
+
+	if (!_startupMode)
+		_mouse->on();
+
 	feedSnail(_vga->_showQ->locate(bakRef + 255), kNear, _heroTab[_sex]->_ptr);
 	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.
 }
@@ -414,8 +419,7 @@ void CGE2Engine::mainLoop() {
 	handleFrame();
 
 	// Handle any pending events
-	//_eventManager->poll();
-	warning("STUB: CGE2Engine::mainLoop() - Event handling is missing!");
+	_eventManager->poll();
 
 	// Check shouldQuit()
 	_quitFlag = shouldQuit();
@@ -426,8 +430,7 @@ void CGE2Engine::handleFrame() {
 	uint32 millis = g_system->getMillis();
 	while (!_quitFlag && (millis < (_lastFrame + kGameFrameDelay))) {
 		// Handle any pending events
-		//_eventManager->poll();
-		warning("STUB: CGE2Engine::handleFrame() - Event handling is missing!");
+		_eventManager->poll();
 
 		if (millis >= (_lastTick + kGameTickDelay)) {
 			// Dispatch the tick to any active objects
@@ -476,8 +479,7 @@ void CGE2Engine::tick() {
 		}
 	}
 
-	//Mouse->Tick();
-	warning("STUB: CGE2Engine::tick() - Mouse");
+	_mouse->tick();
 }
 
 void CGE2Engine::loadMap(int cav) {
@@ -756,4 +758,17 @@ void CGE2Engine::switchHero(bool sex) {
 	warning("STUB: CGE2Engine::switchHero()");
 }
 
+Sprite *CGE2Engine::spriteAt(int x, int y) {
+	Sprite *spr = NULL, *tail = _vga->_showQ->last();
+	if (tail) {
+		for (spr = tail->_prev; spr; spr = spr->_prev) {
+			if (!spr->_flags._hide && !spr->_flags._tran) {
+				if (spr->shp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y))
+					break;
+			}
+		}
+	}
+	return spr;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 670ea61..5c0300f 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -63,23 +63,187 @@ void Keyboard::newKeyboard(Common::Event &event) {
 /*----------------- MOUSE interface -----------------*/
 
 Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
-	warning("STUB: Mouse::Mouse() - Recheck the whole implementation!!!");
+	_hold = NULL;
+	_hx = 0;
+	_hy = 0;
+	_exist = true;
+	_buttons = 0;
+	_busy = NULL;
+	_active = false;
+	_flags._kill = false;
+	
+	setSeq(_stdSeq8);
+
+	BitmapPtr *MC = new BitmapPtr[3];
+	MC[0] = new Bitmap(_vm, "MOUSE");
+	MC[1] = new Bitmap(_vm, "DUMMY");
+	MC[2] = NULL;
+	setShapeList(MC, 2);
+
+	step(1);
+	on();
+	off();
 }
 
 Mouse::~Mouse() {
-	warning("STUB: Mouse::~Mouse()");
+	off();
 }
 
 void Mouse::on() {
-	warning("STUB: Mouse::on()");
+	if (_seqPtr && _exist) {
+		_active = true;
+		step(0);
+		if (_busy)
+			_busy->step(0);
+	}
 }
 
 void Mouse::off() {
-	warning("STUB: Mouse::off()");
+	if (_seqPtr == 0) {
+		if (_exist) {
+			_active = false;
+		}
+
+		step(1);
+		if (_busy)
+			_busy->step(1);
+	}
 }
 
 void Mouse::newMouse(Common::Event &event) {
-	warning("STUB: Mouse::newMouse()");
+	if (!_active)
+		return;
+
+	CGE2Event &evt = _vm->_eventManager->getNextEvent();
+	evt._x = event.mouse.x;
+	evt._y = event.mouse.y;
+	evt._keyCode = Common::KEYCODE_INVALID;
+	evt._spritePtr = _vm->spriteAt(evt._x, evt._y);
+
+	switch (event.type) {
+	case Common::EVENT_MOUSEMOVE:
+		evt._mask = kMouseRoll;
+		break;
+	case Common::EVENT_LBUTTONDOWN:
+		evt._mask = kMouseLeftDown;
+		_buttons |= 1;
+		break;
+	case Common::EVENT_LBUTTONUP:
+		evt._mask = kMouseLeftUp;
+		_buttons &= ~1;
+		break;
+	case Common::EVENT_RBUTTONDOWN:
+		evt._mask = kMouseRightDown;
+		_buttons |= 2;
+		break;
+	case Common::EVENT_RBUTTONUP:
+		evt._mask = kMouseRightUp;
+		_buttons &= ~2;
+		break;
+	default:
+		break;
+	}
+}
+
+/*----------------- EventManager interface -----------------*/
+
+EventManager::EventManager(CGE2Engine *vm) : _vm(vm){
+	_eventQueueHead = 0;
+	_eventQueueTail = 0;
+	memset(&_eventQueue, 0, kEventMax * sizeof(CGE2Event));
+	memset(&_event, 0, sizeof(Common::Event));
+}
+
+void EventManager::poll() {
+	while (g_system->getEventManager()->pollEvent(_event)) {
+		switch (_event.type) {
+		case Common::EVENT_KEYDOWN:
+		case Common::EVENT_KEYUP:
+			// Handle keyboard events
+			_vm->_keyboard->newKeyboard(_event);
+			handleEvents();
+			break;
+		case Common::EVENT_MOUSEMOVE:
+		case Common::EVENT_LBUTTONDOWN:
+		case Common::EVENT_LBUTTONUP:
+		case Common::EVENT_RBUTTONDOWN:
+		case Common::EVENT_RBUTTONUP:
+			// Handle mouse events
+			_vm->_mouse->newMouse(_event);
+			handleEvents();
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+void EventManager::handleEvents() {
+	while (_eventQueueTail != _eventQueueHead) {
+		CGE2Event e = _eventQueue[_eventQueueTail];
+		if (e._mask) {
+			if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold)
+				_vm->_mouse->_hold->touch(e._mask | kEventAttn, e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y, e._keyCode);
+
+			// update mouse cursor position
+			if (e._mask & kMouseRoll)
+				_vm->_mouse->gotoxyz(e._x, kWorldHeight - e._y);
+
+			// activate current touched SPRITE
+			if (e._spritePtr) {
+				if (e._mask & kEventKeyb)
+					e._spritePtr->touch(e._mask, e._x, e._y, e._keyCode);
+				else
+					e._spritePtr->touch(e._mask, e._x - e._spritePtr->_pos2D.x, e._y - e._spritePtr->_pos2D.y, e._keyCode);
+			} else if (_vm->_sys)
+				_vm->_sys->touch(e._mask, e._x, e._y, e._keyCode);
+
+			if (e._mask & kMouseLeftDown) {
+				_vm->_mouse->_hold = e._spritePtr;
+				if (_vm->_mouse->_hold) {
+					_vm->_mouse->_hold->_flags._hold = true;
+
+					if (_vm->_mouse->_hold->_flags._drag) {
+						_vm->_mouse->_hx = e._x - _vm->_mouse->_hold->_pos2D.x;
+						_vm->_mouse->_hy = e._y - _vm->_mouse->_hold->_pos2D.y;
+					}
+				}
+			}
+
+			if (e._mask & kMouseLeftUp) {
+				if (_vm->_mouse->_hold) {
+					_vm->_mouse->_hold->_flags._hold = false;
+					_vm->_mouse->_hold = NULL;
+				}
+			}
+			///Touched = e.Ptr;
+
+			// discard Text if button released
+			if (e._mask & (kMouseLeftUp | kMouseRightUp))
+				_vm->killText();
+		}
+		_eventQueueTail = (_eventQueueTail + 1) % kEventMax;
+	}
+	if (_vm->_mouse->_hold) {
+		if (_vm->_mouse->_hold->_flags._drag)
+			_vm->_mouse->_hold->gotoxyz(_vm->_mouse->_pos2D.x - _vm->_mouse->_hx, kWorldHeight - _vm->_mouse->_pos2D.y - _vm->_mouse->_hy);
+	}
+}
+
+void EventManager::clearEvent(Sprite *spr) {
+	if (spr) {
+		for (uint16 e = _eventQueueTail; e != _eventQueueHead; e = (e + 1) % kEventMax)
+			if (_eventQueue[e]._spritePtr == spr)
+				_eventQueue[e]._mask = 0;
+	} else
+		_eventQueueTail = _eventQueueHead;
+}
+
+CGE2Event &EventManager::getNextEvent() {
+	CGE2Event &evt = _eventQueue[_eventQueueHead];
+	_eventQueueHead = (_eventQueueHead + 1) % kEventMax;
+
+	return evt;
 }
 
 } // End of namespace CGE2
diff --git a/engines/cge2/events.h b/engines/cge2/events.h
index 99f017b..39fbf53 100644
--- a/engines/cge2/events.h
+++ b/engines/cge2/events.h
@@ -65,6 +65,14 @@ public:
 
 /*----------------- MOUSE interface -----------------*/
 
+struct CGE2Event {
+	uint16 _mask;
+	uint16 _x;
+	uint16 _y;
+	Common::KeyCode _keyCode;
+	Sprite *_spritePtr;
+};
+
 class Mouse : public Sprite {
 public:
 	Sprite *_hold;
@@ -83,6 +91,25 @@ private:
 	CGE2Engine *_vm;
 };
 
+/*----------------- EventManager interface -----------------*/
+
+class EventManager {
+private:
+	CGE2Engine *_vm;
+	Common::Event _event;
+	CGE2Event _eventQueue[kEventMax];
+	uint16 _eventQueueHead;
+	uint16 _eventQueueTail;
+
+	void handleEvents();
+public:
+	EventManager(CGE2Engine *vm);
+	void poll();
+	void clearEvent(Sprite *spr);
+
+	CGE2Event &getNextEvent();
+};
+
 } // End of namespace CGE
 
 #endif // #define CGE2_EVENTS_H
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index bc042a5..8158d6d 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -129,7 +129,7 @@ void Sprite::setShapeList(BitmapPtr *shp, int cnt) {
 
 	if (shp) {
 		for (int i = 0; i < cnt; i++) {
-			BitmapPtr p = *shp + i;
+			BitmapPtr p = *(shp + i);
 			if (p->_w > _siz.x)
 				_siz.x = p->_w;
 			if (p->_h > _siz.y)
@@ -472,6 +472,11 @@ void Sprite::step(int nr) {
 		_vm->_waitRef = 0;
 }
 
+#pragma argsused
+void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
+	warning("STUB: Sprite::touch()");
+}
+
 void Sprite::tick() {
 	step();
 }
@@ -530,7 +535,7 @@ void Sprite::gotoxyz(V2D pos) {
 		++trim;
 	}
 	_pos2D.x = pos.x;
-
+	
 	if (pos.y < -kPanHeight) {
 		pos.y = -kPanHeight;
 		++trim;
@@ -963,7 +968,7 @@ void Vga::show() {
 		spr->show();
 	}
 
-	//_vm->_mouse->show();
+	_vm->_mouse->show();
 	update();
 
 	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next) {
@@ -990,8 +995,7 @@ void Vga::show() {
 			spr->_flags._zmov = false;
 		}
 	}
-	//_vm->_mouse->hide();
-	warning("STUB: Vga::show() - Mouse handling is missing!");
+	_vm->_mouse->hide();
 }
 
 void Vga::updateColors() {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 20d97ee..a4829b6 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -198,7 +198,7 @@ public:
 	void step(int nr = -1);
 	Seq *setSeq(Seq *seq);
 	CommandHandler::Command *snList(Action type);
-	//virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
+	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
 	virtual void tick();
 	void clrHide(void) { if (_ext) _ext->_b0 = NULL; }
 	void sync(Common::Serializer &s);


Commit: ff21b2d5c8f8510ea5cfc6e59385c272d9774af9
    https://github.com/scummvm/scummvm/commit/ff21b2d5c8f8510ea5cfc6e59385c272d9774af9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T10:03:15+02:00

Commit Message:
CGE2: Implement Hero::expand(), move Sprite::works()'s stub to hero.cpp.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/hero.cpp
    engines/cge2/hero.h
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 10fd6f1..dfc5bca 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -35,7 +35,14 @@
 
 namespace CGE2 {
 
-Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(NULL), _v(NULL), _map(0), _vm(vm) {
+Bitmap::Bitmap() : _w(0), _h(0), _v(NULL), _b(NULL) {
+}
+
+void Bitmap::setVM(CGE2Engine *vm) {
+	_vm = vm;
+}
+
+Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(NULL), _v(NULL), _b(NULL), _map(0), _vm(vm) {
 	char pat[kMaxPath];
 	forceExt(pat, fname, ".VBM");
 
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 82c3b07..102fb1c 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -66,12 +66,14 @@ public:
 	int32 _map;
 	HideDesc *_b;
 
+	Bitmap();
 	Bitmap(CGE2Engine *vm, const char *fname);
 	Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map);
 	Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill);
 	Bitmap(CGE2Engine *vm, const Bitmap &bmp);
 	~Bitmap();
 
+	void setVM(CGE2Engine *vm);
 	Bitmap *code();
 	Bitmap &operator=(const Bitmap &bmp);
 	void release();
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 3a6d1d2..0c28d4c 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -26,15 +26,185 @@
  */
 
 #include "cge2/hero.h"
+#include "cge2/text.h"
+#include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
-Hero::Hero(CGE2Engine *vm) : Sprite(vm) {
-	warning("STUB: Hero::Hero()");
+Hero::Hero(CGE2Engine *vm)
+	: Sprite(vm), _contact(nullptr), _dir(kNoDir),
+      _curDim(0), _tracePtr(-1), _ignoreMap(false) {
 }
 
-Sprite *Hero::expand(void) {
-	warning("STUB: Hero::expand()");
+Sprite *Hero::expand(void) { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
+	if (_ext)
+		return this;
+
+	char *text = _vm->_text->getText(_ref + 100);
+	char fname[kMaxPath];
+	_vm->mergeExt(fname, _file, kSprExt);
+	_ext = new SprExt(_vm);
+	if (_ext == nullptr)
+		error("No core %s", fname);
+
+	if (*_file) {
+		int cnt[kActions];
+		int shpcnt = 0;
+		int seqcnt = 0;
+		int maxnow = 0;
+		int maxnxt = 0;
+		Seq *seq;
+		int section = kIdPhase;
+
+		for (int i = 0; i < kDimMax; i++) {
+			_dim[i] = new Bitmap[_shpCnt];
+			for (int j = 0; j < _shpCnt; j++)
+				_dim[i][j].setVM(_vm);
+		}
+
+		if (_seqCnt) {
+			seq = new Seq[_seqCnt];
+			if (seq == nullptr)
+				error("No core %s", fname);
+		} else
+			seq = nullptr;
+
+		for (int i = 0; i < kActions; i++)
+			cnt[i] = 0;
+
+		for (int i = 0; i < kActions; i++) {
+			byte n = _actionCtrl[i]._cnt;
+			if (n) {
+				_ext->_actions[i] = new CommandHandler::Command[n];
+				if (_ext->_actions[i] == nullptr)
+					error("No core %s", fname);
+			} else
+				_ext->_actions[i] = nullptr;
+		}
+
+		if (_vm->_resman->exist(fname)) { // sprite description file exist
+			EncryptedStream sprf(_vm, fname);
+			if (sprf.err())
+				error("Bad SPR [%s]", fname);
+
+			ID id;
+			Common::String line;
+			char tmpStr[kLineMax + 1];
+
+			for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
+				if (line.size() == 0)
+					continue;
+				Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+
+				char *p = _vm->token(tmpStr);
+
+				id = _vm->ident(p);
+				switch (id) {
+				case kIdNear:
+				case kIdMTake:
+				case kIdFTake:
+				case kIdPhase:
+				case kIdSeq:
+					section = id;
+					break;
+				case kIdName:
+					Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+					for (p = tmpStr; *p != '='; p++); // We search for the =
+					setName(_vm->tail(p));
+					break;
+				default:
+					if (id >= kIdNear)
+						break;
+					Seq *s;
+					switch (section) {
+					case kIdNear:
+					case kIdMTake:
+					case kIdFTake:
+						id = (ID)_vm->_commandHandler->com(p);
+						if (_actionCtrl[section]._cnt) {
+							CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
+							c->_commandType = CommandType(id);
+							if ((p = _vm->token(nullptr)) == NULL)
+								error("Unexpected end of file! %s", fname);
+							c->_ref = _vm->number(p);
+							if ((p = _vm->token(nullptr)) == NULL)
+								error("Unexpected end of file! %s", fname);
+							c->_val = _vm->number(p);
+							c->_spritePtr = nullptr;
+						}
+						break;
+					case kIdSeq:
+						s = &seq[seqcnt++];
+						s->_now = atoi(p);
+						if (s->_now > maxnow)
+							maxnow = s->_now;
+						if ((p = _vm->token(nullptr)) == NULL)
+							break;
+						s->_next = _vm->number(p);
+						switch (s->_next) {
+						case 0xFF:
+							s->_next = seqcnt;
+							break;
+						case 0xFE:
+							s->_next = seqcnt - 1;
+							break;
+						}
+						if (s->_next > maxnxt)
+							maxnxt = s->_next;
+						if ((p = _vm->token(nullptr)) == NULL)
+							error("Unexpected end of file! %s", fname);
+						s->_dx = _vm->number(p);
+						if ((p = _vm->token(nullptr)) == NULL)
+							error("Unexpected end of file! %s", fname);
+						s->_dy = _vm->number(p);
+						if ((p = _vm->token(nullptr)) == NULL)
+							error("Unexpected end of file! %s", fname);
+						s->_dz = _vm->number(p);
+						if ((p = _vm->token(nullptr)) == NULL)
+							error("Unexpected end of file! %s", fname);
+						s->_dly = _vm->number(p);
+						break;
+					case kIdPhase:
+						for (int i = 0; i < kDimMax; i++) {
+							char *q = p;
+							q[1] = '0' + i;
+							Bitmap b(_vm, q);
+							if (!b.moveHi())
+								error("No EMS %s", q);
+							_dim[i][shpcnt] = b;
+							if (!shpcnt)
+								_hig[i] = b._h;
+						}
+						++shpcnt;
+						break;
+					}
+				}
+			}
+			if (seq) {
+				if (maxnow >= shpcnt)
+					error("Bad PHASE in SEQ %s", fname);
+				if (maxnxt >= seqcnt)
+					error("Bad JUMP in SEQ %s", fname);
+				setSeq(seq);
+			} else
+				setSeq(_stdSeq8);
+
+			BitmapPtr *bmp = new BitmapPtr[shpcnt];
+			for (int i = 0; i < shpcnt; i++)
+				bmp[i] = &_dim[0][i];
+			setShapeList(bmp, shpcnt);
+			delete[] bmp;
+		}
+	}
+	_reachStart = atoi(_vm->token(text));
+	_reachCycle = atoi(_vm->token(nullptr));
+	_sayStart = atoi(_vm->token(nullptr));
+	_funStart = atoi(_vm->token(nullptr));
+	_funDel = _funDel0 = (72 / _ext->_seq[0]._dly) * atoi(_vm->token(nullptr));
+	int i = stepSize() / 2;
+	_maxDist = sqrt(double(i * i * 2));
+	setCurrent();
+	
 	return this;
 }
 
@@ -143,4 +313,21 @@ void Hero::setCave(int c) {
 	warning("STUB: Hero::mapCross()");
 }
 
+bool Sprite::works(Sprite *spr) {
+	//if (!spr || !spr->_ext)
+	//	return false;
+
+	//CommandHandler::Command *c = spr->_ext->_take;
+	//if (c != NULL) {
+	//	c += spr->_takePtr;
+	//	if (c->_ref == _ref)
+	//		if (c->_commandType != kCmdLabel || (c->_val == 0 || c->_val == _vm->_now))
+	//			return true;
+	//}
+
+	warning("STUB: Sprite::works()");
+
+	return false;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 032a46d..9723be8 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -96,8 +96,8 @@ public:
 	void reach(int mode);
 	void setCurrent(void);
 	void setCave(int c);
-	void operator ++ (void);
-	void operator -- (void);
+	void operator++(void);
+	void operator--(void);
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 8158d6d..e4b7dbf 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -144,23 +144,6 @@ void Sprite::setShapeList(BitmapPtr *shp, int cnt) {
 	}
 }
 
-bool Sprite::works(Sprite *spr) {
-	//if (!spr || !spr->_ext)
-	//	return false;
-
-	//CommandHandler::Command *c = spr->_ext->_take;
-	//if (c != NULL) {
-	//	c += spr->_takePtr;
-	//	if (c->_ref == _ref)
-	//		if (c->_commandType != kCmdLabel || (c->_val == 0 || c->_val == _vm->_now))
-	//			return true;
-	//}
-
-	warning("STUB: Sprite::works()");
-
-	return false;
-}
-
 Seq *Sprite::setSeq(Seq *seq) {
 	expand();
 
@@ -264,7 +247,7 @@ Sprite *Sprite::expand() {
 		Common::String line;
 		char tmpStr[kLineMax + 1];
 
-		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
+		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
 			if (line.size() == 0)
 				continue;
 			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));


Commit: 219f4f6695af35d139b32a3daf5371e19d70c71c
    https://github.com/scummvm/scummvm/commit/219f4f6695af35d139b32a3daf5371e19d70c71c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T13:43:28+02:00

Commit Message:
CGE2: Implement Hero::setCurrent().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 0c28d4c..5a6e437 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -209,7 +209,16 @@ Sprite *Hero::expand(void) { // It's very similar to Sprite's expand, but doesn'
 }
 
 void Hero::setCurrent(void) {
-	warning("STUB: Hero::setCurrent()");
+	double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
+	int h = -(V2D::trunc(m * _siz.y));
+
+	int i = 0;
+	for (; i < kDimMax; i++) {
+		if (h >= (_hig[i] + _hig[i + 1]) / 2)
+			break;
+	}
+
+	_ext->_shpList = &_dim[_curDim = i];
 }
 
 void Hero::hStep(void) {


Commit: 562644db48a894bff55eeef03f89ce3b1ecc4c51
    https://github.com/scummvm/scummvm/commit/562644db48a894bff55eeef03f89ce3b1ecc4c51
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T13:50:47+02:00

Commit Message:
CGE2: Remove unnecessary void parameters in Hero.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 5a6e437..151b3da 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -36,7 +36,7 @@ Hero::Hero(CGE2Engine *vm)
       _curDim(0), _tracePtr(-1), _ignoreMap(false) {
 }
 
-Sprite *Hero::expand(void) { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
+Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
 	if (_ext)
 		return this;
 
@@ -208,7 +208,7 @@ Sprite *Hero::expand(void) { // It's very similar to Sprite's expand, but doesn'
 	return this;
 }
 
-void Hero::setCurrent(void) {
+void Hero::setCurrent() {
 	double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
 	int h = -(V2D::trunc(m * _siz.y));
 
@@ -221,16 +221,16 @@ void Hero::setCurrent(void) {
 	_ext->_shpList = &_dim[_curDim = i];
 }
 
-void Hero::hStep(void) {
+void Hero::hStep() {
 	warning("STUB: Hero::hStep()");
 }
 
-Sprite *Hero::setContact(void) {
+Sprite *Hero::setContact() {
 	warning("STUB: Hero::setContact()");
 	return this;
 }
 
-void Hero::tick(void) {
+void Hero::tick() {
 	warning("STUB: Hero::tick()");
 }
 
@@ -248,7 +248,7 @@ void Hero::turn(Dir d) {
 	warning("STUB: Hero::turn()");
 }
 
-void Hero::park(void) {
+void Hero::park() {
 	warning("STUB: Hero::park()");
 }
 
@@ -261,15 +261,15 @@ void Hero::reach(int mode) {
 	warning("STUB: Hero::reach()");
 }
 
-void Hero::fun(void) {
+void Hero::fun() {
 	warning("STUB: Hero::fun()");
 }
 
-void Hero::operator ++ (void) {
+void Hero::operator ++ () {
 	warning("STUB: Hero::operator ++()");
 }
 
-void Hero::operator -- (void) {
+void Hero::operator -- () {
 	warning("STUB: Hero::operator --()");
 }
 
@@ -278,7 +278,7 @@ uint32 Hero::len(V2D v) {
 	return 0;
 }
 
-bool Hero::findWay(void){
+bool Hero::findWay(){
 	warning("STUB: Hero::findWay()");
 	return false;
 }
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 9723be8..8face03 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -67,37 +67,37 @@ public:
 	int _maxDist;
 	bool _ignoreMap;
 	Hero(CGE2Engine *vm);
-	void tick(void);
-	Sprite *expand(void);
-	Sprite *contract(void) { return this; }
-	Sprite *setContact(void);
-	int stepSize(void) { return _ext->_seq[7]._dx; }
+	void tick();
+	Sprite *expand();
+	Sprite *contract() { return this; }
+	Sprite *setContact();
+	int stepSize() { return _ext->_seq[7]._dx; }
 	int distance(V3D pos);
 	int distance(Sprite * spr);
 	void turn(Dir d);
-	void park(void);
+	void park();
 	static uint32 len(V2D v);
-	bool findWay(void);
+	bool findWay();
 	static int snap(int p, int q, int grid);
 	void walkTo(V3D pos);
 	void walkTo(V2D pos) { walkTo(screenToGround(pos)); }
 	V3D screenToGround(V2D pos);
 	void walkTo(Sprite *spr);
-	void say(void) { step(_sayStart); }
-	void fun(void);
-	void resetFun(void) { _funDel = _funDel0; }
-	void hStep(void);
+	void say() { step(_sayStart); }
+	void fun();
+	void resetFun() { _funDel = _funDel0; }
+	void hStep();
 	bool lower(Sprite * spr);
 	int cross(const V2D &a, const V2D &b);
 	int mapCross(const V2D &a, const V2D &b);
 	int mapCross(const V3D &a, const V3D &b);
-	Hero *other(void) { return _vm->_heroTab[!(_ref & 1)]->_ptr;}
-	Action action(void) { return (Action)(_ref % 10); }
+	Hero *other() { return _vm->_heroTab[!(_ref & 1)]->_ptr;}
+	Action action() { return (Action)(_ref % 10); }
 	void reach(int mode);
-	void setCurrent(void);
+	void setCurrent();
 	void setCave(int c);
-	void operator++(void);
-	void operator--(void);
+	void operator++();
+	void operator--();
 };
 
 } // End of namespace CGE2


Commit: 79ef03801d90064291aaa4709c8560c9c98cf5b7
    https://github.com/scummvm/scummvm/commit/79ef03801d90064291aaa4709c8560c9c98cf5b7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T13:58:52+02:00

Commit Message:
CGE2: Implement CGE2Eninge::switchHero().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e9fc11b..1ca99bd 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -755,7 +755,21 @@ void CGE2Engine::killText() {
 }
 
 void CGE2Engine::switchHero(bool sex) {
-	warning("STUB: CGE2Engine::switchHero()");
+	if (sex != _sex) {
+		int scene = _heroTab[sex]->_ptr->_scene;
+		if (_blinkSprite) {
+			_blinkSprite->_flags._hide = false;
+			_blinkSprite = nullptr;
+		}
+		if (scene >= 0) {
+			_commandHandler->addCommand(kCmdSeq, -1, 2, _heroTab[_sex]->_face);
+			_sex = !_sex;
+			switchCave(scene);
+		}
+	}
+	Sprite *face = _heroTab[_sex]->_face;
+	if (face->_seqPtr == 0)
+		_commandHandler->addCommand(kCmdSeq, -1, 1, face);
 }
 
 Sprite *CGE2Engine::spriteAt(int x, int y) {


Commit: 0e62716038ec5ba108cbc272b1b06b49a608b11b
    https://github.com/scummvm/scummvm/commit/0e62716038ec5ba108cbc272b1b06b49a608b11b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T14:33:30+02:00

Commit Message:
CGE2: Add and use Spare::take().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 1ca99bd..5328361 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -399,7 +399,7 @@ void CGE2Engine::switchCave(int cav) {
 }
 
 void CGE2Engine::showBak(int ref) {
-	Sprite *spr = _spare->locate(ref);
+	Sprite *spr = _spare->take(ref);
 	if (spr != nullptr) {
 		_bitmapPalette = _vga->_sysPal;
 		spr->expand();
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index be2fc64..0431221 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -45,6 +45,19 @@ Sprite *Spare::locate(int ref) {
 	return nullptr;
 }
 
+Sprite *Spare::take(int ref) {
+	Sprite *spr = nullptr;
+	if ((spr = locate(ref)) != nullptr) {
+		for (uint i = 0; i < _container.size(); ++i) {
+			if (spr == _container[i]) {
+				_container.remove_at(i);
+				break;
+			}
+		}
+	}
+	return spr;
+}
+
 void Spare::takeCave(int cav) {
 	int bakRef = cav << 8;
 	Common::Array<Sprite*> tempCont = _container;
@@ -52,6 +65,7 @@ void Spare::takeCave(int cav) {
 		Sprite *spr = tempCont[i];
 		int c = spr->_scene;
 		if ((c == _vm->_now || c == 0) && spr->_ref != bakRef) {
+			spr = take(spr->_ref);
 			_vm->_vga->_showQ->insert(spr);
 		}
 	}
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 7bd520d..1890922 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -40,6 +40,7 @@ public:
 	~Spare() { clear(); }
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
+	Sprite *take(int ref);
 	void takeCave(int cav);
 	void update(Sprite *spr);
 	void dispose(Sprite *spr);


Commit: 21513b448fe7061ffa0c0ed92465386ffacfb3b6
    https://github.com/scummvm/scummvm/commit/21513b448fe7061ffa0c0ed92465386ffacfb3b6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T14:37:41+02:00

Commit Message:
CGE2: Partially implement and use loadGame().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 925cb67..b51ae27 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -112,6 +112,7 @@ public:
 	void inf(const char *text, bool wideSpace = false);
 	void movie(const char *ext);
 	void runGame();
+	void loadGame();
 	void loadScript(const char *fname);
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 5328361..78d7435 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -561,9 +561,50 @@ void CGE2Engine::loadUser() {
 	warning("STUB: CGE2Engine::loadUser()");
 	// Missing loading from file. TODO: Implement it with the saving/loading!
 	loadScript("CGE.INI");
+	loadGame();
 	loadPos();
 }
 
+void CGE2Engine::loadGame() {
+	warning("STUB: CGE2Engine::loadGame()");
+
+	// load sprites & pocket
+	
+	Sprite *s;
+	Hero *h;
+	
+	// initialize Andzia
+	s = _spare->take(142);
+	if (s) {
+		h = new Hero(this);
+		*(Sprite*)h = *s;
+		delete s;
+		h->expand();
+		_spare->update(h);
+	}
+	_heroTab[0]->_ptr = h;
+	s = _spare->take(152);
+	_vga->_showQ->insert(s);
+	_heroTab[0]->_face = s;
+
+	// initialize Wacek
+	s = _spare->take(141);
+	if (s) {
+		h = new Hero(this);
+		*(Sprite*)h = *s;
+		delete s;
+		h->expand();
+		_spare->update(h);
+	}
+	_heroTab[1]->_ptr = h;
+	s = _spare->take(151);
+	_vga->_showQ->insert(s);
+	_heroTab[1]->_face = s;
+
+	//--- start!
+	switchHero(_sex);
+}
+
 void CGE2Engine::loadPos() {
 	if (_resman->exist("CGE.HXY")) {
 		for (int cav = 0; cav < kCaveMax; cav++)


Commit: 87db3d2d750c3c609ded7576f14e35a22f96f849
    https://github.com/scummvm/scummvm/commit/87db3d2d750c3c609ded7576f14e35a22f96f849
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T14:38:40+02:00

Commit Message:
CGE2: Add _blinkSprite.

This also fixes previously broken compilation in 79ef038.

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



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index c4ae027..f616a60 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -69,6 +69,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	for (int i = 0; i < 2; i++)
 		_vol[i] = nullptr;
 	_eventManager = nullptr;
+	_blinkSprite = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -143,6 +144,8 @@ void CGE2Engine::deinit() {
 	}
 	delete _sys;
 	delete _eventManager;
+	if (_blinkSprite != nullptr)
+		delete _blinkSprite;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index b51ae27..09e1e0f 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -238,6 +238,7 @@ public:
 	Sprite *_busyPtr;
 	Sprite *_vol[2];
 	EventManager *_eventManager;
+	Sprite *_blinkSprite;
 private:
 	void init();
 	void deinit();


Commit: 6d73870431d0a713520f09d7d8eb4f4512651f23
    https://github.com/scummvm/scummvm/commit/6d73870431d0a713520f09d7d8eb4f4512651f23
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-02T14:46:59+02:00

Commit Message:
CGE2: Move then implement Sprite::touch().

Also add stubs for called functions.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 09e1e0f..69f8b75 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -141,6 +141,8 @@ public:
 	void loadPos();
 	void releasePocket(Sprite *spr);
 	void switchHero(bool sex);
+	void optionTouch(int opt, uint16 mask);
+	void offUse();
 
 	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 78d7435..cec22f2 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -826,4 +826,89 @@ Sprite *CGE2Engine::spriteAt(int x, int y) {
 	return spr;
 }
 
+#pragma argsused
+void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
+	if ((mask & kEventAttn) != 0)
+		return;
+
+	if (!_vm->_startupMode)
+		_vm->_infoLine->setText(name());
+
+	if (_ref < 0)
+		return; // cannot access system sprites
+
+	if (_ref / 10 == 12) {
+		_vm->optionTouch(_ref % 10, mask);
+		return;
+	}
+
+	if (_vm->isHero(this) && !_vm->_blinkSprite) {
+		_vm->switchHero(this == _vm->_heroTab[1]->_ptr);
+	} else { // not HERO || sprite from pocket ready to use
+		if (_flags._kept) { // sprite in pocket
+			for (int sex = 0; sex < 2; sex++) {
+				for (int p = 0; p < kPocketMax; p++) {
+					if (_vm->_heroTab[sex]->_pocket[p] == this) {
+						_vm->switchHero(sex);
+						if (_vm->_sex == sex) {
+							if (_vm->_blinkSprite)
+								_vm->_blinkSprite->_flags._hide = false;
+							if (_vm->_blinkSprite == this)
+								_vm->_blinkSprite = nullptr;
+							else
+								_vm->_blinkSprite = this;
+						}
+					}
+				}
+			}
+		} else { // sprite NOT in pocket
+			Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
+			if (!_vm->_talk) {
+				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1)) h->walkTo(this);
+				else {
+					if (_vm->_blinkSprite) {
+						if (works(_vm->_blinkSprite)) {
+							_vm->feedSnail(_vm->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
+							_vm->_blinkSprite->_flags._hide = false;
+							_vm->_blinkSprite = nullptr;
+						} else
+							_vm->offUse();
+
+						_vm->selectPocket(-1);
+					} else { // no pocket sprite selected
+						if (_flags._port) { // portable
+							if (_vm->findActivePocket(-1) < 0)
+								_vm->pocFul();
+							else {
+								_vm->_commandHandler->addCommand(kCmdReach, -2, _ref, nullptr);
+								_vm->_commandHandler->addCommand(kCmdKeep, -1, -1, this);
+								_flags._port = false;
+							}
+						} else { // non-portable
+							Action a = h->action();
+							if (_actionCtrl[a]._cnt) {
+								CommandHandler::Command *cmdList = snList(a);
+								if (cmdList[_actionCtrl[a]._ptr]._commandType == kCmdNext)
+									_vm->offUse();
+								else
+									_vm->feedSnail(this, a, h);
+							} else
+								_vm->offUse();
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+void CGE2Engine::optionTouch(int opt, uint16 mask) {
+	warning("STUB: CGE2Engine::optionTouch()");
+}
+
+void CGE2Engine::offUse() {
+	warning("STUB: CGE2Engine::offUse()");
+}
+
+
 } // End of namespace CGE2
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index e4b7dbf..cfcf25f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -455,11 +455,6 @@ void Sprite::step(int nr) {
 		_vm->_waitRef = 0;
 }
 
-#pragma argsused
-void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
-	warning("STUB: Sprite::touch()");
-}
-
 void Sprite::tick() {
 	step();
 }


Commit: 5d9e31c708849ef495e07da9271e1039d177a0d4
    https://github.com/scummvm/scummvm/commit/5d9e31c708849ef495e07da9271e1039d177a0d4
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T07:12:49+02:00

Commit Message:
CGE2: Fix rounding error, remove (original) debug code

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index cfcf25f..fb21999 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -528,9 +528,9 @@ void Sprite::gotoxyz(V2D pos) {
 
 	if (!_follow) {
 		double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
-		_pos3D._x = (_vm->_eye->_x + V2D::round(_vm->_eye->_x - _pos2D.x) / m);
+		_pos3D._x = V2D::round(_vm->_eye->_x + (_vm->_eye->_x - _pos2D.x) / m);
 		if (!_constY)
-			_pos3D._y = (_vm->_eye->_y + V2D::round(_vm->_eye->_y - _pos2D.y) / m);
+			_pos3D._y = V2D::round(_vm->_eye->_y + (_vm->_eye->_y - _pos2D.y) / m);
 	}
 
 	if (_next && _next->_flags._slav)
@@ -538,9 +538,6 @@ void Sprite::gotoxyz(V2D pos) {
 
 	if (_flags._shad)
 		_prev->gotoxyz(_prev->_pos2D - o + _pos2D);
-
-	if (_ref == 141 && _pos3D._y >= 5)
-		warning("Sprite::gotoxyz - asm nop");
 }
 
 void Sprite::gotoxyz_(V2D pos) {


Commit: 41f9195f5608df90ab08f397678f064d4e785b5b
    https://github.com/scummvm/scummvm/commit/41f9195f5608df90ab08f397678f064d4e785b5b
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T07:28:33+02:00

Commit Message:
CGE2: Fix flags synchronization

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index fb21999..ff58ccd 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -616,43 +616,41 @@ void Sprite::sync(Common::Serializer &s) {
 	if (s.isLoading()) {
 		s.syncAsUint16LE(flags);
 		_flags._hide = flags & 0x0001 ? true : false;
-		_flags._near = flags & 0x0002 ? true : false;
-		_flags._drag = flags & 0x0004 ? true : false;
-		_flags._hold = flags & 0x0008 ? true : false;
-		//_flags._dummy = flags & 0x0010 ? true : false;
-		_flags._slav = flags & 0x0020 ? true : false;
-		//_flags._syst = flags & 0x0040 ? true : false;
-		_flags._kill = flags & 0x0080 ? true : false;
-		_flags._xlat = flags & 0x0100 ? true : false;
-		_flags._port = flags & 0x0200 ? true : false;
-		_flags._kept = flags & 0x0400 ? true : false;
-		_flags._east = flags & 0x0800 ? true : false;
+		_flags._drag = flags & 0x0002 ? true : false;
+		_flags._hold = flags & 0x0004 ? true : false;
+		_flags._trim = flags & 0x0008 ? true : false;
+		_flags._slav = flags & 0x0010 ? true : false;
+		_flags._kill = flags & 0x0020 ? true : false;
+		_flags._xlat = flags & 0x0040 ? true : false;
+		_flags._port = flags & 0x0080 ? true : false;
+		_flags._kept = flags & 0x0100 ? true : false;
+		_flags._frnt = flags & 0x0200 ? true : false;
+		_flags._east = flags & 0x0400 ? true : false;
+		_flags._near = flags & 0x0800 ? true : false;
 		_flags._shad = flags & 0x1000 ? true : false;
 		_flags._back = flags & 0x2000 ? true : false;
-		//_flags._bDel = flags & 0x4000 ? true : false;
+		_flags._zmov = flags & 0x4000 ? true : false;
 		_flags._tran = flags & 0x8000 ? true : false;
 	} else {
 		flags = (flags << 1) | _flags._tran;
-		//flags = (flags << 1) | _flags._bDel;
+		flags = (flags << 1) | _flags._zmov;
 		flags = (flags << 1) | _flags._back;
 		flags = (flags << 1) | _flags._shad;
+		flags = (flags << 1) | _flags._near;
 		flags = (flags << 1) | _flags._east;
+		flags = (flags << 1) | _flags._frnt;
 		flags = (flags << 1) | _flags._kept;
 		flags = (flags << 1) | _flags._port;
 		flags = (flags << 1) | _flags._xlat;
 		flags = (flags << 1) | _flags._kill;
-		//flags = (flags << 1) | _flags._syst;
 		flags = (flags << 1) | _flags._slav;
-		//flags = (flags << 1) | _flags._dummy;
+		flags = (flags << 1) | _flags._trim;
 		flags = (flags << 1) | _flags._hold;
 		flags = (flags << 1) | _flags._drag;
-		flags = (flags << 1) | _flags._near;
 		flags = (flags << 1) | _flags._hide;
 		s.syncAsUint16LE(flags);
 	}
 
-	warning("STUB: Sprite::sync() - Flags changed compared to CGE1's Sprite type.");
-
 	s.syncAsUint16LE(_pos3D._x);
 	s.syncAsUint16LE(_pos3D._y);
 	s.syncAsByte(_pos3D._z);


Commit: 46d93eb780621392b563995c5c72ffb398e6206e
    https://github.com/scummvm/scummvm/commit/46d93eb780621392b563995c5c72ffb398e6206e
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T07:35:21+02:00

Commit Message:
CGE2: Rework style in touch()

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index cec22f2..64f39a3 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -844,59 +844,55 @@ void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
 
 	if (_vm->isHero(this) && !_vm->_blinkSprite) {
 		_vm->switchHero(this == _vm->_heroTab[1]->_ptr);
-	} else { // not HERO || sprite from pocket ready to use
-		if (_flags._kept) { // sprite in pocket
-			for (int sex = 0; sex < 2; sex++) {
-				for (int p = 0; p < kPocketMax; p++) {
-					if (_vm->_heroTab[sex]->_pocket[p] == this) {
-						_vm->switchHero(sex);
-						if (_vm->_sex == sex) {
-							if (_vm->_blinkSprite)
-								_vm->_blinkSprite->_flags._hide = false;
-							if (_vm->_blinkSprite == this)
-								_vm->_blinkSprite = nullptr;
-							else
-								_vm->_blinkSprite = this;
-						}
+	} else if (_flags._kept) { // sprite in pocket
+		for (int sex = 0; sex < 2; sex++) {
+			for (int p = 0; p < kPocketMax; p++) {
+				if (_vm->_heroTab[sex]->_pocket[p] == this) {
+					_vm->switchHero(sex);
+					if (_vm->_sex == sex) {
+						if (_vm->_blinkSprite)
+							_vm->_blinkSprite->_flags._hide = false;
+						if (_vm->_blinkSprite == this)
+							_vm->_blinkSprite = nullptr;
+						else
+							_vm->_blinkSprite = this;
 					}
 				}
 			}
-		} else { // sprite NOT in pocket
-			Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
-			if (!_vm->_talk) {
-				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1)) h->walkTo(this);
+		}
+	} else { // sprite NOT in pocket
+		Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
+		if (!_vm->_talk) {
+			if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1))
+				h->walkTo(this);
+			else if (_vm->_blinkSprite) {
+				if (works(_vm->_blinkSprite)) {
+					_vm->feedSnail(_vm->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
+					_vm->_blinkSprite->_flags._hide = false;
+					_vm->_blinkSprite = nullptr;
+				} else
+					_vm->offUse();
+
+				_vm->selectPocket(-1);
+			// else, no pocket sprite selected
+			} else if (_flags._port) { // portable
+				if (_vm->findActivePocket(-1) < 0)
+					_vm->pocFul();
 				else {
-					if (_vm->_blinkSprite) {
-						if (works(_vm->_blinkSprite)) {
-							_vm->feedSnail(_vm->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
-							_vm->_blinkSprite->_flags._hide = false;
-							_vm->_blinkSprite = nullptr;
-						} else
-							_vm->offUse();
-
-						_vm->selectPocket(-1);
-					} else { // no pocket sprite selected
-						if (_flags._port) { // portable
-							if (_vm->findActivePocket(-1) < 0)
-								_vm->pocFul();
-							else {
-								_vm->_commandHandler->addCommand(kCmdReach, -2, _ref, nullptr);
-								_vm->_commandHandler->addCommand(kCmdKeep, -1, -1, this);
-								_flags._port = false;
-							}
-						} else { // non-portable
-							Action a = h->action();
-							if (_actionCtrl[a]._cnt) {
-								CommandHandler::Command *cmdList = snList(a);
-								if (cmdList[_actionCtrl[a]._ptr]._commandType == kCmdNext)
-									_vm->offUse();
-								else
-									_vm->feedSnail(this, a, h);
-							} else
-								_vm->offUse();
-						}
-					}
+					_vm->_commandHandler->addCommand(kCmdReach, -2, _ref, nullptr);
+					_vm->_commandHandler->addCommand(kCmdKeep, -1, -1, this);
+					_flags._port = false;
 				}
+			} else { // non-portable
+				Action a = h->action();
+				if (_actionCtrl[a]._cnt) {
+					CommandHandler::Command *cmdList = snList(a);
+					if (cmdList[_actionCtrl[a]._ptr]._commandType == kCmdNext)
+						_vm->offUse();
+					else
+						_vm->feedSnail(this, a, h);
+				} else
+					_vm->offUse();
 			}
 		}
 	}


Commit: 7ef509608e957cb62cda7265e173f1a30a69b659
    https://github.com/scummvm/scummvm/commit/7ef509608e957cb62cda7265e173f1a30a69b659
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T07:42:17+02:00

Commit Message:
CGE2: USe an int for sex instead of a boolean

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index f616a60..4bac09a 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -77,7 +77,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_music = true;
 	_startupMode = 1;
 	_now = 1;
-	_sex = true;
+	_sex = 1;
 	_mouseTop = kWorldHeight / 3;
 	_dark = false;
 	_lastFrame = 0;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 69f8b75..2c34b0a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -140,7 +140,7 @@ public:
 	void qGame();
 	void loadPos();
 	void releasePocket(Sprite *spr);
-	void switchHero(bool sex);
+	void switchHero(int sex);
 	void optionTouch(int opt, uint16 mask);
 	void offUse();
 
@@ -205,7 +205,7 @@ public:
 	bool _music;
 	int _startupMode;
 	int _now;
-	bool _sex;
+	int _sex;
 	int _mouseTop;
 	bool _dark;
 	int _waitSeq;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 64f39a3..e379977 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -573,7 +573,7 @@ void CGE2Engine::loadGame() {
 	Sprite *s;
 	Hero *h;
 	
-	// initialize Andzia
+	// initialize Andzia/Anna
 	s = _spare->take(142);
 	if (s) {
 		h = new Hero(this);
@@ -587,7 +587,7 @@ void CGE2Engine::loadGame() {
 	_vga->_showQ->insert(s);
 	_heroTab[0]->_face = s;
 
-	// initialize Wacek
+	// initialize Wacek/Vincent
 	s = _spare->take(141);
 	if (s) {
 		h = new Hero(this);
@@ -795,7 +795,7 @@ void CGE2Engine::killText() {
 	_talk = NULL;
 }
 
-void CGE2Engine::switchHero(bool sex) {
+void CGE2Engine::switchHero(int sex) {
 	if (sex != _sex) {
 		int scene = _heroTab[sex]->_ptr->_scene;
 		if (_blinkSprite) {
@@ -804,7 +804,7 @@ void CGE2Engine::switchHero(bool sex) {
 		}
 		if (scene >= 0) {
 			_commandHandler->addCommand(kCmdSeq, -1, 2, _heroTab[_sex]->_face);
-			_sex = !_sex;
+			_sex ^= 1;
 			switchCave(scene);
 		}
 	}
@@ -843,10 +843,10 @@ void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
 	}
 
 	if (_vm->isHero(this) && !_vm->_blinkSprite) {
-		_vm->switchHero(this == _vm->_heroTab[1]->_ptr);
+		_vm->switchHero((this == _vm->_heroTab[1]->_ptr) ? 1 : 0);
 	} else if (_flags._kept) { // sprite in pocket
-		for (int sex = 0; sex < 2; sex++) {
-			for (int p = 0; p < kPocketMax; p++) {
+		for (int sex = 0; sex < 2; ++sex) {
+			for (int p = 0; p < kPocketMax; ++p) {
 				if (_vm->_heroTab[sex]->_pocket[p] == this) {
 					_vm->switchHero(sex);
 					if (_vm->_sex == sex) {


Commit: de8affdec579542767cfd827f2dd19a035319d65
    https://github.com/scummvm/scummvm/commit/de8affdec579542767cfd827f2dd19a035319d65
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T17:39:10+02:00

Commit Message:
CGE2: Silence some gcc warnings

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp
    engines/cge2/snail.cpp
    engines/cge2/snail.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e379977..4fb0b29 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -179,7 +179,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 				case kIdNear:
 				case kIdMTake:
 				case kIdFTake:
-					if (_commandHandler->com(p) >= 0)
+					if (_commandHandler->getComId(p) >= 0)
 						++cnt[section];
 					else
 						error("Bad line %d [%s]", sprf.getLineCount(), tmpStr);
@@ -818,7 +818,7 @@ Sprite *CGE2Engine::spriteAt(int x, int y) {
 	if (tail) {
 		for (spr = tail->_prev; spr; spr = spr->_prev) {
 			if (!spr->_flags._hide && !spr->_flags._tran) {
-				if (spr->shp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y))
+				if (spr->getShp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y))
 					break;
 			}
 		}
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 151b3da..a6c1849 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -120,7 +120,7 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 					case kIdNear:
 					case kIdMTake:
 					case kIdFTake:
-						id = (ID)_vm->_commandHandler->com(p);
+						id = (ID)_vm->_commandHandler->getComId(p);
 						if (_actionCtrl[section]._cnt) {
 							CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
 							c->_commandType = CommandType(id);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index f00b02c..e355c44 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -569,7 +569,7 @@ void CommandHandler::clear() {
 	_timerExpiry = 0;
 }
 
-int CommandHandler::com(const char *com) {
+int CommandHandler::getComId(const char *com) {
 	int i = _vm->takeEnum(_commandText, com);
 	return (i < 0) ? i : i + kCmdCom0 + 1;
 }
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index afd52df..6b0bdea 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -136,7 +136,7 @@ public:
 	bool idle();
 	void reset();
 	void clear();
-	int com(const char *com);
+	int getComId(const char *com);
 private:
 	CGE2Engine *_vm;
 	bool _turbo;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index ff58ccd..bc2e07c 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -111,7 +111,7 @@ Sprite::~Sprite() {
 	contract();
 }
 
-BitmapPtr Sprite::shp() {
+BitmapPtr Sprite::getShp() {
 	SprExt *e = _ext;
 	if (!e || !e->_seq)
 		return NULL;
@@ -282,7 +282,7 @@ Sprite *Sprite::expand() {
 				case kIdNear:
 				case kIdMTake:
 				case kIdFTake:
-					id = (ID)_vm->_commandHandler->com(p);
+					id = (ID)_vm->_commandHandler->getComId(p);
 					if (_actionCtrl[section]._cnt) {
 						CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
 						c->_commandType = CommandType(id);
@@ -327,7 +327,7 @@ Sprite *Sprite::expand() {
 						error("Unexpected end of file! %s", fname);
 					s->_dly = _vm->number(p);
 					break;
-				case kIdPhase:
+				case kIdPhase: {
 					BitmapPtr bmp = new Bitmap(_vm, p);
 					shplist[shpcnt] = bmp;
 					if (!shplist[shpcnt]->moveHi())
@@ -335,6 +335,9 @@ Sprite *Sprite::expand() {
 					shpcnt++;
 					break;
 				}
+				default:
+					break;
+				}
 				break;
 			}
 			label = kNoByte;
@@ -382,10 +385,10 @@ Sprite *Sprite::contract() {
 		return this;
 
 	if (_file[2] == '~') { // FLY-type sprite
-		Seq *seq = _ext->_seq;
+		Seq *curSeq = _ext->_seq;
 		// return to middle
-		gotoxyz(_pos3D - V3D(seq->_dx, seq->_dy, seq->_dz));
-		seq->_dx = seq->_dy = seq->_dz = 0;
+		gotoxyz(_pos3D - V3D(curSeq->_dx, curSeq->_dy, curSeq->_dz));
+		curSeq->_dx = curSeq->_dy = curSeq->_dz = 0;
 	}
 
 	if (notify)
@@ -564,7 +567,7 @@ void Sprite::show() {
 		e->_p0 = e->_p1;
 		e->_b0 = e->_b1;
 		e->_p1 = _pos2D;
-		e->_b1 = shp();
+		e->_b1 = getShp();
 	}
 	if (!_flags._hide)
 		e->_b1->show(e->_p1.x, e->_p1.y);
@@ -573,7 +576,7 @@ void Sprite::show() {
 void Sprite::show(uint16 pg) {
 	Graphics::Surface *a = _vm->_vga->_page[1];
 	_vm->_vga->_page[1] = _vm->_vga->_page[pg];
-	shp()->show(_pos2D.x, _pos2D.y);
+	getShp()->show(_pos2D.x, _pos2D.y);
 	_vm->_vga->_page[1] = a;
 }
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index a4829b6..574a607 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -73,8 +73,8 @@ class V2D : public Common::Point {
 public:
 	V2D& operator=(const V3D &p3) {
 		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
-		x = round((_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m));
-		y = round((_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m));
+		x = round(_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m);
+		y = round(_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m);
 		return *this;
 	}
 	V2D(CGE2Engine *vm) : _vm(vm) { }
@@ -170,7 +170,7 @@ public:
 	Sprite(CGE2Engine *vm);
 	Sprite(CGE2Engine *vm, BitmapPtr *shp, int cnt);
 	virtual ~Sprite();
-	BitmapPtr shp();
+	BitmapPtr getShp();
 	void setShapeList(BitmapPtr *shp, int cnt);
 	void moveShapesHi(void);
 	void moveShapesLo(void);


Commit: 11ebdcb5e0f25a6030a3ee3419d823aef6622980
    https://github.com/scummvm/scummvm/commit/11ebdcb5e0f25a6030a3ee3419d823aef6622980
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T20:18:48+02:00

Commit Message:
CGE2: nullify some pointers

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp
    engines/cge2/snail.cpp
    engines/cge2/sound.cpp
    engines/cge2/spare.cpp
    engines/cge2/text.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index dfc5bca..3988360 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -124,6 +124,8 @@ Bitmap::~Bitmap() {
 void Bitmap::release() {
 	free(_m);
 	delete[] _v;
+	_m = nullptr;
+	_v = nullptr;
 }
 
 Bitmap &Bitmap::operator=(const Bitmap &bmp) {
@@ -137,6 +139,7 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 	_map = 0;
 	_vm = bmp._vm;
 	delete[] _v;
+	_v = nullptr;
 
 	if (v0 == NULL) {
 		_v = NULL;
@@ -169,7 +172,7 @@ BitmapPtr Bitmap::code() {
 
 	if (_v) {                                        // old X-map exists, so remove it
 		delete[] _v;
-		_v = NULL;
+		_v = nullptr;
 	}
 
 	while (true) {                                  // at most 2 times: for (V == NULL) & for allocated block;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 4fb0b29..696b840 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -579,6 +579,7 @@ void CGE2Engine::loadGame() {
 		h = new Hero(this);
 		*(Sprite*)h = *s;
 		delete s;
+		s = nullptr;
 		h->expand();
 		_spare->update(h);
 	}
@@ -593,6 +594,7 @@ void CGE2Engine::loadGame() {
 		h = new Hero(this);
 		*(Sprite*)h = *s;
 		delete s;
+		s = nullptr;
 		h->expand();
 		_spare->update(h);
 	}
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index a6c1849..030020e 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -194,6 +194,7 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 				bmp[i] = &_dim[0][i];
 			setShapeList(bmp, shpcnt);
 			delete[] bmp;
+			bmp = nullptr;
 		}
 	}
 	_reachStart = atoi(_vm->token(text));
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index e355c44..8de2e13 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -527,6 +527,7 @@ void CGE2Engine::snGhost(Bitmap *bmp) {
 	bmp->_v = nullptr;
 	bmp->_b = nullptr;
 	delete bmp;
+	bmp = nullptr;
 }
 
 void CGE2Engine::hide1(Sprite *spr) {
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index 9f5ec2b..b497ebf 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -121,7 +121,7 @@ Fx::~Fx() {
 void Fx::clear() {
 	if (_current)
 		delete _current;
-	_current = NULL;
+	_current = nullptr;
 }
 
 Common::String Fx::name(int ref, int sub) {
@@ -186,7 +186,7 @@ void MusicPlayer::killMidi() {
 	Audio::MidiPlayer::stop();
 
 	free(_data);
-	_data = NULL;
+	_data = nullptr;
 }
 
 void MusicPlayer::loadMidi(int ref) {
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 0431221..4452471 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -90,6 +90,7 @@ void Spare::dispose(Sprite *spr) {
 				if (spr == _container[i]) {
 					_container.remove_at(i);
 					delete spr;
+					spr = nullptr;
 					break;
 				}
 			}
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 2f8e9b4..554d6ba 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -85,7 +85,7 @@ void Text::clear() {
 		if (p->_ref) {
 			p->_ref = 0;
 			delete[] p->_text;
-			p->_text = NULL;
+			p->_text = nullptr;
 		}
 	}
 }
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index bc2e07c..ded90ae 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -170,7 +170,7 @@ void Sprite::setName(char *newName) {
 
 	if (_ext->_name) {
 		delete[] _ext->_name;
-		_ext->_name = NULL;
+		_ext->_name = nullptr;
 	}
 	if (newName) {
 		_ext->_name = new char[strlen(newName) + 1];
@@ -394,25 +394,33 @@ Sprite *Sprite::contract() {
 	if (notify)
 		notify();
 
-	if (e->_name)
+	if (e->_name) {
 		delete[] e->_name;
+		e->_name = nullptr;
+	}
 
 	if (e->_shpList) {
 		for (int i = 0; i < _shpCnt; i++)
 			e->_shpList[i]->release();
 		delete[] e->_shpList;
+		e->_shpList = nullptr;
 	}
 
 	if (e->_seq) {
 		if (e->_seq == _stdSeq8)
 			_seqCnt = 0;
-		else
+		else {
 			delete[] e->_seq;
+			e->_seq = nullptr;
+		}
 	}
 
-	for (int i = 0; i < kActions; i++)
-		if (e->_actions[i])
+	for (int i = 0; i < kActions; i++) {
+		if (e->_actions[i]) {
 			delete[] e->_actions[i];
+			e->_actions[i];
+		}
+	}
 
 	_ext = nullptr;
 
@@ -479,9 +487,9 @@ void Sprite::killXlat() {
 
 	uint8 *m = (*_ext->_shpList)->_m;
 	free(m);
-
+	
 	for (BitmapPtr *b = _ext->_shpList; *b; b++)
-		(*b)->_m = NULL;
+		(*b)->_m = nullptr;
 	_flags._xlat = false;
 }
 
@@ -677,8 +685,10 @@ Queue::~Queue() {
 void Queue::clear() {
 	while (_head) {
 		Sprite *s = remove(_head);
-		if (s->_flags._kill)
+		if (s->_flags._kill) {
 			delete s;
+			s = nullptr;
+		}
 	}
 }
 


Commit: 160edae77aa07f520c5331876d91a713eab5cee8
    https://github.com/scummvm/scummvm/commit/160edae77aa07f520c5331876d91a713eab5cee8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T22:12:59+02:00

Commit Message:
CGE2: Silence some gcc and cppcheck warnings

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 3988360..e7ca459 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -35,14 +35,14 @@
 
 namespace CGE2 {
 
-Bitmap::Bitmap() : _w(0), _h(0), _v(NULL), _b(NULL) {
+Bitmap::Bitmap() : _w(0), _h(0), _v(nullptr), _b(nullptr), _m(nullptr), _map(0), _vm(nullptr) {
 }
 
 void Bitmap::setVM(CGE2Engine *vm) {
 	_vm = vm;
 }
 
-Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(NULL), _v(NULL), _b(NULL), _map(0), _vm(vm) {
+Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(nullptr), _v(nullptr), _b(nullptr), _map(0), _vm(vm) {
 	char pat[kMaxPath];
 	forceExt(pat, fname, ".VBM");
 
@@ -57,7 +57,7 @@ Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(NULL), _v(NULL), _b(NULL)
 	}
 }
 
-Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _m(map), _v(NULL), _map(0), _b(NULL), _vm(vm) {
+Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _m(map), _v(nullptr), _map(0), _b(nullptr), _vm(vm) {
 	if (map)
 		code();
 }
@@ -67,7 +67,7 @@ Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _
 // especially for text line real time display
 Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
 	: _w((w + 3) & ~3),                              // only full uint32 allowed!
-	  _h(h), _m(NULL), _map(0), _b(NULL), _vm(vm) {
+	  _h(h), _m(nullptr), _map(0), _b(nullptr), _vm(vm) {
 
 	uint16 dsiz = _w >> 2;                           // data size (1 plane line size)
 	uint16 lsiz = 2 + dsiz + 2;                     // uint16 for line header, uint16 for gap
@@ -104,7 +104,7 @@ Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
 	_b = b;
 }
 
-Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(NULL), _v(NULL), _map(0), _b(NULL), _vm(vm) {
+Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(nullptr), _v(nullptr), _map(0), _b(nullptr), _vm(vm) {
 	uint8 *v0 = bmp._v;
 	if (!v0)
 		return;
@@ -112,7 +112,7 @@ Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(N
 	uint16 vsiz = (uint8 *)(bmp._b) - (uint8 *)(v0);
 	uint16 siz = vsiz + _h * sizeof(HideDesc);
 	uint8 *v1 = new uint8[siz];
-	assert(v1 != NULL);
+	assert(v1 != nullptr);
 	memcpy(v1, v0, siz);
 	_b = (HideDesc *)((_v = v1) + vsiz);
 }
@@ -135,19 +135,19 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 	uint8 *v0 = bmp._v;
 	_w = bmp._w;
 	_h = bmp._h;
-	_m = NULL;
+	_m = nullptr;
 	_map = 0;
 	_vm = bmp._vm;
 	delete[] _v;
 	_v = nullptr;
 
-	if (v0 == NULL) {
-		_v = NULL;
+	if (v0 == nullptr) {
+		_v = nullptr;
 	} else {
 		uint16 vsiz = (uint8 *)bmp._b - (uint8 *)v0;
 		uint16 siz = vsiz + _h * sizeof(HideDesc);
 		uint8 *v1 = new uint8[siz];
-		assert(v1 != NULL);
+		assert(v1 != nullptr);
 		memcpy(v1, v0, siz);
 		_b = (HideDesc *)((_v = v1) + vsiz);
 	}
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 696b840..9d47397 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -571,7 +571,7 @@ void CGE2Engine::loadGame() {
 	// load sprites & pocket
 	
 	Sprite *s;
-	Hero *h;
+	Hero *h = nullptr;
 	
 	// initialize Andzia/Anna
 	s = _spare->take(142);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 8de2e13..7961e6d 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -523,7 +523,7 @@ void CGE2Engine::snRoom(Sprite *spr, int val) {
 void CGE2Engine::snGhost(Bitmap *bmp) {
 	V2D p(this, *bmp->_v & 0xFFFF, *bmp->_v >> 16);
 	bmp->hide(p.x, p.y);
-	delete bmp->_b;
+	delete[] bmp->_b;
 	bmp->_v = nullptr;
 	bmp->_b = nullptr;
 	delete bmp;


Commit: aabe883dc2b82c2ab4cca062c1192b74dd8b321f
    https://github.com/scummvm/scummvm/commit/aabe883dc2b82c2ab4cca062c1192b74dd8b321f
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T22:34:39+02:00

Commit Message:
CGE2: Fix some more GCC warnings

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9d47397..9ab9eb0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -194,6 +194,8 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 						badLab(fname);
 					++seqcnt;
 					break;
+				default:
+					break;
 				}
 				break;
 			}
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index ded90ae..644c753 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -40,8 +40,8 @@
 namespace CGE2 {
 
 Seq *getConstantSeq(bool seqFlag) {
-	const Seq seq1[] = { { 0, 0, 0, 0, 0 } };
-	const Seq seq2[] = { { 0, 1, 0, 0, 0 }, { 1, 0, 0, 0, 0 } };
+	const Seq seq1[] = { { 0, 0, 0, 0, 0, 0 } };
+	const Seq seq2[] = { { 0, 1, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, 0 } };
 
 	Seq *seq;
 	if (seqFlag) {
@@ -215,13 +215,13 @@ Sprite *Sprite::expand() {
 	char fname[kPathMax];
 	_vm->mergeExt(fname, _file, kSprExt);
 
-	Seq *seq;
+	Seq *curSeq;
 	if (_seqCnt) {
-		seq = new Seq[_seqCnt];
-		if (seq == NULL)
+		curSeq = new Seq[_seqCnt];
+		if (curSeq == nullptr)
 			error("No core %s", fname);
 	} else
-		seq = nullptr;
+		curSeq = nullptr;
 
 	for (int i = 0; i < kActions; i++)
 		cnt[i] = 0;
@@ -297,7 +297,7 @@ Sprite *Sprite::expand() {
 					}
 					break;
 				case kIdSeq:
-					s = &seq[seqcnt++];
+					s = &curSeq[seqcnt++];
 					s->_now = atoi(p);
 					if (s->_now > maxnow)
 						maxnow = s->_now;
@@ -348,12 +348,12 @@ Sprite *Sprite::expand() {
 		} else // no sprite description: try to read immediately from .BMP
 		shplist[shpcnt++] = new Bitmap (_vm, _file);
 
-	if (seq) {
+	if (curSeq) {
 		if (maxnow >= shpcnt)
 			error("Bad PHASE in SEQ %s", fname);
 		if (maxnxt && maxnxt >= seqcnt)
 			error("Bad JUMP in SEQ %s", fname);
-		setSeq(seq);
+		setSeq(curSeq);
 	} else {
 		setSeq(_stdSeq8);
 		_seqCnt = (shpcnt < ARRAYSIZE(_stdSeq8)) ? shpcnt : ARRAYSIZE(_stdSeq8);
@@ -367,13 +367,13 @@ Sprite *Sprite::expand() {
 	setShapeList(shapeList, shpcnt);
 
 	if (_file[2] == '~') { // FLY-type sprite
-		Seq *seq = _ext->_seq;
-		int x = (seq + 1)->_dx, y = (seq + 1)->_dy, z = (seq + 1)->_dz;
+		Seq *curSeq = _ext->_seq;
+		int x = (curSeq + 1)->_dx, y = (curSeq + 1)->_dy, z = (curSeq + 1)->_dz;
 		// random position
-		seq->_dx = _vm->newRandom(x + x) - x;
-		seq->_dy = _vm->newRandom(y + y) - y;
-		seq->_dz = _vm->newRandom(z + z) - z;
-		gotoxyz(_pos3D + V3D(seq->_dx, seq->_dy, seq->_dz));
+		curSeq->_dx = _vm->newRandom(x + x) - x;
+		curSeq->_dy = _vm->newRandom(y + y) - y;
+		curSeq->_dz = _vm->newRandom(z + z) - z;
+		gotoxyz(_pos3D + V3D(curSeq->_dx, curSeq->_dy, curSeq->_dz));
 	}
 
 	return this;
@@ -418,7 +418,7 @@ Sprite *Sprite::contract() {
 	for (int i = 0; i < kActions; i++) {
 		if (e->_actions[i]) {
 			delete[] e->_actions[i];
-			e->_actions[i];
+			e->_actions[i] = nullptr;
 		}
 	}
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 574a607..391c56c 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -79,7 +79,7 @@ public:
 	}
 	V2D(CGE2Engine *vm) : _vm(vm) { }
 	V2D(CGE2Engine *vm, const V3D &p3) : _vm(vm) { *this = p3; }
-	V2D(CGE2Engine *vm, int x, int y) : _vm(vm), Common::Point(x, y) { }
+	V2D(CGE2Engine *vm, int posx, int posy) : _vm(vm), Common::Point(posx, posy) { }
 	bool operator<(const V2D &p) const { return (x <  p.x) && (y <  p.y); }
 	bool operator<=(const V2D &p) const { return (x <= p.x) && (y <= p.y); }
 	bool operator>(const V2D &p) const { return (x >  p.x) && (y >  p.y); }


Commit: 516ad6e84377e14c4cbba9f25b99a523c1b0d276
    https://github.com/scummvm/scummvm/commit/516ad6e84377e14c4cbba9f25b99a523c1b0d276
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T22:41:19+02:00

Commit Message:
CGE2: Reduce the scope of some variables

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 030020e..30fd252 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -49,10 +49,6 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 
 	if (*_file) {
 		int cnt[kActions];
-		int shpcnt = 0;
-		int seqcnt = 0;
-		int maxnow = 0;
-		int maxnxt = 0;
 		Seq *seq;
 		int section = kIdPhase;
 
@@ -90,6 +86,10 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 			ID id;
 			Common::String line;
 			char tmpStr[kLineMax + 1];
+			int shpcnt = 0;
+			int seqcnt = 0;
+			int maxnow = 0;
+			int maxnxt = 0;
 
 			for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
 				if (line.size() == 0)


Commit: c5072db8fb6706768ad4a116c9cb3bd3c5f5efa3
    https://github.com/scummvm/scummvm/commit/c5072db8fb6706768ad4a116c9cb3bd3c5f5efa3
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-03T22:46:59+02:00

Commit Message:
CGE2: Fix remaining shadowed variables

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/sound.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9ab9eb0..a60b31b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -818,13 +818,11 @@ void CGE2Engine::switchHero(int sex) {
 }
 
 Sprite *CGE2Engine::spriteAt(int x, int y) {
-	Sprite *spr = NULL, *tail = _vga->_showQ->last();
-	if (tail) {
-		for (spr = tail->_prev; spr; spr = spr->_prev) {
-			if (!spr->_flags._hide && !spr->_flags._tran) {
-				if (spr->getShp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y))
-					break;
-			}
+	Sprite *spr = NULL, *queueTail = _vga->_showQ->last();
+	if (queueTail) {
+		for (spr = queueTail->_prev; spr; spr = spr->_prev) {
+			if (!spr->_flags._hide && !spr->_flags._tran && spr->getShp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y))
+				break;
 		}
 	}
 	return spr;
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index b497ebf..c657a37 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -125,9 +125,9 @@ void Fx::clear() {
 }
 
 Common::String Fx::name(int ref, int sub) {
-	char name[] = "%.2dfx%.2d.WAV\0";
-	char subn[] = "%.2dfx%.2d?.WAV\0";
-	char *p = (sub) ? subn : name;
+	char fxname[] = "%.2dfx%.2d.WAV\0";
+	char subName[] = "%.2dfx%.2d?.WAV\0";
+	char *p = (sub) ? subName : fxname;
 	Common::String filename = Common::String::format(p, ref >> 8, ref & 0xFF);
 	if (sub)
 		filename.setChar('@' + sub, 6);
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 644c753..334aa99 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -367,13 +367,13 @@ Sprite *Sprite::expand() {
 	setShapeList(shapeList, shpcnt);
 
 	if (_file[2] == '~') { // FLY-type sprite
-		Seq *curSeq = _ext->_seq;
-		int x = (curSeq + 1)->_dx, y = (curSeq + 1)->_dy, z = (curSeq + 1)->_dz;
+		Seq *nextSeq = _ext->_seq;
+		int x = (nextSeq + 1)->_dx, y = (nextSeq + 1)->_dy, z = (nextSeq + 1)->_dz;
 		// random position
-		curSeq->_dx = _vm->newRandom(x + x) - x;
-		curSeq->_dy = _vm->newRandom(y + y) - y;
-		curSeq->_dz = _vm->newRandom(z + z) - z;
-		gotoxyz(_pos3D + V3D(curSeq->_dx, curSeq->_dy, curSeq->_dz));
+		nextSeq->_dx = _vm->newRandom(x + x) - x;
+		nextSeq->_dy = _vm->newRandom(y + y) - y;
+		nextSeq->_dz = _vm->newRandom(z + z) - z;
+		gotoxyz(_pos3D + V3D(nextSeq->_dx, nextSeq->_dy, nextSeq->_dz));
 	}
 
 	return this;


Commit: b6d8e2b24716f9d1c8e91be15f5cba6da7764cae
    https://github.com/scummvm/scummvm/commit/b6d8e2b24716f9d1c8e91be15f5cba6da7764cae
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-04T01:03:51+02:00

Commit Message:
CGE2: Unstub some code used to move sprites

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 334aa99..d7f8fb2 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -455,9 +455,8 @@ void Sprite::step(int nr) {
 				p._x += seq->_dx;
 				p._y += seq->_dy;
 				p._z += seq->_dz;
-				//if (!_flags._kept)
-				//	gotoxyz(p);
-				warning("STUB: Sprite::step()");
+				if (!_flags._kept)
+					gotoxyz(p);
 			}
 		}
 		if (seq && (seq->_dly >= 0))


Commit: 8d00ce68d5361d854b04d2b84af0b786c06823af
    https://github.com/scummvm/scummvm/commit/8d00ce68d5361d854b04d2b84af0b786c06823af
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-04T01:08:25+02:00

Commit Message:
CGE2: Remove 2 useless stubs

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index e7ca459..f42e2b2 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -385,13 +385,13 @@ void Bitmap::xLatPos(V2D& p) {
 	p.y = kWorldHeight - p.y - _h;
 }
 
-bool Bitmap::moveHi(void) {
-	warning("STUB: Bitmap::moveHi()");
+bool Bitmap::moveHi() {
+	// No implementation needed in ScummVM
 	return true;
 }
 
-bool Bitmap::moveLo(void) {
-	warning("STUB: Bitmap::moveLo()");
+bool Bitmap::moveLo() {
+	// No implementation needed in ScummVM
 	return true;
 }
 


Commit: a0aa7df19c7ce3ce4912286dc646a6ea1495d07d
    https://github.com/scummvm/scummvm/commit/a0aa7df19c7ce3ce4912286dc646a6ea1495d07d
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-04T07:10:27+02:00

Commit Message:
CGE2: Remove useless 'void'

Changed paths:
    engines/cge2/bitmap.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 102fb1c..88ab3d8 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -82,8 +82,8 @@ public:
 	void xShow(int16 x, int16 y);
 	bool solidAt(int16 x, int16 y);
 	void xLatPos(V2D& p);
-	bool moveHi(void);
-	bool moveLo(void);
+	bool moveHi();
+	bool moveLo();
 };
 
 
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index d7f8fb2..fee570a 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -56,7 +56,7 @@ Seq *getConstantSeq(bool seqFlag) {
 	return seq;
 }
 
-void(*Sprite::notify) (void) = nullptr;
+void (*Sprite::notify)() = nullptr;
 
 byte Sprite::_constY = 0;
 byte Sprite::_follow = 0;
@@ -427,7 +427,7 @@ Sprite *Sprite::contract() {
 	return this;
 }
 
-void Sprite::backShow(void) {
+void Sprite::backShow() {
 	expand();
 	show(2);
 	show(1);
@@ -496,7 +496,7 @@ void Sprite::gotoxyz(int x, int y, int z) {
 	gotoxyz(V3D(x, y, z));
 }
 
-void Sprite::gotoxyz(void) {
+void Sprite::gotoxyz() {
 	gotoxyz(_pos3D);
 }
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 391c56c..583cf73 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -55,7 +55,7 @@ namespace CGE2 {
 class V3D {
 public:
 	double _x, _y, _z;
-	V3D(void) { }
+	V3D() { }
 	V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
 	V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
 	V3D operator+(const V3D &p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
@@ -72,6 +72,8 @@ class V2D : public Common::Point {
 	CGE2Engine *_vm;
 public:
 	V2D& operator=(const V3D &p3) {
+		if (p3._z == 200)
+			warning("");
 		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
 		x = round(_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m);
 		y = round(_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m);
@@ -86,16 +88,17 @@ public:
 	bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
 	V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
 	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
-	uint16 area(void) { return x * y; }
+	uint16 area() { return x * y; }
 	bool limited(const V2D &p) {
 		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
 	}
 	V2D scale(int z) {
 		double m = _vm->_eye->_z / (_vm->_eye->_z - z);
+		warning("scale: %f %f %f, x, y, m");
 		return V2D(_vm, trunc(m * x), trunc(m * y));
 	}
 	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
-	static double round(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); }
+	static double round(double number) { return number < 0.0 ? ceil(number) : floor(number); }
 };
 
 struct Seq {
@@ -172,18 +175,18 @@ public:
 	virtual ~Sprite();
 	BitmapPtr getShp();
 	void setShapeList(BitmapPtr *shp, int cnt);
-	void moveShapesHi(void);
-	void moveShapesLo(void);
+	void moveShapesHi();
+	void moveShapesLo();
 	int labVal(Action snq, int lab);
 	Sprite *expand();
 	Sprite *contract();
-	void backShow(void);
+	void backShow();
 	void setName(char *newName);
 	inline char *name() {
 		return (_ext) ? _ext->_name : NULL;
 	}
 	void gotoxyz(int x, int y, int z = 0);
-	void gotoxyz(void);
+	void gotoxyz();
 	void gotoxyz(V2D pos);
 	void gotoxyz_(V2D pos);
 	void gotoxyz(V3D pos);
@@ -200,10 +203,10 @@ public:
 	CommandHandler::Command *snList(Action type);
 	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
 	virtual void tick();
-	void clrHide(void) { if (_ext) _ext->_b0 = NULL; }
+	void clrHide() { if (_ext) _ext->_b0 = NULL; }
 	void sync(Common::Serializer &s);
 
-	static void (*notify) (void);
+	static void (*notify) ();
 };
 
 class Queue {


Commit: 58ee44ceb263b33f40b9eef89254cb8db2f00410
    https://github.com/scummvm/scummvm/commit/58ee44ceb263b33f40b9eef89254cb8db2f00410
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-04T22:50:32+02:00

Commit Message:
CGE2: Remove unnecessary check from Sprite::step().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index fee570a..26e6604 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -455,8 +455,7 @@ void Sprite::step(int nr) {
 				p._x += seq->_dx;
 				p._y += seq->_dy;
 				p._z += seq->_dz;
-				if (!_flags._kept)
-					gotoxyz(p);
+				gotoxyz(p);
 			}
 		}
 		if (seq && (seq->_dly >= 0))


Commit: 26b7ecd2eee36cc1ef05689be60cd5b3c6843245
    https://github.com/scummvm/scummvm/commit/26b7ecd2eee36cc1ef05689be60cd5b3c6843245
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-04T22:57:02+02:00

Commit Message:
CGE2: Get rid of _spareQ.

CGE2 uses an instance of Spare instead of it.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a60b31b..ee53e53 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -556,7 +556,6 @@ void CGE2Engine::runGame() {
 	_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
 	_mouse->off();
 	_vga->_showQ->clear();
-	_vga->_spareQ->clear();
 }
 
 void CGE2Engine::loadUser() {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 26e6604..9fb2a47 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -777,7 +777,6 @@ Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false),
 	_oldColors = NULL;
 	_newColors = NULL;
 	_showQ = new Queue(true);
-	_spareQ = new Queue(false);
 	_sysPal = new Dac[kPalCount];
 
 	for (int idx = 0; idx < 4; idx++) {
@@ -821,7 +820,6 @@ Vga::~Vga() {
 	debugN("%s", buffer.c_str());
 
 	delete _showQ;
-	delete _spareQ;
 	delete[] _sysPal;
 
 	for (int idx = 0; idx < 4; idx++) {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 583cf73..0c45ab8 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -247,7 +247,6 @@ class Vga {
 public:
 	uint32 _frmCnt;
 	Queue *_showQ;
-	Queue *_spareQ;
 	int _mono;
 	Graphics::Surface *_page[4];
 	Dac *_sysPal;


Commit: 7838852f9401772307e93cb79da98855ebb143b2
    https://github.com/scummvm/scummvm/commit/7838852f9401772307e93cb79da98855ebb143b2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-05T00:11:35+02:00

Commit Message:
CGE2: Stub buggy part of loadTab().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ee53e53..e1a2b0b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -646,6 +646,7 @@ void CGE2Engine::loadTab() {
 	for (int i = 0; i < kCaveMax; i++)
 		*(_eyeTab[i]) = *_eye;
 
+	/*
 	if (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
 		for (int i = 0; i < kCaveMax; i++) {
@@ -672,8 +673,8 @@ void CGE2Engine::loadTab() {
 			}
 		}
 	}
-
-	warning("STUB: CGE2Engine::loadTab() - Recheck this");
+	*/
+	warning("STUB: CGE2Engine::loadTab()");
 }
 
 void CGE2Engine::cge2_main() {


Commit: 85d9e9238c4f34ef983e1e91230e937c0dccd017
    https://github.com/scummvm/scummvm/commit/85d9e9238c4f34ef983e1e91230e937c0dccd017
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-05T00:45:33+02:00

Commit Message:
CGE2: Remove _m and xShow() from Bitmap, makeXlat() and killXlat() from Sprite.

They are not used in CGE2 at all (or used differently).

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index f42e2b2..4771428 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -35,14 +35,14 @@
 
 namespace CGE2 {
 
-Bitmap::Bitmap() : _w(0), _h(0), _v(nullptr), _b(nullptr), _m(nullptr), _map(0), _vm(nullptr) {
+Bitmap::Bitmap() : _w(0), _h(0), _v(nullptr), _b(nullptr), _map(0), _vm(nullptr) {
 }
 
 void Bitmap::setVM(CGE2Engine *vm) {
 	_vm = vm;
 }
 
-Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(nullptr), _v(nullptr), _b(nullptr), _map(0), _vm(vm) {
+Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _v(nullptr), _b(nullptr), _map(0), _vm(vm) {
 	char pat[kMaxPath];
 	forceExt(pat, fname, ".VBM");
 
@@ -57,9 +57,9 @@ Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _m(nullptr), _v(nullptr), _b
 	}
 }
 
-Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _m(map), _v(nullptr), _map(0), _b(nullptr), _vm(vm) {
+Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _v(nullptr), _map(0), _b(nullptr), _vm(vm) {
 	if (map)
-		code();
+		code(map);
 }
 
 // following routine creates filled rectangle
@@ -67,7 +67,7 @@ Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 *map) : _w(w), _h(h), _
 // especially for text line real time display
 Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
 	: _w((w + 3) & ~3),                              // only full uint32 allowed!
-	  _h(h), _m(nullptr), _map(0), _b(nullptr), _vm(vm) {
+	  _h(h), _map(0), _b(nullptr), _vm(vm) {
 
 	uint16 dsiz = _w >> 2;                           // data size (1 plane line size)
 	uint16 lsiz = 2 + dsiz + 2;                     // uint16 for line header, uint16 for gap
@@ -104,7 +104,7 @@ Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
 	_b = b;
 }
 
-Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _m(nullptr), _v(nullptr), _map(0), _b(nullptr), _vm(vm) {
+Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _v(nullptr), _map(0), _b(nullptr), _vm(vm) {
 	uint8 *v0 = bmp._v;
 	if (!v0)
 		return;
@@ -122,9 +122,7 @@ Bitmap::~Bitmap() {
 }
 
 void Bitmap::release() {
-	free(_m);
 	delete[] _v;
-	_m = nullptr;
 	_v = nullptr;
 }
 
@@ -135,7 +133,6 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 	uint8 *v0 = bmp._v;
 	_w = bmp._w;
 	_h = bmp._h;
-	_m = nullptr;
 	_map = 0;
 	_vm = bmp._vm;
 	delete[] _v;
@@ -164,8 +161,8 @@ char *Bitmap::forceExt(char *buf, const char *name, const char *ext) {
 	return buf;
 }
 
-BitmapPtr Bitmap::code() {
-	if (!_m)
+BitmapPtr Bitmap::code(uint8 *map) {
+	if (!map)
 		return NULL;
 
 	uint16 cnt;
@@ -187,7 +184,7 @@ BitmapPtr Bitmap::code() {
 			}
 		}
 		for (bpl = 0; bpl < 4; bpl++) {              // once per each bitplane
-			uint8 *bm = _m;
+			uint8 *bm = map;
 			bool skip = (bm[bpl] == kPixelTransp);
 			uint16 j;
 
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 88ab3d8..bcc51d8 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -61,7 +61,6 @@ class Bitmap {
 public:
 	uint16 _w;
 	uint16 _h;
-	uint8 *_m;
 	uint8 *_v;
 	int32 _map;
 	HideDesc *_b;
@@ -74,12 +73,11 @@ public:
 	~Bitmap();
 
 	void setVM(CGE2Engine *vm);
-	Bitmap *code();
+	Bitmap *code(uint8 *map);
 	Bitmap &operator=(const Bitmap &bmp);
 	void release();
 	void hide(int16 x, int16 y);
 	void show(int16 x, int16 y);
-	void xShow(int16 x, int16 y);
 	bool solidAt(int16 x, int16 y);
 	void xLatPos(V2D& p);
 	bool moveHi();
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 9fb2a47..c7979f1 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -468,29 +468,6 @@ void Sprite::tick() {
 	step();
 }
 
-void Sprite::makeXlat(uint8 *x) {
-	if (!_ext)
-		return;
-
-	if (_flags._xlat)
-		killXlat();
-	for (BitmapPtr *b = _ext->_shpList; *b; b++)
-		(*b)->_m = x;
-	_flags._xlat = true;
-}
-
-void Sprite::killXlat() {
-	if (!_flags._xlat || !_ext)
-		return;
-
-	uint8 *m = (*_ext->_shpList)->_m;
-	free(m);
-	
-	for (BitmapPtr *b = _ext->_shpList; *b; b++)
-		(*b)->_m = nullptr;
-	_flags._xlat = false;
-}
-
 void Sprite::gotoxyz(int x, int y, int z) {
 	gotoxyz(V3D(x, y, z));
 }
@@ -1020,59 +997,6 @@ void Vga::copyPage(uint16 d, uint16 s) {
 	_page[d]->copyFrom(*_page[s]);
 }
 
-//--------------------------------------------------------------------------
-
-void Bitmap::xShow(int16 x, int16 y) {
-	const byte *srcP = (const byte *)_v;
-	byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
-	byte *lookupTable = _m;
-
-	// Loop through processing data for each plane. The game originally ran in plane mapped mode, where a
-	// given plane holds each fourth pixel sequentially. So to handle an entire picture, each plane's data
-	// must be decompressed and inserted into the surface
-	for (int planeCtr = 0; planeCtr < 4; planeCtr++) {
-		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x + planeCtr, y);
-
-		for (;;) {
-			uint16 v = READ_LE_UINT16(srcP);
-			srcP += 2;
-			int cmd = v >> 14;
-			int count = v & 0x3FFF;
-
-			if (cmd == 0) {
-				// End of image
-				break;
-			}
-
-			assert(destP < destEndP);
-
-			if (cmd == 2)
-				srcP++;
-			else if (cmd == 3)
-				srcP += count;
-
-			// Handle a set of pixels
-			while (count-- > 0) {
-				// Transfer operation
-				switch (cmd) {
-				case 1:
-					// SKIP
-					break;
-				case 2:
-				case 3:
-					// TINT
-					*destP = lookupTable[*destP];
-					break;
-				}
-
-				// Move to next dest position
-				destP += 4;
-			}
-		}
-	}
-}
-
-
 void Bitmap::show(int16 x, int16 y) {
 	V2D pos(_vm, x, y);
 	xLatPos(pos);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 0c45ab8..9144595 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -196,8 +196,6 @@ public:
 	void show();
 	void hide();
 	BitmapPtr ghost();
-	void makeXlat(uint8 *x);
-	void killXlat();
 	void step(int nr = -1);
 	Seq *setSeq(Seq *seq);
 	CommandHandler::Command *snList(Action type);


Commit: c6fd9bf8ce06a9512ec6e8ff6d844718576d26a0
    https://github.com/scummvm/scummvm/commit/c6fd9bf8ce06a9512ec6e8ff6d844718576d26a0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T12:00:22+02:00

Commit Message:
CGE2: Remove stub from Vga::update().

It was for displaying debug lines. May be placed back again later during some debugging.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index c7979f1..01d0bf3 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -970,19 +970,6 @@ void Vga::update() {
 		updateColors();
 		_setPal = false;
 	}
-	/*if (_vm->_showBoundariesFl) {
-		Vga::_page[0]->hLine(0, 200 - kPanHeight, 320, 0xee);
-		if (_vm->_barriers[_vm->_now]._horz != 255) {
-		for (int i = 0; i < 8; i++)
-		Vga::_page[0]->vLine((_vm->_barriers[_vm->_now]._horz * 8) + i, 0, 200, 0xff);
-		}
-		if (_vm->_barriers[_vm->_now]._vert != 255) {
-		for (int i = 0; i < 4; i++)
-		Vga::_page[0]->hLine(0, 80 + (_vm->_barriers[_vm->_now]._vert * 4) + i, 320, 0xff);
-		}
-		}*/
-
-	warning("STUB: Vga::update()");
 
 	g_system->copyRectToScreen(Vga::_page[0]->getPixels(), kScrWidth, 0, 0, kScrWidth, kScrHeight);
 	g_system->updateScreen();


Commit: f2c006976541e00411b4f9154efe9ab16c633472
    https://github.com/scummvm/scummvm/commit/f2c006976541e00411b4f9154efe9ab16c633472
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T14:57:34+02:00

Commit Message:
CGE2: Change BitmapPtr *_shpList -> BitmapPtr _shpList.

Update rest of the code accordingly.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/events.cpp
    engines/cge2/hero.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 4771428..ff7c3e1 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -122,7 +122,8 @@ Bitmap::~Bitmap() {
 }
 
 void Bitmap::release() {
-	delete[] _v;
+	if (_v != nullptr)
+		delete[] _v;
 	_v = nullptr;
 }
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e1a2b0b..99447ef 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -737,13 +737,13 @@ bool CGE2Engine::showTitle(const char *name) {
 		return false;
 
 	_bitmapPalette = _vga->_sysPal;
-	BitmapPtr *LB = new BitmapPtr[2];
-	LB[0] = new Bitmap(this, name);
-	LB[1] = NULL;
-	_bitmapPalette = NULL;
+	BitmapPtr LB = new Bitmap[1];
+	LB[0] = Bitmap(this, name);
+	_bitmapPalette = nullptr;
 
 	Sprite D(this, LB, 1);
 	D._flags._kill = true;
+	strcpy(D._file, "hatter");
 	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
 	D.gotoxyz(kScrWidth >> 1, -(kPanHeight >> 1));
 	_vga->sunset();
@@ -758,7 +758,7 @@ bool CGE2Engine::showTitle(const char *name) {
 	_vga->update();
 
 	warning("STUB: CGE2Engine::showTitle()");
-
+	
 	return true;
 }
 
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 5c0300f..c036d5d 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -74,10 +74,9 @@ Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _vm
 	
 	setSeq(_stdSeq8);
 
-	BitmapPtr *MC = new BitmapPtr[3];
-	MC[0] = new Bitmap(_vm, "MOUSE");
-	MC[1] = new Bitmap(_vm, "DUMMY");
-	MC[2] = NULL;
+	BitmapPtr MC = new Bitmap[2];
+	MC[0] = Bitmap(_vm, "MOUSE");
+	MC[1] = Bitmap(_vm, "DUMMY");
 	setShapeList(MC, 2);
 
 	step(1);
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 30fd252..04ff05c 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -189,12 +189,7 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 			} else
 				setSeq(_stdSeq8);
 
-			BitmapPtr *bmp = new BitmapPtr[shpcnt];
-			for (int i = 0; i < shpcnt; i++)
-				bmp[i] = &_dim[0][i];
-			setShapeList(bmp, shpcnt);
-			delete[] bmp;
-			bmp = nullptr;
+			setShapeList(_dim[0], shpcnt);
 		}
 	}
 	_reachStart = atoi(_vm->token(text));
@@ -219,7 +214,7 @@ void Hero::setCurrent() {
 			break;
 	}
 
-	_ext->_shpList = &_dim[_curDim = i];
+	_ext->_shpList = _dim[_curDim = i];
 }
 
 void Hero::hStep() {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 01d0bf3..b8fe54d 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -91,7 +91,7 @@ Sprite::Sprite(CGE2Engine *vm)
 	_flags._frnt = 1;
 }
 
-Sprite::Sprite(CGE2Engine *vm, BitmapPtr *shpP, int cnt)
+Sprite::Sprite(CGE2Engine *vm, BitmapPtr shpP, int cnt)
 	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
      _next(NULL), _prev(NULL), _time(0),
      _ext(NULL), _ref(-1), _scene(0), _vm(vm),
@@ -119,17 +119,17 @@ BitmapPtr Sprite::getShp() {
 	int i = e->_seq[_seqPtr]._now;
 	if (i >= _shpCnt)
 		error("Invalid PHASE in SPRITE::Shp() %s", _file);
-	return e->_shpList[i];
+	return e->_shpList + i;
 }
 
-void Sprite::setShapeList(BitmapPtr *shp, int cnt) {
+void Sprite::setShapeList(BitmapPtr shp, int cnt) {
 	_shpCnt = cnt;
 	_siz.x = 0;
 	_siz.y = 0;
 
 	if (shp) {
 		for (int i = 0; i < cnt; i++) {
-			BitmapPtr p = *(shp + i);
+			BitmapPtr p = shp + i;
 			if (p->_w > _siz.x)
 				_siz.x = p->_w;
 			if (p->_h > _siz.y)
@@ -202,9 +202,7 @@ Sprite *Sprite::expand() {
 	if (!*_file)
 		return this;
 
-	Common::Array<BitmapPtr> shplist;
-	for (int i = 0; i < _shpCnt; ++i)
-		shplist.push_back(NULL);
+	BitmapPtr shplist = new Bitmap[_shpCnt];
 
 	int cnt[kActions],
 		shpcnt = 0,
@@ -328,9 +326,8 @@ Sprite *Sprite::expand() {
 					s->_dly = _vm->number(p);
 					break;
 				case kIdPhase: {
-					BitmapPtr bmp = new Bitmap(_vm, p);
-					shplist[shpcnt] = bmp;
-					if (!shplist[shpcnt]->moveHi())
+					shplist[shpcnt] = Bitmap(_vm, p);
+					if (!shplist[shpcnt].moveHi())
 						error("No EMS");
 					shpcnt++;
 					break;
@@ -346,7 +343,7 @@ Sprite *Sprite::expand() {
 		if (!shpcnt)
 			error("No shapes - %s", fname);
 		} else // no sprite description: try to read immediately from .BMP
-		shplist[shpcnt++] = new Bitmap (_vm, _file);
+		shplist[shpcnt++] = Bitmap(_vm, _file);
 
 	if (curSeq) {
 		if (maxnow >= shpcnt)
@@ -359,12 +356,7 @@ Sprite *Sprite::expand() {
 		_seqCnt = (shpcnt < ARRAYSIZE(_stdSeq8)) ? shpcnt : ARRAYSIZE(_stdSeq8);
 	}
 
-	// Set the shape list
-	BitmapPtr *shapeList = new BitmapPtr[shplist.size()];
-	for (uint i = 0; i < shplist.size(); ++i)
-		shapeList[i] = shplist[i];
-
-	setShapeList(shapeList, shpcnt);
+	setShapeList(shplist, shpcnt);
 
 	if (_file[2] == '~') { // FLY-type sprite
 		Seq *nextSeq = _ext->_seq;
@@ -401,7 +393,7 @@ Sprite *Sprite::contract() {
 
 	if (e->_shpList) {
 		for (int i = 0; i < _shpCnt; i++)
-			e->_shpList[i]->release();
+			e->_shpList[i].release();
 		delete[] e->_shpList;
 		e->_shpList = nullptr;
 	}
@@ -1055,53 +1047,19 @@ void Bitmap::hide(int16 x, int16 y) {
 /*--------------------------------------------------------------------------*/
 
 HorizLine::HorizLine(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
-	// Set the sprite list
-	BitmapPtr *HL = new BitmapPtr[2];
-	HL[0] = new Bitmap(_vm, "HLINE");
-	HL[1] = NULL;
-
-	setShapeList(HL, 1);
-
-	warning("HorizLine::HorizLine() - Recheck this!");
+	warning("HorizLine::HorizLine()");
 }
 
 SceneLight::SceneLight(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
-	// Set the sprite list
-	BitmapPtr *PR = new BitmapPtr[2];
-	PR[0] = new Bitmap(_vm, "PRESS");
-	PR[1] = NULL;
-
-	setShapeList(PR, 1);
-
-	warning("SceneLight::SceneLight() - Recheck this!");
+	warning("SceneLight::SceneLight()");
 }
 
 Speaker::Speaker(CGE2Engine *vm): Sprite(vm), _vm(vm) {
-	// Set the sprite list
-	BitmapPtr *SP = new BitmapPtr[3];
-	SP[0] = new Bitmap(_vm, "SPK_L");
-	SP[1] = new Bitmap(_vm, "SPK_R");
-	SP[2] = NULL;
-
-	setShapeList(SP, 2);
-
-	warning("Speaker::Speaker() - Recheck this!");
+	warning("Speaker::Speaker()");
 }
 
 PocLight::PocLight(CGE2Engine *vm): Sprite(vm), _vm(vm) {
-	// Set the sprite list
-	BitmapPtr *LI = new BitmapPtr[5];
-	LI[0] = new Bitmap(_vm, "LITE0");
-	LI[1] = new Bitmap(_vm, "LITE1");
-	LI[2] = new Bitmap(_vm, "LITE2");
-	LI[3] = new Bitmap(_vm, "LITE3");
-	LI[4] = NULL;
-
-	setShapeList(LI, 4);
-
-	_flags._kill = false;
-
-	warning("PocLight::PocLight() - Recheck this!");
+	warning("PocLight::PocLight()");
 }
 
 } // End of namespace CGE2
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 9144595..09eb61a 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -116,7 +116,7 @@ public:
 	V2D _p1;
 	BitmapPtr _b0;
 	BitmapPtr _b1;
-	BitmapPtr *_shpList;
+	BitmapPtr _shpList;
 	int _location;
 	Seq *_seq;
 	char *_name;
@@ -171,10 +171,10 @@ public:
 		return _ext != NULL;
 	}
 	Sprite(CGE2Engine *vm);
-	Sprite(CGE2Engine *vm, BitmapPtr *shp, int cnt);
+	Sprite(CGE2Engine *vm, BitmapPtr shp, int cnt);
 	virtual ~Sprite();
 	BitmapPtr getShp();
-	void setShapeList(BitmapPtr *shp, int cnt);
+	void setShapeList(BitmapPtr shp, int cnt);
 	void moveShapesHi();
 	void moveShapesLo();
 	int labVal(Action snq, int lab);


Commit: 63a153165a0c2b933dde0c4023a96526d716bdb4
    https://github.com/scummvm/scummvm/commit/63a153165a0c2b933dde0c4023a96526d716bdb4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T16:45:02+02:00

Commit Message:
CGE2: Implement Font.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/talk.cpp
    engines/cge2/talk.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 4bac09a..c80bf50 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -70,6 +70,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_vol[i] = nullptr;
 	_eventManager = nullptr;
 	_blinkSprite = nullptr;
+	_font = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -115,6 +116,7 @@ void CGE2Engine::init() {
 		_point[i] = new V3D();
 	_sys = new System(this);
 	_eventManager = new EventManager(this);
+	_font = new Font(this);
 }
 
 void CGE2Engine::deinit() {
@@ -146,6 +148,7 @@ void CGE2Engine::deinit() {
 	delete _eventManager;
 	if (_blinkSprite != nullptr)
 		delete _blinkSprite;
+	delete _font;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 2c34b0a..2db0d48 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -56,6 +56,7 @@ class Hero;
 class Bitmap;
 class System;
 class EventManager;
+class Font;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -79,20 +80,6 @@ enum CallbackType {
 
 enum Action { kNear, kMTake, kFTake, kActions };
 
-class Font {
-	char _path[kPathMax];
-	void load();
-	CGE2Engine *_vm;
-public:
-	uint8  *_widthArr;
-	uint16 *_pos;
-	uint8  *_map;
-	Font(CGE2Engine *vm, const char *name);
-	~Font();
-	uint16 width(const char *text);
-	void save();
-};
-
 class CGE2Engine : public Engine {
 private:
 	uint32 _lastFrame, _lastTick;
@@ -241,6 +228,7 @@ public:
 	Sprite *_vol[2];
 	EventManager *_eventManager;
 	Sprite *_blinkSprite;
+	Font *_font;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 2913327..cff0945 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -27,27 +27,83 @@
 
 #include "cge2/general.h"
 #include "cge2/talk.h"
-//#include "cge2/game.h"
-//#include "cge2/events.h"
 #include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
-Font::Font(CGE2Engine *vm, const char *name) : _vm(vm) {
-	warning("STUB: Font::Font()");
+Font::Font(CGE2Engine *vm) : _vm(vm) {
+	_map = new uint8[kMapSize];
+	_pos = new uint16[kPosSize];
+	_widthArr = new uint8[kWidSize];
+
+	assert((_map != NULL) && (_pos != NULL) && (_widthArr != NULL));
+	load();
 }
 
 Font::~Font() {
-	warning("STUB: Font::~Font()");
+	delete[] _map;
+	delete[] _pos;
+	delete[] _widthArr;
 }
 
 void Font::load() {
-	warning("STUB: Font::load()");
+	char *path = "CGE.CFT";
+	if (!_vm->_resman->exist(path))
+		error("Missing configuration file! %s", path);
+
+	EncryptedStream fontFile(_vm, path);
+	assert(!fontFile.err());
+
+	fontFile.read(_widthArr, kWidSize);
+	assert(!fontFile.err());
+
+	uint16 p = 0;
+	for (uint16 i = 0; i < kPosSize; i++) {
+		_pos[i] = p;
+		p += _widthArr[i];
+	}
+	fontFile.read(_map, p);
+
+	path = "CGE.TXC";
+	if (!_vm->_resman->exist(path))
+		error("Missing configuration file! %s", path);
+
+	// Reading in _colorSet:
+	EncryptedStream colorFile(_vm, path);
+	assert(!colorFile.err());
+
+	char tmpStr[kLineMax + 1];
+	Common::String line;
+	int n = 0;
+
+	for (line = colorFile.readLine(); !colorFile.eos(); line = colorFile.readLine()){
+		if (line.size() == 0)
+			continue;
+		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+		
+		char *p;
+
+		if ((p = _vm->token(tmpStr)) == NULL)
+			error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
+		_colorSet[n][0] = _vm->number(p);
+
+		for (int i = 1; i < 4; i++) {
+			if ((p = _vm->token(nullptr)) == NULL)
+				error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
+			_colorSet[n][i] = _vm->number(p);
+		}
+
+		n++;
+	}
 }
 
 uint16 Font::width(const char *text) {
-	warning("STUB: Font::width()");
-	return 0;
+	uint16 w = 0;
+	if (!text)
+		return 0;
+	while (*text)
+		w += _widthArr[(unsigned char)*(text++)];
+	return w;
 }
 
 Talk::Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, bool wideSpace)
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
index 2d4c235..a9e5d63 100644
--- a/engines/cge2/talk.h
+++ b/engines/cge2/talk.h
@@ -33,8 +33,6 @@
 
 namespace CGE2 {
 
-#define kTextColFG         kVgaColDark              // foreground color
-#define kTextColBG         kVgaColGray              // background color
 #define kTextHMargin      (6&~1)                    // EVEN horizontal margins!
 #define kTextVMargin       5                        // vertical margins
 #define kTextLineSpace     2                        // line spacing
@@ -44,6 +42,23 @@ namespace CGE2 {
 #define kMapSize          (256*8)
 #define kFontHigh          8
 #define kFontExt           ".CFT"
+#define kCaptionSide       24
+#define kInfName           101
+#define kSayName           102
+#define kColorNum          6
+
+class Font {
+	void load();
+	CGE2Engine *_vm;
+public:
+	uint8  *_widthArr;
+	uint16 *_pos;
+	uint8  *_map;
+	uint8  _colorSet[kColorNum][4];
+	Font(CGE2Engine *vm);
+	~Font();
+	uint16 width(const char *text);
+};
 
 enum TextBoxStyle { kTBPure, kTBRect, kTBRound };
 


Commit: 9efb2ef1a9e57ee1bf01a0111a1bdbd387486938
    https://github.com/scummvm/scummvm/commit/9efb2ef1a9e57ee1bf01a0111a1bdbd387486938
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T21:35:29+02:00

Commit Message:
CGE2: Implement Talk.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/talk.cpp
    engines/cge2/talk.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 2db0d48..ec206af 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -130,6 +130,7 @@ public:
 	void switchHero(int sex);
 	void optionTouch(int opt, uint16 mask);
 	void offUse();
+	void setAutoColors();
 
 	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index cff0945..df88f72 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -31,6 +31,10 @@
 
 namespace CGE2 {
 
+void CGE2Engine::setAutoColors() {
+	warning("STUB: CGE2Engine::setAutoColors()");
+}
+
 Font::Font(CGE2Engine *vm) : _vm(vm) {
 	_map = new uint8[kMapSize];
 	_pos = new uint16[kPosSize];
@@ -106,23 +110,138 @@ uint16 Font::width(const char *text) {
 	return w;
 }
 
-Talk::Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, bool wideSpace)
-	: Sprite(vm), _mode(mode), _wideSpace(wideSpace), _vm(vm) {
-	warning("STUB: Talk::Talk()");
+Talk::Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, ColorBank color, bool wideSpace)
+	: Sprite(vm), _mode(mode), _created(false), _wideSpace(wideSpace), _vm(vm) {
+	_color = _vm->_font->_colorSet[color];
+
+	if (color == kCBRel)
+		_vm->setAutoColors();
+	update(text);
 }
 
-Talk::Talk(CGE2Engine *vm)
+Talk::Talk(CGE2Engine *vm, ColorBank color)
 	: Sprite(vm), _mode(kTBPure), _vm(vm) {
-	warning("STUB: Talk::Talk()");
+	_color = _vm->_font->_colorSet[color];
+	
+	if (color == kCBRel)
+		_vm->setAutoColors();
 }
 
-void Talk::update(const char *text) {
-	warning("STUB: Talk::update()");
+uint8 *Talk::box(V2D siz) {
+	uint8 *b, *p, *q;
+	uint16 n, r = (_mode == kTBRound) ? kTextRoundCorner : 0;
+	const byte lt = _color[1], bg = _color[2], dk = _color[3];
+	int i;
+
+	if (siz.x < 8) siz.x = 8;
+	if (siz.y < 8) siz.y = 8;
+	b = new uint8[n = siz.area()];
+	if (!b)
+		error("No core!");
+	memset(b, bg, n);
+
+	if (_mode) {
+		p = b;
+		q = b + n - siz.x;
+		memset(p, lt, siz.x);
+		memset(q, dk, siz.x);
+		while (p < q) {
+			p += siz.x;
+			*(p - 1) = dk;
+			*p = lt;
+		}
+		p = b;
+		for (i = 0; i < r; i++) {
+			int j;
+			for (j = 0; j < r - i; j++) {
+				p[j] = kPixelTransp;
+				p[siz.x - j - 1] = kPixelTransp;
+				q[j] = kPixelTransp;
+				q[siz.x - j - 1] = kPixelTransp;
+			}
+			p[j] = lt;
+			p[siz.x - j - 1] = dk;
+			q[j] = lt;
+			q[siz.x - j - 1] = dk;
+			p += siz.x;
+			q -= siz.x;
+		}
+	}
+	return b;
 }
 
-Bitmap *Talk::box(uint16 w, uint16 h) {
-	warning("STUB: Talk::box()");
-	return *_ts;
+void Talk::update(const char *text) {
+	const uint16 vmarg = (_mode) ? kTextVMargin : 0;
+	const uint16 hmarg = (_mode) ? kTextHMargin : 0;
+	uint16 mw;
+	uint16 mh;
+	uint16 ln = vmarg;
+	uint8 *m;
+	uint8 *map;
+	uint8 fg = _color[0];
+
+	if (_created) {
+		mw = _ext->_shpList->_w;
+		mh = _ext->_shpList->_h;
+		delete _ext->_shpList;
+	} else {
+		uint16 k = 2 * hmarg;
+		mh = 2 * vmarg + kFontHigh;
+		mw = 0;
+		for (const char *p = text; *p; p++) {
+			if (*p == '|' || *p == '\n') {
+				mh += kFontHigh + kTextLineSpace;
+				if (k > mw)
+					mw = k;
+				k = 2 * hmarg;
+			} else if ((*p == 0x20) && (_vm->_font->_widthArr[(unsigned char)*p] > 4) && (!_wideSpace))
+				k += _vm->_font->_widthArr[(unsigned char)*p] - 2;
+			else
+				k += _vm->_font->_widthArr[(unsigned char)*p];
+		}
+		if (k > mw)
+			mw = k;
+
+		_created = true;
+	}
+
+	V2D sz(_vm, mw, mh);
+	map = box(sz);
+
+	m = map + ln * mw + hmarg;
+
+	while (*text) {
+		if (*text == '|' || *text == '\n') {
+			m = map + (ln += kFontHigh + kTextLineSpace) * mw + hmarg;
+		} else {
+			int cw = _vm->_font->_widthArr[(unsigned char)*text];
+			uint8 *f = _vm->_font->_map + _vm->_font->_pos[(unsigned char)*text];
+
+			// Handle properly space size, after it was enlarged to display properly
+			// 'F1' text.
+			int8 fontStart = 0;
+			if ((*text == 0x20) && (cw > 4) && (!_wideSpace))
+				fontStart = 2;
+
+			for (int i = fontStart; i < cw; i++) {
+				uint8 *pp = m;
+				uint16 n;
+				uint16 b = *(f++);
+				for (n = 0; n < kFontHigh; n++) {
+					if (b & 1)
+						*pp = fg;
+					b >>= 1;
+					pp += mw;
+				}
+				m++;
+			}
+		}
+		text++;
+	}
+	BitmapPtr b = new Bitmap[1];
+	b[0] = Bitmap(_vm, sz.x, sz.y, map);
+	delete[] map;
+	setShapeList(b, 1);
 }
 
 InfoLine::InfoLine(CGE2Engine *vm, uint16 w) : Talk(vm), _oldText(NULL), _vm(vm) {
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
index a9e5d63..771478c 100644
--- a/engines/cge2/talk.h
+++ b/engines/cge2/talk.h
@@ -62,17 +62,21 @@ public:
 
 enum TextBoxStyle { kTBPure, kTBRect, kTBRound };
 
+enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
+
 class Talk : public Sprite {
 protected:
 	TextBoxStyle _mode;
-	BitmapPtr *_ts;
-	Bitmap *box(uint16 w, uint16 h);
+	bool _created;
+	uint8 *box(V2D siz);
 	bool _wideSpace;
 public:
-	Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode, bool wideSpace = false);
-	Talk(CGE2Engine *vm);
+	uint8 *_color;
+
+	Talk(CGE2Engine *vm, const char *text, TextBoxStyle mode = kTBPure, ColorBank color = kCBStd, bool wideSpace = false);
+	Talk(CGE2Engine *vm, ColorBank color = kCBStd);
 
-	virtual void update(const char *text);
+	void update(const char *text);
 private:
 	CGE2Engine *_vm;
 };


Commit: 152d795b456e4e71e85322cdfcfa402241bf9365
    https://github.com/scummvm/scummvm/commit/152d795b456e4e71e85322cdfcfa402241bf9365
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T22:07:32+02:00

Commit Message:
CGE2: Implement InfoLine.

Move initialization of _font, so it precedes _infoLine's and doesn't cause more problems.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/talk.cpp
    engines/cge2/talk.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index c80bf50..231e72b 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -58,6 +58,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_spare = nullptr;
 	_commandHandler = nullptr;
 	_commandHandlerTurbo = nullptr;
+	_font = nullptr;
 	_infoLine = nullptr;
 	_mouse = nullptr;
 	_keyboard = nullptr;
@@ -70,7 +71,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_vol[i] = nullptr;
 	_eventManager = nullptr;
 	_blinkSprite = nullptr;
-	_font = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -109,6 +109,7 @@ void CGE2Engine::init() {
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
 	_commandHandlerTurbo = new CommandHandler(this, true);
+	_font = new Font(this);
 	_infoLine = new InfoLine(this, kInfoW);
 	_mouse = new Mouse(this);
 	_keyboard = new Keyboard(this);
@@ -116,7 +117,6 @@ void CGE2Engine::init() {
 		_point[i] = new V3D();
 	_sys = new System(this);
 	_eventManager = new EventManager(this);
-	_font = new Font(this);
 }
 
 void CGE2Engine::deinit() {
@@ -136,6 +136,7 @@ void CGE2Engine::deinit() {
 	delete _sprite;
 	delete _commandHandler;
 	delete _commandHandlerTurbo;
+	delete _font;
 	delete _infoLine;
 	delete _mouse;
 	delete _keyboard;
@@ -148,7 +149,6 @@ void CGE2Engine::deinit() {
 	delete _eventManager;
 	if (_blinkSprite != nullptr)
 		delete _blinkSprite;
-	delete _font;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index ec206af..d049339 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -219,6 +219,7 @@ public:
 	Spare *_spare;
 	CommandHandler *_commandHandler;
 	CommandHandler *_commandHandlerTurbo;
+	Font *_font;
 	InfoLine *_infoLine;
 	Mouse *_mouse;
 	Keyboard *_keyboard;
@@ -229,7 +230,6 @@ public:
 	Sprite *_vol[2];
 	EventManager *_eventManager;
 	Sprite *_blinkSprite;
-	Font *_font;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 99447ef..a37abbc 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -516,8 +516,7 @@ void CGE2Engine::runGame() {
 		
 	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
 	_infoLine->setText(nullptr);
-	//_vga->_showQ->insert(_infoLine);
-	warning("STUB: CGE2Engine::runGame() - Info Line is missing!");
+	_vga->_showQ->insert(_infoLine);
 
 	caveUp(_now);
 	_startupMode = 0;
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index df88f72..ee4a675 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -244,20 +244,71 @@ void Talk::update(const char *text) {
 	setShapeList(b, 1);
 }
 
-InfoLine::InfoLine(CGE2Engine *vm, uint16 w) : Talk(vm), _oldText(NULL), _vm(vm) {
-	warning("STUB: InfoLine::InfoLine()");
+InfoLine::InfoLine(CGE2Engine *vm, uint16 w, ColorBank color)
+: Talk(vm), _oldText(nullptr), _newText(nullptr), _realTime(false), _vm(vm) {
+	BitmapPtr b = new Bitmap[1];
+	if (color == kCBRel)
+		_vm->setAutoColors();
+	_color = _vm->_font->_colorSet[color];
+	V2D siz = V2D(_vm, w, kFontHigh);
+	b[0] = Bitmap(_vm, siz.x, siz.y, _color[2]);
+	setShapeList(b, 1);
 }
 
 void InfoLine::update(const char *text) {
-	warning("STUB: InfoLine::update()");
-}
+	if (!_realTime && text == _oldText)
+		return;
+
+	_oldText = text;
+
+	uint16 w = _ext->_shpList->_w;
+	uint16 h = _ext->_shpList->_h;
+	uint8 *v = _ext->_shpList->_v;
+	uint16 dsiz = w >> 2;                           // data size (1 plane line size)
+	uint16 lsiz = 2 + dsiz + 2;                     // uint16 for line header, uint16 for gap
+	uint16 psiz = h * lsiz;                         // - last gape, but + plane trailer
+	uint16 size = 4 * psiz;                         // whole map size
+	uint8 fg = _color[0];
+	uint8 bg = _color[2];
 
-void InfoLine::update() {
-	warning("STUB: InfoLine::update()");
-}
+	// clear whole rectangle
+	memset(v + 2, bg, dsiz);                // data bytes
+	for (byte *pDest = v + lsiz; pDest < (v + psiz); pDest += lsiz) {
+		Common::copy(v, v + lsiz, pDest);
+	}
+	*(uint16 *)(v + psiz - 2) = TO_LE_16(kBmpEOI);  // plane trailer uint16
+	for (byte *pDest = v + psiz; pDest < (v + 4 * psiz); pDest += psiz) {
+		Common::copy(v, v + psiz, pDest);
+	}
 
-void InfoLine::setText(const char *txt) {
-	warning("STUB: InfoLine::setText()");
+	// paint text line
+	if (_newText) {
+		uint8 *p = v + 2, *q = p + size;
+
+		while (*text) {
+			uint16 cw = _vm->_font->_widthArr[(unsigned char)*text];
+			uint8 *fp = _vm->_font->_map + _vm->_font->_pos[(unsigned char)*text];
+
+			// Handle properly space size, after it was enlarged to display properly
+			// 'F1' text.
+			int8 fontStart = 0;
+			if ((*text == 0x20) && (cw > 4) && (!_wideSpace))
+				fontStart = 2;
+
+			for (int i = fontStart; i < cw; i++) {
+				uint16 b = fp[i];
+				for (uint16 n = 0; n < kFontHigh; n++) {
+					if (b & 1)
+						*p = fg;
+					b >>= 1;
+					p += lsiz;
+				}
+				if (p >= q)
+					p = p - size + 1;
+			}
+			text++;
+		}
+	}
 }
 
 } // End of namespace CGE2
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
index 771478c..84ba728 100644
--- a/engines/cge2/talk.h
+++ b/engines/cge2/talk.h
@@ -82,12 +82,13 @@ private:
 };
 
 class InfoLine : public Talk {
-	const char *_oldText;
+	const char *_oldText, *_newText;
 public:
-	InfoLine(CGE2Engine *vm, uint16 wid);
+	bool _realTime;
+	InfoLine(CGE2Engine *vm, uint16 wid, ColorBank color = kCBStd);
 	void update(const char *text);
-	void update();
-	void setText(const char *txt);
+	void update() { update(_newText); }
+	void setText(const char *txt) { _newText = txt; }
 private:
 	CGE2Engine *_vm;
 };


Commit: 97bb1370a317b7ce3784889d74b61b6e5fd7bc84
    https://github.com/scummvm/scummvm/commit/97bb1370a317b7ce3784889d74b61b6e5fd7bc84
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T22:20:05+02:00

Commit Message:
CGE2: Reimplement the way of handling y coord.

In CGE2, the top left coords are (0, kScreenHeight), not (0,0).

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index c036d5d..55c384c 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -155,6 +155,7 @@ EventManager::EventManager(CGE2Engine *vm) : _vm(vm){
 
 void EventManager::poll() {
 	while (g_system->getEventManager()->pollEvent(_event)) {
+		_event.mouse.y = kScrHeight - _event.mouse.y;
 		switch (_event.type) {
 		case Common::EVENT_KEYDOWN:
 		case Common::EVENT_KEYUP:
@@ -186,7 +187,7 @@ void EventManager::handleEvents() {
 
 			// update mouse cursor position
 			if (e._mask & kMouseRoll)
-				_vm->_mouse->gotoxyz(e._x, kWorldHeight - e._y);
+				_vm->_mouse->gotoxyz(e._x, e._y);
 
 			// activate current touched SPRITE
 			if (e._spritePtr) {


Commit: 968f24af4787563c27c839ada08d4772b1ecd1b9
    https://github.com/scummvm/scummvm/commit/968f24af4787563c27c839ada08d4772b1ecd1b9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-06T22:26:27+02:00

Commit Message:
CGE2: Fix coord conversion in EventManager::poll().

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 55c384c..75da3fa 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -155,7 +155,7 @@ EventManager::EventManager(CGE2Engine *vm) : _vm(vm){
 
 void EventManager::poll() {
 	while (g_system->getEventManager()->pollEvent(_event)) {
-		_event.mouse.y = kScrHeight - _event.mouse.y;
+		_event.mouse.y = kWorldHeight - _event.mouse.y;
 		switch (_event.type) {
 		case Common::EVENT_KEYDOWN:
 		case Common::EVENT_KEYUP:


Commit: 23d40712c6c7af0977fe2d38751f922e30a8b3b6
    https://github.com/scummvm/scummvm/commit/23d40712c6c7af0977fe2d38751f922e30a8b3b6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-07T19:40:29+02:00

Commit Message:
CGE2: Refine implementation of Queue::insert().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index b8fe54d..6032391 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -696,6 +696,9 @@ void Queue::insert(Sprite *spr, Sprite *nxt) {
 }
 
 void Queue::insert(Sprite *spr) {
+	if (locate(spr))
+		return; // We only queue it if it's not already queued.
+
 	Sprite *s;
 	for (s = _head; s; s = s->_next)
 		if (s->_pos3D._z < spr->_pos3D._z)


Commit: acb81c5e74ac2b54fc9b430d439389fb82233069
    https://github.com/scummvm/scummvm/commit/acb81c5e74ac2b54fc9b430d439389fb82233069
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-07T19:44:16+02:00

Commit Message:
CGE2: Fully implement caveUp().

Also implement connected parts of Hero.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a37abbc..a545647 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -368,9 +368,19 @@ void CGE2Engine::caveUp(int cav) {
 	_spare->takeCave(_now);
 	openPocket();
 	
-	warning("STUB: CGE2Engine::caveUp()");
-	// TODO: Implement "Hero" things here!
-
+	for (int i = 0; i < 2; i++) {
+		Hero *h = _heroTab[i]->_ptr;
+		if (h && h->_scene == _now) {
+			V2D p = *_heroTab[i]->_posTab[_now];
+			h->gotoxyz(V3D(p.x, 0, p.y));
+			h->clrHide();
+			_vga->_showQ->insert(h);
+			h->park();
+			h->setCurrent();
+			h->setContact();
+		}
+	}
+	
 	_sound->stop();
 	_fx->clear();
 
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 04ff05c..3e22d72 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -222,8 +222,19 @@ void Hero::hStep() {
 }
 
 Sprite *Hero::setContact() {
-	warning("STUB: Hero::setContact()");
-	return this;
+	Sprite *spr;
+	int md = _maxDist << 1;
+	for (spr = _vm->_vga->_showQ->first(); spr; spr = spr->_next) {
+		if (spr->_actionCtrl[kNear]._cnt && (spr->_ref & 255) != 255) {
+			if (distance(spr) <= md) {
+				if (spr == _contact)
+					return nullptr;
+				else
+					break;
+			}
+		}
+	}
+	return (_contact = spr);
 }
 
 void Hero::tick() {
@@ -231,13 +242,29 @@ void Hero::tick() {
 }
 
 int Hero::distance(V3D pos) {
-	warning("STUB: Hero::distance()");
-	return 0;
+	V3D di = _pos3D - pos;
+	long x = V2D::round(di._x);
+	long z = V2D::round(di._z);
+	return ((x * x + z * z) * (x * x + z * z));
 }
 
 int Hero::distance(Sprite *spr) {
-	warning("STUB: Hero::distance()");
-	return 0;
+	V3D pos = spr->_pos3D;
+	int mdx = (spr->_siz.x >> 1) + (_siz.x >> 1);
+	int dx = V2D::round(_pos3D._x - spr->_pos3D._x);
+	if (dx < 0) {
+		mdx = -mdx;
+		if (dx > mdx)
+			pos._x = _pos3D._x;
+		else
+			pos._x += mdx;
+	} else {
+		if (dx < mdx)
+			pos._x = _pos3D._x;
+		else
+			pos._x += mdx;
+	}
+	return distance(pos);
 }
 
 void Hero::turn(Dir d) {
@@ -245,7 +272,17 @@ void Hero::turn(Dir d) {
 }
 
 void Hero::park() {
-	warning("STUB: Hero::park()");
+	if (_dir != kNoDir) {
+		step(8 + 5 * _dir);
+		_dir = kNoDir;
+		_trace[0] = _pos3D;
+		_tracePtr = -1;
+		setCurrent();
+		_flags._zmov = true;
+	}
+	_ignoreMap = false;
+	if (_time == 0)
+		++_time;
 }
 
 bool Hero::lower(Sprite * spr) {


Commit: bb216eba2f8f9fd04a4e338393e37723b1328390
    https://github.com/scummvm/scummvm/commit/bb216eba2f8f9fd04a4e338393e37723b1328390
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-07T20:33:52+02:00

Commit Message:
CGE2: Implement System::touch().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/events.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index d049339..f25df58 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -73,6 +73,7 @@ class Font;
 #define kInfoX         160
 #define kInfoY         -11
 #define kInfoW         180
+#define kPocketsWidth   59
 
 enum CallbackType {
 	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a545647..065e905 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -41,8 +41,60 @@ System::System(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
 	warning("STUB: System::System()");
 }
 
-void System::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
-	warning("STUB: System::touch()");
+void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
+	if (mask & kEventKeyb) {
+		if (keyCode == Common::KEYCODE_ESCAPE) {
+			// The original was calling keyClick()
+			// The sound is uselessly annoying and noisy, so it has been removed
+			_vm->killText();
+			if (_vm->_startupMode == 1) {
+				_vm->_commandHandler->addCommand(kCmdClear, -1, 0, NULL);
+				return;
+			}
+		}
+	} else {
+		if (_vm->_startupMode)
+			return;
+		int selectedScene = 0;
+		_vm->_infoLine->setText(nullptr);
+		
+		if (mask & kMouseLeftUp) {
+			if (pos.y >= 0)	{ // world
+				if (!_vm->_talk && pos.y < _vm->_mouseTop)
+					_vm->_heroTab[_vm->_sex]->_ptr->walkTo(pos);
+			} else { // panel
+				if (_vm->_commandHandler->idle()) {
+					int sex = pos.x < kPocketsWidth;
+					if (sex || pos.x >= kScrWidth - kPocketsWidth) {
+						_vm->switchHero(sex);
+						if (_vm->_sex == sex) {
+							int dx = kPocketsWidth >> 1,
+								dy = 1 - (kPanHeight >> 1);
+							Sprite *s;
+							if (!sex)
+								pos.x -= kScrWidth - kPocketsWidth;
+							dx -= pos.x;
+							dy -= pos.y;
+							if (dx * dx + dy * dy > 10 * 10) {
+								int n = 0;
+								if (1 - pos.y >= (kPanHeight >> 1))
+									n += 2;
+								if (pos.x >= (kPocketsWidth >> 1))
+									++n;
+								s = _vm->_heroTab[_vm->_sex]->_pocket[n];
+								if (_vm->_blinkSprite)
+									_vm->_blinkSprite->_flags._hide = false;
+								if (_vm->_blinkSprite == s)
+									_vm->_blinkSprite = nullptr;
+								else
+									_vm->_blinkSprite = s;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
 }
 
 void System::tick() {
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index 272cdf7..a0bd780 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -56,7 +56,7 @@ public:
 
 	System(CGE2Engine *vm);
 	
-	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
+	virtual void touch(uint16 mask, V2D pos, Common::KeyCode keyCode);
 	void tick();
 private:
 	CGE2Engine *_vm;
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 75da3fa..a143c77 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -196,7 +196,7 @@ void EventManager::handleEvents() {
 				else
 					e._spritePtr->touch(e._mask, e._x - e._spritePtr->_pos2D.x, e._y - e._spritePtr->_pos2D.y, e._keyCode);
 			} else if (_vm->_sys)
-				_vm->_sys->touch(e._mask, e._x, e._y, e._keyCode);
+				_vm->_sys->touch(e._mask, V2D(_vm, e._x, e._y), e._keyCode);
 
 			if (e._mask & kMouseLeftDown) {
 				_vm->_mouse->_hold = e._spritePtr;


Commit: 0cad1988e4103172a0d3281606b34d4fd381c30b
    https://github.com/scummvm/scummvm/commit/0cad1988e4103172a0d3281606b34d4fd381c30b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-07T21:07:46+02:00

Commit Message:
CGE2: Remove unnecessary variable from System::touch().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 065e905..7d9e715 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -55,7 +55,6 @@ void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 	} else {
 		if (_vm->_startupMode)
 			return;
-		int selectedScene = 0;
 		_vm->_infoLine->setText(nullptr);
 		
 		if (mask & kMouseLeftUp) {


Commit: f2a1d4f1c865861dc42deb99a8b4aa4a97ecb235
    https://github.com/scummvm/scummvm/commit/f2a1d4f1c865861dc42deb99a8b4aa4a97ecb235
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-07T21:09:19+02:00

Commit Message:
CGE2: Implement walkTo() and snap() in Hero.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 3e22d72..f429c40 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -317,16 +317,59 @@ bool Hero::findWay(){
 }
 
 int Hero::snap(int p, int q, int grid) {
-	warning("STUB: Hero::findWay()");
-	return 0;
+	int d = q - p;
+	d = ((d >= 0) ? d : -d) % grid;
+	if (d > (grid >> 1))
+		d -= grid;
+	return (q >= p) ? (q - d) : (q + d);
 }
 
 void Hero::walkTo(V3D pos) {
-	warning("STUB: Hero::walkTo()");
+	if (distance(pos) <= _maxDist)
+		return;
+	int stp = stepSize();
+	pos._x = snap(V2D::round(_pos3D._x), V2D::round(pos._x), stp);
+	pos._y = 0;
+	pos._z = snap(V2D::round(_pos3D._z), V2D::round(pos._z), stp);
+
+	V2D p0(_vm, V2D::round(_pos3D._x), V2D::round(_pos3D._z));
+	V2D p1(_vm, V2D::round(pos._x), V2D::round(pos._z));
+	resetFun();
+	int cnt = mapCross(p0, p1);
+	if ((cnt & 1) == 0) { // even == way exists
+		_trace[_tracePtr = 0] = pos;
+		if (!findWay()) {
+			int i;
+			++_tracePtr;
+			for (i = stp; i < kMaxTry; i += stp) {
+				_trace[_tracePtr] = pos + V3D(i, 0, 0);
+				if (!mapCross(_trace[_tracePtr - 1], _trace[_tracePtr]) && findWay())
+					break;
+
+				_trace[_tracePtr] = pos + V3D(-i, 0, 0);
+				if (!mapCross(_trace[_tracePtr - 1], _trace[_tracePtr]) && findWay())
+					break;
+
+				_trace[_tracePtr] = pos + V3D(0, 0, i);
+				if (!mapCross(_trace[_tracePtr - 1], _trace[_tracePtr]) && findWay())
+					break;
+
+				_trace[_tracePtr] = pos + V3D(0, 0, -i);
+				if (!mapCross(_trace[_tracePtr - 1], _trace[_tracePtr]) && findWay())
+					break;
+			}
+			if (i >= kMaxTry)
+				_trace[_tracePtr] = V3D(_pos3D._x, 0, pos._z); // not found
+		}
+	}
 }
 
 void Hero::walkTo(Sprite *spr) {
-	warning("STUB: Hero::walkTo()");
+	int mdx = _siz.x >> 1;
+	int stp = (stepSize() + 1) / 2;
+	if (!spr->_flags._east)
+		mdx = -mdx;
+	walkTo(spr->_pos3D + V3D(mdx, 0, (!spr->_flags._frnt || spr->_pos3D._z < 8) ? stp : -stp));
 }
 
 V3D Hero::screenToGround(V2D pos) {
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 8face03..8a8d400 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -31,6 +31,8 @@
 #include "cge2/vga13h.h"
 #include "cge2/snail.h"
 
+#define	kMaxTry	400
+
 namespace CGE2 {
 
 #define kMaxTry 400


Commit: a62e044174f296cc8cf7dced7b35cc3d4fe0ea01
    https://github.com/scummvm/scummvm/commit/a62e044174f296cc8cf7dced7b35cc3d4fe0ea01
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-07T21:35:48+02:00

Commit Message:
CGE2: Keep on implementing Hero.

Also add a couple of helping functions to CGE2Engine.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/hero.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index f25df58..0533e19 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -132,6 +132,10 @@ public:
 	void optionTouch(int opt, uint16 mask);
 	void offUse();
 	void setAutoColors();
+	bool cross(const V2D &a, const V2D &b, const V2D &c, const V2D &d);
+	bool contain(const V2D &a, const V2D &b, const V2D &p);
+	int sgn(long n);
+	int mapCross(const V2D &a, const V2D &b);
 
 	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index f429c40..0c46b82 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -307,12 +307,33 @@ void Hero::operator -- () {
 }
 
 uint32 Hero::len(V2D v) {
-	warning("STUB: Hero::works()");
-	return 0;
+	long x = v.x, y = v.y;
+	return (uint32)((x * x + y * y) * (x * x + y * y));
 }
 
 bool Hero::findWay(){
-	warning("STUB: Hero::findWay()");
+	V2D p0(_vm, V2D::round(_pos3D._x), V2D::round(_pos3D._z));
+	V2D p1(_vm, V2D::round(_trace[_tracePtr]._x), V2D::round(_trace[_tracePtr]._z));
+	bool pvOk;
+	bool phOk;
+	V2D ph(_vm, p1.x, p0.y);
+	V2D pv(_vm, p0.x, p1.y);
+	pvOk = (!mapCross(p0, pv) && !mapCross(pv, p1));
+	phOk = (!mapCross(p0, ph) && !mapCross(ph, p1));
+	int md = (_maxDist >> 1);
+	if (pvOk && (len(ph - p0) <= md || len(p1 - ph) <= md))
+		return true;
+	if (phOk && (len(pv - p0) <= md || len(p1 - pv) <= md))
+		return true;
+
+	if (pvOk) {
+		_trace[++_tracePtr] = V3D(pv.x, 0, pv.y);
+		return true;
+	}
+	if (phOk) {
+		_trace[++_tracePtr] = V3D(ph.x, 0, ph.y);
+		return true;
+	}
 	return false;
 }
 
@@ -380,22 +401,48 @@ V3D Hero::screenToGround(V2D pos) {
 
 
 int Hero::cross(const V2D &a, const V2D &b) {
-	warning("STUB: Hero::cross()");
+	int x = V2D::trunc(_pos3D._x);
+	int z = V2D::trunc(_pos3D._z);
+	int r = ((_siz.x / 3) * V2D::trunc(_vm->_eye->_z)) / (V2D::trunc(_vm->_eye->_z) - z);
+	return _vm->cross(a, b, V2D(_vm, x - r, z), V2D(_vm, x + r, z)) << 1;
+}
+
+
+
+bool CGE2Engine::cross(const V2D &a, const V2D &b, const V2D &c, const V2D &d) {
+	warning("STUB: CGE2Engine::cross()");
+	return false;
+}
+
+bool CGE2Engine::contain(const V2D &a, const V2D &b, const V2D &p) {
+	warning("STUB: CGE2Engine::contain()");
+	return false;
+}
+
+int CGE2Engine::sgn(long n) {
+	warning("STUB: CGE2Engine::sgn()");
 	return 0;
 }
 
 int Hero::mapCross(const V2D &a, const V2D &b) {
-	warning("STUB: Hero::mapCross()");
-	return 0;
+	Hero *o = other();
+	int n = (o->_scene == _scene) ? o->cross(a, b) : 0;
+	if (!_ignoreMap)
+		n += _vm->mapCross(a, b);
+	return n;
 }
 
 int Hero::mapCross(const V3D &a, const V3D &b) {
-	warning("STUB: Hero::mapCross()");
+	return mapCross(V2D(_vm, V2D::round(a._x), V2D::round(a._z)), V2D(_vm, V2D::round(b._x), V2D::round(b._z)));
+}
+
+int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
+	warning("STUB: CGE2Engine::cross()");
 	return 0;
 }
 
 void Hero::setCave(int c) {
-	warning("STUB: Hero::mapCross()");
+	warning("STUB: Hero::setCave()");
 }
 
 bool Sprite::works(Sprite *spr) {


Commit: 9aa80d6d05f11afcb0682699c1a631ed9287341b
    https://github.com/scummvm/scummvm/commit/9aa80d6d05f11afcb0682699c1a631ed9287341b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T07:30:31+02:00

Commit Message:
CGE2: Implement helper functions connected to Hero.

Also rework Hero::len() during the process.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 0533e19..be2bbd3 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -134,6 +134,7 @@ public:
 	void setAutoColors();
 	bool cross(const V2D &a, const V2D &b, const V2D &c, const V2D &d);
 	bool contain(const V2D &a, const V2D &b, const V2D &p);
+	long det(const V2D &a, const V2D &b, const V2D &c);
 	int sgn(long n);
 	int mapCross(const V2D &a, const V2D &b);
 
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 0c46b82..5ebce6e 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -306,9 +306,8 @@ void Hero::operator -- () {
 	warning("STUB: Hero::operator --()");
 }
 
-uint32 Hero::len(V2D v) {
-	long x = v.x, y = v.y;
-	return (uint32)((x * x + y * y) * (x * x + y * y));
+int Hero::len(V2D v) {
+	return ((v.x * v.x + v.y * v.y) * (v.x * v.x + v.y * v.y));
 }
 
 bool Hero::findWay(){
@@ -399,7 +398,6 @@ V3D Hero::screenToGround(V2D pos) {
 	return V3D(V2D::round(x), 0, V2D::round(z));
 }
 
-
 int Hero::cross(const V2D &a, const V2D &b) {
 	int x = V2D::trunc(_pos3D._x);
 	int z = V2D::trunc(_pos3D._z);
@@ -407,21 +405,31 @@ int Hero::cross(const V2D &a, const V2D &b) {
 	return _vm->cross(a, b, V2D(_vm, x - r, z), V2D(_vm, x + r, z)) << 1;
 }
 
-
-
 bool CGE2Engine::cross(const V2D &a, const V2D &b, const V2D &c, const V2D &d) {
-	warning("STUB: CGE2Engine::cross()");
-	return false;
+	if (contain(a, b, c))
+		return true;
+	if (contain(a, b, d))
+		return true;
+	if (contain(c, d, a))
+		return true;
+	if (contain(c, d, b))
+		return true;
+	return sgn(det(a, b, c)) != sgn(det(a, b, d)) && sgn(det(c, d, a)) != sgn(det(c, d, b));
 }
 
 bool CGE2Engine::contain(const V2D &a, const V2D &b, const V2D &p) {
-	warning("STUB: CGE2Engine::contain()");
-	return false;
+	if (det(a, b, p))
+		return false;
+	return ((long)(a.x - p.x) * (p.x - b.x) >= 0 && (long)(a.y - p.y) * (p.y - b.y) >= 0);
+}
+
+long CGE2Engine::det(const V2D &a, const V2D &b, const V2D &c) {
+	long n = ((long)a.x * b.y + (long)b.x * c.y + (long)c.x*a.y) - ((long)c.x*b.y + (long)b.x*a.y + (long)a.x*c.y);
+	return n;
 }
 
 int CGE2Engine::sgn(long n) {
-	warning("STUB: CGE2Engine::sgn()");
-	return 0;
+	return (n == 0) ? 0 : ((n > 0) ? 1 : -1);
 }
 
 int Hero::mapCross(const V2D &a, const V2D &b) {
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 8a8d400..c993386 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -78,7 +78,7 @@ public:
 	int distance(Sprite * spr);
 	void turn(Dir d);
 	void park();
-	static uint32 len(V2D v);
+	int len(V2D v);
 	bool findWay();
 	static int snap(int p, int q, int grid);
 	void walkTo(V3D pos);


Commit: 8c3e63e47139c4ff168e93b105297e7f8f669016
    https://github.com/scummvm/scummvm/commit/8c3e63e47139c4ff168e93b105297e7f8f669016
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T07:38:16+02:00

Commit Message:
CGE2: Reduce number of unhandled commands (seemingly).

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index be2bbd3..dcbffdf 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -181,10 +181,12 @@ public:
 	void snBackPt(Sprite *spr, int val);
 	void snFlash(int val);
 	void snLight(int val);
+	void snCycle(int cnt);
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
 	void snSound(Sprite *spr, int wav);
 	void snRoom(Sprite *spr, int val);
+	void snDim(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
 	
 	void hide1(Sprite *spr);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 7961e6d..1368652 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -276,7 +276,7 @@ void CommandHandler::runCommand() {
 			_vm->snLight(tailCmd._val != 0);
 			break;
 		case kCmdCycle:
-			warning("Unhandled command - kCmdCycle");
+			_vm->snCycle(tailCmd._val);
 			break;
 		case kCmdWalk:
 			_vm->snWalk(spr, tailCmd._val);
@@ -298,7 +298,7 @@ void CommandHandler::runCommand() {
 			_vm->snRoom(spr, tailCmd._val);
 			break;
 		case kCmdDim:
-			warning("Unhandled command - kCmdDim");
+			_vm->snDim(spr, tailCmd._val);
 			break;
 		case kCmdExec:
 			warning("Unhandled command - kCmdExec");
@@ -491,6 +491,10 @@ void CGE2Engine::snLight(int val) {
 	warning("STUB: CGE2Engine::snLight()");
 }
 
+void CGE2Engine::snCycle(int cnt) {
+	warning("STUB: CGE2Engine::snCycle()");
+}
+
 void CGE2Engine::snWalk(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snWalk()");
 }
@@ -520,6 +524,15 @@ void CGE2Engine::snRoom(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snRoom()");
 }
 
+void CGE2Engine::snDim(Sprite *spr, int val) {
+	if (isHero(spr)) {
+		if (val > 0)
+			++*(Hero*)spr;
+		if (val < 0)
+			--*(Hero*)spr;
+	}
+}
+
 void CGE2Engine::snGhost(Bitmap *bmp) {
 	V2D p(this, *bmp->_v & 0xFFFF, *bmp->_v >> 16);
 	bmp->hide(p.x, p.y);


Commit: 5a7924678ac8af99e6cd58edc3f5cb3342253038
    https://github.com/scummvm/scummvm/commit/5a7924678ac8af99e6cd58edc3f5cb3342253038
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T07:41:25+02:00

Commit Message:
CGE2: Further implement Hero's functions.

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 5ebce6e..601e289 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -298,14 +298,6 @@ void Hero::fun() {
 	warning("STUB: Hero::fun()");
 }
 
-void Hero::operator ++ () {
-	warning("STUB: Hero::operator ++()");
-}
-
-void Hero::operator -- () {
-	warning("STUB: Hero::operator --()");
-}
-
 int Hero::len(V2D v) {
 	return ((v.x * v.x + v.y * v.y) * (v.x * v.x + v.y * v.y));
 }
@@ -450,7 +442,18 @@ int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
 }
 
 void Hero::setCave(int c) {
-	warning("STUB: Hero::setCave()");
+	_scene = c;
+	resetFun();
+}
+
+void Hero::operator++() {
+	if (_curDim > 0)
+		_ext->_shpList = _dim[--_curDim];
+}
+
+void Hero::operator--() {
+	if (_curDim < kDimMax - 1)
+		_ext->_shpList = _dim[++_curDim];
 }
 
 bool Sprite::works(Sprite *spr) {


Commit: 5fca8c328ca49e3de7b3d9e4dc03293dab504e89
    https://github.com/scummvm/scummvm/commit/5fca8c328ca49e3de7b3d9e4dc03293dab504e89
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T07:44:46+02:00

Commit Message:
CGE2: Fix stub message in CGE2Engine::mapCross().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 601e289..62568ae 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -437,7 +437,7 @@ int Hero::mapCross(const V3D &a, const V3D &b) {
 }
 
 int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
-	warning("STUB: CGE2Engine::cross()");
+	warning("STUB: CGE2Engine::mapCross()");
 	return 0;
 }
 


Commit: cfe03245fae13dff869ea6f8c934fb510161e431
    https://github.com/scummvm/scummvm/commit/cfe03245fae13dff869ea6f8c934fb510161e431
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T07:52:21+02:00

Commit Message:
CGE2: Handle kCmdNop correctly.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 1368652..d41aa80 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -309,6 +309,8 @@ void CommandHandler::runCommand() {
 		case kCmdGhost:
 			_vm->snGhost((Bitmap *)tailCmd._spritePtr);
 			break;
+		case kCmdNop: // Do nothing.
+			break;
 		default:
 			warning("Unhandled command");
 			break;


Commit: 9afe6bd570e5445db951792f338d2781ad67d1ee
    https://github.com/scummvm/scummvm/commit/9afe6bd570e5445db951792f338d2781ad67d1ee
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T09:53:47+02:00

Commit Message:
CGE2: Add, implement and use Map.

Changed paths:
  A engines/cge2/map.cpp
  A engines/cge2/map.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 231e72b..b32ca76 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -38,6 +38,7 @@
 #include "cge2/events.h"
 #include "cge2/talk.h"
 #include "cge2/cge2_main.h"
+#include "cge2/map.h"
 
 namespace CGE2 {
 
@@ -71,6 +72,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_vol[i] = nullptr;
 	_eventManager = nullptr;
 	_blinkSprite = nullptr;
+	_map = nullptr;
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
@@ -117,6 +119,7 @@ void CGE2Engine::init() {
 		_point[i] = new V3D();
 	_sys = new System(this);
 	_eventManager = new EventManager(this);
+	_map = new Map(this);
 }
 
 void CGE2Engine::deinit() {
@@ -149,6 +152,7 @@ void CGE2Engine::deinit() {
 	delete _eventManager;
 	if (_blinkSprite != nullptr)
 		delete _blinkSprite;
+	delete _map;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index dcbffdf..4fc8576 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -57,6 +57,7 @@ class Bitmap;
 class System;
 class EventManager;
 class Font;
+class Map;
 
 #define kScrWidth      320
 #define kScrHeight     240
@@ -109,7 +110,6 @@ public:
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
-	void loadMap(int cav);
 	void openPocket();
 	void selectPocket(int n);
 	void busy(bool on);
@@ -238,6 +238,7 @@ public:
 	Sprite *_vol[2];
 	EventManager *_eventManager;
 	Sprite *_blinkSprite;
+	Map *_map;
 private:
 	void init();
 	void deinit();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 7d9e715..e256d72 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -34,6 +34,7 @@
 #include "cge2/hero.h"
 #include "cge2/spare.h"
 #include "cge2/events.h"
+#include "cge2/map.h"
 
 namespace CGE2 {
 
@@ -416,6 +417,7 @@ void CGE2Engine::caveUp(int cav) {
 	showBak(bakRef);
 	*_eye = *(_eyeTab[_now]);
 	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
+	_map->load(_now);
 	_spare->takeCave(_now);
 	openPocket();
 	
@@ -545,10 +547,6 @@ void CGE2Engine::tick() {
 	_mouse->tick();
 }
 
-void CGE2Engine::loadMap(int cav) {
-	warning("STUB: CGE2Engine::loadMap()");
-}
-
 void CGE2Engine::openPocket() {
 	warning("STUB: CGE2Engine::openPocket()");
 }
diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
new file mode 100644
index 0000000..ed8ce21
--- /dev/null
+++ b/engines/cge2/map.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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/map.h"
+#include "cge2/cge2_main.h"
+
+namespace CGE2 {
+
+Map::Map(CGE2Engine *vm) :_vm(vm) {}
+
+Map::~Map() {
+	_container.clear();
+}
+
+int	Map::convertCoord(int coord) {
+	return (coord + (kMapGrid >> 1)) & kMapMask;
+}
+
+void Map::load(int cave) {
+	char fname[] = "%.2d.MAP\0";
+	Common::String filename = Common::String::format(fname, cave);
+	clear();
+	if (!_vm->_resman->exist(filename.c_str()))
+		return;
+
+	EncryptedStream file(_vm, filename.c_str());
+	
+	char tmpStr[kLineMax + 1];
+	Common::String line;
+
+	for (line = file.readLine(); !file.eos(); line = file.readLine()) {
+		if (line.size() == 0)
+			continue;
+
+		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+
+		char *currPos = tmpStr;
+		currPos = strtok(currPos, " (),");
+		int x = atoi(currPos);
+		currPos = strtok(nullptr, " (),");
+		int y = atoi(currPos);
+		_container.push_back(V2D(_vm, convertCoord(x), convertCoord(y)));
+
+		while (true) {
+			currPos = strtok(nullptr, " (),");
+			if (currPos == nullptr)
+				break;
+			int x = atoi(currPos);
+			currPos = strtok(nullptr, " (),");
+			int y = atoi(currPos);
+			_container.push_back(V2D(_vm, convertCoord(x), convertCoord(y)));
+		}
+	}
+}
+
+int Map::size() {
+	return _container.size();
+}
+
+void Map::clear() {
+	_container.clear();
+}
+
+V2D &Map::operator[](int idx) {
+	return _container[idx];
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/map.h b/engines/cge2/map.h
new file mode 100644
index 0000000..7b792b2
--- /dev/null
+++ b/engines/cge2/map.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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_MAP_H
+#define CGE2_MAP_H
+
+#include "cge2/vga13h.h"
+
+namespace CGE2 {
+
+#define kMapGrid   4
+#define kMapMask   (~(kMapGrid - 1))
+
+class Map {
+	CGE2Engine *_vm;
+	Common::Array<V2D> _container;
+
+	int	convertCoord(int coord);
+public:
+	Map(CGE2Engine *vm);
+	~Map();
+	void load(int cave);
+	int size();
+	void clear();
+	V2D &operator[](int idx);
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_MAP_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 7272ed3..dc74de5 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -13,7 +13,8 @@ MODULE_OBJS = \
 	snail.o \
 	spare.o \
 	talk.o \
-	events.o
+	events.o \
+	map.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)


Commit: 1d8536e6df8db7dec0cc4fb05f85bf67183e848d
    https://github.com/scummvm/scummvm/commit/1d8536e6df8db7dec0cc4fb05f85bf67183e848d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T11:06:12+02:00

Commit Message:
CGE2: Replace tab with space.

Changed paths:
    engines/cge2/map.cpp



diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
index ed8ce21..1ae9451 100644
--- a/engines/cge2/map.cpp
+++ b/engines/cge2/map.cpp
@@ -36,7 +36,7 @@ Map::~Map() {
 	_container.clear();
 }
 
-int	Map::convertCoord(int coord) {
+int Map::convertCoord(int coord) {
 	return (coord + (kMapGrid >> 1)) & kMapMask;
 }
 


Commit: acbd19bec43302ec97e0f00513351410dc540618
    https://github.com/scummvm/scummvm/commit/acbd19bec43302ec97e0f00513351410dc540618
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T12:42:05+02:00

Commit Message:
CGE2: Some rework in Map.

Changed paths:
    engines/cge2/map.cpp
    engines/cge2/map.h



diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
index 1ae9451..579f44b 100644
--- a/engines/cge2/map.cpp
+++ b/engines/cge2/map.cpp
@@ -36,53 +36,54 @@ Map::~Map() {
 	_container.clear();
 }
 
-int Map::convertCoord(int coord) {
-	return (coord + (kMapGrid >> 1)) & kMapMask;
+void Map::clear() {
+	_container.clear();
 }
 
-void Map::load(int cave) {
-	char fname[] = "%.2d.MAP\0";
-	Common::String filename = Common::String::format(fname, cave);
+void Map::load(int scene) {
 	clear();
-	if (!_vm->_resman->exist(filename.c_str()))
+
+	char fname[] = "%.2d.MAP\0";
+	Common::String fileName = Common::String::format(fname, scene);
+	if (!_vm->_resman->exist(fileName.c_str()))
 		return;
 
-	EncryptedStream file(_vm, filename.c_str());
+	EncryptedStream file(_vm, fileName.c_str());
 	
-	char tmpStr[kLineMax + 1];
 	Common::String line;
-
 	for (line = file.readLine(); !file.eos(); line = file.readLine()) {
 		if (line.size() == 0)
 			continue;
 
+		char tmpStr[kLineMax + 1];
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 
 		char *currPos = tmpStr;
-		currPos = strtok(currPos, " (),");
-		int x = atoi(currPos);
-		currPos = strtok(nullptr, " (),");
-		int y = atoi(currPos);
-		_container.push_back(V2D(_vm, convertCoord(x), convertCoord(y)));
-
+		int x = nextNum(currPos);
 		while (true) {
-			currPos = strtok(nullptr, " (),");
-			if (currPos == nullptr)
-				break;
-			int x = atoi(currPos);
-			currPos = strtok(nullptr, " (),");
-			int y = atoi(currPos);
+			int y = nextNum(nullptr);
 			_container.push_back(V2D(_vm, convertCoord(x), convertCoord(y)));
+			x = nextNum(nullptr);
+			if (x == -1) // We stop if there are no more data left to process in the current line.
+				break;
 		}
 	}
 }
 
-int Map::size() {
-	return _container.size();
+int Map::nextNum(char *currPos) {
+	currPos = strtok(currPos, " (),");
+	if (currPos == nullptr)
+		return -1;
+	int num = atoi(currPos);
+	return num;
 }
 
-void Map::clear() {
-	_container.clear();
+int Map::convertCoord(int coord) {
+	return (coord + (kMapGrid >> 1)) & kMapMask;
+}
+
+int Map::size() {
+	return _container.size();
 }
 
 V2D &Map::operator[](int idx) {
diff --git a/engines/cge2/map.h b/engines/cge2/map.h
index 7b792b2..10448f0 100644
--- a/engines/cge2/map.h
+++ b/engines/cge2/map.h
@@ -39,13 +39,14 @@ class Map {
 	CGE2Engine *_vm;
 	Common::Array<V2D> _container;
 
-	int	convertCoord(int coord);
+	int convertCoord(int coord);
+	int nextNum(char *currPos);
 public:
 	Map(CGE2Engine *vm);
 	~Map();
-	void load(int cave);
-	int size();
 	void clear();
+	void load(int scene);
+	int size();
 	V2D &operator[](int idx);
 };
 


Commit: ba8bc2e40b94aa6055222550651452c3645c2515
    https://github.com/scummvm/scummvm/commit/ba8bc2e40b94aa6055222550651452c3645c2515
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T12:55:19+02:00

Commit Message:
CGE2: Rework empty-checks of strings.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp
    engines/cge2/map.cpp
    engines/cge2/talk.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e256d72..20b16fa 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -168,7 +168,7 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 		Common::String line;
 
 		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()){
-			if (line.size() == 0)
+			if (line.empty())
 				continue;
 			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 				
@@ -313,7 +313,7 @@ void CGE2Engine::loadScript(const char *fname) {
 	Common::String line;
 
 	for (line = scrf.readLine(); !scrf.eos(); line = scrf.readLine()) {
-		if (line.size() == 0)
+		if (line.empty())
 			continue;
 
 		char *p;
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 62568ae..de0dc26 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -92,7 +92,7 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 			int maxnxt = 0;
 
 			for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
-				if (line.size() == 0)
+				if (line.empty())
 					continue;
 				Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 
diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
index 579f44b..6dbf57f 100644
--- a/engines/cge2/map.cpp
+++ b/engines/cge2/map.cpp
@@ -52,7 +52,7 @@ void Map::load(int scene) {
 	
 	Common::String line;
 	for (line = file.readLine(); !file.eos(); line = file.readLine()) {
-		if (line.size() == 0)
+		if (line.empty())
 			continue;
 
 		char tmpStr[kLineMax + 1];
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index ee4a675..acadd2e 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -81,7 +81,7 @@ void Font::load() {
 	int n = 0;
 
 	for (line = colorFile.readLine(); !colorFile.eos(); line = colorFile.readLine()){
-		if (line.size() == 0)
+		if (line.empty())
 			continue;
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 		
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 6032391..7da9535 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -246,7 +246,7 @@ Sprite *Sprite::expand() {
 		char tmpStr[kLineMax + 1];
 
 		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
-			if (line.size() == 0)
+			if (line.empty())
 				continue;
 			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 


Commit: 93010a840734507b84554ad47e50eec7db34a939
    https://github.com/scummvm/scummvm/commit/93010a840734507b84554ad47e50eec7db34a939
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-08T14:26:42+02:00

Commit Message:
CGE2: Implement CGE2Engine::mapCross().

Rework Map during the process.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/map.cpp
    engines/cge2/map.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index de0dc26..530ff11 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -28,6 +28,7 @@
 #include "cge2/hero.h"
 #include "cge2/text.h"
 #include "cge2/cge2_main.h"
+#include "cge2/map.h"
 
 namespace CGE2 {
 
@@ -437,8 +438,23 @@ int Hero::mapCross(const V3D &a, const V3D &b) {
 }
 
 int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
-	warning("STUB: CGE2Engine::mapCross()");
-	return 0;
+	int cnt = 0;
+	V2D *n0 = nullptr;
+	V2D *p = nullptr;
+	for (int i = 0; i < _map->size(); i++) {
+		V2D *n = _map->getCoord(i);
+		if (p) {
+			if (cross(a, b, *n0, *n))
+				++cnt;
+		
+			if (n == p)
+				p = nullptr;	
+		} else {
+			p = n;
+		}
+		n0 = n;
+	}
+	return cnt;
 }
 
 void Hero::setCave(int c) {
diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
index 6dbf57f..8a9a5db 100644
--- a/engines/cge2/map.cpp
+++ b/engines/cge2/map.cpp
@@ -86,8 +86,8 @@ int Map::size() {
 	return _container.size();
 }
 
-V2D &Map::operator[](int idx) {
-	return _container[idx];
+V2D *Map::getCoord(int idx) {
+	return &_container[idx];
 }
 
 } // End of namespace CGE2
diff --git a/engines/cge2/map.h b/engines/cge2/map.h
index 10448f0..206479b 100644
--- a/engines/cge2/map.h
+++ b/engines/cge2/map.h
@@ -47,7 +47,7 @@ public:
 	void clear();
 	void load(int scene);
 	int size();
-	V2D &operator[](int idx);
+	V2D *getCoord(int idx);
 };
 
 } // End of namespace CGE2


Commit: 5d80601c06c02db12147b64c5c17feeaf5565bc8
    https://github.com/scummvm/scummvm/commit/5d80601c06c02db12147b64c5c17feeaf5565bc8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-08T22:53:38+02:00

Commit Message:
CGE2: Reduce the scope of a couple of variables, fix style

Changed paths:
    engines/cge2/talk.cpp



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index acadd2e..8770383 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -128,21 +128,21 @@ Talk::Talk(CGE2Engine *vm, ColorBank color)
 }
 
 uint8 *Talk::box(V2D siz) {
-	uint8 *b, *p, *q;
 	uint16 n, r = (_mode == kTBRound) ? kTextRoundCorner : 0;
 	const byte lt = _color[1], bg = _color[2], dk = _color[3];
-	int i;
 
-	if (siz.x < 8) siz.x = 8;
-	if (siz.y < 8) siz.y = 8;
-	b = new uint8[n = siz.area()];
+	if (siz.x < 8)
+		siz.x = 8;
+	if (siz.y < 8)
+		siz.y = 8;
+	uint8 *b = new uint8[n = siz.area()];
 	if (!b)
 		error("No core!");
 	memset(b, bg, n);
 
 	if (_mode) {
-		p = b;
-		q = b + n - siz.x;
+		uint8 *p = b;
+		uint8 *q = b + n - siz.x;
 		memset(p, lt, siz.x);
 		memset(q, dk, siz.x);
 		while (p < q) {
@@ -151,9 +151,9 @@ uint8 *Talk::box(V2D siz) {
 			*p = lt;
 		}
 		p = b;
-		for (i = 0; i < r; i++) {
-			int j;
-			for (j = 0; j < r - i; j++) {
+		for (int i = 0; i < r; i++) {
+			int j = 0;
+			for (; j < r - i; j++) {
 				p[j] = kPixelTransp;
 				p[siz.x - j - 1] = kPixelTransp;
 				q[j] = kPixelTransp;


Commit: 76fa66fc8ce531d3391a81259e13474b429277f5
    https://github.com/scummvm/scummvm/commit/76fa66fc8ce531d3391a81259e13474b429277f5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-09T23:20:46+02:00

Commit Message:
CGE2: Fix endless loop regarding kCmdWait.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 20b16fa..764bdde 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -538,7 +538,7 @@ void CGE2Engine::tick() {
 				spr->tick();
 		}
 		if (_waitRef) {
-			if (_waitRef == _sprite->_ref)
+			if (_waitRef == spr->_ref)
 				if (spr->seqTest(_waitSeq))
 					_waitRef = 0;
 		}


Commit: 63fa2d4906dbe119c552e993ae0f4cd2a4079ddb
    https://github.com/scummvm/scummvm/commit/63fa2d4906dbe119c552e993ae0f4cd2a4079ddb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-09T23:34:40+02:00

Commit Message:
CGE2: Simplify if-statements.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 764bdde..99b0f26 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -533,13 +533,11 @@ bool CGE2Engine::isHero(Sprite *spr) {
 
 void CGE2Engine::tick() {
 	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
-		if (spr->_time) {
-			if (--spr->_time == 0)
+		if (spr->_time && (--spr->_time == 0))
 				spr->tick();
-		}
+		
 		if (_waitRef) {
-			if (_waitRef == spr->_ref)
-				if (spr->seqTest(_waitSeq))
+			if (_waitRef == spr->_ref && spr->seqTest(_waitSeq))
 					_waitRef = 0;
 		}
 	}


Commit: 12c531284b4108ce1935982a924971339bec188a
    https://github.com/scummvm/scummvm/commit/12c531284b4108ce1935982a924971339bec188a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-09T23:54:45+02:00

Commit Message:
CGE2: Implement a couple of command handling functions.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index d41aa80..3af4c88 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -422,7 +422,13 @@ void CGE2Engine::snGive(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snGoto(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snGoto()");
+	if (spr) {
+		V3D eye = *_eye;
+		if (spr->_scene > 0)
+			setEye(*_eyeTab[spr->_scene]);
+		spr->gotoxyz(*_point[val]);
+		setEye(eye);
+	}
 }
 
 void CGE2Engine::snMove(Sprite *spr, V3D pos) {
@@ -446,7 +452,11 @@ void CGE2Engine::snMouse(int val) {
 }
 
 void CGE2Engine::snNNext(Sprite *spr, Action act, int val) {
-	warning("STUB: CGE2Engine::snNNext()");
+	if (spr) {
+		if (val > 255)
+			val = spr->labVal(act, val >> 8);
+		spr->_actionCtrl[act]._ptr = val;
+	}
 }
 
 void CGE2Engine::snRNNext(Sprite *spr, int val) {
@@ -466,7 +476,8 @@ void CGE2Engine::snRmNear(Sprite *spr) {
 }
 
 void CGE2Engine::snRmMTake(Sprite *spr) {
-	warning("STUB: CGE2Engine::snRmMTake()");
+	if (spr)
+		spr->_actionCtrl[kMTake]._cnt = 0;
 }
 
 void CGE2Engine::snRmFTake(Sprite *spr) {


Commit: e10f22b62f85b5d940a4274e65a53b907f2eae4b
    https://github.com/scummvm/scummvm/commit/e10f22b62f85b5d940a4274e65a53b907f2eae4b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-10T14:02:17+02:00

Commit Message:
CGE2: Move kLineMax to cge2.h.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.h
    engines/cge2/hero.cpp
    engines/cge2/map.cpp
    engines/cge2/talk.cpp
    engines/cge2/text.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 4fc8576..ebee2ed 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -75,6 +75,7 @@ class Map;
 #define kInfoY         -11
 #define kInfoW         180
 #define kPocketsWidth   59
+#define kLineMax       512
 
 enum CallbackType {
 	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index a0bd780..e59c6f0 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -32,7 +32,6 @@
 
 namespace CGE2 {
 
-#define kLineMax          512
 #define kIntroExt         ".I80"
 #define kTabName          "CGE.TAB"
 #define kPocketFull       170
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 530ff11..5efb24e 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -27,7 +27,6 @@
 
 #include "cge2/hero.h"
 #include "cge2/text.h"
-#include "cge2/cge2_main.h"
 #include "cge2/map.h"
 
 namespace CGE2 {
diff --git a/engines/cge2/map.cpp b/engines/cge2/map.cpp
index 8a9a5db..1ed0ea7 100644
--- a/engines/cge2/map.cpp
+++ b/engines/cge2/map.cpp
@@ -26,7 +26,6 @@
  */
 
 #include "cge2/map.h"
-#include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 8770383..a6d9945 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -27,7 +27,6 @@
 
 #include "cge2/general.h"
 #include "cge2/talk.h"
-#include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 554d6ba..ac222f9 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -30,7 +30,6 @@
 //#include "cge/talk.h"
 //#include "cge/game.h"
 //#include "cge/snail.h"
-#include "cge2/cge2_main.h"
 #include "common/str.h"
 
 namespace CGE2 {


Commit: 71b0a4cc69185ee6b6f01b488a958c7c19503c3f
    https://github.com/scummvm/scummvm/commit/71b0a4cc69185ee6b6f01b488a958c7c19503c3f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-10T14:02:33+02:00

Commit Message:
CGE2: Implement Sprite::labVal().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 7da9535..486db29 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -180,8 +180,64 @@ void Sprite::setName(char *newName) {
 }
 
 int Sprite::labVal(Action snq, int lab) {
-	warning("STUB: Sprite::labVal()");
-	return 0;
+	int lv = -1;
+	if (active()) {
+		int n = _actionCtrl[snq]._cnt;
+		CommandHandler::Command *com = snList(snq);
+
+		int i;
+		for (i = 0; i < n; i++)
+			if (com[i]._lab == lab)
+				break;
+		if (i < n)
+			return i;
+	} else {
+		char tmpStr[kLineMax + 1];
+		_vm->mergeExt(tmpStr, _file, kSprExt);
+
+		if (_vm->_resman->exist(tmpStr)) { // sprite description file exist
+			EncryptedStream sprf(_vm, tmpStr);
+			if (sprf.err())
+				error("Bad SPR [%s]", tmpStr);
+
+			int cnt = 0;
+			int section = kIdPhase;
+			ID id;
+			Common::String line;
+
+			while (lv == -1 && !sprf.eos()) {
+				line = sprf.readLine();
+				if (line.empty())
+					continue;
+
+				Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+
+				char *p;
+				p = _vm->token(tmpStr);
+
+				if (*p == '@') {
+					if (section == snq && atoi(p + 1) == lab)
+						lv = cnt;
+				} else {
+					id = _vm->ident(p);
+					switch (id) {
+					case kIdMTake:
+					case kIdFTake:
+					case kIdNear:
+					case kIdPhase:
+					case kIdSeq:
+						section = id;
+						break;
+					default:
+						if (id < 0 && section == snq)
+							++cnt;
+						break;
+					}
+				}
+			}
+		}
+	}
+	return lv;
 }
 
 CommandHandler::Command *Sprite::snList(Action type) {


Commit: 85c55333b334f18f795118a3a3e4a2d2c210253b
    https://github.com/scummvm/scummvm/commit/85c55333b334f18f795118a3a3e4a2d2c210253b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-10T14:38:30+02:00

Commit Message:
CGE2: Handle kCmdSetRef.

Fix Snail during the process.

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 3af4c88..6957f8f 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -488,8 +488,11 @@ void CGE2Engine::snFlag(int ref, int val) {
 	warning("STUB: CGE2Engine::snFlag()");
 }
 
-void CGE2Engine::snSetRef(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snSetRef()");
+void CGE2Engine::snSetRef(Sprite *spr, int val) { // TODO:: Recheck this!
+	if (spr) {
+		spr->_ref = val;
+		_spare->update(spr);
+	}
 }
 
 void CGE2Engine::snBackPt(Sprite *spr, int val) {
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 4452471..63e85e8 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -79,6 +79,8 @@ void Spare::update(Sprite *spr) {
 	Sprite *sp = locate(spr->_ref);
 	if (sp == nullptr)
 		store(spr);
+	else
+		*sp = *spr;
 }
 
 void Spare::dispose(Sprite *spr) {


Commit: 5a5fe344a0f26f164b4908109bbf7cfa39e6c47f
    https://github.com/scummvm/scummvm/commit/5a5fe344a0f26f164b4908109bbf7cfa39e6c47f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-10T17:27:59+02:00

Commit Message:
CGE2: Implement display of speech bubbles.

The sound code connected to them is still gappy.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/general.h
    engines/cge2/snail.cpp
    engines/cge2/text.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index ff7c3e1..7a7a884 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -28,7 +28,7 @@
 #include "cge2/bitmap.h"
 #include "cge2/cge2.h"
 #include "cge2/vga13h.h"
-//#include "cge/cge_main.h"
+#include "cge2/talk.h"
 #include "common/system.h"
 #include "common/debug.h"
 #include "common/debug-channels.h"
@@ -393,4 +393,68 @@ bool Bitmap::moveLo() {
 	return true;
 }
 
+#define	_    kPixelTransp,
+#define L               1,
+#define G               2,
+#define D               3,
+#define kDesignSize   240
+
+uint8 *Bitmap::paint(int which, uint8 colorSet[][4]) {
+	uint8 kSLDesign[kDesignSize] = {
+		G G G G G G G G G _ _ _ _ _ _
+		L G G G G G G G G D _ _ _ _ _
+		_ L G G G G G G G D _ _ _ _ _
+		_ _ L G G G G G G G D _ _ _ _
+		_ _ _ L G G G G G G D _ _ _ _
+		_ _ _ _ L G G G G G D _ _ _ _
+		_ _ _ _ _ L G G G G G D _ _ _
+		_ _ _ _ _ _ L G G G G D _ _ _
+		_ _ _ _ _ _ _ L G G G D _ _ _
+		_ _ _ _ _ _ _ _ L G G G D _ _
+		_ _ _ _ _ _ _ _ _ L G G D _ _
+		_ _ _ _ _ _ _ _ _ _ L G D _ _
+		_ _ _ _ _ _ _ _ _ _ _ L G D _
+		_ _ _ _ _ _ _ _ _ _ _ _ L D _
+		_ _ _ _ _ _ _ _ _ _ _ _ _ L D
+		_ _ _ _ _ _ _ _ _ _ _ _ _ _ D
+	};
+
+	uint8 kSRDesign[kDesignSize] = {
+		_ _ _ _ _ _ G G G G G G G G G
+		_ _ _ _ _ L G G G G G G G G D
+		_ _ _ _ _ L G G G G G G G D _
+		_ _ _ _ L G G G G G G G D _ _
+		_ _ _ _ L G G G G G G D _ _ _
+		_ _ _ _ L G G G G G D _ _ _ _
+		_ _ _ L G G G G G D _ _ _ _ _
+		_ _ _ L G G G G D _ _ _ _ _ _
+		_ _ _ L G G G D _ _ _ _ _ _ _
+		_ _ L G G G D _ _ _ _ _ _ _ _
+		_ _ L G G D _ _ _ _ _ _ _ _ _
+		_ _ L G D _ _ _ _ _ _ _ _ _ _
+		_ L G D _ _ _ _ _ _ _ _ _ _ _
+		_ L D _ _ _ _ _ _ _ _ _ _ _ _
+		L D _ _ _ _ _ _ _ _ _ _ _ _ _
+		D _ _ _ _ _ _ _ _ _ _ _ _ _ _
+	};
+
+	uint8 *des = new uint8[kDesignSize];
+	switch (which) {
+	case 0:
+		memcpy(des, kSLDesign, sizeof(kSLDesign));
+		break;
+	case 1:
+		memcpy(des, kSRDesign, sizeof(kSRDesign));
+		break;
+	default:
+		error("Wrong parameter in Bitmap::paint!");
+		break;
+	}
+
+	for (int i = 0; i < kDesignSize; i++)
+		if (des[i] >= 1 && des[i] <= 3)
+			des[i] = colorSet[kCBSay][des[i]];
+	return des;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index bcc51d8..8bff8fe 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -37,7 +37,8 @@ class CGE2Engine;
 class EncryptedStream;
 class V2D;
 
-#define kMaxPath  128
+#define kMaxPath      128
+
 enum {
 	kBmpEOI = 0x0000,
 	kBmpSKP = 0x4000,
@@ -56,9 +57,13 @@ struct HideDesc {
 
 class Bitmap {
 	CGE2Engine *_vm;
+
 	char *forceExt(char *buf, const char *name, const char *ext);
 	bool loadVBM(EncryptedStream *f);
 public:
+	static uint8 *kSLDesign;
+	static uint8 *kSRDesign;
+
 	uint16 _w;
 	uint16 _h;
 	uint8 *_v;
@@ -82,6 +87,8 @@ public:
 	void xLatPos(V2D& p);
 	bool moveHi();
 	bool moveLo();
+
+	static uint8 *paint(int des, uint8 colorSet[][4]);
 };
 
 
diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index b32ca76..565615c 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -94,6 +94,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_endGame = false;
 	for (int i = 0; i < 4; i++)
 		_flag[i] = false;
+	_sayCap = true;
+	_sayVox = true;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index ebee2ed..a3d6f99 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -189,6 +189,7 @@ public:
 	void snRoom(Sprite *spr, int val);
 	void snDim(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
+	void snSay(Sprite *spr, int val);
 	
 	void hide1(Sprite *spr);
 
@@ -214,6 +215,8 @@ public:
 	bool _taken;
 	bool _endGame;
 	bool _flag[4];
+	bool _sayCap;
+	bool _sayVox;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/general.h b/engines/cge2/general.h
index 0239402..7213c2e 100644
--- a/engines/cge2/general.h
+++ b/engines/cge2/general.h
@@ -32,8 +32,6 @@
 
 namespace CGE2 {
 
-#define SCR_WID_ 320
-
 class CGE2Engine;
 
 struct Dac {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 6957f8f..aa0988f 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -126,8 +126,7 @@ void CommandHandler::runCommand() {
 			_vm->snHide(spr, tailCmd._val);
 			break;
 		case kCmdSay:
-			if (spr && spr->active() && _talkEnable) //-- mouth animation
-				warning("STUB: CommandHandler::runCommand() - Mouth animation missing!");
+			_vm->snSay(spr, tailCmd._val);
 			break;
 		case kCmdInf:
 			if (_talkEnable)
@@ -559,6 +558,24 @@ void CGE2Engine::snGhost(Bitmap *bmp) {
 	bmp = nullptr;
 }
 
+void CGE2Engine::snSay(Sprite *spr, int val) {
+	if (spr && spr->active() && _commandHandler->_talkEnable) {
+		//-- mouth animation
+		if (isHero(spr) && spr->seqTest(-1))
+			((Hero *)spr)->say();
+		if (_sayCap)
+			_text->say(_text->getText(val), spr);
+		if (_sayVox) {
+			int i = val;
+			if (i < 256)
+				i -= 100;
+			// TODO: These 2 lines may need some re-check with the whole sound-code!
+			snSound(spr, i);
+			_commandStat._wait = &_sound->_smpinf._counter;
+		}
+	}
+}
+
 void CGE2Engine::hide1(Sprite *spr) {
 	_commandHandlerTurbo->addCommand(kCmdGhost, -1, 0, spr->ghost());
 }
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index ac222f9..83088ea 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -132,7 +132,50 @@ char *Text::getText(int ref) {
 }
 
 void Text::say(const char *text, Sprite *spr) {
-	warning("STUB: Text::say()");
+	_vm->killText();
+
+	_vm->_talk = new Talk(_vm, text, kTBRound, kCBSay);
+	if (!_vm->_talk)
+		return;
+
+	Speaker *speaker = new Speaker(_vm);
+
+	bool east = spr->_flags._east;
+	V2D d(_vm, 20, spr->_siz.y - 2);
+	if (!east)
+		d.x = -d.x;
+	if (_vm->isHero(spr))
+		d = d.scale(V2D::trunc(spr->_pos3D._z));
+	V2D pos = spr->_pos2D + d;
+	uint16 sw = (speaker->_siz.x >> 1);
+	if (!east)
+		sw = -sw;
+
+	if (east) {
+		if (pos.x + sw + kTextRoundCorner + kCaptionSide >= kScrWidth)
+			east = false;
+	} else {
+		if (pos.x <= kCaptionSide + kTextRoundCorner - sw)
+			east = true;
+	}
+	if (east != (d.x > 0)) {
+		d.x = -d.x;
+		sw = -sw;
+	}
+	pos.x = spr->_pos2D.x + d.x + sw;
+
+	_vm->_talk->_flags._kill = true;
+	_vm->_talk->setName(getText(kSayName));
+	_vm->_talk->gotoxyz(pos.x, pos.y + speaker->_siz.y - 1, 0);
+
+	speaker->gotoxyz(pos.x, V2D::trunc(_vm->_talk->_pos3D._y) - speaker->_siz.y + 1, 0);
+	speaker->_flags._slav = true;
+	speaker->_flags._kill = true;
+	speaker->setName(getText(kSayName));
+	speaker->step(east);
+
+	_vm->_vga->_showQ->append(_vm->_talk);
+	_vm->_vga->_showQ->append(speaker);
 }
 
 void CGE2Engine::inf(const char *text, bool wideSpace) {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 486db29..61b367b 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1114,7 +1114,15 @@ SceneLight::SceneLight(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
 }
 
 Speaker::Speaker(CGE2Engine *vm): Sprite(vm), _vm(vm) {
-	warning("Speaker::Speaker()");
+	// Set the sprite list
+	BitmapPtr SP = new Bitmap[2];
+	uint8 *map = Bitmap::paint(0, _vm->_font->_colorSet);
+	SP[0] = Bitmap(_vm, 15, 16, map);
+	delete[] map;
+	map = Bitmap::paint(1, _vm->_font->_colorSet);
+	SP[1] = Bitmap(_vm, 15, 16, map);
+	delete[] map;
+	setShapeList(SP, 2);
 }
 
 PocLight::PocLight(CGE2Engine *vm): Sprite(vm), _vm(vm) {


Commit: 45f8bd755cd6d741f6c342272e01ce1af6464ea7
    https://github.com/scummvm/scummvm/commit/45f8bd755cd6d741f6c342272e01ce1af6464ea7
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-12T01:18:10+02:00

Commit Message:
CGE2: Fix code computing distance

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 5efb24e..d6dab6d 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -245,7 +245,7 @@ int Hero::distance(V3D pos) {
 	V3D di = _pos3D - pos;
 	long x = V2D::round(di._x);
 	long z = V2D::round(di._z);
-	return ((x * x + z * z) * (x * x + z * z));
+	return (int)sqrt((long double)(x * x + z * z));
 }
 
 int Hero::distance(Sprite *spr) {


Commit: 207f3c8be22b03b8f33e1f92a9010613747a5d03
    https://github.com/scummvm/scummvm/commit/207f3c8be22b03b8f33e1f92a9010613747a5d03
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-12T07:20:55+02:00

Commit Message:
CGE2: Implement FXP code. Still WIP, loadTab to be fixed

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h
    engines/cge2/hero.cpp
    engines/cge2/text.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index a3d6f99..cb5e620 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -43,6 +43,7 @@ class Fx;
 class Sound;
 class Text;
 struct HeroTab;
+class FXP;
 class V3D;
 class V2D;
 struct Dac;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 99b0f26..2809de1 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -702,34 +702,23 @@ void CGE2Engine::loadTab() {
 	for (int i = 0; i < kCaveMax; i++)
 		*(_eyeTab[i]) = *_eye;
 
-	/*
-	if (_resman->exist(kTabName)) {
+if  (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
 		for (int i = 0; i < kCaveMax; i++) {
-			for (int j = 0; j < 3; j++) {
-				signed b = f.readSint16BE();
-				unsigned a = f.readUint16BE();
-				uint16 round = uint16((long(a) << 16) / 100);
-				
-				if (round > 0x7FFF)
-					b++;
-			
-				switch (j) {
-				case 0:
-					_eyeTab[i]->_x = b;
-					break;
-				case 1:
-					_eyeTab[i]->_y = b;
-					break;
-				case 2:
-					_eyeTab[i]->_z = b;
-					break;
-				}
-				
-			}
+			int16 varI = f.readSint16LE();
+			int16 varF = f.readUint16LE();
+			_eyeTab[i]->_x = FXP(varI, varF);
+
+			varI = f.readSint16LE();
+			varF = f.readUint16LE();
+			_eyeTab[i]->_y = FXP(varI, varF);
+
+			varI = f.readSint16LE();
+			varF = f.readUint16LE();
+			_eyeTab[i]->_z = FXP(varI, varF);
 		}
 	}
-	*/
+
 	warning("STUB: CGE2Engine::loadTab()");
 }
 
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 4fec4a6..0ec1bce 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -228,6 +228,10 @@ signed EncryptedStream::readSint16LE() {
 	return _readStream->readSint16LE();
 }
 
+signed EncryptedStream::readUint16LE() {
+	return _readStream->readUint16LE();
+}
+
 bool EncryptedStream::err() {
 	return (_error & _readStream->err());
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 83a1456..6bf5942 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -125,6 +125,7 @@ public:
 	unsigned readUint16BE();
 	signed readSint16BE();
 	signed readSint16LE();
+	signed readUint16LE();
 	Common::String readLine();
 	int getLineCount() { return _lineCount; }
 
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index d6dab6d..2671d0e 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -205,8 +205,9 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 }
 
 void Hero::setCurrent() {
-	double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
-	int h = -(V2D::trunc(m * _siz.y));
+	FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
+	FXP tmp = m * _siz.y;
+	int h = -(tmp.trunc());
 
 	int i = 0;
 	for (; i < kDimMax; i++) {
@@ -243,15 +244,15 @@ void Hero::tick() {
 
 int Hero::distance(V3D pos) {
 	V3D di = _pos3D - pos;
-	long x = V2D::round(di._x);
-	long z = V2D::round(di._z);
-	return (int)sqrt((long double)(x * x + z * z));
+	int x = di._x.round();
+	int z = di._z.round();
+	return ((int)sqrt((long double)x * x + z * z));
 }
 
 int Hero::distance(Sprite *spr) {
 	V3D pos = spr->_pos3D;
 	int mdx = (spr->_siz.x >> 1) + (_siz.x >> 1);
-	int dx = V2D::round(_pos3D._x - spr->_pos3D._x);
+	int dx = (_pos3D._x - spr->_pos3D._x).round();
 	if (dx < 0) {
 		mdx = -mdx;
 		if (dx > mdx)
@@ -303,8 +304,8 @@ int Hero::len(V2D v) {
 }
 
 bool Hero::findWay(){
-	V2D p0(_vm, V2D::round(_pos3D._x), V2D::round(_pos3D._z));
-	V2D p1(_vm, V2D::round(_trace[_tracePtr]._x), V2D::round(_trace[_tracePtr]._z));
+	V2D p0(_vm, _pos3D._x.round(), _pos3D._z.round());
+	V2D p1(_vm, _trace[_tracePtr]._x.round(), _trace[_tracePtr]._z.round());
 	bool pvOk;
 	bool phOk;
 	V2D ph(_vm, p1.x, p0.y);
@@ -340,12 +341,12 @@ void Hero::walkTo(V3D pos) {
 	if (distance(pos) <= _maxDist)
 		return;
 	int stp = stepSize();
-	pos._x = snap(V2D::round(_pos3D._x), V2D::round(pos._x), stp);
+	pos._x = snap(_pos3D._x.round(), pos._x.round(), stp);
 	pos._y = 0;
-	pos._z = snap(V2D::round(_pos3D._z), V2D::round(pos._z), stp);
+	pos._z = snap(_pos3D._z.round(), pos._z.round(), stp);
 
-	V2D p0(_vm, V2D::round(_pos3D._x), V2D::round(_pos3D._z));
-	V2D p1(_vm, V2D::round(pos._x), V2D::round(pos._z));
+	V2D p0(_vm, _pos3D._x.round(), _pos3D._z.round());
+	V2D p1(_vm, pos._x.round(), pos._z.round());
 	resetFun();
 	int cnt = mapCross(p0, p1);
 	if ((cnt & 1) == 0) { // even == way exists
@@ -385,15 +386,15 @@ void Hero::walkTo(Sprite *spr) {
 }
 
 V3D Hero::screenToGround(V2D pos) {
-	double z = _vm->_eye->_z + (_vm->_eye->_y * _vm->_eye->_z) / (double(pos.y) - _vm->_eye->_y);
-	double x = _vm->_eye->_x - ((double(pos.x) - _vm->_eye->_x) * (z - _vm->_eye->_z)) / _vm->_eye->_z;
-	return V3D(V2D::round(x), 0, V2D::round(z));
+	FXP z = _vm->_eye->_z + (_vm->_eye->_y * _vm->_eye->_z) / (FXP(pos.y) - _vm->_eye->_y);
+	FXP x = _vm->_eye->_x - ((FXP(pos.x) - _vm->_eye->_x) * (z - _vm->_eye->_z)) / _vm->_eye->_z;
+	return V3D(x.round(), 0, z.round());
 }
 
 int Hero::cross(const V2D &a, const V2D &b) {
-	int x = V2D::trunc(_pos3D._x);
-	int z = V2D::trunc(_pos3D._z);
-	int r = ((_siz.x / 3) * V2D::trunc(_vm->_eye->_z)) / (V2D::trunc(_vm->_eye->_z) - z);
+	int x = _pos3D._x.trunc();
+	int z = _pos3D._z.trunc();
+	int r = ((_siz.x / 3) * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc()- z);
 	return _vm->cross(a, b, V2D(_vm, x - r, z), V2D(_vm, x + r, z)) << 1;
 }
 
@@ -433,7 +434,7 @@ int Hero::mapCross(const V2D &a, const V2D &b) {
 }
 
 int Hero::mapCross(const V3D &a, const V3D &b) {
-	return mapCross(V2D(_vm, V2D::round(a._x), V2D::round(a._z)), V2D(_vm, V2D::round(b._x), V2D::round(b._z)));
+	return mapCross(V2D(_vm, a._x.round(), a._z.round()), V2D(_vm, b._x.round(), b._z.round()));
 }
 
 int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 83088ea..cf4dda4 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -145,7 +145,7 @@ void Text::say(const char *text, Sprite *spr) {
 	if (!east)
 		d.x = -d.x;
 	if (_vm->isHero(spr))
-		d = d.scale(V2D::trunc(spr->_pos3D._z));
+		d = d.scale(spr->_pos3D._z.trunc());
 	V2D pos = spr->_pos2D + d;
 	uint16 sw = (speaker->_siz.x >> 1);
 	if (!east)
@@ -168,7 +168,7 @@ void Text::say(const char *text, Sprite *spr) {
 	_vm->_talk->setName(getText(kSayName));
 	_vm->_talk->gotoxyz(pos.x, pos.y + speaker->_siz.y - 1, 0);
 
-	speaker->gotoxyz(pos.x, V2D::trunc(_vm->_talk->_pos3D._y) - speaker->_siz.y + 1, 0);
+	speaker->gotoxyz(pos.x, _vm->_talk->_pos3D._y.trunc() - speaker->_siz.y + 1, 0);
 	speaker->_flags._slav = true;
 	speaker->_flags._kill = true;
 	speaker->setName(getText(kSayName));
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 61b367b..e59e825 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -531,9 +531,9 @@ void Sprite::gotoxyz(V2D pos) {
 	byte trim = 0;
 
 	if (_ref / 10 == 14) { // HERO
-		int z = V2D::trunc(_pos3D._z);
-		ctr = (ctr * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
-		rem = (rem * V2D::trunc(_vm->_eye->_z) / (V2D::trunc(_vm->_eye->_z) - z));
+		int z = _pos3D._z.trunc();
+		ctr = (ctr * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc() - z);
+		rem = (rem * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc() - z);
 		ctr = (ctr * 3) / 4;
 		rem = (rem * 3) / 4;
 	}
@@ -561,10 +561,15 @@ void Sprite::gotoxyz(V2D pos) {
 	_flags._trim = (trim != 0);
 
 	if (!_follow) {
-		double m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
-		_pos3D._x = V2D::round(_vm->_eye->_x + (_vm->_eye->_x - _pos2D.x) / m);
-		if (!_constY)
-			_pos3D._y = V2D::round(_vm->_eye->_y + (_vm->_eye->_y - _pos2D.y) / m);
+		// CHECKME: Original was using Pos2d.Eye, which shouldn't make a difference (static var)
+		FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
+		_pos3D._x = (_vm->_eye->_x + (_vm->_eye->_x - _pos2D.x) / m);
+		_pos3D._x.round();
+
+		if (!_constY) {
+			_pos3D._y = _vm->_eye->_y + (_vm->_eye->_y - _pos2D.y) / m;
+			_pos3D._y.round();
+		}
 	}
 
 	if (_next && _next->_flags._slav)
@@ -685,9 +690,23 @@ void Sprite::sync(Common::Serializer &s) {
 		s.syncAsUint16LE(flags);
 	}
 
-	s.syncAsUint16LE(_pos3D._x);
-	s.syncAsUint16LE(_pos3D._y);
-	s.syncAsByte(_pos3D._z);
+	int pos = 0;
+	if (s.isLoading()) {
+		s.syncAsSint16LE(pos);
+		_pos3D._x = FXP(pos, 0);
+		s.syncAsSint16LE(pos);
+		_pos3D._y = pos;
+		s.syncAsSint16LE(pos);
+		_pos3D._z = pos;
+	} else {
+		pos = _pos3D._x.trunc();
+		s.syncAsUint16LE(pos);
+		pos = _pos3D._y.trunc();
+		s.syncAsUint16LE(pos);
+		pos = _pos3D._z.trunc();
+		s.syncAsByte(pos);
+	}
+
 	s.syncAsUint16LE(_time);
 	s.syncAsSint16LE(_seqPtr);
 	s.syncAsUint16LE(_shpCnt);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 09eb61a..73667bc 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -51,19 +51,74 @@ namespace CGE2 {
 #define kPalCount        256
 #define kPalSize         (kPalCount * 3)
 
+// From FXP.H
+class FXP	// fixed point
+{
+	uint16 f;
+	int16 i;
+	long& Joined (void) const { return *(long *)&f; }
+public:
+	FXP (void) { }
+	FXP (int i0, int f0 = 0) : i(i0), f((int) ((((long) f0) << 16)/100)) { }
+	FXP& operator = (const int& x) { i = x; f = 0; return *this; }
+	FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined()+x.Joined(); return y; }
+	FXP operator - (const FXP& x) const { FXP y; y.Joined() = Joined()-x.Joined(); return y; }
+	FXP operator * (const FXP& x) const {
+		FXP y; long t;
+		y.i = i * x.i;
+		t = ((long) f * x.f) >> 16;
+		t += ((long) i * x.f) + ((long) f  * x.i);
+		y.f = t & 0xFFFF;
+		y.i += t >> 16;
+		return y;
+	}
+	FXP operator / (const FXP& x) const {
+		FXP y; bool sign = false;
+		long j = Joined(), jx = x.Joined();
+		if (j < 0) {
+			j = -j;
+			sign ^= 1;
+		}
+		if (jx < 0) {
+			jx = -jx;
+			sign ^= 1;
+		}
+		y.i = signed(j / jx);
+		long r = j - jx * y.i;
+		//-- binary division
+		y.f = unsigned((r << 4) / (jx >> 12));
+		//------------------
+		if (sign)
+			y.Joined() = -y.Joined();
+
+		return y;
+	}
+	//int& operator = (int& a, const FXP& b) { return a = b.i; }
+	friend int& operator += (int& a, const FXP& b) { return a += b.i; }
+	friend int& operator -= (int& a, const FXP& b) { return a -= b.i; }
+	friend FXP& operator += (FXP& a, const int& b) { a.i += b; return a; }
+	friend FXP& operator -= (FXP& a, const int& b) { a.i -= b; return a; }
+	friend bool operator == (const FXP &a, const FXP &b) { return (a.i == b.i) && (a.f == b.f); }
+	friend bool operator != (const FXP &a, const FXP &b) { return (a.i != b.i) || (a.f != b.f); }
+	friend bool operator < (const FXP &a, const FXP &b) { return (a.i < b.i) || ((a.i == b.i) && (a.f < b.f)); }
+	friend bool operator > (const FXP &a, const FXP &b) { return (a.i > b.i) || ((a.i == b.i) && (a.f > b.f)); }
+	int trunc(void) const { return i; }
+	int round(void) const { return i + (f > 0x7FFF); }
+};
+
 // From CGETYPE.H:
 class V3D {
 public:
-	double _x, _y, _z;
+	FXP _x, _y, _z;
 	V3D() { }
-	V3D(double x, double y, double z = 0) : _x(x), _y(y), _z(z) { }
+	V3D(FXP x, FXP y, FXP z = 0) : _x(x), _y(y), _z(z) { }
 	V3D(const V3D &p) : _x(p._x), _y(p._y), _z(p._z) { }
 	V3D operator+(const V3D &p) const { return V3D(_x + p._x, _y + p._y, _z + p._z); }
 	V3D operator-(const V3D &p) const { return V3D(_x - p._x, _y - p._y, _z - p._z); }
 	V3D operator*(long n) const { return V3D(_x * n, _y * n, _z * n); }
 	V3D operator/ (long n) const { return V3D(_x / n, _y / n, _z / n); }
-	bool operator==(V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
-	bool operator!=(V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
+	bool operator==(const V3D &p) const { return _x == p._x && _y == p._y && _z == p._z; }
+	bool operator!=(const V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
 	V3D& operator+=(const V3D &x) { return *this = *this + x; }
 	V3D& operator-=(const V3D &x) { return *this = *this - x; }
 };
@@ -72,11 +127,11 @@ class V2D : public Common::Point {
 	CGE2Engine *_vm;
 public:
 	V2D& operator=(const V3D &p3) {
-		if (p3._z == 200)
-			warning("");
-		double m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
-		x = round(_vm->_eye->_x + (_vm->_eye->_x - p3._x) * m);
-		y = round(_vm->_eye->_y + (_vm->_eye->_y - p3._y) * m);
+		FXP m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
+		FXP posx = _vm->_eye->_x + (_vm->_eye->_x - p3._x) * m;
+		x = posx.round();
+		FXP posy = _vm->_eye->_y + (_vm->_eye->_y - p3._y) * m;
+		y = posy.round();
 		return *this;
 	}
 	V2D(CGE2Engine *vm) : _vm(vm) { }
@@ -88,14 +143,17 @@ public:
 	bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
 	V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
 	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
+	bool operator==(const V3D &p) const { V3D tmp(x, y); return tmp._x == p._x && tmp._y == p._y && tmp._z == p._z; }
+	bool operator!=(const V3D &p) const { V3D tmp(x, y); return tmp._x != p._x || tmp._y != p._y || tmp._z == p._z; }
 	uint16 area() { return x * y; }
 	bool limited(const V2D &p) {
-		return (uint16(x) < uint16(p.x)) && (uint16(y) < uint16(p.y));
+		return ((x < p.x) && (y < p.y));
 	}
-	V2D scale(int z) {
-		double m = _vm->_eye->_z / (_vm->_eye->_z - z);
-		warning("scale: %f %f %f, x, y, m");
-		return V2D(_vm, trunc(m * x), trunc(m * y));
+	V2D scale (int z) {
+		FXP m = _vm->_eye->_z / (_vm->_eye->_z - z);
+		FXP posx = m * x;
+		FXP posy = m * y;
+		return V2D(_vm, posx.trunc(), posy.trunc());
 	}
 	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
 	static double round(double number) { return number < 0.0 ? ceil(number) : floor(number); }


Commit: dfc94267d568a8e7b261961417fdf5716717cbd0
    https://github.com/scummvm/scummvm/commit/dfc94267d568a8e7b261961417fdf5716717cbd0
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-12T21:05:19+02:00

Commit Message:
CGE2: Get somewhat better values

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2809de1..032c73c 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -705,16 +705,28 @@ void CGE2Engine::loadTab() {
 if  (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
 		for (int i = 0; i < kCaveMax; i++) {
-			int16 varI = f.readSint16LE();
-			int16 varF = f.readUint16LE();
+			int16 varI = f.readSint16BE();
+			int16 varF = f.readUint16BE();
+			if (varF & 0x8000) {
+				varI = -varI;
+				varF &= 0x7FFF;
+			}
 			_eyeTab[i]->_x = FXP(varI, varF);
 
-			varI = f.readSint16LE();
-			varF = f.readUint16LE();
+			varI = f.readSint16BE();
+			varF = f.readUint16BE();
+			if (varF & 0x8000) {
+				varI = -varI;
+				varF &= 0x7FFF;
+			}
 			_eyeTab[i]->_y = FXP(varI, varF);
 
-			varI = f.readSint16LE();
-			varF = f.readUint16LE();
+			varI = f.readSint16BE();
+			varF = f.readUint16BE();
+			if (varF & 0x8000) {
+				varI = -varI;
+				varF &= 0x7FFF;
+			}
 			_eyeTab[i]->_z = FXP(varI, varF);
 		}
 	}


Commit: 162c840937027ae2935fddd7d660c28713a7b004
    https://github.com/scummvm/scummvm/commit/162c840937027ae2935fddd7d660c28713a7b004
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-06-12T23:49:06-04:00

Commit Message:
CGE2: Fix FXP initialiation and division operator

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 73667bc..dee551f 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -58,7 +58,7 @@ class FXP	// fixed point
 	int16 i;
 	long& Joined (void) const { return *(long *)&f; }
 public:
-	FXP (void) { }
+	FXP (void): f(0), i(0) { }
 	FXP (int i0, int f0 = 0) : i(i0), f((int) ((((long) f0) << 16)/100)) { }
 	FXP& operator = (const int& x) { i = x; f = 0; return *this; }
 	FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined()+x.Joined(); return y; }
@@ -74,22 +74,24 @@ public:
 	}
 	FXP operator / (const FXP& x) const {
 		FXP y; bool sign = false;
-		long j = Joined(), jx = x.Joined();
-		if (j < 0) {
-			j = -j;
-			sign ^= 1;
+		if (!x.empty()) {
+			long j = Joined(), jx = x.Joined();
+			if (j < 0) {
+				j = -j;
+				sign ^= 1;
+			}
+			if (jx < 0) {
+				jx = -jx;
+				sign ^= 1;
+			}
+			y.i = signed(j / jx);
+			long r = j - jx * y.i;
+			//-- binary division
+			y.f = unsigned((r << 4) / (jx >> 12));
+			//------------------
+			if (sign)
+				y.Joined() = -y.Joined();
 		}
-		if (jx < 0) {
-			jx = -jx;
-			sign ^= 1;
-		}
-		y.i = signed(j / jx);
-		long r = j - jx * y.i;
-		//-- binary division
-		y.f = unsigned((r << 4) / (jx >> 12));
-		//------------------
-		if (sign)
-			y.Joined() = -y.Joined();
 
 		return y;
 	}
@@ -104,6 +106,7 @@ public:
 	friend bool operator > (const FXP &a, const FXP &b) { return (a.i > b.i) || ((a.i == b.i) && (a.f > b.f)); }
 	int trunc(void) const { return i; }
 	int round(void) const { return i + (f > 0x7FFF); }
+	bool empty() const { return i == 0 && f == 0; }
 };
 
 // From CGETYPE.H:


Commit: 6ac5e2cfcfa3e13b3eb93c88790c7babcb7af6d2
    https://github.com/scummvm/scummvm/commit/6ac5e2cfcfa3e13b3eb93c88790c7babcb7af6d2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T14:07:35+02:00

Commit Message:
CGE2: Fix initialization of HeroTab.

Changed paths:
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index c993386..26b6dcc 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -46,6 +46,11 @@ struct HeroTab {
 	int _pocPtr;
 	V2D *_posTab[kCaveMax];
 	HeroTab(CGE2Engine *vm) {
+		_ptr = nullptr;
+		_face = nullptr;
+		for (int i = 0; i < kPocketMax + 1; i++)
+			_pocket[i] = nullptr;
+		_pocPtr = 0;
 		for (int i = 0; i < kCaveMax; i++)
 			_posTab[i] = new V2D(vm);
 	}


Commit: 95c844a0351d8865aa5190bb5572dff23b8886fd
    https://github.com/scummvm/scummvm/commit/95c844a0351d8865aa5190bb5572dff23b8886fd
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T16:13:36+02:00

Commit Message:
CGE2: Implement snKill().

Add and implement Sprite::setCave() during the process.

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index aa0988f..07cded0 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -30,6 +30,7 @@
 #include "cge2/hero.h"
 #include "cge2/text.h"
 #include "cge2/sound.h"
+#include "cge2/events.h"
 
 namespace CGE2 {
 
@@ -324,7 +325,22 @@ void CommandHandler::runCommand() {
 }
 
 void CGE2Engine::snKill(Sprite *spr) {
-	warning("STUB: CGE2Engine::snKill()");
+	if (spr) {
+		if (spr->_flags._kept)
+			releasePocket(spr);
+		Sprite *nx = spr->_next;
+		hide1(spr);
+		_vga->_showQ->remove(spr);
+		_eventManager->clearEvent(spr);
+		if (spr->_flags._kill)
+			delete spr;
+		else {
+			spr->setCave(-1);
+			_spare->dispose(spr);
+		}
+		if (nx && nx->_flags._slav)
+			snKill(nx);
+	}
 }
 
 void CGE2Engine::snHide(Sprite *spr, int val) {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index e59e825..28f738c 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -516,6 +516,10 @@ void Sprite::tick() {
 	step();
 }
 
+void Sprite::setCave(int c) {
+	_scene = c;
+}
+
 void Sprite::gotoxyz(int x, int y, int z) {
 	gotoxyz(V3D(x, y, z));
 }
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index dee551f..c864e48 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -262,6 +262,7 @@ public:
 	CommandHandler::Command *snList(Action type);
 	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
 	virtual void tick();
+	virtual void setCave(int c);
 	void clrHide() { if (_ext) _ext->_b0 = NULL; }
 	void sync(Common::Serializer &s);
 


Commit: 2ad2be370e6464a660170ff19a0c74d6fb77e055
    https://github.com/scummvm/scummvm/commit/2ad2be370e6464a660170ff19a0c74d6fb77e055
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T16:31:32+02:00

Commit Message:
CGE2: Implement Hero::tick().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 2671d0e..a4d0441 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -239,7 +239,62 @@ Sprite *Hero::setContact() {
 }
 
 void Hero::tick() {
-	warning("STUB: Hero::tick()");
+	int z = _pos3D._z.trunc();
+	//-- maybe not exactly wid/2, but wid/3 ?
+	int d = ((_siz.x / 2) * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc() - z);
+
+	if (_dir != kNoDir) { // just walking...
+		if (_flags._hold || _tracePtr < 0)
+			park();
+		else {
+			Sprite *spr = setContact();
+			if (spr)
+				_vm->feedSnail(spr, kNear, this);
+		}
+	}
+	//---------------------------------------------------------------
+	if (_tracePtr >= 0) {
+		if (distance(_trace[_tracePtr]) <= _maxDist)
+			--_tracePtr;
+
+		if (_tracePtr < 0)
+			park();
+		else {
+			int stp = stepSize() / 2;
+			int dx = _trace[_tracePtr]._x.round() - _pos3D._x.round();
+			int dz = _trace[_tracePtr]._z.round() - _pos3D._z.round();
+			Dir dir = (dx > stp) ? kEE : ((-dx > stp) ? kWW : ((dz > stp) ? kNN : kSS));
+			turn(dir);
+		}
+	}
+
+	//---------------------------------------------------------------
+	hStep();
+	setCurrent();
+	switch (_dir) {
+	case kSS:
+		if (_pos3D._z < stepSize() / 2)
+			park();
+		break;
+	case kWW:
+		if (_pos2D.x <= d)
+			park();
+		break;
+	case kNN:
+		if (_pos3D._z > kScrDepth)
+			park();
+		break;
+	case kEE:
+		if (_pos2D.x >= kScrWidth - 1 - d)
+			park();
+		break;
+	}
+	if (_flags._trim)
+		gotoxyz_(_pos2D);
+	if (_pos3D._z.trunc() != z)
+		_flags._zmov = true;
+	if (--_funDel == 0)
+		fun();
 }
 
 int Hero::distance(V3D pos) {


Commit: bad8e7ea26a645affa74e2971fdac87e4afc20e7
    https://github.com/scummvm/scummvm/commit/bad8e7ea26a645affa74e2971fdac87e4afc20e7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T17:02:17+02:00

Commit Message:
CGE2: Fix Sprite::ghost and snGhost().

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 07cded0..c086d2b 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -565,7 +565,7 @@ void CGE2Engine::snDim(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snGhost(Bitmap *bmp) {
-	V2D p(this, *bmp->_v & 0xFFFF, *bmp->_v >> 16);
+	V2D p(this, bmp->_map & 0xFFFF, bmp->_map >> 16);
 	bmp->hide(p.x, p.y);
 	delete[] bmp->_b;
 	bmp->_v = nullptr;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 28f738c..2498781 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -641,6 +641,7 @@ BitmapPtr Sprite::ghost() {
 	uint8 *v = new uint8;
 	*v = (e->_p1.y << 16) + e->_p1.x;
 	bmp->_v = v;
+	bmp->_map = (e->_p1.y << 16) + e->_p1.x;
 
 	return bmp;
 }


Commit: 235d0fffbd0f827b6dd43ba52a934417b75efbab
    https://github.com/scummvm/scummvm/commit/235d0fffbd0f827b6dd43ba52a934417b75efbab
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T19:36:36+02:00

Commit Message:
CGE2: Reimplement Hero::setCave().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index a4d0441..87e74f0 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -513,7 +513,7 @@ int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
 }
 
 void Hero::setCave(int c) {
-	_scene = c;
+	Sprite::setCave(c);
 	resetFun();
 }
 


Commit: 3aae5cfa06c0753f20631fe2843f69f08f0ae6fd
    https://github.com/scummvm/scummvm/commit/3aae5cfa06c0753f20631fe2843f69f08f0ae6fd
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T19:39:24+02:00

Commit Message:
CGE2: Implement Hero::hStep().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 87e74f0..d2c1b64 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -219,7 +219,20 @@ void Hero::setCurrent() {
 }
 
 void Hero::hStep() {
-	warning("STUB: Hero::hStep()");
+	if (!_ignoreMap && _ext) {
+		Seq *seq = _ext->_seq;
+		int ptr = seq[_seqPtr]._next;
+		seq += ptr;
+		if (seq->_dx | seq->_dz) {
+			V2D p0(_vm, _pos3D._x.round(), _pos3D._z.round());
+			V2D p1(_vm, p0.x + seq->_dx, p0.y + seq->_dz);
+			if (mapCross(p0, p1)) {
+				park();
+				return;
+			}
+		}
+	}
+	step();
 }
 
 Sprite *Hero::setContact() {


Commit: 95e3f240d620f5e3788743782ef910446a01ab79
    https://github.com/scummvm/scummvm/commit/95e3f240d620f5e3788743782ef910446a01ab79
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T19:41:43+02:00

Commit Message:
CGE2: Implement Hero::turn().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index d2c1b64..49d1361 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -337,7 +337,12 @@ int Hero::distance(Sprite *spr) {
 }
 
 void Hero::turn(Dir d) {
-	warning("STUB: Hero::turn()");
+	Dir dir = (_dir == kNoDir) ? kSS : _dir;
+	if (d != _dir) {
+		step((d == dir) ? 57 : (8 + 4 * dir + d));
+		_dir = d;
+	}
+	resetFun();
 }
 
 void Hero::park() {


Commit: 0bd781a3dcb844ffc570166ee53084ed1b643c00
    https://github.com/scummvm/scummvm/commit/0bd781a3dcb844ffc570166ee53084ed1b643c00
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T19:52:28+02:00

Commit Message:
CGE2: Implement releasePocket().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 032c73c..655910f 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -685,7 +685,16 @@ void CGE2Engine::loadPos() {
 }
 
 void CGE2Engine::releasePocket(Sprite *spr) {
-	warning("STUB: CGE2Engine::releasePocket()");
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax; j++) {
+			Sprite *poc = _heroTab[i]->_pocket[j];
+			if (poc == spr) {
+				spr->_flags._kept = false;
+				poc = nullptr;
+				return;
+			}
+		}
+	}
 }
 
 void CGE2Engine::checkSaySwitch() {


Commit: 52fb03fc97d852a0a5c19d72599d678ac536514d
    https://github.com/scummvm/scummvm/commit/52fb03fc97d852a0a5c19d72599d678ac536514d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T22:19:41+02:00

Commit Message:
CGE2: Fix Sprite::touch().

Not it only takes action if the user actually clicked.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 655910f..d9d22c8 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -910,57 +910,59 @@ void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
 		return;
 	}
 
-	if (_vm->isHero(this) && !_vm->_blinkSprite) {
-		_vm->switchHero((this == _vm->_heroTab[1]->_ptr) ? 1 : 0);
-	} else if (_flags._kept) { // sprite in pocket
-		for (int sex = 0; sex < 2; ++sex) {
-			for (int p = 0; p < kPocketMax; ++p) {
-				if (_vm->_heroTab[sex]->_pocket[p] == this) {
-					_vm->switchHero(sex);
-					if (_vm->_sex == sex) {
-						if (_vm->_blinkSprite)
-							_vm->_blinkSprite->_flags._hide = false;
-						if (_vm->_blinkSprite == this)
-							_vm->_blinkSprite = nullptr;
-						else
-							_vm->_blinkSprite = this;
+	if ((mask & kMouseLeftUp) && _vm->_commandHandler->idle()) {
+		if (_vm->isHero(this) && !_vm->_blinkSprite) {
+			_vm->switchHero((this == _vm->_heroTab[1]->_ptr) ? 1 : 0);
+		} else if (_flags._kept) { // sprite in pocket
+			for (int sex = 0; sex < 2; ++sex) {
+				for (int p = 0; p < kPocketMax; ++p) {
+					if (_vm->_heroTab[sex]->_pocket[p] == this) {
+						_vm->switchHero(sex);
+						if (_vm->_sex == sex) {
+							if (_vm->_blinkSprite)
+								_vm->_blinkSprite->_flags._hide = false;
+							if (_vm->_blinkSprite == this)
+								_vm->_blinkSprite = nullptr;
+							else
+								_vm->_blinkSprite = this;
+						}
 					}
 				}
 			}
-		}
-	} else { // sprite NOT in pocket
-		Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
-		if (!_vm->_talk) {
-			if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1))
-				h->walkTo(this);
-			else if (_vm->_blinkSprite) {
-				if (works(_vm->_blinkSprite)) {
-					_vm->feedSnail(_vm->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
-					_vm->_blinkSprite->_flags._hide = false;
-					_vm->_blinkSprite = nullptr;
-				} else
-					_vm->offUse();
-
-				_vm->selectPocket(-1);
-			// else, no pocket sprite selected
-			} else if (_flags._port) { // portable
-				if (_vm->findActivePocket(-1) < 0)
-					_vm->pocFul();
-				else {
-					_vm->_commandHandler->addCommand(kCmdReach, -2, _ref, nullptr);
-					_vm->_commandHandler->addCommand(kCmdKeep, -1, -1, this);
-					_flags._port = false;
-				}
-			} else { // non-portable
-				Action a = h->action();
-				if (_actionCtrl[a]._cnt) {
-					CommandHandler::Command *cmdList = snList(a);
-					if (cmdList[_actionCtrl[a]._ptr]._commandType == kCmdNext)
+		} else { // sprite NOT in pocket
+			Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
+			if (!_vm->_talk) {
+				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1))
+					h->walkTo(this);
+				else if (_vm->_blinkSprite) {
+					if (works(_vm->_blinkSprite)) {
+						_vm->feedSnail(_vm->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
+						_vm->_blinkSprite->_flags._hide = false;
+						_vm->_blinkSprite = nullptr;
+					} else
 						_vm->offUse();
-					else
-						_vm->feedSnail(this, a, h);
-				} else
-					_vm->offUse();
+
+					_vm->selectPocket(-1);
+					// else, no pocket sprite selected
+				} else if (_flags._port) { // portable
+					if (_vm->findActivePocket(-1) < 0)
+						_vm->pocFul();
+					else {
+						_vm->_commandHandler->addCommand(kCmdReach, -2, _ref, nullptr);
+						_vm->_commandHandler->addCommand(kCmdKeep, -1, -1, this);
+						_flags._port = false;
+					}
+				} else { // non-portable
+					Action a = h->action();
+					if (_actionCtrl[a]._cnt) {
+						CommandHandler::Command *cmdList = snList(a);
+						if (cmdList[_actionCtrl[a]._ptr]._commandType == kCmdNext)
+							_vm->offUse();
+						else
+							_vm->feedSnail(this, a, h);
+					} else
+						_vm->offUse();
+				}
 			}
 		}
 	}


Commit: 63c0cb40feb9acfb600503688358af28da4f14b7
    https://github.com/scummvm/scummvm/commit/63c0cb40feb9acfb600503688358af28da4f14b7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T22:20:19+02:00

Commit Message:
CGE2: Stub snSay again.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index c086d2b..ee94ab8 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -585,9 +585,7 @@ void CGE2Engine::snSay(Sprite *spr, int val) {
 			int i = val;
 			if (i < 256)
 				i -= 100;
-			// TODO: These 2 lines may need some re-check with the whole sound-code!
-			snSound(spr, i);
-			_commandStat._wait = &_sound->_smpinf._counter;
+			warning("STUB: CGE2Engine::snSay"); // TODO: Implement it with the revision of the sound code!
 		}
 	}
 }


Commit: 2b5eec4427814e501f4a11103befedaf4628f528
    https://github.com/scummvm/scummvm/commit/2b5eec4427814e501f4a11103befedaf4628f528
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T22:29:39+02:00

Commit Message:
CGE2: Implement snCover and snUncover.

Also add and implement expandSprite().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index cb5e620..968fe2b 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -193,6 +193,7 @@ public:
 	void snSay(Sprite *spr, int val);
 	
 	void hide1(Sprite *spr);
+	Sprite *expandSprite(Sprite *spr);
 
 	const ADGameDescription *_gameDescription;
 
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index ee94ab8..86ce006 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -416,12 +416,40 @@ void CGE2Engine::snSend(Sprite *spr, int val) {
 void CGE2Engine::snSwap(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snSwap()");
 }
+
 void CGE2Engine::snCover(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snCover()");
+	bool tak = _taken;
+	Sprite *xspr = locate(val);
+	if (spr && xspr) {
+		spr->_flags._hide = true;
+		xspr->setCave(spr->_scene);
+		xspr->gotoxyz(spr->_pos3D);
+		expandSprite(xspr);
+		if ((xspr->_flags._shad = spr->_flags._shad) == true) {
+			_vga->_showQ->insert(_vga->_showQ->remove(spr->_prev), xspr);
+			spr->_flags._shad = false;
+		}
+		feedSnail(xspr, kNear, _heroTab[_sex]->_ptr);
+		_taken = false;
+	}
+	if (_taken)
+		_spare->dispose(xspr);
+	_taken = tak;
 }
 
 void CGE2Engine::snUncover(Sprite *spr, Sprite *spr2) {
-	warning("STUB: CGE2Engine::snUncover()");
+	if (spr && spr2) {
+		spr->_flags._hide = false;
+		spr->setCave(spr2->_scene);
+		if ((spr->_flags._shad = spr2->_flags._shad) == true) {
+			_vga->_showQ->insert(_vga->_showQ->remove(spr2->_prev), spr);
+			spr2->_flags._shad = false;
+		}
+		spr->gotoxyz(spr2->_pos3D);
+		snSend(spr2, -1);
+		if (spr->_time == 0)
+			++spr->_time;
+	}
 }
 
 void CGE2Engine::snFocus(int val) {
@@ -594,6 +622,12 @@ void CGE2Engine::hide1(Sprite *spr) {
 	_commandHandlerTurbo->addCommand(kCmdGhost, -1, 0, spr->ghost());
 }
 
+Sprite *CGE2Engine::expandSprite(Sprite *spr) {
+	if (spr)
+		_vga->_showQ->insert(spr);
+	return spr;
+}
+
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
 	if (ref == 2)
 		ref = 142 - _vm->_sex;


Commit: a2c3a11708840f7b21d971241ad2b1fa70d74025
    https://github.com/scummvm/scummvm/commit/a2c3a11708840f7b21d971241ad2b1fa70d74025
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-13T22:36:32+02:00

Commit Message:
CGE2: Rename setCave() to setScene().

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h
    engines/cge2/snail.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 49d1361..f68cf82 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -530,8 +530,8 @@ int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
 	return cnt;
 }
 
-void Hero::setCave(int c) {
-	Sprite::setCave(c);
+void Hero::setScene(int c) {
+	Sprite::setScene(c);
 	resetFun();
 }
 
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 26b6dcc..69ee7b7 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -102,7 +102,7 @@ public:
 	Action action() { return (Action)(_ref % 10); }
 	void reach(int mode);
 	void setCurrent();
-	void setCave(int c);
+	void setScene(int c);
 	void operator++();
 	void operator--();
 };
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 86ce006..bf9108d 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -335,7 +335,7 @@ void CGE2Engine::snKill(Sprite *spr) {
 		if (spr->_flags._kill)
 			delete spr;
 		else {
-			spr->setCave(-1);
+			spr->setScene(-1);
 			_spare->dispose(spr);
 		}
 		if (nx && nx->_flags._slav)
@@ -422,7 +422,7 @@ void CGE2Engine::snCover(Sprite *spr, int val) {
 	Sprite *xspr = locate(val);
 	if (spr && xspr) {
 		spr->_flags._hide = true;
-		xspr->setCave(spr->_scene);
+		xspr->setScene(spr->_scene);
 		xspr->gotoxyz(spr->_pos3D);
 		expandSprite(xspr);
 		if ((xspr->_flags._shad = spr->_flags._shad) == true) {
@@ -440,7 +440,7 @@ void CGE2Engine::snCover(Sprite *spr, int val) {
 void CGE2Engine::snUncover(Sprite *spr, Sprite *spr2) {
 	if (spr && spr2) {
 		spr->_flags._hide = false;
-		spr->setCave(spr2->_scene);
+		spr->setScene(spr2->_scene);
 		if ((spr->_flags._shad = spr2->_flags._shad) == true) {
 			_vga->_showQ->insert(_vga->_showQ->remove(spr2->_prev), spr);
 			spr2->_flags._shad = false;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 2498781..71e472f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -516,7 +516,7 @@ void Sprite::tick() {
 	step();
 }
 
-void Sprite::setCave(int c) {
+void Sprite::setScene(int c) {
 	_scene = c;
 }
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index c864e48..67506c8 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -262,7 +262,7 @@ public:
 	CommandHandler::Command *snList(Action type);
 	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
 	virtual void tick();
-	virtual void setCave(int c);
+	virtual void setScene(int c);
 	void clrHide() { if (_ext) _ext->_b0 = NULL; }
 	void sync(Common::Serializer &s);
 


Commit: 28717ff056015d3aafdb1c91b7535cdc82a235cf
    https://github.com/scummvm/scummvm/commit/28717ff056015d3aafdb1c91b7535cdc82a235cf
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-06-13T23:22:44-04:00

Commit Message:
CGE2: Fix vertical screen clipping in Bitmap::show and Bitmap::hide

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 71e472f..302d129 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1064,8 +1064,11 @@ void Bitmap::show(int16 x, int16 y) {
 	xLatPos(pos);
 	x = pos.x;
 	y = pos.y;
+
+	// TODO: This doesn't currently support left/right side clipping
 	const byte *srcP = (const byte *)_v;
-	byte *destEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
+	byte *screenStartP = (byte *)_vm->_vga->_page[1]->getPixels();
+	byte *screenEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
 
 	// Loop through processing data for each plane. The game originally ran in plane mapped mode, where a
 	// given plane holds each fourth pixel sequentially. So to handle an entire picture, each plane's data
@@ -1084,8 +1087,6 @@ void Bitmap::show(int16 x, int16 y) {
 				break;
 			}
 
-			assert(destP < destEndP);
-
 			// Handle a set of pixels
 			while (count-- > 0) {
 				// Transfer operation
@@ -1095,11 +1096,14 @@ void Bitmap::show(int16 x, int16 y) {
 					break;
 				case 2:
 					// REPEAT
-					*destP = *srcP;
+					if (destP >= screenStartP && destP < screenEndP)
+						*destP = *srcP;
 					break;
 				case 3:
 					// COPY
-					*destP = *srcP++;
+					if (destP >= screenStartP && destP < screenEndP)
+						*destP = *srcP;
+					srcP++;
 					break;
 				}
 
@@ -1120,10 +1124,12 @@ void Bitmap::hide(int16 x, int16 y) {
 	x = pos.x;
 	y = pos.y;
 	for (int yp = y; yp < y + _h; yp++) {
-		const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(x, yp);
-		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x, yp);
+		if (yp >= 0 && yp < kScrHeight) {
+			const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(x, yp);
+			byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x, yp);
 
-		Common::copy(srcP, srcP + _w, destP);
+			Common::copy(srcP, srcP + _w, destP);
+		}
 	}
 }
 


Commit: 3d63184fee4e8b533763ecf2cae187f76954ac97
    https://github.com/scummvm/scummvm/commit/3d63184fee4e8b533763ecf2cae187f76954ac97
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-14T19:46:18+02:00

Commit Message:
CGE2: Rethink Spare::dispose().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d9d22c8..9a736ef 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -370,7 +370,7 @@ void CGE2Engine::loadScript(const char *fname) {
 
 			int n = _spare->count();
 			if (_spare->locate(_sprite->_ref) == nullptr)
-				_spare->store(_sprite);
+				_spare->dispose(_sprite);
 			_sprite = nullptr;
 			if (_spare->count() == n)
 				error("Durplicated reference! %s", SpN);
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 63e85e8..9531fe6 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -87,16 +87,6 @@ void Spare::dispose(Sprite *spr) {
 	if (spr) {
 		_vm->_vga->_showQ->remove(spr);
 		update(spr->contract());
-		if (!_vm->isHero(spr)) {
-			for (uint i = 0; i < _container.size(); ++i) {
-				if (spr == _container[i]) {
-					_container.remove_at(i);
-					delete spr;
-					spr = nullptr;
-					break;
-				}
-			}
-		}
 	}
 }
 


Commit: 58c312d9e9ac5d78e39ee2ddbb40305bba689aec
    https://github.com/scummvm/scummvm/commit/58c312d9e9ac5d78e39ee2ddbb40305bba689aec
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-14T20:13:08+02:00

Commit Message:
CGE2: Implement snReach() and connected functions.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index f68cf82..2090d49 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -360,12 +360,29 @@ void Hero::park() {
 }
 
 bool Hero::lower(Sprite * spr) {
-		warning("STUB: Hero::lower()");
-		return false;
+	return (spr->_pos3D._y + (spr->_siz.y >> 2) < 10);
 }
 
 void Hero::reach(int mode) {
-	warning("STUB: Hero::reach()");
+	Sprite *spr = nullptr;
+	if (mode >= 4) {
+		spr = _vm->_vga->_showQ->locate(mode);
+		if (spr) {
+			mode = !spr->_flags._east;      // 0-1
+			if (lower(spr))                 // 2-3
+				mode += 2;
+		}
+	}
+	// note: insert SNAIL commands in reverse order
+	_vm->_commandHandler->insertCommand(kCmdPause, -1, 24, nullptr);
+	_vm->_commandHandler->insertCommand(kCmdSeq, -1, _reachStart + _reachCycle * mode, this);
+	if (spr) {
+		_vm->_commandHandler->insertCommand(kCmdWait, -1, -1, this);
+		_vm->_commandHandler->insertCommand(kCmdWalk, -1, spr->_ref, this);
+	}
+	// sequence is not finished,
+	// now it is just at sprite appear (disappear) point
+	resetFun();
 }
 
 void Hero::fun() {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index bf9108d..f8664b4 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -559,7 +559,8 @@ void CGE2Engine::snWalk(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snReach(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snReach()");
+	if (isHero(spr))
+		((Hero *)spr)->reach(val);
 }
 
 void CGE2Engine::snSound(Sprite *spr, int wav) {
@@ -647,7 +648,20 @@ void CommandHandler::addCallback(CommandType com, int ref, int val, CallbackType
 }
 
 void CommandHandler::insertCommand(CommandType com, int ref, int val, void *ptr) {
-	warning("STUB: CommandHandler::insertCommand()");
+	if (ref == -2)
+		ref = 142 - _vm->_sex;
+	--_tail;
+	Command *tailCmd = &_commandList[_tail];
+	tailCmd->_commandType = com;
+	tailCmd->_ref = ref;
+	tailCmd->_val = val;
+	tailCmd->_spritePtr = ptr;
+	tailCmd->_cbType = kNullCB;
+	if (com == kCmdClear) {
+		_tail = _head;
+		_vm->killText();
+		_timerExpiry = 0;
+	}
 }
 
 bool CommandHandler::idle() {


Commit: 600c32adf91a3fa4d8c54e4b7f85bd8cc06b6746
    https://github.com/scummvm/scummvm/commit/600c32adf91a3fa4d8c54e4b7f85bd8cc06b6746
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-14T20:27:26+02:00

Commit Message:
CGE2: Implement snWalk().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index f8664b4..6b9ade6 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -555,7 +555,16 @@ void CGE2Engine::snCycle(int cnt) {
 }
 
 void CGE2Engine::snWalk(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snWalk()");
+	if (isHero(spr)) {
+		if (val < kMaxPoint)
+			((Hero *)spr)->walkTo(*_point[val]);
+		else {
+			Sprite *s = _vga->_showQ->locate(val);
+			if (s)
+				((Hero *)spr)->walkTo(s);
+		}
+		((Hero *)spr)->_time = 1;
+	}
 }
 
 void CGE2Engine::snReach(Sprite *spr, int val) {


Commit: c48c585f88a4c037e3fe5f2363a7aaca1946b343
    https://github.com/scummvm/scummvm/commit/c48c585f88a4c037e3fe5f2363a7aaca1946b343
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-06-14T19:34:30-04:00

Commit Message:
CGE2: Fix loading of fixed-point integer values

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9a736ef..802b72e 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -711,36 +711,21 @@ void CGE2Engine::loadTab() {
 	for (int i = 0; i < kCaveMax; i++)
 		*(_eyeTab[i]) = *_eye;
 
-if  (_resman->exist(kTabName)) {
+	if  (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
+		uint32 v;
+
 		for (int i = 0; i < kCaveMax; i++) {
-			int16 varI = f.readSint16BE();
-			int16 varF = f.readUint16BE();
-			if (varF & 0x8000) {
-				varI = -varI;
-				varF &= 0x7FFF;
-			}
-			_eyeTab[i]->_x = FXP(varI, varF);
+			v = f.readUint32LE();
+			_eyeTab[i]->_x = FXP(v >> 8, static_cast<int>((int8)(v & 0xff)));
 
-			varI = f.readSint16BE();
-			varF = f.readUint16BE();
-			if (varF & 0x8000) {
-				varI = -varI;
-				varF &= 0x7FFF;
-			}
-			_eyeTab[i]->_y = FXP(varI, varF);
+			v = f.readUint32LE();
+			_eyeTab[i]->_y = FXP(v >> 8, static_cast<int>((int8)(v & 0xff)));
 
-			varI = f.readSint16BE();
-			varF = f.readUint16BE();
-			if (varF & 0x8000) {
-				varI = -varI;
-				varF &= 0x7FFF;
-			}
-			_eyeTab[i]->_z = FXP(varI, varF);
+			v = f.readUint32LE();
+			_eyeTab[i]->_z = FXP(v >> 8, static_cast<int>((int8)(v & 0xff)));
 		}
 	}
-
-	warning("STUB: CGE2Engine::loadTab()");
 }
 
 void CGE2Engine::cge2_main() {
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 0ec1bce..cc07ef6 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -232,6 +232,10 @@ signed EncryptedStream::readUint16LE() {
 	return _readStream->readUint16LE();
 }
 
+uint32 EncryptedStream::readUint32LE() {
+	return _readStream->readUint32LE();
+}
+
 bool EncryptedStream::err() {
 	return (_error & _readStream->err());
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 6bf5942..0938507 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -126,6 +126,7 @@ public:
 	signed readSint16BE();
 	signed readSint16LE();
 	signed readUint16LE();
+	uint32 readUint32LE();
 	Common::String readLine();
 	int getLineCount() { return _lineCount; }
 
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 302d129..5c3b59b 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1065,7 +1065,6 @@ void Bitmap::show(int16 x, int16 y) {
 	x = pos.x;
 	y = pos.y;
 
-	// TODO: This doesn't currently support left/right side clipping
 	const byte *srcP = (const byte *)_v;
 	byte *screenStartP = (byte *)_vm->_vga->_page[1]->getPixels();
 	byte *screenEndP = (byte *)_vm->_vga->_page[1]->getBasePtr(0, kScrHeight);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 67506c8..9088971 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -59,7 +59,7 @@ class FXP	// fixed point
 	long& Joined (void) const { return *(long *)&f; }
 public:
 	FXP (void): f(0), i(0) { }
-	FXP (int i0, int f0 = 0) : i(i0), f((int) ((((long) f0) << 16)/100)) { }
+	FXP (int i0, int f0 = 0) : i(i0), f(0) { }
 	FXP& operator = (const int& x) { i = x; f = 0; return *this; }
 	FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined()+x.Joined(); return y; }
 	FXP operator - (const FXP& x) const { FXP y; y.Joined() = Joined()-x.Joined(); return y; }


Commit: 0f923c7e98d183a93f3f9415f34c81acd0615049
    https://github.com/scummvm/scummvm/commit/0f923c7e98d183a93f3f9415f34c81acd0615049
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-15T11:12:13+02:00

Commit Message:
CGE2: Change the Flags structure to make use of booleans

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 5c3b59b..ba652a6 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -676,22 +676,22 @@ void Sprite::sync(Common::Serializer &s) {
 		_flags._zmov = flags & 0x4000 ? true : false;
 		_flags._tran = flags & 0x8000 ? true : false;
 	} else {
-		flags = (flags << 1) | _flags._tran;
-		flags = (flags << 1) | _flags._zmov;
-		flags = (flags << 1) | _flags._back;
-		flags = (flags << 1) | _flags._shad;
-		flags = (flags << 1) | _flags._near;
-		flags = (flags << 1) | _flags._east;
-		flags = (flags << 1) | _flags._frnt;
-		flags = (flags << 1) | _flags._kept;
-		flags = (flags << 1) | _flags._port;
-		flags = (flags << 1) | _flags._xlat;
-		flags = (flags << 1) | _flags._kill;
-		flags = (flags << 1) | _flags._slav;
-		flags = (flags << 1) | _flags._trim;
-		flags = (flags << 1) | _flags._hold;
-		flags = (flags << 1) | _flags._drag;
-		flags = (flags << 1) | _flags._hide;
+		flags = (flags << 1) | (_flags._tran ? 1 : 0);
+		flags = (flags << 1) | (_flags._zmov ? 1 : 0);
+		flags = (flags << 1) | (_flags._back ? 1 : 0);
+		flags = (flags << 1) | (_flags._shad ? 1 : 0);
+		flags = (flags << 1) | (_flags._near ? 1 : 0);
+		flags = (flags << 1) | (_flags._east ? 1 : 0);
+		flags = (flags << 1) | (_flags._frnt ? 1 : 0);
+		flags = (flags << 1) | (_flags._kept ? 1 : 0);
+		flags = (flags << 1) | (_flags._port ? 1 : 0);
+		flags = (flags << 1) | (_flags._xlat ? 1 : 0);
+		flags = (flags << 1) | (_flags._kill ? 1 : 0);
+		flags = (flags << 1) | (_flags._slav ? 1 : 0);
+		flags = (flags << 1) | (_flags._trim ? 1 : 0);
+		flags = (flags << 1) | (_flags._hold ? 1 : 0);
+		flags = (flags << 1) | (_flags._drag ? 1 : 0);
+		flags = (flags << 1) | (_flags._hide ? 1 : 0);
 		s.syncAsUint16LE(flags);
 	}
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 9088971..359c20f 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -193,22 +193,22 @@ public:
 	int _ref;
 	signed char _scene;
 	struct Flags {
-		uint16 _hide : 1;       // general visibility switch
-		uint16 _drag : 1;       // sprite is moveable
-		uint16 _hold : 1;       // sprite is held with mouse
-		uint16 _trim : 1;       // Trim flag
-		uint16 _slav : 1;       // slave object
-		uint16 _kill : 1;       // dispose memory after remove
-		uint16 _xlat : 1;       // 2nd way display: xlat table
-		uint16 _port : 1;       // portable
-		uint16 _kept : 1;       // kept in pocket
-		uint16 _frnt : 1;       // stay in front of sprite
-		uint16 _east : 1;       // talk to east (in opposite to west)
-		uint16 _near : 1;       // Near action lock
-		uint16 _shad : 1;       // shadow
-		uint16 _back : 1;       // 'send to background' request
-		uint16 _zmov : 1;       // sprite needs Z-update in queue
-		uint16 _tran : 1;       // transparent (untouchable)
+		bool _hide : true;       // general visibility switch
+		bool _drag : true;       // sprite is moveable
+		bool _hold : true;       // sprite is held with mouse
+		bool _trim : true;       // Trim flag
+		bool _slav : true;       // slave object
+		bool _kill : true;       // dispose memory after remove
+		bool _xlat : true;       // 2nd way display: xlat table
+		bool _port : true;       // portable
+		bool _kept : true;       // kept in pocket
+		bool _frnt : true;       // stay in front of sprite
+		bool _east : true;       // talk to east (in opposite to west)
+		bool _near : true;       // Near action lock
+		bool _shad : true;       // shadow
+		bool _back : true;       // 'send to background' request
+		bool _zmov : true;       // sprite needs Z-update in queue
+		bool _tran : true;       // transparent (untouchable)
 	} _flags;
 	V2D _pos2D;
 	V3D _pos3D;


Commit: c82246ee555581e22231c69c83b9abdac84c70ab
    https://github.com/scummvm/scummvm/commit/c82246ee555581e22231c69c83b9abdac84c70ab
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-15T11:25:56+02:00

Commit Message:
CGE2: remove useless code related to boolean values

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index ba652a6..48c0b1b 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -659,22 +659,22 @@ void Sprite::sync(Common::Serializer &s) {
 	uint16 flags = 0;
 	if (s.isLoading()) {
 		s.syncAsUint16LE(flags);
-		_flags._hide = flags & 0x0001 ? true : false;
-		_flags._drag = flags & 0x0002 ? true : false;
-		_flags._hold = flags & 0x0004 ? true : false;
-		_flags._trim = flags & 0x0008 ? true : false;
-		_flags._slav = flags & 0x0010 ? true : false;
-		_flags._kill = flags & 0x0020 ? true : false;
-		_flags._xlat = flags & 0x0040 ? true : false;
-		_flags._port = flags & 0x0080 ? true : false;
-		_flags._kept = flags & 0x0100 ? true : false;
-		_flags._frnt = flags & 0x0200 ? true : false;
-		_flags._east = flags & 0x0400 ? true : false;
-		_flags._near = flags & 0x0800 ? true : false;
-		_flags._shad = flags & 0x1000 ? true : false;
-		_flags._back = flags & 0x2000 ? true : false;
-		_flags._zmov = flags & 0x4000 ? true : false;
-		_flags._tran = flags & 0x8000 ? true : false;
+		_flags._hide = flags & 0x0001;
+		_flags._drag = flags & 0x0002;
+		_flags._hold = flags & 0x0004;
+		_flags._trim = flags & 0x0008;
+		_flags._slav = flags & 0x0010;
+		_flags._kill = flags & 0x0020;
+		_flags._xlat = flags & 0x0040;
+		_flags._port = flags & 0x0080;
+		_flags._kept = flags & 0x0100;
+		_flags._frnt = flags & 0x0200;
+		_flags._east = flags & 0x0400;
+		_flags._near = flags & 0x0800;
+		_flags._shad = flags & 0x1000;
+		_flags._back = flags & 0x2000;
+		_flags._zmov = flags & 0x4000;
+		_flags._tran = flags & 0x8000;
 	} else {
 		flags = (flags << 1) | (_flags._tran ? 1 : 0);
 		flags = (flags << 1) | (_flags._zmov ? 1 : 0);


Commit: ae96463036ff99540478b7355746d8fd653ff527
    https://github.com/scummvm/scummvm/commit/ae96463036ff99540478b7355746d8fd653ff527
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-15T21:11:42+02:00

Commit Message:
CGE2: Rework EventManager::handleEvents().

Also add and implement spriteAt() during the process.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/events.cpp
    engines/cge2/events.h
    engines/cge2/talk.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 968fe2b..6119768 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -139,6 +139,7 @@ public:
 	long det(const V2D &a, const V2D &b, const V2D &c);
 	int sgn(long n);
 	int mapCross(const V2D &a, const V2D &b);
+	Sprite *spriteAt(V2D pos);
 
 	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index a143c77..79455af 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -62,7 +62,7 @@ void Keyboard::newKeyboard(Common::Event &event) {
 
 /*----------------- MOUSE interface -----------------*/
 
-Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
+Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _point(_vm), _vm(vm) {
 	_hold = NULL;
 	_hx = 0;
 	_hy = 0;
@@ -181,42 +181,31 @@ void EventManager::poll() {
 void EventManager::handleEvents() {
 	while (_eventQueueTail != _eventQueueHead) {
 		CGE2Event e = _eventQueue[_eventQueueTail];
+		_vm->_mouse->_point = V2D(_vm, e._x, e._y);
 		if (e._mask) {
-			if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold)
-				_vm->_mouse->_hold->touch(e._mask | kEventAttn, e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y, e._keyCode);
-
-			// update mouse cursor position
-			if (e._mask & kMouseRoll)
-				_vm->_mouse->gotoxyz(e._x, e._y);
+			if (e._mask & kMouseMask) {
+				e._spritePtr = _vm->spriteAt(_vm->_mouse->_point);
+				e._x += (_vm->_mouse->_siz.x >> 1);
+				e._y -= _vm->_mouse->_siz.y;
+				if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold) {
+					_vm->_mouse->_hold->touch(e._mask | kEventAttn,
+						e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y, e._keyCode);
+				}
+				// update mouse cursor position
+				if (e._mask & kMouseRoll)
+					_vm->_mouse->gotoxyz(V2D(_vm, e._x, e._y));
+			}
 
 			// activate current touched SPRITE
 			if (e._spritePtr) {
 				if (e._mask & kEventKeyb)
-					e._spritePtr->touch(e._mask, e._x, e._y, e._keyCode);
-				else
-					e._spritePtr->touch(e._mask, e._x - e._spritePtr->_pos2D.x, e._y - e._spritePtr->_pos2D.y, e._keyCode);
-			} else if (_vm->_sys)
-				_vm->_sys->touch(e._mask, V2D(_vm, e._x, e._y), e._keyCode);
-
-			if (e._mask & kMouseLeftDown) {
-				_vm->_mouse->_hold = e._spritePtr;
-				if (_vm->_mouse->_hold) {
-					_vm->_mouse->_hold->_flags._hold = true;
-
-					if (_vm->_mouse->_hold->_flags._drag) {
-						_vm->_mouse->_hx = e._x - _vm->_mouse->_hold->_pos2D.x;
-						_vm->_mouse->_hy = e._y - _vm->_mouse->_hold->_pos2D.y;
-					}
+					e._spritePtr->touch(e._mask, _vm->_mouse->_point.x, _vm->_mouse->_point.y, e._keyCode);
+				else {
+					V2D temp = _vm->_mouse->_point - e._spritePtr->_pos2D;
+					e._spritePtr->touch(e._mask, temp.x, temp.y, e._keyCode);
 				}
-			}
-
-			if (e._mask & kMouseLeftUp) {
-				if (_vm->_mouse->_hold) {
-					_vm->_mouse->_hold->_flags._hold = false;
-					_vm->_mouse->_hold = NULL;
-				}
-			}
-			///Touched = e.Ptr;
+			} else if (_vm->_sys)
+				_vm->_sys->touch(e._mask, _vm->_mouse->_point, e._keyCode);
 
 			// discard Text if button released
 			if (e._mask & (kMouseLeftUp | kMouseRightUp))
@@ -224,10 +213,6 @@ void EventManager::handleEvents() {
 		}
 		_eventQueueTail = (_eventQueueTail + 1) % kEventMax;
 	}
-	if (_vm->_mouse->_hold) {
-		if (_vm->_mouse->_hold->_flags._drag)
-			_vm->_mouse->_hold->gotoxyz(_vm->_mouse->_pos2D.x - _vm->_mouse->_hx, kWorldHeight - _vm->_mouse->_pos2D.y - _vm->_mouse->_hy);
-	}
 }
 
 void EventManager::clearEvent(Sprite *spr) {
diff --git a/engines/cge2/events.h b/engines/cge2/events.h
index 39fbf53..2522c34 100644
--- a/engines/cge2/events.h
+++ b/engines/cge2/events.h
@@ -45,6 +45,7 @@ enum EventMask {
 	kMouseRightDown = 1 << 3,
 	kMouseRightUp = 1 << 4,
 	kEventAttn = 1 << 5,
+	kMouseMask = (kMouseRoll | kMouseLeftDown | kMouseLeftUp |	kMouseRightDown | kMouseRightUp),
 	kEventKeyb = 1 << 7
 };
 
@@ -75,6 +76,7 @@ struct CGE2Event {
 
 class Mouse : public Sprite {
 public:
+	V2D _point;
 	Sprite *_hold;
 	bool _active;
 	int _hx;
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index a6d9945..54e9ea3 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -34,6 +34,20 @@ void CGE2Engine::setAutoColors() {
 	warning("STUB: CGE2Engine::setAutoColors()");
 }
 
+Sprite *CGE2Engine::spriteAt(V2D pos) {
+	Sprite *spr;
+	
+	for (spr = _vga->_showQ->last(); spr; spr = spr->_prev) {
+		if (!spr->_flags._hide && !spr->_flags._tran) {
+			V2D temp = pos - spr->_pos2D;
+			if (spr->getShp()->solidAt(temp.x, temp.y))
+				break;
+		}
+	}
+
+	return spr;
+}
+
 Font::Font(CGE2Engine *vm) : _vm(vm) {
 	_map = new uint8[kMapSize];
 	_pos = new uint16[kPosSize];


Commit: baffdd97e22851ad050bbeb1e800e38606b8f4c1
    https://github.com/scummvm/scummvm/commit/baffdd97e22851ad050bbeb1e800e38606b8f4c1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-15T21:11:42+02:00

Commit Message:
CGE2: Fix coordinates of mouse handling.

Now infoLine is working properly. Rework solidAt() to achieve that.
Also move spriteAt from talk.cpp to cge2_main.cpp, and remove the older version which didn't use V2D as a parameter.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/events.cpp
    engines/cge2/talk.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 7a7a884..c62a784 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -274,13 +274,16 @@ BitmapPtr Bitmap::code(uint8 *map) {
 	return this;
 }
 
-bool Bitmap::solidAt(int16 x, int16 y) {
-	if ((x >= _w) || (y >= _h))
+bool Bitmap::solidAt(V2D pos) {
+	pos.x += _w >> 1;
+	pos.y = _h - pos.y;
+
+	if (!pos.limited(V2D(_vm, _w, _h)))
 		return false;
 
 	uint8 *m = _v;
-	uint16 r = static_cast<uint16>(x) % 4;
-	uint16 n0 = (kScrWidth * y + x) / 4;
+	uint16 r = static_cast<uint16>(pos.x) % 4;
+	uint16 n0 = (kScrWidth * pos.y + pos.x) / 4;
 	uint16 n = 0;
 
 	while (r) {
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 8bff8fe..2c7b31b 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -83,7 +83,7 @@ public:
 	void release();
 	void hide(int16 x, int16 y);
 	void show(int16 x, int16 y);
-	bool solidAt(int16 x, int16 y);
+	bool solidAt(V2D pos);
 	void xLatPos(V2D& p);
 	bool moveHi();
 	bool moveLo();
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 6119768..0206a3c 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -123,7 +123,6 @@ public:
 	void mainLoop();
 	void handleFrame();
 	Sprite *locate(int ref);
-	Sprite *spriteAt(int x, int y);
 	bool isHero(Sprite *spr);
 	void loadUser();
 	void checkSaySwitch();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 802b72e..198f4a3 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -868,17 +868,6 @@ void CGE2Engine::switchHero(int sex) {
 		_commandHandler->addCommand(kCmdSeq, -1, 1, face);
 }
 
-Sprite *CGE2Engine::spriteAt(int x, int y) {
-	Sprite *spr = NULL, *queueTail = _vga->_showQ->last();
-	if (queueTail) {
-		for (spr = queueTail->_prev; spr; spr = spr->_prev) {
-			if (!spr->_flags._hide && !spr->_flags._tran && spr->getShp()->solidAt(x - spr->_pos2D.x, y - spr->_pos2D.y))
-				break;
-		}
-	}
-	return spr;
-}
-
 #pragma argsused
 void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
 	if ((mask & kEventAttn) != 0)
@@ -961,5 +950,17 @@ void CGE2Engine::offUse() {
 	warning("STUB: CGE2Engine::offUse()");
 }
 
+Sprite *CGE2Engine::spriteAt(V2D pos) {
+	Sprite *spr;
+
+	for (spr = _vga->_showQ->last(); spr; spr = spr->_prev) {
+		if (!spr->_flags._hide && !spr->_flags._tran) {
+			if (spr->getShp()->solidAt(pos - spr->_pos2D))
+				break;
+		}
+	}
+
+	return spr;
+}
 
 } // End of namespace CGE2
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 79455af..c3433df 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -117,7 +117,7 @@ void Mouse::newMouse(Common::Event &event) {
 	evt._x = event.mouse.x;
 	evt._y = event.mouse.y;
 	evt._keyCode = Common::KEYCODE_INVALID;
-	evt._spritePtr = _vm->spriteAt(evt._x, evt._y);
+	evt._spritePtr = _vm->spriteAt(V2D(_vm, evt._x, evt._y));
 
 	switch (event.type) {
 	case Common::EVENT_MOUSEMOVE:
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 54e9ea3..a6d9945 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -34,20 +34,6 @@ void CGE2Engine::setAutoColors() {
 	warning("STUB: CGE2Engine::setAutoColors()");
 }
 
-Sprite *CGE2Engine::spriteAt(V2D pos) {
-	Sprite *spr;
-	
-	for (spr = _vga->_showQ->last(); spr; spr = spr->_prev) {
-		if (!spr->_flags._hide && !spr->_flags._tran) {
-			V2D temp = pos - spr->_pos2D;
-			if (spr->getShp()->solidAt(temp.x, temp.y))
-				break;
-		}
-	}
-
-	return spr;
-}
-
 Font::Font(CGE2Engine *vm) : _vm(vm) {
 	_map = new uint8[kMapSize];
 	_pos = new uint16[kPosSize];


Commit: e3b5686c43fe1f2f05d7d760d6377a4d3cafce7a
    https://github.com/scummvm/scummvm/commit/e3b5686c43fe1f2f05d7d760d6377a4d3cafce7a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-15T21:23:14+02:00

Commit Message:
CGE2: Rename caves to scenes.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 565615c..135f786 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -54,7 +54,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = nullptr;
 	_eye = nullptr;
-	for (int i = 0; i < kCaveMax; i++)
+	for (int i = 0; i < kSceneMax; i++)
 		_eyeTab[i] = nullptr;
 	_spare = nullptr;
 	_commandHandler = nullptr;
@@ -108,7 +108,7 @@ void CGE2Engine::init() {
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = new HeroTab(this);
 	_eye = new V3D();
-	for (int i = 0; i < kCaveMax; i++)
+	for (int i = 0; i < kSceneMax; i++)
 		_eyeTab[i] = new V3D();
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
@@ -133,7 +133,7 @@ void CGE2Engine::deinit() {
 	delete _text;
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
-	for (int i = 0; i < kCaveMax; i++) {
+	for (int i = 0; i < kSceneMax; i++) {
 		delete _eyeTab[i];
 	}
 	delete _eye;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 0206a3c..e19ca57 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -70,7 +70,7 @@ class Map;
 #define kDimMax          8
 #define kWayMax         10
 #define kPocketMax       4
-#define kCaveMax       100
+#define kSceneMax      100
 #define kMaxPoint        4
 #define kInfoX         160
 #define kInfoY         -11
@@ -107,8 +107,8 @@ public:
 	void loadScript(const char *fname);
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
-	void caveUp(int cav);
-	void switchCave(int cav);
+	void sceneUp(int cav);
+	void switchScene(int cav);
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
@@ -229,7 +229,7 @@ public:
 	Text *_text;
 	HeroTab *_heroTab[2];
 	V3D *_eye;
-	V3D *_eyeTab[kCaveMax];
+	V3D *_eyeTab[kSceneMax];
 	Spare *_spare;
 	CommandHandler *_commandHandler;
 	CommandHandler *_commandHandlerTurbo;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 198f4a3..f4b90d3 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -394,7 +394,7 @@ void CGE2Engine::movie(const char *ext) {
 		int now = _now;
 		_now = atoi(ext + 2);
 		loadScript(fn);
-		caveUp(_now);
+		sceneUp(_now);
 
 		while (!_commandHandler->idle() && !_quitFlag)
 			mainLoop();
@@ -409,7 +409,7 @@ void CGE2Engine::movie(const char *ext) {
 	}
 }
 
-void CGE2Engine::caveUp(int cav) {
+void CGE2Engine::sceneUp(int cav) {
 	_now = cav;
 	int bakRef = _now << 8;
 	if (_music)
@@ -418,7 +418,7 @@ void CGE2Engine::caveUp(int cav) {
 	*_eye = *(_eyeTab[_now]);
 	_mouseTop = V2D(this, V3D(0, 1, kScrDepth)).y;
 	_map->load(_now);
-	_spare->takeCave(_now);
+	_spare->takeScene(_now);
 	openPocket();
 	
 	for (int i = 0; i < 2; i++) {
@@ -459,8 +459,8 @@ void CGE2Engine::caveUp(int cav) {
 	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.
 }
 
-void CGE2Engine::switchCave(int cav) {
-	warning("STUB: CGE2Engine::switchCave()");
+void CGE2Engine::switchScene(int cav) {
+	warning("STUB: CGE2Engine::switchScene()");
 }
 
 void CGE2Engine::showBak(int ref) {
@@ -575,7 +575,7 @@ void CGE2Engine::runGame() {
 	_infoLine->setText(nullptr);
 	_vga->_showQ->insert(_infoLine);
 
-	caveUp(_now);
+	sceneUp(_now);
 	_startupMode = 0;
 	_mouse->center();
 	_mouse->off();
@@ -666,12 +666,12 @@ void CGE2Engine::loadGame() {
 
 void CGE2Engine::loadPos() {
 	if (_resman->exist("CGE.HXY")) {
-		for (int cav = 0; cav < kCaveMax; cav++)
+		for (int cav = 0; cav < kSceneMax; cav++)
 			_heroTab[1]->_posTab[cav] = new V2D(this, 180, 10);
 		
 		EncryptedStream file(this, "CGE.HXY");
 
-		for (int cav = 0; cav < kCaveMax; cav++) {
+		for (int cav = 0; cav < kSceneMax; cav++) {
 			_heroTab[0]->_posTab[cav]->x = file.readSint16LE();
 			_heroTab[0]->_posTab[cav]->y = file.readSint16LE();
 		}
@@ -708,14 +708,14 @@ void CGE2Engine::qGame() {
 
 void CGE2Engine::loadTab() {
 	setEye(_text->getText(240));
-	for (int i = 0; i < kCaveMax; i++)
+	for (int i = 0; i < kSceneMax; i++)
 		*(_eyeTab[i]) = *_eye;
 
 	if  (_resman->exist(kTabName)) {
 		EncryptedStream f(this, kTabName);
 		uint32 v;
 
-		for (int i = 0; i < kCaveMax; i++) {
+		for (int i = 0; i < kSceneMax; i++) {
 			v = f.readUint32LE();
 			_eyeTab[i]->_x = FXP(v >> 8, static_cast<int>((int8)(v & 0xff)));
 
@@ -860,7 +860,7 @@ void CGE2Engine::switchHero(int sex) {
 		if (scene >= 0) {
 			_commandHandler->addCommand(kCmdSeq, -1, 2, _heroTab[_sex]->_face);
 			_sex ^= 1;
-			switchCave(scene);
+			switchScene(scene);
 		}
 	}
 	Sprite *face = _heroTab[_sex]->_face;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 69ee7b7..628f7c1 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -44,18 +44,18 @@ struct HeroTab {
 	Sprite *_face;
 	Sprite *_pocket[kPocketMax + 1];
 	int _pocPtr;
-	V2D *_posTab[kCaveMax];
+	V2D *_posTab[kSceneMax];
 	HeroTab(CGE2Engine *vm) {
 		_ptr = nullptr;
 		_face = nullptr;
 		for (int i = 0; i < kPocketMax + 1; i++)
 			_pocket[i] = nullptr;
 		_pocPtr = 0;
-		for (int i = 0; i < kCaveMax; i++)
+		for (int i = 0; i < kSceneMax; i++)
 			_posTab[i] = new V2D(vm);
 	}
 	~HeroTab() {
-		for (int i = 0; i < kCaveMax; i++)
+		for (int i = 0; i < kSceneMax; i++)
 			delete _posTab[i];
 	}
 };
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 6b9ade6..5e417a1 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -137,7 +137,7 @@ void CommandHandler::runCommand() {
 			warning("STUB: CommandHandler::runCommand() - Something missing connected to kCmdTime!");
 			break;
 		case kCmdCave:
-			_vm->switchCave(tailCmd._val);
+			_vm->switchScene(tailCmd._val);
 			break;
 		case kCmdMidi:
 			_vm->snMidi(tailCmd._val);
@@ -381,9 +381,9 @@ void CGE2Engine::snSend(Sprite *spr, int val) {
 	if (!spr)
 		return;
 	
-	// Sending", spr->File
-	// from cave", spr->Cave
-	// to cave", val
+	// Sending", spr->_file
+	// from scene", spr->_scene
+	// to scene", val
 	bool was1 = (_vga->_showQ->locate(spr->_ref) != nullptr);
 	bool val1 = (val == 0 || val == _now);
 	spr->_scene = val;


Commit: 7f4af90777136170ca6682e8315725cda9b3c50d
    https://github.com/scummvm/scummvm/commit/7f4af90777136170ca6682e8315725cda9b3c50d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-15T21:24:59+02:00

Commit Message:
CGE2: Fix compilation broken by previous commit.

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 9531fe6..2977a58 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -58,7 +58,7 @@ Sprite *Spare::take(int ref) {
 	return spr;
 }
 
-void Spare::takeCave(int cav) {
+void Spare::takeScene(int cav) {
 	int bakRef = cav << 8;
 	Common::Array<Sprite*> tempCont = _container;
 	for (uint i = 0; i < tempCont.size(); ++i) {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 1890922..77bdb33 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -41,7 +41,7 @@ public:
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
 	Sprite *take(int ref);
-	void takeCave(int cav);
+	void takeScene(int cav);
 	void update(Sprite *spr);
 	void dispose(Sprite *spr);
 	void dispose(int ref);


Commit: c488c15289d9a5c21fc6bad54c9614f54dd8b3bf
    https://github.com/scummvm/scummvm/commit/c488c15289d9a5c21fc6bad54c9614f54dd8b3bf
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-15T21:29:32+02:00

Commit Message:
CGE2: Rework Sprite::touch to use V2D for coords.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/events.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f4b90d3..c0b41e4 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -869,7 +869,7 @@ void CGE2Engine::switchHero(int sex) {
 }
 
 #pragma argsused
-void Sprite::touch(uint16 mask, int x, int y, Common::KeyCode keyCode) {
+void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 	if ((mask & kEventAttn) != 0)
 		return;
 
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index c3433df..0c163a5 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -189,7 +189,7 @@ void EventManager::handleEvents() {
 				e._y -= _vm->_mouse->_siz.y;
 				if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold) {
 					_vm->_mouse->_hold->touch(e._mask | kEventAttn,
-						e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y, e._keyCode);
+						V2D(_vm, e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y), e._keyCode);
 				}
 				// update mouse cursor position
 				if (e._mask & kMouseRoll)
@@ -199,11 +199,9 @@ void EventManager::handleEvents() {
 			// activate current touched SPRITE
 			if (e._spritePtr) {
 				if (e._mask & kEventKeyb)
-					e._spritePtr->touch(e._mask, _vm->_mouse->_point.x, _vm->_mouse->_point.y, e._keyCode);
-				else {
-					V2D temp = _vm->_mouse->_point - e._spritePtr->_pos2D;
-					e._spritePtr->touch(e._mask, temp.x, temp.y, e._keyCode);
-				}
+					e._spritePtr->touch(e._mask, _vm->_mouse->_point, e._keyCode);
+				else 
+					e._spritePtr->touch(e._mask, _vm->_mouse->_point - e._spritePtr->_pos2D, e._keyCode);
 			} else if (_vm->_sys)
 				_vm->_sys->touch(e._mask, _vm->_mouse->_point, e._keyCode);
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 359c20f..32cf38d 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -260,7 +260,7 @@ public:
 	void step(int nr = -1);
 	Seq *setSeq(Seq *seq);
 	CommandHandler::Command *snList(Action type);
-	virtual void touch(uint16 mask, int x, int y, Common::KeyCode keyCode);
+	virtual void touch(uint16 mask, V2D pos, Common::KeyCode keyCode);
 	virtual void tick();
 	virtual void setScene(int c);
 	void clrHide() { if (_ext) _ext->_b0 = NULL; }


Commit: 9023240545bdadd0ccea93dddae30d1e13f5b107
    https://github.com/scummvm/scummvm/commit/9023240545bdadd0ccea93dddae30d1e13f5b107
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-15T21:33:41+02:00

Commit Message:
CGE2: Rework show() and hide() in Bitmap to use V2Ds as parameters.

Changed paths:
    engines/cge2/bitmap.h
    engines/cge2/snail.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 2c7b31b..e7a4637 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -81,8 +81,8 @@ public:
 	Bitmap *code(uint8 *map);
 	Bitmap &operator=(const Bitmap &bmp);
 	void release();
-	void hide(int16 x, int16 y);
-	void show(int16 x, int16 y);
+	void hide(V2D pos);
+	void show(V2D pos);
 	bool solidAt(V2D pos);
 	void xLatPos(V2D& p);
 	bool moveHi();
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 5e417a1..068ccf8 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -604,7 +604,7 @@ void CGE2Engine::snDim(Sprite *spr, int val) {
 
 void CGE2Engine::snGhost(Bitmap *bmp) {
 	V2D p(this, bmp->_map & 0xFFFF, bmp->_map >> 16);
-	bmp->hide(p.x, p.y);
+	bmp->hide(p);
 	delete[] bmp->_b;
 	bmp->_v = nullptr;
 	bmp->_b = nullptr;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 48c0b1b..24376d9 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -610,20 +610,20 @@ void Sprite::show() {
 		e->_b1 = getShp();
 	}
 	if (!_flags._hide)
-		e->_b1->show(e->_p1.x, e->_p1.y);
+		e->_b1->show(e->_p1);
 }
 
 void Sprite::show(uint16 pg) {
 	Graphics::Surface *a = _vm->_vga->_page[1];
 	_vm->_vga->_page[1] = _vm->_vga->_page[pg];
-	getShp()->show(_pos2D.x, _pos2D.y);
+	getShp()->show(_pos2D);
 	_vm->_vga->_page[1] = a;
 }
 
 void Sprite::hide() {
 	SprExt *e = _ext;
 	if (e->_b0)
-		e->_b0->hide(e->_p0.x, e->_p0.y);
+		e->_b0->hide(e->_p0);
 }
 
 BitmapPtr Sprite::ghost() {
@@ -1059,11 +1059,8 @@ void Vga::copyPage(uint16 d, uint16 s) {
 	_page[d]->copyFrom(*_page[s]);
 }
 
-void Bitmap::show(int16 x, int16 y) {
-	V2D pos(_vm, x, y);
+void Bitmap::show(V2D pos) {
 	xLatPos(pos);
-	x = pos.x;
-	y = pos.y;
 
 	const byte *srcP = (const byte *)_v;
 	byte *screenStartP = (byte *)_vm->_vga->_page[1]->getPixels();
@@ -1073,7 +1070,7 @@ void Bitmap::show(int16 x, int16 y) {
 	// given plane holds each fourth pixel sequentially. So to handle an entire picture, each plane's data
 	// must be decompressed and inserted into the surface
 	for (int planeCtr = 0; planeCtr < 4; planeCtr++) {
-		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x + planeCtr, y);
+		byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(pos.x + planeCtr, pos.y);
 
 		for (;;) {
 			uint16 v = READ_LE_UINT16(srcP);
@@ -1117,15 +1114,13 @@ void Bitmap::show(int16 x, int16 y) {
 }
 
 
-void Bitmap::hide(int16 x, int16 y) {
-	V2D pos(_vm, x, y);
+void Bitmap::hide(V2D pos) {
 	xLatPos(pos);
-	x = pos.x;
-	y = pos.y;
-	for (int yp = y; yp < y + _h; yp++) {
+	
+	for (int yp = pos.y; yp < pos.y + _h; yp++) {
 		if (yp >= 0 && yp < kScrHeight) {
-			const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(x, yp);
-			byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(x, yp);
+			const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(pos.x, yp);
+			byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(pos.x, yp);
 
 			Common::copy(srcP, srcP + _w, destP);
 		}


Commit: 40262bad980ffb0a86492e67c5430b24e6454438
    https://github.com/scummvm/scummvm/commit/40262bad980ffb0a86492e67c5430b24e6454438
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-15T22:48:23+02:00

Commit Message:
CGE: Remove (broken) variable length specification

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 32cf38d..a6e12fe 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -193,22 +193,22 @@ public:
 	int _ref;
 	signed char _scene;
 	struct Flags {
-		bool _hide : true;       // general visibility switch
-		bool _drag : true;       // sprite is moveable
-		bool _hold : true;       // sprite is held with mouse
-		bool _trim : true;       // Trim flag
-		bool _slav : true;       // slave object
-		bool _kill : true;       // dispose memory after remove
-		bool _xlat : true;       // 2nd way display: xlat table
-		bool _port : true;       // portable
-		bool _kept : true;       // kept in pocket
-		bool _frnt : true;       // stay in front of sprite
-		bool _east : true;       // talk to east (in opposite to west)
-		bool _near : true;       // Near action lock
-		bool _shad : true;       // shadow
-		bool _back : true;       // 'send to background' request
-		bool _zmov : true;       // sprite needs Z-update in queue
-		bool _tran : true;       // transparent (untouchable)
+		bool _hide;       // general visibility switch
+		bool _drag;       // sprite is moveable
+		bool _hold;       // sprite is held with mouse
+		bool _trim;       // Trim flag
+		bool _slav;       // slave object
+		bool _kill;       // dispose memory after remove
+		bool _xlat;       // 2nd way display: xlat table
+		bool _port;       // portable
+		bool _kept;       // kept in pocket
+		bool _frnt;       // stay in front of sprite
+		bool _east;       // talk to east (in opposite to west)
+		bool _near;       // Near action lock
+		bool _shad;       // shadow
+		bool _back;       // 'send to background' request
+		bool _zmov;       // sprite needs Z-update in queue
+		bool _tran;       // transparent (untouchable)
 	} _flags;
 	V2D _pos2D;
 	V3D _pos3D;


Commit: 186d90e5b58c09e04f570b51f97a7bd3315dcbde
    https://github.com/scummvm/scummvm/commit/186d90e5b58c09e04f570b51f97a7bd3315dcbde
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-17T15:37:55+02:00

Commit Message:
CGE2: Implement switching between scenes.

Minor modification in Spare again to do so.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 135f786..96beff7 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -96,6 +96,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_flag[i] = false;
 	_sayCap = true;
 	_sayVox = true;
+	_req = 1;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index e19ca57..bc4a16c 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -78,8 +78,11 @@ class Map;
 #define kPocketsWidth   59
 #define kLineMax       512
 
+#define kExitOkText     40
+#define kCrackedText    44
+
 enum CallbackType {
-	kNullCB = 0, kQGame, kMiniStep, kXScene, kSoundSetVolume
+	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
 };
 
 enum Action { kNear, kMTake, kFTake, kActions };
@@ -108,7 +111,9 @@ public:
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
 	void sceneUp(int cav);
-	void switchScene(int cav);
+	void sceneDown();
+	void closePocket();
+	void switchScene(int scene);
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
@@ -126,7 +131,6 @@ public:
 	bool isHero(Sprite *spr);
 	void loadUser();
 	void checkSaySwitch();
-	void qGame();
 	void loadPos();
 	void releasePocket(Sprite *spr);
 	void switchHero(int sex);
@@ -194,6 +198,9 @@ public:
 	
 	void hide1(Sprite *spr);
 	Sprite *expandSprite(Sprite *spr);
+	void qGame();
+	void xScene();
+	void sndSetVolume();
 
 	const ADGameDescription *_gameDescription;
 
@@ -219,6 +226,7 @@ public:
 	bool _flag[4];
 	bool _sayCap;
 	bool _sayVox;
+	int _req;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index c0b41e4..0fc2d5a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -459,8 +459,69 @@ void CGE2Engine::sceneUp(int cav) {
 	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.
 }
 
-void CGE2Engine::switchScene(int cav) {
-	warning("STUB: CGE2Engine::switchScene()");
+void CGE2Engine::sceneDown() {
+	busy(true);
+	_commandStat._wait = nullptr; // unlock snail
+	Sprite *spr = _vga->_showQ->locate((_now << 8) | 254);
+	if (spr)
+		feedSnail(spr, kNear, _heroTab[_sex]->_ptr);
+	while (!(_commandHandler->idle() && _commandHandlerTurbo->idle())) {
+		_commandHandlerTurbo->runCommand();
+		_commandHandler->runCommand();
+	}
+	closePocket();
+	for (int i = 0; i < 2; i++)
+		_spare->update(_vga->_showQ->remove(_heroTab[i]->_ptr));
+	_spare->dispose();
+}
+
+void CGE2Engine::closePocket() {
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax + 1; j++) {
+			Sprite *spr = _heroTab[i]->_pocket[j];
+			_heroTab[i]->_pocket[j] = (Sprite*)((spr) ? spr->_ref : -1);
+		}
+	}
+}
+
+void CGE2Engine::switchScene(int scene) {
+	if (scene == _now)
+		return;
+	
+	if (scene >= 0) {
+		if (!_flag[2]) // PROT
+			_flag[2] = true;
+		else {
+			int t = _text->getText(kCrackedText) ? kCrackedText : kExitOkText;
+			_commandHandler->addCommand(kCmdInf, -1, t, nullptr);
+			return;
+		}
+	}
+
+	_req = scene;
+	for (int i = 0; i < 2; i++) {
+		Hero *h = _heroTab[i]->_ptr;
+		if (h->_scene == _now) {
+			delete _heroTab[i]->_posTab[_now];
+			V2D *temp = new V2D(this, h->_pos3D._x.trunc(), h->_pos3D._z.trunc());
+			_heroTab[i]->_posTab[_now] = temp;
+		}
+	}
+	*(_eyeTab[_now]) = *_eye;
+	if (scene < 0)
+		_commandHandler->addCallback(kCmdExec, -1, 0, kQGame); // quit game
+	else {
+		if (_heroTab[_sex]->_ptr->_scene == _now) {
+			_heroTab[_sex]->_ptr->setScene(scene);
+			if (_heroTab[!_sex]->_ptr->_scene == _now)
+				_heroTab[!_sex]->_ptr->setScene(scene);
+		}
+		_mouse->off();
+		if (_heroTab[_sex]->_ptr)
+			_heroTab[_sex]->_ptr->park();
+		killText();
+		_commandHandler->addCallback(kCmdExec, -1, 0, kXScene); // switch scene
+	}
 }
 
 void CGE2Engine::showBak(int ref) {
@@ -701,11 +762,6 @@ void CGE2Engine::checkSaySwitch() {
 	warning("STUB: CGE2Engine::checkSaySwitch()");
 }
 
-void CGE2Engine::qGame() {
-	warning("STUB: CGE2Engine::qGame()");
-	_endGame = true;
-}
-
 void CGE2Engine::loadTab() {
 	setEye(_text->getText(240));
 	for (int i = 0; i < kSceneMax; i++)
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 068ccf8..d799f28 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -301,7 +301,20 @@ void CommandHandler::runCommand() {
 			_vm->snDim(spr, tailCmd._val);
 			break;
 		case kCmdExec:
-			warning("Unhandled command - kCmdExec");
+			switch (tailCmd._cbType) {
+			case kQGame:
+				_vm->qGame();
+				break;
+			case kXScene:
+				_vm->xScene();
+				break;
+			case kSoundSetVolume:
+				_vm->sndSetVolume();
+				break;
+			default:
+				error("Unknown Callback Type in SNEXEC");
+				break;
+			}
 			break;
 		case kCmdStep:
 			spr->step();
@@ -638,6 +651,20 @@ Sprite *CGE2Engine::expandSprite(Sprite *spr) {
 	return spr;
 }
 
+void CGE2Engine::qGame() {
+	warning("STUB: CGE2Engine::qGame()");
+	_endGame = true;
+}
+
+void CGE2Engine::xScene() {
+	sceneDown();
+	sceneUp(_req);
+}
+
+void CGE2Engine::sndSetVolume() {
+	warning("STUB: CGE2Engine::sndSetVolume()");
+}
+
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
 	if (ref == 2)
 		ref = 142 - _vm->_sex;
@@ -653,7 +680,17 @@ void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
 }
 
 void CommandHandler::addCallback(CommandType com, int ref, int val, CallbackType cbType) {
-	warning("STUB: CommandHandler::addCallback()");
+	Command *headCmd = &_commandList[_head++];
+	headCmd->_commandType = com;
+	headCmd->_ref = ref;
+	headCmd->_val = val;
+	headCmd->_spritePtr = NULL;
+	headCmd->_cbType = cbType;
+	if (headCmd->_commandType == kCmdClear) {
+		_tail = _head;
+		_vm->killText();
+		_timerExpiry = 0;
+	}
 }
 
 void CommandHandler::insertCommand(CommandType com, int ref, int val, void *ptr) {
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 2977a58..8382310 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -65,7 +65,7 @@ void Spare::takeScene(int cav) {
 		Sprite *spr = tempCont[i];
 		int c = spr->_scene;
 		if ((c == _vm->_now || c == 0) && spr->_ref != bakRef) {
-			spr = take(spr->_ref);
+			spr = locate(spr->_ref);
 			_vm->_vga->_showQ->insert(spr);
 		}
 	}


Commit: 26901479d3e60eed76dfd306988b27408b22e3ee
    https://github.com/scummvm/scummvm/commit/26901479d3e60eed76dfd306988b27408b22e3ee
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-17T15:38:24+02:00

Commit Message:
CGE2: Fix initialization of _posTab.

Fixes a possible memory leak.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 0fc2d5a..5fa4453 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -733,6 +733,7 @@ void CGE2Engine::loadPos() {
 		EncryptedStream file(this, "CGE.HXY");
 
 		for (int cav = 0; cav < kSceneMax; cav++) {
+			_heroTab[0]->_posTab[cav] = new V2D(this);
 			_heroTab[0]->_posTab[cav]->x = file.readSint16LE();
 			_heroTab[0]->_posTab[cav]->y = file.readSint16LE();
 		}
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 628f7c1..7ddc871 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -52,7 +52,7 @@ struct HeroTab {
 			_pocket[i] = nullptr;
 		_pocPtr = 0;
 		for (int i = 0; i < kSceneMax; i++)
-			_posTab[i] = new V2D(vm);
+			_posTab[i] = nullptr;
 	}
 	~HeroTab() {
 		for (int i = 0; i < kSceneMax; i++)


Commit: fb97e24a5adfb117add2cfa959c075a2af569fad
    https://github.com/scummvm/scummvm/commit/fb97e24a5adfb117add2cfa959c075a2af569fad
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-18T20:43:24+02:00

Commit Message:
CGE2: Fix coords of misplaced speech bubbles.

The origin of the bug is that when we added the command (triggered by a mouse-click on a sprite) to display a speech bubble we checked the command's reference wrong and didn't bind (by modifying the reference) the bubble to a certain hero. So they just appeared randomly above the sprites what triggered the event, or even in worse places.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index d799f28..e3c3baa 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -666,7 +666,7 @@ void CGE2Engine::sndSetVolume() {
 }
 
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
-	if (ref == 2)
+	if (ref == -2)
 		ref = 142 - _vm->_sex;
 	Command *headCmd = &_commandList[_head++];
 	headCmd->_commandType = com;


Commit: d85d3229e6a790e9d6caf3a422632d562dcc3e3f
    https://github.com/scummvm/scummvm/commit/d85d3229e6a790e9d6caf3a422632d562dcc3e3f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-18T22:37:54+02:00

Commit Message:
CGE2: Implement functions connected to inventory handling.

Also move closePocket() closer to the others and fix the stub message in busy().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 5fa4453..b17f48d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -475,15 +475,6 @@ void CGE2Engine::sceneDown() {
 	_spare->dispose();
 }
 
-void CGE2Engine::closePocket() {
-	for (int i = 0; i < 2; i++) {
-		for (int j = 0; j < kPocketMax + 1; j++) {
-			Sprite *spr = _heroTab[i]->_pocket[j];
-			_heroTab[i]->_pocket[j] = (Sprite*)((spr) ? spr->_ref : -1);
-		}
-	}
-}
-
 void CGE2Engine::switchScene(int scene) {
 	if (scene == _now)
 		return;
@@ -607,15 +598,38 @@ void CGE2Engine::tick() {
 }
 
 void CGE2Engine::openPocket() {
-	warning("STUB: CGE2Engine::openPocket()");
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax + 1; j++) {
+			int ref = (int)_heroTab[i]->_pocket[j];
+			_heroTab[i]->_pocket[j] = (ref == -1) ? nullptr : _vga->_showQ->locate(ref);
+		}
+	}
+}
+
+void CGE2Engine::closePocket() {
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax + 1; j++) {
+			Sprite *spr = _heroTab[i]->_pocket[j];
+			_heroTab[i]->_pocket[j] = (Sprite*)((spr) ? spr->_ref : -1);
+		}
+	}
 }
 
+
 void CGE2Engine::selectPocket(int n) {
-	warning("STUB: CGE2Engine::selectPocket()");
+	Sprite **p = _heroTab[_sex]->_pocket;
+	int &pp = _heroTab[_sex]->_pocPtr;
+	if (n < 0 || pp == n) {
+		n = findActivePocket(-1);
+		if (n >= 0)
+			pp = n;
+	} else if (p[n]) {
+		pp = n;
+	}
 }
 
 void CGE2Engine::busy(bool on) {
-	warning("STUB: CGE2Engine::selectPocket()");
+	warning("STUB: CGE2Engine::busy()");
 }
 
 void CGE2Engine::runGame() {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index e3c3baa..3a17168 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -740,9 +740,6 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 		CommandHandler::Command *c = &comtab[ptr];
 		CommandHandler::Command *q = &comtab[cnt];
 
-		warning("STUB: CGE2Engine::feedSnail()");
-		// Dont bother with pockets (inventory system) for now... TODO: Implement it later!!!
-		/*
 		int pocFre = freePockets(hero->_ref & 1);
 		int pocReq = 0;
 		CommandHandler::Command *p = c;
@@ -771,7 +768,7 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 				pocFul();
 				return;
 			}
-		}*/
+		}
 
 		while (c < q) {
 			if (c->_commandType == kCmdTalk) {


Commit: ea5697d5a0ff66c7e93db4e53c881980df0a5971
    https://github.com/scummvm/scummvm/commit/ea5697d5a0ff66c7e93db4e53c881980df0a5971
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-18T22:58:33+02:00

Commit Message:
CGE2: Implement snKeep().

Now the inventory system is (at least partially) working.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 3a17168..d40789c 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -469,8 +469,39 @@ void CGE2Engine::snFocus(int val) {
 	warning("STUB: CGE2Engine::snFocus()");
 }
 
-void CGE2Engine::snKeep(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snKeep()");
+void CGE2Engine::snKeep(Sprite *spr, int stp) {
+	int sex = _sex;
+	if (stp > 127) {
+		_sex = stp & 1; // for another hero
+		stp = -1;
+	}
+	HeroTab *ht = _heroTab[_sex];
+	selectPocket(-1);
+	int pp = ht->_pocPtr;
+
+	if (spr && !spr->_flags._kept && ht->_pocket[pp] == nullptr) {
+		V3D pos(14, -10, -1);
+		snSound(ht->_ptr, 3);
+		if (_taken) {
+			_vga->_showQ->insert(spr);
+			_taken = false;
+		}
+		ht->_pocket[pp] = spr;
+		spr->setScene(0);
+		spr->_flags._kept = true;
+		if (!_sex)
+			pos._x += kScrWidth - 58;
+		if (pp & 1)
+			pos._x += 29;
+		if (pp >> 1)
+			pos._y -= 20;
+		pos._y -= (spr->_siz.y / 2);
+		spr->gotoxyz(pos);
+		if (stp >= 0)
+			spr->step(stp);
+	}
+	_sex = sex;
+	selectPocket(-1);
 }
 
 void CGE2Engine::snGive(Sprite *spr, int val) {


Commit: 7a549f2693222743dd76697534664fdc498a456c
    https://github.com/scummvm/scummvm/commit/7a549f2693222743dd76697534664fdc498a456c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-18T23:34:26+02:00

Commit Message:
CGE2: Implement offUse().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index bc4a16c..e743d7b 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -80,6 +80,8 @@ class Map;
 
 #define kExitOkText     40
 #define kCrackedText    44
+#define kOffUseCount   130
+#define kOffUseText    131
 
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index b17f48d..c27b160 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1018,7 +1018,24 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 }
 
 void CGE2Engine::offUse() {
-	warning("STUB: CGE2Engine::offUse()");
+	int seq = 0;
+	int offUseCount = atoi(_text->getText(kOffUseCount));
+
+	// This fixes the issue of empty speech bubbles in the original.
+	// Now we only let this cycle pass if it randoms a valid value for getText().
+	int txt = 0;
+	do { 
+		txt = kOffUseText + _sex * offUseCount + newRandom(offUseCount);
+	} while (_text->getText(txt) == nullptr);
+
+	Hero *h = _heroTab[_sex]->_ptr;
+	h->park();
+	_commandHandler->addCommand(kCmdWait, -1, -1, h);
+	_commandHandler->addCommand(kCmdSeq, -1, seq, h);
+	if (!_sayVox)
+		_commandHandler->addCommand(kCmdSound, -1, 6 + _sex, h);
+	_commandHandler->addCommand(kCmdWait, -1, -1, h);
+	_commandHandler->addCommand(kCmdSay, -1, txt, h);
 }
 
 Sprite *CGE2Engine::spriteAt(V2D pos) {


Commit: d7e70eb5fac638e386f6da1bbf93d9256adb3596
    https://github.com/scummvm/scummvm/commit/d7e70eb5fac638e386f6da1bbf93d9256adb3596
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T00:09:01+02:00

Commit Message:
CGE2: Implement inf().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/talk.h
    engines/cge2/text.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index e743d7b..bb59c48 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -89,6 +89,8 @@ enum CallbackType {
 
 enum Action { kNear, kMTake, kFTake, kActions };
 
+enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
+
 class CGE2Engine : public Engine {
 private:
 	uint32 _lastFrame, _lastTick;
@@ -105,7 +107,7 @@ public:
 	bool showTitle(const char *name);
 	void cge2_main();
 	char *mergeExt(char *buf, const char *name, const char *ext);
-	void inf(const char *text, bool wideSpace = false);
+	void inf(const char *text, ColorBank col = kCBInf);
 	void movie(const char *ext);
 	void runGame();
 	void loadGame();
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
index 84ba728..cddcdc2 100644
--- a/engines/cge2/talk.h
+++ b/engines/cge2/talk.h
@@ -62,8 +62,6 @@ public:
 
 enum TextBoxStyle { kTBPure, kTBRect, kTBRound };
 
-enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
-
 class Talk : public Sprite {
 protected:
 	TextBoxStyle _mode;
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index cf4dda4..c7f6a06 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -178,8 +178,15 @@ void Text::say(const char *text, Sprite *spr) {
 	_vm->_vga->_showQ->append(speaker);
 }
 
-void CGE2Engine::inf(const char *text, bool wideSpace) {
-	warning("STUB: CGE2Engine::inf()");
+void CGE2Engine::inf(const char *text, ColorBank col) {
+	killText();
+	_talk = new Talk(this, text, kTBRect, col);
+	if (_talk) {
+		_talk->_flags._kill = true;
+		_talk->setName(_text->getText(kInfName));
+		_talk->center();
+		_vga->_showQ->append(_talk);
+	}
 }
 
 void Text::sayTime(Sprite *spr) {


Commit: 535b70934e80591aed0cd221c9a9928de3ede2f4
    https://github.com/scummvm/scummvm/commit/535b70934e80591aed0cd221c9a9928de3ede2f4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T10:44:00+02:00

Commit Message:
CGE2: Comment out code and add TODO in switchScene().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index c27b160..669b28d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -479,6 +479,9 @@ void CGE2Engine::switchScene(int scene) {
 	if (scene == _now)
 		return;
 	
+	/* TODO:: Recheck this flag-thing! As far as it seems it's only for checking if the game
+	   is being run from the CD-ROM. In this context, it's useless for us.
+
 	if (scene >= 0) {
 		if (!_flag[2]) // PROT
 			_flag[2] = true;
@@ -488,6 +491,7 @@ void CGE2Engine::switchScene(int scene) {
 			return;
 		}
 	}
+	*/
 
 	_req = scene;
 	for (int i = 0; i < 2; i++) {


Commit: 56c7df46d3f713bdf8817217807570bcf0d976c9
    https://github.com/scummvm/scummvm/commit/56c7df46d3f713bdf8817217807570bcf0d976c9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T11:34:25+02:00

Commit Message:
CGE2: Implement showing the selected item in the inventory.

Now the selected item's picture is blinking until deselected.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 96beff7..9e1e30a 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -71,7 +71,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	for (int i = 0; i < 2; i++)
 		_vol[i] = nullptr;
 	_eventManager = nullptr;
-	_blinkSprite = nullptr;
 	_map = nullptr;
 	
 	_quitFlag = false;
@@ -153,8 +152,6 @@ void CGE2Engine::deinit() {
 	}
 	delete _sys;
 	delete _eventManager;
-	if (_blinkSprite != nullptr)
-		delete _blinkSprite;
 	delete _map;
 }
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index bb59c48..c02b01c 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -83,6 +83,9 @@ class Map;
 #define kOffUseCount   130
 #define kOffUseText    131
 
+#define kSysTimeRate     6 // 12 Hz
+#define kBlinkRate       4 //  3 Hz
+
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
 };
@@ -255,7 +258,6 @@ public:
 	Sprite *_busyPtr;
 	Sprite *_vol[2];
 	EventManager *_eventManager;
-	Sprite *_blinkSprite;
 	Map *_map;
 private:
 	void init();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 669b28d..816eea1 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -39,7 +39,9 @@
 namespace CGE2 {
 
 System::System(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
-	warning("STUB: System::System()");
+	_blinkCounter = 0;
+	_blinkSprite = nullptr;
+	tick();
 }
 
 void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
@@ -82,12 +84,12 @@ void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 								if (pos.x >= (kPocketsWidth >> 1))
 									++n;
 								s = _vm->_heroTab[_vm->_sex]->_pocket[n];
-								if (_vm->_blinkSprite)
-									_vm->_blinkSprite->_flags._hide = false;
-								if (_vm->_blinkSprite == s)
-									_vm->_blinkSprite = nullptr;
+								if (_vm->_sys->_blinkSprite)
+									_vm->_sys->_blinkSprite->_flags._hide = false;
+								if (_vm->_sys->_blinkSprite == s)
+									_vm->_sys->_blinkSprite = nullptr;
 								else
-									_vm->_blinkSprite = s;
+									_vm->_sys->_blinkSprite = s;
 							}
 						}
 					}
@@ -98,7 +100,15 @@ void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 }
 
 void System::tick() {
-	warning("STUB: System::tick()");
+	_time = kSysTimeRate;
+
+	if (_blinkCounter)
+		--_blinkCounter;
+	else {
+		if (_blinkSprite)
+			_blinkSprite->_flags._hide ^= 1;
+		_blinkCounter = kBlinkRate;
+	}
 }
 
 int CGE2Engine::number(char *s) { // TODO: Rework it later to include the preceding token() call!
@@ -588,6 +598,10 @@ bool CGE2Engine::isHero(Sprite *spr) {
 }
 
 void CGE2Engine::tick() {
+	// system pseudo-sprite
+	if (_sys && _sys->_time && (--_sys->_time == 0))
+		_sys->tick();
+
 	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
 		if (spr->_time && (--spr->_time == 0))
 				spr->tick();
@@ -928,9 +942,9 @@ void CGE2Engine::killText() {
 void CGE2Engine::switchHero(int sex) {
 	if (sex != _sex) {
 		int scene = _heroTab[sex]->_ptr->_scene;
-		if (_blinkSprite) {
-			_blinkSprite->_flags._hide = false;
-			_blinkSprite = nullptr;
+		if (_sys->_blinkSprite) {
+			_sys->_blinkSprite->_flags._hide = false;
+			_sys->_blinkSprite = nullptr;
 		}
 		if (scene >= 0) {
 			_commandHandler->addCommand(kCmdSeq, -1, 2, _heroTab[_sex]->_face);
@@ -960,7 +974,7 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 	}
 
 	if ((mask & kMouseLeftUp) && _vm->_commandHandler->idle()) {
-		if (_vm->isHero(this) && !_vm->_blinkSprite) {
+		if (_vm->isHero(this) && !_vm->_sys->_blinkSprite) {
 			_vm->switchHero((this == _vm->_heroTab[1]->_ptr) ? 1 : 0);
 		} else if (_flags._kept) { // sprite in pocket
 			for (int sex = 0; sex < 2; ++sex) {
@@ -968,12 +982,12 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 					if (_vm->_heroTab[sex]->_pocket[p] == this) {
 						_vm->switchHero(sex);
 						if (_vm->_sex == sex) {
-							if (_vm->_blinkSprite)
-								_vm->_blinkSprite->_flags._hide = false;
-							if (_vm->_blinkSprite == this)
-								_vm->_blinkSprite = nullptr;
+							if (_vm->_sys->_blinkSprite)
+								_vm->_sys->_blinkSprite->_flags._hide = false;
+							if (_vm->_sys->_blinkSprite == this)
+								_vm->_sys->_blinkSprite = nullptr;
 							else
-								_vm->_blinkSprite = this;
+								_vm->_sys->_blinkSprite = this;
 						}
 					}
 				}
@@ -983,11 +997,11 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 			if (!_vm->_talk) {
 				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1))
 					h->walkTo(this);
-				else if (_vm->_blinkSprite) {
-					if (works(_vm->_blinkSprite)) {
-						_vm->feedSnail(_vm->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
-						_vm->_blinkSprite->_flags._hide = false;
-						_vm->_blinkSprite = nullptr;
+				else if (_vm->_sys->_blinkSprite) {
+					if (works(_vm->_sys->_blinkSprite)) {
+						_vm->feedSnail(_vm->_sys->_blinkSprite, (_vm->_sex) ? kMTake : kFTake, _vm->_heroTab[_vm->_sex]->_ptr);
+						_vm->_sys->_blinkSprite->_flags._hide = false;
+						_vm->_sys->_blinkSprite = nullptr;
 					} else
 						_vm->offUse();
 


Commit: ff99cb9658eacdcf9bf0cafb22b0529e76a4b3f9
    https://github.com/scummvm/scummvm/commit/ff99cb9658eacdcf9bf0cafb22b0529e76a4b3f9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T11:43:01+02:00

Commit Message:
CGE2: Implement Sprite::works().

Now Anna is also reachable/playable.

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 2090d49..0958563 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -563,20 +563,38 @@ void Hero::operator--() {
 }
 
 bool Sprite::works(Sprite *spr) {
-	//if (!spr || !spr->_ext)
-	//	return false;
-
-	//CommandHandler::Command *c = spr->_ext->_take;
-	//if (c != NULL) {
-	//	c += spr->_takePtr;
-	//	if (c->_ref == _ref)
-	//		if (c->_commandType != kCmdLabel || (c->_val == 0 || c->_val == _vm->_now))
-	//			return true;
-	//}
-
-	warning("STUB: Sprite::works()");
-
-	return false;
+	if (!spr || !spr->_ext)
+		return false;
+	
+	bool ok = false;
+
+	Action a = _vm->_heroTab[_vm->_sex]->_ptr->action();
+	CommandHandler::Command *ct = spr->_ext->_actions[a];
+	if (ct) {
+		int i = spr->_actionCtrl[a]._ptr;
+		int n = spr->_actionCtrl[a]._cnt;
+		while (i < n && !ok) {
+			CommandHandler::Command *c = &ct[i++];
+			if (c->_commandType != kCmdUse)
+				break;
+			ok = (c->_ref == _ref);
+			if (c->_val > 255) {
+				if (ok) {
+					int p = spr->labVal(a, c->_val >> 8);
+					if (p >= 0)
+						spr->_actionCtrl[a]._ptr = p;
+					else
+						ok = false;
+				}
+			} else {
+				if (c->_val && c->_val != _vm->_now)
+					ok = false;
+				break;
+			}
+		}
+	}
+	
+	return ok;
 }
 
 } // End of namespace CGE2


Commit: ea9b4d0729a8f88515164a2d823247b48e55e5b2
    https://github.com/scummvm/scummvm/commit/ea9b4d0729a8f88515164a2d823247b48e55e5b2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T11:50:42+02:00

Commit Message:
CGE2: Implement snMouse().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c02b01c..62d57fb 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -181,7 +181,7 @@ public:
 	void snSlave(Sprite *spr, int val);
 	void snTrans(Sprite *spr, int val);
 	void snPort(Sprite *spr, int val);
-	void snMouse(int val);
+	void snMouse(bool on);
 	void snNNext(Sprite *spr, Action act, int val);
 	void snRNNext(Sprite *spr, int val);
 	void snRMTNext(Sprite *spr, int val);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index d40789c..b7731ae 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -534,8 +534,11 @@ void CGE2Engine::snPort(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snPort()");
 }
 
-void CGE2Engine::snMouse(int val) {
-	warning("STUB: CGE2Engine::snMouse()");
+void CGE2Engine::snMouse(bool on) {
+	if (on)
+		_mouse->on();
+	else
+		_mouse->off();
 }
 
 void CGE2Engine::snNNext(Sprite *spr, Action act, int val) {


Commit: 76846bf4f5567a314c185b77629c0313c9dab22f
    https://github.com/scummvm/scummvm/commit/76846bf4f5567a314c185b77629c0313c9dab22f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T12:23:00+02:00

Commit Message:
CGE2: Implement Hero::fun().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 0958563..1ddf870 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -386,7 +386,12 @@ void Hero::reach(int mode) {
 }
 
 void Hero::fun() {
-	warning("STUB: Hero::fun()");
+	if (_vm->_commandHandler->idle()) {
+		park();
+		_vm->_commandHandler->addCommand(kCmdWait, -1, -1, this);
+		_vm->_commandHandler->addCommand(kCmdSeq, -1, _funStart, this);
+	}
+	_funDel = _funDel0 >> 2;
 }
 
 int Hero::len(V2D v) {


Commit: fcd387553f5242139e78db87f91047c55705e259
    https://github.com/scummvm/scummvm/commit/fcd387553f5242139e78db87f91047c55705e259
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-19T12:30:44+02:00

Commit Message:
CGE2: Implement optionTouch().

Add stubs for called functions.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 62d57fb..db79c64 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -141,7 +141,6 @@ public:
 	void loadPos();
 	void releasePocket(Sprite *spr);
 	void switchHero(int sex);
-	void optionTouch(int opt, uint16 mask);
 	void offUse();
 	void setAutoColors();
 	bool cross(const V2D &a, const V2D &b, const V2D &c, const V2D &d);
@@ -151,6 +150,14 @@ public:
 	int mapCross(const V2D &a, const V2D &b);
 	Sprite *spriteAt(V2D pos);
 
+	void optionTouch(int opt, uint16 mask);
+	void switchColorMode();
+	void switchMusic();
+	void quit();
+	void setVolume(int idx, int cnt);
+	void switchCap();
+	void switchVox();
+
 	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);
 	void setEye(const char *s);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 816eea1..f16f0ce 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1032,7 +1032,62 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 }
 
 void CGE2Engine::optionTouch(int opt, uint16 mask) {
-	warning("STUB: CGE2Engine::optionTouch()");
+	switch (opt) {
+	case 1:
+		if (mask & kMouseLeftUp)
+			switchColorMode();
+		break;
+	case 2:
+		if (mask & kMouseLeftUp)
+			switchMusic();
+		break;
+	case 3:
+		if (mask & kMouseLeftUp)
+			quit();
+		break;
+	case 4:
+		if (mask & (kMouseLeftUp | kMouseRightUp))
+			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
+		break;
+	case 5:
+		if (mask & (kMouseLeftUp | kMouseRightUp))
+			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
+		break;
+	case 8:
+		if (mask & kMouseLeftUp)
+			switchCap();
+		break;
+	case 9:
+		if (mask & kMouseLeftUp)
+			switchVox();
+		break;
+	default:
+		break;
+	}
+}
+
+void CGE2Engine::switchColorMode() {
+	warning("STUB: CGE2Engine::switchColorMode()");
+}
+
+void CGE2Engine::switchMusic() {
+	warning("STUB: CGE2Engine::switchMusic()");
+}
+
+void CGE2Engine::quit() {
+	warning("STUB: CGE2Engine::quit()");
+}
+
+void CGE2Engine::setVolume(int idx, int cnt) {
+	warning("STUB: CGE2Engine::setVolume()");
+}
+
+void CGE2Engine::switchCap() {
+	warning("STUB: CGE2Engine::switchCap()");
+}
+
+void CGE2Engine::switchVox() {
+	warning("STUB: CGE2Engine::switchVox()");
 }
 
 void CGE2Engine::offUse() {


Commit: e708c1e5cd14e1eed2f9e68ff4335cdd00b93f20
    https://github.com/scummvm/scummvm/commit/e708c1e5cd14e1eed2f9e68ff4335cdd00b93f20
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-21T01:57:18+02:00

Commit Message:
CGE2: Implement "quit menu".

Now the "main switch" on the menu panel is working.
Also move a couple of defines from cge2_main.h to cge2.h during the process.

Changed paths:
  A engines/cge2/vmenu.cpp
  A engines/cge2/vmenu.h
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/cge2_main.h
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index db79c64..17d68fb 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -60,31 +60,50 @@ class EventManager;
 class Font;
 class Map;
 
-#define kScrWidth      320
-#define kScrHeight     240
-#define kScrDepth      480
-#define kPanHeight     40
-#define kWorldHeight   (kScrHeight - kPanHeight)
-#define kMaxFile       128
-#define kPathMax       128
-#define kDimMax          8
-#define kWayMax         10
-#define kPocketMax       4
-#define kSceneMax      100
-#define kMaxPoint        4
-#define kInfoX         160
-#define kInfoY         -11
-#define kInfoW         180
-#define kPocketsWidth   59
-#define kLineMax       512
+#define kScrWidth         320
+#define kScrHeight        240
+#define kScrDepth         480
+#define kPanHeight         40
+#define kWorldHeight      (kScrHeight - kPanHeight)
+#define kMaxFile          128
+#define kPathMax          128
+#define kDimMax             8
+#define kWayMax            10
+#define kPocketMax          4
+#define kSceneMax         100
+#define kMaxPoint           4
+#define kInfoX            160
+#define kInfoY            -11
+#define kInfoW            180
+#define kPocketsWidth      59
+#define kLineMax          512
 
-#define kExitOkText     40
-#define kCrackedText    44
-#define kOffUseCount   130
-#define kOffUseText    131
+#define kIntroExt         ".I80"
+#define kTabName          "CGE.TAB"
+#define kPocketFull       170
+#define kGameFrameDelay   (750 / 50)
+#define kGameTickDelay    (750 / 62)
 
-#define kSysTimeRate     6 // 12 Hz
-#define kBlinkRate       4 //  3 Hz
+#define kMusicRef         122
+#define kPowerRef         123
+#define kDvolRef          124
+#define kMvolRef	      125
+#define kRef              126
+#define kBusyRef	      127
+#define kCapRef           128
+#define kVoxRef           129
+
+#define kExitOkText        40
+#define kCrackedText       44
+#define kOffUseCount      130
+#define kOffUseText       131
+
+#define kSysTimeRate        6 // 12 Hz
+#define kBlinkRate          4 //  3 Hz
+
+#define kQuitTitle        200
+#define kQuitText         201
+#define kNoQuitText       202
 
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
@@ -149,6 +168,7 @@ public:
 	int sgn(long n);
 	int mapCross(const V2D &a, const V2D &b);
 	Sprite *spriteAt(V2D pos);
+	void keyClick();
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f16f0ce..34e7cfe 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -35,6 +35,7 @@
 #include "cge2/spare.h"
 #include "cge2/events.h"
 #include "cge2/map.h"
+#include "cge2/vmenu.h"
 
 namespace CGE2 {
 
@@ -1075,7 +1076,27 @@ void CGE2Engine::switchMusic() {
 }
 
 void CGE2Engine::quit() {
-	warning("STUB: CGE2Engine::quit()");
+	Common::Array<Choice *> quitMenu; // Deleted in VMenu's destructor.
+	quitMenu.push_back(new StartCountDownChoice(this));
+	quitMenu.push_back(new ResetQSwitchChoice(this));
+
+	if (_commandHandler->idle()) {
+		if (VMenu::_addr) {
+			_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, VMenu::_addr);
+			ResetQSwitchChoice rqsChoice(this);
+			rqsChoice.proc();
+		} else {
+			quitMenu[0]->_text = _text->getText(kQuitText);
+			quitMenu[1]->_text = _text->getText(kNoQuitText);
+			(new VMenu(this, quitMenu, V2D(this, -1, -1), kCBMnu))->setName(_text->getText(kQuitTitle));
+			_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 0, nullptr);
+			keyClick();
+		}
+	}
+}
+
+void CGE2Engine::keyClick() {
+	_commandHandlerTurbo->addCommand(kCmdSound, -1, 5, nullptr);
 }
 
 void CGE2Engine::setVolume(int idx, int cnt) {
diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index e59c6f0..d6f2371 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -32,21 +32,6 @@
 
 namespace CGE2 {
 
-#define kIntroExt         ".I80"
-#define kTabName          "CGE.TAB"
-#define kPocketFull       170
-#define kGameFrameDelay   (750 / 50)
-#define kGameTickDelay    (750 / 62)
-
-#define kMusicRef         122
-#define kPowerRef         123
-#define kDvolRef          124
-#define kMvolRef	      125
-#define kRef              126
-#define kBusyRef	      127
-#define kCapRef           128
-#define kVoxRef           129
-
 class System : public Sprite {
 public:
 	int _funDel;
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index dc74de5..9a6e0cb 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -14,7 +14,8 @@ MODULE_OBJS = \
 	spare.o \
 	talk.o \
 	events.o \
-	map.o
+	map.o \
+	vmenu.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
new file mode 100644
index 0000000..55ddc2a
--- /dev/null
+++ b/engines/cge2/vmenu.cpp
@@ -0,0 +1,154 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/cge2.h"
+#include "cge2/vmenu.h"
+#include "cge2/events.h"
+
+namespace CGE2 {
+
+void StartCountDownChoice::proc() {
+	_vm->switchScene(-1);
+}
+
+void ResetQSwitchChoice::proc() {
+	_vm->_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
+	_vm->keyClick();
+}
+
+MenuBar::MenuBar(CGE2Engine *vm, uint16 w, byte *c) : Talk(vm) {
+	_color = c;
+	int h = kFontHigh + 2 * kMenuBarVerticalMargin, i = (w += 2 * kMenuBarHorizontalMargin) * h;
+	uint8 *p = new uint8[i];
+	uint8 *p1;
+	uint8 *p2;
+	uint8 lt = _color[kLt];
+	uint8 rb = _color[kRb];
+	BitmapPtr b;
+
+	memset(p + w, kPixelTransp, i - 2 * w);
+	memset(p, lt, w);
+	memset(p + i - w, rb, w);
+	p1 = p;
+	p2 = p + i - 1;
+	for (i = 0; i < h; i++) {
+		*p1 = lt;
+		*p2 = rb;
+		p1 += w;
+		p2 -= w;
+	}
+	b = new Bitmap[1];
+	b[0] = Bitmap(vm, w, h, p);
+	delete[] p;
+	setShapeList(b, 1);
+	_flags._slav = true;
+	_flags._tran = true;
+	_flags._kill = true;
+}
+
+VMenu *VMenu::_addr = nullptr;
+
+VMenu::VMenu(CGE2Engine *vm, Common::Array<Choice *> list, V2D pos, ColorBank col)
+	: Talk(vm, vmGather(list), kTBRect, col), _menu(list), _bar(nullptr), _items(list.size()), _vm(vm) {
+	delete[] _vmgt; // Lefotver of vmGather.
+
+	_addr = this;
+	_recent = -1;
+	_flags._kill = true;
+
+	if (pos.x < 0 || pos.y < 0)
+		center();
+	else
+		gotoxyz(V2D(_vm, pos.x - _siz.x / 2, pos.y - (kTextVMargin + kFontHigh / 2)));
+
+	_vm->_vga->_showQ->append(this);
+	_bar = new MenuBar(_vm, _siz.x - 2 * kTextHMargin, _color);
+	_bar->gotoxyz(V2D(_vm, _pos2D.x, _pos2D.y + kTextVMargin - kMenuBarVerticalMargin));
+	_vm->_vga->_showQ->append(_bar);
+}
+
+char *VMenu::vmGather(Common::Array<Choice *> list) {
+	int len = 0;
+	int h = 0;
+
+	for (int i = 0; i < list.size(); i++) {
+		len += strlen(list[i]->_text);
+		++h;
+	}
+	_vmgt = new char[len + h];
+	if (_vmgt) {
+		*_vmgt = '\0';
+		for (int i = 0; i < list.size(); i++) {
+			if (*_vmgt)
+				strcat(_vmgt, "|");
+			strcat(_vmgt, list[i]->_text);
+			++h;
+		}
+	}
+	return _vmgt;
+}
+
+
+VMenu::~VMenu() {
+	_addr = nullptr;
+
+	for (int i = 0; i < _menu.size(); i++) {
+		delete _menu[i];
+	}
+}
+
+void VMenu::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
+	int h = kFontHigh + kTextLineSpace;
+	int n = 0;
+	bool ok = false;
+
+	if (_items) {
+		Sprite::touch(mask, pos, keyCode);
+
+		pos.y -= kTextVMargin - 1;
+		if (pos.y >= 0) {
+			if (pos.x < 0)
+				pos.x = -pos.x;
+			n = pos.y / h;
+			if (n < _items)
+				ok = (pos.x <= (_siz.x >> 1) - kTextHMargin);
+			else
+				n = _items - 1;
+		}
+
+		_bar->gotoxyz(V2D(_vm, _pos2D.x, _pos2D.y + kTextVMargin + n * h - kMenuBarVerticalMargin));
+		n = _items - 1 - n;
+
+		if (ok && (mask & kMouseLeftUp)) {
+			_items = 0;
+			_vm->_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, this);
+			_menu[_recent = n]->proc();
+		}
+	}
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/vmenu.h b/engines/cge2/vmenu.h
new file mode 100644
index 0000000..c988e1e
--- /dev/null
+++ b/engines/cge2/vmenu.h
@@ -0,0 +1,86 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_VMENU_H
+#define CGE2_VMENU_H
+
+#define kMenuBarVerticalMargin   1
+#define kMenuBarHorizontalMargin 3
+#define kLt                      3
+#define kRb                      1
+
+#include "cge2/talk.h"
+
+namespace CGE2 {
+
+class Choice {
+protected:
+	CGE2Engine *_vm;
+public:
+	char *_text;
+	virtual void proc() = 0;
+
+	Choice(CGE2Engine *vm) : _vm(vm), _text(nullptr) {}
+};
+
+class StartCountDownChoice : public Choice {
+public:
+	StartCountDownChoice(CGE2Engine *vm) : Choice(vm) {}
+	void proc();
+};
+
+class ResetQSwitchChoice : public Choice {
+public:
+	ResetQSwitchChoice(CGE2Engine *vm) : Choice(vm) {}
+	void proc();
+};
+
+class MenuBar : public Talk {
+public:
+	MenuBar(CGE2Engine *vm, uint16 w, byte *c);
+};
+
+class VMenu : public Talk {
+	CGE2Engine *_vm;
+
+	uint16 _items;
+	Common::Array<Choice *> _menu;
+public:
+	char *_vmgt;
+	static VMenu *_addr;
+	int _recent;
+	MenuBar *_bar;
+
+	VMenu(CGE2Engine *vm, Common::Array<Choice *> list, V2D pos, ColorBank col);
+	~VMenu(void);
+	void touch(uint16 mask, V2D pos, Common::KeyCode keyCode);
+	char *vmGather(Common::Array<Choice *> list);
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_VMENU_H


Commit: 7faa95bfdd7d5fd2eb2719269090f23b43bfc6bc
    https://github.com/scummvm/scummvm/commit/7faa95bfdd7d5fd2eb2719269090f23b43bfc6bc
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-21T18:33:31+02:00

Commit Message:
CGE2: Avoid some signed/unsigned comparisons

Changed paths:
    engines/cge2/vmenu.cpp



diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
index 55ddc2a..a2f2f05 100644
--- a/engines/cge2/vmenu.cpp
+++ b/engines/cge2/vmenu.cpp
@@ -95,14 +95,14 @@ char *VMenu::vmGather(Common::Array<Choice *> list) {
 	int len = 0;
 	int h = 0;
 
-	for (int i = 0; i < list.size(); i++) {
+	for (uint i = 0; i < list.size(); i++) {
 		len += strlen(list[i]->_text);
 		++h;
 	}
 	_vmgt = new char[len + h];
 	if (_vmgt) {
 		*_vmgt = '\0';
-		for (int i = 0; i < list.size(); i++) {
+		for (uint i = 0; i < list.size(); i++) {
 			if (*_vmgt)
 				strcat(_vmgt, "|");
 			strcat(_vmgt, list[i]->_text);
@@ -116,7 +116,7 @@ char *VMenu::vmGather(Common::Array<Choice *> list) {
 VMenu::~VMenu() {
 	_addr = nullptr;
 
-	for (int i = 0; i < _menu.size(); i++) {
+	for (uint i = 0; i < _menu.size(); i++) {
 		delete _menu[i];
 	}
 }


Commit: f1b14c6d31b1f7eafe4720302460c6265fb87025
    https://github.com/scummvm/scummvm/commit/f1b14c6d31b1f7eafe4720302460c6265fb87025
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-21T18:45:28+02:00

Commit Message:
CGE2: Reduce the scope of some variables

Changed paths:
    engines/cge2/vmenu.cpp



diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
index a2f2f05..fa4c29c 100644
--- a/engines/cge2/vmenu.cpp
+++ b/engines/cge2/vmenu.cpp
@@ -122,13 +122,12 @@ VMenu::~VMenu() {
 }
 
 void VMenu::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
-	int h = kFontHigh + kTextLineSpace;
-	int n = 0;
-	bool ok = false;
-
 	if (_items) {
 		Sprite::touch(mask, pos, keyCode);
 
+		int n = 0;
+		bool ok = false;
+		int h = kFontHigh + kTextLineSpace;
 		pos.y -= kTextVMargin - 1;
 		if (pos.y >= 0) {
 			if (pos.x < 0)


Commit: fc5c92b5d0b46c0728a5642e43b06741871f8ec7
    https://github.com/scummvm/scummvm/commit/fc5c92b5d0b46c0728a5642e43b06741871f8ec7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T13:05:24+02:00

Commit Message:
CGE2: Implement snGive() and snRmNear().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index b7731ae..824d4e3 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -505,7 +505,16 @@ void CGE2Engine::snKeep(Sprite *spr, int stp) {
 }
 
 void CGE2Engine::snGive(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snGive()");
+	if (spr) {
+		int p = findActivePocket(spr->_ref);
+		if (p >= 0) {
+			releasePocket(spr);
+			spr->setScene(_now);
+			if (val >= 0)
+				spr->step(val);
+		}
+	}
+	selectPocket(-1);
 }
 
 void CGE2Engine::snGoto(Sprite *spr, int val) {
@@ -562,7 +571,8 @@ void CGE2Engine::snRFTNext(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snRmNear(Sprite *spr) {
-	warning("STUB: CGE2Engine::snRmNear()");
+	if (spr)
+		spr->_actionCtrl[kNear]._cnt = 0;
 }
 
 void CGE2Engine::snRmMTake(Sprite *spr) {


Commit: f36cfb629ce6d23fc0f7a4437ea3b71daa11833f
    https://github.com/scummvm/scummvm/commit/f36cfb629ce6d23fc0f7a4437ea3b71daa11833f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T13:26:55+02:00

Commit Message:
CGE2: Fix mapCross().

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 1ddf870..5e075d8 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -542,7 +542,7 @@ int CGE2Engine::mapCross(const V2D &a, const V2D &b) {
 			if (cross(a, b, *n0, *n))
 				++cnt;
 		
-			if (n == p)
+			if (*n == *p)
 				p = nullptr;	
 		} else {
 			p = n;
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index a6e12fe..948c3ab 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -148,6 +148,7 @@ public:
 	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }
 	bool operator==(const V3D &p) const { V3D tmp(x, y); return tmp._x == p._x && tmp._y == p._y && tmp._z == p._z; }
 	bool operator!=(const V3D &p) const { V3D tmp(x, y); return tmp._x != p._x || tmp._y != p._y || tmp._z == p._z; }
+	bool operator==(const V2D &p) const { return x == p.x && y == p.y; }
 	uint16 area() { return x * y; }
 	bool limited(const V2D &p) {
 		return ((x < p.x) && (y < p.y));


Commit: 8ae41648f9b7240aee5418afad3da4d6035b0c6e
    https://github.com/scummvm/scummvm/commit/8ae41648f9b7240aee5418afad3da4d6035b0c6e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T13:38:47+02:00

Commit Message:
CGE2: Implement snSwap().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 17d68fb..130b1ba 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -169,6 +169,7 @@ public:
 	int mapCross(const V2D &a, const V2D &b);
 	Sprite *spriteAt(V2D pos);
 	void keyClick();
+	void swapInPocket(Sprite *spr, Sprite *xspr);
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 824d4e3..4a932e5 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -427,7 +427,38 @@ void CGE2Engine::snSend(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snSwap(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snSwap()");
+	bool tak = _taken;
+	Sprite *xspr = locate(val);
+	if (spr && xspr) {
+		bool was1 = (_vga->_showQ->locate(spr->_ref) != nullptr);
+		bool xwas1 = (_vga->_showQ->locate(val) != nullptr);
+
+		int tmp = spr->_scene;
+		spr->setScene(xspr->_scene);
+		xspr->setScene(tmp);
+
+		SWAP(spr->_pos2D, xspr->_pos2D);
+		SWAP(spr->_pos3D, xspr->_pos3D);
+		if (spr->_flags._kept)
+			swapInPocket(spr, xspr);
+		if (xwas1 != was1) {
+			if (was1) {
+				hide1(spr);
+				_spare->dispose(spr);
+			} else
+				expandSprite(spr);
+			if (xwas1) {
+				hide1(xspr);
+				_spare->dispose(xspr);
+			} else {
+				expandSprite(xspr);
+				_taken = false;
+			}
+		}
+	}
+	if (_taken)
+		_spare->dispose(xspr);
+	_taken = tak;
 }
 
 void CGE2Engine::snCover(Sprite *spr, int val) {
@@ -689,6 +720,22 @@ void CGE2Engine::hide1(Sprite *spr) {
 	_commandHandlerTurbo->addCommand(kCmdGhost, -1, 0, spr->ghost());
 }
 
+void CGE2Engine::swapInPocket(Sprite *spr, Sprite *xspr) {
+	int i, j;
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax; j++) {
+			Sprite *&poc = _heroTab[i]->_pocket[j];
+			if (poc == spr) {
+				spr->_flags._kept = false;
+				poc = xspr;
+				xspr->_flags._kept = true;
+				xspr->_flags._port = false;
+				return;
+			}
+		}
+	}
+}
+
 Sprite *CGE2Engine::expandSprite(Sprite *spr) {
 	if (spr)
 		_vga->_showQ->insert(spr);


Commit: af646247f30af15c3641a1ec481d00d9a8eb9239
    https://github.com/scummvm/scummvm/commit/af646247f30af15c3641a1ec481d00d9a8eb9239
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-22T13:48:58+02:00

Commit Message:
CGE2: Remove useless variable declarations

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 4a932e5..300c02a 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -721,7 +721,6 @@ void CGE2Engine::hide1(Sprite *spr) {
 }
 
 void CGE2Engine::swapInPocket(Sprite *spr, Sprite *xspr) {
-	int i, j;
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < kPocketMax; j++) {
 			Sprite *&poc = _heroTab[i]->_pocket[j];


Commit: cb3dce698c3903f180bfe4a19fca287d3affeea6
    https://github.com/scummvm/scummvm/commit/cb3dce698c3903f180bfe4a19fca287d3affeea6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T14:10:47+02:00

Commit Message:
CGE2: Rework Hero::len().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 5e075d8..fdec752 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -395,7 +395,7 @@ void Hero::fun() {
 }
 
 int Hero::len(V2D v) {
-	return ((v.x * v.x + v.y * v.y) * (v.x * v.x + v.y * v.y));
+	return sqrt(double(v.x * v.x + v.y * v.y));
 }
 
 bool Hero::findWay(){


Commit: 6015eddc41643ac71d7fa57a99a7378ecd5a1da7
    https://github.com/scummvm/scummvm/commit/6015eddc41643ac71d7fa57a99a7378ecd5a1da7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T18:44:33+02:00

Commit Message:
CGE2: Remove double definition kMaxTry.

Changed paths:
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 7ddc871..2998d7e 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -31,8 +31,6 @@
 #include "cge2/vga13h.h"
 #include "cge2/snail.h"
 
-#define	kMaxTry	400
-
 namespace CGE2 {
 
 #define kMaxTry 400


Commit: 7b628c7ffc779f065fcd60caa2c1d1172460b9be
    https://github.com/scummvm/scummvm/commit/7b628c7ffc779f065fcd60caa2c1d1172460b9be
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T19:06:40+02:00

Commit Message:
CGE2: Fix some formatting in Hero.

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index fdec752..3e9a439 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -489,7 +489,7 @@ V3D Hero::screenToGround(V2D pos) {
 int Hero::cross(const V2D &a, const V2D &b) {
 	int x = _pos3D._x.trunc();
 	int z = _pos3D._z.trunc();
-	int r = ((_siz.x / 3) * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc()- z);
+	int r = ((_siz.x / 3) * _vm->_eye->_z.trunc()) / (_vm->_eye->_z.trunc() - z);
 	return _vm->cross(a, b, V2D(_vm, x - r, z), V2D(_vm, x + r, z)) << 1;
 }
 
@@ -512,7 +512,7 @@ bool CGE2Engine::contain(const V2D &a, const V2D &b, const V2D &p) {
 }
 
 long CGE2Engine::det(const V2D &a, const V2D &b, const V2D &c) {
-	long n = ((long)a.x * b.y + (long)b.x * c.y + (long)c.x*a.y) - ((long)c.x*b.y + (long)b.x*a.y + (long)a.x*c.y);
+	long n = ((long)a.x * b.y + (long)b.x * c.y + (long)c.x * a.y) - ((long)c.x * b.y + (long)b.x * a.y + (long)a.x * c.y);
 	return n;
 }
 


Commit: c8ed838c054d743ec692d21e643717097f1681e5
    https://github.com/scummvm/scummvm/commit/c8ed838c054d743ec692d21e643717097f1681e5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T19:28:55+02:00

Commit Message:
CGE2: Fix formatting in FXP.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 948c3ab..1340175 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -61,8 +61,8 @@ public:
 	FXP (void): f(0), i(0) { }
 	FXP (int i0, int f0 = 0) : i(i0), f(0) { }
 	FXP& operator = (const int& x) { i = x; f = 0; return *this; }
-	FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined()+x.Joined(); return y; }
-	FXP operator - (const FXP& x) const { FXP y; y.Joined() = Joined()-x.Joined(); return y; }
+	FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined() + x.Joined(); return y; }
+	FXP operator - (const FXP& x) const { FXP y; y.Joined() = Joined() - x.Joined(); return y; }
 	FXP operator * (const FXP& x) const {
 		FXP y; long t;
 		y.i = i * x.i;


Commit: 19bc15193941d9afd5a896c8bdead2e896f780bd
    https://github.com/scummvm/scummvm/commit/19bc15193941d9afd5a896c8bdead2e896f780bd
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-22T23:11:27+02:00

Commit Message:
CGE2: Some more formatting fix in FXP.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 1340175..6876bcd 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -52,8 +52,7 @@ namespace CGE2 {
 #define kPalSize         (kPalCount * 3)
 
 // From FXP.H
-class FXP	// fixed point
-{
+class FXP { // fixed point
 	uint16 f;
 	int16 i;
 	long& Joined (void) const { return *(long *)&f; }
@@ -67,7 +66,7 @@ public:
 		FXP y; long t;
 		y.i = i * x.i;
 		t = ((long) f * x.f) >> 16;
-		t += ((long) i * x.f) + ((long) f  * x.i);
+		t += ((long) i * x.f) + ((long) f * x.i);
 		y.f = t & 0xFFFF;
 		y.i += t >> 16;
 		return y;


Commit: 2226eb078969dc4217bb490e594819e027187590
    https://github.com/scummvm/scummvm/commit/2226eb078969dc4217bb490e594819e027187590
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-23T10:20:24+02:00

Commit Message:
CGE2: Implement snSay(), reimplement some parts of the sound code.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 300c02a..5ec6274 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -286,13 +286,12 @@ void CommandHandler::runCommand() {
 			break;
 		case kCmdSound:
 			_vm->snSound(spr, tailCmd._val);
-			_count = 1;
 			break;
 		case kCmdMap:
 			_vm->_heroTab[tailCmd._ref & 1]->_ptr->_ignoreMap = tailCmd._val == 0;
 			break;
 		case kCmdCount:
-			_count = tailCmd._val;
+			_vm->_sound->setRepeat(tailCmd._val);
 			break;
 		case kCmdRoom:
 			_vm->snRoom(spr, tailCmd._val);
@@ -512,7 +511,10 @@ void CGE2Engine::snKeep(Sprite *spr, int stp) {
 
 	if (spr && !spr->_flags._kept && ht->_pocket[pp] == nullptr) {
 		V3D pos(14, -10, -1);
+		int16 oldRepeat = _sound->getRepeat();
+		_sound->setRepeat(1);
 		snSound(ht->_ptr, 3);
+		_sound->setRepeat(oldRepeat);
 		if (_taken) {
 			_vga->_showQ->insert(spr);
 			_taken = false;
@@ -674,7 +676,8 @@ void CGE2Engine::snSound(Sprite *spr, int wav) {
 		_sound->play(_fx->load(_commandStat._ref[1], _commandStat._ref[0]),
 			(spr) ? (spr->_pos2D.x / (kScrWidth / 16)) : 8);
 	}
-	
+
+	_sound->setRepeat(1);
 }
 
 void CGE2Engine::snRoom(Sprite *spr, int val) {
@@ -711,7 +714,14 @@ void CGE2Engine::snSay(Sprite *spr, int val) {
 			int i = val;
 			if (i < 256)
 				i -= 100;
-			warning("STUB: CGE2Engine::snSay"); // TODO: Implement it with the revision of the sound code!
+			int16 oldRepeat = _sound->getRepeat();
+			_sound->setRepeat(1);
+			snSound(spr, i);
+			_sound->setRepeat(oldRepeat);
+			//_commandStat._wait = &_sound->_smpinf._counter;
+			// This line is commented out for now since I wasn't able to find where this flag is reset
+			// and it's prevented the main loop from doing anything.
+			// TODO: Recheck this later! At the moment it seems working fine.
 		}
 	}
 }


Commit: 23adc159ef4dff0a7d08ba2b11d9847805e5dea8
    https://github.com/scummvm/scummvm/commit/23adc159ef4dff0a7d08ba2b11d9847805e5dea8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-23T11:50:49+02:00

Commit Message:
CGE2: Implement busy() and revise connected parts of the engine.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/sound.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 9e1e30a..6976a6f 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -96,6 +96,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_sayCap = true;
 	_sayVox = true;
 	_req = 1;
+	_midiNotify = nullptr;
+	_spriteNotify = nullptr;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 130b1ba..c569bf9 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -113,6 +113,8 @@ enum Action { kNear, kMTake, kFTake, kActions };
 
 enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
 
+typedef void (CGE2Engine::*NotifyFunctionType)();
+
 class CGE2Engine : public Engine {
 private:
 	uint32 _lastFrame, _lastTick;
@@ -170,6 +172,7 @@ public:
 	Sprite *spriteAt(V2D pos);
 	void keyClick();
 	void swapInPocket(Sprite *spr, Sprite *xspr);
+	void busyStep();
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
@@ -262,6 +265,8 @@ public:
 	bool _sayCap;
 	bool _sayVox;
 	int _req;
+	NotifyFunctionType _midiNotify;
+	NotifyFunctionType _spriteNotify;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 34e7cfe..797dbe2 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -648,7 +648,21 @@ void CGE2Engine::selectPocket(int n) {
 }
 
 void CGE2Engine::busy(bool on) {
-	warning("STUB: CGE2Engine::busy()");
+	if (on) {
+		_spriteNotify = _midiNotify = &CGE2::CGE2Engine::busyStep;
+		busyStep();
+	} else {
+		if (_busyPtr)
+			_busyPtr->step(0);
+		_spriteNotify = _midiNotify = nullptr;
+	}
+}
+
+void CGE2Engine::busyStep() {
+	if (_busyPtr) {
+		_busyPtr->step((_busyPtr->_seqPtr) ? -1 : 1);
+		_busyPtr->show(0);
+	}
 }
 
 void CGE2Engine::runGame() {
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index c657a37..652907b 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -190,7 +190,8 @@ void MusicPlayer::killMidi() {
 }
 
 void MusicPlayer::loadMidi(int ref) {
-	warning("STUB: MusicPlayer::loadMidi()"); // if (MidiNotify) MidiNotify();
+	if (_vm->_midiNotify != nullptr)
+		(_vm->*_vm->_midiNotify)();
 
 	// Work out the filename and check the given MIDI file exists
 	Common::String filename = Common::String::format("%.2dSG%.2d.MID", ref >> 8, ref & 0xFF);
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 24376d9..1c48a96 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -56,8 +56,6 @@ Seq *getConstantSeq(bool seqFlag) {
 	return seq;
 }
 
-void (*Sprite::notify)() = nullptr;
-
 byte Sprite::_constY = 0;
 byte Sprite::_follow = 0;
 
@@ -249,8 +247,8 @@ Sprite *Sprite::expand() {
 	if (_ext)
 		return this;
 
-	if (notify != nullptr)
-		notify();
+	if (_vm->_spriteNotify != nullptr)
+		(_vm->*_vm->_spriteNotify)();
 
 	_ext = new SprExt(_vm);
 	assert(_ext != NULL);
@@ -439,8 +437,8 @@ Sprite *Sprite::contract() {
 		curSeq->_dx = curSeq->_dy = curSeq->_dz = 0;
 	}
 
-	if (notify)
-		notify();
+	if (_vm->_spriteNotify != nullptr)
+		(_vm->*_vm->_spriteNotify)();
 
 	if (e->_name) {
 		delete[] e->_name;


Commit: 0eece817ebb5f6463467294f274da1dfb0b3164c
    https://github.com/scummvm/scummvm/commit/0eece817ebb5f6463467294f274da1dfb0b3164c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-23T13:11:54+02:00

Commit Message:
CGE2: Fix releasePocket().

Now the inventory system is working as intended.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 797dbe2..6c572d0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -796,7 +796,7 @@ void CGE2Engine::loadPos() {
 void CGE2Engine::releasePocket(Sprite *spr) {
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < kPocketMax; j++) {
-			Sprite *poc = _heroTab[i]->_pocket[j];
+			Sprite *&poc = _heroTab[i]->_pocket[j];
 			if (poc == spr) {
 				spr->_flags._kept = false;
 				poc = nullptr;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 1c48a96..2c8a3a6 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -104,7 +104,7 @@ Sprite::Sprite(CGE2Engine *vm, BitmapPtr shpP, int cnt)
 
 Sprite::~Sprite() {
 	if (_vm->_sprite == this)
-		_vm->_sprite = NULL;
+		_vm->_sprite = nullptr;
 
 	contract();
 }


Commit: 840eef8eb199c032a119357bd6bad394d287e78f
    https://github.com/scummvm/scummvm/commit/840eef8eb199c032a119357bd6bad394d287e78f
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-23T18:10:05+02:00

Commit Message:
CGE2: Add a big hack to work around the coordinates issue

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 6c572d0..2940833 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1010,7 +1010,8 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 		} else { // sprite NOT in pocket
 			Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
 			if (!_vm->_talk) {
-				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1))
+				// HACK: the "+3" is a ugly hack used to compensate a pathfinding issue. To be fixed!!
+				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1) + 3)
 					h->walkTo(this);
 				else if (_vm->_sys->_blinkSprite) {
 					if (works(_vm->_sys->_blinkSprite)) {
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 3e9a439..d1caf1f 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -314,7 +314,8 @@ int Hero::distance(V3D pos) {
 	V3D di = _pos3D - pos;
 	int x = di._x.round();
 	int z = di._z.round();
-	return ((int)sqrt((long double)x * x + z * z));
+	int retval = (int)sqrt((long double)x * x + z * z);
+	return retval;
 }
 
 int Hero::distance(Sprite *spr) {


Commit: 3dd6c9f7aad7acf43cf90e5405047706ec697adc
    https://github.com/scummvm/scummvm/commit/3dd6c9f7aad7acf43cf90e5405047706ec697adc
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-24T22:14:19+02:00

Commit Message:
CGE2: Implement a couple of stubs

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2940833..5d4a97f 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -807,7 +807,10 @@ void CGE2Engine::releasePocket(Sprite *spr) {
 }
 
 void CGE2Engine::checkSaySwitch() {
-	warning("STUB: CGE2Engine::checkSaySwitch()");
+//	if (SNDDrvInfo.DDEV == DEV_QUIET)
+//		_sayVox = !(_sayCap = true);
+	_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
+	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
 }
 
 void CGE2Engine::loadTab() {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 5ec6274..49041bb 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -592,15 +592,18 @@ void CGE2Engine::snNNext(Sprite *spr, Action act, int val) {
 }
 
 void CGE2Engine::snRNNext(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snRNNext()");
+	if (spr)
+		spr->_actionCtrl[kNear]._ptr += val;
 }
 
 void CGE2Engine::snRMTNext(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snRMTNext()");
+	if (spr)
+		spr->_actionCtrl[kMTake]._ptr += val;
 }
 
-void CGE2Engine::snRFTNext(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snRFTNext()");
+void CGE2Engine::snRFTNext(Sprite * spr, int val) {
+	if (spr)
+		spr->_actionCtrl[kFTake]._ptr += val;
 }
 
 void CGE2Engine::snRmNear(Sprite *spr) {
@@ -614,7 +617,8 @@ void CGE2Engine::snRmMTake(Sprite *spr) {
 }
 
 void CGE2Engine::snRmFTake(Sprite *spr) {
-	warning("STUB: CGE2Engine::snRmFTake()");
+	if (spr)
+		spr->_actionCtrl[kFTake]._cnt = 0;
 }
 
 void CGE2Engine::snFlag(int ref, int val) {


Commit: 2bc35f6f6db4fd963d6348e2772d928d136480f8
    https://github.com/scummvm/scummvm/commit/2bc35f6f6db4fd963d6348e2772d928d136480f8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-24T23:36:37+02:00

Commit Message:
CGE2: Add a work around for missing VBM in scene 4

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index c62a784..6c7e39a 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -44,7 +44,14 @@ void Bitmap::setVM(CGE2Engine *vm) {
 
 Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _v(nullptr), _b(nullptr), _map(0), _vm(vm) {
 	char pat[kMaxPath];
-	forceExt(pat, fname, ".VBM");
+
+	if (!strcmp(fname, "04tal201")) {
+		strcpy(pat, "04tal202");
+		warning("Workaround for missing VBM: 04tal201");
+	} else
+		strcpy(pat, fname);
+
+	forceExt(pat, pat, ".VBM");
 
 	if (_vm->_resman->exist(pat)) {
 		EncryptedStream file(_vm, pat);
@@ -53,7 +60,7 @@ Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _v(nullptr), _b(nullptr), _m
 		if (!loadVBM(&file))
 			error("Bad VBM [%s]", fname);
 	} else {
-		error("Bad VBM [%s]", fname);
+		warning("Missing VBM [%s]", pat);
 	}
 }
 


Commit: 384f1b664bc10c18a1501093b80fa4d6ca146475
    https://github.com/scummvm/scummvm/commit/384f1b664bc10c18a1501093b80fa4d6ca146475
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-25T19:36:59+02:00

Commit Message:
CGE2: Implement snMidi()

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 49041bb..9b77fe3 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -364,7 +364,10 @@ void CGE2Engine::snHide(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snMidi(int val) {
-	warning("STUB: CGE2Engine::snMidi()");
+	if (val < 0)
+		_midiPlayer->killMidi();
+	else if (_music)
+		_midiPlayer->loadMidi(val);
 }
 
 void CGE2Engine::snSetDlg(int clr, int set) {


Commit: 00c867f8ea983cc2194a0bf2208d48511605d685
    https://github.com/scummvm/scummvm/commit/00c867f8ea983cc2194a0bf2208d48511605d685
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-25T19:37:25+02:00

Commit Message:
CGE2: Add a safeguard in Sprite::show()

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 2c8a3a6..9507ade 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -612,6 +612,7 @@ void Sprite::show() {
 }
 
 void Sprite::show(uint16 pg) {
+	assert(pg < 4);
 	Graphics::Surface *a = _vm->_vga->_page[1];
 	_vm->_vga->_page[1] = _vm->_vga->_page[pg];
 	getShp()->show(_pos2D);
@@ -802,8 +803,8 @@ Sprite *Queue::remove(Sprite *spr) {
 		spr->_next->_prev = spr->_prev;
 	if (spr->_prev)
 		spr->_prev->_next = spr->_next;
-	spr->_prev = NULL;
-	spr->_next = NULL;
+	spr->_prev = nullptr;
+	spr->_next = nullptr;
 	return spr;
 }
 


Commit: 014d6bd9f0d561b0fff4748a46606281042046e0
    https://github.com/scummvm/scummvm/commit/014d6bd9f0d561b0fff4748a46606281042046e0
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-26T21:07:24+02:00

Commit Message:
CGE2: Hopefully fix compilation for GCC

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 5d4a97f..75b9aff 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -619,7 +619,7 @@ void CGE2Engine::tick() {
 void CGE2Engine::openPocket() {
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < kPocketMax + 1; j++) {
-			int ref = (int)_heroTab[i]->_pocket[j];
+			int ref = (int)_heroTab[i]->_downPocketId[j];
 			_heroTab[i]->_pocket[j] = (ref == -1) ? nullptr : _vga->_showQ->locate(ref);
 		}
 	}
@@ -629,7 +629,7 @@ void CGE2Engine::closePocket() {
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < kPocketMax + 1; j++) {
 			Sprite *spr = _heroTab[i]->_pocket[j];
-			_heroTab[i]->_pocket[j] = (Sprite*)((spr) ? spr->_ref : -1);
+			_heroTab[i]->_downPocketId[j] = (spr) ? spr->_ref : -1;
 		}
 	}
 }
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 2998d7e..41eb3ac 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -41,13 +41,16 @@ struct HeroTab {
 	Hero *_ptr;
 	Sprite *_face;
 	Sprite *_pocket[kPocketMax + 1];
+	int _downPocketId[kPocketMax + 1];
 	int _pocPtr;
 	V2D *_posTab[kSceneMax];
 	HeroTab(CGE2Engine *vm) {
 		_ptr = nullptr;
 		_face = nullptr;
-		for (int i = 0; i < kPocketMax + 1; i++)
+		for (int i = 0; i < kPocketMax + 1; i++) {
 			_pocket[i] = nullptr;
+			_downPocketId[i] = -1;
+		}
 		_pocPtr = 0;
 		for (int i = 0; i < kSceneMax; i++)
 			_posTab[i] = nullptr;


Commit: e9396f8d1035b771d8c3fe99d8b815a3db39cfe5
    https://github.com/scummvm/scummvm/commit/e9396f8d1035b771d8c3fe99d8b815a3db39cfe5
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-27T01:09:34+02:00

Commit Message:
CGE2: Fix some GCC warnings

Changed paths:
    engines/cge2/talk.cpp



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index a6d9945..ddd98ac 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -50,7 +50,8 @@ Font::~Font() {
 }
 
 void Font::load() {
-	char *path = "CGE.CFT";
+	char path[10];
+	strcpy(path, "CGE.CFT");
 	if (!_vm->_resman->exist(path))
 		error("Missing configuration file! %s", path);
 
@@ -67,7 +68,7 @@ void Font::load() {
 	}
 	fontFile.read(_map, p);
 
-	path = "CGE.TXC";
+	strcpy(path, "CGE.TXC");
 	if (!_vm->_resman->exist(path))
 		error("Missing configuration file! %s", path);
 
@@ -84,16 +85,16 @@ void Font::load() {
 			continue;
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 		
-		char *p;
+		char *token;
 
-		if ((p = _vm->token(tmpStr)) == NULL)
+		if ((token = _vm->token(tmpStr)) == NULL)
 			error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
-		_colorSet[n][0] = _vm->number(p);
+		_colorSet[n][0] = _vm->number(token);
 
 		for (int i = 1; i < 4; i++) {
-			if ((p = _vm->token(nullptr)) == NULL)
+			if ((token = _vm->token(nullptr)) == NULL)
 				error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
-			_colorSet[n][i] = _vm->number(p);
+			_colorSet[n][i] = _vm->number(token);
 		}
 
 		n++;


Commit: b08b3eac33a6f4039df5f55a15557f7a2eca245f
    https://github.com/scummvm/scummvm/commit/b08b3eac33a6f4039df5f55a15557f7a2eca245f
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-27T07:34:27+02:00

Commit Message:
CGE2: Add a virtual destructor in Choice, some minor cleanup

Changed paths:
    engines/cge2/text.cpp
    engines/cge2/vga13h.h
    engines/cge2/vmenu.h



diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index c7f6a06..24fc8e5 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -45,7 +45,7 @@ Text::Text(CGE2Engine *vm, const char *fname) : _vm(vm) {
 	_cache = new Handler[txtCount];
 	for (_size = 0; _size < txtCount; _size++) {
 		_cache[_size]._ref = 0;
-		_cache[_size]._text = NULL;
+		_cache[_size]._text = nullptr;
 	}
 	load();
 }
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 6876bcd..5e1280c 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -55,7 +55,7 @@ namespace CGE2 {
 class FXP { // fixed point
 	uint16 f;
 	int16 i;
-	long& Joined (void) const { return *(long *)&f; }
+	long& Joined() const { return *(long *)&f; }
 public:
 	FXP (void): f(0), i(0) { }
 	FXP (int i0, int f0 = 0) : i(i0), f(0) { }
diff --git a/engines/cge2/vmenu.h b/engines/cge2/vmenu.h
index c988e1e..724fb5d 100644
--- a/engines/cge2/vmenu.h
+++ b/engines/cge2/vmenu.h
@@ -45,6 +45,7 @@ public:
 	virtual void proc() = 0;
 
 	Choice(CGE2Engine *vm) : _vm(vm), _text(nullptr) {}
+	virtual ~Choice() {}
 };
 
 class StartCountDownChoice : public Choice {
@@ -76,7 +77,7 @@ public:
 	MenuBar *_bar;
 
 	VMenu(CGE2Engine *vm, Common::Array<Choice *> list, V2D pos, ColorBank col);
-	~VMenu(void);
+	~VMenu();
 	void touch(uint16 mask, V2D pos, Common::KeyCode keyCode);
 	char *vmGather(Common::Array<Choice *> list);
 };


Commit: 723bdc12add207c5a8c87e3b3300e61458e568b5
    https://github.com/scummvm/scummvm/commit/723bdc12add207c5a8c87e3b3300e61458e568b5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-27T12:11:06+02:00

Commit Message:
CGE2: Make Hero's expand() and contract() virtual.

Now it mimics the original correctly.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 5e1280c..617e1a7 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -239,8 +239,8 @@ public:
 	void moveShapesHi();
 	void moveShapesLo();
 	int labVal(Action snq, int lab);
-	Sprite *expand();
-	Sprite *contract();
+	virtual Sprite *expand();
+	virtual Sprite *contract();
 	void backShow();
 	void setName(char *newName);
 	inline char *name() {


Commit: 2514d866301ca9c9bcc26b54031889e2a0e5a28d
    https://github.com/scummvm/scummvm/commit/2514d866301ca9c9bcc26b54031889e2a0e5a28d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-27T23:40:23+02:00

Commit Message:
CGE2: Implement Sprite::step() fully.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 9507ade..29ee5c8 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -492,7 +492,36 @@ void Sprite::step(int nr) {
 			_seqPtr = _ext->_seq[_seqPtr]._next;
 
 		if (_file[2] == '~') { // FLY-type sprite
-			warning("STUB: Sprite::step() - FLY-type sprite");
+			seq = _ext->_seq;
+			// return to middle
+			p._x -= seq->_dx;
+			p._y -= seq->_dy;
+			p._z -= seq->_dz;
+			// generate motion
+			if (_vm->newRandom(10) < 5) {
+				if ((seq + 1)->_dx)
+					seq->_dx += _vm->newRandom(3) - 1;
+				if ((seq + 1)->_dy)
+					seq->_dy += _vm->newRandom(3) - 1;
+				if ((seq + 1)->_dz)
+					seq->_dz += _vm->newRandom(3) - 1;
+			}
+			if (seq->_dx < -(seq + 1)->_dx)
+				seq->_dx += 2;
+			if (seq->_dx >= (seq + 1)->_dx)
+				seq->_dx -= 2;
+			if (seq->_dy < -(seq + 1)->_dy)
+				seq->_dy += 2;
+			if (seq->_dy >= (seq + 1)->_dy)
+				seq->_dy -= 2;
+			if (seq->_dz < -(seq + 1)->_dz)
+				seq->_dz += 2;
+			if (seq->_dz >= (seq + 1)->_dz)
+				seq->_dz -= 2;
+			p._x += seq->_dx;
+			p._y += seq->_dy;
+			p._z += seq->_dz;
+			gotoxyz(p);
 		} else {
 			seq = _ext->_seq + _seqPtr;
 			if (seq->_dz == 127 && seq->_dx != 0) {


Commit: 6f2e4a76cc590652145daec12174136eb8f5d0a8
    https://github.com/scummvm/scummvm/commit/6f2e4a76cc590652145daec12174136eb8f5d0a8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-06-28T00:46:32+02:00

Commit Message:
CGE2: Add workaround for badly named VBM file in room 11

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 6c7e39a..93818c0 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -48,6 +48,9 @@ Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _v(nullptr), _b(nullptr), _m
 	if (!strcmp(fname, "04tal201")) {
 		strcpy(pat, "04tal202");
 		warning("Workaround for missing VBM: 04tal201");
+	} else if (!strcmp(fname, "11oqlist-")) {
+		strcpy(pat, "11oqlist");
+		warning("Workaround for wrong VBM name: 11oqlist-");
 	} else
 		strcpy(pat, fname);
 


Commit: 69c8871c3f6fda7baca65f6c389a35c58943f21e
    https://github.com/scummvm/scummvm/commit/69c8871c3f6fda7baca65f6c389a35c58943f21e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-28T19:53:05+02:00

Commit Message:
CGE2: Silence GCC warning in Hero::tick().

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index d1caf1f..dfc0e4b 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -301,6 +301,8 @@ void Hero::tick() {
 		if (_pos2D.x >= kScrWidth - 1 - d)
 			park();
 		break;
+	default:
+		break;
 	}
 	if (_flags._trim)
 		gotoxyz_(_pos2D);


Commit: f69ee470ed7d28d4dfd31b7339c7b4a160e52543
    https://github.com/scummvm/scummvm/commit/f69ee470ed7d28d4dfd31b7339c7b4a160e52543
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-28T21:38:21+02:00

Commit Message:
CGE2: Rework FXP::Joined().

This commit hopefully silence a great wall of GCC warnings.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 617e1a7..9d26bd8 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -55,13 +55,22 @@ namespace CGE2 {
 class FXP { // fixed point
 	uint16 f;
 	int16 i;
-	long& Joined() const { return *(long *)&f; }
+	long getJoined() const {
+		long ret = 0;
+		ret += f;
+		ret += i << 16;
+		return ret;
+	}
+	void setJoined(long joined) {
+		i = joined >> 16;
+		f = joined;
+	}
 public:
 	FXP (void): f(0), i(0) { }
 	FXP (int i0, int f0 = 0) : i(i0), f(0) { }
 	FXP& operator = (const int& x) { i = x; f = 0; return *this; }
-	FXP operator + (const FXP& x) const { FXP y; y.Joined() = Joined() + x.Joined(); return y; }
-	FXP operator - (const FXP& x) const { FXP y; y.Joined() = Joined() - x.Joined(); return y; }
+	FXP operator + (const FXP& x) const { FXP y; y.setJoined(getJoined() + x.getJoined()); return y; }
+	FXP operator - (const FXP& x) const { FXP y; y.setJoined(getJoined() - x.getJoined()); return y; }
 	FXP operator * (const FXP& x) const {
 		FXP y; long t;
 		y.i = i * x.i;
@@ -74,7 +83,7 @@ public:
 	FXP operator / (const FXP& x) const {
 		FXP y; bool sign = false;
 		if (!x.empty()) {
-			long j = Joined(), jx = x.Joined();
+			long j = getJoined(), jx = x.getJoined();
 			if (j < 0) {
 				j = -j;
 				sign ^= 1;
@@ -89,7 +98,7 @@ public:
 			y.f = unsigned((r << 4) / (jx >> 12));
 			//------------------
 			if (sign)
-				y.Joined() = -y.Joined();
+				y.setJoined(-y.getJoined());
 		}
 
 		return y;


Commit: 2f80cf6faf10e6e10728a19a72c414587b14cd26
    https://github.com/scummvm/scummvm/commit/2f80cf6faf10e6e10728a19a72c414587b14cd26
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-28T21:39:16+02:00

Commit Message:
CGE2: Fix formatting of FXP's operators.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 9d26bd8..6c68c8c 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -68,10 +68,10 @@ class FXP { // fixed point
 public:
 	FXP (void): f(0), i(0) { }
 	FXP (int i0, int f0 = 0) : i(i0), f(0) { }
-	FXP& operator = (const int& x) { i = x; f = 0; return *this; }
-	FXP operator + (const FXP& x) const { FXP y; y.setJoined(getJoined() + x.getJoined()); return y; }
-	FXP operator - (const FXP& x) const { FXP y; y.setJoined(getJoined() - x.getJoined()); return y; }
-	FXP operator * (const FXP& x) const {
+	FXP& operator=(const int& x) { i = x; f = 0; return *this; }
+	FXP operator+(const FXP& x) const { FXP y; y.setJoined(getJoined() + x.getJoined()); return y; }
+	FXP operator-(const FXP& x) const { FXP y; y.setJoined(getJoined() - x.getJoined()); return y; }
+	FXP operator*(const FXP& x) const {
 		FXP y; long t;
 		y.i = i * x.i;
 		t = ((long) f * x.f) >> 16;
@@ -80,7 +80,7 @@ public:
 		y.i += t >> 16;
 		return y;
 	}
-	FXP operator / (const FXP& x) const {
+	FXP operator/(const FXP& x) const {
 		FXP y; bool sign = false;
 		if (!x.empty()) {
 			long j = getJoined(), jx = x.getJoined();
@@ -104,14 +104,14 @@ public:
 		return y;
 	}
 	//int& operator = (int& a, const FXP& b) { return a = b.i; }
-	friend int& operator += (int& a, const FXP& b) { return a += b.i; }
-	friend int& operator -= (int& a, const FXP& b) { return a -= b.i; }
-	friend FXP& operator += (FXP& a, const int& b) { a.i += b; return a; }
-	friend FXP& operator -= (FXP& a, const int& b) { a.i -= b; return a; }
-	friend bool operator == (const FXP &a, const FXP &b) { return (a.i == b.i) && (a.f == b.f); }
-	friend bool operator != (const FXP &a, const FXP &b) { return (a.i != b.i) || (a.f != b.f); }
-	friend bool operator < (const FXP &a, const FXP &b) { return (a.i < b.i) || ((a.i == b.i) && (a.f < b.f)); }
-	friend bool operator > (const FXP &a, const FXP &b) { return (a.i > b.i) || ((a.i == b.i) && (a.f > b.f)); }
+	friend int& operator+=(int& a, const FXP& b) { return a += b.i; }
+	friend int& operator-=(int& a, const FXP& b) { return a -= b.i; }
+	friend FXP& operator+=(FXP& a, const int& b) { a.i += b; return a; }
+	friend FXP& operator-=(FXP& a, const int& b) { a.i -= b; return a; }
+	friend bool operator==(const FXP &a, const FXP &b) { return (a.i == b.i) && (a.f == b.f); }
+	friend bool operator!=(const FXP &a, const FXP &b) { return (a.i != b.i) || (a.f != b.f); }
+	friend bool operator<(const FXP &a, const FXP &b) { return (a.i < b.i) || ((a.i == b.i) && (a.f < b.f)); }
+	friend bool operator>(const FXP &a, const FXP &b) { return (a.i > b.i) || ((a.i == b.i) && (a.f > b.f)); }
 	int trunc(void) const { return i; }
 	int round(void) const { return i + (f > 0x7FFF); }
 	bool empty() const { return i == 0 && f == 0; }


Commit: 160212c8e3219b28968ad653a0d730223b338a38
    https://github.com/scummvm/scummvm/commit/160212c8e3219b28968ad653a0d730223b338a38
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-28T23:44:48+02:00

Commit Message:
CGE2: Add fallback detection for the currently WIP English translation.

Changed paths:
    engines/cge2/detection.cpp



diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index e417a13..cbe78da 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -45,15 +45,6 @@ static const ADGameDescription gameDescriptions[] = {
 		},
 		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
 	},
-	{
-		"sfinx", "Sfinx English Alfa v0.1",
-		{
-			{"vol.cat", 0, "41a61030468e33828f3531fd53ef0319", 129024},
-			{"vol.dat", 0, "978ebe56442c111d193fdb4d960cc58d", 34382498},	
-			AD_LISTEND
-		},
-		Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
-	},
 	AD_TABLE_END_MARKER
 };
 
@@ -73,6 +64,8 @@ public:
 
 	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
 	virtual bool hasFeature(MetaEngineFeature f) const;
+
+	const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
 };
 
 bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
@@ -86,6 +79,32 @@ bool CGE2MetaEngine::hasFeature(MetaEngineFeature f) const {
 	return false;
 }
 
+const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
+	static ADGameDescription desc;
+
+	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+		if (file->isDirectory()) {
+			continue;
+		}
+		if (file->getName().equalsIgnoreCase("lang.eng")) {
+			Common::File dataFile;
+			if (!dataFile.open(*file)) {
+				continue;
+			}
+			
+			desc.gameid = "sfinx";
+			desc.extra = "Sfinx English Alfa v0.1";
+			desc.language = Common::EN_ANY;
+			desc.platform = Common::kPlatformDOS;
+			desc.flags = ADGF_NO_FLAGS;
+			desc.guioptions = GUIO0();
+			
+			return (const ADGameDescription *)&desc;
+		}
+	}
+	return 0;
+}
+
 } // End of namespace CGE2
 
 #if PLUGIN_ENABLED_DYNAMIC(CGE2)


Commit: 38a59bee3e85f82672ce88befb2e428d243416db
    https://github.com/scummvm/scummvm/commit/38a59bee3e85f82672ce88befb2e428d243416db
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-29T20:36:54+02:00

Commit Message:
CGE2: Add skeleton for save/load system.

Also rename loadGame() to loadHeroes().

Changed paths:
  A engines/cge2/detection.h
  A engines/cge2/saveload.cpp
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/detection.cpp
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 6976a6f..1a9f48d 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -35,7 +35,6 @@
 #include "cge2/hero.h"
 #include "cge2/general.h"
 #include "cge2/spare.h"
-#include "cge2/events.h"
 #include "cge2/talk.h"
 #include "cge2/cge2_main.h"
 #include "cge2/map.h"
@@ -158,24 +157,9 @@ void CGE2Engine::deinit() {
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
-	return false;
-}
-
-bool CGE2Engine::canLoadGameStateCurrently() {
-	return false;
-}
-bool CGE2Engine::canSaveGameStateCurrently() {
-	return false;
-}
-
-Common::Error CGE2Engine::loadGameState(int slot) {
-	warning("STUB: CGE2Engine::loadGameState()");
-	return Common::kNoError;
-}
-
-Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
-	warning("STUB: CGE2Engine::saveGameState()");
-	return Common::kNoError;
+	return
+		(f == kSupportsLoadingDuringRuntime) ||
+		(f == kSupportsSavingDuringRuntime);
 }
 
 Common::Error CGE2Engine::run() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c569bf9..e3606b8 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -29,6 +29,8 @@
 #define CGE2_H
 
 #include "common/random.h"
+#include "common/savefile.h"
+#include "common/serializer.h"
 #include "engines/engine.h"
 #include "engines/advancedDetector.h"
 #include "common/system.h"
@@ -59,6 +61,7 @@ class System;
 class EventManager;
 class Font;
 class Map;
+struct SavegameHeader;
 
 #define kScrWidth         320
 #define kScrHeight        240
@@ -105,6 +108,10 @@ class Map;
 #define kQuitText         201
 #define kNoQuitText       202
 
+#define kSavegameVersion    1
+#define kSavegameStrSize   12
+#define kSavegameStr       "SCUMMVM_CGE2"
+
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
 };
@@ -119,22 +126,28 @@ class CGE2Engine : public Engine {
 private:
 	uint32 _lastFrame, _lastTick;
 	void tick();
+
+	Common::String generateSaveName(int slot);
+	void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
+	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
+	void syncHeader(Common::Serializer &s);
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
 	virtual bool hasFeature(EngineFeature f) const;
-	virtual bool canLoadGameStateCurrently();
 	virtual bool canSaveGameStateCurrently();
-	virtual Common::Error loadGameState(int slot);
+	virtual bool canLoadGameStateCurrently();
 	virtual Common::Error saveGameState(int slot, const Common::String &desc);
+	virtual Common::Error loadGameState(int slot);
 	virtual Common::Error run();
 
+	static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
 	bool showTitle(const char *name);
 	void cge2_main();
 	char *mergeExt(char *buf, const char *name, const char *ext);
 	void inf(const char *text, ColorBank col = kCBInf);
 	void movie(const char *ext);
 	void runGame();
-	void loadGame();
+	void loadHeroes();
 	void loadScript(const char *fname);
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 75b9aff..77ad718 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -726,12 +726,12 @@ void CGE2Engine::loadUser() {
 	warning("STUB: CGE2Engine::loadUser()");
 	// Missing loading from file. TODO: Implement it with the saving/loading!
 	loadScript("CGE.INI");
-	loadGame();
+	loadHeroes();
 	loadPos();
 }
 
-void CGE2Engine::loadGame() {
-	warning("STUB: CGE2Engine::loadGame()");
+void CGE2Engine::loadHeroes() { // Original name: loadGame()
+	warning("STUB: CGE2Engine::loadHeroes()");
 
 	// load sprites & pocket
 	
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index cbe78da..599934b 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -25,49 +25,10 @@
  * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
  */
 
-#include "cge2/cge2.h"
-#include "engines/advancedDetector.h"
+#include "cge2/detection.h"
 
 namespace CGE2 {
 
-static const PlainGameDescriptor CGE2Games[] = {
-	{ "sfinx", "Sfinx" },
-	{ 0, 0 }
-};
-
-static const ADGameDescription gameDescriptions[] = {
-	{
-		"sfinx", "Sfinx Freeware",
-		{
-			{ "vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024 },
-			{ "vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844 },
-			AD_LISTEND
-		},
-		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
-	},
-	AD_TABLE_END_MARKER
-};
-
-class CGE2MetaEngine : public AdvancedMetaEngine {
-public:
-	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games) {
-		_singleid = "sfinx";
-	}
-
-	virtual const char *getName() const {
-		return "CGE2";
-	}
-
-	virtual const char *getOriginalCopyright() const {
-		return "Sfinx (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon";
-	}
-
-	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-	virtual bool hasFeature(MetaEngineFeature f) const;
-
-	const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
-};
-
 bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
 	if (desc) {
 		*engine = new CGE2::CGE2Engine(syst, desc);
@@ -76,7 +37,11 @@ bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
 }
 
 bool CGE2MetaEngine::hasFeature(MetaEngineFeature f) const {
-	return false;
+	return
+		(f == kSupportsDeleteSave) ||
+		(f == kSavesSupportMetaInfo) ||
+		(f == kSavesSupportThumbnail) ||
+		(f == kSavesSupportCreationDate);
 }
 
 const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
@@ -108,7 +73,7 @@ const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles,
 } // End of namespace CGE2
 
 #if PLUGIN_ENABLED_DYNAMIC(CGE2)
-	REGISTER_PLUGIN_DYNAMIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
+REGISTER_PLUGIN_DYNAMIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
 #else
-	REGISTER_PLUGIN_STATIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
+REGISTER_PLUGIN_STATIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
 #endif
diff --git a/engines/cge2/detection.h b/engines/cge2/detection.h
new file mode 100644
index 0000000..5569807
--- /dev/null
+++ b/engines/cge2/detection.h
@@ -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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#ifndef CGE2_DETECTION_H
+#define CGE2_DETECTION_H
+
+#include "cge2/cge2.h"
+#include "engines/advancedDetector.h"
+
+namespace CGE2 {
+
+static const PlainGameDescriptor CGE2Games[] = {
+	{ "sfinx", "Sfinx" },
+	{ 0, 0 }
+};
+
+static const ADGameDescription gameDescriptions[] = {
+	{
+		"sfinx", "Sfinx Freeware",
+		{
+			{ "vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024 },
+			{ "vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844 },
+			AD_LISTEND
+		},
+		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+	},
+	AD_TABLE_END_MARKER
+};
+
+class CGE2MetaEngine : public AdvancedMetaEngine {
+public:
+	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games) {
+		_singleid = "sfinx";
+	}
+
+	virtual const char *getName() const {
+		return "CGE2";
+	}
+
+	virtual const char *getOriginalCopyright() const {
+		return "Sfinx (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon";
+	}
+
+	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual bool hasFeature(MetaEngineFeature f) const;
+	virtual int getMaximumSaveSlot() const;
+	virtual SaveStateList listSaves(const char *target) const;
+	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+	virtual void removeSaveState(const char *target, int slot) const;
+
+	const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
+};
+
+} // End of namespace CGE2
+
+#endif // CGE2_DETECTION_H
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 9a6e0cb..cb2b51e 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -15,7 +15,8 @@ MODULE_OBJS = \
 	talk.o \
 	events.o \
 	map.o \
-	vmenu.o
+	vmenu.o \
+	saveload.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
new file mode 100644
index 0000000..ac059e5
--- /dev/null
+++ b/engines/cge2/saveload.cpp
@@ -0,0 +1,197 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/detection.h"
+#include "common/config-manager.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "graphics/thumbnail.h"
+#include "graphics/surface.h"
+#include "graphics/palette.h"
+#include "graphics/scaler.h"
+#include "cge2/events.h"
+#include "cge2/snail.h"
+#include "cge2/hero.h"
+
+namespace CGE2 {
+
+struct SavegameHeader {
+	uint8 version;
+	Common::String saveName;
+	Graphics::Surface *thumbnail;
+	int saveYear, saveMonth, saveDay;
+	int saveHour, saveMinutes;
+};
+
+int CGE2MetaEngine::getMaximumSaveSlot() const {
+	return 99;
+}
+
+SaveStateList CGE2MetaEngine::listSaves(const char *target) const {
+	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+	Common::StringArray filenames;
+	Common::String pattern = target;
+	pattern += ".???";
+
+	filenames = saveFileMan->listSavefiles(pattern);
+	sort(filenames.begin(), filenames.end());   // Sort (hopefully ensuring we are sorted numerically..)
+
+	SaveStateList saveList;
+	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
+		// Obtain the last 3 digits of the filename, since they correspond to the save slot
+		int slotNum = atoi(filename->c_str() + filename->size() - 3);
+
+		if (slotNum >= 0 && slotNum <= 99) {
+
+			Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
+			if (file) {
+				CGE2::SavegameHeader header;
+
+				// Check to see if it's a ScummVM savegame or not
+				char buffer[kSavegameStrSize + 1];
+				file->read(buffer, kSavegameStrSize + 1);
+
+				if (!strncmp(buffer, kSavegameStr, kSavegameStrSize + 1)) {
+					// Valid savegame
+					if (CGE2::CGE2Engine::readSavegameHeader(file, header)) {
+						saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
+						if (header.thumbnail) {
+							header.thumbnail->free();
+							delete header.thumbnail;
+						}
+					}
+				} else {
+					// Must be an original format savegame
+					saveList.push_back(SaveStateDescriptor(slotNum, "Unknown"));
+				}
+
+				delete file;
+			}
+		}
+	}
+
+	return saveList;
+}
+
+SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s.%03d", target, slot);
+	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
+
+	if (f) {
+		CGE2::SavegameHeader header;
+
+		// Check to see if it's a ScummVM savegame or not
+		char buffer[kSavegameStrSize + 1];
+		f->read(buffer, kSavegameStrSize + 1);
+
+		bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
+			CGE2::CGE2Engine::readSavegameHeader(f, header);
+		delete f;
+
+		if (!hasHeader) {
+			// Original savegame perhaps?
+			SaveStateDescriptor desc(slot, "Unknown");
+			return desc;
+		} else {
+			// Create the return descriptor
+			SaveStateDescriptor desc(slot, header.saveName);
+			desc.setThumbnail(header.thumbnail);
+			desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
+			desc.setSaveTime(header.saveHour, header.saveMinutes);
+
+			// Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
+			// we prevent it from being deleted or overwritten by accident.
+			desc.setDeletableFlag(slot != 0);
+			desc.setWriteProtectedFlag(slot == 0);
+
+			return desc;
+		}
+	}
+
+	return SaveStateDescriptor();
+}
+
+bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
+	header.thumbnail = nullptr;
+
+	// Get the savegame version
+	header.version = in->readByte();
+	if (header.version > kSavegameVersion)
+		return false;
+
+	// Read in the string
+	header.saveName.clear();
+	char ch;
+	while ((ch = (char)in->readByte()) != '\0')
+		header.saveName += ch;
+
+	// Get the thumbnail
+	header.thumbnail = Graphics::loadThumbnail(*in);
+	if (!header.thumbnail)
+		return false;
+
+	// Read in save date/time
+	header.saveYear = in->readSint16LE();
+	header.saveMonth = in->readSint16LE();
+	header.saveDay = in->readSint16LE();
+	header.saveHour = in->readSint16LE();
+	header.saveMinutes = in->readSint16LE();
+
+	return true;
+}
+
+void CGE2MetaEngine::removeSaveState(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s.%03d", target, slot);
+	g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
+bool CGE2Engine::canSaveGameStateCurrently() {
+	bool isHeroVisible = false;
+	for (int i = 0; i < 2; i++) {
+		isHeroVisible = !_heroTab[i]->_ptr->_flags._hide;
+		if (isHeroVisible)
+			break;
+	}
+	return (_startupMode == 0) && _mouse->_active &&
+		_commandHandler->idle() && isHeroVisible;
+}
+
+bool CGE2Engine::canLoadGameStateCurrently() {
+	return (_startupMode == 0) && _mouse->_active;
+}
+
+Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
+	warning("STUB: CGE2Engine::saveGameState()");
+	return Common::kNoError;
+}
+
+Common::Error CGE2Engine::loadGameState(int slot) {
+	warning("STUB: CGE2Engine::loadGameState()");
+	return Common::kNoError;
+}
+
+} // End of namespace CGE2


Commit: b6d4281917d10effdd3890f8d1f740558da409c4
    https://github.com/scummvm/scummvm/commit/b6d4281917d10effdd3890f8d1f740558da409c4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-29T21:38:46+02:00

Commit Message:
CGE2: Call loadPos() from loadHero() instead of loadUser().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 77ad718..2e70125 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -727,7 +727,6 @@ void CGE2Engine::loadUser() {
 	// Missing loading from file. TODO: Implement it with the saving/loading!
 	loadScript("CGE.INI");
 	loadHeroes();
-	loadPos();
 }
 
 void CGE2Engine::loadHeroes() { // Original name: loadGame()
@@ -770,6 +769,8 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 
 	//--- start!
 	switchHero(_sex);
+
+	loadPos();
 }
 
 void CGE2Engine::loadPos() {


Commit: ade740de1098930d5b9827b98c844d300ded04b8
    https://github.com/scummvm/scummvm/commit/ade740de1098930d5b9827b98c844d300ded04b8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-29T22:52:03+02:00

Commit Message:
CGE2: Implement saving.

Changed paths:
    engines/cge2/saveload.cpp
    engines/cge2/spare.cpp
    engines/cge2/spare.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index ac059e5..971b044 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -36,9 +36,13 @@
 #include "cge2/events.h"
 #include "cge2/snail.h"
 #include "cge2/hero.h"
+#include "cge2/text.h"
 
 namespace CGE2 {
 
+#define kSavegameCheckSum (1997 + _now + _music + kWorldHeight)
+#define kBadSVG           99
+
 struct SavegameHeader {
 	uint8 version;
 	Common::String saveName;
@@ -123,11 +127,6 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
 			desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
 			desc.setSaveTime(header.saveHour, header.saveMinutes);
 
-			// Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
-			// we prevent it from being deleted or overwritten by accident.
-			desc.setDeletableFlag(slot != 0);
-			desc.setWriteProtectedFlag(slot == 0);
-
 			return desc;
 		}
 	}
@@ -185,10 +184,122 @@ bool CGE2Engine::canLoadGameStateCurrently() {
 }
 
 Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
-	warning("STUB: CGE2Engine::saveGameState()");
+	// Set up the serializer
+	Common::String slotName = generateSaveName(slot);
+	Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(slotName);
+
+	// Write out the ScummVM savegame header
+	SavegameHeader header;
+	header.saveName = desc;
+	header.version = kSavegameVersion;
+	writeSavegameHeader(saveFile, header);
+
+	// Write out the data of the savegame
+	syncGame(NULL, saveFile);
+
+	// Finish writing out game data
+	saveFile->finalize();
+	delete saveFile;
+
 	return Common::kNoError;
 }
 
+/**
+* Support method that generates a savegame name
+* @param slot		Slot number
+*/
+Common::String CGE2Engine::generateSaveName(int slot) {
+	return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header) {
+	// Write out a savegame header
+	out->write(kSavegameStr, kSavegameStrSize + 1);
+
+	out->writeByte(kSavegameVersion);
+
+	// Write savegame name
+	out->write(header.saveName.c_str(), header.saveName.size() + 1);
+
+	// Get the active palette
+	uint8 thumbPalette[256 * 3];
+	g_system->getPaletteManager()->grabPalette(thumbPalette, 0, 256);
+
+	// Create a thumbnail and save it
+	Graphics::Surface *thumb = new Graphics::Surface();
+	Graphics::Surface *s = _vga->_page[0];
+	::createThumbnail(thumb, (const byte *)s->getPixels(), kScrWidth, kScrHeight, thumbPalette);
+	Graphics::saveThumbnail(*out, *thumb);
+	thumb->free();
+	delete thumb;
+
+	// Write out the save date/time
+	TimeDate td;
+	g_system->getTimeAndDate(td);
+	out->writeSint16LE(td.tm_year + 1900);
+	out->writeSint16LE(td.tm_mon + 1);
+	out->writeSint16LE(td.tm_mday);
+	out->writeSint16LE(td.tm_hour);
+	out->writeSint16LE(td.tm_min);
+}
+
+void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream) {
+	Common::Serializer s(readStream, writeStream);
+
+	// Synchronise header data
+	syncHeader(s);
+
+	if (s.isSaving()) {
+		for (int i = 0; i < kSceneMax; i++)
+			_eyeTab[i]->sync(s);
+
+		_spare->sync(s);
+
+		// The references of the items in the heroes pockets:
+		for (int i = 0; i < 2; i++) {
+			for (int j = 0; j < kPocketMax; j++) {
+				Sprite *spr = _heroTab[i]->_pocket[j];
+				int ref = (spr) ? spr->_ref : -1;
+				s.syncAsSint16LE(ref);
+			}
+		}
+		
+		for (int i = 0; i < kMaxPoint; i++)
+			_point[i]->sync(s);
+	} else {
+		// Loading game
+	}
+}
+
+void CGE2Engine::syncHeader(Common::Serializer &s) {
+	s.syncAsUint16LE(_now);
+	s.syncAsUint16LE(_sex);
+	s.syncAsUint16LE(_music);
+	s.syncAsUint16LE(_waitSeq);
+	s.syncAsUint16LE(_waitRef);
+	s.syncAsUint16LE(_sayCap);
+	s.syncAsUint16LE(_sayVox);
+	for (int i = 0; i < 4; i++)
+		s.syncAsUint16LE(_flag[i]);
+
+	if (s.isLoading()) {
+		// Reset scene values
+		//initSceneValues();
+	}
+
+	if (s.isSaving()) {
+		// Write checksum
+		int checksum = kSavegameCheckSum;
+		s.syncAsUint16LE(checksum);
+	} else {
+		// Read checksum and validate it
+		uint16 checksum = 0;
+		s.syncAsUint16LE(checksum);
+		if (checksum != kSavegameCheckSum)
+			error("%s", _text->getText(kBadSVG));
+	}
+}
+
 Common::Error CGE2Engine::loadGameState(int slot) {
 	warning("STUB: CGE2Engine::loadGameState()");
 	return Common::kNoError;
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 8382310..76f00651 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -29,8 +29,9 @@
 
 namespace CGE2 {
 
-void Spare::synchronize() {
-	warning("STUB: Spare::Load");
+void Spare::sync(Common::Serializer &s) {
+	for (int i = 0; i < _container.size(); i++)
+		_container[i]->sync(s);
 }
 
 void Spare::clear() {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 77bdb33..7dc6ce6 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -46,7 +46,7 @@ public:
 	void dispose(Sprite *spr);
 	void dispose(int ref);
 	void dispose();
-	void synchronize();
+	void sync(Common::Serializer &s);
 	uint16 count() { return _container.size(); }
 	void clear();
 };
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 29ee5c8..a181621 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -39,6 +39,25 @@
 
 namespace CGE2 {
 
+void V3D::sync(Common::Serializer &s) {
+	int pos = 0;
+	if (s.isLoading()) {
+		s.syncAsSint16LE(pos);
+		_x = FXP(pos);
+		s.syncAsSint16LE(pos);
+		_y = FXP(pos);
+		s.syncAsSint16LE(pos);
+		_z = FXP(pos);
+	} else {
+		pos = _x.trunc();
+		s.syncAsUint16LE(pos);
+		pos = _y.trunc();
+		s.syncAsUint16LE(pos);
+		pos = _z.trunc();
+		s.syncAsByte(pos);
+	}
+}
+
 Seq *getConstantSeq(bool seqFlag) {
 	const Seq seq1[] = { { 0, 0, 0, 0, 0, 0 } };
 	const Seq seq2[] = { { 0, 1, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, 0 } };
@@ -675,10 +694,6 @@ BitmapPtr Sprite::ghost() {
 }
 
 void Sprite::sync(Common::Serializer &s) {
-	uint16 unused = 0;
-
-	s.syncAsUint16LE(unused);
-	s.syncAsUint16LE(unused);	// _ext
 	s.syncAsUint16LE(_ref);
 	s.syncAsByte(_scene);
 
@@ -723,31 +738,24 @@ void Sprite::sync(Common::Serializer &s) {
 		s.syncAsUint16LE(flags);
 	}
 
-	int pos = 0;
-	if (s.isLoading()) {
-		s.syncAsSint16LE(pos);
-		_pos3D._x = FXP(pos, 0);
-		s.syncAsSint16LE(pos);
-		_pos3D._y = pos;
-		s.syncAsSint16LE(pos);
-		_pos3D._z = pos;
-	} else {
-		pos = _pos3D._x.trunc();
-		s.syncAsUint16LE(pos);
-		pos = _pos3D._y.trunc();
-		s.syncAsUint16LE(pos);
-		pos = _pos3D._z.trunc();
-		s.syncAsByte(pos);
-	}
+	s.syncAsSint16LE(_pos2D.x);
+	s.syncAsSint16LE(_pos2D.y);
+
+	_pos3D.sync(s);
+
+	s.syncAsSint16LE(_siz.x);
+	s.syncAsSint16LE(_siz.y);
 
 	s.syncAsUint16LE(_time);
+	for (int i = 0; i < kActions; i++){
+		s.syncAsSint16LE(_actionCtrl->_ptr);
+		s.syncAsSint16LE(_actionCtrl->_cnt);
+	}
 	s.syncAsSint16LE(_seqPtr);
+	s.syncAsSint16LE(_seqCnt);
 	s.syncAsUint16LE(_shpCnt);
 	s.syncBytes((byte *)&_file[0], 9);
 	_file[8] = '\0';
-
-	s.syncAsUint16LE(unused);	// _prev
-	s.syncAsUint16LE(unused);	// _next
 }
 
 Queue::Queue(bool show) : _head(NULL), _tail(NULL) {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 6c68c8c..c42b7a7 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -132,6 +132,7 @@ public:
 	bool operator!=(const V3D &p) const { return _x != p._x || _y != p._y || _z != p._z; }
 	V3D& operator+=(const V3D &x) { return *this = *this + x; }
 	V3D& operator-=(const V3D &x) { return *this = *this - x; }
+	void sync(Common::Serializer &s);
 };
 
 class V2D : public Common::Point {


Commit: 7810df976b2c2df324092add3f06b0841e1b0dca
    https://github.com/scummvm/scummvm/commit/7810df976b2c2df324092add3f06b0841e1b0dca
Author: uruk (koppirnyo at gmail.com)
Date: 2014-06-30T01:10:17+02:00

Commit Message:
CGE2: Rework Hero::expand() so it won't modify Text's content.

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index dfc0e4b..7e6c384 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -40,7 +40,10 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 	if (_ext)
 		return this;
 
-	char *text = _vm->_text->getText(_ref + 100);
+	Common::String str(_vm->_text->getText(_ref + 100));
+	char text[kLineMax + 1];
+	strcpy(text, str.c_str());
+
 	char fname[kMaxPath];
 	_vm->mergeExt(fname, _file, kSprExt);
 	_ext = new SprExt(_vm);


Commit: b48c94a5415ece41319d5aa814e4ad16cf1ff4a8
    https://github.com/scummvm/scummvm/commit/b48c94a5415ece41319d5aa814e4ad16cf1ff4a8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-02T01:33:37+02:00

Commit Message:
CGE2: Fix GCC warning

Changed paths:
    engines/cge2/spare.cpp



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 76f00651..d202be9 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -30,7 +30,7 @@
 namespace CGE2 {
 
 void Spare::sync(Common::Serializer &s) {
-	for (int i = 0; i < _container.size(); i++)
+	for (uint i = 0; i < _container.size(); i++)
 		_container[i]->sync(s);
 }
 


Commit: 1305bc8aa8b46459dfea08ad52309a57dbda64d8
    https://github.com/scummvm/scummvm/commit/1305bc8aa8b46459dfea08ad52309a57dbda64d8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T12:58:45+02:00

Commit Message:
CGE2: Add, implement and use saveHeroPos().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index e3606b8..af16311 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -155,6 +155,7 @@ public:
 	void sceneDown();
 	void closePocket();
 	void switchScene(int scene);
+	void saveHeroPos();
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2e70125..dead21d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -505,14 +505,9 @@ void CGE2Engine::switchScene(int scene) {
 	*/
 
 	_req = scene;
-	for (int i = 0; i < 2; i++) {
-		Hero *h = _heroTab[i]->_ptr;
-		if (h->_scene == _now) {
-			delete _heroTab[i]->_posTab[_now];
-			V2D *temp = new V2D(this, h->_pos3D._x.trunc(), h->_pos3D._z.trunc());
-			_heroTab[i]->_posTab[_now] = temp;
-		}
-	}
+
+	saveHeroPos();
+	
 	*(_eyeTab[_now]) = *_eye;
 	if (scene < 0)
 		_commandHandler->addCallback(kCmdExec, -1, 0, kQGame); // quit game
@@ -530,6 +525,17 @@ void CGE2Engine::switchScene(int scene) {
 	}
 }
 
+void CGE2Engine::saveHeroPos() {
+	for (int i = 0; i < 2; i++) {
+		Hero *h = _heroTab[i]->_ptr;
+		if (h->_scene == _now) {
+			delete _heroTab[i]->_posTab[_now];
+			V2D *temp = new V2D(this, h->_pos3D._x.trunc(), h->_pos3D._z.trunc());
+			_heroTab[i]->_posTab[_now] = temp;
+		}
+	}
+}
+
 void CGE2Engine::showBak(int ref) {
 	Sprite *spr = _spare->take(ref);
 	if (spr != nullptr) {


Commit: b9dc93c451d891704d828e3c384aae015a63ff40
    https://github.com/scummvm/scummvm/commit/b9dc93c451d891704d828e3c384aae015a63ff40
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T12:58:46+02:00

Commit Message:
CGE2: Heavily rework memory management of Sprites.

Hopefully it will solve a bunch of memory leak problems.
Now Spare is a central container, which stores pointers to every Sprite currently used by the engine.
Because of that, there's no more need for Queue's clear().
In case of snKill(), it's just a safeguard, since it's only used by the engine to "kill" the speech bubbles, but we will check Spare anyway, so it's the safest this way.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp
    engines/cge2/spare.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 1a9f48d..e6df241 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -126,6 +126,7 @@ void CGE2Engine::init() {
 }
 
 void CGE2Engine::deinit() {
+	delete _spare;
 	delete _resman;
 	delete _vga;
 	delete _fx;
@@ -138,7 +139,6 @@ void CGE2Engine::deinit() {
 		delete _eyeTab[i];
 	}
 	delete _eye;
-	delete _spare;
 	delete _sprite;
 	delete _commandHandler;
 	delete _commandHandlerTurbo;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index dead21d..5a4b2c1 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -280,8 +280,6 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 			_sprite = h;
 		}
 	} else {
-		if (_sprite)
-			delete _sprite;
 		_sprite = new Sprite(this);
 		if (_sprite)
 			_sprite->gotoxyz(pos);
@@ -414,7 +412,6 @@ void CGE2Engine::movie(const char *ext) {
 
 		_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 		_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
-		_vga->_showQ->clear();
 		_spare->clear();
 		_now = now;
 	}
@@ -725,7 +722,6 @@ void CGE2Engine::runGame() {
 	_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 	_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
 	_mouse->off();
-	_vga->_showQ->clear();
 }
 
 void CGE2Engine::loadUser() {
@@ -749,7 +745,6 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 		h = new Hero(this);
 		*(Sprite*)h = *s;
 		delete s;
-		s = nullptr;
 		h->expand();
 		_spare->update(h);
 	}
@@ -757,6 +752,7 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 	s = _spare->take(152);
 	_vga->_showQ->insert(s);
 	_heroTab[0]->_face = s;
+	_spare->update(s);
 
 	// initialize Wacek/Vincent
 	s = _spare->take(141);
@@ -764,7 +760,6 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 		h = new Hero(this);
 		*(Sprite*)h = *s;
 		delete s;
-		s = nullptr;
 		h->expand();
 		_spare->update(h);
 	}
@@ -772,6 +767,7 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 	s = _spare->take(151);
 	_vga->_showQ->insert(s);
 	_heroTab[1]->_face = s;
+	_spare->update(s);
 
 	//--- start!
 	switchHero(_sex);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 9b77fe3..609196c 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -344,9 +344,10 @@ void CGE2Engine::snKill(Sprite *spr) {
 		hide1(spr);
 		_vga->_showQ->remove(spr);
 		_eventManager->clearEvent(spr);
-		if (spr->_flags._kill)
+		if (spr->_flags._kill) {
+			_spare->take(spr->_ref);
 			delete spr;
-		else {
+		} else {
 			spr->setScene(-1);
 			_spare->dispose(spr);
 		}
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index d202be9..dde37d4 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -35,6 +35,9 @@ void Spare::sync(Common::Serializer &s) {
 }
 
 void Spare::clear() {
+	for (int i = 0; i < _container.size(); i++)
+		delete _container[i];
+
 	_container.clear();
 }
 
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index a181621..3ce690e 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -761,20 +761,6 @@ void Sprite::sync(Common::Serializer &s) {
 Queue::Queue(bool show) : _head(NULL), _tail(NULL) {
 }
 
-Queue::~Queue() {
-	clear();
-}
-
-void Queue::clear() {
-	while (_head) {
-		Sprite *s = remove(_head);
-		if (s->_flags._kill) {
-			delete s;
-			s = nullptr;
-		}
-	}
-}
-
 void Queue::append(Sprite *spr) {
 	if (spr->_flags._back)
 		spr->backShow();
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index c42b7a7..ce914ce 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -284,7 +284,6 @@ class Queue {
 	Sprite *_tail;
 public:
 	Queue(bool show);
-	~Queue();
 
 	void append(Sprite *spr);
 	void insert(Sprite *spr, Sprite *nxt);
@@ -298,7 +297,6 @@ public:
 	}
 	Sprite *locate(int ref);
 	bool locate(Sprite *spr);
-	void clear();
 };
 
 class Vga {


Commit: aeaac02332a8faa32a7f6c534309b71432dd3a2b
    https://github.com/scummvm/scummvm/commit/aeaac02332a8faa32a7f6c534309b71432dd3a2b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T12:58:47+02:00

Commit Message:
CGE2: Silence warning.

Changed paths:
    engines/cge2/spare.cpp



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index dde37d4..5db4772 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -36,6 +36,7 @@ void Spare::sync(Common::Serializer &s) {
 
 void Spare::clear() {
 	for (int i = 0; i < _container.size(); i++)
+	for (uint i = 0; i < _container.size(); i++)
 		delete _container[i];
 
 	_container.clear();


Commit: f155546ecb03e0a308cdb6b2308ab01c992e71ce
    https://github.com/scummvm/scummvm/commit/f155546ecb03e0a308cdb6b2308ab01c992e71ce
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T13:01:28+02:00

Commit Message:
CGE2: Partially working save/load system.

There's a mayor bug which blocks the toolbar from interaction after loading. To be investigated during the upcoming days.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp
    engines/cge2/spare.cpp
    engines/cge2/spare.h
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index af16311..aade31f 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -131,6 +131,8 @@ private:
 	void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
 	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
 	void syncHeader(Common::Serializer &s);
+	bool loadGame(int slotNumber);
+	void resetGame();
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
 	virtual bool hasFeature(EngineFeature f) const;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 5a4b2c1..0713405 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -729,6 +729,7 @@ void CGE2Engine::loadUser() {
 	// Missing loading from file. TODO: Implement it with the saving/loading!
 	loadScript("CGE.INI");
 	loadHeroes();
+	loadPos();
 }
 
 void CGE2Engine::loadHeroes() { // Original name: loadGame()
@@ -771,8 +772,6 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 
 	//--- start!
 	switchHero(_sex);
-
-	loadPos();
 }
 
 void CGE2Engine::loadPos() {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 971b044..8d0237e 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -37,6 +37,7 @@
 #include "cge2/snail.h"
 #include "cge2/hero.h"
 #include "cge2/text.h"
+#include "cge2/sound.h"
 
 namespace CGE2 {
 
@@ -195,7 +196,10 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 	writeSavegameHeader(saveFile, header);
 
 	// Write out the data of the savegame
-	syncGame(NULL, saveFile);
+	saveHeroPos();
+	sceneDown();
+	syncGame(nullptr, saveFile);
+	sceneUp(_now);
 
 	// Finish writing out game data
 	saveFile->finalize();
@@ -249,13 +253,11 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 	// Synchronise header data
 	syncHeader(s);
 
-	if (s.isSaving()) {
-		for (int i = 0; i < kSceneMax; i++)
-			_eyeTab[i]->sync(s);
-
-		_spare->sync(s);
+	// Synchronise _spare and mingled with it, the sprites of the heroes'
+	_spare->sync(s, _heroTab);
 
-		// The references of the items in the heroes pockets:
+	if (s.isSaving()) {
+		// Save the references of the items in the heroes pockets:
 		for (int i = 0; i < 2; i++) {
 			for (int j = 0; j < kPocketMax; j++) {
 				Sprite *spr = _heroTab[i]->_pocket[j];
@@ -263,11 +265,23 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 				s.syncAsSint16LE(ref);
 			}
 		}
-		
-		for (int i = 0; i < kMaxPoint; i++)
-			_point[i]->sync(s);
 	} else {
-		// Loading game
+		// Load items to the pockets
+		for (int i = 0; i < 2; i++) {
+			for (int j = 0; j < kPocketMax; j++) {
+				int ref = 0;
+				s.syncAsSint16LE(ref);
+				_heroTab[i]->_pocket[j] = _spare->locate(ref);
+			}
+		}
+	}
+
+	// Heroes' _posTabs
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kSceneMax; j++) {
+			s.syncAsSint16LE(_heroTab[i]->_posTab[j]->x);
+			s.syncAsSint16LE(_heroTab[i]->_posTab[j]->y);
+		}
 	}
 }
 
@@ -282,11 +296,6 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 	for (int i = 0; i < 4; i++)
 		s.syncAsUint16LE(_flag[i]);
 
-	if (s.isLoading()) {
-		// Reset scene values
-		//initSceneValues();
-	}
-
 	if (s.isSaving()) {
 		// Write checksum
 		int checksum = kSavegameCheckSum;
@@ -301,8 +310,75 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 }
 
 Common::Error CGE2Engine::loadGameState(int slot) {
-	warning("STUB: CGE2Engine::loadGameState()");
+	// Clear current game activity
+	sceneDown();
+	resetGame();
+	// If music is playing, kill it.
+	if (_music)
+		_midiPlayer->killMidi();
+	
+	if (!loadGame(slot))
+		return Common::kReadingFailed;
+
+	loadHeroes();
+
+	sceneUp(_now);
+
+	_busyPtr = _vga->_showQ->locate(kBusyRef);
+
+	_vol[0] = _vga->_showQ->locate(kDvolRef);
+	_vol[1] = _vga->_showQ->locate(kMvolRef);
+
 	return Common::kNoError;
 }
 
+void CGE2Engine::resetGame() {
+	_busyPtr = nullptr;
+	busy(false);
+	_spare->clear();
+	_vga->_showQ->clear();
+	_commandHandler->reset();
+}
+
+bool CGE2Engine::loadGame(int slotNumber) {
+	Common::MemoryReadStream *readStream;
+
+	// Open up the savegame file
+	Common::String slotName = generateSaveName(slotNumber);
+	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName);
+
+	// Read the data into a data buffer
+	int size = saveFile->size();
+	byte *dataBuffer = (byte *)malloc(size);
+	saveFile->read(dataBuffer, size);
+	readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES);
+	delete saveFile;
+	
+	// Check to see if it's a ScummVM savegame or not
+	char buffer[kSavegameStrSize + 1];
+	readStream->read(buffer, kSavegameStrSize + 1);
+
+	if (strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) != 0) {
+		delete readStream;
+		return false;
+	} else {
+		SavegameHeader saveHeader;
+
+		if (!readSavegameHeader(readStream, saveHeader)) {
+			delete readStream;
+			return false;
+		}
+
+		// Delete the thumbnail
+		saveHeader.thumbnail->free();
+		delete saveHeader.thumbnail;
+	}
+
+	// Get in the savegame
+	syncGame(readStream, nullptr);
+
+	delete readStream;
+	return true;
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 5db4772..4bc4a5f 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -29,13 +29,30 @@
 
 namespace CGE2 {
 
-void Spare::sync(Common::Serializer &s) {
-	for (uint i = 0; i < _container.size(); i++)
-		_container[i]->sync(s);
+void Spare::sync(Common::Serializer &s, HeroTab *heroTab[2]) {
+	if (s.isSaving()) {
+		int size = 0;
+		for (uint i = 0; i < _container.size(); i++)
+			if (_container[i]->_ref >= 141)
+				size++;
+		s.syncAsSint16LE(size);
+
+		for (uint i = 0; i < _container.size(); i++)
+			if (_container[i]->_ref >= 141)
+				_container[i]->sync(s);
+	} else {
+		int size;
+		s.syncAsSint16LE(size);
+
+		for (int i = 0; i < size; i++) {
+			Sprite *sprite = new Sprite(_vm);
+			sprite->sync(s);
+			store(sprite);
+		}
+	}
 }
 
 void Spare::clear() {
-	for (int i = 0; i < _container.size(); i++)
 	for (uint i = 0; i < _container.size(); i++)
 		delete _container[i];
 
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 7dc6ce6..d34ca48 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -46,7 +46,7 @@ public:
 	void dispose(Sprite *spr);
 	void dispose(int ref);
 	void dispose();
-	void sync(Common::Serializer &s);
+	void sync(Common::Serializer &s, HeroTab *heroTab[2]);
 	uint16 count() { return _container.size(); }
 	void clear();
 };
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 3ce690e..f40c84e 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -40,22 +40,14 @@
 namespace CGE2 {
 
 void V3D::sync(Common::Serializer &s) {
-	int pos = 0;
-	if (s.isLoading()) {
-		s.syncAsSint16LE(pos);
-		_x = FXP(pos);
-		s.syncAsSint16LE(pos);
-		_y = FXP(pos);
-		s.syncAsSint16LE(pos);
-		_z = FXP(pos);
-	} else {
-		pos = _x.trunc();
-		s.syncAsUint16LE(pos);
-		pos = _y.trunc();
-		s.syncAsUint16LE(pos);
-		pos = _z.trunc();
-		s.syncAsByte(pos);
-	}
+	_x.sync(s);
+	_y.sync(s);
+	_z.sync(s);
+}
+
+void FXP::sync(Common::Serializer &s) {
+	s.syncAsUint16LE(f);
+	s.syncAsSint16LE(i);
 }
 
 Seq *getConstantSeq(bool seqFlag) {
@@ -748,8 +740,8 @@ void Sprite::sync(Common::Serializer &s) {
 
 	s.syncAsUint16LE(_time);
 	for (int i = 0; i < kActions; i++){
-		s.syncAsSint16LE(_actionCtrl->_ptr);
-		s.syncAsSint16LE(_actionCtrl->_cnt);
+		s.syncAsByte(_actionCtrl[i]._ptr);
+		s.syncAsByte(_actionCtrl[i]._cnt);
 	}
 	s.syncAsSint16LE(_seqPtr);
 	s.syncAsSint16LE(_seqCnt);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index ce914ce..7dd7933 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -115,6 +115,7 @@ public:
 	int trunc(void) const { return i; }
 	int round(void) const { return i + (f > 0x7FFF); }
 	bool empty() const { return i == 0 && f == 0; }
+	void sync(Common::Serializer &s);
 };
 
 // From CGETYPE.H:
@@ -274,6 +275,7 @@ public:
 	virtual void tick();
 	virtual void setScene(int c);
 	void clrHide() { if (_ext) _ext->_b0 = NULL; }
+
 	void sync(Common::Serializer &s);
 
 	static void (*notify) ();
@@ -297,6 +299,7 @@ public:
 	}
 	Sprite *locate(int ref);
 	bool locate(Sprite *spr);
+	void clear() { _head = _tail = nullptr; }
 };
 
 class Vga {


Commit: 927be46c8738ea474476e94ed9868be3c4c0dcf6
    https://github.com/scummvm/scummvm/commit/927be46c8738ea474476e94ed9868be3c4c0dcf6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T13:01:28+02:00

Commit Message:
CGE2: Remove unnecessary parameter from Spare::sync().

Changed paths:
    engines/cge2/saveload.cpp
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 8d0237e..cb1e981 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -253,8 +253,8 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 	// Synchronise header data
 	syncHeader(s);
 
-	// Synchronise _spare and mingled with it, the sprites of the heroes'
-	_spare->sync(s, _heroTab);
+	// Synchronise _spare
+	_spare->sync(s);
 
 	if (s.isSaving()) {
 		// Save the references of the items in the heroes pockets:
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 4bc4a5f..a0c3f74 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -29,7 +29,7 @@
 
 namespace CGE2 {
 
-void Spare::sync(Common::Serializer &s, HeroTab *heroTab[2]) {
+void Spare::sync(Common::Serializer &s) {
 	if (s.isSaving()) {
 		int size = 0;
 		for (uint i = 0; i < _container.size(); i++)
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index d34ca48..7dc6ce6 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -46,7 +46,7 @@ public:
 	void dispose(Sprite *spr);
 	void dispose(int ref);
 	void dispose();
-	void sync(Common::Serializer &s, HeroTab *heroTab[2]);
+	void sync(Common::Serializer &s);
 	uint16 count() { return _container.size(); }
 	void clear();
 };


Commit: ddf4f4598de95ea8b631d9e77c3da4178d61c1d2
    https://github.com/scummvm/scummvm/commit/ddf4f4598de95ea8b631d9e77c3da4178d61c1d2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T13:01:29+02:00

Commit Message:
CGE2: Rename saveHeroPos() to storeHeroPos().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index aade31f..dddf0c3 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -157,7 +157,7 @@ public:
 	void sceneDown();
 	void closePocket();
 	void switchScene(int scene);
-	void saveHeroPos();
+	void storeHeroPos();
 	void showBak(int ref);
 	void loadTab();
 	int newRandom(int range);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 0713405..804294d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -503,7 +503,7 @@ void CGE2Engine::switchScene(int scene) {
 
 	_req = scene;
 
-	saveHeroPos();
+	storeHeroPos();
 	
 	*(_eyeTab[_now]) = *_eye;
 	if (scene < 0)
@@ -522,7 +522,7 @@ void CGE2Engine::switchScene(int scene) {
 	}
 }
 
-void CGE2Engine::saveHeroPos() {
+void CGE2Engine::storeHeroPos() {
 	for (int i = 0; i < 2; i++) {
 		Hero *h = _heroTab[i]->_ptr;
 		if (h->_scene == _now) {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index cb1e981..f6cbbf9 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -196,7 +196,7 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 	writeSavegameHeader(saveFile, header);
 
 	// Write out the data of the savegame
-	saveHeroPos();
+	storeHeroPos();
 	sceneDown();
 	syncGame(nullptr, saveFile);
 	sceneUp(_now);


Commit: dbbafb5d8939453bba847dc49b7a87b534020d48
    https://github.com/scummvm/scummvm/commit/dbbafb5d8939453bba847dc49b7a87b534020d48
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T13:01:29+02:00

Commit Message:
CGE2: Rename and heavily rework Bitmap::forceExt().

Since the extension is always ".VBM" in case of Bitmaps, there's no need to pass it as an argument.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 93818c0..396610a 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -53,8 +53,8 @@ Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _v(nullptr), _b(nullptr), _m
 		warning("Workaround for wrong VBM name: 11oqlist-");
 	} else
 		strcpy(pat, fname);
-
-	forceExt(pat, pat, ".VBM");
+	
+	strcpy(pat, addExt(pat).c_str());
 
 	if (_vm->_resman->exist(pat)) {
 		EncryptedStream file(_vm, pat);
@@ -162,14 +162,12 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 	return *this;
 }
 
-char *Bitmap::forceExt(char *buf, const char *name, const char *ext) {
-	strcpy(buf, name);
-	char *dot = strrchr(buf, '.');
-	if (dot)
-		*dot = '\0';
-	strcat(buf, ext);
-
-	return buf;
+Common::String Bitmap::addExt(const char *name) {
+	Common::String fname;
+	fname = Common::String::format("%s.VBM", name);
+	if (fname.size() >= kMaxPath)
+		error("Bitmap's filename is too long %s", name);
+	return fname;
 }
 
 BitmapPtr Bitmap::code(uint8 *map) {
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index e7a4637..3d71635 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -58,7 +58,7 @@ struct HideDesc {
 class Bitmap {
 	CGE2Engine *_vm;
 
-	char *forceExt(char *buf, const char *name, const char *ext);
+	static Common::String addExt(const char *name);
 	bool loadVBM(EncryptedStream *f);
 public:
 	static uint8 *kSLDesign;


Commit: a3071a00f98b4e322c28281e026ac85a751db071
    https://github.com/scummvm/scummvm/commit/a3071a00f98b4e322c28281e026ac85a751db071
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T13:26:27+02:00

Commit Message:
CGE2: Replace addExt() wit setExtension().

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 396610a..4d1fb6a 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -53,8 +53,8 @@ Bitmap::Bitmap(CGE2Engine *vm, const char *fname) : _v(nullptr), _b(nullptr), _m
 		warning("Workaround for wrong VBM name: 11oqlist-");
 	} else
 		strcpy(pat, fname);
-	
-	strcpy(pat, addExt(pat).c_str());
+
+	strcpy(pat, setExtension(pat, ".VBM").c_str());
 
 	if (_vm->_resman->exist(pat)) {
 		EncryptedStream file(_vm, pat);
@@ -162,12 +162,16 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 	return *this;
 }
 
-Common::String Bitmap::addExt(const char *name) {
-	Common::String fname;
-	fname = Common::String::format("%s.VBM", name);
-	if (fname.size() >= kMaxPath)
-		error("Bitmap's filename is too long %s", name);
-	return fname;
+// Blatant rip from hopkins engine where it's ripped from gob engine. Hi DrMcCoy, hi Strangerke! ;>
+Common::String Bitmap::setExtension(const Common::String &str, const Common::String &ext) {
+	if (str.empty())
+		return str;
+
+	const char *dot = strrchr(str.c_str(), '.');
+	if (dot)
+		return Common::String(str.c_str(), dot - str.c_str()) + ext;
+
+	return str + ext;
 }
 
 BitmapPtr Bitmap::code(uint8 *map) {


Commit: 07fa4831426142a6ec0bede7af979a0628e53ea4
    https://github.com/scummvm/scummvm/commit/07fa4831426142a6ec0bede7af979a0628e53ea4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T18:04:40+02:00

Commit Message:
CGE2: Fix broken compilation by previous commit.

Changed paths:
    engines/cge2/bitmap.h



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 3d71635..159631e 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -58,7 +58,7 @@ struct HideDesc {
 class Bitmap {
 	CGE2Engine *_vm;
 
-	static Common::String addExt(const char *name);
+	Common::String setExtension(const Common::String &str, const Common::String &ext);
 	bool loadVBM(EncryptedStream *f);
 public:
 	static uint8 *kSLDesign;


Commit: 8b8216bf2cfbaa016aa20a15eb7ac9069d8f9f21
    https://github.com/scummvm/scummvm/commit/8b8216bf2cfbaa016aa20a15eb7ac9069d8f9f21
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T18:39:03+02:00

Commit Message:
CGE2: Fully implement the save/load system.

Now the toolbar is working too after loading.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index dddf0c3..f126da5 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -149,6 +149,7 @@ public:
 	void inf(const char *text, ColorBank col = kCBInf);
 	void movie(const char *ext);
 	void runGame();
+	void initToolbar();
 	void loadHeroes();
 	void loadScript(const char *fname);
 	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 804294d..935a3c9 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -672,40 +672,11 @@ void CGE2Engine::runGame() {
 	if (_quitFlag)
 		return;
 
-	selectPocket(-1);
-
 	loadUser();
 
-	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, _music, nullptr);
-	if (!_music)
-		_midiPlayer->killMidi();
-
-	checkSaySwitch();
-		
-	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
-	_infoLine->setText(nullptr);
-	_vga->_showQ->insert(_infoLine);
+	initToolbar();
 
 	sceneUp(_now);
-	_startupMode = 0;
-	_mouse->center();
-	_mouse->off();
-	_mouse->on();
-
-	_keyboard->setClient(_sys);
-	_commandHandler->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
-
-	_busyPtr = _vga->_showQ->locate(kBusyRef);
-
-	_vol[0] = _vga->_showQ->locate(kDvolRef);
-	_vol[1] = _vga->_showQ->locate(kMvolRef);
-
-	// these sprites are loaded with SeqPtr==0 (why?!)
-	if (_vol[0])
-		_vol[0]->step((/*(int)SNDDrvInfo.VOL4.DL * */ _vol[0]->_seqCnt + _vol[0]->_seqCnt / 2) >> 4);
-	if (_vol[1])
-		_vol[1]->step((/*(int)SNDDrvInfo.VOL4.ML * */ _vol[1]->_seqCnt + _vol[1]->_seqCnt / 2) >> 4);
-	// TODO: Recheck these! ^
 
 	// main loop
 	while (!_endGame && !_quitFlag) {
@@ -795,6 +766,40 @@ void CGE2Engine::loadPos() {
 		error("Missing file: CGE.HXY");
 }
 
+void CGE2Engine::initToolbar() {
+	selectPocket(-1);
+
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, _music, nullptr);
+	if (!_music)
+		_midiPlayer->killMidi();
+
+	checkSaySwitch();
+
+	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
+	_infoLine->setText(nullptr);
+	_vga->_showQ->insert(_infoLine);
+
+	_startupMode = 0;
+	_mouse->center();
+	_mouse->off();
+	_mouse->on();
+
+	_keyboard->setClient(_sys);
+	_commandHandler->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
+
+	_busyPtr = _vga->_showQ->locate(kBusyRef);
+
+	_vol[0] = _vga->_showQ->locate(kDvolRef);
+	_vol[1] = _vga->_showQ->locate(kMvolRef);
+
+	// these sprites are loaded with SeqPtr==0 (why?!)
+	if (_vol[0])
+		_vol[0]->step((/*(int)SNDDrvInfo.VOL4.DL * */ _vol[0]->_seqCnt + _vol[0]->_seqCnt / 2) >> 4);
+	if (_vol[1])
+		_vol[1]->step((/*(int)SNDDrvInfo.VOL4.ML * */ _vol[1]->_seqCnt + _vol[1]->_seqCnt / 2) >> 4);
+	// TODO: Recheck these! ^
+}
+
 void CGE2Engine::releasePocket(Sprite *spr) {
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < kPocketMax; j++) {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index f6cbbf9..0ea957f 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -38,6 +38,7 @@
 #include "cge2/hero.h"
 #include "cge2/text.h"
 #include "cge2/sound.h"
+#include "cge2/cge2_main.h"
 
 namespace CGE2 {
 
@@ -260,8 +261,7 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 		// Save the references of the items in the heroes pockets:
 		for (int i = 0; i < 2; i++) {
 			for (int j = 0; j < kPocketMax; j++) {
-				Sprite *spr = _heroTab[i]->_pocket[j];
-				int ref = (spr) ? spr->_ref : -1;
+				int ref = _heroTab[i]->_downPocketId[j];
 				s.syncAsSint16LE(ref);
 			}
 		}
@@ -271,7 +271,7 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 			for (int j = 0; j < kPocketMax; j++) {
 				int ref = 0;
 				s.syncAsSint16LE(ref);
-				_heroTab[i]->_pocket[j] = _spare->locate(ref);
+				_heroTab[i]->_downPocketId[j] = ref;
 			}
 		}
 	}
@@ -310,25 +310,13 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 }
 
 Common::Error CGE2Engine::loadGameState(int slot) {
-	// Clear current game activity
 	sceneDown();
 	resetGame();
-	// If music is playing, kill it.
-	if (_music)
-		_midiPlayer->killMidi();
-	
 	if (!loadGame(slot))
 		return Common::kReadingFailed;
-
+	initToolbar();
 	loadHeroes();
-
 	sceneUp(_now);
-
-	_busyPtr = _vga->_showQ->locate(kBusyRef);
-
-	_vol[0] = _vga->_showQ->locate(kDvolRef);
-	_vol[1] = _vga->_showQ->locate(kMvolRef);
-
 	return Common::kNoError;
 }
 
@@ -338,6 +326,9 @@ void CGE2Engine::resetGame() {
 	_spare->clear();
 	_vga->_showQ->clear();
 	_commandHandler->reset();
+	loadScript("CGE.INI");
+	delete _infoLine;
+	_infoLine = new InfoLine(this, kInfoW);
 }
 
 bool CGE2Engine::loadGame(int slotNumber) {
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index a0c3f74..93c8a26 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -47,7 +47,7 @@ void Spare::sync(Common::Serializer &s) {
 		for (int i = 0; i < size; i++) {
 			Sprite *sprite = new Sprite(_vm);
 			sprite->sync(s);
-			store(sprite);
+			update(sprite);
 		}
 	}
 }


Commit: 31bba2e38c0bfad3b990ccf9884c6f8f578a19ee
    https://github.com/scummvm/scummvm/commit/31bba2e38c0bfad3b990ccf9884c6f8f578a19ee
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T18:59:33+02:00

Commit Message:
CGE2: Remove unnecessary warning and debug info from showTitle().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 935a3c9..77df792 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -908,8 +908,6 @@ bool CGE2Engine::showTitle(const char *name) {
 
 	Sprite D(this, LB, 1);
 	D._flags._kill = true;
-	strcpy(D._file, "hatter");
-	warning("STUB: Sprite::showTitle() - Flags changed compared to CGE1's Sprite type.");
 	D.gotoxyz(kScrWidth >> 1, -(kPanHeight >> 1));
 	_vga->sunset();
 


Commit: e15f40978a6904dec7a50cfefbb2a05c454c6c74
    https://github.com/scummvm/scummvm/commit/e15f40978a6904dec7a50cfefbb2a05c454c6c74
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-04T19:07:38+02:00

Commit Message:
CGE2: Implement loading from the Launcher.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/detection.cpp
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index e6df241..aa87f99 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -26,7 +26,7 @@
  */
 
 #include "engines/util.h"
-
+#include "common/config-manager.h"
 #include "cge2/cge2.h"
 #include "cge2/bitmap.h"
 #include "cge2/vga13h.h"
@@ -123,6 +123,8 @@ void CGE2Engine::init() {
 	_sys = new System(this);
 	_eventManager = new EventManager(this);
 	_map = new Map(this);
+
+	_startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
 }
 
 void CGE2Engine::deinit() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index f126da5..a2cd131 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -284,6 +284,7 @@ public:
 	int _req;
 	NotifyFunctionType _midiNotify;
 	NotifyFunctionType _spriteNotify;
+	int _startGameSlot;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 77df792..b9787b0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -696,11 +696,13 @@ void CGE2Engine::runGame() {
 }
 
 void CGE2Engine::loadUser() {
-	warning("STUB: CGE2Engine::loadUser()");
-	// Missing loading from file. TODO: Implement it with the saving/loading!
-	loadScript("CGE.INI");
-	loadHeroes();
 	loadPos();
+	if (_startGameSlot != -1)
+		loadGame(_startGameSlot);
+	else {
+		loadScript("CGE.INI");
+		loadHeroes();
+	}
 }
 
 void CGE2Engine::loadHeroes() { // Original name: loadGame()
@@ -847,7 +849,11 @@ void CGE2Engine::cge2_main() {
 
 	loadTab();
 
-	_mode++;
+	if (_startGameSlot != -1) {
+		// Starting up a savegame from the launcher
+		_mode++;
+		runGame();
+	}
 
 	if (showTitle("WELCOME")) {
 #if 0
@@ -900,6 +906,8 @@ int CGE2Engine::newRandom(int range) {
 bool CGE2Engine::showTitle(const char *name) {
 	if (_quitFlag)
 		return false;
+	
+	_mode++;
 
 	_bitmapPalette = _vga->_sysPal;
 	BitmapPtr LB = new Bitmap[1];
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 599934b..6d4f633 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -41,7 +41,9 @@ bool CGE2MetaEngine::hasFeature(MetaEngineFeature f) const {
 		(f == kSupportsDeleteSave) ||
 		(f == kSavesSupportMetaInfo) ||
 		(f == kSavesSupportThumbnail) ||
-		(f == kSavesSupportCreationDate);
+		(f == kSavesSupportCreationDate) ||
+		(f == kSupportsListSaves) ||
+		(f == kSupportsLoadingDuringStartup);
 }
 
 const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 0ea957f..3890e74 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -311,11 +311,8 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 
 Common::Error CGE2Engine::loadGameState(int slot) {
 	sceneDown();
-	resetGame();
 	if (!loadGame(slot))
 		return Common::kReadingFailed;
-	initToolbar();
-	loadHeroes();
 	sceneUp(_now);
 	return Common::kNoError;
 }
@@ -365,10 +362,16 @@ bool CGE2Engine::loadGame(int slotNumber) {
 		delete saveHeader.thumbnail;
 	}
 
+	resetGame();
+
 	// Get in the savegame
 	syncGame(readStream, nullptr);
 
 	delete readStream;
+
+	initToolbar();
+	loadHeroes();
+
 	return true;
 }
 


Commit: 21a4c44bea2e413444716994671f63e8fe6aa373
    https://github.com/scummvm/scummvm/commit/21a4c44bea2e413444716994671f63e8fe6aa373
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-07-04T22:05:02-04:00

Commit Message:
CGE2: Add extra clipping to Bitmap::hide

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index f40c84e..805c1e7 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1131,12 +1131,15 @@ void Bitmap::show(V2D pos) {
 void Bitmap::hide(V2D pos) {
 	xLatPos(pos);
 	
-	for (int yp = pos.y; yp < pos.y + _h; yp++) {
+	int w = MIN<int>(_w, kScrWidth - pos.x);
+	int h = MIN<int>(_h, kScrHeight - pos.y);
+
+	for (int yp = pos.y; yp < pos.y + h; yp++) {
 		if (yp >= 0 && yp < kScrHeight) {
 			const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(pos.x, yp);
 			byte *destP = (byte *)_vm->_vga->_page[1]->getBasePtr(pos.x, yp);
 
-			Common::copy(srcP, srcP + _w, destP);
+			Common::copy(srcP, srcP + w, destP);
 		}
 	}
 }


Commit: c5855b4293522f365329593e41a16e68b1424967
    https://github.com/scummvm/scummvm/commit/c5855b4293522f365329593e41a16e68b1424967
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-07T10:41:43+02:00

Commit Message:
CGE2: Add workaround for the missing dialogs in room 21 (concert)

Changed paths:
    engines/cge2/text.cpp
    engines/cge2/text.h



diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 24fc8e5..ecc5521 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -38,16 +38,19 @@ Text::Text(CGE2Engine *vm, const char *fname) : _vm(vm) {
 	_vm->mergeExt(_fileName, fname, kSayExt);
 	if (!_vm->_resman->exist(_fileName))
 		error("No talk (%s)", _fileName);
-	int16 txtCount = count() + 1;
-	if (!txtCount)
+	_txtCount = count();
+	if (_txtCount == -1)
 		error("Unable to read dialog file %s", _fileName);
 
-	_cache = new Handler[txtCount];
-	for (_size = 0; _size < txtCount; _size++) {
+	_txtCount += 2;
+	_cache = new Handler[_txtCount];
+	for (_size = 0; _size < _txtCount; _size++) {
 		_cache[_size]._ref = 0;
 		_cache[_size]._text = nullptr;
 	}
 	load();
+	_cache[_txtCount - 1]._ref = 0;
+	_cache[_txtCount - 1]._text = "";
 }
 
 Text::~Text() {
@@ -127,8 +130,8 @@ char *Text::getText(int ref) {
 	if (i < _size)
 		return _cache[i]._text;
 
-	warning("getText: Unable to find ref %d", ref);
-	return NULL;
+	warning("getText: Unable to find ref %d:%d", ref / 256, ref % 256);
+	return _cache[_txtCount - 1]._text;
 }
 
 void Text::say(const char *text, Sprite *spr) {
diff --git a/engines/cge2/text.h b/engines/cge2/text.h
index bca7743..88ed501 100644
--- a/engines/cge2/text.h
+++ b/engines/cge2/text.h
@@ -48,6 +48,7 @@ class Text {
 		char *_text;
 	} *_cache;
 	int _size;
+	int16 _txtCount;
 	char _fileName[kPathMax];
 	void load();
 	int16 count();


Commit: c7aa91019b08c52976356031cf2059333ab6fd23
    https://github.com/scummvm/scummvm/commit/c7aa91019b08c52976356031cf2059333ab6fd23
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-07T21:42:45+02:00

Commit Message:
CGE2: Replace NULL with nullptr everywhere.

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/events.cpp
    engines/cge2/fileio.cpp
    engines/cge2/hero.cpp
    engines/cge2/snail.cpp
    engines/cge2/sound.cpp
    engines/cge2/talk.cpp
    engines/cge2/text.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 4d1fb6a..fd2f6a4 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -84,7 +84,7 @@ Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
 	uint16 psiz = _h * lsiz;                         // - last gape, but + plane trailer
 	uint8 *v = new uint8[4 * psiz + _h * sizeof(*_b)];// the same for 4 planes
 	                                                // + room for wash table
-	assert(v != NULL);
+	assert(v != nullptr);
 
 	WRITE_LE_UINT16(v, (kBmpCPY | dsiz));                 // data chunk hader
 	memset(v + 2, fill, dsiz);                      // data bytes
@@ -176,7 +176,7 @@ Common::String Bitmap::setExtension(const Common::String &str, const Common::Str
 
 BitmapPtr Bitmap::code(uint8 *map) {
 	if (!map)
-		return NULL;
+		return nullptr;
 
 	uint16 cnt;
 
@@ -265,7 +265,7 @@ BitmapPtr Bitmap::code(uint8 *map) {
 
 		uint16 sizV = (uint16)(im - 2 - _v);
 		_v = new uint8[sizV + _h * sizeof(*_b)];
-		assert(_v != NULL);
+		assert(_v != nullptr);
 
 		_b = (HideDesc *)(_v + sizV);
 	}
@@ -383,7 +383,7 @@ bool Bitmap::loadVBM(EncryptedStream *f) {
 				f->seek(f->pos() + kPalSize);
 		}
 	}
-	if ((_v = new uint8[n]) == NULL)
+	if ((_v = new uint8[n]) == nullptr)
 		return false;
 
 	if (!f->err())
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index b9787b0..be83bed 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -52,7 +52,7 @@ void System::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 			// The sound is uselessly annoying and noisy, so it has been removed
 			_vm->killText();
 			if (_vm->_startupMode == 1) {
-				_vm->_commandHandler->addCommand(kCmdClear, -1, 0, NULL);
+				_vm->_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 				return;
 			}
 		}
@@ -335,43 +335,43 @@ void CGE2Engine::loadScript(const char *fname) {
 		V3D P;
 
 		// sprite ident number
-		if ((p = token(tmpStr)) == NULL)
+		if ((p = token(tmpStr)) == nullptr)
 			break;
 		int SpI = number(p);
 
 		// sprite file name
 		char *SpN;
-		if ((SpN = token(nullptr)) == NULL)
+		if ((SpN = token(nullptr)) == nullptr)
 			break;
 
 		// sprite scene
-		if ((p = token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == nullptr)
 			break;
 		int SpA = number(p);
 
 		// sprite column
-		if ((p = token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == nullptr)
 			break;
 		P._x = number(p);
 
 		// sprite row
-		if ((p = token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == nullptr)
 			break;
 		P._y = number(p);
 
 		// sprite Z pos
-		if ((p = token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == nullptr)
 			break;
 		P._z = number(p);
 
 		// sprite life
-		if ((p = token(nullptr)) == NULL)
+		if ((p = token(nullptr)) == nullptr)
 			break;
 		bool BkG = number(p) == 0;
 
 		ok = true; // no break: OK
 
-		_sprite = NULL;
+		_sprite = nullptr;
 		loadSprite(SpN, SpI, SpA, P);
 		if (_sprite) {
 			if (BkG)
@@ -538,7 +538,7 @@ void CGE2Engine::showBak(int ref) {
 	if (spr != nullptr) {
 		_bitmapPalette = _vga->_sysPal;
 		spr->expand();
-		_bitmapPalette = NULL;
+		_bitmapPalette = nullptr;
 		spr->show(2);
 		_vga->copyPage(1, 2);
 		_spare->dispose(spr);
@@ -860,7 +860,7 @@ void CGE2Engine::cge2_main() {
 		if (_mode == 1)
 			movie(kIntroExt);
 #endif
-		if (_text->getText(255) != NULL) {
+		if (_text->getText(255) != nullptr) {
 			runGame();
 			_startupMode = 2;
 		} else
@@ -892,8 +892,8 @@ void CGE2Engine::setEye(const char *s) {
 	char tempStr[kLineMax];
 	strcpy(tempStr, s);
 	_eye->_x = atoi(token(tempStr));
-	_eye->_y = atoi(token(NULL));
-	_eye->_z = atoi(token(NULL));
+	_eye->_y = atoi(token(nullptr));
+	_eye->_z = atoi(token(nullptr));
 }
 
 int CGE2Engine::newRandom(int range) {
@@ -967,7 +967,7 @@ void CGE2Engine::killText() {
 		return;
 
 	_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, _talk);
-	_talk = NULL;
+	_talk = nullptr;
 }
 
 void CGE2Engine::switchHero(int sex) {
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 0c163a5..c56f005 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -39,7 +39,7 @@ namespace CGE2 {
 
 /*----------------- KEYBOARD interface -----------------*/
 
-Keyboard::Keyboard(CGE2Engine *vm) : _client(NULL), _vm(vm) {
+Keyboard::Keyboard(CGE2Engine *vm) : _client(nullptr), _vm(vm) {
 	warning("STUB: Keyboard::Keyboard() - Recheck the whole implementation!!!");
 }
 
@@ -62,13 +62,13 @@ void Keyboard::newKeyboard(Common::Event &event) {
 
 /*----------------- MOUSE interface -----------------*/
 
-Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(NULL), _hold(NULL), _hx(0), _point(_vm), _vm(vm) {
-	_hold = NULL;
+Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(nullptr), _hold(nullptr), _hx(0), _point(_vm), _vm(vm) {
+	_hold = nullptr;
 	_hx = 0;
 	_hy = 0;
 	_exist = true;
 	_buttons = 0;
-	_busy = NULL;
+	_busy = nullptr;
 	_active = false;
 	_flags._kill = false;
 	
diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index cc07ef6..257e977 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -75,7 +75,7 @@ ResourceManager::ResourceManager() {
 		_buff[i]._page = new BtPage;
 		_buff[i]._pageNo = kBtValNone;
 		_buff[i]._index = -1;
-		assert(_buff[i]._page != NULL);
+		assert(_buff[i]._page != nullptr);
 	}
 }
 
@@ -160,7 +160,7 @@ BtKeypack *ResourceManager::find(const char *key) {
 			return &pg->_leaf[i];
 		}
 	}
-	return NULL;
+	return nullptr;
 }
 
 bool ResourceManager::exist(const char *name) {
@@ -272,7 +272,7 @@ const char *EncryptedStream::kIdTab[] = {
 	"[near]", "[mtake]", "[ftake]", "[phase]", "[seq]",
 	"Name", "Type", "Front", "East",
 	"Portable", "Transparent",
-	NULL
+	nullptr
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 7e6c384..4b50ccc 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -127,10 +127,10 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 						if (_actionCtrl[section]._cnt) {
 							CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
 							c->_commandType = CommandType(id);
-							if ((p = _vm->token(nullptr)) == NULL)
+							if ((p = _vm->token(nullptr)) == nullptr)
 								error("Unexpected end of file! %s", fname);
 							c->_ref = _vm->number(p);
-							if ((p = _vm->token(nullptr)) == NULL)
+							if ((p = _vm->token(nullptr)) == nullptr)
 								error("Unexpected end of file! %s", fname);
 							c->_val = _vm->number(p);
 							c->_spritePtr = nullptr;
@@ -141,7 +141,7 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 						s->_now = atoi(p);
 						if (s->_now > maxnow)
 							maxnow = s->_now;
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							break;
 						s->_next = _vm->number(p);
 						switch (s->_next) {
@@ -154,16 +154,16 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 						}
 						if (s->_next > maxnxt)
 							maxnxt = s->_next;
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							error("Unexpected end of file! %s", fname);
 						s->_dx = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							error("Unexpected end of file! %s", fname);
 						s->_dy = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							error("Unexpected end of file! %s", fname);
 						s->_dz = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							error("Unexpected end of file! %s", fname);
 						s->_dly = _vm->number(p);
 						break;
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 609196c..62dfd99 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -54,7 +54,7 @@ const char *CommandHandler::_commandText[] = {
 	"RMNEAR", "RMMTAKE", "RMFTAKE",
 	"SETREF", "BACKPT",
 	"WALKTO", "REACH", "COVER", "UNCOVER",
-	NULL };
+	nullptr };
 
 CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo)
 	: _turbo(turbo), _textDelay(false), _timerExpiry(0), _talkEnable(true),
@@ -424,7 +424,7 @@ void CGE2Engine::snSend(Sprite *spr, int val) {
 				((Hero*)spr)->setCurrent();
 			}
 			_taken = false;
-			_bitmapPalette = NULL;
+			_bitmapPalette = nullptr;
 		}
 	}
 }
@@ -792,7 +792,7 @@ void CommandHandler::addCallback(CommandType com, int ref, int val, CallbackType
 	headCmd->_commandType = com;
 	headCmd->_ref = ref;
 	headCmd->_val = val;
-	headCmd->_spritePtr = NULL;
+	headCmd->_spritePtr = nullptr;
 	headCmd->_cbType = cbType;
 	if (headCmd->_commandType == kCmdClear) {
 		_tail = _head;
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index 652907b..51764b7 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -46,7 +46,7 @@ DataCk::~DataCk() {
 }
 
 Sound::Sound(CGE2Engine *vm) : _vm(vm) {
-	_audioStream = NULL;
+	_audioStream = nullptr;
 	_soundRepeatCount = 1;
 	open();
 }
@@ -108,10 +108,10 @@ void Sound::stop() {
 void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
 	if (_vm->_mixer->isSoundHandleActive(_soundHandle))
 		_vm->_mixer->stopHandle(_soundHandle);
-	_audioStream = NULL;
+	_audioStream = nullptr;
 }
 
-Fx::Fx(CGE2Engine *vm, int size) : _current(NULL), _vm(vm) {
+Fx::Fx(CGE2Engine *vm, int size) : _current(nullptr), _vm(vm) {
 }
 
 Fx::~Fx() {
@@ -157,7 +157,7 @@ DataCk *Fx::loadWave(EncryptedStream *file) {
 }
 
 MusicPlayer::MusicPlayer(CGE2Engine *vm) : _vm(vm) {
-	_data = NULL;
+	_data = nullptr;
 	_isGM = false;
 
 	MidiPlayer::createDriver();
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index ddd98ac..eda8123 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -39,7 +39,7 @@ Font::Font(CGE2Engine *vm) : _vm(vm) {
 	_pos = new uint16[kPosSize];
 	_widthArr = new uint8[kWidSize];
 
-	assert((_map != NULL) && (_pos != NULL) && (_widthArr != NULL));
+	assert((_map != nullptr) && (_pos != nullptr) && (_widthArr != nullptr));
 	load();
 }
 
@@ -87,12 +87,12 @@ void Font::load() {
 		
 		char *token;
 
-		if ((token = _vm->token(tmpStr)) == NULL)
+		if ((token = _vm->token(tmpStr)) == nullptr)
 			error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
 		_colorSet[n][0] = _vm->number(token);
 
 		for (int i = 1; i < 4; i++) {
-			if ((token = _vm->token(nullptr)) == NULL)
+			if ((token = _vm->token(nullptr)) == nullptr)
 				error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
 			_colorSet[n][i] = _vm->number(token);
 		}
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index ecc5521..5826f6e 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -72,7 +72,7 @@ int16 Text::count() {
 		char *s;
 		assert(line.size() <= 513);
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-		if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
+		if ((s = strtok(tmpStr, " =,;/\t\n")) == nullptr)
 			continue;
 		if (!Common::isDigit(*s))
 			continue;
@@ -104,7 +104,7 @@ void Text::load() {
 		int n = line.size();
 		char *s;
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-		if ((s = strtok(tmpStr, " =,;/\t\n")) == NULL)
+		if ((s = strtok(tmpStr, " =,;/\t\n")) == nullptr)
 			continue;
 		if (!Common::isDigit(*s))
 			continue;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 805c1e7..340f9c0 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -83,16 +83,16 @@ Seq Sprite::_stdSeq8[] =
 
 SprExt::SprExt(CGE2Engine *vm)
 	: _p0(vm, 0, 0), _p1(vm, 0, 0),
-     _b0(NULL), _b1(NULL), _shpList(NULL),
-	 _location(0), _seq(NULL), _name(NULL) {
+     _b0(nullptr), _b1(nullptr), _shpList(nullptr),
+	 _location(0), _seq(nullptr), _name(nullptr) {
 	for (int i = 0; i < kActions; i++)
 		_actions[i] = nullptr;
 }
 
 Sprite::Sprite(CGE2Engine *vm)
 	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
-      _next(NULL), _prev(NULL), _time(0),
-	  _ext(NULL), _ref(-1), _scene(0), _vm(vm),
+      _next(nullptr), _prev(nullptr), _time(0),
+	  _ext(nullptr), _ref(-1), _scene(0), _vm(vm),
 	  _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
@@ -102,8 +102,8 @@ Sprite::Sprite(CGE2Engine *vm)
 
 Sprite::Sprite(CGE2Engine *vm, BitmapPtr shpP, int cnt)
 	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
-     _next(NULL), _prev(NULL), _time(0),
-     _ext(NULL), _ref(-1), _scene(0), _vm(vm),
+     _next(nullptr), _prev(nullptr), _time(0),
+     _ext(nullptr), _ref(-1), _scene(0), _vm(vm),
      _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
@@ -123,7 +123,7 @@ Sprite::~Sprite() {
 BitmapPtr Sprite::getShp() {
 	SprExt *e = _ext;
 	if (!e || !e->_seq)
-		return NULL;
+		return nullptr;
 
 	int i = e->_seq[_seqPtr]._now;
 	if (i >= _shpCnt)
@@ -183,7 +183,7 @@ void Sprite::setName(char *newName) {
 	}
 	if (newName) {
 		_ext->_name = new char[strlen(newName) + 1];
-		assert(_ext->_name != NULL);
+		assert(_ext->_name != nullptr);
 		strcpy(_ext->_name, newName);
 	}
 }
@@ -251,7 +251,7 @@ int Sprite::labVal(Action snq, int lab) {
 
 CommandHandler::Command *Sprite::snList(Action type) {
 	SprExt *e = _ext;
-	return (e) ? e->_actions[type] : NULL;
+	return (e) ? e->_actions[type] : nullptr;
 }
 
 Sprite *Sprite::expand() {
@@ -262,7 +262,7 @@ Sprite *Sprite::expand() {
 		(_vm->*_vm->_spriteNotify)();
 
 	_ext = new SprExt(_vm);
-	assert(_ext != NULL);
+	assert(_ext != nullptr);
 
 	if (!*_file)
 		return this;
@@ -350,10 +350,10 @@ Sprite *Sprite::expand() {
 						CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
 						c->_commandType = CommandType(id);
 						c->_lab = label;
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							error("Unexpected end of file! %s", fname);
 						c->_ref = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == NULL)
+						if ((p = _vm->token(nullptr)) == nullptr)
 							error("Unexpected end of file! %s", fname);
 						c->_val = _vm->number(p);
 						c->_spritePtr = nullptr;
@@ -364,7 +364,7 @@ Sprite *Sprite::expand() {
 					s->_now = atoi(p);
 					if (s->_now > maxnow)
 						maxnow = s->_now;
-					if ((p = _vm->token(nullptr)) == NULL)
+					if ((p = _vm->token(nullptr)) == nullptr)
 						break;
 					s->_next = _vm->number(p);
 					switch (s->_next) {
@@ -377,16 +377,16 @@ Sprite *Sprite::expand() {
 					}
 					if (s->_next > maxnxt)
 						maxnxt = s->_next;
-					if ((p = _vm->token(nullptr)) == NULL)
+					if ((p = _vm->token(nullptr)) == nullptr)
 						error("Unexpected end of file! %s", fname);
 					s->_dx = _vm->number(p);
-					if ((p = _vm->token(nullptr)) == NULL)
+					if ((p = _vm->token(nullptr)) == nullptr)
 						error("Unexpected end of file! %s", fname);
 					s->_dy = _vm->number(p);
-					if ((p = _vm->token(nullptr)) == NULL)
+					if ((p = _vm->token(nullptr)) == nullptr)
 						error("Unexpected end of file! %s", fname);
 					s->_dz = _vm->number(p);
-					if ((p = _vm->token(nullptr)) == NULL)
+					if ((p = _vm->token(nullptr)) == nullptr)
 						error("Unexpected end of file! %s", fname);
 					s->_dly = _vm->number(p);
 					break;
@@ -750,7 +750,7 @@ void Sprite::sync(Common::Serializer &s) {
 	_file[8] = '\0';
 }
 
-Queue::Queue(bool show) : _head(NULL), _tail(NULL) {
+Queue::Queue(bool show) : _head(nullptr), _tail(nullptr) {
 }
 
 void Queue::append(Sprite *spr) {
@@ -828,7 +828,7 @@ Sprite *Queue::locate(int ref) {
 		if (spr->_ref == ref)
 			return spr;
 	}
-	return NULL;
+	return nullptr;
 }
 
 bool Queue::locate(Sprite *spr) {
@@ -839,9 +839,9 @@ bool Queue::locate(Sprite *spr) {
 	return false;
 }
 
-Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(NULL), _name(NULL), _setPal(false), _mono(0), _vm(vm) {
-	_oldColors = NULL;
-	_newColors = NULL;
+Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(false), _mono(0), _vm(vm) {
+	_oldColors = nullptr;
+	_newColors = nullptr;
 	_showQ = new Queue(true);
 	_sysPal = new Dac[kPalCount];
 
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 7dd7933..17ce4d3 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -240,7 +240,7 @@ public:
 	bool works(Sprite *spr);
 	bool seqTest(int n);
 	inline bool active() {
-		return _ext != NULL;
+		return _ext != nullptr;
 	}
 	Sprite(CGE2Engine *vm);
 	Sprite(CGE2Engine *vm, BitmapPtr shp, int cnt);
@@ -255,7 +255,7 @@ public:
 	void backShow();
 	void setName(char *newName);
 	inline char *name() {
-		return (_ext) ? _ext->_name : NULL;
+		return (_ext) ? _ext->_name : nullptr;
 	}
 	void gotoxyz(int x, int y, int z = 0);
 	void gotoxyz();
@@ -274,7 +274,7 @@ public:
 	virtual void touch(uint16 mask, V2D pos, Common::KeyCode keyCode);
 	virtual void tick();
 	virtual void setScene(int c);
-	void clrHide() { if (_ext) _ext->_b0 = NULL; }
+	void clrHide() { if (_ext) _ext->_b0 = nullptr; }
 
 	void sync(Common::Serializer &s);
 


Commit: 1335247f8235c4abd3062ff0989ea2a3cd5b608b
    https://github.com/scummvm/scummvm/commit/1335247f8235c4abd3062ff0989ea2a3cd5b608b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-07T21:52:16+02:00

Commit Message:
CGE2: Hopefully fix memory leak problems regarding _ext.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 4b50ccc..85eb09b 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -46,6 +46,9 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 
 	char fname[kMaxPath];
 	_vm->mergeExt(fname, _file, kSprExt);
+
+	if (_ext != nullptr)
+		delete _ext;
 	_ext = new SprExt(_vm);
 	if (_ext == nullptr)
 		error("No core %s", fname);
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 340f9c0..d7e0552 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -261,8 +261,14 @@ Sprite *Sprite::expand() {
 	if (_vm->_spriteNotify != nullptr)
 		(_vm->*_vm->_spriteNotify)();
 
+	char fname[kPathMax];
+	_vm->mergeExt(fname, _file, kSprExt);
+
+	if (_ext != nullptr)
+		delete _ext;
 	_ext = new SprExt(_vm);
-	assert(_ext != nullptr);
+	if (_ext == nullptr)
+		error("No core %s", fname);
 
 	if (!*_file)
 		return this;
@@ -275,9 +281,6 @@ Sprite *Sprite::expand() {
 		maxnow = 0,
 		maxnxt = 0;
 
-	char fname[kPathMax];
-	_vm->mergeExt(fname, _file, kSprExt);
-
 	Seq *curSeq;
 	if (_seqCnt) {
 		curSeq = new Seq[_seqCnt];
@@ -479,6 +482,7 @@ Sprite *Sprite::contract() {
 		}
 	}
 
+	delete _ext;
 	_ext = nullptr;
 
 	return this;


Commit: 10a37ea478050c37d368f31815fb189f4c7af7b1
    https://github.com/scummvm/scummvm/commit/10a37ea478050c37d368f31815fb189f4c7af7b1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-07T23:35:27+02:00

Commit Message:
CGE2: Fix Hero::setCurrent().

This fixes a crash regarding the mechanic on scene 6.

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 85eb09b..393aa4b 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -216,7 +216,7 @@ void Hero::setCurrent() {
 	int h = -(tmp.trunc());
 
 	int i = 0;
-	for (; i < kDimMax; i++) {
+	for (; i < kDimMax - 1; i++) {
 		if (h >= (_hig[i] + _hig[i + 1]) / 2)
 			break;
 	}


Commit: be5ec466b3028f15a8aa51331426b3cd317fe789
    https://github.com/scummvm/scummvm/commit/be5ec466b3028f15a8aa51331426b3cd317fe789
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-07T23:58:06+02:00

Commit Message:
CGE2: Fix another probable memory-leak source.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 393aa4b..f9c9996 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -34,6 +34,10 @@ namespace CGE2 {
 Hero::Hero(CGE2Engine *vm)
 	: Sprite(vm), _contact(nullptr), _dir(kNoDir),
       _curDim(0), _tracePtr(-1), _ignoreMap(false) {
+
+	for (int i = 0; i < kDimMax; i++) {
+		_dim[i] = nullptr;
+	}
 }
 
 Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
@@ -210,6 +214,15 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 	return this;
 }
 
+Sprite *Hero::contract() {
+	for (int i = 0; i < kDimMax; i++) {
+		if (_dim[i] != nullptr)
+			delete[] _dim[i];
+	}
+
+	return this;
+}
+
 void Hero::setCurrent() {
 	FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
 	FXP tmp = m * _siz.y;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index 41eb3ac..c277b4a 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -77,7 +77,7 @@ public:
 	Hero(CGE2Engine *vm);
 	void tick();
 	Sprite *expand();
-	Sprite *contract() { return this; }
+	Sprite *contract();
 	Sprite *setContact();
 	int stepSize() { return _ext->_seq[7]._dx; }
 	int distance(V3D pos);


Commit: 3935a427f94c7619c56976db3c8c4aeca1df500b
    https://github.com/scummvm/scummvm/commit/3935a427f94c7619c56976db3c8c4aeca1df500b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-07-07T21:48:02-04:00

Commit Message:
CGE2: Add extra clipping to Bitmap::hide

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index d7e0552..a53a116 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1134,10 +1134,24 @@ void Bitmap::show(V2D pos) {
 
 void Bitmap::hide(V2D pos) {
 	xLatPos(pos);
-	
+
+	// Perform clipping to screen
 	int w = MIN<int>(_w, kScrWidth - pos.x);
 	int h = MIN<int>(_h, kScrHeight - pos.y);
+	if (pos.x < 0) {
+		w -= -pos.x;
+		pos.x = 0;
+		if (w < 0)
+			return;
+	}
+	if (pos.y < 0) {
+		h -= -pos.y;
+		pos.y = 0;
+		if (h < 0)
+			return;
+	}
 
+	// Perform copying of screen section
 	for (int yp = pos.y; yp < pos.y + h; yp++) {
 		if (yp >= 0 && yp < kScrHeight) {
 			const byte *srcP = (const byte *)_vm->_vga->_page[2]->getBasePtr(pos.x, yp);


Commit: a73aea1ce8cb72607d258063f48b8540925b79e2
    https://github.com/scummvm/scummvm/commit/a73aea1ce8cb72607d258063f48b8540925b79e2
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-08T09:45:22+02:00

Commit Message:
CGE2: Fix GCC warning, rewrite Text::clear()

Changed paths:
    engines/cge2/text.cpp



diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 5826f6e..e1b2552 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -49,8 +49,10 @@ Text::Text(CGE2Engine *vm, const char *fname) : _vm(vm) {
 		_cache[_size]._text = nullptr;
 	}
 	load();
-	_cache[_txtCount - 1]._ref = 0;
-	_cache[_txtCount - 1]._text = "";
+
+	_cache[_txtCount - 1]._ref = -1;
+	_cache[_txtCount - 1]._text = new char[3];
+	strcpy(_cache[_txtCount - 1]._text, "");
 }
 
 Text::~Text() {
@@ -83,11 +85,11 @@ int16 Text::count() {
 }
 
 void Text::clear() {
-	for (Handler *p = _cache, *q = p + _size; p < q; p++) {
-		if (p->_ref) {
-			p->_ref = 0;
-			delete[] p->_text;
-			p->_text = nullptr;
+	for (int i = 0; i < _txtCount; i++) {
+		if (_cache[i]._ref) {
+			_cache[i]._ref = 0;
+			delete[] _cache[i]._text;
+			_cache[i]._text = nullptr;
 		}
 	}
 }


Commit: b75d308697f96902ea8a290aa5fb7e3bbadbd69e
    https://github.com/scummvm/scummvm/commit/b75d308697f96902ea8a290aa5fb7e3bbadbd69e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-08T14:09:10+02:00

Commit Message:
CGE2: Rework CGE2Engine::locate().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index be83bed..071e49b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -590,7 +590,7 @@ Sprite *CGE2Engine::locate(int ref) {
 	_taken = false;
 	Sprite *spr = _vga->_showQ->locate(ref);
 	if (!spr) {
-		spr = _spare->locate(ref);
+		spr = _spare->take(ref);
 		if (spr)
 			_taken = true;
 	}


Commit: ffbed9f86de014075a363430fb9c822758431ea8
    https://github.com/scummvm/scummvm/commit/ffbed9f86de014075a363430fb9c822758431ea8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-08T14:09:11+02:00

Commit Message:
CGE2: Comment out Hero::contract() for now.

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index f9c9996..65138cd 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -215,11 +215,12 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 }
 
 Sprite *Hero::contract() {
+	/* TODO: Recheck this later!
 	for (int i = 0; i < kDimMax; i++) {
 		if (_dim[i] != nullptr)
 			delete[] _dim[i];
 	}
-
+	*/
 	return this;
 }
 


Commit: d0a6fa4ce2594bf84cb1e6c12108fb96055beb1e
    https://github.com/scummvm/scummvm/commit/d0a6fa4ce2594bf84cb1e6c12108fb96055beb1e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T10:41:36+02:00

Commit Message:
CGE2: Implement switchColorMode().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 071e49b..76829b0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1099,7 +1099,9 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 }
 
 void CGE2Engine::switchColorMode() {
-	warning("STUB: CGE2Engine::switchColorMode()");
+	_commandHandlerTurbo->addCommand(kCmdSeq, 121, _vga->_mono = !_vga->_mono, NULL);
+	keyClick();
+	_vga->setColors(_vga->_sysPal, 64);
 }
 
 void CGE2Engine::switchMusic() {


Commit: 45da1e7c741a1906b60ad3d55a9e0087fd9a4a3e
    https://github.com/scummvm/scummvm/commit/45da1e7c741a1906b60ad3d55a9e0087fd9a4a3e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T11:17:30+02:00

Commit Message:
CGE2: Implement switchVox() and switchCap().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index aa87f99..16deafb 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -97,6 +97,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_req = 1;
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
+	_enaCap = true;
+	_enaVox = true;
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index a2cd131..252fad0 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -285,6 +285,8 @@ public:
 	NotifyFunctionType _midiNotify;
 	NotifyFunctionType _spriteNotify;
 	int _startGameSlot;
+	bool _enaCap;
+	bool _enaVox;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 76829b0..b7dcf65 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1137,11 +1137,23 @@ void CGE2Engine::setVolume(int idx, int cnt) {
 }
 
 void CGE2Engine::switchCap() {
-	warning("STUB: CGE2Engine::switchCap()");
+	if (_enaCap) {
+		_sayCap = !_sayCap;
+		if (!_sayCap)
+			_sayVox = true;
+		keyClick();
+		checkSaySwitch();
+	}
 }
 
 void CGE2Engine::switchVox() {
-	warning("STUB: CGE2Engine::switchVox()");
+	if (_enaVox) {
+		_sayVox = !_sayVox;
+		if (!_sayVox)
+			_sayCap = true;
+		keyClick();
+		checkSaySwitch();
+	}
 }
 
 void CGE2Engine::offUse() {


Commit: 5a1383343fb645b5fbd80060da81253b2443bf28
    https://github.com/scummvm/scummvm/commit/5a1383343fb645b5fbd80060da81253b2443bf28
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T11:33:02+02:00

Commit Message:
CGE2: Rework number().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/hero.cpp
    engines/cge2/talk.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index b7dcf65..a46767b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -112,7 +112,10 @@ void System::tick() {
 	}
 }
 
-int CGE2Engine::number(char *s) { // TODO: Rework it later to include the preceding token() call!
+int CGE2Engine::number(char *str) {
+	char *s = token(str);
+	if (s == nullptr)
+		error("Wrong input for CGE2Engine::number()");
 	int r = atoi(s);
 	char *pp = strchr(s, ':');
 	if (pp)
@@ -335,9 +338,7 @@ void CGE2Engine::loadScript(const char *fname) {
 		V3D P;
 
 		// sprite ident number
-		if ((p = token(tmpStr)) == nullptr)
-			break;
-		int SpI = number(p);
+		int SpI = number(tmpStr);
 
 		// sprite file name
 		char *SpN;
@@ -345,29 +346,19 @@ void CGE2Engine::loadScript(const char *fname) {
 			break;
 
 		// sprite scene
-		if ((p = token(nullptr)) == nullptr)
-			break;
-		int SpA = number(p);
+		int SpA = number(nullptr);
 
 		// sprite column
-		if ((p = token(nullptr)) == nullptr)
-			break;
-		P._x = number(p);
+		P._x = number(nullptr);
 
 		// sprite row
-		if ((p = token(nullptr)) == nullptr)
-			break;
-		P._y = number(p);
+		P._y = number(nullptr);
 
 		// sprite Z pos
-		if ((p = token(nullptr)) == nullptr)
-			break;
-		P._z = number(p);
+		P._z = number(nullptr);
 
 		// sprite life
-		if ((p = token(nullptr)) == nullptr)
-			break;
-		bool BkG = number(p) == 0;
+		bool BkG = number(nullptr) == 0;
 
 		ok = true; // no break: OK
 
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 65138cd..6281e4d 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -134,12 +134,8 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 						if (_actionCtrl[section]._cnt) {
 							CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
 							c->_commandType = CommandType(id);
-							if ((p = _vm->token(nullptr)) == nullptr)
-								error("Unexpected end of file! %s", fname);
-							c->_ref = _vm->number(p);
-							if ((p = _vm->token(nullptr)) == nullptr)
-								error("Unexpected end of file! %s", fname);
-							c->_val = _vm->number(p);
+							c->_ref = _vm->number(nullptr);
+							c->_val = _vm->number(nullptr);
 							c->_spritePtr = nullptr;
 						}
 						break;
@@ -148,9 +144,7 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 						s->_now = atoi(p);
 						if (s->_now > maxnow)
 							maxnow = s->_now;
-						if ((p = _vm->token(nullptr)) == nullptr)
-							break;
-						s->_next = _vm->number(p);
+						s->_next = _vm->number(nullptr);
 						switch (s->_next) {
 						case 0xFF:
 							s->_next = seqcnt;
@@ -161,18 +155,10 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 						}
 						if (s->_next > maxnxt)
 							maxnxt = s->_next;
-						if ((p = _vm->token(nullptr)) == nullptr)
-							error("Unexpected end of file! %s", fname);
-						s->_dx = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == nullptr)
-							error("Unexpected end of file! %s", fname);
-						s->_dy = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == nullptr)
-							error("Unexpected end of file! %s", fname);
-						s->_dz = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == nullptr)
-							error("Unexpected end of file! %s", fname);
-						s->_dly = _vm->number(p);
+						s->_dx = _vm->number(nullptr);
+						s->_dy = _vm->number(nullptr);
+						s->_dz = _vm->number(nullptr);
+						s->_dly = _vm->number(nullptr);
 						break;
 					case kIdPhase:
 						for (int i = 0; i < kDimMax; i++) {
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index eda8123..fd1c140 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -87,15 +87,11 @@ void Font::load() {
 		
 		char *token;
 
-		if ((token = _vm->token(tmpStr)) == nullptr)
-			error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
-		_colorSet[n][0] = _vm->number(token);
-
-		for (int i = 1; i < 4; i++) {
-			if ((token = _vm->token(nullptr)) == nullptr)
-				error("Wrong line! (%d) in %s", colorFile.getLineCount(), path);
-			_colorSet[n][i] = _vm->number(token);
-		}
+		
+		_colorSet[n][0] = _vm->number(tmpStr);
+
+		for (int i = 1; i < 4; i++)
+			_colorSet[n][i] = _vm->number(nullptr);
 
 		n++;
 	}
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index a53a116..069c267 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -353,12 +353,8 @@ Sprite *Sprite::expand() {
 						CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
 						c->_commandType = CommandType(id);
 						c->_lab = label;
-						if ((p = _vm->token(nullptr)) == nullptr)
-							error("Unexpected end of file! %s", fname);
-						c->_ref = _vm->number(p);
-						if ((p = _vm->token(nullptr)) == nullptr)
-							error("Unexpected end of file! %s", fname);
-						c->_val = _vm->number(p);
+						c->_ref = _vm->number(nullptr);
+						c->_val = _vm->number(nullptr);
 						c->_spritePtr = nullptr;
 					}
 					break;
@@ -367,9 +363,7 @@ Sprite *Sprite::expand() {
 					s->_now = atoi(p);
 					if (s->_now > maxnow)
 						maxnow = s->_now;
-					if ((p = _vm->token(nullptr)) == nullptr)
-						break;
-					s->_next = _vm->number(p);
+					s->_next = _vm->number(nullptr);
 					switch (s->_next) {
 					case 0xFF:
 						s->_next = seqcnt;
@@ -380,18 +374,10 @@ Sprite *Sprite::expand() {
 					}
 					if (s->_next > maxnxt)
 						maxnxt = s->_next;
-					if ((p = _vm->token(nullptr)) == nullptr)
-						error("Unexpected end of file! %s", fname);
-					s->_dx = _vm->number(p);
-					if ((p = _vm->token(nullptr)) == nullptr)
-						error("Unexpected end of file! %s", fname);
-					s->_dy = _vm->number(p);
-					if ((p = _vm->token(nullptr)) == nullptr)
-						error("Unexpected end of file! %s", fname);
-					s->_dz = _vm->number(p);
-					if ((p = _vm->token(nullptr)) == nullptr)
-						error("Unexpected end of file! %s", fname);
-					s->_dly = _vm->number(p);
+					s->_dx = _vm->number(nullptr);
+					s->_dy = _vm->number(nullptr);
+					s->_dz = _vm->number(nullptr);
+					s->_dly = _vm->number(nullptr);
 					break;
 				case kIdPhase: {
 					shplist[shpcnt] = Bitmap(_vm, p);


Commit: c1bda3c973cda3c3d7ed73aac8ca8be7ce6f0bc8
    https://github.com/scummvm/scummvm/commit/c1bda3c973cda3c3d7ed73aac8ca8be7ce6f0bc8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T11:53:52+02:00

Commit Message:
CGE2: Remove unnecessary stub from run().

Changed paths:
    engines/cge2/cge2.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 16deafb..1fb880c 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -167,8 +167,6 @@ bool CGE2Engine::hasFeature(EngineFeature f) const {
 }
 
 Common::Error CGE2Engine::run() {
-	warning("STUB: CGE2Engine::run()");
-
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();


Commit: 8f869c74c09858dd3fd553c30ca645d942b4cdb0
    https://github.com/scummvm/scummvm/commit/8f869c74c09858dd3fd553c30ca645d942b4cdb0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T11:55:27+02:00

Commit Message:
CGE2: Add option for enabling color blind mode from the Launcher.

Changed paths:
    engines/cge2/detection.cpp
    engines/cge2/detection.h
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 6d4f633..5fcbe2e 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -64,7 +64,7 @@ const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles,
 			desc.language = Common::EN_ANY;
 			desc.platform = Common::kPlatformDOS;
 			desc.flags = ADGF_NO_FLAGS;
-			desc.guioptions = GUIO0();
+			desc.guioptions = GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF);
 			
 			return (const ADGameDescription *)&desc;
 		}
diff --git a/engines/cge2/detection.h b/engines/cge2/detection.h
index 5569807..51e2988 100644
--- a/engines/cge2/detection.h
+++ b/engines/cge2/detection.h
@@ -30,9 +30,12 @@
 
 #include "cge2/cge2.h"
 #include "engines/advancedDetector.h"
+#include "common/translation.h"
 
 namespace CGE2 {
 
+#define GAMEOPTION_COLOR_BLIND_DEFAULT_OFF  GUIO_GAMEOPTIONS1
+
 static const PlainGameDescriptor CGE2Games[] = {
 	{ "sfinx", "Sfinx" },
 	{ 0, 0 }
@@ -46,14 +49,28 @@ static const ADGameDescription gameDescriptions[] = {
 			{ "vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844 },
 			AD_LISTEND
 		},
-		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO0()
+		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
 	},
 	AD_TABLE_END_MARKER
 };
 
+static const ADExtraGuiOptionsMap optionsList[] = {
+		{
+			GAMEOPTION_COLOR_BLIND_DEFAULT_OFF,
+			{
+				_s("Color Blind Mode"),
+				_s("Enable Color Blind Mode by default"),
+				"enable_color_blind",
+				false
+			}
+		},
+
+		AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
 class CGE2MetaEngine : public AdvancedMetaEngine {
 public:
-	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games) {
+	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games, optionsList) {
 		_singleid = "sfinx";
 	}
 
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 069c267..10c6bbd 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -840,10 +840,8 @@ Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(fa
 		_page[idx]->create(kScrWidth, kScrHeight, Graphics::PixelFormat::createFormatCLUT8());
 	}
 
-	/*if (ConfMan.getBool("enable_color_blind"))
-		_mono = 1;*/
-	
-	warning("STUB: Vga::Vga()");
+	if (ConfMan.getBool("enable_color_blind"))
+		_mono = 1;
 
 	_oldColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
 	_newColors = (Dac *)malloc(sizeof(Dac) * kPalCount);


Commit: 2f8abb06c34fa6ed418682a05da9a944789e4429
    https://github.com/scummvm/scummvm/commit/2f8abb06c34fa6ed418682a05da9a944789e4429
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T12:46:49+02:00

Commit Message:
CGE2: Implement Sound::open(), add stub for checkSaySwitch().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/sound.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a46767b..cda7b20 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -807,6 +807,7 @@ void CGE2Engine::releasePocket(Sprite *spr) {
 }
 
 void CGE2Engine::checkSaySwitch() {
+	warning("STUB: CGE2Engine::checkSaySwitch()");
 //	if (SNDDrvInfo.DDEV == DEV_QUIET)
 //		_sayVox = !(_sayCap = true);
 	_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index 51764b7..a7815b7 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -61,7 +61,7 @@ void Sound::close() {
 
 void Sound::open() {
 	setRepeat(1);
-	warning("STUB: Sound::open()");
+	_vm->checkSaySwitch();
 	play(_vm->_fx->load(99, 99));
 }
 


Commit: 3dc79442c9e1a92649f2a52b8e8ef0a9f890ae93
    https://github.com/scummvm/scummvm/commit/3dc79442c9e1a92649f2a52b8e8ef0a9f890ae93
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T12:51:03+02:00

Commit Message:
CGE2: Fix Sound::open().

Changed paths:
    engines/cge2/sound.cpp



diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index a7815b7..b7b39d2 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -61,7 +61,8 @@ void Sound::close() {
 
 void Sound::open() {
 	setRepeat(1);
-	_vm->checkSaySwitch();
+	if (_vm->_commandHandlerTurbo != nullptr)
+		_vm->checkSaySwitch();
 	play(_vm->_fx->load(99, 99));
 }
 


Commit: ec88528080e0c393598042902aca771396f72b1f
    https://github.com/scummvm/scummvm/commit/ec88528080e0c393598042902aca771396f72b1f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T12:53:51+02:00

Commit Message:
CGE2: Remove unnecessary stub from cge2_main().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index cda7b20..2148848 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -837,8 +837,6 @@ void CGE2Engine::loadTab() {
 }
 
 void CGE2Engine::cge2_main() {
-	warning("STUB: CGE2Engine::cge2_main()");
-
 	loadTab();
 
 	if (_startGameSlot != -1) {


Commit: 55f91da1ee02fcf8be40e10beccbc7e509b03902
    https://github.com/scummvm/scummvm/commit/55f91da1ee02fcf8be40e10beccbc7e509b03902
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T12:56:16+02:00

Commit Message:
CGE2: Remove unused local variable from loadScript().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2148848..ff8621f 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -328,8 +328,6 @@ void CGE2Engine::loadScript(const char *fname) {
 		if (line.empty())
 			continue;
 
-		char *p;
-
 		lcnt++;
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 		


Commit: dbea97b7c451fedec35bac35dcff3af7b62e5b1e
    https://github.com/scummvm/scummvm/commit/dbea97b7c451fedec35bac35dcff3af7b62e5b1e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T12:57:11+02:00

Commit Message:
CGE2: Remove unnecessary stub from loadHeroes().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ff8621f..bdfd552 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -695,8 +695,6 @@ void CGE2Engine::loadUser() {
 }
 
 void CGE2Engine::loadHeroes() { // Original name: loadGame()
-	warning("STUB: CGE2Engine::loadHeroes()");
-
 	// load sprites & pocket
 	
 	Sprite *s;


Commit: dc2330a3b14cd31806785cc8b2fd98a49d3721fc
    https://github.com/scummvm/scummvm/commit/dc2330a3b14cd31806785cc8b2fd98a49d3721fc
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-09T15:48:47+02:00

Commit Message:
CGE2: Implement the keyboard handler

Changed paths:
    engines/cge2/cge2_main.h
    engines/cge2/events.cpp



diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index d6f2371..e2f6785 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -32,6 +32,8 @@
 
 namespace CGE2 {
 
+#define kShowScummVMVersion 10
+
 class System : public Sprite {
 public:
 	int _funDel;
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index c56f005..7dab8f7 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -41,23 +41,89 @@ namespace CGE2 {
 
 Keyboard::Keyboard(CGE2Engine *vm) : _client(nullptr), _vm(vm) {
 	warning("STUB: Keyboard::Keyboard() - Recheck the whole implementation!!!");
+	_keyAlt = false;
 }
 
 Keyboard::~Keyboard() {
 }
 
 Sprite *Keyboard::setClient(Sprite *spr) {
-	warning("STUB: Keyboard::setClient()");
+	SWAP(_client, spr);
 	return spr;
 }
 
 bool Keyboard::getKey(Common::Event &event) {
-	warning("STUB: Keyboard::getKey()");
-	return false;
+	Common::KeyCode keycode = event.kbd.keycode;
+
+	if (((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) && event.type == Common::EVENT_KEYDOWN)
+		_keyAlt = true;
+	else
+		_keyAlt = false;
+
+	switch (keycode) {
+	case Common::KEYCODE_F1:
+		if (event.type == Common::EVENT_KEYUP)
+			return false;
+		// Display ScummVM version and translation strings
+		for (int i = 0; i < 5; i++)
+			_vm->_commandHandler->addCommand(kCmdInf, 1, kShowScummVMVersion + i, NULL);
+		return false;
+	case Common::KEYCODE_F5:
+		if (_vm->canSaveGameStateCurrently()) {
+			GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save", true);
+			int16 savegameId = dialog->runModalWithCurrentTarget();
+			Common::String savegameDescription = dialog->getResultString();
+			delete dialog;
+
+			if (savegameId != -1)
+				_vm->saveGameState(savegameId, savegameDescription);
+		}
+		return false;
+	case Common::KEYCODE_F7:
+		if (_vm->canLoadGameStateCurrently()) {
+			GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
+			int16 savegameId = dialog->runModalWithCurrentTarget();
+			delete dialog;
+
+			if (savegameId != -1)
+				_vm->loadGameState(savegameId);
+		}
+		return false;
+	case Common::KEYCODE_d:
+		/*
+		if (event.kbd.flags & Common::KBD_CTRL) {
+			// Start the debugger
+			_vm->getDebugger()->attach();
+			_vm->getDebugger()->onFrame();
+			return false;
+		}
+		*/
+		break;
+	case Common::KEYCODE_x:
+		if (event.kbd.flags & Common::KBD_ALT) {
+			_vm->quit();
+			return false;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return true;
 }
 
 void Keyboard::newKeyboard(Common::Event &event) {
-	warning("STUB: Keyboard::newKeyboard()");
+	if (!getKey(event))
+		return;
+
+	if ((event.type == Common::EVENT_KEYDOWN) && (_client)) {
+		CGE2Event &evt = _vm->_eventManager->getNextEvent();
+		evt._x = 0;
+		evt._y = 0;
+		evt._keyCode = event.kbd.keycode;   // Keycode
+		evt._mask = kEventKeyb;             // Event mask
+		evt._spritePtr = _client;           // Sprite pointer
+	}
 }
 
 /*----------------- MOUSE interface -----------------*/


Commit: 1be1ce6117a97c73f1bab24b4421a8fbc5c5ec2c
    https://github.com/scummvm/scummvm/commit/1be1ce6117a97c73f1bab24b4421a8fbc5c5ec2c
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-09T16:44:23+02:00

Commit Message:
CGE2: Set widespace for Inf text, update first line of info text in CGE.SAY

Changed paths:
    engines/cge2/cge2_main.h
    engines/cge2/text.cpp



diff --git a/engines/cge2/cge2_main.h b/engines/cge2/cge2_main.h
index e2f6785..afbe7b3 100644
--- a/engines/cge2/cge2_main.h
+++ b/engines/cge2/cge2_main.h
@@ -32,7 +32,7 @@
 
 namespace CGE2 {
 
-#define kShowScummVMVersion 10
+#define kShowScummVMVersion 15
 
 class System : public Sprite {
 public:
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index e1b2552..9ebed58 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -185,7 +185,7 @@ void Text::say(const char *text, Sprite *spr) {
 
 void CGE2Engine::inf(const char *text, ColorBank col) {
 	killText();
-	_talk = new Talk(this, text, kTBRect, col);
+	_talk = new Talk(this, text, kTBRect, col, true);
 	if (_talk) {
 		_talk->_flags._kill = true;
 		_talk->setName(_text->getText(kInfName));


Commit: f57d2ff4d6268e0bf2dd8edf419fde6b649a9f34
    https://github.com/scummvm/scummvm/commit/f57d2ff4d6268e0bf2dd8edf419fde6b649a9f34
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T16:56:32+02:00

Commit Message:
CGE2: Remove unnecessary stub from Keyboard's constructor.

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 7dab8f7..48febd2 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -40,7 +40,6 @@ namespace CGE2 {
 /*----------------- KEYBOARD interface -----------------*/
 
 Keyboard::Keyboard(CGE2Engine *vm) : _client(nullptr), _vm(vm) {
-	warning("STUB: Keyboard::Keyboard() - Recheck the whole implementation!!!");
 	_keyAlt = false;
 }
 


Commit: fcce50e6fe954ed275de29da60d29cc99ce77008
    https://github.com/scummvm/scummvm/commit/fcce50e6fe954ed275de29da60d29cc99ce77008
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-09T16:56:33+02:00

Commit Message:
CGE2: Hook handling of F10 into the Keyboard::getKey().

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 48febd2..ecb6183 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -104,6 +104,10 @@ bool Keyboard::getKey(Common::Event &event) {
 			return false;
 		}
 		break;
+	case Common::KEYCODE_F10:
+		if (_vm->_commandHandler->idle())
+			_vm->switchScene(-1); // Exits the game.
+		return false;
 	default:
 		break;
 	}


Commit: 4d2c1315ac24870ac8b2d53cdc6b274893df7157
    https://github.com/scummvm/scummvm/commit/4d2c1315ac24870ac8b2d53cdc6b274893df7157
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-09T18:48:16+02:00

Commit Message:
CGE2: Silence a GCC warning, reduce the scope of a variable

Changed paths:
    engines/cge2/talk.cpp



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index fd1c140..227e013 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -77,17 +77,12 @@ void Font::load() {
 	assert(!colorFile.err());
 
 	char tmpStr[kLineMax + 1];
-	Common::String line;
 	int n = 0;
 
-	for (line = colorFile.readLine(); !colorFile.eos(); line = colorFile.readLine()){
+	for (Common::String line = colorFile.readLine(); !colorFile.eos(); line = colorFile.readLine()){
 		if (line.empty())
 			continue;
 		Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-		
-		char *token;
-
-		
 		_colorSet[n][0] = _vm->number(tmpStr);
 
 		for (int i = 1; i < 4; i++)


Commit: 89295b789552a337645e8218e1f237772f0ac1ed
    https://github.com/scummvm/scummvm/commit/89295b789552a337645e8218e1f237772f0ac1ed
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-14T18:01:36+02:00

Commit Message:
CGE2: Remove unnecessary comment from ~Vga().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 10c6bbd..fef9b6b 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -855,14 +855,6 @@ Vga::~Vga() {
 	_mono = 0;
 
 	Common::String buffer = "";
-/*
-	clear(0);
-	setMode(_oldMode);
-	setColors();
-	restoreScreen(_oldScreen);
-	sunrise(_oldColors);
-*/
-	warning("STUB: Vga::~Vga()");
 
 	free(_oldColors);
 	free(_newColors);


Commit: b941fe226d07477f114197dcc69c581dd173e689
    https://github.com/scummvm/scummvm/commit/b941fe226d07477f114197dcc69c581dd173e689
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-14T18:04:16+02:00

Commit Message:
CGE2: Unstub movie().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index bdfd552..edf9db9 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -394,10 +394,10 @@ void CGE2Engine::movie(const char *ext) {
 		loadScript(fn);
 		sceneUp(_now);
 
+		_keyboard->setClient(_sys);
 		while (!_commandHandler->idle() && !_quitFlag)
 			mainLoop();
-
-		warning("STUB: CGE2Engine::movie()");
+		_keyboard->setClient(nullptr);
 
 		_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 		_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);


Commit: 807f354cba9866248c8f7bd0d0bc9367aa4981af
    https://github.com/scummvm/scummvm/commit/807f354cba9866248c8f7bd0d0bc9367aa4981af
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-14T18:14:20+02:00

Commit Message:
CGE2: Remove unused classes from vga13h.

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index fef9b6b..02d536c 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1107,7 +1107,6 @@ void Bitmap::show(V2D pos) {
 	}
 }
 
-
 void Bitmap::hide(V2D pos) {
 	xLatPos(pos);
 
@@ -1138,16 +1137,6 @@ void Bitmap::hide(V2D pos) {
 	}
 }
 
-/*--------------------------------------------------------------------------*/
-
-HorizLine::HorizLine(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
-	warning("HorizLine::HorizLine()");
-}
-
-SceneLight::SceneLight(CGE2Engine *vm) : Sprite(vm), _vm(vm) {
-	warning("SceneLight::SceneLight()");
-}
-
 Speaker::Speaker(CGE2Engine *vm): Sprite(vm), _vm(vm) {
 	// Set the sprite list
 	BitmapPtr SP = new Bitmap[2];
@@ -1160,8 +1149,4 @@ Speaker::Speaker(CGE2Engine *vm): Sprite(vm), _vm(vm) {
 	setShapeList(SP, 2);
 }
 
-PocLight::PocLight(CGE2Engine *vm): Sprite(vm), _vm(vm) {
-	warning("PocLight::PocLight()");
-}
-
 } // End of namespace CGE2
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 17ce4d3..77bece6 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -339,30 +339,12 @@ public:
 	void dacToPal(const Dac *tab, byte *palData);
 };
 
-class HorizLine: public Sprite {
-	CGE2Engine *_vm;
-public:
-	HorizLine(CGE2Engine *vm);
-};
-
-class SceneLight: public Sprite {
-	CGE2Engine *_vm;
-public:
-	SceneLight(CGE2Engine *vm);
-};
-
 class Speaker: public Sprite {
 	CGE2Engine *_vm;
 public:
 	Speaker(CGE2Engine *vm);
 };
 
-class PocLight: public Sprite {
-	CGE2Engine *_vm;
-public:
-	PocLight(CGE2Engine *vm);
-};
-
 } // End of namespace CGE2
 
 #endif // CGE2_VGA13H_H


Commit: 2f8967d95948aae6f15e4949d2b06a7e6b7674a4
    https://github.com/scummvm/scummvm/commit/2f8967d95948aae6f15e4949d2b06a7e6b7674a4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-14T18:15:49+02:00

Commit Message:
CGE2: Unstub showTitle().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index edf9db9..bddb83b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -913,8 +913,6 @@ bool CGE2Engine::showTitle(const char *name) {
 	_vga->sunrise(_vga->_sysPal);
 
 	_vga->update();
-
-	warning("STUB: CGE2Engine::showTitle()");
 	
 	return true;
 }


Commit: 753b5f89bab3eb2cdd6d0f4567a76d5d4fd83624
    https://github.com/scummvm/scummvm/commit/753b5f89bab3eb2cdd6d0f4567a76d5d4fd83624
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-14T18:17:07+02:00

Commit Message:
CGE2: Unstub CommandHandler::reset().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 62dfd99..df4c67c 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -823,7 +823,7 @@ bool CommandHandler::idle() {
 }
 
 void CommandHandler::reset() {
-	warning("STUB: CommandHandler::reset()");
+	_tail = _head;
 }
 
 void CommandHandler::clear() {


Commit: 035fb6ad1cdb8ca126ac8dd5a930b954f650061c
    https://github.com/scummvm/scummvm/commit/035fb6ad1cdb8ca126ac8dd5a930b954f650061c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T13:53:26+02:00

Commit Message:
CGE2: Hopefully fix a memory leak problem regarding Hero::_dim;

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 6281e4d..6778118 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -33,11 +33,7 @@ namespace CGE2 {
 
 Hero::Hero(CGE2Engine *vm)
 	: Sprite(vm), _contact(nullptr), _dir(kNoDir),
-      _curDim(0), _tracePtr(-1), _ignoreMap(false) {
-
-	for (int i = 0; i < kDimMax; i++) {
-		_dim[i] = nullptr;
-	}
+      _curDim(0), _tracePtr(-1), _ignoreMap(false), _isDimLoaded(false) {
 }
 
 Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
@@ -62,10 +58,14 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 		Seq *seq;
 		int section = kIdPhase;
 
-		for (int i = 0; i < kDimMax; i++) {
-			_dim[i] = new Bitmap[_shpCnt];
-			for (int j = 0; j < _shpCnt; j++)
-				_dim[i][j].setVM(_vm);
+		if (!_isDimLoaded) {
+			for (int i = 0; i < kDimMax; i++) {
+				_dim[i] = new Bitmap[_shpCnt];
+				for (int j = 0; j < _shpCnt; j++)
+					_dim[i][j].setVM(_vm);
+			}
+
+			_isDimLoaded = true;
 		}
 
 		if (_seqCnt) {
@@ -200,16 +200,6 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 	return this;
 }
 
-Sprite *Hero::contract() {
-	/* TODO: Recheck this later!
-	for (int i = 0; i < kDimMax; i++) {
-		if (_dim[i] != nullptr)
-			delete[] _dim[i];
-	}
-	*/
-	return this;
-}
-
 void Hero::setCurrent() {
 	FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
 	FXP tmp = m * _siz.y;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index c277b4a..f45a652 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -62,6 +62,7 @@ struct HeroTab {
 };
 
 class Hero : public Sprite {
+	bool _isDimLoaded;
 	int _hig[kDimMax];
 	Sprite *_contact;
 public:
@@ -77,7 +78,6 @@ public:
 	Hero(CGE2Engine *vm);
 	void tick();
 	Sprite *expand();
-	Sprite *contract();
 	Sprite *setContact();
 	int stepSize() { return _ext->_seq[7]._dx; }
 	int distance(V3D pos);


Commit: 470736b9c456cc9217f7377dbd543774eebcb88b
    https://github.com/scummvm/scummvm/commit/470736b9c456cc9217f7377dbd543774eebcb88b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T14:19:55+02:00

Commit Message:
CGE2: Remove unnecessary comment from sceneUp().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index bddb83b..0e2e702 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -453,7 +453,6 @@ void CGE2Engine::sceneUp(int cav) {
 		_mouse->on();
 
 	feedSnail(_vga->_showQ->locate(bakRef + 255), kNear, _heroTab[_sex]->_ptr);
-	//setDrawColors(); - It's only for debugging purposes. Can be left out for now.
 }
 
 void CGE2Engine::sceneDown() {


Commit: 8861b0b583f1cd56ff5e8f7a8b408f696c85f545
    https://github.com/scummvm/scummvm/commit/8861b0b583f1cd56ff5e8f7a8b408f696c85f545
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T14:41:46+02:00

Commit Message:
CGE2: Get rid of _mode.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 1fb880c..b820ba5 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -74,7 +74,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
-	_mode = 0;
 	_music = true;
 	_startupMode = 1;
 	_now = 1;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 252fad0..d97ba3d 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -263,7 +263,6 @@ public:
 
 	bool _quitFlag;
 	Dac *_bitmapPalette;
-	int _mode;
 	bool _music;
 	int _startupMode;
 	int _now;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 0e2e702..29592d7 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -836,14 +836,12 @@ void CGE2Engine::cge2_main() {
 
 	if (_startGameSlot != -1) {
 		// Starting up a savegame from the launcher
-		_mode++;
 		runGame();
 	}
 
 	if (showTitle("WELCOME")) {
 #if 0
-		if (_mode == 1)
-			movie(kIntroExt);
+		movie(kIntroExt);
 #endif
 		if (_text->getText(255) != nullptr) {
 			runGame();
@@ -891,8 +889,6 @@ int CGE2Engine::newRandom(int range) {
 bool CGE2Engine::showTitle(const char *name) {
 	if (_quitFlag)
 		return false;
-	
-	_mode++;
 
 	_bitmapPalette = _vga->_sysPal;
 	BitmapPtr LB = new Bitmap[1];


Commit: d9471679319e5a5bbc61c71fc3a07548d242fe6d
    https://github.com/scummvm/scummvm/commit/d9471679319e5a5bbc61c71fc3a07548d242fe6d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T15:17:00+02:00

Commit Message:
CGE2: Fix the intro animation.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 29592d7..d0a11643 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -402,6 +402,7 @@ void CGE2Engine::movie(const char *ext) {
 		_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 		_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
 		_spare->clear();
+		_vga->_showQ->clear();
 		_now = now;
 	}
 }
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index df4c67c..7ba0c36 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -848,33 +848,35 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 		CommandHandler::Command *c = &comtab[ptr];
 		CommandHandler::Command *q = &comtab[cnt];
 
-		int pocFre = freePockets(hero->_ref & 1);
-		int pocReq = 0;
-		CommandHandler::Command *p = c;
-		for (; p < q && p->_commandType != kCmdNext; p++) { // scan commands
-			// drop from pocket?
-			if ((p->_commandType == kCmdSend && p->_val != _now)
-				|| p->_commandType == kCmdGive) {
-				int ref = p->_ref;
-				if (ref < 0)
-					ref = spr->_ref;
-				if (findActivePocket(ref) >= 0)
-					--pocReq;
-			}
-			// make/dispose additional room?
-			if (p->_commandType == kCmdRoom) {
-				if (p->_val == 0)
+		if (hero != nullptr) {
+			int pocFre = freePockets(hero->_ref & 1);
+			int pocReq = 0;
+			CommandHandler::Command *p = c;
+			for (; p < q && p->_commandType != kCmdNext; p++) { // scan commands
+				// drop from pocket?
+				if ((p->_commandType == kCmdSend && p->_val != _now)
+					|| p->_commandType == kCmdGive) {
+					int ref = p->_ref;
+					if (ref < 0)
+						ref = spr->_ref;
+					if (findActivePocket(ref) >= 0)
+						--pocReq;
+				}
+				// make/dispose additional room?
+				if (p->_commandType == kCmdRoom) {
+					if (p->_val == 0)
+						++pocReq;
+					else
+						--pocReq;
+				}
+				// put into pocket?
+				if (p->_commandType == kCmdKeep)
 					++pocReq;
-				else
-					--pocReq;
-			}
-			// put into pocket?
-			if (p->_commandType == kCmdKeep)
-				++pocReq;
-			// overloaded?
-			if (pocReq > pocFre) {
-				pocFul();
-				return;
+				// overloaded?
+				if (pocReq > pocFre) {
+					pocFul();
+					return;
+				}
 			}
 		}
 


Commit: 8fae34df055ecc90cce6324a8c9eb09112e21e31
    https://github.com/scummvm/scummvm/commit/8fae34df055ecc90cce6324a8c9eb09112e21e31
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T16:22:43+02:00

Commit Message:
CGE2: Implement snRoom().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index d97ba3d..b152b61 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -246,7 +246,7 @@ public:
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
 	void snSound(Sprite *spr, int wav);
-	void snRoom(Sprite *spr, int val);
+	void snRoom(Sprite *spr, bool on);
 	void snDim(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
 	void snSay(Sprite *spr, int val);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 7ba0c36..284cecf 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -688,8 +688,27 @@ void CGE2Engine::snSound(Sprite *spr, int wav) {
 	_sound->setRepeat(1);
 }
 
-void CGE2Engine::snRoom(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snRoom()");
+void CGE2Engine::snRoom(Sprite *spr, bool on) {
+	if (!isHero(spr))
+		return;
+	int sx = spr->_ref & 1;
+	Sprite **p = _heroTab[sx]->_pocket;
+	if (on) {
+		if (freePockets(sx) == 0 && p[kPocketMax] == nullptr) {
+			SWAP(p[kPocketMax], p[kPocketMax - 1]);
+			snHide(p[kPocketMax], 1);
+		}
+	} else {
+		if (p[kPocketMax]) {
+			for (int i = 0; i < kPocketMax; i++) {
+				if (p[i] == nullptr) {
+					snHide(p[kPocketMax], 0);
+					SWAP(p[kPocketMax], p[i]);
+					break;
+				}
+			}
+		}
+	}
 }
 
 void CGE2Engine::snDim(Sprite *spr, int val) {


Commit: fbd8f2c390af8f73a138110450e4f2b98adffd49
    https://github.com/scummvm/scummvm/commit/fbd8f2c390af8f73a138110450e4f2b98adffd49
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-15T19:32:07+02:00

Commit Message:
CGE2: Some rework in snail

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 284cecf..84a0373 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -691,21 +691,20 @@ void CGE2Engine::snSound(Sprite *spr, int wav) {
 void CGE2Engine::snRoom(Sprite *spr, bool on) {
 	if (!isHero(spr))
 		return;
-	int sx = spr->_ref & 1;
-	Sprite **p = _heroTab[sx]->_pocket;
+
+	int sex = spr->_ref & 1;
+	Sprite **p = _heroTab[sex]->_pocket;
 	if (on) {
-		if (freePockets(sx) == 0 && p[kPocketMax] == nullptr) {
+		if (freePockets(sex) == 0 && p[kPocketMax] == nullptr) {
 			SWAP(p[kPocketMax], p[kPocketMax - 1]);
 			snHide(p[kPocketMax], 1);
 		}
-	} else {
-		if (p[kPocketMax]) {
-			for (int i = 0; i < kPocketMax; i++) {
-				if (p[i] == nullptr) {
-					snHide(p[kPocketMax], 0);
-					SWAP(p[kPocketMax], p[i]);
-					break;
-				}
+	} else if (p[kPocketMax]) {
+		for (int i = 0; i < kPocketMax; i++) {
+			if (p[i] == nullptr) {
+				snHide(p[kPocketMax], 0);
+				SWAP(p[kPocketMax], p[i]);
+				break;
 			}
 		}
 	}
@@ -715,7 +714,7 @@ void CGE2Engine::snDim(Sprite *spr, int val) {
 	if (isHero(spr)) {
 		if (val > 0)
 			++*(Hero*)spr;
-		if (val < 0)
+		else if (val < 0)
 			--*(Hero*)spr;
 	}
 }
@@ -951,7 +950,7 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 			}
 			if (c->_commandType == kCmdIf) {
 				Sprite *s = (c->_ref < 0) ? spr : _vga->_showQ->locate(c->_ref);
-				if (s) { // sprite extsts 
+				if (s) { // sprite exists 
 					if (!s->seqTest(-1)) { // not parked
 						int v = c->_val;
 						if (v > 255) if (s) v = s->labVal(snq, v >> 8);


Commit: 0b0f998aacb1d8804e8cdf2679df69966a643c41
    https://github.com/scummvm/scummvm/commit/0b0f998aacb1d8804e8cdf2679df69966a643c41
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T22:15:06+02:00

Commit Message:
CGE2: Try a different approach regarding _dim.

Now it doesn't crash the hospital scene, but I am not entirely sure it's totally leak-free...

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 6778118..0a72178 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -33,7 +33,11 @@ namespace CGE2 {
 
 Hero::Hero(CGE2Engine *vm)
 	: Sprite(vm), _contact(nullptr), _dir(kNoDir),
-      _curDim(0), _tracePtr(-1), _ignoreMap(false), _isDimLoaded(false) {
+      _curDim(0), _tracePtr(-1), _ignoreMap(false) {
+
+	for (int i = 0; i < kDimMax; i++) {
+		_dim[i] = nullptr;
+	}
 }
 
 Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
@@ -57,15 +61,18 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 		int cnt[kActions];
 		Seq *seq;
 		int section = kIdPhase;
-
-		if (!_isDimLoaded) {
-			for (int i = 0; i < kDimMax; i++) {
-				_dim[i] = new Bitmap[_shpCnt];
-				for (int j = 0; j < _shpCnt; j++)
-					_dim[i][j].setVM(_vm);
+	
+		for (int i = 0; i < kDimMax; i++) {
+			if (_dim[i] != nullptr) {
+				delete[] _dim[i];
+				_dim[i] = nullptr;
 			}
+		}
 
-			_isDimLoaded = true;
+		for (int i = 0; i < kDimMax; i++) {
+			_dim[i] = new Bitmap[_shpCnt];
+			for (int j = 0; j < _shpCnt; j++)
+				_dim[i][j].setVM(_vm);
 		}
 
 		if (_seqCnt) {
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index f45a652..e8cce71 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -62,7 +62,6 @@ struct HeroTab {
 };
 
 class Hero : public Sprite {
-	bool _isDimLoaded;
 	int _hig[kDimMax];
 	Sprite *_contact;
 public:


Commit: 7d6c02ce3f3e05b72538ca0b0a169dbf4868caef
    https://github.com/scummvm/scummvm/commit/7d6c02ce3f3e05b72538ca0b0a169dbf4868caef
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T23:12:58+02:00

Commit Message:
CGE2: Add Hero::contract().

Fix the crash introduced by previous commit on the second scene.

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 0a72178..cebfe73 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -207,6 +207,19 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 	return this;
 }
 
+Sprite *Hero::contract() {
+	for (int i = 0; i < kDimMax; i++) {
+		if (_dim[i] != nullptr) {
+			delete[] _dim[i];
+			if (_ext->_shpList == _dim[i])
+				_ext->_shpList = nullptr;
+			_dim[i] = nullptr;
+		}
+	}
+	Sprite::contract();
+	return this;
+}
+
 void Hero::setCurrent() {
 	FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
 	FXP tmp = m * _siz.y;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index e8cce71..c277b4a 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -77,6 +77,7 @@ public:
 	Hero(CGE2Engine *vm);
 	void tick();
 	Sprite *expand();
+	Sprite *contract();
 	Sprite *setContact();
 	int stepSize() { return _ext->_seq[7]._dx; }
 	int distance(V3D pos);


Commit: 20eb951b3acf2c1d0be588f9375d3a92184aceee
    https://github.com/scummvm/scummvm/commit/20eb951b3acf2c1d0be588f9375d3a92184aceee
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-15T23:54:07+02:00

Commit Message:
CGE2: Rework getText() so it works nicely with offUse().

Changed paths:
    engines/cge2/text.cpp



diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 9ebed58..9989dab 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -133,7 +133,7 @@ char *Text::getText(int ref) {
 		return _cache[i]._text;
 
 	warning("getText: Unable to find ref %d:%d", ref / 256, ref % 256);
-	return _cache[_txtCount - 1]._text;
+	return nullptr;
 }
 
 void Text::say(const char *text, Sprite *spr) {


Commit: a82bd2d9c600cd50fc29c3078f9f2d8c79ea18ff
    https://github.com/scummvm/scummvm/commit/a82bd2d9c600cd50fc29c3078f9f2d8c79ea18ff
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T15:18:55+02:00

Commit Message:
CGE2: Fix memory leak regarding Sprite::ghost().

uint8 *v = new uint8;
was the faulty line in Sprite::ghost(), and it should be released right here.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 84a0373..5c152f4 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -722,8 +722,8 @@ void CGE2Engine::snDim(Sprite *spr, int val) {
 void CGE2Engine::snGhost(Bitmap *bmp) {
 	V2D p(this, bmp->_map & 0xFFFF, bmp->_map >> 16);
 	bmp->hide(p);
+	bmp->release();
 	delete[] bmp->_b;
-	bmp->_v = nullptr;
 	bmp->_b = nullptr;
 	delete bmp;
 	bmp = nullptr;


Commit: d9e82f8f8e1db2f5a3b03a512643b46553bcc88a
    https://github.com/scummvm/scummvm/commit/d9e82f8f8e1db2f5a3b03a512643b46553bcc88a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T15:41:49+02:00

Commit Message:
CGE2: Get rid of _sprite.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index b820ba5..cddf833 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -45,7 +45,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	: Engine(syst), _gameDescription(gameDescription), _randomSource("cge") {
 	_resman = nullptr;
 	_vga = nullptr;
-	_sprite = nullptr;
 	_midiPlayer = nullptr;
 	_fx = nullptr;
 	_sound = nullptr;
@@ -142,7 +141,6 @@ void CGE2Engine::deinit() {
 		delete _eyeTab[i];
 	}
 	delete _eye;
-	delete _sprite;
 	delete _commandHandler;
 	delete _commandHandlerTurbo;
 	delete _font;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index b152b61..6f07102 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -152,7 +152,7 @@ public:
 	void initToolbar();
 	void loadHeroes();
 	void loadScript(const char *fname);
-	void loadSprite(const char *fname, int ref, int scene, V3D &pos);
+	Sprite *loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
 	void sceneUp(int cav);
 	void sceneDown();
@@ -289,7 +289,6 @@ public:
 
 	ResourceManager *_resman;
 	Vga *_vga;
-	Sprite *_sprite;
 	MusicPlayer *_midiPlayer;
 	Fx *_fx;
 	Sound *_sound;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d0a11643..d9fcbb2 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -156,7 +156,7 @@ void CGE2Engine::badLab(const char *fn) {
 	error("Misplaced label in %s!", fn);
 }
 
-void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
+Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 	int shpcnt = 0;
 	int seqcnt = 0;
 	int cnt[kActions];
@@ -275,40 +275,43 @@ void CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos) {
 		++shpcnt;
 
 	// Make sprite of choosen type:
+	Sprite *sprite = nullptr;
 	char c = *fname | 0x20;
 	if (c >= 'a' && c <= 'z' && fname[1] == '0' && fname[2] == '\0') {
 		h = new Hero(this);
 		if (h) {
 			h->gotoxyz(pos);
-			_sprite = h;
+			sprite = h;
 		}
 	} else {
-		_sprite = new Sprite(this);
-		if (_sprite)
-			_sprite->gotoxyz(pos);
+		sprite = new Sprite(this);
+		if (sprite)
+			sprite->gotoxyz(pos);
 	}
 
-	if (_sprite) {
-		_sprite->_ref = ref;
-		_sprite->_scene = scene;
+	if (sprite) {
+		sprite->_ref = ref;
+		sprite->_scene = scene;
 
-		_sprite->_flags._frnt = frnt;
-		_sprite->_flags._east = east;
-		_sprite->_flags._port = port;
-		_sprite->_flags._tran = tran;
-		_sprite->_flags._kill = true;
+		sprite->_flags._frnt = frnt;
+		sprite->_flags._east = east;
+		sprite->_flags._port = port;
+		sprite->_flags._tran = tran;
+		sprite->_flags._kill = true;
 
 		// Extract the filename, without the extension
-		Common::strlcpy(_sprite->_file, fname, sizeof(_sprite->_file));
-		char *p = strchr(_sprite->_file, '.');
+		Common::strlcpy(sprite->_file, fname, sizeof(sprite->_file));
+		char *p = strchr(sprite->_file, '.');
 		if (p)
 			*p = '\0';
 
-		_sprite->_shpCnt = shpcnt;
-		_sprite->_seqCnt = seqcnt;
+		sprite->_shpCnt = shpcnt;
+		sprite->_seqCnt = seqcnt;
 
 		for (int i = 0; i < kActions; i++)
-			_sprite->_actionCtrl[i]._cnt = cnt[i];
+			sprite->_actionCtrl[i]._cnt = cnt[i];
+
+		return sprite;
 	}
 }
 
@@ -360,16 +363,16 @@ void CGE2Engine::loadScript(const char *fname) {
 
 		ok = true; // no break: OK
 
-		_sprite = nullptr;
-		loadSprite(SpN, SpI, SpA, P);
-		if (_sprite) {
+		Sprite *sprite = loadSprite(SpN, SpI, SpA, P);
+		if (sprite) {
 			if (BkG)
-				_sprite->_flags._back = true;
+				sprite->_flags._back = true;
 
 			int n = _spare->count();
-			if (_spare->locate(_sprite->_ref) == nullptr)
-				_spare->dispose(_sprite);
-			_sprite = nullptr;
+			if (_spare->locate(sprite->_ref) == nullptr)
+				_spare->dispose(sprite);
+			else
+				delete sprite;
 			if (_spare->count() == n)
 				error("Durplicated reference! %s", SpN);
 		}
@@ -445,7 +448,6 @@ void CGE2Engine::sceneUp(int cav) {
 	_vga->copyPage(1, 0);
 	_vga->show();
 
-	_sprite = _vga->_showQ->first();
 	_vga->sunrise(_vga->_sysPal);
 
 	_dark = false;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 02d536c..ea82fb7 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -114,9 +114,6 @@ Sprite::Sprite(CGE2Engine *vm, BitmapPtr shpP, int cnt)
 }
 
 Sprite::~Sprite() {
-	if (_vm->_sprite == this)
-		_vm->_sprite = nullptr;
-
 	contract();
 }
 


Commit: 2203b7df8c6d212899d86bb7460526b670ad44f1
    https://github.com/scummvm/scummvm/commit/2203b7df8c6d212899d86bb7460526b670ad44f1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T16:41:32+02:00

Commit Message:
CGE2: Smaller revision regarding Spare.

Changed paths:
    engines/cge2/spare.cpp



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 93c8a26..756f937 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -73,11 +73,10 @@ Sprite *Spare::take(int ref) {
 		for (uint i = 0; i < _container.size(); ++i) {
 			if (spr == _container[i]) {
 				_container.remove_at(i);
-				break;
+				return spr;
 			}
 		}
 	}
-	return spr;
 }
 
 void Spare::takeScene(int cav) {
@@ -94,7 +93,7 @@ void Spare::takeScene(int cav) {
 }
 
 void Spare::store(Sprite *spr) {
-	_container.insert_at(_container.size(), spr);
+	_container.push_back(spr);
 }
 
 void Spare::update(Sprite *spr) {


Commit: 5e780d3d97cc992a0cdb46266dfddfdaa229d605
    https://github.com/scummvm/scummvm/commit/5e780d3d97cc992a0cdb46266dfddfdaa229d605
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T16:44:02+02:00

Commit Message:
CGE2: Use locate() instead of take() where possible.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d9fcbb2..9111a10 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -525,14 +525,13 @@ void CGE2Engine::storeHeroPos() {
 }
 
 void CGE2Engine::showBak(int ref) {
-	Sprite *spr = _spare->take(ref);
+	Sprite *spr = _spare->locate(ref);
 	if (spr != nullptr) {
 		_bitmapPalette = _vga->_sysPal;
 		spr->expand();
 		_bitmapPalette = nullptr;
 		spr->show(2);
 		_vga->copyPage(1, 2);
-		_spare->dispose(spr);
 	}
 }
 
@@ -712,10 +711,9 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 		_spare->update(h);
 	}
 	_heroTab[0]->_ptr = h;
-	s = _spare->take(152);
+	s = _spare->locate(152);
 	_vga->_showQ->insert(s);
 	_heroTab[0]->_face = s;
-	_spare->update(s);
 
 	// initialize Wacek/Vincent
 	s = _spare->take(141);
@@ -727,10 +725,9 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame()
 		_spare->update(h);
 	}
 	_heroTab[1]->_ptr = h;
-	s = _spare->take(151);
+	s = _spare->locate(151);
 	_vga->_showQ->insert(s);
 	_heroTab[1]->_face = s;
-	_spare->update(s);
 
 	//--- start!
 	switchHero(_sex);


Commit: 49cea2d927c4a9a278827e6c4d0877386bb327d2
    https://github.com/scummvm/scummvm/commit/49cea2d927c4a9a278827e6c4d0877386bb327d2
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T17:23:12+02:00

Commit Message:
CGE2: Initialize _wideSpace in InfoLine's constructor.

Changed paths:
    engines/cge2/talk.cpp



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 227e013..b086627 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -237,6 +237,7 @@ void Talk::update(const char *text) {
 
 InfoLine::InfoLine(CGE2Engine *vm, uint16 w, ColorBank color)
 : Talk(vm), _oldText(nullptr), _newText(nullptr), _realTime(false), _vm(vm) {
+	_wideSpace = false;
 	BitmapPtr b = new Bitmap[1];
 	if (color == kCBRel)
 		_vm->setAutoColors();


Commit: 5963a540ef161e804f756d54970b2c7cb55fcc00
    https://github.com/scummvm/scummvm/commit/5963a540ef161e804f756d54970b2c7cb55fcc00
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T17:33:04+02:00

Commit Message:
CGE2: Add destructor to Hero().

Hopefully it will cut short the leak problems with _dim[].

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/hero.h



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index cebfe73..c9b8dc5 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -40,6 +40,10 @@ Hero::Hero(CGE2Engine *vm)
 	}
 }
 
+Hero::~Hero() {
+	contract();
+}
+
 Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
 	if (_ext)
 		return this;
diff --git a/engines/cge2/hero.h b/engines/cge2/hero.h
index c277b4a..3b5329e 100644
--- a/engines/cge2/hero.h
+++ b/engines/cge2/hero.h
@@ -75,6 +75,7 @@ public:
 	int _maxDist;
 	bool _ignoreMap;
 	Hero(CGE2Engine *vm);
+	~Hero();
 	void tick();
 	Sprite *expand();
 	Sprite *contract();


Commit: f3345f296f992ec2766fe9e9687f9997b0c34c6f
    https://github.com/scummvm/scummvm/commit/f3345f296f992ec2766fe9e9687f9997b0c34c6f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-17T20:50:16+02:00

Commit Message:
CGE2: Use locate instead() of take() in CGE2Eninge::locate().

It fixes the regression with the hole of the sign post on the ground from scene 6 and the display bug in the hospital.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9111a10..e0cd688 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -580,7 +580,7 @@ Sprite *CGE2Engine::locate(int ref) {
 	_taken = false;
 	Sprite *spr = _vga->_showQ->locate(ref);
 	if (!spr) {
-		spr = _spare->take(ref);
+		spr = _spare->locate(ref);
 		if (spr)
 			_taken = true;
 	}


Commit: c285d3299c2c87f6d5c6279e7ebcb65274024b9b
    https://github.com/scummvm/scummvm/commit/c285d3299c2c87f6d5c6279e7ebcb65274024b9b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-18T00:12:53+02:00

Commit Message:
CGE2: Silence GCC warnings.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e0cd688..938ad84 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -310,9 +310,9 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 
 		for (int i = 0; i < kActions; i++)
 			sprite->_actionCtrl[i]._cnt = cnt[i];
-
-		return sprite;
 	}
+
+	return sprite;
 }
 
 void CGE2Engine::loadScript(const char *fname) {
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 756f937..411327e 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -73,10 +73,11 @@ Sprite *Spare::take(int ref) {
 		for (uint i = 0; i < _container.size(); ++i) {
 			if (spr == _container[i]) {
 				_container.remove_at(i);
-				return spr;
+				break;
 			}
 		}
 	}
+	return spr;
 }
 
 void Spare::takeScene(int cav) {


Commit: db9e503cfcca7096a1260c96ed24aef3dc4ed450
    https://github.com/scummvm/scummvm/commit/db9e503cfcca7096a1260c96ed24aef3dc4ed450
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-18T02:26:13+02:00

Commit Message:
CGE2: Rework snSetRef().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 5c152f4..1361c64 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -629,10 +629,9 @@ void CGE2Engine::snFlag(int ref, int val) {
 	warning("STUB: CGE2Engine::snFlag()");
 }
 
-void CGE2Engine::snSetRef(Sprite *spr, int val) { // TODO:: Recheck this!
+void CGE2Engine::snSetRef(Sprite *spr, int val) {
 	if (spr) {
 		spr->_ref = val;
-		_spare->update(spr);
 	}
 }
 


Commit: 1176721034b07ddc6517e0a8b96c5eedb0b57e08
    https://github.com/scummvm/scummvm/commit/1176721034b07ddc6517e0a8b96c5eedb0b57e08
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-21T19:52:46+02:00

Commit Message:
CGE2: Fix the issue of loading sprites with changed _ref.

It fixes the problem with the multiply displayed Vulcanizer after giving him the glasses/basket ball, then saving and loading.

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 411327e..54918f7 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -47,7 +47,17 @@ void Spare::sync(Common::Serializer &s) {
 		for (int i = 0; i < size; i++) {
 			Sprite *sprite = new Sprite(_vm);
 			sprite->sync(s);
-			update(sprite);
+
+			// In case the reference of the sprite is changed comapred to CGE.INI
+			// TODO: Rework the whole loading so it doesn't load every sprite from CGE.INI
+			// and then update them, but load everything from file, so this check isn't
+			// needed anymore. To do that, I also have to save/load the toolbar's sprites too.
+			Sprite *loc = locate(sprite->_file);
+			if (loc->_ref != sprite->_ref) {
+				loc->contract();
+				*loc = *sprite;
+			} else
+				update(sprite);
 		}
 	}
 }
@@ -67,6 +77,14 @@ Sprite *Spare::locate(int ref) {
 	return nullptr;
 }
 
+Sprite *Spare::locate(char *file) {
+	for (uint i = 0; i < _container.size(); ++i) {
+		if (strcmp(_container[i]->_file, file) == 0)
+			return _container[i];
+	}
+	return nullptr;
+}
+
 Sprite *Spare::take(int ref) {
 	Sprite *spr = nullptr;
 	if ((spr = locate(ref)) != nullptr) {
@@ -101,8 +119,10 @@ void Spare::update(Sprite *spr) {
 	Sprite *sp = locate(spr->_ref);
 	if (sp == nullptr)
 		store(spr);
-	else
+	else {
+		sp->contract();
 		*sp = *spr;
+	}
 }
 
 void Spare::dispose(Sprite *spr) {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index 7dc6ce6..cfc158d 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -40,6 +40,7 @@ public:
 	~Spare() { clear(); }
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
+	Sprite *locate(char *file);
 	Sprite *take(int ref);
 	void takeScene(int cav);
 	void update(Sprite *spr);


Commit: 6e26422468b8667c86219069cea25466370656e1
    https://github.com/scummvm/scummvm/commit/6e26422468b8667c86219069cea25466370656e1
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-21T19:57:33+02:00

Commit Message:
CGE2: Rework loading of sprites from file.

Now it satisfies the needs described in the last commit's TODO comment.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp
    engines/cge2/spare.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 6f07102..cd3a566 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -151,7 +151,7 @@ public:
 	void runGame();
 	void initToolbar();
 	void loadHeroes();
-	void loadScript(const char *fname);
+	void loadScript(const char *fname, bool onlyToolbar = false);
 	Sprite *loadSprite(const char *fname, int ref, int scene, V3D &pos);
 	void badLab(const char *fn);
 	void sceneUp(int cav);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 938ad84..51d9816 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -315,7 +315,7 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 	return sprite;
 }
 
-void CGE2Engine::loadScript(const char *fname) {
+void CGE2Engine::loadScript(const char *fname, bool onlyToolbar) {
 	EncryptedStream scrf(this, fname);
 
 	if (scrf.err())
@@ -341,6 +341,9 @@ void CGE2Engine::loadScript(const char *fname) {
 		// sprite ident number
 		int SpI = number(tmpStr);
 
+		if (onlyToolbar && SpI >= 141)
+			return;
+
 		// sprite file name
 		char *SpN;
 		if ((SpN = token(nullptr)) == nullptr)
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 3890e74..b9a856f 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -323,7 +323,7 @@ void CGE2Engine::resetGame() {
 	_spare->clear();
 	_vga->_showQ->clear();
 	_commandHandler->reset();
-	loadScript("CGE.INI");
+	loadScript("CGE.INI", true);
 	delete _infoLine;
 	_infoLine = new InfoLine(this, kInfoW);
 }
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 54918f7..547d070 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -47,17 +47,7 @@ void Spare::sync(Common::Serializer &s) {
 		for (int i = 0; i < size; i++) {
 			Sprite *sprite = new Sprite(_vm);
 			sprite->sync(s);
-
-			// In case the reference of the sprite is changed comapred to CGE.INI
-			// TODO: Rework the whole loading so it doesn't load every sprite from CGE.INI
-			// and then update them, but load everything from file, so this check isn't
-			// needed anymore. To do that, I also have to save/load the toolbar's sprites too.
-			Sprite *loc = locate(sprite->_file);
-			if (loc->_ref != sprite->_ref) {
-				loc->contract();
-				*loc = *sprite;
-			} else
-				update(sprite);
+			update(sprite);
 		}
 	}
 }


Commit: bac952917ffb4901ad03e67a6ba65f74e65ec5e4
    https://github.com/scummvm/scummvm/commit/bac952917ffb4901ad03e67a6ba65f74e65ec5e4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-21T20:20:33+02:00

Commit Message:
CGE2: Remove Spare::locate(char *file), since it's not used anymore.

Changed paths:
    engines/cge2/spare.cpp
    engines/cge2/spare.h



diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 547d070..4ca2900 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -67,14 +67,6 @@ Sprite *Spare::locate(int ref) {
 	return nullptr;
 }
 
-Sprite *Spare::locate(char *file) {
-	for (uint i = 0; i < _container.size(); ++i) {
-		if (strcmp(_container[i]->_file, file) == 0)
-			return _container[i];
-	}
-	return nullptr;
-}
-
 Sprite *Spare::take(int ref) {
 	Sprite *spr = nullptr;
 	if ((spr = locate(ref)) != nullptr) {
diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h
index cfc158d..7dc6ce6 100644
--- a/engines/cge2/spare.h
+++ b/engines/cge2/spare.h
@@ -40,7 +40,6 @@ public:
 	~Spare() { clear(); }
 	void store(Sprite *spr);	
 	Sprite *locate(int ref);
-	Sprite *locate(char *file);
 	Sprite *take(int ref);
 	void takeScene(int cav);
 	void update(Sprite *spr);


Commit: 77b5c7e4adea3485a8c3cfb215eca4471deae443
    https://github.com/scummvm/scummvm/commit/77b5c7e4adea3485a8c3cfb215eca4471deae443
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T15:41:33+02:00

Commit Message:
CGE2: Rename _commandStat to _soundStat.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index cddf833..e247cf5 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -83,9 +83,9 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_lastTick = 0;
 	_waitSeq = 0;
 	_waitRef = 0;
-	_commandStat._wait = nullptr;
-	_commandStat._ref[0] = 0;
-	_commandStat._ref[1] = 0;
+	_soundStat._wait = nullptr;
+	_soundStat._ref[0] = 0;
+	_soundStat._ref[1] = 0;
 	_taken = false;
 	_endGame = false;
 	for (int i = 0; i < 4; i++)
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index cd3a566..48d9bc8 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -271,10 +271,10 @@ public:
 	bool _dark;
 	int _waitSeq;
 	int _waitRef;
-	struct CommandStat {
+	struct {
 		int *_wait;
 		int _ref[2];
-	} _commandStat;
+	} _soundStat;
 	bool _taken;
 	bool _endGame;
 	bool _flag[4];
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 51d9816..f887bdc 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -463,7 +463,7 @@ void CGE2Engine::sceneUp(int cav) {
 
 void CGE2Engine::sceneDown() {
 	busy(true);
-	_commandStat._wait = nullptr; // unlock snail
+	_soundStat._wait = nullptr; // unlock snail
 	Sprite *spr = _vga->_showQ->locate((_now << 8) | 254);
 	if (spr)
 		feedSnail(spr, kNear, _heroTab[_sex]->_ptr);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 1361c64..cee4531 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -67,13 +67,13 @@ CommandHandler::~CommandHandler() {
 }
 
 void CommandHandler::runCommand() {
-	if (!_turbo && _vm->_commandStat._wait) {
-		if (*(_vm->_commandStat._wait))
+	if (!_turbo && _vm->_soundStat._wait) {
+		if (*(_vm->_soundStat._wait))
 			return;
 		else {
-			++_vm->_commandStat._ref[0];
+			++_vm->_soundStat._ref[0];
 			warning("STUB: CommandHandler::runCommand() - Sound code missing!");
-			_vm->_commandStat._wait = nullptr;
+			_vm->_soundStat._wait = nullptr;
 		}
 	}
 
@@ -675,12 +675,12 @@ void CGE2Engine::snSound(Sprite *spr, int wav) {
 	else {
 		if (_sound->_smpinf._counter && wav < 20)
 			return;
-		if (_commandStat._wait && ((wav & 255) > 80))
+		if (_soundStat._wait && ((wav & 255) > 80))
 			return;
 
-		_commandStat._ref[1] = wav;
-		_commandStat._ref[0] = !_fx->exist(_commandStat._ref[1]);
-		_sound->play(_fx->load(_commandStat._ref[1], _commandStat._ref[0]),
+		_soundStat._ref[1] = wav;
+		_soundStat._ref[0] = !_fx->exist(_soundStat._ref[1]);
+		_sound->play(_fx->load(_soundStat._ref[1], _soundStat._ref[0]),
 			(spr) ? (spr->_pos2D.x / (kScrWidth / 16)) : 8);
 	}
 


Commit: e261886d92ea3c173d0e3a38cce73ac2b6d54c3f
    https://github.com/scummvm/scummvm/commit/e261886d92ea3c173d0e3a38cce73ac2b6d54c3f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T17:59:16+02:00

Commit Message:
CGE2: Fix snSound().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index cee4531..c8b1722 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -286,6 +286,7 @@ void CommandHandler::runCommand() {
 			break;
 		case kCmdSound:
 			_vm->snSound(spr, tailCmd._val);
+			_sound->setRepeat(1);
 			break;
 		case kCmdMap:
 			_vm->_heroTab[tailCmd._ref & 1]->_ptr->_ignoreMap = tailCmd._val == 0;
@@ -683,8 +684,6 @@ void CGE2Engine::snSound(Sprite *spr, int wav) {
 		_sound->play(_fx->load(_soundStat._ref[1], _soundStat._ref[0]),
 			(spr) ? (spr->_pos2D.x / (kScrWidth / 16)) : 8);
 	}
-
-	_sound->setRepeat(1);
 }
 
 void CGE2Engine::snRoom(Sprite *spr, bool on) {


Commit: 2f19de9ebe1d62d3bb6f93a121c68e52337a179f
    https://github.com/scummvm/scummvm/commit/2f19de9ebe1d62d3bb6f93a121c68e52337a179f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T18:01:37+02:00

Commit Message:
CGE2: Fix error introduced by previous commit.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index c8b1722..8cb8d19 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -286,7 +286,7 @@ void CommandHandler::runCommand() {
 			break;
 		case kCmdSound:
 			_vm->snSound(spr, tailCmd._val);
-			_sound->setRepeat(1);
+			_vm->_sound->setRepeat(1);
 			break;
 		case kCmdMap:
 			_vm->_heroTab[tailCmd._ref & 1]->_ptr->_ignoreMap = tailCmd._val == 0;


Commit: def6b4fc3e38392c8345af9945cb3a1d208a7726
    https://github.com/scummvm/scummvm/commit/def6b4fc3e38392c8345af9945cb3a1d208a7726
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T18:54:48+02:00

Commit Message:
CGE2: Add and use Sound::checkSoundHandle().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/snail.cpp
    engines/cge2/sound.cpp
    engines/cge2/sound.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f887bdc..f8fa274 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -551,6 +551,8 @@ void CGE2Engine::mainLoop() {
 
 	// Check shouldQuit()
 	_quitFlag = shouldQuit();
+
+	_sound->checkSoundHandle();
 }
 
 void CGE2Engine::handleFrame() {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 8cb8d19..9dce4db 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -742,10 +742,7 @@ void CGE2Engine::snSay(Sprite *spr, int val) {
 			_sound->setRepeat(1);
 			snSound(spr, i);
 			_sound->setRepeat(oldRepeat);
-			//_commandStat._wait = &_sound->_smpinf._counter;
-			// This line is commented out for now since I wasn't able to find where this flag is reset
-			// and it's prevented the main loop from doing anything.
-			// TODO: Recheck this later! At the moment it seems working fine.
+			_soundStat._wait = &_sound->_smpinf._counter;
 		}
 	}
 }
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index b7b39d2..7e886e5 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -106,6 +106,11 @@ void Sound::stop() {
 	sndDigiStop(&_smpinf);
 }
 
+void Sound::checkSoundHandle() {
+	if (!_vm->_mixer->isSoundHandleActive(_soundHandle))
+		_smpinf._counter = 0;
+}
+
 void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
 	if (_vm->_mixer->isSoundHandleActive(_soundHandle))
 		_vm->_mixer->stopHandle(_soundHandle);
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
index 6fa2b2a..e2e9482 100644
--- a/engines/cge2/sound.h
+++ b/engines/cge2/sound.h
@@ -76,6 +76,7 @@ public:
 	int16 getRepeat();
 	void setRepeat(int16 count);
 	void stop();
+	void checkSoundHandle();
 private:
 	int _soundRepeatCount;
 	CGE2Engine *_vm;


Commit: aa6b4601d766f775e97c1b38332948a2a6a2c3e0
    https://github.com/scummvm/scummvm/commit/aa6b4601d766f775e97c1b38332948a2a6a2c3e0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T18:59:22+02:00

Commit Message:
CGE2: Change call order of checkSoundHandle().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f8fa274..353abb8 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -539,6 +539,8 @@ void CGE2Engine::showBak(int ref) {
 }
 
 void CGE2Engine::mainLoop() {
+	_sound->checkSoundHandle();
+
 	_vga->show();
 	_commandHandlerTurbo->runCommand();
 	_commandHandler->runCommand();
@@ -551,8 +553,6 @@ void CGE2Engine::mainLoop() {
 
 	// Check shouldQuit()
 	_quitFlag = shouldQuit();
-
-	_sound->checkSoundHandle();
 }
 
 void CGE2Engine::handleFrame() {


Commit: 848b2650e9427739b79e8b8c6c46f0501d6c3f18
    https://github.com/scummvm/scummvm/commit/848b2650e9427739b79e8b8c6c46f0501d6c3f18
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T19:07:56+02:00

Commit Message:
CGE2: Unstub CommandHandler::runCommand().

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 9dce4db..f6c6e2d 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -72,7 +72,13 @@ void CommandHandler::runCommand() {
 			return;
 		else {
 			++_vm->_soundStat._ref[0];
-			warning("STUB: CommandHandler::runCommand() - Sound code missing!");
+			if (_vm->_fx->exist(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0])) {
+				int16 oldRepeat = _vm->_sound->getRepeat();
+				_vm->_sound->setRepeat(1);
+				_vm->_sound->play(_vm->_fx->load(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0]), _vm->_sound->_smpinf._span);
+				_vm->_sound->setRepeat(oldRepeat);
+				return;
+			}
 			_vm->_soundStat._wait = nullptr;
 		}
 	}


Commit: 49f68a89132590ec5ef261451884249721de636b
    https://github.com/scummvm/scummvm/commit/49f68a89132590ec5ef261451884249721de636b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-22T20:25:21+02:00

Commit Message:
CGE2: Reimplement checkSaySwitch().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index e247cf5..30529d9 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -92,6 +92,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_flag[i] = false;
 	_sayCap = true;
 	_sayVox = true;
+	_oldSayVox = false;
 	_req = 1;
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
@@ -164,6 +165,7 @@ bool CGE2Engine::hasFeature(EngineFeature f) const {
 }
 
 Common::Error CGE2Engine::run() {
+	syncSoundSettings();
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 48d9bc8..dbde43a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -280,6 +280,7 @@ public:
 	bool _flag[4];
 	bool _sayCap;
 	bool _sayVox;
+	bool _oldSayVox;
 	int _req;
 	NotifyFunctionType _midiNotify;
 	NotifyFunctionType _spriteNotify;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 353abb8..65c5a74 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -26,6 +26,7 @@
  */
 
 #include "sound.h"
+#include "common/config-manager.h"
 #include "cge2/cge2_main.h"
 #include "cge2/cge2.h"
 #include "cge2/vga13h.h"
@@ -540,6 +541,7 @@ void CGE2Engine::showBak(int ref) {
 
 void CGE2Engine::mainLoop() {
 	_sound->checkSoundHandle();
+	checkSaySwitch();
 
 	_vga->show();
 	_commandHandlerTurbo->runCommand();
@@ -766,7 +768,7 @@ void CGE2Engine::initToolbar() {
 	if (!_music)
 		_midiPlayer->killMidi();
 
-	checkSaySwitch();
+	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr); // Sets the speech caption switch on.
 
 	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
 	_infoLine->setText(nullptr);
@@ -807,11 +809,24 @@ void CGE2Engine::releasePocket(Sprite *spr) {
 }
 
 void CGE2Engine::checkSaySwitch() {
-	warning("STUB: CGE2Engine::checkSaySwitch()");
-//	if (SNDDrvInfo.DDEV == DEV_QUIET)
-//		_sayVox = !(_sayCap = true);
-	_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
-	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
+	bool mute = false;
+	if (ConfMan.hasKey("mute"))
+		mute = ConfMan.getBool("mute");
+	bool speechMute = mute;
+	if (!speechMute)
+		speechMute = ConfMan.getBool("speech_mute");
+
+	if (mute || speechMute) {
+		_sayVox = false;
+		_sayCap = true;
+	}
+
+	if (_oldSayVox != _sayVox) {
+		_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
+		_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
+	}
+		
+	_oldSayVox = _sayVox;
 }
 
 void CGE2Engine::loadTab() {


Commit: 93b8f101c363e4e0b8bd8e27b504e8b037ae0aa3
    https://github.com/scummvm/scummvm/commit/93b8f101c363e4e0b8bd8e27b504e8b037ae0aa3
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T09:28:57+02:00

Commit Message:
CGE2: Implement switchMusic():

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 65c5a74..f5587e1 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1104,7 +1104,9 @@ void CGE2Engine::switchColorMode() {
 }
 
 void CGE2Engine::switchMusic() {
-	warning("STUB: CGE2Engine::switchMusic()");
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, (_music = !_music), nullptr);
+	keyClick();
+	_commandHandlerTurbo->addCommand(kCmdMidi, -1, (_music) ? (_now << 8) : -1, nullptr);
 }
 
 void CGE2Engine::quit() {


Commit: 2f5e115e9a3b1a8cde9f17dade63b2ce1d0fa52d
    https://github.com/scummvm/scummvm/commit/2f5e115e9a3b1a8cde9f17dade63b2ce1d0fa52d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T09:29:24+02:00

Commit Message:
CGE2: Use nullptr instead of NULL in switchColorMode().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f5587e1..00b3add 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -1098,7 +1098,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 }
 
 void CGE2Engine::switchColorMode() {
-	_commandHandlerTurbo->addCommand(kCmdSeq, 121, _vga->_mono = !_vga->_mono, NULL);
+	_commandHandlerTurbo->addCommand(kCmdSeq, 121, _vga->_mono = !_vga->_mono, nullptr);
 	keyClick();
 	_vga->setColors(_vga->_sysPal, 64);
 }


Commit: 71a9ead967180344310f28b329158cd5e812be31
    https://github.com/scummvm/scummvm/commit/71a9ead967180344310f28b329158cd5e812be31
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T09:52:05+02:00

Commit Message:
CGE2: Add and implement checkSounds() and checkMusicSwitch().

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 30529d9..b6e406c 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -74,6 +74,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_music = true;
+	_musicMuted = false;
 	_startupMode = 1;
 	_now = 1;
 	_sex = 1;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index dbde43a..df4e4f7 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -190,6 +190,8 @@ public:
 	void keyClick();
 	void swapInPocket(Sprite *spr, Sprite *xspr);
 	void busyStep();
+	void checkSounds();
+	void checkMusicSwitch();
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
@@ -264,6 +266,7 @@ public:
 	bool _quitFlag;
 	Dac *_bitmapPalette;
 	bool _music;
+	bool _musicMuted;
 	int _startupMode;
 	int _now;
 	int _sex;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 00b3add..37821fb 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -540,8 +540,7 @@ void CGE2Engine::showBak(int ref) {
 }
 
 void CGE2Engine::mainLoop() {
-	_sound->checkSoundHandle();
-	checkSaySwitch();
+	checkSounds();
 
 	_vga->show();
 	_commandHandlerTurbo->runCommand();
@@ -557,6 +556,25 @@ void CGE2Engine::mainLoop() {
 	_quitFlag = shouldQuit();
 }
 
+void CGE2Engine::checkSounds() {
+	_sound->checkSoundHandle();
+	checkSaySwitch();
+	checkMusicSwitch();
+}
+
+void CGE2Engine::checkMusicSwitch() {
+	bool mute = false;
+	if (ConfMan.hasKey("mute"))
+		mute = ConfMan.getBool("mute");
+	_musicMuted = mute;
+	int musicVolume = ConfMan.getInt("music_volume");
+	if (!_musicMuted)
+		_musicMuted = musicVolume == 0;
+
+	if (_musicMuted && _music)
+		switchMusic();
+}
+
 void CGE2Engine::handleFrame() {
 	// Game frame delay
 	uint32 millis = g_system->getMillis();
@@ -1069,7 +1087,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchColorMode();
 		break;
 	case 2:
-		if (mask & kMouseLeftUp)
+		if ((mask & kMouseLeftUp) && !_musicMuted)
 			switchMusic();
 		break;
 	case 3:


Commit: b15b1043f91996c5213d7f1b5aa46202703a572b
    https://github.com/scummvm/scummvm/commit/b15b1043f91996c5213d7f1b5aa46202703a572b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T10:00:03+02:00

Commit Message:
CGE2: Updgrade checkSaySwitch().

Now it takes into account the "Speech volume" option in the Launcher and it only plays the keyClick() sound if the button is really switched, not every time it's clicked.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 37821fb..4d38b10 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -833,6 +833,10 @@ void CGE2Engine::checkSaySwitch() {
 	bool speechMute = mute;
 	if (!speechMute)
 		speechMute = ConfMan.getBool("speech_mute");
+	if (!speechMute) {
+		int speechVolume = ConfMan.getInt("speech_volume");
+		speechMute = speechVolume == 0;
+	}
 
 	if (mute || speechMute) {
 		_sayVox = false;
@@ -842,6 +846,7 @@ void CGE2Engine::checkSaySwitch() {
 	if (_oldSayVox != _sayVox) {
 		_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
 		_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
+		keyClick();
 	}
 		
 	_oldSayVox = _sayVox;
@@ -1160,7 +1165,6 @@ void CGE2Engine::switchCap() {
 		_sayCap = !_sayCap;
 		if (!_sayCap)
 			_sayVox = true;
-		keyClick();
 		checkSaySwitch();
 	}
 }
@@ -1170,7 +1174,6 @@ void CGE2Engine::switchVox() {
 		_sayVox = !_sayVox;
 		if (!_sayVox)
 			_sayCap = true;
-		keyClick();
 		checkSaySwitch();
 	}
 }


Commit: 4c3bd3e0f51d20019d0cfe237f23b3a0f237cf0e
    https://github.com/scummvm/scummvm/commit/4c3bd3e0f51d20019d0cfe237f23b3a0f237cf0e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T10:09:27+02:00

Commit Message:
CGE2: Add MidiPlayer::syncVolume() call to checkSounds().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 4d38b10..8341f8a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -560,6 +560,7 @@ void CGE2Engine::checkSounds() {
 	_sound->checkSoundHandle();
 	checkSaySwitch();
 	checkMusicSwitch();
+	_midiPlayer->syncVolume();
 }
 
 void CGE2Engine::checkMusicSwitch() {


Commit: 6336ddb3ce4a9b2b42fc53985bad2e6a69012188
    https://github.com/scummvm/scummvm/commit/6336ddb3ce4a9b2b42fc53985bad2e6a69012188
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T12:31:06+02:00

Commit Message:
CGE2: Keep music setting in sync with the Launcher.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index b6e406c..916b12f 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -75,6 +75,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_bitmapPalette = nullptr;
 	_music = true;
 	_musicMuted = false;
+	_oldMusicVolume = ConfMan.getInt("music_volume");;
 	_startupMode = 1;
 	_now = 1;
 	_sex = 1;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index df4e4f7..0c5ab4d 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -195,7 +195,7 @@ public:
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
-	void switchMusic();
+	void switchMusic(bool on);
 	void quit();
 	void setVolume(int idx, int cnt);
 	void switchCap();
@@ -267,6 +267,7 @@ public:
 	Dac *_bitmapPalette;
 	bool _music;
 	bool _musicMuted;
+	int _oldMusicVolume;
 	int _startupMode;
 	int _now;
 	int _sex;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 8341f8a..a22df8d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -571,9 +571,14 @@ void CGE2Engine::checkMusicSwitch() {
 	int musicVolume = ConfMan.getInt("music_volume");
 	if (!_musicMuted)
 		_musicMuted = musicVolume == 0;
-
-	if (_musicMuted && _music)
-		switchMusic();
+	
+	if (!_musicMuted && !_music) {
+		_oldMusicVolume = musicVolume;
+		switchMusic(_music = true);
+	}
+	if (_musicMuted && _music) {
+		switchMusic(_music = false);
+	}
 }
 
 void CGE2Engine::handleFrame() {
@@ -1093,8 +1098,8 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchColorMode();
 		break;
 	case 2:
-		if ((mask & kMouseLeftUp) && !_musicMuted)
-			switchMusic();
+		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute"))
+			switchMusic(_music = !_music);
 		break;
 	case 3:
 		if (mask & kMouseLeftUp)
@@ -1127,10 +1132,18 @@ void CGE2Engine::switchColorMode() {
 	_vga->setColors(_vga->_sysPal, 64);
 }
 
-void CGE2Engine::switchMusic() {
-	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, (_music = !_music), nullptr);
+void CGE2Engine::switchMusic(bool on) {
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
 	keyClick();
-	_commandHandlerTurbo->addCommand(kCmdMidi, -1, (_music) ? (_now << 8) : -1, nullptr);
+	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
+
+	if (!on) {
+		if (!_musicMuted) {
+			_oldMusicVolume = ConfMan.getInt("music_volume");
+			ConfMan.setInt("music_volume", 0);
+		}
+	} else
+		ConfMan.setInt("music_volume", _oldMusicVolume);
 }
 
 void CGE2Engine::quit() {


Commit: 014b734c984c6e7d09ce6924d5e216525cffab5c
    https://github.com/scummvm/scummvm/commit/014b734c984c6e7d09ce6924d5e216525cffab5c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T14:24:06+02:00

Commit Message:
CGE2: Increase readability of code connected to music switch.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 916b12f..55ac835 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -74,7 +74,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_music = true;
-	_musicMuted = false;
 	_oldMusicVolume = ConfMan.getInt("music_volume");;
 	_startupMode = 1;
 	_now = 1;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 0c5ab4d..b7b2dd3 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -266,7 +266,6 @@ public:
 	bool _quitFlag;
 	Dac *_bitmapPalette;
 	bool _music;
-	bool _musicMuted;
 	int _oldMusicVolume;
 	int _startupMode;
 	int _now;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a22df8d..10e9bb9 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -567,16 +567,15 @@ void CGE2Engine::checkMusicSwitch() {
 	bool mute = false;
 	if (ConfMan.hasKey("mute"))
 		mute = ConfMan.getBool("mute");
-	_musicMuted = mute;
+	bool musicMuted = mute;
 	int musicVolume = ConfMan.getInt("music_volume");
-	if (!_musicMuted)
-		_musicMuted = musicVolume == 0;
-	
-	if (!_musicMuted && !_music) {
-		_oldMusicVolume = musicVolume;
+	if (!musicMuted)
+		musicMuted = musicVolume == 0;
+
+	if (!musicMuted && !_music) {
 		switchMusic(_music = true);
 	}
-	if (_musicMuted && _music) {
+	if (musicMuted && _music) {
 		switchMusic(_music = false);
 	}
 }
@@ -1098,8 +1097,21 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchColorMode();
 		break;
 	case 2:
-		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute"))
+		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute")) {
 			switchMusic(_music = !_music);
+
+			switch (_music) {
+			case false:
+				_oldMusicVolume = ConfMan.getInt("music_volume");
+				ConfMan.setInt("music_volume", 0);
+				break;
+			case true:
+				ConfMan.setInt("music_volume", _oldMusicVolume);
+				break;
+			default:
+				break;
+			}
+		}
 		break;
 	case 3:
 		if (mask & kMouseLeftUp)
@@ -1136,14 +1148,6 @@ void CGE2Engine::switchMusic(bool on) {
 	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
 	keyClick();
 	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
-
-	if (!on) {
-		if (!_musicMuted) {
-			_oldMusicVolume = ConfMan.getInt("music_volume");
-			ConfMan.setInt("music_volume", 0);
-		}
-	} else
-		ConfMan.setInt("music_volume", _oldMusicVolume);
 }
 
 void CGE2Engine::quit() {


Commit: cd8b7c0d15ab6dd190a21ed2bc785959a077332d
    https://github.com/scummvm/scummvm/commit/cd8b7c0d15ab6dd190a21ed2bc785959a077332d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T14:47:43+02:00

Commit Message:
CGE2: Move toolbar's functions from cge2_main.cpp to toolbar.cpp.

Changed paths:
  A engines/cge2/toolbar.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 10e9bb9..ecc741e 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -26,7 +26,6 @@
  */
 
 #include "sound.h"
-#include "common/config-manager.h"
 #include "cge2/cge2_main.h"
 #include "cge2/cge2.h"
 #include "cge2/vga13h.h"
@@ -34,9 +33,7 @@
 #include "cge2/snail.h"
 #include "cge2/hero.h"
 #include "cge2/spare.h"
-#include "cge2/events.h"
 #include "cge2/map.h"
-#include "cge2/vmenu.h"
 
 namespace CGE2 {
 
@@ -563,23 +560,6 @@ void CGE2Engine::checkSounds() {
 	_midiPlayer->syncVolume();
 }
 
-void CGE2Engine::checkMusicSwitch() {
-	bool mute = false;
-	if (ConfMan.hasKey("mute"))
-		mute = ConfMan.getBool("mute");
-	bool musicMuted = mute;
-	int musicVolume = ConfMan.getInt("music_volume");
-	if (!musicMuted)
-		musicMuted = musicVolume == 0;
-
-	if (!musicMuted && !_music) {
-		switchMusic(_music = true);
-	}
-	if (musicMuted && _music) {
-		switchMusic(_music = false);
-	}
-}
-
 void CGE2Engine::handleFrame() {
 	// Game frame delay
 	uint32 millis = g_system->getMillis();
@@ -657,7 +637,6 @@ void CGE2Engine::closePocket() {
 	}
 }
 
-
 void CGE2Engine::selectPocket(int n) {
 	Sprite **p = _heroTab[_sex]->_pocket;
 	int &pp = _heroTab[_sex]->_pocPtr;
@@ -784,40 +763,6 @@ void CGE2Engine::loadPos() {
 		error("Missing file: CGE.HXY");
 }
 
-void CGE2Engine::initToolbar() {
-	selectPocket(-1);
-
-	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, _music, nullptr);
-	if (!_music)
-		_midiPlayer->killMidi();
-
-	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr); // Sets the speech caption switch on.
-
-	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
-	_infoLine->setText(nullptr);
-	_vga->_showQ->insert(_infoLine);
-
-	_startupMode = 0;
-	_mouse->center();
-	_mouse->off();
-	_mouse->on();
-
-	_keyboard->setClient(_sys);
-	_commandHandler->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
-
-	_busyPtr = _vga->_showQ->locate(kBusyRef);
-
-	_vol[0] = _vga->_showQ->locate(kDvolRef);
-	_vol[1] = _vga->_showQ->locate(kMvolRef);
-
-	// these sprites are loaded with SeqPtr==0 (why?!)
-	if (_vol[0])
-		_vol[0]->step((/*(int)SNDDrvInfo.VOL4.DL * */ _vol[0]->_seqCnt + _vol[0]->_seqCnt / 2) >> 4);
-	if (_vol[1])
-		_vol[1]->step((/*(int)SNDDrvInfo.VOL4.ML * */ _vol[1]->_seqCnt + _vol[1]->_seqCnt / 2) >> 4);
-	// TODO: Recheck these! ^
-}
-
 void CGE2Engine::releasePocket(Sprite *spr) {
 	for (int i = 0; i < 2; i++) {
 		for (int j = 0; j < kPocketMax; j++) {
@@ -831,32 +776,6 @@ void CGE2Engine::releasePocket(Sprite *spr) {
 	}
 }
 
-void CGE2Engine::checkSaySwitch() {
-	bool mute = false;
-	if (ConfMan.hasKey("mute"))
-		mute = ConfMan.getBool("mute");
-	bool speechMute = mute;
-	if (!speechMute)
-		speechMute = ConfMan.getBool("speech_mute");
-	if (!speechMute) {
-		int speechVolume = ConfMan.getInt("speech_volume");
-		speechMute = speechVolume == 0;
-	}
-
-	if (mute || speechMute) {
-		_sayVox = false;
-		_sayCap = true;
-	}
-
-	if (_oldSayVox != _sayVox) {
-		_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
-		_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
-		keyClick();
-	}
-		
-	_oldSayVox = _sayVox;
-}
-
 void CGE2Engine::loadTab() {
 	setEye(_text->getText(240));
 	for (int i = 0; i < kSceneMax; i++)
@@ -1090,112 +1009,10 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 	}
 }
 
-void CGE2Engine::optionTouch(int opt, uint16 mask) {
-	switch (opt) {
-	case 1:
-		if (mask & kMouseLeftUp)
-			switchColorMode();
-		break;
-	case 2:
-		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute")) {
-			switchMusic(_music = !_music);
-
-			switch (_music) {
-			case false:
-				_oldMusicVolume = ConfMan.getInt("music_volume");
-				ConfMan.setInt("music_volume", 0);
-				break;
-			case true:
-				ConfMan.setInt("music_volume", _oldMusicVolume);
-				break;
-			default:
-				break;
-			}
-		}
-		break;
-	case 3:
-		if (mask & kMouseLeftUp)
-			quit();
-		break;
-	case 4:
-		if (mask & (kMouseLeftUp | kMouseRightUp))
-			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
-		break;
-	case 5:
-		if (mask & (kMouseLeftUp | kMouseRightUp))
-			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
-		break;
-	case 8:
-		if (mask & kMouseLeftUp)
-			switchCap();
-		break;
-	case 9:
-		if (mask & kMouseLeftUp)
-			switchVox();
-		break;
-	default:
-		break;
-	}
-}
-
-void CGE2Engine::switchColorMode() {
-	_commandHandlerTurbo->addCommand(kCmdSeq, 121, _vga->_mono = !_vga->_mono, nullptr);
-	keyClick();
-	_vga->setColors(_vga->_sysPal, 64);
-}
-
-void CGE2Engine::switchMusic(bool on) {
-	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
-	keyClick();
-	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
-}
-
-void CGE2Engine::quit() {
-	Common::Array<Choice *> quitMenu; // Deleted in VMenu's destructor.
-	quitMenu.push_back(new StartCountDownChoice(this));
-	quitMenu.push_back(new ResetQSwitchChoice(this));
-
-	if (_commandHandler->idle()) {
-		if (VMenu::_addr) {
-			_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, VMenu::_addr);
-			ResetQSwitchChoice rqsChoice(this);
-			rqsChoice.proc();
-		} else {
-			quitMenu[0]->_text = _text->getText(kQuitText);
-			quitMenu[1]->_text = _text->getText(kNoQuitText);
-			(new VMenu(this, quitMenu, V2D(this, -1, -1), kCBMnu))->setName(_text->getText(kQuitTitle));
-			_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 0, nullptr);
-			keyClick();
-		}
-	}
-}
-
 void CGE2Engine::keyClick() {
 	_commandHandlerTurbo->addCommand(kCmdSound, -1, 5, nullptr);
 }
 
-void CGE2Engine::setVolume(int idx, int cnt) {
-	warning("STUB: CGE2Engine::setVolume()");
-}
-
-void CGE2Engine::switchCap() {
-	if (_enaCap) {
-		_sayCap = !_sayCap;
-		if (!_sayCap)
-			_sayVox = true;
-		checkSaySwitch();
-	}
-}
-
-void CGE2Engine::switchVox() {
-	if (_enaVox) {
-		_sayVox = !_sayVox;
-		if (!_sayVox)
-			_sayCap = true;
-		checkSaySwitch();
-	}
-}
-
 void CGE2Engine::offUse() {
 	int seq = 0;
 	int offUseCount = atoi(_text->getText(kOffUseCount));
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index cb2b51e..e3cdf76 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -16,7 +16,8 @@ MODULE_OBJS = \
 	events.o \
 	map.o \
 	vmenu.o \
-	saveload.o
+	saveload.o \
+	toolbar.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
new file mode 100644
index 0000000..693d940
--- /dev/null
+++ b/engines/cge2/toolbar.cpp
@@ -0,0 +1,217 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "sound.h"
+#include "common/config-manager.h"
+#include "cge2/cge2.h"
+#include "cge2/events.h"
+#include "cge2/vmenu.h"
+#include "cge2/text.h"
+#include "cge2/cge2_main.h"
+
+namespace CGE2 {
+
+void CGE2Engine::optionTouch(int opt, uint16 mask) {
+	switch (opt) {
+	case 1:
+		if (mask & kMouseLeftUp)
+			switchColorMode();
+		break;
+	case 2:
+		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute")) {
+			switchMusic(_music = !_music);
+
+			switch (_music) {
+			case false:
+				_oldMusicVolume = ConfMan.getInt("music_volume");
+				ConfMan.setInt("music_volume", 0);
+				break;
+			case true:
+				ConfMan.setInt("music_volume", _oldMusicVolume);
+				break;
+			default:
+				break;
+			}
+		}
+		break;
+	case 3:
+		if (mask & kMouseLeftUp)
+			quit();
+		break;
+	case 4:
+		if (mask & (kMouseLeftUp | kMouseRightUp))
+			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
+		break;
+	case 5:
+		if (mask & (kMouseLeftUp | kMouseRightUp))
+			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
+		break;
+	case 8:
+		if (mask & kMouseLeftUp)
+			switchCap();
+		break;
+	case 9:
+		if (mask & kMouseLeftUp)
+			switchVox();
+		break;
+	default:
+		break;
+	}
+}
+
+void CGE2Engine::switchColorMode() {
+	_commandHandlerTurbo->addCommand(kCmdSeq, 121, _vga->_mono = !_vga->_mono, nullptr);
+	keyClick();
+	_vga->setColors(_vga->_sysPal, 64);
+}
+
+void CGE2Engine::switchMusic(bool on) {
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
+	keyClick();
+	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
+}
+
+void CGE2Engine::checkMusicSwitch() {
+	bool mute = false;
+	if (ConfMan.hasKey("mute"))
+		mute = ConfMan.getBool("mute");
+	bool musicMuted = mute;
+	int musicVolume = ConfMan.getInt("music_volume");
+	if (!musicMuted)
+		musicMuted = musicVolume == 0;
+
+	if (!musicMuted && !_music) {
+		switchMusic(_music = true);
+	}
+	if (musicMuted && _music) {
+		switchMusic(_music = false);
+	}
+}
+
+void CGE2Engine::quit() {
+	Common::Array<Choice *> quitMenu; // Deleted in VMenu's destructor.
+	quitMenu.push_back(new StartCountDownChoice(this));
+	quitMenu.push_back(new ResetQSwitchChoice(this));
+
+	if (_commandHandler->idle()) {
+		if (VMenu::_addr) {
+			_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, VMenu::_addr);
+			ResetQSwitchChoice rqsChoice(this);
+			rqsChoice.proc();
+		} else {
+			quitMenu[0]->_text = _text->getText(kQuitText);
+			quitMenu[1]->_text = _text->getText(kNoQuitText);
+			(new VMenu(this, quitMenu, V2D(this, -1, -1), kCBMnu))->setName(_text->getText(kQuitTitle));
+			_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 0, nullptr);
+			keyClick();
+		}
+	}
+}
+
+void CGE2Engine::setVolume(int idx, int cnt) {
+	warning("STUB: CGE2Engine::setVolume()");
+}
+
+void CGE2Engine::switchCap() {
+	if (_enaCap) {
+		_sayCap = !_sayCap;
+		if (!_sayCap)
+			_sayVox = true;
+		checkSaySwitch();
+	}
+}
+
+void CGE2Engine::switchVox() {
+	if (_enaVox) {
+		_sayVox = !_sayVox;
+		if (!_sayVox)
+			_sayCap = true;
+		checkSaySwitch();
+	}
+}
+
+void CGE2Engine::checkSaySwitch() {
+	bool mute = false;
+	if (ConfMan.hasKey("mute"))
+		mute = ConfMan.getBool("mute");
+	bool speechMute = mute;
+	if (!speechMute)
+		speechMute = ConfMan.getBool("speech_mute");
+	if (!speechMute) {
+		int speechVolume = ConfMan.getInt("speech_volume");
+		speechMute = speechVolume == 0;
+	}
+
+	if (speechMute) {
+		_sayVox = false;
+		_sayCap = true;
+	}
+
+	if (_oldSayVox != _sayVox) {
+		_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
+		_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
+		keyClick();
+	}
+
+	_oldSayVox = _sayVox;
+}
+
+void CGE2Engine::initToolbar() {
+	selectPocket(-1);
+
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, _music, nullptr);
+	if (!_music)
+		_midiPlayer->killMidi();
+
+	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr); // Sets the speech caption switch on.
+
+	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
+	_infoLine->setText(nullptr);
+	_vga->_showQ->insert(_infoLine);
+
+	_startupMode = 0;
+	_mouse->center();
+	_mouse->off();
+	_mouse->on();
+
+	_keyboard->setClient(_sys);
+	_commandHandler->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
+
+	_busyPtr = _vga->_showQ->locate(kBusyRef);
+
+	_vol[0] = _vga->_showQ->locate(kDvolRef);
+	_vol[1] = _vga->_showQ->locate(kMvolRef);
+
+	// these sprites are loaded with SeqPtr==0 (why?!)
+	if (_vol[0])
+		_vol[0]->step((/*(int)SNDDrvInfo.VOL4.DL * */ _vol[0]->_seqCnt + _vol[0]->_seqCnt / 2) >> 4);
+	if (_vol[1])
+		_vol[1]->step((/*(int)SNDDrvInfo.VOL4.ML * */ _vol[1]->_seqCnt + _vol[1]->_seqCnt / 2) >> 4);
+	// TODO: Recheck these! ^
+}
+
+} // End of namespace CGE2


Commit: a6eb08903351d916d2c243ca031392a5ebd2240a
    https://github.com/scummvm/scummvm/commit/a6eb08903351d916d2c243ca031392a5ebd2240a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-23T14:56:11+02:00

Commit Message:
CGE2: Move inventory system's functions from cge2_main.cpp to inventory.cpp.

Changed paths:
  A engines/cge2/inventory.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/module.mk



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index ecc741e..24adb0e 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -619,36 +619,6 @@ void CGE2Engine::tick() {
 	_mouse->tick();
 }
 
-void CGE2Engine::openPocket() {
-	for (int i = 0; i < 2; i++) {
-		for (int j = 0; j < kPocketMax + 1; j++) {
-			int ref = (int)_heroTab[i]->_downPocketId[j];
-			_heroTab[i]->_pocket[j] = (ref == -1) ? nullptr : _vga->_showQ->locate(ref);
-		}
-	}
-}
-
-void CGE2Engine::closePocket() {
-	for (int i = 0; i < 2; i++) {
-		for (int j = 0; j < kPocketMax + 1; j++) {
-			Sprite *spr = _heroTab[i]->_pocket[j];
-			_heroTab[i]->_downPocketId[j] = (spr) ? spr->_ref : -1;
-		}
-	}
-}
-
-void CGE2Engine::selectPocket(int n) {
-	Sprite **p = _heroTab[_sex]->_pocket;
-	int &pp = _heroTab[_sex]->_pocPtr;
-	if (n < 0 || pp == n) {
-		n = findActivePocket(-1);
-		if (n >= 0)
-			pp = n;
-	} else if (p[n]) {
-		pp = n;
-	}
-}
-
 void CGE2Engine::busy(bool on) {
 	if (on) {
 		_spriteNotify = _midiNotify = &CGE2::CGE2Engine::busyStep;
@@ -763,19 +733,6 @@ void CGE2Engine::loadPos() {
 		error("Missing file: CGE.HXY");
 }
 
-void CGE2Engine::releasePocket(Sprite *spr) {
-	for (int i = 0; i < 2; i++) {
-		for (int j = 0; j < kPocketMax; j++) {
-			Sprite *&poc = _heroTab[i]->_pocket[j];
-			if (poc == spr) {
-				spr->_flags._kept = false;
-				poc = nullptr;
-				return;
-			}
-		}
-	}
-}
-
 void CGE2Engine::loadTab() {
 	setEye(_text->getText(240));
 	for (int i = 0; i < kSceneMax; i++)
@@ -879,35 +836,6 @@ bool CGE2Engine::showTitle(const char *name) {
 	return true;
 }
 
-int CGE2Engine::freePockets(int sx) {
-	int n = 0;
-	for (int i = 0; i < kPocketMax; i++){
-		if (_heroTab[sx]->_pocket[i] == nullptr)
-			++n;
-	}
-	return n;
-}
-
-int CGE2Engine::findActivePocket(int ref) {
-	for (int i = 0; i < kPocketMax; i++) {
-		Sprite *spr = _heroTab[_sex]->_pocket[i];
-		if (ref >= 0) {
-			if (spr && spr->_ref == ref)
-				return i;
-		} else if (!spr)
-			return i;
-	}
-	return -1;
-}
-
-void CGE2Engine::pocFul() {
-	Hero *h = _heroTab[_sex]->_ptr;
-	h->park();
-	_commandHandler->addCommand(kCmdWait, -1, -1, h);
-	_commandHandler->addCommand(kCmdSound, -1, 2, h);
-	_commandHandler->addCommand(kCmdSay, -1, kPocketFull + _sex, h);
-}
-
 void CGE2Engine::killText() {
 	if (!_talk)
 		return;
diff --git a/engines/cge2/inventory.cpp b/engines/cge2/inventory.cpp
new file mode 100644
index 0000000..7029a64
--- /dev/null
+++ b/engines/cge2/inventory.cpp
@@ -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.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This code is based on original Sfinx source code
+ * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
+ */
+
+#include "cge2/cge2.h"
+#include "cge2/hero.h"
+
+namespace CGE2 {
+
+int CGE2Engine::findActivePocket(int ref) {
+	for (int i = 0; i < kPocketMax; i++) {
+		Sprite *spr = _heroTab[_sex]->_pocket[i];
+		if (ref >= 0) {
+			if (spr && spr->_ref == ref)
+				return i;
+		} else if (!spr)
+			return i;
+	}
+	return -1;
+}
+
+void CGE2Engine::selectPocket(int n) {
+	Sprite **p = _heroTab[_sex]->_pocket;
+	int &pp = _heroTab[_sex]->_pocPtr;
+	if (n < 0 || pp == n) {
+		n = findActivePocket(-1);
+		if (n >= 0)
+			pp = n;
+	} else if (p[n]) {
+		pp = n;
+	}
+}
+
+void CGE2Engine::pocFul() {
+	Hero *h = _heroTab[_sex]->_ptr;
+	h->park();
+	_commandHandler->addCommand(kCmdWait, -1, -1, h);
+	_commandHandler->addCommand(kCmdSound, -1, 2, h);
+	_commandHandler->addCommand(kCmdSay, -1, kPocketFull + _sex, h);
+}
+
+void CGE2Engine::releasePocket(Sprite *spr) {
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax; j++) {
+			Sprite *&poc = _heroTab[i]->_pocket[j];
+			if (poc == spr) {
+				spr->_flags._kept = false;
+				poc = nullptr;
+				return;
+			}
+		}
+	}
+}
+
+int CGE2Engine::freePockets(int sx) {
+	int n = 0;
+	for (int i = 0; i < kPocketMax; i++){
+		if (_heroTab[sx]->_pocket[i] == nullptr)
+			++n;
+	}
+	return n;
+}
+
+void CGE2Engine::openPocket() {
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax + 1; j++) {
+			int ref = (int)_heroTab[i]->_downPocketId[j];
+			_heroTab[i]->_pocket[j] = (ref == -1) ? nullptr : _vga->_showQ->locate(ref);
+		}
+	}
+}
+
+void CGE2Engine::closePocket() {
+	for (int i = 0; i < 2; i++) {
+		for (int j = 0; j < kPocketMax + 1; j++) {
+			Sprite *spr = _heroTab[i]->_pocket[j];
+			_heroTab[i]->_downPocketId[j] = (spr) ? spr->_ref : -1;
+		}
+	}
+}
+
+} // End of namespace CGE2
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index e3cdf76..256087f 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -17,7 +17,8 @@ MODULE_OBJS = \
 	map.o \
 	vmenu.o \
 	saveload.o \
-	toolbar.o
+	toolbar.o \
+	inventory.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)


Commit: 755fedcceba70267ea41ea5fed5a4e021c05b0e7
    https://github.com/scummvm/scummvm/commit/755fedcceba70267ea41ea5fed5a4e021c05b0e7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T16:50:36+02:00

Commit Message:
CGE2: Set speech only/text only/both modes according to Launcher options.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/saveload.cpp
    engines/cge2/sound.cpp
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 55ac835..94b876c 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -91,6 +91,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_endGame = false;
 	for (int i = 0; i < 4; i++)
 		_flag[i] = false;
+	_enaVox = true;
 	_sayCap = true;
 	_sayVox = true;
 	_oldSayVox = false;
@@ -98,7 +99,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
 	_enaCap = true;
-	_enaVox = true;
 }
 
 void CGE2Engine::init() {
@@ -177,4 +177,11 @@ Common::Error CGE2Engine::run() {
 	return Common::kNoError;
 }
 
+void CGE2Engine::syncSoundSettings() {
+	Engine::syncSoundSettings();
+
+	_enaCap = _sayCap = ConfMan.getBool("subtitles");
+	_enaVox = _sayVox = !ConfMan.getBool("speech_mute");
+}
+
 } // End of namespace CGE2
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index b7b2dd3..62db99a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -133,6 +133,7 @@ private:
 	void syncHeader(Common::Serializer &s);
 	bool loadGame(int slotNumber);
 	void resetGame();
+	void syncSoundSettings();
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
 	virtual bool hasFeature(EngineFeature f) const;
@@ -175,6 +176,7 @@ public:
 	Sprite *locate(int ref);
 	bool isHero(Sprite *spr);
 	void loadUser();
+	void switchSay();
 	void checkSaySwitch();
 	void loadPos();
 	void releasePocket(Sprite *spr);
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index b9a856f..6d7bb24 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -366,9 +366,9 @@ bool CGE2Engine::loadGame(int slotNumber) {
 
 	// Get in the savegame
 	syncGame(readStream, nullptr);
-
 	delete readStream;
 
+	syncSoundSettings();
 	initToolbar();
 	loadHeroes();
 
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index 7e886e5..b42ba18 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -62,7 +62,7 @@ void Sound::close() {
 void Sound::open() {
 	setRepeat(1);
 	if (_vm->_commandHandlerTurbo != nullptr)
-		_vm->checkSaySwitch();
+		_vm->switchSay();
 	play(_vm->_fx->load(99, 99));
 }
 
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 693d940..e643632 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -137,47 +137,32 @@ void CGE2Engine::setVolume(int idx, int cnt) {
 }
 
 void CGE2Engine::switchCap() {
-	if (_enaCap) {
+	if (_enaCap && _enaVox) {
 		_sayCap = !_sayCap;
-		if (!_sayCap)
+		if (!_sayCap && _enaVox)
 			_sayVox = true;
-		checkSaySwitch();
+		keyClick();
+		switchSay();
 	}
 }
 
 void CGE2Engine::switchVox() {
-	if (_enaVox) {
+	if (_enaVox && _enaCap) {
 		_sayVox = !_sayVox;
-		if (!_sayVox)
+		if (!_sayVox && _enaCap)
 			_sayCap = true;
-		checkSaySwitch();
+		keyClick();
+		switchSay();
 	}
 }
 
-void CGE2Engine::checkSaySwitch() {
-	bool mute = false;
-	if (ConfMan.hasKey("mute"))
-		mute = ConfMan.getBool("mute");
-	bool speechMute = mute;
-	if (!speechMute)
-		speechMute = ConfMan.getBool("speech_mute");
-	if (!speechMute) {
-		int speechVolume = ConfMan.getInt("speech_volume");
-		speechMute = speechVolume == 0;
-	}
-
-	if (speechMute) {
-		_sayVox = false;
-		_sayCap = true;
-	}
-
-	if (_oldSayVox != _sayVox) {
-		_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
-		_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
-		keyClick();
-	}
+void CGE2Engine::switchSay() {
+	_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
+	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
+}
 
-	_oldSayVox = _sayVox;
+void CGE2Engine::checkSaySwitch() {
+	warning("STUB: checkSaySwitch()");
 }
 
 void CGE2Engine::initToolbar() {
@@ -187,7 +172,7 @@ void CGE2Engine::initToolbar() {
 	if (!_music)
 		_midiPlayer->killMidi();
 
-	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr); // Sets the speech caption switch on.
+	switchSay();
 
 	_infoLine->gotoxyz(V3D(kInfoX, kInfoY, 0));
 	_infoLine->setText(nullptr);


Commit: 24cc8a8762ded511e8f69ee2790f38b913ddcae9
    https://github.com/scummvm/scummvm/commit/24cc8a8762ded511e8f69ee2790f38b913ddcae9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T18:11:10+02:00

Commit Message:
CGE2: Implement checkSaySwitch() and add/fix connected code.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/saveload.cpp
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 94b876c..5a5e345 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -74,7 +74,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_music = true;
-	_oldMusicVolume = ConfMan.getInt("music_volume");;
+	_oldMusicVolume = ConfMan.getInt("music_volume");
 	_startupMode = 1;
 	_now = 1;
 	_sex = 1;
@@ -94,7 +94,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_enaVox = true;
 	_sayCap = true;
 	_sayVox = true;
-	_oldSayVox = false;
+	_oldSpeechVolume = ConfMan.getInt("speech_volume");
 	_req = 1;
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
@@ -167,6 +167,7 @@ bool CGE2Engine::hasFeature(EngineFeature f) const {
 
 Common::Error CGE2Engine::run() {
 	syncSoundSettings();
+	syncSpeechSettings();
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();
@@ -177,11 +178,10 @@ Common::Error CGE2Engine::run() {
 	return Common::kNoError;
 }
 
-void CGE2Engine::syncSoundSettings() {
-	Engine::syncSoundSettings();
-
+void CGE2Engine::syncSpeechSettings() {
 	_enaCap = _sayCap = ConfMan.getBool("subtitles");
 	_enaVox = _sayVox = !ConfMan.getBool("speech_mute");
 }
 
+
 } // End of namespace CGE2
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 62db99a..363c7c4 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -133,7 +133,7 @@ private:
 	void syncHeader(Common::Serializer &s);
 	bool loadGame(int slotNumber);
 	void resetGame();
-	void syncSoundSettings();
+	void syncSpeechSettings();
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
 	virtual bool hasFeature(EngineFeature f) const;
@@ -285,7 +285,7 @@ public:
 	bool _flag[4];
 	bool _sayCap;
 	bool _sayVox;
-	bool _oldSayVox;
+	int _oldSpeechVolume;
 	int _req;
 	NotifyFunctionType _midiNotify;
 	NotifyFunctionType _spriteNotify;
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 6d7bb24..3c57e62 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -368,7 +368,7 @@ bool CGE2Engine::loadGame(int slotNumber) {
 	syncGame(readStream, nullptr);
 	delete readStream;
 
-	syncSoundSettings();
+	syncSpeechSettings();
 	initToolbar();
 	loadHeroes();
 
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index e643632..3c0ee52 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -75,8 +75,21 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchCap();
 		break;
 	case 9:
-		if (mask & kMouseLeftUp)
+		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute")) {
 			switchVox();
+
+			switch (_sayVox) {
+			case false:
+				_oldSpeechVolume = ConfMan.getInt("speech_volume");
+				ConfMan.setInt("speech_volume", 0);
+				break;
+			case true:
+				ConfMan.setInt("speech_volume", _oldSpeechVolume);
+				break;
+			default:
+				break;
+			}
+		}
 		break;
 	default:
 		break;
@@ -162,7 +175,21 @@ void CGE2Engine::switchSay() {
 }
 
 void CGE2Engine::checkSaySwitch() {
-	warning("STUB: checkSaySwitch()");
+	bool mute = false;
+	if (ConfMan.hasKey("mute"))
+		mute = ConfMan.getBool("mute");
+	bool speechMuted = mute;
+	if (!speechMuted) {
+		int speechVolume = ConfMan.getInt("speech_volume");
+		speechMuted = speechVolume == 0;
+	}
+
+	if (!speechMuted && !_sayVox) {
+		switchVox();
+	}
+	if (speechMuted && _sayVox) {
+		switchVox();
+	}
 }
 
 void CGE2Engine::initToolbar() {


Commit: ff97d52d728a0a47f421dfdfabb40b30f0b1c920
    https://github.com/scummvm/scummvm/commit/ff97d52d728a0a47f421dfdfabb40b30f0b1c920
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T18:55:09+02:00

Commit Message:
CGE2: Distinguish SFX from speech when playing sounds.

Now the sound options of ScummVM are taken into account when playing these two types of sounds. Until now, everything was considered SFX sound.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp
    engines/cge2/sound.cpp
    engines/cge2/sound.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 363c7c4..380e7da 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -35,6 +35,7 @@
 #include "engines/advancedDetector.h"
 #include "common/system.h"
 #include "cge2/fileio.h"
+#include "audio/mixer.h"
 
 namespace CGE2 {
 
@@ -249,7 +250,7 @@ public:
 	void snCycle(int cnt);
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
-	void snSound(Sprite *spr, int wav);
+	void snSound(Sprite *spr, int wav, Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType);
 	void snRoom(Sprite *spr, bool on);
 	void snDim(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index f6c6e2d..aebe1f0 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -75,7 +75,7 @@ void CommandHandler::runCommand() {
 			if (_vm->_fx->exist(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0])) {
 				int16 oldRepeat = _vm->_sound->getRepeat();
 				_vm->_sound->setRepeat(1);
-				_vm->_sound->play(_vm->_fx->load(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0]), _vm->_sound->_smpinf._span);
+				_vm->_sound->play(Audio::Mixer::kSFXSoundType, _vm->_fx->load(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0]), _vm->_sound->_smpinf._span);
 				_vm->_sound->setRepeat(oldRepeat);
 				return;
 			}
@@ -676,7 +676,7 @@ void CGE2Engine::snReach(Sprite *spr, int val) {
 		((Hero *)spr)->reach(val);
 }
 
-void CGE2Engine::snSound(Sprite *spr, int wav) {
+void CGE2Engine::snSound(Sprite *spr, int wav, Audio::Mixer::SoundType soundType) {
 	if (wav == -1)
 		_sound->stop();
 	else {
@@ -687,7 +687,7 @@ void CGE2Engine::snSound(Sprite *spr, int wav) {
 
 		_soundStat._ref[1] = wav;
 		_soundStat._ref[0] = !_fx->exist(_soundStat._ref[1]);
-		_sound->play(_fx->load(_soundStat._ref[1], _soundStat._ref[0]),
+		_sound->play(soundType, _fx->load(_soundStat._ref[1], _soundStat._ref[0]),
 			(spr) ? (spr->_pos2D.x / (kScrWidth / 16)) : 8);
 	}
 }
@@ -746,7 +746,7 @@ void CGE2Engine::snSay(Sprite *spr, int val) {
 				i -= 100;
 			int16 oldRepeat = _sound->getRepeat();
 			_sound->setRepeat(1);
-			snSound(spr, i);
+			snSound(spr, i, Audio::Mixer::kSpeechSoundType);
 			_sound->setRepeat(oldRepeat);
 			_soundStat._wait = &_sound->_smpinf._counter;
 		}
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index b42ba18..27a3af8 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -26,8 +26,6 @@
  */
 
 #include "cge2/sound.h"
-//#include "cge/text.h"
-//#include "cge/cge_main.h"
 #include "common/config-manager.h"
 #include "common/memstream.h"
 #include "audio/decoders/raw.h"
@@ -63,7 +61,7 @@ void Sound::open() {
 	setRepeat(1);
 	if (_vm->_commandHandlerTurbo != nullptr)
 		_vm->switchSay();
-	play(_vm->_fx->load(99, 99));
+	play(Audio::Mixer::kSFXSoundType, _vm->_fx->load(99, 99));
 }
 
 void Sound::setRepeat(int16 count) {
@@ -74,47 +72,61 @@ int16 Sound::getRepeat() {
 	return _soundRepeatCount;
 }
 
-void Sound::play(DataCk *wav, int pan) {
+void Sound::play(Audio::Mixer::SoundType soundType, DataCk *wav, int pan) {
 	if (wav) {
 		stop();
 		_smpinf._saddr = &*(wav->addr());
 		_smpinf._slen = (uint16)wav->size();
 		_smpinf._span = pan;
 		_smpinf._counter = getRepeat();
-		sndDigiStart(&_smpinf);
+		sndDigiStart(&_smpinf, soundType);
 	}
 }
 
-void Sound::sndDigiStart(SmpInfo *PSmpInfo) {
+void Sound::sndDigiStart(SmpInfo *PSmpInfo, Audio::Mixer::SoundType soundType) {
 	// Create an audio stream wrapper for sound
 	Common::MemoryReadStream *stream = new Common::MemoryReadStream(PSmpInfo->_saddr,
 		PSmpInfo->_slen, DisposeAfterUse::NO);
 	_audioStream = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
 
+	// Decide which handle to use
+	Audio::SoundHandle *handle = nullptr;
+	switch (soundType) {
+	case Audio::Mixer::kSFXSoundType:
+		handle = &_soundHandle;
+		break;
+	case Audio::Mixer::kSpeechSoundType:
+		handle = &_speechHandle;
+		break;
+	default:
+		break;
+	}
+
 	// Start the new sound
-	_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle,
+	_vm->_mixer->playStream(soundType, handle,
 		Audio::makeLoopingAudioStream(_audioStream, (uint)PSmpInfo->_counter));
 
 	// CGE pan:
 	// 8 = Center
 	// Less = Left
 	// More = Right
-	_vm->_mixer->setChannelBalance(_soundHandle, (int8)CLIP(((PSmpInfo->_span - 8) * 16), -127, 127));
+	_vm->_mixer->setChannelBalance(*handle, (int8)CLIP(((PSmpInfo->_span - 8) * 16), -127, 127));
 }
 
 void Sound::stop() {
-	sndDigiStop(&_smpinf);
+	sndDigiStop(_soundHandle);
+	sndDigiStop(_speechHandle);
+	_audioStream = nullptr;
 }
 
 void Sound::checkSoundHandle() {
-	if (!_vm->_mixer->isSoundHandleActive(_soundHandle))
+	if (!_vm->_mixer->isSoundHandleActive(_speechHandle))
 		_smpinf._counter = 0;
 }
 
-void Sound::sndDigiStop(SmpInfo *PSmpInfo) {
-	if (_vm->_mixer->isSoundHandleActive(_soundHandle))
-		_vm->_mixer->stopHandle(_soundHandle);
-	_audioStream = nullptr;
+void Sound::sndDigiStop(Audio::SoundHandle &handle) {
+	if (_vm->_mixer->isSoundHandleActive(handle))
+		_vm->_mixer->stopHandle(handle);
 }
 
 Fx::Fx(CGE2Engine *vm, int size) : _current(nullptr), _vm(vm) {
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
index e2e9482..7dd549c 100644
--- a/engines/cge2/sound.h
+++ b/engines/cge2/sound.h
@@ -72,7 +72,7 @@ public:
 	~Sound();
 	void open();
 	void close();
-	void play(DataCk *wav, int pan = 8);
+	void play(Audio::Mixer::SoundType soundType, DataCk *wav, int pan = 8);
 	int16 getRepeat();
 	void setRepeat(int16 count);
 	void stop();
@@ -81,10 +81,11 @@ private:
 	int _soundRepeatCount;
 	CGE2Engine *_vm;
 	Audio::SoundHandle _soundHandle;
+	Audio::SoundHandle _speechHandle;
 	Audio::RewindableAudioStream *_audioStream;
 
-	void sndDigiStart(SmpInfo *PSmpInfo);
-	void sndDigiStop(SmpInfo *PSmpInfo);
+	void sndDigiStart(SmpInfo *PSmpInfo, Audio::Mixer::SoundType soundType);
+	void sndDigiStop(Audio::SoundHandle &handle);
 };
 
 class Fx {


Commit: 6743b8b6a3199cc75518e2c05625b76db361484f
    https://github.com/scummvm/scummvm/commit/6743b8b6a3199cc75518e2c05625b76db361484f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T18:55:41+02:00

Commit Message:
CGE2: Remove redundant default labels.

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 3c0ee52..23c6fd1 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -53,8 +53,6 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			case true:
 				ConfMan.setInt("music_volume", _oldMusicVolume);
 				break;
-			default:
-				break;
 			}
 		}
 		break;
@@ -86,8 +84,6 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			case true:
 				ConfMan.setInt("speech_volume", _oldSpeechVolume);
 				break;
-			default:
-				break;
 			}
 		}
 		break;


Commit: 7c65aa7aecef35e77c0f39c0e2c2a864858e6b9d
    https://github.com/scummvm/scummvm/commit/7c65aa7aecef35e77c0f39c0e2c2a864858e6b9d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T19:44:09+02:00

Commit Message:
CGE2: Repair/rename checkSoundHandle().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/sound.cpp
    engines/cge2/sound.h



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 24adb0e..e4b34a0 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -554,7 +554,7 @@ void CGE2Engine::mainLoop() {
 }
 
 void CGE2Engine::checkSounds() {
-	_sound->checkSoundHandle();
+	_sound->checkSoundHandles();
 	checkSaySwitch();
 	checkMusicSwitch();
 	_midiPlayer->syncVolume();
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index 27a3af8..cc148d6 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -119,8 +119,8 @@ void Sound::stop() {
 	_audioStream = nullptr;
 }
 
-void Sound::checkSoundHandle() {
-	if (!_vm->_mixer->isSoundHandleActive(_speechHandle))
+void Sound::checkSoundHandles() {
+	if (!_vm->_mixer->isSoundHandleActive(_speechHandle) && !_vm->_mixer->isSoundHandleActive(_soundHandle))
 		_smpinf._counter = 0;
 }
 
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
index 7dd549c..b97cd11 100644
--- a/engines/cge2/sound.h
+++ b/engines/cge2/sound.h
@@ -76,7 +76,7 @@ public:
 	int16 getRepeat();
 	void setRepeat(int16 count);
 	void stop();
-	void checkSoundHandle();
+	void checkSoundHandles();
 private:
 	int _soundRepeatCount;
 	CGE2Engine *_vm;


Commit: 15a225697201482e93253a0d77e03a7d255c6c18
    https://github.com/scummvm/scummvm/commit/15a225697201482e93253a0d77e03a7d255c6c18
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T22:19:11+02:00

Commit Message:
CGE2: Implement snTrans() and snPort().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 380e7da..336d727 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -232,8 +232,8 @@ public:
 	void snGoto(Sprite *spr, int val);
 	void snMove(Sprite *spr, V3D pos);
 	void snSlave(Sprite *spr, int val);
-	void snTrans(Sprite *spr, int val);
-	void snPort(Sprite *spr, int val);
+	void snTrans(Sprite *spr, int trans);
+	void snPort(Sprite *spr, int port);
 	void snMouse(bool on);
 	void snNNext(Sprite *spr, Action act, int val);
 	void snRNNext(Sprite *spr, int val);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index aebe1f0..4ba8348 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -579,12 +579,16 @@ void CGE2Engine::snSlave(Sprite *spr, int val) {
 	warning("STUB: CGE2Engine::snSlave()");
 }
 
-void CGE2Engine::snTrans(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snTrans()");
+void CGE2Engine::snTrans(Sprite *spr, int trans) {
+	if (spr) {
+		spr->_flags._tran = (trans < 0) ? !spr->_flags._tran : (trans != 0);
+	}
 }
 
-void CGE2Engine::snPort(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snPort()");
+void CGE2Engine::snPort(Sprite *spr, int port) {
+	if (spr) {
+		spr->_flags._port = (port < 0) ? !spr->_flags._port : (port != 0);
+	}
 }
 
 void CGE2Engine::snMouse(bool on) {


Commit: c84389813221559510a00f2aa1ad492051a5fa44
    https://github.com/scummvm/scummvm/commit/c84389813221559510a00f2aa1ad492051a5fa44
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T22:57:26+02:00

Commit Message:
CGE2: Remove handling of unused opcodes.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 336d727..0c5492f 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -218,21 +218,15 @@ public:
 	void snKill(Sprite *spr);
 	void snHide(Sprite *spr, int val);
 	void snMidi(int val);
-	void snSetDlg(int clr, int set);
-	void snMskDlg(int clr, int set);
 	void snSeq(Sprite *spr, int val);
 	void snRSeq(Sprite *spr, int val);
 	void snSend(Sprite *spr, int val);
 	void snSwap(Sprite *spr, int val);
 	void snCover(Sprite *spr, int val);
 	void snUncover(Sprite *spr, Sprite *spr2);
-	void snFocus(int val);
 	void snKeep(Sprite *spr, int val);
 	void snGive(Sprite *spr, int val);
 	void snGoto(Sprite *spr, int val);
-	void snMove(Sprite *spr, V3D pos);
-	void snSlave(Sprite *spr, int val);
-	void snTrans(Sprite *spr, int trans);
 	void snPort(Sprite *spr, int port);
 	void snMouse(bool on);
 	void snNNext(Sprite *spr, Action act, int val);
@@ -242,11 +236,8 @@ public:
 	void snRmNear(Sprite *spr);
 	void snRmMTake(Sprite *spr);
 	void snRmFTake(Sprite *spr);
-	void snFlag(int ref, int val);
 	void snSetRef(Sprite *spr, int val);
-	void snBackPt(Sprite *spr, int val);
 	void snFlash(int val);
-	void snLight(int val);
 	void snCycle(int cnt);
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 4ba8348..1bc821d 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -139,21 +139,12 @@ void CommandHandler::runCommand() {
 			if (_talkEnable)
 				_vm->inf(((tailCmd._val) >= 0) ? _vm->_text->getText(tailCmd._val) : (const char *)tailCmd._spritePtr);
 			break;
-		case kCmdTime:
-			warning("STUB: CommandHandler::runCommand() - Something missing connected to kCmdTime!");
-			break;
 		case kCmdCave:
 			_vm->switchScene(tailCmd._val);
 			break;
 		case kCmdMidi:
 			_vm->snMidi(tailCmd._val);
 			break;
-		case kCmdSetDlg:
-			_vm->snSetDlg(tailCmd._ref, tailCmd._val);
-			break;
-		case kCmdMskDlg:
-			_vm->snMskDlg(tailCmd._ref, tailCmd._val);
-			break;
 		case kCmdKill:
 			_vm->snKill(spr);
 			break;
@@ -175,9 +166,6 @@ void CommandHandler::runCommand() {
 		case kCmdUncover:
 			_vm->snUncover(spr, (tailCmd._val >= 0) ? _vm->locate(tailCmd._val) : ((Sprite *)tailCmd._spritePtr));
 			break;
-		case kCmdFocus:
-			_vm->snFocus(tailCmd._val);
-			break;
 		case kCmdKeep:
 			_vm->snKeep(spr, tailCmd._val);
 			break;
@@ -196,15 +184,6 @@ void CommandHandler::runCommand() {
 		case kCmdAdd:
 			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) + *(_vm->_point[tailCmd._val]);
 			break;
-		case kCmdSub:
-			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) - *(_vm->_point[tailCmd._val]);
-			break;
-		case kCmdMul:
-			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) * tailCmd._val;
-			break;
-		case kCmdDiv:
-			*(_vm->_point[tailCmd._ref]) = *(_vm->_point[tailCmd._ref]) / tailCmd._val;
-			break;
 		case kCmdGetPos:
 			if (spr)
 				*(_vm->_point[tailCmd._val]) = spr->_pos3D;
@@ -212,30 +191,11 @@ void CommandHandler::runCommand() {
 		case kCmdGoto:
 			_vm->snGoto(spr, tailCmd._val);
 			break;
-		case kCmdMoveX:
-			_vm->snMove(spr, V3D(tailCmd._val, 0, 0));
-			break;
-		case kCmdMoveY:
-			_vm->snMove(spr, V3D(0, tailCmd._val, 0));
-			break;
-		case kCmdMoveZ:
-			_vm->snMove(spr, V3D(0, 0, tailCmd._val));
-			break;
-		case kCmdSlave:
-			_vm->snSlave(spr, tailCmd._val);
-			break;
-		case kCmdTrans:
-			_vm->snTrans(spr, tailCmd._val);
-			break;
 		case kCmdPort:
 			_vm->snPort(spr, tailCmd._val);
 			break;
 		case kCmdNext:
 			break;
-		case kCmdIf:
-			break;
-		case kCmdTalk:
-			break;
 		case kCmdMouse:
 			_vm->snMouse(tailCmd._val != 0);
 			break;
@@ -266,21 +226,12 @@ void CommandHandler::runCommand() {
 		case kCmdRMFTake:
 			_vm->snRmFTake(spr);
 			break;
-		case kCmdFlag:
-			_vm->snFlag(tailCmd._ref & 3, tailCmd._val);
-			break;
 		case kCmdSetRef:
 			_vm->snSetRef(spr, tailCmd._val);
 			break;
-		case kCmdBackPt:
-			_vm->snBackPt(spr, tailCmd._val);
-			break;
 		case kCmdFlash:
 			_vm->snFlash(tailCmd._val != 0);
 			break;
-		case kCmdLight:
-			_vm->snLight(tailCmd._val != 0);
-			break;
 		case kCmdCycle:
 			_vm->snCycle(tailCmd._val);
 			break;
@@ -297,9 +248,6 @@ void CommandHandler::runCommand() {
 		case kCmdMap:
 			_vm->_heroTab[tailCmd._ref & 1]->_ptr->_ignoreMap = tailCmd._val == 0;
 			break;
-		case kCmdCount:
-			_vm->_sound->setRepeat(tailCmd._val);
-			break;
 		case kCmdRoom:
 			_vm->snRoom(spr, tailCmd._val);
 			break;
@@ -378,14 +326,6 @@ void CGE2Engine::snMidi(int val) {
 		_midiPlayer->loadMidi(val);
 }
 
-void CGE2Engine::snSetDlg(int clr, int set) {
-	warning("STUB: CGE2Engine::snSetDlg()");
-}
-
-void CGE2Engine::snMskDlg(int clr, int set) {
-	warning("STUB: CGE2Engine::snMskDlg()");
-}
-
 void CGE2Engine::snSeq(Sprite *spr, int val) {
 	if (spr) {
 		if (isHero(spr) && val == 0)
@@ -506,10 +446,6 @@ void CGE2Engine::snUncover(Sprite *spr, Sprite *spr2) {
 	}
 }
 
-void CGE2Engine::snFocus(int val) {
-	warning("STUB: CGE2Engine::snFocus()");
-}
-
 void CGE2Engine::snKeep(Sprite *spr, int stp) {
 	int sex = _sex;
 	if (stp > 127) {
@@ -571,20 +507,6 @@ void CGE2Engine::snGoto(Sprite *spr, int val) {
 	}
 }
 
-void CGE2Engine::snMove(Sprite *spr, V3D pos) {
-	warning("STUB: CGE2Engine::snMove()");
-}
-
-void CGE2Engine::snSlave(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snSlave()");
-}
-
-void CGE2Engine::snTrans(Sprite *spr, int trans) {
-	if (spr) {
-		spr->_flags._tran = (trans < 0) ? !spr->_flags._tran : (trans != 0);
-	}
-}
-
 void CGE2Engine::snPort(Sprite *spr, int port) {
 	if (spr) {
 		spr->_flags._port = (port < 0) ? !spr->_flags._port : (port != 0);
@@ -636,28 +558,16 @@ void CGE2Engine::snRmFTake(Sprite *spr) {
 		spr->_actionCtrl[kFTake]._cnt = 0;
 }
 
-void CGE2Engine::snFlag(int ref, int val) {
-	warning("STUB: CGE2Engine::snFlag()");
-}
-
 void CGE2Engine::snSetRef(Sprite *spr, int val) {
 	if (spr) {
 		spr->_ref = val;
 	}
 }
 
-void CGE2Engine::snBackPt(Sprite *spr, int val) {
-	warning("STUB: CGE2Engine::snBackPt()");
-}
-
 void CGE2Engine::snFlash(int val) {
 	warning("STUB: CGE2Engine::snFlash()");
 }
 
-void CGE2Engine::snLight(int val) {
-	warning("STUB: CGE2Engine::snLight()");
-}
-
 void CGE2Engine::snCycle(int cnt) {
 	warning("STUB: CGE2Engine::snCycle()");
 }
@@ -904,10 +814,6 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 		}
 
 		while (c < q) {
-			if (c->_commandType == kCmdTalk) {
-				if ((_commandHandler->_talkEnable = (c->_val != 0)) == false)
-					killText();
-			}
 			if (c->_commandType == kCmdWalk || c->_commandType == kCmdReach) {
 				if (c->_val == -1)
 					c->_val = spr->_ref;
@@ -953,17 +859,8 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 				if (s == spr)
 					break;
 			}
-			if (c->_commandType == kCmdIf) {
-				Sprite *s = (c->_ref < 0) ? spr : _vga->_showQ->locate(c->_ref);
-				if (s) { // sprite exists 
-					if (!s->seqTest(-1)) { // not parked
-						int v = c->_val;
-						if (v > 255) if (s) v = s->labVal(snq, v >> 8);
-						c = comtab + (v - 1);
-					}
-				}
-			} else
-				_commandHandler->addCommand(c->_commandType, c->_ref, c->_val, spr);
+			
+			_commandHandler->addCommand(c->_commandType, c->_ref, c->_val, spr);
 
 			++c;
 		}


Commit: 12210ecf27eea137e2ac9f58312d7143a0a015cb
    https://github.com/scummvm/scummvm/commit/12210ecf27eea137e2ac9f58312d7143a0a015cb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T23:06:11+02:00

Commit Message:
CGE2: Remove the unused opcodes.

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 1bc821d..5e889b2 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -36,23 +36,21 @@ namespace CGE2 {
 
 const char *CommandHandler::_commandText[] = {
 	"NOP", "USE", "PAUSE", "INF", "CAVE",
-	"SLAVE", "FOCUS", "SETX", "SETY", "SETZ",
-	"ADD", "SUB", "MUL", "DIV", "IF", "FLAG",
-	"FLASH", "LIGHT", "CYCLE",
+	"SETX", "SETY", "SETZ",
+	"ADD", "SUB", "MUL", "DIV", "IF",
+	"FLASH", "CYCLE",
 	"CLEAR", "TALK", "MOUSE",
 	"MAP", "COUNT", "MIDI",
-	"SETDLG", "MSKDLG",
 	".DUMMY.",
 	"WAIT", "HIDE", "ROOM",
 	"SAY", "SOUND", "TIME", "KILL",
 	"RSEQ", "SEQ", "SEND", "SWAP",
 	"KEEP", "GIVE",
-	"GETPOS", "GOTO", "MOVEX", "MOVEY",
-	"MOVEZ", "TRANS", "PORT",
+	"GETPOS", "GOTO", "PORT",
 	"NEXT", "NNEXT", "MTNEXT", "FTNEXT",
 	"RNNEXT", "RMTNEXT", "RFTNEXT",
 	"RMNEAR", "RMMTAKE", "RMFTAKE",
-	"SETREF", "BACKPT",
+	"SETREF",
 	"WALKTO", "REACH", "COVER", "UNCOVER",
 	nullptr };
 
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 6b0bdea..a83926a 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -44,8 +44,6 @@ enum CommandType {
 	kCmdPause,   // PAUSE -1 <dly>            :: delay <dly>/72 seconds
 	kCmdInf,     // INF -1 <ref>              :: show text referrenced by <ref>
 	kCmdCave,    // CAVE -1 <cav>             :: go to board <cav>
-	kCmdSlave,   // SLAVE
-	kCmdFocus,   // FOCUS                     :: change active hero
 	kCmdSetX,    // SETX <x> <idx>            :: set sprite shift in x axis
 	kCmdSetY,    // SETX <y> <idx>            :: set sprite shift in y axis
 	kCmdSetZ,    // SETX <z> <idx>            :: set sprite shift in z axis
@@ -54,9 +52,7 @@ enum CommandType {
 	kCmdMul,     // MUL <idx> <nr>            :: multiply vector by number
 	kCmdDiv,     // DIV <idx> <nr>            :: divide vector by number
 	kCmdIf,      // IF
-	kCmdFlag,    // FLAG <nr> <val>           :: set flag <nr> to <val>
 	kCmdFlash,   // FLASH -1 0|1              :: lighten whole image (on/off)
-	kCmdLight,   // LIGHT
 	kCmdCycle,   // CYCLE <cnt>               :: rotate <cnt> colors from 1
 	kCmdClear,   // CLEAR -1 0                :: clear kCmdAIL queue
 	kCmdTalk,    // TALK -1 0|1               :: enable speach (on/off)
@@ -64,8 +60,6 @@ enum CommandType {
 	kCmdMap,     // MAP  0|1 0                :: temporarily turn off map for hero
 	kCmdCount,   // COUNT
 	kCmdMidi,    // MIDI -1 <midi>            :: play MIDI referenced by <midi> (-1 = off)
-	kCmdSetDlg,  // SETDLG 0..3 0..3          :: switch of speach mode
-	kCmdMskDlg,  // MSKDLG 0..3 0..3          :: switch of speach mode mask
 
 	kCmdSpr,
 
@@ -84,10 +78,6 @@ enum CommandType {
 	kCmdGive,    // GIVE <spr> <seq>          :: remove sprite from pocket and jump to <seq>
 	kCmdGetPos,  // GETPOS <spr> <idx>        :: take sprite's position
 	kCmdGoto,    // GOTO <spr> <idx>          :: move sprite to position
-	kCmdMoveX,   // MOVEX <spr> <dx>          :: relative move along X axis
-	kCmdMoveY,   // MOVEY <spr> <dy>          :: relative move along Y axis
-	kCmdMoveZ,   // MOVEZ <spr> <dz>          :: relative move along Z axis
-	kCmdTrans,   // TRANS <spr> 0|1           :: clear/set logical transparency
 	kCmdPort,    // PORT <spr> 0|1            :: clear/set "takeability" of sprite
 	kCmdNext,    // NEXT <spr> <nr>           :: jump to <nr> - NEAR or TAKE
 	kCmdNNext,   // NNEXT <spr> <nr>          :: jump to <nr> - NEAR
@@ -99,8 +89,7 @@ enum CommandType {
 	kCmdRMNear,  // RMNEAR <spr> 0            :: remove NEAR list
 	kCmdRMMTake, // RMMTAKE <spr> 0           :: remove TAKE list
 	kCmdRMFTake, // RMFTAKE <spr> 0           :: remove TAKE list
-	kCmdSetRef,  // RETREF <spr> <ref>        :: change reference of sprite <spr> to <ref> 
-	kCmdBackPt,  // BACKPT <spr> 0            :: paint sprite onto the background
+	kCmdSetRef,  // RETREF <spr> <ref>        :: change reference of sprite <spr> to <ref>
 	kCmdWalk,    // WALK <hero> <ref>|<point> :: go close to the sprite or point
 	kCmdReach,   // REACH <hero> <ref>|<m>    :: reach the sprite or point with <m> method
 	kCmdCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>


Commit: 6caee925df370a4d0b19c5ce37cbd52a91464d25
    https://github.com/scummvm/scummvm/commit/6caee925df370a4d0b19c5ce37cbd52a91464d25
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T23:07:11+02:00

Commit Message:
CGE2: Fix typo in SETREF's comment.

Changed paths:
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index a83926a..48b65cb 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -89,7 +89,7 @@ enum CommandType {
 	kCmdRMNear,  // RMNEAR <spr> 0            :: remove NEAR list
 	kCmdRMMTake, // RMMTAKE <spr> 0           :: remove TAKE list
 	kCmdRMFTake, // RMFTAKE <spr> 0           :: remove TAKE list
-	kCmdSetRef,  // RETREF <spr> <ref>        :: change reference of sprite <spr> to <ref>
+	kCmdSetRef,  // SETREF <spr> <ref>        :: change reference of sprite <spr> to <ref>
 	kCmdWalk,    // WALK <hero> <ref>|<point> :: go close to the sprite or point
 	kCmdReach,   // REACH <hero> <ref>|<m>    :: reach the sprite or point with <m> method
 	kCmdCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>


Commit: 42f044012720563fed5e0899097548999d5537a4
    https://github.com/scummvm/scummvm/commit/42f044012720563fed5e0899097548999d5537a4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T23:16:12+02:00

Commit Message:
CGE2: Remove more unused opcodes.

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 5e889b2..e2f04cc 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -37,13 +37,13 @@ namespace CGE2 {
 const char *CommandHandler::_commandText[] = {
 	"NOP", "USE", "PAUSE", "INF", "CAVE",
 	"SETX", "SETY", "SETZ",
-	"ADD", "SUB", "MUL", "DIV", "IF",
+	"ADD",
 	"FLASH", "CYCLE",
-	"CLEAR", "TALK", "MOUSE",
-	"MAP", "COUNT", "MIDI",
+	"CLEAR", "MOUSE",
+	"MAP", "MIDI",
 	".DUMMY.",
 	"WAIT", "HIDE", "ROOM",
-	"SAY", "SOUND", "TIME", "KILL",
+	"SAY", "SOUND", "KILL",
 	"RSEQ", "SEQ", "SEND", "SWAP",
 	"KEEP", "GIVE",
 	"GETPOS", "GOTO", "PORT",
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 48b65cb..afe359b 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -48,17 +48,11 @@ enum CommandType {
 	kCmdSetY,    // SETX <y> <idx>            :: set sprite shift in y axis
 	kCmdSetZ,    // SETX <z> <idx>            :: set sprite shift in z axis
 	kCmdAdd,     // ADD <idx1> <idx2>         :: sum vectors
-	kCmdSub,     // SUB <idx1> <idx2>         :: subtract vectors
-	kCmdMul,     // MUL <idx> <nr>            :: multiply vector by number
-	kCmdDiv,     // DIV <idx> <nr>            :: divide vector by number
-	kCmdIf,      // IF
 	kCmdFlash,   // FLASH -1 0|1              :: lighten whole image (on/off)
 	kCmdCycle,   // CYCLE <cnt>               :: rotate <cnt> colors from 1
 	kCmdClear,   // CLEAR -1 0                :: clear kCmdAIL queue
-	kCmdTalk,    // TALK -1 0|1               :: enable speach (on/off)
 	kCmdMouse,   // MOUSE -1 0|1              :: enable mouse (on/off)
 	kCmdMap,     // MAP  0|1 0                :: temporarily turn off map for hero
-	kCmdCount,   // COUNT
 	kCmdMidi,    // MIDI -1 <midi>            :: play MIDI referenced by <midi> (-1 = off)
 
 	kCmdSpr,
@@ -68,7 +62,6 @@ enum CommandType {
 	kCmdRoom,    // ROOM <hero> 0|1           :: additional room in pocket (no/yes)
 	kCmdSay,     // SAY <spr> <ref>           :: say text referenced by <ref>
 	kCmdSound,   // SOUND <spr> <ref>         :: play sound effect referenced by <ref>
-	kCmdTime,    // TIME <spr> 0              :: say current time
 	kCmdKill,    // KILL <spr> 0              :: remove sprite
 	kCmdRSeq,    // RSEQ <spr> <nr>           :: relative jump SEQ <nr> lines
 	kCmdSeq,     // SEQ <spr> <seq>           :: jump to certain SEQ


Commit: b85e5dcfdb482b3bfa6a513537e88ccd1eb695fe
    https://github.com/scummvm/scummvm/commit/b85e5dcfdb482b3bfa6a513537e88ccd1eb695fe
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T23:19:02+02:00

Commit Message:
CGE2: Remove kCmdDim and kCmdStep and connected code.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 0c5492f..8d3f052 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -243,7 +243,6 @@ public:
 	void snReach(Sprite *spr, int val);
 	void snSound(Sprite *spr, int wav, Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType);
 	void snRoom(Sprite *spr, bool on);
-	void snDim(Sprite *spr, int val);
 	void snGhost(Bitmap *bmp);
 	void snSay(Sprite *spr, int val);
 	
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index e2f04cc..510dc2d 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -249,9 +249,6 @@ void CommandHandler::runCommand() {
 		case kCmdRoom:
 			_vm->snRoom(spr, tailCmd._val);
 			break;
-		case kCmdDim:
-			_vm->snDim(spr, tailCmd._val);
-			break;
 		case kCmdExec:
 			switch (tailCmd._cbType) {
 			case kQGame:
@@ -268,9 +265,6 @@ void CommandHandler::runCommand() {
 				break;
 			}
 			break;
-		case kCmdStep:
-			spr->step();
-			break;
 		case kCmdGhost:
 			_vm->snGhost((Bitmap *)tailCmd._spritePtr);
 			break;
@@ -626,15 +620,6 @@ void CGE2Engine::snRoom(Sprite *spr, bool on) {
 	}
 }
 
-void CGE2Engine::snDim(Sprite *spr, int val) {
-	if (isHero(spr)) {
-		if (val > 0)
-			++*(Hero*)spr;
-		else if (val < 0)
-			--*(Hero*)spr;
-	}
-}
-
 void CGE2Engine::snGhost(Bitmap *bmp) {
 	V2D p(this, bmp->_map & 0xFFFF, bmp->_map >> 16);
 	bmp->hide(p);
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index afe359b..66e35dc 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -88,9 +88,7 @@ enum CommandType {
 	kCmdCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>
 	kCmdUncover, // UNCOVER <sp1> <sp2>       :: restore the state before COVER
 
-	kCmdDim,
 	kCmdExec,
-	kCmdStep,
 	kCmdGhost,
 	
 	kCmdNOne = kNoByte


Commit: 8a1d0461878b3a38c385d9c6c4c294ee88eb3472
    https://github.com/scummvm/scummvm/commit/8a1d0461878b3a38c385d9c6c4c294ee88eb3472
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T23:22:46+02:00

Commit Message:
CGE2: Fix kCmdWalk's comment.

Changed paths:
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 66e35dc..ed6aae7 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -83,7 +83,7 @@ enum CommandType {
 	kCmdRMMTake, // RMMTAKE <spr> 0           :: remove TAKE list
 	kCmdRMFTake, // RMFTAKE <spr> 0           :: remove TAKE list
 	kCmdSetRef,  // SETREF <spr> <ref>        :: change reference of sprite <spr> to <ref>
-	kCmdWalk,    // WALK <hero> <ref>|<point> :: go close to the sprite or point
+	kCmdWalk,    // WALKTO <hero> <ref>|<point> :: go close to the sprite or point
 	kCmdReach,   // REACH <hero> <ref>|<m>    :: reach the sprite or point with <m> method
 	kCmdCover,   // COVER <sp1> <sp2>         :: cover sprite <sp1> with sprite <sp2>
 	kCmdUncover, // UNCOVER <sp1> <sp2>       :: restore the state before COVER


Commit: 737fc953a4a34b4d8cf020ba865dc4db18baef98
    https://github.com/scummvm/scummvm/commit/737fc953a4a34b4d8cf020ba865dc4db18baef98
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-24T23:25:09+02:00

Commit Message:
CGE2: Rearrange _commandText[]'s content.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 510dc2d..8a1340f 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -35,23 +35,12 @@
 namespace CGE2 {
 
 const char *CommandHandler::_commandText[] = {
-	"NOP", "USE", "PAUSE", "INF", "CAVE",
-	"SETX", "SETY", "SETZ",
-	"ADD",
-	"FLASH", "CYCLE",
-	"CLEAR", "MOUSE",
-	"MAP", "MIDI",
-	".DUMMY.",
-	"WAIT", "HIDE", "ROOM",
-	"SAY", "SOUND", "KILL",
-	"RSEQ", "SEQ", "SEND", "SWAP",
-	"KEEP", "GIVE",
-	"GETPOS", "GOTO", "PORT",
-	"NEXT", "NNEXT", "MTNEXT", "FTNEXT",
-	"RNNEXT", "RMTNEXT", "RFTNEXT",
-	"RMNEAR", "RMMTAKE", "RMFTAKE",
-	"SETREF",
-	"WALKTO", "REACH", "COVER", "UNCOVER",
+	"NOP", "USE", "PAUSE", "INF", "CAVE", "SETX", "SETY", "SETZ", "ADD",
+	"FLASH", "CYCLE", "CLEAR", "MOUSE", "MAP", "MIDI", ".DUMMY.", "WAIT",
+	"HIDE", "ROOM", "SAY", "SOUND", "KILL", "RSEQ", "SEQ", "SEND", "SWAP",
+	"KEEP", "GIVE", "GETPOS", "GOTO", "PORT", "NEXT", "NNEXT", "MTNEXT",
+	"FTNEXT", "RNNEXT", "RMTNEXT", "RFTNEXT", "RMNEAR", "RMMTAKE", "RMFTAKE",
+	"SETREF", "WALKTO", "REACH", "COVER", "UNCOVER",
 	nullptr };
 
 CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo)


Commit: d83a8162bb4e2795e158c48679b9f4db5cf6cc41
    https://github.com/scummvm/scummvm/commit/d83a8162bb4e2795e158c48679b9f4db5cf6cc41
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-25T10:55:53+02:00

Commit Message:
CGE2: Remove unused constant in Talk, fix a warning

Changed paths:
    engines/cge2/talk.cpp
    engines/cge2/talk.h



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index b086627..2e7f87d 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -53,7 +53,7 @@ void Font::load() {
 	char path[10];
 	strcpy(path, "CGE.CFT");
 	if (!_vm->_resman->exist(path))
-		error("Missing configuration file! %s", path);
+		error("Missing Font file! %s", path);
 
 	EncryptedStream fontFile(_vm, path);
 	assert(!fontFile.err());
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
index cddcdc2..ec4a347 100644
--- a/engines/cge2/talk.h
+++ b/engines/cge2/talk.h
@@ -41,7 +41,6 @@ namespace CGE2 {
 #define kPosSize           256
 #define kMapSize          (256*8)
 #define kFontHigh          8
-#define kFontExt           ".CFT"
 #define kCaptionSide       24
 #define kInfName           101
 #define kSayName           102


Commit: 72c8dbaf669c850ad4d4d91a7a1befaa48d7f56d
    https://github.com/scummvm/scummvm/commit/72c8dbaf669c850ad4d4d91a7a1befaa48d7f56d
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-25T10:58:54+02:00

Commit Message:
CGE2: Update another warning

Changed paths:
    engines/cge2/talk.cpp



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 2e7f87d..8e5773c 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -70,7 +70,7 @@ void Font::load() {
 
 	strcpy(path, "CGE.TXC");
 	if (!_vm->_resman->exist(path))
-		error("Missing configuration file! %s", path);
+		error("Missing Color file! %s", path);
 
 	// Reading in _colorSet:
 	EncryptedStream colorFile(_vm, path);


Commit: 3c0665edfa5fcbb1557aba3bc13c512f48f86dc6
    https://github.com/scummvm/scummvm/commit/3c0665edfa5fcbb1557aba3bc13c512f48f86dc6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T19:20:50+02:00

Commit Message:
CGE2: Rework loadUser().

Now initToolbar() works as intended both when starting a new game or when loading an old gamestate.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e4b34a0..87ab2de 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -643,9 +643,8 @@ void CGE2Engine::runGame() {
 
 	loadUser();
 
-	initToolbar();
-
 	sceneUp(_now);
+	initToolbar();
 
 	// main loop
 	while (!_endGame && !_quitFlag) {
@@ -666,12 +665,13 @@ void CGE2Engine::runGame() {
 
 void CGE2Engine::loadUser() {
 	loadPos();
+
 	if (_startGameSlot != -1)
 		loadGame(_startGameSlot);
-	else {
+	else
 		loadScript("CGE.INI");
-		loadHeroes();
-	}
+	
+	loadHeroes();
 }
 
 void CGE2Engine::loadHeroes() { // Original name: loadGame()
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 3c57e62..5e60f07 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -369,9 +369,7 @@ bool CGE2Engine::loadGame(int slotNumber) {
 	delete readStream;
 
 	syncSpeechSettings();
-	initToolbar();
-	loadHeroes();
-
+	
 	return true;
 }
 


Commit: aaf1f6a1a084ef1d5d40a4e8794014a62795b7db
    https://github.com/scummvm/scummvm/commit/aaf1f6a1a084ef1d5d40a4e8794014a62795b7db
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T20:24:10+02:00

Commit Message:
CGE2: Fix initialization of sound switches on the toolbar.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 5a5e345..d28215b 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -74,7 +74,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_music = true;
-	_oldMusicVolume = ConfMan.getInt("music_volume");
 	_startupMode = 1;
 	_now = 1;
 	_sex = 1;
@@ -94,11 +93,17 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_enaVox = true;
 	_sayCap = true;
 	_sayVox = true;
-	_oldSpeechVolume = ConfMan.getInt("speech_volume");
 	_req = 1;
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
 	_enaCap = true;
+	if (ConfMan.getBool("mute")) {
+		_oldSpeechVolume = _oldMusicVolume = _musicVolume = _sfxVolume = 0;
+	} else {
+		_oldSpeechVolume = ConfMan.getInt("speech_volume");
+		_oldMusicVolume = _musicVolume = ConfMan.getInt("music_volume");
+		_sfxVolume = ConfMan.getInt("sfx_volume");
+	}
 }
 
 void CGE2Engine::init() {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 8d3f052..e6c1308 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -113,6 +113,10 @@ struct SavegameHeader;
 #define kSavegameStrSize   12
 #define kSavegameStr       "SCUMMVM_CGE2"
 
+#define kSoundSwtichRate  25.7
+// == 257 / 10; where 10 equals to the sound switches' number of states
+// and ScummVM has a scale of 257 different values for setting sounds.
+
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
 };
@@ -283,6 +287,8 @@ public:
 	int _startGameSlot;
 	bool _enaCap;
 	bool _enaVox;
+	int _musicVolume;
+	int _sfxVolume;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 23c6fd1..08a21da 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -214,11 +214,10 @@ void CGE2Engine::initToolbar() {
 	_vol[0] = _vga->_showQ->locate(kDvolRef);
 	_vol[1] = _vga->_showQ->locate(kMvolRef);
 
-	// these sprites are loaded with SeqPtr==0 (why?!)
 	if (_vol[0])
-		_vol[0]->step((/*(int)SNDDrvInfo.VOL4.DL * */ _vol[0]->_seqCnt + _vol[0]->_seqCnt / 2) >> 4);
+		_vol[0]->step(_sfxVolume / kSoundSwtichRate);
 	if (_vol[1])
-		_vol[1]->step((/*(int)SNDDrvInfo.VOL4.ML * */ _vol[1]->_seqCnt + _vol[1]->_seqCnt / 2) >> 4);
+		_vol[1]->step(_musicVolume / kSoundSwtichRate);
 	// TODO: Recheck these! ^
 }
 


Commit: 22f1207cffa251a77748a0fe531ddb6ec000b332
    https://github.com/scummvm/scummvm/commit/22f1207cffa251a77748a0fe531ddb6ec000b332
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T20:27:05+02:00

Commit Message:
CGE2: Rename kSoundSwtichRate  to kVolumeSwitchRate.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index e6c1308..c23a101 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -113,8 +113,8 @@ struct SavegameHeader;
 #define kSavegameStrSize   12
 #define kSavegameStr       "SCUMMVM_CGE2"
 
-#define kSoundSwtichRate  25.7
-// == 257 / 10; where 10 equals to the sound switches' number of states
+#define kVolumeSwitchRate  25.7
+// == 257 / 10; where 10 equals to the volume switches' number of states
 // and ScummVM has a scale of 257 different values for setting sounds.
 
 enum CallbackType {
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 08a21da..eafdaf4 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -215,9 +215,9 @@ void CGE2Engine::initToolbar() {
 	_vol[1] = _vga->_showQ->locate(kMvolRef);
 
 	if (_vol[0])
-		_vol[0]->step(_sfxVolume / kSoundSwtichRate);
+		_vol[0]->step(_sfxVolume / kVolumeSwtichRate);
 	if (_vol[1])
-		_vol[1]->step(_musicVolume / kSoundSwtichRate);
+		_vol[1]->step(_musicVolume / kVolumeSwtichRate);
 	// TODO: Recheck these! ^
 }
 


Commit: 98c6bfa0f573861517466fe06220a3730d314f40
    https://github.com/scummvm/scummvm/commit/98c6bfa0f573861517466fe06220a3730d314f40
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T20:29:42+02:00

Commit Message:
CGE2: Fix broken compilation by previous commit.

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index eafdaf4..01943e2 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -215,9 +215,9 @@ void CGE2Engine::initToolbar() {
 	_vol[1] = _vga->_showQ->locate(kMvolRef);
 
 	if (_vol[0])
-		_vol[0]->step(_sfxVolume / kVolumeSwtichRate);
+		_vol[0]->step(_sfxVolume / kVolumeSwitchRate);
 	if (_vol[1])
-		_vol[1]->step(_musicVolume / kVolumeSwtichRate);
+		_vol[1]->step(_musicVolume / kVolumeSwitchRate);
 	// TODO: Recheck these! ^
 }
 


Commit: 9524f1d128df9588d0934ab3afa64f22d0df4fd0
    https://github.com/scummvm/scummvm/commit/9524f1d128df9588d0934ab3afa64f22d0df4fd0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T20:30:12+02:00

Commit Message:
CGE2: Remove useless TODO comment.

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 01943e2..529f0b51 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -218,7 +218,6 @@ void CGE2Engine::initToolbar() {
 		_vol[0]->step(_sfxVolume / kVolumeSwitchRate);
 	if (_vol[1])
 		_vol[1]->step(_musicVolume / kVolumeSwitchRate);
-	// TODO: Recheck these! ^
 }
 
 } // End of namespace CGE2


Commit: 668b133dabdf642ee08b53bab75a273c90cc9529
    https://github.com/scummvm/scummvm/commit/668b133dabdf642ee08b53bab75a273c90cc9529
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T22:24:36+02:00

Commit Message:
CGE2: Implement the music volume button on the toolbar.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c23a101..caf3922 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -113,10 +113,6 @@ struct SavegameHeader;
 #define kSavegameStrSize   12
 #define kSavegameStr       "SCUMMVM_CGE2"
 
-#define kVolumeSwitchRate  25.7
-// == 257 / 10; where 10 equals to the volume switches' number of states
-// and ScummVM has a scale of 257 different values for setting sounds.
-
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
 };
@@ -199,6 +195,7 @@ public:
 	void busyStep();
 	void checkSounds();
 	void checkMusicSwitch();
+	void checkVolumeSwitches();
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 87ab2de..65f856d 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -556,6 +556,7 @@ void CGE2Engine::mainLoop() {
 void CGE2Engine::checkSounds() {
 	_sound->checkSoundHandles();
 	checkSaySwitch();
+	checkVolumeSwitches();
 	checkMusicSwitch();
 	_midiPlayer->syncVolume();
 }
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 529f0b51..edabd12 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -35,6 +35,17 @@
 
 namespace CGE2 {
 
+#define kSoundNumtoStateRate  25.7
+// == 257 / 10; where 10 equals to the volume switches' number of states [0..9]
+// and ScummVM has a scale of 257 different values for setting sounds.
+
+#define kSoundStatetoNumRate  28.45
+// == 256 / 9 + 0.1; where 256 is the positive range of numbers we can set the volume to
+// and the 10 states of a switch cut this range up to 9 equally big parts.
+// We don't take into account 0 regarding the 256 different values (it would be the 257th),
+// since 0 * x == 0.
+// 0.1 is only for correct rounding at the 10th state.
+
 void CGE2Engine::optionTouch(int opt, uint16 mask) {
 	switch (opt) {
 	case 1:
@@ -52,6 +63,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 				break;
 			case true:
 				ConfMan.setInt("music_volume", _oldMusicVolume);
+				_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
 				break;
 			}
 		}
@@ -142,7 +154,46 @@ void CGE2Engine::quit() {
 }
 
 void CGE2Engine::setVolume(int idx, int cnt) {
-	warning("STUB: CGE2Engine::setVolume()");
+	if (cnt && _vol[idx]) {
+		int p = _vol[idx]->_seqPtr + cnt;
+		if (p >= 0 && p < _vol[idx]->_seqCnt) {
+			_vol[idx]->step(p);
+			int newVolume = p * kSoundStatetoNumRate;
+			switch (idx) {
+			case 0:
+				ConfMan.setInt("sfx_volume", newVolume);
+				break;
+			case 1:
+				if (newVolume == 0)
+					_oldMusicVolume = ConfMan.getInt("music_volume");
+				ConfMan.setInt("music_volume", newVolume);
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
+void CGE2Engine::checkVolumeSwitches() {
+	bool mute = false;
+	if (ConfMan.hasKey("mute"))
+		mute = ConfMan.getBool("mute");
+	bool musicMuted = mute;
+	int musicVolume = ConfMan.getInt("music_volume");
+	if (!musicMuted)
+		musicMuted = musicVolume == 0;
+	bool sfxMuted = mute;
+	int sfxVolume = ConfMan.getInt("sfx_volume");
+	if (!sfxMuted)
+		sfxMuted = sfxVolume == 0;
+	
+	if ((!musicMuted && !_music) || (musicVolume != _oldMusicVolume)) {
+		_vol[1]->step(musicVolume / kSoundNumtoStateRate);
+	}
+	if (musicMuted && _music) {
+		_vol[1]->step(0);
+	}
 }
 
 void CGE2Engine::switchCap() {
@@ -215,9 +266,9 @@ void CGE2Engine::initToolbar() {
 	_vol[1] = _vga->_showQ->locate(kMvolRef);
 
 	if (_vol[0])
-		_vol[0]->step(_sfxVolume / kVolumeSwitchRate);
+		_vol[0]->step(_sfxVolume / kSoundNumtoStateRate);
 	if (_vol[1])
-		_vol[1]->step(_musicVolume / kVolumeSwitchRate);
+		_vol[1]->step(_musicVolume / kSoundNumtoStateRate);
 }
 
 } // End of namespace CGE2


Commit: 944465431a4b0d4c8372456e52720f7baf5865ec
    https://github.com/scummvm/scummvm/commit/944465431a4b0d4c8372456e52720f7baf5865ec
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T22:32:18+02:00

Commit Message:
CGE2: Implement the sfx volume button on the toolbar.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index d28215b..9dbbf7d 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -74,6 +74,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
 	_music = true;
+	_sfx = true;
 	_startupMode = 1;
 	_now = 1;
 	_sex = 1;
@@ -102,7 +103,7 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	} else {
 		_oldSpeechVolume = ConfMan.getInt("speech_volume");
 		_oldMusicVolume = _musicVolume = ConfMan.getInt("music_volume");
-		_sfxVolume = ConfMan.getInt("sfx_volume");
+		_oldSfxVolume = _sfxVolume = ConfMan.getInt("sfx_volume");
 	}
 }
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index caf3922..613168e 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -260,7 +260,9 @@ public:
 	bool _quitFlag;
 	Dac *_bitmapPalette;
 	bool _music;
+	bool _sfx;
 	int _oldMusicVolume;
+	int _oldSfxVolume;
 	int _startupMode;
 	int _now;
 	int _sex;
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index edabd12..bf538b5 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -194,6 +194,16 @@ void CGE2Engine::checkVolumeSwitches() {
 	if (musicMuted && _music) {
 		_vol[1]->step(0);
 	}
+
+	if ((!sfxMuted && !_sfx) || (sfxVolume != _oldSfxVolume)) {
+		_vol[0]->step(sfxVolume / kSoundNumtoStateRate);
+		_oldSfxVolume = sfxVolume;
+		_sfx = true;
+	}
+	if (sfxMuted && _sfx) {
+		_vol[0]->step(0);
+		_sfx = false;
+	}
 }
 
 void CGE2Engine::switchCap() {


Commit: eaddafdea707c03a7f4c6be0e7c24aafaae4dd34
    https://github.com/scummvm/scummvm/commit/eaddafdea707c03a7f4c6be0e7c24aafaae4dd34
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T22:34:39+02:00

Commit Message:
CGE2: Get rid of unnecessary variables.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 9dbbf7d..985a77a 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -99,11 +99,11 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_spriteNotify = nullptr;
 	_enaCap = true;
 	if (ConfMan.getBool("mute")) {
-		_oldSpeechVolume = _oldMusicVolume = _musicVolume = _sfxVolume = 0;
+		_oldSpeechVolume = _oldMusicVolume = _oldSfxVolume = 0;
 	} else {
 		_oldSpeechVolume = ConfMan.getInt("speech_volume");
-		_oldMusicVolume = _musicVolume = ConfMan.getInt("music_volume");
-		_oldSfxVolume = _sfxVolume = ConfMan.getInt("sfx_volume");
+		_oldMusicVolume = ConfMan.getInt("music_volume");
+		_oldSfxVolume = ConfMan.getInt("sfx_volume");
 	}
 }
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 613168e..987a773 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -286,8 +286,6 @@ public:
 	int _startGameSlot;
 	bool _enaCap;
 	bool _enaVox;
-	int _musicVolume;
-	int _sfxVolume;
 
 	ResourceManager *_resman;
 	Vga *_vga;
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index bf538b5..d8687e3 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -276,9 +276,9 @@ void CGE2Engine::initToolbar() {
 	_vol[1] = _vga->_showQ->locate(kMvolRef);
 
 	if (_vol[0])
-		_vol[0]->step(_sfxVolume / kSoundNumtoStateRate);
+		_vol[0]->step(ConfMan.getInt("sfx_volume") / kSoundNumtoStateRate);
 	if (_vol[1])
-		_vol[1]->step(_musicVolume / kSoundNumtoStateRate);
+		_vol[1]->step(ConfMan.getInt("music_volume") / kSoundNumtoStateRate);
 }
 
 } // End of namespace CGE2


Commit: ac178b6013f3a1b090cfca1d8e9e2ad6429f4e77
    https://github.com/scummvm/scummvm/commit/ac178b6013f3a1b090cfca1d8e9e2ad6429f4e77
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T22:43:20+02:00

Commit Message:
CGE2: Fix optionTouch().

Now you can't change the sound options via the toolbar if the Mute All option is checked in the GGM/Launcher.

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index d8687e3..2242cc4 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -73,11 +73,11 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			quit();
 		break;
 	case 4:
-		if (mask & (kMouseLeftUp | kMouseRightUp))
+		if ((mask & (kMouseLeftUp | kMouseRightUp)) && !ConfMan.getBool("mute"))
 			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
 		break;
 	case 5:
-		if (mask & (kMouseLeftUp | kMouseRightUp))
+		if ((mask & (kMouseLeftUp | kMouseRightUp)) && !ConfMan.getBool("mute"))
 			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
 		break;
 	case 8:


Commit: 62e0a32a903321fd40234a245fd5b301ed50431c
    https://github.com/scummvm/scummvm/commit/62e0a32a903321fd40234a245fd5b301ed50431c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T22:53:49+02:00

Commit Message:
CGE2: Repair checkVolumeSwitches().

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 2242cc4..ce951f5 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -188,7 +188,8 @@ void CGE2Engine::checkVolumeSwitches() {
 	if (!sfxMuted)
 		sfxMuted = sfxVolume == 0;
 	
-	if ((!musicMuted && !_music) || (musicVolume != _oldMusicVolume)) {
+	if ((!musicMuted && !_music) ||
+		(musicVolume != _oldMusicVolume && !musicMuted)) {
 		_vol[1]->step(musicVolume / kSoundNumtoStateRate);
 	}
 	if (musicMuted && _music) {


Commit: 8a9a088b31dd01facf1f4dd9f1dd1d2cadbfa2d0
    https://github.com/scummvm/scummvm/commit/8a9a088b31dd01facf1f4dd9f1dd1d2cadbfa2d0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T22:59:39+02:00

Commit Message:
CGE2: Fix optionTouch().

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index ce951f5..93b5c64 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -60,6 +60,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			case false:
 				_oldMusicVolume = ConfMan.getInt("music_volume");
 				ConfMan.setInt("music_volume", 0);
+				_vol[1]->step(0);
 				break;
 			case true:
 				ConfMan.setInt("music_volume", _oldMusicVolume);


Commit: 870349078ec02f8d8921dd6bb32efd17cff68a24
    https://github.com/scummvm/scummvm/commit/870349078ec02f8d8921dd6bb32efd17cff68a24
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T23:05:23+02:00

Commit Message:
CGE2: Refactor optionTouch().

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 93b5c64..3556ec7 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -47,13 +47,14 @@ namespace CGE2 {
 // 0.1 is only for correct rounding at the 10th state.
 
 void CGE2Engine::optionTouch(int opt, uint16 mask) {
+	bool notMuted = !ConfMan.getBool("mute");
 	switch (opt) {
 	case 1:
 		if (mask & kMouseLeftUp)
 			switchColorMode();
 		break;
 	case 2:
-		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute")) {
+		if ((mask & kMouseLeftUp) && notMuted) {
 			switchMusic(_music = !_music);
 
 			switch (_music) {
@@ -74,11 +75,11 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			quit();
 		break;
 	case 4:
-		if ((mask & (kMouseLeftUp | kMouseRightUp)) && !ConfMan.getBool("mute"))
+		if ((mask & (kMouseLeftUp | kMouseRightUp)) && notMuted)
 			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
 		break;
 	case 5:
-		if ((mask & (kMouseLeftUp | kMouseRightUp)) && !ConfMan.getBool("mute"))
+		if ((mask & (kMouseLeftUp | kMouseRightUp)) && notMuted)
 			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
 		break;
 	case 8:
@@ -86,7 +87,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchCap();
 		break;
 	case 9:
-		if ((mask & kMouseLeftUp) && !ConfMan.getBool("mute")) {
+		if ((mask & kMouseLeftUp) && notMuted) {
 			switchVox();
 
 			switch (_sayVox) {


Commit: 85909a52e42fb1151322bd7b5601d042ff844fad
    https://github.com/scummvm/scummvm/commit/85909a52e42fb1151322bd7b5601d042ff844fad
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T23:08:02+02:00

Commit Message:
CGE2: Refactor optionTouch().

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 3556ec7..6c4a3e7 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -54,21 +54,8 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchColorMode();
 		break;
 	case 2:
-		if ((mask & kMouseLeftUp) && notMuted) {
+		if ((mask & kMouseLeftUp) && notMuted)
 			switchMusic(_music = !_music);
-
-			switch (_music) {
-			case false:
-				_oldMusicVolume = ConfMan.getInt("music_volume");
-				ConfMan.setInt("music_volume", 0);
-				_vol[1]->step(0);
-				break;
-			case true:
-				ConfMan.setInt("music_volume", _oldMusicVolume);
-				_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
-				break;
-			}
-		}
 		break;
 	case 3:
 		if (mask & kMouseLeftUp)
@@ -87,19 +74,8 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchCap();
 		break;
 	case 9:
-		if ((mask & kMouseLeftUp) && notMuted) {
+		if ((mask & kMouseLeftUp) && notMuted)
 			switchVox();
-
-			switch (_sayVox) {
-			case false:
-				_oldSpeechVolume = ConfMan.getInt("speech_volume");
-				ConfMan.setInt("speech_volume", 0);
-				break;
-			case true:
-				ConfMan.setInt("speech_volume", _oldSpeechVolume);
-				break;
-			}
-		}
 		break;
 	default:
 		break;
@@ -116,6 +92,18 @@ void CGE2Engine::switchMusic(bool on) {
 	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
 	keyClick();
 	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
+
+	switch (_music) {
+	case false:
+		_oldMusicVolume = ConfMan.getInt("music_volume");
+		ConfMan.setInt("music_volume", 0);
+		_vol[1]->step(0);
+		break;
+	case true:
+		ConfMan.setInt("music_volume", _oldMusicVolume);
+		_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
+		break;
+	}
 }
 
 void CGE2Engine::checkMusicSwitch() {
@@ -226,6 +214,16 @@ void CGE2Engine::switchVox() {
 			_sayCap = true;
 		keyClick();
 		switchSay();
+
+		switch (_sayVox) {
+		case false:
+			_oldSpeechVolume = ConfMan.getInt("speech_volume");
+			ConfMan.setInt("speech_volume", 0);
+			break;
+		case true:
+			ConfMan.setInt("speech_volume", _oldSpeechVolume);
+			break;
+		}
 	}
 }
 


Commit: 266f1c7dee502db432b047c1bef29595ba0ce332
    https://github.com/scummvm/scummvm/commit/266f1c7dee502db432b047c1bef29595ba0ce332
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T23:15:36+02:00

Commit Message:
Revert "CGE2: Refactor optionTouch()."

This reverts commit 85909a52e42fb1151322bd7b5601d042ff844fad.

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 6c4a3e7..3556ec7 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -54,8 +54,21 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchColorMode();
 		break;
 	case 2:
-		if ((mask & kMouseLeftUp) && notMuted)
+		if ((mask & kMouseLeftUp) && notMuted) {
 			switchMusic(_music = !_music);
+
+			switch (_music) {
+			case false:
+				_oldMusicVolume = ConfMan.getInt("music_volume");
+				ConfMan.setInt("music_volume", 0);
+				_vol[1]->step(0);
+				break;
+			case true:
+				ConfMan.setInt("music_volume", _oldMusicVolume);
+				_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
+				break;
+			}
+		}
 		break;
 	case 3:
 		if (mask & kMouseLeftUp)
@@ -74,8 +87,19 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchCap();
 		break;
 	case 9:
-		if ((mask & kMouseLeftUp) && notMuted)
+		if ((mask & kMouseLeftUp) && notMuted) {
 			switchVox();
+
+			switch (_sayVox) {
+			case false:
+				_oldSpeechVolume = ConfMan.getInt("speech_volume");
+				ConfMan.setInt("speech_volume", 0);
+				break;
+			case true:
+				ConfMan.setInt("speech_volume", _oldSpeechVolume);
+				break;
+			}
+		}
 		break;
 	default:
 		break;
@@ -92,18 +116,6 @@ void CGE2Engine::switchMusic(bool on) {
 	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
 	keyClick();
 	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
-
-	switch (_music) {
-	case false:
-		_oldMusicVolume = ConfMan.getInt("music_volume");
-		ConfMan.setInt("music_volume", 0);
-		_vol[1]->step(0);
-		break;
-	case true:
-		ConfMan.setInt("music_volume", _oldMusicVolume);
-		_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
-		break;
-	}
 }
 
 void CGE2Engine::checkMusicSwitch() {
@@ -214,16 +226,6 @@ void CGE2Engine::switchVox() {
 			_sayCap = true;
 		keyClick();
 		switchSay();
-
-		switch (_sayVox) {
-		case false:
-			_oldSpeechVolume = ConfMan.getInt("speech_volume");
-			ConfMan.setInt("speech_volume", 0);
-			break;
-		case true:
-			ConfMan.setInt("speech_volume", _oldSpeechVolume);
-			break;
-		}
 	}
 }
 


Commit: 5861b963ed4af0531052c2354159acdd57e661c7
    https://github.com/scummvm/scummvm/commit/5861b963ed4af0531052c2354159acdd57e661c7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T23:19:11+02:00

Commit Message:
CGE2: Now refactor optionTouch() the right way.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 987a773..9e85d03 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -196,6 +196,8 @@ public:
 	void checkSounds();
 	void checkMusicSwitch();
 	void checkVolumeSwitches();
+	void updateMusicVolume();
+	void updateSpeechVolume();
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 3556ec7..b6bcfd7 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -56,18 +56,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 	case 2:
 		if ((mask & kMouseLeftUp) && notMuted) {
 			switchMusic(_music = !_music);
-
-			switch (_music) {
-			case false:
-				_oldMusicVolume = ConfMan.getInt("music_volume");
-				ConfMan.setInt("music_volume", 0);
-				_vol[1]->step(0);
-				break;
-			case true:
-				ConfMan.setInt("music_volume", _oldMusicVolume);
-				_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
-				break;
-			}
+			updateMusicVolume();
 		}
 		break;
 	case 3:
@@ -89,16 +78,7 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 	case 9:
 		if ((mask & kMouseLeftUp) && notMuted) {
 			switchVox();
-
-			switch (_sayVox) {
-			case false:
-				_oldSpeechVolume = ConfMan.getInt("speech_volume");
-				ConfMan.setInt("speech_volume", 0);
-				break;
-			case true:
-				ConfMan.setInt("speech_volume", _oldSpeechVolume);
-				break;
-			}
+			updateSpeechVolume();
 		}
 		break;
 	default:
@@ -118,6 +98,20 @@ void CGE2Engine::switchMusic(bool on) {
 	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
 }
 
+void CGE2Engine::updateMusicVolume() {
+	switch (_music) {
+	case false:
+		_oldMusicVolume = ConfMan.getInt("music_volume");
+		ConfMan.setInt("music_volume", 0);
+		_vol[1]->step(0);
+		break;
+	case true:
+		ConfMan.setInt("music_volume", _oldMusicVolume);
+		_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
+		break;
+	}
+}
+
 void CGE2Engine::checkMusicSwitch() {
 	bool mute = false;
 	if (ConfMan.hasKey("mute"))
@@ -229,6 +223,18 @@ void CGE2Engine::switchVox() {
 	}
 }
 
+void CGE2Engine::updateSpeechVolume() {
+	switch (_sayVox) {
+	case false:
+		_oldSpeechVolume = ConfMan.getInt("speech_volume");
+		ConfMan.setInt("speech_volume", 0);
+		break;
+	case true:
+		ConfMan.setInt("speech_volume", _oldSpeechVolume);
+		break;
+	}
+}
+
 void CGE2Engine::switchSay() {
 	_commandHandlerTurbo->addCommand(kCmdSeq, 129, _sayVox, nullptr);
 	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);


Commit: 56da652e8f748155cea0269d3dec5f295905a9be
    https://github.com/scummvm/scummvm/commit/56da652e8f748155cea0269d3dec5f295905a9be
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T23:24:06+02:00

Commit Message:
CGE2: Rearrange things a bit in cge2.h.

Changed paths:
    engines/cge2/cge2.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 9e85d03..c5f7b54 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -151,7 +151,6 @@ public:
 	void inf(const char *text, ColorBank col = kCBInf);
 	void movie(const char *ext);
 	void runGame();
-	void initToolbar();
 	void loadHeroes();
 	void loadScript(const char *fname, bool onlyToolbar = false);
 	Sprite *loadSprite(const char *fname, int ref, int scene, V3D &pos);
@@ -177,8 +176,6 @@ public:
 	Sprite *locate(int ref);
 	bool isHero(Sprite *spr);
 	void loadUser();
-	void switchSay();
-	void checkSaySwitch();
 	void loadPos();
 	void releasePocket(Sprite *spr);
 	void switchHero(int sex);
@@ -193,19 +190,23 @@ public:
 	void keyClick();
 	void swapInPocket(Sprite *spr, Sprite *xspr);
 	void busyStep();
-	void checkSounds();
-	void checkMusicSwitch();
-	void checkVolumeSwitches();
-	void updateMusicVolume();
-	void updateSpeechVolume();
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
 	void switchMusic(bool on);
+	void updateMusicVolume();
+	void checkMusicSwitch();
 	void quit();
 	void setVolume(int idx, int cnt);
+	void checkVolumeSwitches();
 	void switchCap();
 	void switchVox();
+	void updateSpeechVolume();
+	void switchSay();
+	void checkSaySwitch();
+	void initToolbar();
+
+	void checkSounds();
 
 	void setEye(const V3D &e);
 	void setEye(const V2D& e2, int z = -kScrWidth);


Commit: 88286115c8dddfac4f45740c58a2e2d3a062be8d
    https://github.com/scummvm/scummvm/commit/88286115c8dddfac4f45740c58a2e2d3a062be8d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-25T23:34:58+02:00

Commit Message:
CGE2: More refactoring in cge2.h and cge2.cpp.

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



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 985a77a..b05fca8 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -70,11 +70,8 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 		_vol[i] = nullptr;
 	_eventManager = nullptr;
 	_map = nullptr;
-	
 	_quitFlag = false;
 	_bitmapPalette = nullptr;
-	_music = true;
-	_sfx = true;
 	_startupMode = 1;
 	_now = 1;
 	_sex = 1;
@@ -91,19 +88,23 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_endGame = false;
 	for (int i = 0; i < 4; i++)
 		_flag[i] = false;
-	_enaVox = true;
-	_sayCap = true;
-	_sayVox = true;
 	_req = 1;
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
+	
 	_enaCap = true;
+	_enaVox = true;
+	_sayCap = true;
+	_sayVox = true;
 	if (ConfMan.getBool("mute")) {
 		_oldSpeechVolume = _oldMusicVolume = _oldSfxVolume = 0;
+		_music = _sfx = false;
 	} else {
 		_oldSpeechVolume = ConfMan.getInt("speech_volume");
 		_oldMusicVolume = ConfMan.getInt("music_volume");
 		_oldSfxVolume = ConfMan.getInt("sfx_volume");
+		_music = _oldMusicVolume != 0;
+		_sfx = _oldSfxVolume != 0;
 	}
 }
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index c5f7b54..94263ac 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -262,10 +262,6 @@ public:
 
 	bool _quitFlag;
 	Dac *_bitmapPalette;
-	bool _music;
-	bool _sfx;
-	int _oldMusicVolume;
-	int _oldSfxVolume;
 	int _startupMode;
 	int _now;
 	int _sex;
@@ -280,15 +276,20 @@ public:
 	bool _taken;
 	bool _endGame;
 	bool _flag[4];
-	bool _sayCap;
-	bool _sayVox;
-	int _oldSpeechVolume;
 	int _req;
 	NotifyFunctionType _midiNotify;
 	NotifyFunctionType _spriteNotify;
 	int _startGameSlot;
+
 	bool _enaCap;
 	bool _enaVox;
+	bool _sayCap;
+	bool _sayVox;
+	int _oldSpeechVolume;
+	int _oldMusicVolume;
+	int _oldSfxVolume;
+	bool _music;
+	bool _sfx;
 
 	ResourceManager *_resman;
 	Vga *_vga;


Commit: 6ac879270f34c8de99f172a7d56c25e12339a106
    https://github.com/scummvm/scummvm/commit/6ac879270f34c8de99f172a7d56c25e12339a106
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-26T11:44:35+02:00

Commit Message:
CGE2: Repair display of version and translation strings.

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index ecb6183..914f125 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -64,7 +64,7 @@ bool Keyboard::getKey(Common::Event &event) {
 		if (event.type == Common::EVENT_KEYUP)
 			return false;
 		// Display ScummVM version and translation strings
-		for (int i = 0; i < 5; i++)
+		for (int i = 0; i < 3; i++)
 			_vm->_commandHandler->addCommand(kCmdInf, 1, kShowScummVMVersion + i, NULL);
 		return false;
 	case Common::KEYCODE_F5:


Commit: 8d21a21b6392bfd766780da3c7445241febcf81c
    https://github.com/scummvm/scummvm/commit/8d21a21b6392bfd766780da3c7445241febcf81c
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-26T12:08:54+02:00

Commit Message:
CGE2: Change random source.

Changed paths:
    engines/cge2/cge2.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index b05fca8..7c208d1 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -42,7 +42,7 @@
 namespace CGE2 {
 
 CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
-	: Engine(syst), _gameDescription(gameDescription), _randomSource("cge") {
+	: Engine(syst), _gameDescription(gameDescription), _randomSource("cge2") {
 	_resman = nullptr;
 	_vga = nullptr;
 	_midiPlayer = nullptr;


Commit: c78596a80e5dde89a37486417288be8cb65cc4b5
    https://github.com/scummvm/scummvm/commit/c78596a80e5dde89a37486417288be8cb65cc4b5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-26T12:52:27+02:00

Commit Message:
CGE2: Remove another unused opcode.

Changed paths:
    engines/cge2/snail.h



diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index ed6aae7..3026f07 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -90,8 +90,6 @@ enum CommandType {
 
 	kCmdExec,
 	kCmdGhost,
-	
-	kCmdNOne = kNoByte
 };
 
 class CommandHandler {


Commit: 0bfde974cde8eea024d66d35b5444ad4c1469701
    https://github.com/scummvm/scummvm/commit/0bfde974cde8eea024d66d35b5444ad4c1469701
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-26T12:59:39+02:00

Commit Message:
CGE2: Implement debug console and add a debug channel for opcodes.

Changed paths:
  A engines/cge2/console.h
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/events.cpp
    engines/cge2/module.mk
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 7c208d1..6f4c34c 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -27,6 +27,8 @@
 
 #include "engines/util.h"
 #include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
 #include "cge2/cge2.h"
 #include "cge2/bitmap.h"
 #include "cge2/vga13h.h"
@@ -43,6 +45,10 @@ namespace CGE2 {
 
 CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	: Engine(syst), _gameDescription(gameDescription), _randomSource("cge2") {
+
+	// Debug/console setup
+	DebugMan.addDebugChannel(kCGE2DebugOpcode, "opcode", "CGE2 opcode debug channel");
+
 	_resman = nullptr;
 	_vga = nullptr;
 	_midiPlayer = nullptr;
@@ -109,6 +115,9 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 }
 
 void CGE2Engine::init() {
+	// Create debugger console
+	_console = new CGE2Console(this);
+
 	_resman = new ResourceManager();
 	_vga = new Vga(this);
 	_fx = new Fx(this, 16);
@@ -137,6 +146,11 @@ void CGE2Engine::init() {
 }
 
 void CGE2Engine::deinit() {
+	// Remove all of our debug levels here
+	DebugMan.clearAllDebugChannels();
+
+	delete _console;
+
 	delete _spare;
 	delete _resman;
 	delete _vga;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 94263ac..833cb66 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -35,6 +35,7 @@
 #include "engines/advancedDetector.h"
 #include "common/system.h"
 #include "cge2/fileio.h"
+#include "cge2/console.h"
 #include "audio/mixer.h"
 
 namespace CGE2 {
@@ -113,6 +114,11 @@ struct SavegameHeader;
 #define kSavegameStrSize   12
 #define kSavegameStr       "SCUMMVM_CGE2"
 
+// our engine debug channels
+enum {
+	kCGE2DebugOpcode = 1 << 0,
+};
+
 enum CallbackType {
 	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
 };
@@ -128,6 +134,10 @@ private:
 	uint32 _lastFrame, _lastTick;
 	void tick();
 
+	CGE2Console *_console;
+	void init();
+	void deinit();
+
 	Common::String generateSaveName(int slot);
 	void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
 	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
@@ -143,6 +153,9 @@ public:
 	virtual Common::Error saveGameState(int slot, const Common::String &desc);
 	virtual Common::Error loadGameState(int slot);
 	virtual Common::Error run();
+	GUI::Debugger *getDebugger() {
+		return _console;
+	}
 
 	static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
 	bool showTitle(const char *name);
@@ -314,9 +327,6 @@ public:
 	Sprite *_vol[2];
 	EventManager *_eventManager;
 	Map *_map;
-private:
-	void init();
-	void deinit();
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/console.h b/engines/cge2/console.h
new file mode 100644
index 0000000..cb2120d
--- /dev/null
+++ b/engines/cge2/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 CGE2_CONSOLE_H
+#define CGE2_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace CGE2 {
+
+class CGE2Engine;
+
+class CGE2Console : public GUI::Debugger {
+public:
+	CGE2Console(CGE2Engine *vm) : GUI::Debugger(), _vm(vm) {}
+	virtual ~CGE2Console() {}
+
+private:
+	CGE2Engine *_vm;
+};
+
+} // End of namespace CGE
+
+#endif // CGE2_CONSOLE_H
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 914f125..25ca77f 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -89,14 +89,12 @@ bool Keyboard::getKey(Common::Event &event) {
 		}
 		return false;
 	case Common::KEYCODE_d:
-		/*
 		if (event.kbd.flags & Common::KBD_CTRL) {
 			// Start the debugger
 			_vm->getDebugger()->attach();
 			_vm->getDebugger()->onFrame();
 			return false;
 		}
-		*/
 		break;
 	case Common::KEYCODE_x:
 		if (event.kbd.flags & Common::KBD_ALT) {
diff --git a/engines/cge2/module.mk b/engines/cge2/module.mk
index 256087f..4b321d8 100644
--- a/engines/cge2/module.mk
+++ b/engines/cge2/module.mk
@@ -18,7 +18,8 @@ MODULE_OBJS = \
 	vmenu.o \
 	saveload.o \
 	toolbar.o \
-	inventory.o
+	inventory.o \
+	console.o
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_CGE2), DYNAMIC_PLUGIN)
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 8a1340f..ba33dd0 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -40,7 +40,7 @@ const char *CommandHandler::_commandText[] = {
 	"HIDE", "ROOM", "SAY", "SOUND", "KILL", "RSEQ", "SEQ", "SEND", "SWAP",
 	"KEEP", "GIVE", "GETPOS", "GOTO", "PORT", "NEXT", "NNEXT", "MTNEXT",
 	"FTNEXT", "RNNEXT", "RMTNEXT", "RFTNEXT", "RMNEAR", "RMMTAKE", "RMFTAKE",
-	"SETREF", "WALKTO", "REACH", "COVER", "UNCOVER",
+	"SETREF", "WALKTO", "REACH", "COVER", "UNCOVER", "EXEC", "GHOST",
 	nullptr };
 
 CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo)
@@ -102,6 +102,8 @@ void CommandHandler::runCommand() {
 		if (tailCmd._commandType > kCmdSpr)
 			spr = (tailCmd._ref < 0) ? ((Sprite *)tailCmd._spritePtr) : _vm->locate(tailCmd._ref);
 
+		debugC(1, kCGE2DebugOpcode, getComStr(tailCmd._commandType));
+
 		switch (tailCmd._commandType) {
 		case kCmdUse:
 			break;
@@ -742,6 +744,10 @@ int CommandHandler::getComId(const char *com) {
 	return (i < 0) ? i : i + kCmdCom0 + 1;
 }
 
+const char *CommandHandler::getComStr(CommandType cmdType) {
+	return _commandText[cmdType - kCmdNop];
+}
+
 void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 	if (!spr || !spr->active())
 		return;
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 3026f07..55da490 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -115,6 +115,7 @@ public:
 	void reset();
 	void clear();
 	int getComId(const char *com);
+	const char *getComStr(CommandType cmdType);
 private:
 	CGE2Engine *_vm;
 	bool _turbo;


Commit: 8e28a2c0d0fe03bf3ef0f6315ceeb637846f4881
    https://github.com/scummvm/scummvm/commit/8e28a2c0d0fe03bf3ef0f6315ceeb637846f4881
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-26T13:37:59+02:00

Commit Message:
CGE2: Make the debug channel of the opcodes more verbose.

Changed paths:
    engines/cge2/snail.cpp



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index ba33dd0..b4a78f0 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -102,7 +102,15 @@ void CommandHandler::runCommand() {
 		if (tailCmd._commandType > kCmdSpr)
 			spr = (tailCmd._ref < 0) ? ((Sprite *)tailCmd._spritePtr) : _vm->locate(tailCmd._ref);
 
-		debugC(1, kCGE2DebugOpcode, getComStr(tailCmd._commandType));
+		Common::String sprStr;
+		if (spr && spr->_file && tailCmd._commandType != kCmdGhost)
+			// In case of kCmdGhost _spritePtr stores a pointer to a Bitmap, not to a Sprite...
+			sprStr = Common::String(spr->_file);
+		else
+			sprStr = "None";
+		if (sprStr.empty())
+			sprStr = "None";
+		debugC(1, kCGE2DebugOpcode, "Command: %s; Ref: %d; Val: %d; Sprite: %s;", getComStr(tailCmd._commandType), tailCmd._ref, tailCmd._val, sprStr.c_str());
 
 		switch (tailCmd._commandType) {
 		case kCmdUse:


Commit: c394a685891cfab7d5f59233a5ca82cd0db92833
    https://github.com/scummvm/scummvm/commit/c394a685891cfab7d5f59233a5ca82cd0db92833
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-27T00:46:30+02:00

Commit Message:
CGE2: Fix misleading tabulation, improve warning

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index ea82fb7..617cb7d 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -124,7 +124,7 @@ BitmapPtr Sprite::getShp() {
 
 	int i = e->_seq[_seqPtr]._now;
 	if (i >= _shpCnt)
-		error("Invalid PHASE in SPRITE::Shp() %s", _file);
+		error("Invalid PHASE in SPRITE::Shp() %s - %d", _file, i);
 	return e->_shpList + i;
 }
 
@@ -393,7 +393,7 @@ Sprite *Sprite::expand() {
 
 		if (!shpcnt)
 			error("No shapes - %s", fname);
-		} else // no sprite description: try to read immediately from .BMP
+	} else // no sprite description: try to read immediately from .BMP
 		shplist[shpcnt++] = Bitmap(_vm, _file);
 
 	if (curSeq) {


Commit: 73784c26b7737f4474ec33974fb3abe156370025
    https://github.com/scummvm/scummvm/commit/73784c26b7737f4474ec33974fb3abe156370025
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-07-27T18:45:07+02:00

Commit Message:
CGE2: Add work around for piram_/pirami issue

Changed paths:
    engines/cge2/fileio.cpp



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 257e977..11a01c6 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -156,6 +156,12 @@ BtKeypack *ResourceManager::find(const char *key) {
 				if (scumm_stricmp((const char *)key, (const char *)pg->_leaf[i]._key) <= 0)
 					break;
 			}
+
+			// FIXME: Terrible hack to work around a mix between 24piram_ and 24pirami
+			if (!strcmp(key, "24piram_.SPR") && (scumm_stricmp((const char *)key, (const char *)pg->_leaf[i]._key) < 0))
+				++i;
+			//
+
 			_buff[lev]._index = i;
 			return &pg->_leaf[i];
 		}


Commit: ab2f720f379935a738c7c9a04d0cfc647c241467
    https://github.com/scummvm/scummvm/commit/ab2f720f379935a738c7c9a04d0cfc647c241467
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:17:12+02:00

Commit Message:
CGE2: Remove commas at the end of enumerator lists.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 833cb66..81b2071 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -116,7 +116,7 @@ struct SavegameHeader;
 
 // our engine debug channels
 enum {
-	kCGE2DebugOpcode = 1 << 0,
+	kCGE2DebugOpcode = 1 << 0
 };
 
 enum CallbackType {
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 55da490..62201a9 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -89,7 +89,7 @@ enum CommandType {
 	kCmdUncover, // UNCOVER <sp1> <sp2>       :: restore the state before COVER
 
 	kCmdExec,
-	kCmdGhost,
+	kCmdGhost
 };
 
 class CommandHandler {


Commit: cc7a70d967cc91d7829476f43550c28d0454f976
    https://github.com/scummvm/scummvm/commit/cc7a70d967cc91d7829476f43550c28d0454f976
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:17:13+02:00

Commit Message:
CGE2: Use if-else instead of switch-case with boolean values.

Changed paths:
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index b6bcfd7..e595074 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -99,16 +99,13 @@ void CGE2Engine::switchMusic(bool on) {
 }
 
 void CGE2Engine::updateMusicVolume() {
-	switch (_music) {
-	case false:
+	if (_music) {
+		ConfMan.setInt("music_volume", _oldMusicVolume);
+		_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
+	} else {
 		_oldMusicVolume = ConfMan.getInt("music_volume");
 		ConfMan.setInt("music_volume", 0);
 		_vol[1]->step(0);
-		break;
-	case true:
-		ConfMan.setInt("music_volume", _oldMusicVolume);
-		_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
-		break;
 	}
 }
 
@@ -224,14 +221,11 @@ void CGE2Engine::switchVox() {
 }
 
 void CGE2Engine::updateSpeechVolume() {
-	switch (_sayVox) {
-	case false:
+	if (_sayVox) {
+		ConfMan.setInt("speech_volume", _oldSpeechVolume);
+	} else {
 		_oldSpeechVolume = ConfMan.getInt("speech_volume");
 		ConfMan.setInt("speech_volume", 0);
-		break;
-	case true:
-		ConfMan.setInt("speech_volume", _oldSpeechVolume);
-		break;
 	}
 }
 


Commit: b9d13ae41dfa668b8937d333edb04e571e23c0ad
    https://github.com/scummvm/scummvm/commit/b9d13ae41dfa668b8937d333edb04e571e23c0ad
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:17:13+02:00

Commit Message:
CGE2: Get rid of unused variables in Bitmap.

Changed paths:
    engines/cge2/bitmap.h



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 159631e..12f7651 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -61,9 +61,6 @@ class Bitmap {
 	Common::String setExtension(const Common::String &str, const Common::String &ext);
 	bool loadVBM(EncryptedStream *f);
 public:
-	static uint8 *kSLDesign;
-	static uint8 *kSRDesign;
-
 	uint16 _w;
 	uint16 _h;
 	uint8 *_v;


Commit: fe77bfecf78d499bfb34e353e699e3d56a9f3a5a
    https://github.com/scummvm/scummvm/commit/fe77bfecf78d499bfb34e353e699e3d56a9f3a5a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:17:14+02:00

Commit Message:
CGE2: Rename Bitmap::paint() to makeSpeechBubleTail().

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index fd2f6a4..2c7c010 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -414,7 +414,7 @@ bool Bitmap::moveLo() {
 #define D               3,
 #define kDesignSize   240
 
-uint8 *Bitmap::paint(int which, uint8 colorSet[][4]) {
+uint8 *Bitmap::makeSpeechBubbleTail(int which, uint8 colorSet[][4]) {
 	uint8 kSLDesign[kDesignSize] = {
 		G G G G G G G G G _ _ _ _ _ _
 		L G G G G G G G G D _ _ _ _ _
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 12f7651..8643c37 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -85,7 +85,7 @@ public:
 	bool moveHi();
 	bool moveLo();
 
-	static uint8 *paint(int des, uint8 colorSet[][4]);
+	static uint8 *makeSpeechBubbleTail(int des, uint8 colorSet[][4]);
 };
 
 
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 617cb7d..4e43e9e 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1137,10 +1137,10 @@ void Bitmap::hide(V2D pos) {
 Speaker::Speaker(CGE2Engine *vm): Sprite(vm), _vm(vm) {
 	// Set the sprite list
 	BitmapPtr SP = new Bitmap[2];
-	uint8 *map = Bitmap::paint(0, _vm->_font->_colorSet);
+	uint8 *map = Bitmap::makeSpeechBubbleTail(0, _vm->_font->_colorSet);
 	SP[0] = Bitmap(_vm, 15, 16, map);
 	delete[] map;
-	map = Bitmap::paint(1, _vm->_font->_colorSet);
+	map = Bitmap::makeSpeechBubbleTail(1, _vm->_font->_colorSet);
 	SP[1] = Bitmap(_vm, 15, 16, map);
 	delete[] map;
 	setShapeList(SP, 2);


Commit: ae4adf4a9fd10a48fbdbb002d8686bd4560729ab
    https://github.com/scummvm/scummvm/commit/ae4adf4a9fd10a48fbdbb002d8686bd4560729ab
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:26:10+02:00

Commit Message:
CGE2: Move implementation of Console into a .cpp file.

Also get rid of unused _vm variable of it.

Changed paths:
  A engines/cge2/console.cpp
    engines/cge2/console.h



diff --git a/engines/cge2/console.cpp b/engines/cge2/console.cpp
new file mode 100644
index 0000000..c67c7ab
--- /dev/null
+++ b/engines/cge2/console.cpp
@@ -0,0 +1,33 @@
+/* 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 "cge2/console.h"
+
+namespace CGE2 {
+
+CGE2Console::CGE2Console(CGE2Engine *vm) : GUI::Debugger() {
+}
+
+CGE2Console::~CGE2Console() {
+}
+
+} // End of namespace CGE
diff --git a/engines/cge2/console.h b/engines/cge2/console.h
index cb2120d..15956bf 100644
--- a/engines/cge2/console.h
+++ b/engines/cge2/console.h
@@ -31,11 +31,8 @@ class CGE2Engine;
 
 class CGE2Console : public GUI::Debugger {
 public:
-	CGE2Console(CGE2Engine *vm) : GUI::Debugger(), _vm(vm) {}
-	virtual ~CGE2Console() {}
-
-private:
-	CGE2Engine *_vm;
+	CGE2Console(CGE2Engine *vm);
+	virtual ~CGE2Console();
 };
 
 } // End of namespace CGE


Commit: fca11e77f8620889d4c8eb8513a6fc0dc89e3a04
    https://github.com/scummvm/scummvm/commit/fca11e77f8620889d4c8eb8513a6fc0dc89e3a04
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:29:51+02:00

Commit Message:
CGE2: Get rid of more unused variables.

Changed paths:
    engines/cge2/fileio.h
    engines/cge2/snail.cpp
    engines/cge2/snail.h
    engines/cge2/sound.h



diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 0938507..0732b24 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -110,7 +110,6 @@ class EncryptedStream {
 private:
 	CGE2Engine *_vm;
 	Common::SeekableReadStream *_readStream;
-	const char **_tab;
 	int _lineCount;
 	bool _error;
 public:
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index b4a78f0..b6ae9db 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -46,7 +46,7 @@ const char *CommandHandler::_commandText[] = {
 CommandHandler::CommandHandler(CGE2Engine *vm, bool turbo)
 	: _turbo(turbo), _textDelay(false), _timerExpiry(0), _talkEnable(true),
       _head(0), _tail(0), _commandList((Command *)malloc(sizeof(Command)* 256)),
-      _count(1), _vm(vm) {
+      _vm(vm) {
 }
 
 CommandHandler::~CommandHandler() {
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 62201a9..82df181 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -121,10 +121,8 @@ private:
 	bool _turbo;
 	uint8 _head;
 	uint8 _tail;
-	bool _busy;
 	bool _textDelay;
 	uint32 _timerExpiry; // "pause" in the original.
-	int _count;
 };
 
 } // End of namespace CGE2
diff --git a/engines/cge2/sound.h b/engines/cge2/sound.h
index b97cd11..2960dc3 100644
--- a/engines/cge2/sound.h
+++ b/engines/cge2/sound.h
@@ -90,7 +90,6 @@ private:
 
 class Fx {
 	CGE2Engine *_vm;
-	int _size;
 
 	DataCk *loadWave(EncryptedStream *file);
 	Common::String name(int ref, int sub);


Commit: b911b66cc4ea2db2dcf869e1eba01f8aa7007ec6
    https://github.com/scummvm/scummvm/commit/b911b66cc4ea2db2dcf869e1eba01f8aa7007ec6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T16:40:06+02:00

Commit Message:
CGE2: Keep in sync the in-game color blind option with the Launcher's.

Changed paths:
    engines/cge2/toolbar.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index e595074..2604a2f 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -88,6 +88,8 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 
 void CGE2Engine::switchColorMode() {
 	_commandHandlerTurbo->addCommand(kCmdSeq, 121, _vga->_mono = !_vga->_mono, nullptr);
+	ConfMan.setBool("enable_color_blind", _vga->_mono);
+	ConfMan.flushToDisk();
 	keyClick();
 	_vga->setColors(_vga->_sysPal, 64);
 }
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 4e43e9e..c850db2 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -826,7 +826,7 @@ bool Queue::locate(Sprite *spr) {
 	return false;
 }
 
-Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(false), _mono(0), _vm(vm) {
+Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(false), _vm(vm) {
 	_oldColors = nullptr;
 	_newColors = nullptr;
 	_showQ = new Queue(true);
@@ -837,8 +837,7 @@ Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(fa
 		_page[idx]->create(kScrWidth, kScrHeight, Graphics::PixelFormat::createFormatCLUT8());
 	}
 
-	if (ConfMan.getBool("enable_color_blind"))
-		_mono = 1;
+	_mono = ConfMan.getBool("enable_color_blind");
 
 	_oldColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
 	_newColors = (Dac *)malloc(sizeof(Dac) * kPalCount);
@@ -849,8 +848,6 @@ Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(fa
 }
 
 Vga::~Vga() {
-	_mono = 0;
-
 	Common::String buffer = "";
 
 	free(_oldColors);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 77bece6..d98402e 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -318,7 +318,7 @@ class Vga {
 public:
 	uint32 _frmCnt;
 	Queue *_showQ;
-	int _mono;
+	bool _mono;
 	Graphics::Surface *_page[4];
 	Dac *_sysPal;
 


Commit: db6cab7a6f92855b2264f1899011346dc2e1b91d
    https://github.com/scummvm/scummvm/commit/db6cab7a6f92855b2264f1899011346dc2e1b91d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T20:40:42+02:00

Commit Message:
CGE2: Repair loading from savestate.

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 65f856d..2669ac9 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -669,10 +669,10 @@ void CGE2Engine::loadUser() {
 
 	if (_startGameSlot != -1)
 		loadGame(_startGameSlot);
-	else
+	else {
 		loadScript("CGE.INI");
-	
-	loadHeroes();
+		loadHeroes();
+	}
 }
 
 void CGE2Engine::loadHeroes() { // Original name: loadGame()
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 5e60f07..c468f65 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -369,6 +369,9 @@ bool CGE2Engine::loadGame(int slotNumber) {
 	delete readStream;
 
 	syncSpeechSettings();
+
+	loadHeroes();
+	initToolbar();
 	
 	return true;
 }


Commit: dd1637af9f8847be7077dc7962c1a4f4d527de95
    https://github.com/scummvm/scummvm/commit/dd1637af9f8847be7077dc7962c1a4f4d527de95
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-28T22:28:33+02:00

Commit Message:
CGE2: Fix initialization of Mouse.

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 25ca77f..ccddc25 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -129,7 +129,7 @@ void Keyboard::newKeyboard(Common::Event &event) {
 
 /*----------------- MOUSE interface -----------------*/
 
-Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(nullptr), _hold(nullptr), _hx(0), _point(_vm), _vm(vm) {
+Mouse::Mouse(CGE2Engine *vm) : Sprite(vm), _busy(nullptr), _hold(nullptr), _hx(0), _point(vm), _vm(vm) {
 	_hold = nullptr;
 	_hx = 0;
 	_hy = 0;


Commit: f538660c1558f6eb170bf82421cfe34155f6a9c3
    https://github.com/scummvm/scummvm/commit/f538660c1558f6eb170bf82421cfe34155f6a9c3
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T08:48:45+02:00

Commit Message:
CGE2: Fix graphic glitch at closing the game.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 2669ac9..8c16684 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -762,6 +762,7 @@ void CGE2Engine::cge2_main() {
 	if (_startGameSlot != -1) {
 		// Starting up a savegame from the launcher
 		runGame();
+		return;
 	}
 
 	if (showTitle("WELCOME")) {


Commit: d95a4c5f726c8c4e9259132a07857d2c910ca1f8
    https://github.com/scummvm/scummvm/commit/d95a4c5f726c8c4e9259132a07857d2c910ca1f8
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T09:05:41+02:00

Commit Message:
CGE2: Get rid of _flag.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 6f4c34c..f175fce 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -92,8 +92,6 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_soundStat._ref[1] = 0;
 	_taken = false;
 	_endGame = false;
-	for (int i = 0; i < 4; i++)
-		_flag[i] = false;
 	_req = 1;
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 81b2071..7fd5431 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -288,7 +288,6 @@ public:
 	} _soundStat;
 	bool _taken;
 	bool _endGame;
-	bool _flag[4];
 	int _req;
 	NotifyFunctionType _midiNotify;
 	NotifyFunctionType _spriteNotify;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 8c16684..d07eef3 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -648,11 +648,8 @@ void CGE2Engine::runGame() {
 	initToolbar();
 
 	// main loop
-	while (!_endGame && !_quitFlag) {
-		if (_flag[3]) // Flag FINIS
-			_commandHandler->addCallback(kCmdExec, -1, 0, kQGame);
+	while (!_endGame && !_quitFlag)
 		mainLoop();
-	}
 
 	// If finishing game due to closing ScummVM window, explicitly save the game
 	if (!_endGame && canSaveGameStateCurrently())
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index c468f65..30d6b3d 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -286,6 +286,8 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 }
 
 void CGE2Engine::syncHeader(Common::Serializer &s) {
+	int dummy = 0;
+
 	s.syncAsUint16LE(_now);
 	s.syncAsUint16LE(_sex);
 	s.syncAsUint16LE(_music);
@@ -294,7 +296,7 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 	s.syncAsUint16LE(_sayCap);
 	s.syncAsUint16LE(_sayVox);
 	for (int i = 0; i < 4; i++)
-		s.syncAsUint16LE(_flag[i]);
+		s.syncAsUint16LE(dummy); // _flag
 
 	if (s.isSaving()) {
 		// Write checksum


Commit: 5016e09acf8884a9a06bc7871b564d3070875222
    https://github.com/scummvm/scummvm/commit/5016e09acf8884a9a06bc7871b564d3070875222
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T09:06:14+02:00

Commit Message:
CGE2: Don't bother with  saving/loading sound options.

We always get them for the setting of the Launcher.

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 30d6b3d..ecf55d2 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -290,11 +290,11 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 
 	s.syncAsUint16LE(_now);
 	s.syncAsUint16LE(_sex);
-	s.syncAsUint16LE(_music);
+	s.syncAsUint16LE(dummy); // _music
 	s.syncAsUint16LE(_waitSeq);
 	s.syncAsUint16LE(_waitRef);
-	s.syncAsUint16LE(_sayCap);
-	s.syncAsUint16LE(_sayVox);
+	s.syncAsUint16LE(dummy); // _sayCap
+	s.syncAsUint16LE(dummy); // _sayVox
 	for (int i = 0; i < 4; i++)
 		s.syncAsUint16LE(dummy); // _flag
 


Commit: d4e14253c45ef9e747a7b1e5082a959fa61c0eb5
    https://github.com/scummvm/scummvm/commit/d4e14253c45ef9e747a7b1e5082a959fa61c0eb5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T10:38:05+02:00

Commit Message:
CGE2: Implement snFlash().

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 7fd5431..d947f01 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -254,7 +254,7 @@ public:
 	void snRmMTake(Sprite *spr);
 	void snRmFTake(Sprite *spr);
 	void snSetRef(Sprite *spr, int val);
-	void snFlash(int val);
+	void snFlash(bool on);
 	void snCycle(int cnt);
 	void snWalk(Sprite *spr, int val);
 	void snReach(Sprite *spr, int val);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index b6ae9db..3fab991 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -555,8 +555,27 @@ void CGE2Engine::snSetRef(Sprite *spr, int val) {
 	}
 }
 
-void CGE2Engine::snFlash(int val) {
-	warning("STUB: CGE2Engine::snFlash()");
+void CGE2Engine::snFlash(bool on) {
+	if (on) {
+		Dac *pal = (Dac *)malloc(sizeof(Dac) * kPalCount);
+		if (pal) {
+			memcpy(pal, _vga->_sysPal, kPalSize);
+			for (int i = 0; i < kPalCount; i++) {
+				register int c;
+				c = pal[i]._r << 1;
+				pal[i]._r = (c < 64) ? c : 63;
+				c = pal[i]._g << 1;
+				pal[i]._g = (c < 64) ? c : 63;
+				c = pal[i]._b << 1;
+				pal[i]._b = (c < 64) ? c : 63;
+			}
+			_vga->setColors(pal, 64);
+		}
+
+		free(pal);
+	} else
+		_vga->setColors(_vga->_sysPal, 64);
+	_dark = false;
 }
 
 void CGE2Engine::snCycle(int cnt) {


Commit: df59c0d0f6f3f5193a769e8a7f31fd08fe9ee31e
    https://github.com/scummvm/scummvm/commit/df59c0d0f6f3f5193a769e8a7f31fd08fe9ee31e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T10:56:04+02:00

Commit Message:
CGE2: Remove not useful comment from switchScene().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index d07eef3..9bdd57a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -478,20 +478,6 @@ void CGE2Engine::sceneDown() {
 void CGE2Engine::switchScene(int scene) {
 	if (scene == _now)
 		return;
-	
-	/* TODO:: Recheck this flag-thing! As far as it seems it's only for checking if the game
-	   is being run from the CD-ROM. In this context, it's useless for us.
-
-	if (scene >= 0) {
-		if (!_flag[2]) // PROT
-			_flag[2] = true;
-		else {
-			int t = _text->getText(kCrackedText) ? kCrackedText : kExitOkText;
-			_commandHandler->addCommand(kCmdInf, -1, t, nullptr);
-			return;
-		}
-	}
-	*/
 
 	_req = scene;
 


Commit: 77610ad993cbfa6025a8e463ffce1c9f07ad3112
    https://github.com/scummvm/scummvm/commit/77610ad993cbfa6025a8e463ffce1c9f07ad3112
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T11:06:37+02:00

Commit Message:
CGE2: Get rid of kCrackedText.

Changed paths:
    engines/cge2/cge2.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index d947f01..00306e7 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -99,7 +99,6 @@ struct SavegameHeader;
 #define kVoxRef           129
 
 #define kExitOkText        40
-#define kCrackedText       44
 #define kOffUseCount      130
 #define kOffUseText       131
 


Commit: 3d69c67f9934731b452b6c66d71f2cd22b8a64fe
    https://github.com/scummvm/scummvm/commit/3d69c67f9934731b452b6c66d71f2cd22b8a64fe
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T11:09:05+02:00

Commit Message:
CGE2: Get rid of kExitOkText.

Changed paths:
    engines/cge2/cge2.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 00306e7..930995a 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -98,7 +98,6 @@ struct SavegameHeader;
 #define kCapRef           128
 #define kVoxRef           129
 
-#define kExitOkText        40
 #define kOffUseCount      130
 #define kOffUseText       131
 


Commit: 70f54c6609c5f3f66e4223d35a895b6a18e9a9a0
    https://github.com/scummvm/scummvm/commit/70f54c6609c5f3f66e4223d35a895b6a18e9a9a0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T11:12:35+02:00

Commit Message:
CGE2: Remove unused code.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index c850db2..6db73f4 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1008,11 +1008,6 @@ void Vga::show() {
 			if ((p && spr->_pos3D._z > p->_pos3D._z) ||
 				(n && spr->_pos3D._z < n->_pos3D._z)) {
 				_showQ->insert(_showQ->remove(spr));
-				if (s) {
-					//s->gotoxyz(V3D(s->_pos3D._x, s->_pos3D._y, spr->_pos3D._z));
-					//_showQ->insert(_showQ->remove(s), spr);
-					// These two lines are also commented out in the original.
-				}
 			}
 			spr->_flags._zmov = false;
 		}


Commit: 375a7c3b15ef68e95d7169973f7aaf144d7a35ac
    https://github.com/scummvm/scummvm/commit/375a7c3b15ef68e95d7169973f7aaf144d7a35ac
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T11:17:07+02:00

Commit Message:
CGE2: Implement snCycle, add stub for Vga::rotate().

Changed paths:
    engines/cge2/snail.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 3fab991..240b70a 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -579,7 +579,7 @@ void CGE2Engine::snFlash(bool on) {
 }
 
 void CGE2Engine::snCycle(int cnt) {
-	warning("STUB: CGE2Engine::snCycle()");
+	_vga->_rot._len = cnt;
 }
 
 void CGE2Engine::snWalk(Sprite *spr, int val) {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 6db73f4..856ee68 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -992,6 +992,7 @@ void Vga::show() {
 
 	_vm->_mouse->show();
 	update();
+	rotate();
 
 	for (Sprite *spr = _showQ->first(); spr; spr = spr->_next) {
 		spr->hide();
@@ -1033,6 +1034,10 @@ void Vga::update() {
 	g_system->updateScreen();
 }
 
+void Vga::rotate() {
+	warning("STUB: Vga::rotate()");
+}
+
 void Vga::clear(uint8 color) {
 	for (int paneNum = 0; paneNum < 4; paneNum++)
 		_page[paneNum]->fillRect(Common::Rect(0, 0, kScrWidth, kScrHeight), color);
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index d98402e..d8fe715 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -321,6 +321,7 @@ public:
 	bool _mono;
 	Graphics::Surface *_page[4];
 	Dac *_sysPal;
+	struct { uint8 _org, _len, _cnt, _dly; } _rot;
 
 	Vga(CGE2Engine *vm);
 	~Vga();
@@ -334,6 +335,7 @@ public:
 	void sunset();
 	void show();
 	void update();
+	void rotate();
 
 	void palToDac(const byte *palData, Dac *tab);
 	void dacToPal(const Dac *tab, byte *palData);


Commit: e828be1bf9ea8ac3cba5c46a8c7a838e06dca198
    https://github.com/scummvm/scummvm/commit/e828be1bf9ea8ac3cba5c46a8c7a838e06dca198
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T11:20:20+02:00

Commit Message:
CGE2: Initialize Vga::_rot properly.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 856ee68..1a85973 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -827,6 +827,11 @@ bool Queue::locate(Sprite *spr) {
 }
 
 Vga::Vga(CGE2Engine *vm) : _frmCnt(0), _msg(nullptr), _name(nullptr), _setPal(false), _vm(vm) {
+	_rot._org = 1;
+	_rot._len = 0;
+	_rot._cnt = 0;
+	_rot._dly = 1;
+
 	_oldColors = nullptr;
 	_newColors = nullptr;
 	_showQ = new Queue(true);


Commit: 6e00d80b4bbb49453ab736f5ea84cec2ddfa05af
    https://github.com/scummvm/scummvm/commit/6e00d80b4bbb49453ab736f5ea84cec2ddfa05af
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T11:52:57+02:00

Commit Message:
CGE2: Implement Vga::rotate().

Changed paths:
    engines/cge2/saveload.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index ecf55d2..c505358 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -290,7 +290,7 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 
 	s.syncAsUint16LE(_now);
 	s.syncAsUint16LE(_sex);
-	s.syncAsUint16LE(dummy); // _music
+	s.syncAsUint16LE(_vga->_rot._len);
 	s.syncAsUint16LE(_waitSeq);
 	s.syncAsUint16LE(_waitRef);
 	s.syncAsUint16LE(dummy); // _sayCap
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 1a85973..1cd2c95 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -1040,7 +1040,14 @@ void Vga::update() {
 }
 
 void Vga::rotate() {
-	warning("STUB: Vga::rotate()");
+	if (_rot._len) {
+		Dac c;
+		getColors(_newColors);
+		c = _newColors[_rot._org];
+		memmove(_newColors + _rot._org, _newColors + _rot._org + 1, (_rot._len - 1) * sizeof(Dac));
+		_newColors[_rot._org + _rot._len - 1] = c;
+		_setPal = true;
+	}
 }
 
 void Vga::clear(uint8 color) {


Commit: 95854c3a5743564aa2ef3e7c1d8ef21156ae7f2e
    https://github.com/scummvm/scummvm/commit/95854c3a5743564aa2ef3e7c1d8ef21156ae7f2e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T12:13:38+02:00

Commit Message:
CGE2: Get rid of sndSetVolume() and connected code.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 930995a..4febca3 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -118,7 +118,7 @@ enum {
 };
 
 enum CallbackType {
-	kNullCB = 0, kQGame, kXScene, kSoundSetVolume
+	kNullCB = 0, kQGame, kXScene
 };
 
 enum Action { kNear, kMTake, kFTake, kActions };
@@ -265,7 +265,6 @@ public:
 	Sprite *expandSprite(Sprite *spr);
 	void qGame();
 	void xScene();
-	void sndSetVolume();
 
 	const ADGameDescription *_gameDescription;
 
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 240b70a..54ef036 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -256,9 +256,6 @@ void CommandHandler::runCommand() {
 			case kXScene:
 				_vm->xScene();
 				break;
-			case kSoundSetVolume:
-				_vm->sndSetVolume();
-				break;
 			default:
 				error("Unknown Callback Type in SNEXEC");
 				break;
@@ -703,10 +700,6 @@ void CGE2Engine::xScene() {
 	sceneUp(_req);
 }
 
-void CGE2Engine::sndSetVolume() {
-	warning("STUB: CGE2Engine::sndSetVolume()");
-}
-
 void CommandHandler::addCommand(CommandType com, int ref, int val, void *ptr) {
 	if (ref == -2)
 		ref = 142 - _vm->_sex;


Commit: cee669e76325dd9f6dca12262faf61cbe0392828
    https://github.com/scummvm/scummvm/commit/cee669e76325dd9f6dca12262faf61cbe0392828
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T13:25:13+02:00

Commit Message:
CGE2: Implement setAutoColors().

Add a redefinition of closest() to do so.

Changed paths:
    engines/cge2/talk.cpp
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index 8e5773c..f6321d3 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -31,7 +31,16 @@
 namespace CGE2 {
 
 void CGE2Engine::setAutoColors() {
-	warning("STUB: CGE2Engine::setAutoColors()");
+	Dac def[4] = {
+		{ 0, 0, 0 },
+		{ 220 >> 2, 220 >> 2, 220 >> 2 },
+		{ 190 >> 2, 190 >> 2, 190 >> 2 },
+		{ 160 >> 2, 160 >> 2, 160 >> 2 },
+	};
+	Dac pal[kPalCount];
+	_vga->getColors(pal);
+	for (int i = 0; i < 4; i++)
+		_font->_colorSet[kCBRel][i] = _vga->closest(pal, def[i]);
 }
 
 Font::Font(CGE2Engine *vm) : _vm(vm) {
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 1cd2c95..62b070d 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -913,6 +913,28 @@ uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 col
 #undef f
 }
 
+uint8 Vga::closest(Dac *pal, Dac x) {
+	int exp = (sizeof(long) * 8 - 1);
+	long D = (1 << exp) - 1; // Maximume value of long.
+	long R = x._r;
+	long G = x._g;
+	long B = x._b;
+	int idx;
+	for (int n = 0; n < 256; n++) {
+		long dR = R - pal[n]._r;
+		long dG = G - pal[n]._g;
+		long dB = B - pal[n]._b,
+			d = dR * dR + dG * dG + dB * dB;
+		if (d < D) {
+			idx = n;
+			D = d;
+			if (!d)
+				break;
+		}
+	}
+	return idx;
+}
+
 uint8 *Vga::glass(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB) {
 	uint8 *x = (uint8 *)malloc(256);
 	if (x) {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index d8fe715..3ed5fd5 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -336,6 +336,7 @@ public:
 	void show();
 	void update();
 	void rotate();
+	uint8 closest(Dac *pal, Dac x);
 
 	void palToDac(const byte *palData, Dac *tab);
 	void dacToPal(const Dac *tab, byte *palData);


Commit: 800ff40219c44c0961ff02faaf75d692f0d9a98a
    https://github.com/scummvm/scummvm/commit/800ff40219c44c0961ff02faaf75d692f0d9a98a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T13:25:39+02:00

Commit Message:
CGE2: Move ColorBank and kColorNum to one place.

They are strongly connected.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/talk.h



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 4febca3..05afd26 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -112,6 +112,10 @@ struct SavegameHeader;
 #define kSavegameStrSize   12
 #define kSavegameStr       "SCUMMVM_CGE2"
 
+#define kColorNum           6
+
+enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
+
 // our engine debug channels
 enum {
 	kCGE2DebugOpcode = 1 << 0
@@ -123,8 +127,6 @@ enum CallbackType {
 
 enum Action { kNear, kMTake, kFTake, kActions };
 
-enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
-
 typedef void (CGE2Engine::*NotifyFunctionType)();
 
 class CGE2Engine : public Engine {
diff --git a/engines/cge2/talk.h b/engines/cge2/talk.h
index ec4a347..d748465 100644
--- a/engines/cge2/talk.h
+++ b/engines/cge2/talk.h
@@ -44,7 +44,6 @@ namespace CGE2 {
 #define kCaptionSide       24
 #define kInfName           101
 #define kSayName           102
-#define kColorNum          6
 
 class Font {
 	void load();


Commit: 02c0b419d6b28350c654eadccdb8fe7f1b1f1b7d
    https://github.com/scummvm/scummvm/commit/02c0b419d6b28350c654eadccdb8fe7f1b1f1b7d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T13:30:23+02:00

Commit Message:
CGE2: Remove unnecessary CHECKME comment.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 62b070d..b355268 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -590,7 +590,6 @@ void Sprite::gotoxyz(V2D pos) {
 	_flags._trim = (trim != 0);
 
 	if (!_follow) {
-		// CHECKME: Original was using Pos2d.Eye, which shouldn't make a difference (static var)
 		FXP m = _vm->_eye->_z / (_pos3D._z - _vm->_eye->_z);
 		_pos3D._x = (_vm->_eye->_x + (_vm->_eye->_x - _pos2D.x) / m);
 		_pos3D._x.round();


Commit: 2c5af2ae54c475167f6fae1b9792ef48dd01d86e
    https://github.com/scummvm/scummvm/commit/2c5af2ae54c475167f6fae1b9792ef48dd01d86e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T13:40:53+02:00

Commit Message:
CGE2: Remove unused functions from EncryptedStream.

Changed paths:
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 11a01c6..41ea1c1 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -222,22 +222,10 @@ uint32 EncryptedStream::read(byte *dataPtr, uint32 dataSize) {
 	return _readStream->read(dataPtr, dataSize);
 }
 
-unsigned EncryptedStream::readUint16BE() {
-	return _readStream->readUint16BE();
-}
-
-signed EncryptedStream::readSint16BE() {
-	return _readStream->readSint16BE();
-}
-
 signed EncryptedStream::readSint16LE() {
 	return _readStream->readSint16LE();
 }
 
-signed EncryptedStream::readUint16LE() {
-	return _readStream->readUint16LE();
-}
-
 uint32 EncryptedStream::readUint32LE() {
 	return _readStream->readUint32LE();
 }
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 0732b24..0f3755b 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -105,7 +105,6 @@ public:
 	bool exist(const char *name);
 };
 
-// TODO: Revise the whole class!
 class EncryptedStream {
 private:
 	CGE2Engine *_vm;
@@ -121,10 +120,7 @@ public:
 	int32 pos();
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
-	unsigned readUint16BE();
-	signed readSint16BE();
 	signed readSint16LE();
-	signed readUint16LE();
 	uint32 readUint32LE();
 	Common::String readLine();
 	int getLineCount() { return _lineCount; }


Commit: e51888d9cef36d8d9a329abbbd9198aaa555e7e4
    https://github.com/scummvm/scummvm/commit/e51888d9cef36d8d9a329abbbd9198aaa555e7e4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T15:59:43+02:00

Commit Message:
CGE2: Refactor Hero::expand() and Sprite::expand().

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index c9b8dc5..0b8e227 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -44,14 +44,10 @@ Hero::~Hero() {
 	contract();
 }
 
-Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bother with "labels" for example. TODO: Try to unify the two later!
+Sprite *Hero::expand() {
 	if (_ext)
 		return this;
 
-	Common::String str(_vm->_text->getText(_ref + 100));
-	char text[kLineMax + 1];
-	strcpy(text, str.c_str());
-
 	char fname[kMaxPath];
 	_vm->mergeExt(fname, _file, kSprExt);
 
@@ -61,149 +57,157 @@ Sprite *Hero::expand() { // It's very similar to Sprite's expand, but doesn't bo
 	if (_ext == nullptr)
 		error("No core %s", fname);
 
-	if (*_file) {
-		int cnt[kActions];
-		Seq *seq;
-		int section = kIdPhase;
-	
-		for (int i = 0; i < kDimMax; i++) {
-			if (_dim[i] != nullptr) {
-				delete[] _dim[i];
-				_dim[i] = nullptr;
-			}
-		}
+	if (!*_file)
+		return this;
 
-		for (int i = 0; i < kDimMax; i++) {
-			_dim[i] = new Bitmap[_shpCnt];
-			for (int j = 0; j < _shpCnt; j++)
-				_dim[i][j].setVM(_vm);
+	for (int i = 0; i < kDimMax; i++) {
+		if (_dim[i] != nullptr) {
+			delete[] _dim[i];
+			_dim[i] = nullptr;
 		}
+	}
+	for (int i = 0; i < kDimMax; i++) {
+		_dim[i] = new Bitmap[_shpCnt];
+		for (int j = 0; j < _shpCnt; j++)
+			_dim[i][j].setVM(_vm);
+	}
 
-		if (_seqCnt) {
-			seq = new Seq[_seqCnt];
-			if (seq == nullptr)
+	int cnt[kActions],
+		shpcnt = 0,
+		seqcnt = 0,
+		maxnow = 0,
+		maxnxt = 0;
+
+	for (int i = 0; i < kActions; i++)
+		cnt[i] = 0;
+
+	for (int i = 0; i < kActions; i++) {
+		byte n = _actionCtrl[i]._cnt;
+		if (n) {
+			_ext->_actions[i] = new CommandHandler::Command[n];
+			if (_ext->_actions[i] == nullptr)
 				error("No core %s", fname);
 		} else
-			seq = nullptr;
-
-		for (int i = 0; i < kActions; i++)
-			cnt[i] = 0;
-
-		for (int i = 0; i < kActions; i++) {
-			byte n = _actionCtrl[i]._cnt;
-			if (n) {
-				_ext->_actions[i] = new CommandHandler::Command[n];
-				if (_ext->_actions[i] == nullptr)
-					error("No core %s", fname);
-			} else
-				_ext->_actions[i] = nullptr;
-		}
+			_ext->_actions[i] = nullptr;
+	}
 
-		if (_vm->_resman->exist(fname)) { // sprite description file exist
-			EncryptedStream sprf(_vm, fname);
-			if (sprf.err())
-				error("Bad SPR [%s]", fname);
-
-			ID id;
-			Common::String line;
-			char tmpStr[kLineMax + 1];
-			int shpcnt = 0;
-			int seqcnt = 0;
-			int maxnow = 0;
-			int maxnxt = 0;
-
-			for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
-				if (line.empty())
-					continue;
+	Seq *curSeq;
+	if (_seqCnt) {
+		curSeq = new Seq[_seqCnt];
+		if (curSeq == nullptr)
+			error("No core %s", fname);
+	} else
+		curSeq = nullptr;
+
+	if (_vm->_resman->exist(fname)) { // sprite description file exist
+		EncryptedStream sprf(_vm, fname);
+		if (sprf.err())
+			error("Bad SPR [%s]", fname);
+
+		ID section = kIdPhase;
+		ID id;
+		Common::String line;
+		char tmpStr[kLineMax + 1];
+
+		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
+			if (line.empty())
+				continue;
+			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
+
+			char *p = _vm->token(tmpStr);
+
+			id = _vm->ident(p);
+			switch (id) {
+			case kIdNear:
+			case kIdMTake:
+			case kIdFTake:
+			case kIdPhase:
+			case kIdSeq:
+				section = id;
+				break;
+			case kIdName:
 				Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-
-				char *p = _vm->token(tmpStr);
-
-				id = _vm->ident(p);
-				switch (id) {
+				for (p = tmpStr; *p != '='; p++); // We search for the =
+				setName(_vm->tail(p));
+				break;
+			default:
+				if (id >= kIdNear)
+					break;
+				Seq *s;
+				switch (section) {
 				case kIdNear:
 				case kIdMTake:
 				case kIdFTake:
-				case kIdPhase:
-				case kIdSeq:
-					section = id;
-					break;
-				case kIdName:
-					Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
-					for (p = tmpStr; *p != '='; p++); // We search for the =
-					setName(_vm->tail(p));
+					id = (ID)_vm->_commandHandler->getComId(p);
+					if (_actionCtrl[section]._cnt) {
+						CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
+						c->_commandType = CommandType(id);
+						c->_ref = _vm->number(nullptr);
+						c->_val = _vm->number(nullptr);
+						c->_spritePtr = nullptr;
+					}
 					break;
-				default:
-					if (id >= kIdNear)
-						break;
-					Seq *s;
-					switch (section) {
-					case kIdNear:
-					case kIdMTake:
-					case kIdFTake:
-						id = (ID)_vm->_commandHandler->getComId(p);
-						if (_actionCtrl[section]._cnt) {
-							CommandHandler::Command *c = &_ext->_actions[section][cnt[section]++];
-							c->_commandType = CommandType(id);
-							c->_ref = _vm->number(nullptr);
-							c->_val = _vm->number(nullptr);
-							c->_spritePtr = nullptr;
-						}
-						break;
-					case kIdSeq:
-						s = &seq[seqcnt++];
-						s->_now = atoi(p);
-						if (s->_now > maxnow)
-							maxnow = s->_now;
-						s->_next = _vm->number(nullptr);
-						switch (s->_next) {
-						case 0xFF:
-							s->_next = seqcnt;
-							break;
-						case 0xFE:
-							s->_next = seqcnt - 1;
-							break;
-						}
-						if (s->_next > maxnxt)
-							maxnxt = s->_next;
-						s->_dx = _vm->number(nullptr);
-						s->_dy = _vm->number(nullptr);
-						s->_dz = _vm->number(nullptr);
-						s->_dly = _vm->number(nullptr);
+				case kIdSeq:
+					s = &curSeq[seqcnt++];
+					s->_now = atoi(p);
+					if (s->_now > maxnow)
+						maxnow = s->_now;
+					s->_next = _vm->number(nullptr);
+					switch (s->_next) {
+					case 0xFF:
+						s->_next = seqcnt;
 						break;
-					case kIdPhase:
-						for (int i = 0; i < kDimMax; i++) {
-							char *q = p;
-							q[1] = '0' + i;
-							Bitmap b(_vm, q);
-							if (!b.moveHi())
-								error("No EMS %s", q);
-							_dim[i][shpcnt] = b;
-							if (!shpcnt)
-								_hig[i] = b._h;
-						}
-						++shpcnt;
+					case 0xFE:
+						s->_next = seqcnt - 1;
 						break;
 					}
+					if (s->_next > maxnxt)
+						maxnxt = s->_next;
+					s->_dx = _vm->number(nullptr);
+					s->_dy = _vm->number(nullptr);
+					s->_dz = _vm->number(nullptr);
+					s->_dly = _vm->number(nullptr);
+					break;
+				case kIdPhase:
+					for (int i = 0; i < kDimMax; i++) {
+						char *q = p;
+						q[1] = '0' + i;
+						Bitmap b(_vm, q);
+						if (!b.moveHi())
+							error("No EMS %s", q);
+						_dim[i][shpcnt] = b;
+						if (!shpcnt)
+							_hig[i] = b._h;
+					}
+					++shpcnt;
+					break;
+				default:
+					break;
 				}
 			}
-			if (seq) {
-				if (maxnow >= shpcnt)
-					error("Bad PHASE in SEQ %s", fname);
-				if (maxnxt >= seqcnt)
-					error("Bad JUMP in SEQ %s", fname);
-				setSeq(seq);
-			} else
-				setSeq(_stdSeq8);
-
-			setShapeList(_dim[0], shpcnt);
 		}
+
+		if (curSeq) {
+			if (maxnow >= shpcnt)
+				error("Bad PHASE in SEQ %s", fname);
+			if (maxnxt >= seqcnt)
+				error("Bad JUMP in SEQ %s", fname);
+			setSeq(curSeq);
+		} else
+			setSeq(_stdSeq8);
+
+		setShapeList(_dim[0], shpcnt);
 	}
+
+	Common::String str(_vm->_text->getText(_ref + 100));
+	char text[kLineMax + 1];
+	strcpy(text, str.c_str());
 	_reachStart = atoi(_vm->token(text));
 	_reachCycle = atoi(_vm->token(nullptr));
 	_sayStart = atoi(_vm->token(nullptr));
 	_funStart = atoi(_vm->token(nullptr));
 	_funDel = _funDel0 = (72 / _ext->_seq[0]._dly) * atoi(_vm->token(nullptr));
+
 	int i = stepSize() / 2;
 	_maxDist = sqrt(double(i * i * 2));
 	setCurrent();
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index b355268..5f3cf18 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -278,14 +278,6 @@ Sprite *Sprite::expand() {
 		maxnow = 0,
 		maxnxt = 0;
 
-	Seq *curSeq;
-	if (_seqCnt) {
-		curSeq = new Seq[_seqCnt];
-		if (curSeq == nullptr)
-			error("No core %s", fname);
-	} else
-		curSeq = nullptr;
-
 	for (int i = 0; i < kActions; i++)
 		cnt[i] = 0;
 
@@ -299,6 +291,14 @@ Sprite *Sprite::expand() {
 			_ext->_actions[i] = nullptr;
 	}
 
+	Seq *curSeq;
+	if (_seqCnt) {
+		curSeq = new Seq[_seqCnt];
+		if (curSeq == nullptr)
+			error("No core %s", fname);
+	} else
+		curSeq = nullptr;
+
 	if (_vm->_resman->exist(fname)) { // sprite description file exist
 		EncryptedStream sprf(_vm, fname);
 		if (sprf.err())
@@ -376,13 +376,12 @@ Sprite *Sprite::expand() {
 					s->_dz = _vm->number(nullptr);
 					s->_dly = _vm->number(nullptr);
 					break;
-				case kIdPhase: {
+				case kIdPhase:
 					shplist[shpcnt] = Bitmap(_vm, p);
 					if (!shplist[shpcnt].moveHi())
 						error("No EMS");
 					shpcnt++;
 					break;
-				}
 				default:
 					break;
 				}


Commit: b33653000da25846bebe7a76c26337d49743884d
    https://github.com/scummvm/scummvm/commit/b33653000da25846bebe7a76c26337d49743884d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T16:13:29+02:00

Commit Message:
CGE2: Fix saving of moving heroes.

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index c505358..652dbea 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -230,6 +230,11 @@ void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &h
 	uint8 thumbPalette[256 * 3];
 	g_system->getPaletteManager()->grabPalette(thumbPalette, 0, 256);
 
+	// Stop the heroes from moving and redraw them before taking the picture.
+	for (int i = 0; i < 2; i++)
+		_heroTab[i]->_ptr->park();
+	_vga->show();
+	
 	// Create a thumbnail and save it
 	Graphics::Surface *thumb = new Graphics::Surface();
 	Graphics::Surface *s = _vga->_page[0];


Commit: fc8f6d9cfef1345774ef3dc4a0193033597a4b04
    https://github.com/scummvm/scummvm/commit/fc8f6d9cfef1345774ef3dc4a0193033597a4b04
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T16:27:18+02:00

Commit Message:
CGE2: Fix initialization of volume switches.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 05afd26..38b48aa 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -218,6 +218,7 @@ public:
 	void switchSay();
 	void checkSaySwitch();
 	void initToolbar();
+	void initVolumeSwitch(Sprite *volSwitch);
 
 	void checkSounds();
 
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 2604a2f..51614af 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -281,9 +281,16 @@ void CGE2Engine::initToolbar() {
 	_vol[1] = _vga->_showQ->locate(kMvolRef);
 
 	if (_vol[0])
-		_vol[0]->step(ConfMan.getInt("sfx_volume") / kSoundNumtoStateRate);
+		initVolumeSwitch(_vol[0]);
 	if (_vol[1])
-		_vol[1]->step(ConfMan.getInt("music_volume") / kSoundNumtoStateRate);
+		initVolumeSwitch(_vol[1]);
+}
+
+void CGE2Engine::initVolumeSwitch(Sprite *volSwitch) {
+	int state = 0;
+	if (!ConfMan.getBool("mute"))
+		state = ConfMan.getInt("sfx_volume") / kSoundNumtoStateRate;
+	volSwitch->step(state);
 }
 
 } // End of namespace CGE2


Commit: 4e32736e44a7bd90e34608d2ec7764b2ed260f52
    https://github.com/scummvm/scummvm/commit/4e32736e44a7bd90e34608d2ec7764b2ed260f52
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T16:41:56+02:00

Commit Message:
CGE2: Prevent the engine from entering an endless loop when loading.

Also remove CommandHandler::reset(), since it's not useful anymore.

Changed paths:
    engines/cge2/saveload.cpp
    engines/cge2/snail.cpp
    engines/cge2/snail.h



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 652dbea..b984a48 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -317,6 +317,8 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 }
 
 Common::Error CGE2Engine::loadGameState(int slot) {
+	_commandHandler->clear();
+	_commandHandlerTurbo->clear();
 	sceneDown();
 	if (!loadGame(slot))
 		return Common::kReadingFailed;
@@ -329,7 +331,6 @@ void CGE2Engine::resetGame() {
 	busy(false);
 	_spare->clear();
 	_vga->_showQ->clear();
-	_commandHandler->reset();
 	loadScript("CGE.INI", true);
 	delete _infoLine;
 	_infoLine = new InfoLine(this, kInfoW);
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 54ef036..48e8ffd 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -749,10 +749,6 @@ bool CommandHandler::idle() {
 	return (!_vm->_waitRef && _head == _tail);
 }
 
-void CommandHandler::reset() {
-	_tail = _head;
-}
-
 void CommandHandler::clear() {
 	_tail = _head;
 	_vm->killText();
diff --git a/engines/cge2/snail.h b/engines/cge2/snail.h
index 82df181..7e618da 100644
--- a/engines/cge2/snail.h
+++ b/engines/cge2/snail.h
@@ -112,7 +112,6 @@ public:
 	void addCallback(CommandType com, int ref, int val, CallbackType cbType);
 	void insertCommand(CommandType com, int ref, int val, void *ptr);
 	bool idle();
-	void reset();
 	void clear();
 	int getComId(const char *com);
 	const char *getComStr(CommandType cmdType);


Commit: 0b8a727a0e7538f4dd4040b3d741532fcac41920
    https://github.com/scummvm/scummvm/commit/0b8a727a0e7538f4dd4040b3d741532fcac41920
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T18:42:00+02:00

Commit Message:
CGE2: Repair computation of save checksum.

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index b984a48..78a0631 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -42,7 +42,7 @@
 
 namespace CGE2 {
 
-#define kSavegameCheckSum (1997 + _now + _music + kWorldHeight)
+#define kSavegameCheckSum (1997 + _now + kWorldHeight)
 #define kBadSVG           99
 
 struct SavegameHeader {


Commit: e5139cdd9cca259f22f47b2f55a15f4b32e0f047
    https://github.com/scummvm/scummvm/commit/e5139cdd9cca259f22f47b2f55a15f4b32e0f047
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-29T20:59:29+02:00

Commit Message:
CGE2: Fix loading during gameplay.

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 78a0631..63abe3a 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -323,6 +323,7 @@ Common::Error CGE2Engine::loadGameState(int slot) {
 	if (!loadGame(slot))
 		return Common::kReadingFailed;
 	sceneUp(_now);
+	initToolbar();
 	return Common::kNoError;
 }
 
@@ -379,7 +380,6 @@ bool CGE2Engine::loadGame(int slotNumber) {
 	syncSpeechSettings();
 
 	loadHeroes();
-	initToolbar();
 	
 	return true;
 }


Commit: 4139e79fccbc47c4d291371c8baf79b6e143eb62
    https://github.com/scummvm/scummvm/commit/4139e79fccbc47c4d291371c8baf79b6e143eb62
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-07-29T20:23:02-04:00

Commit Message:
CGE2: Fixes for the FXP class

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 5f3cf18..105fd3f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -46,8 +46,7 @@ void V3D::sync(Common::Serializer &s) {
 }
 
 void FXP::sync(Common::Serializer &s) {
-	s.syncAsUint16LE(f);
-	s.syncAsSint16LE(i);
+	s.syncAsSint32LE(v);
 }
 
 Seq *getConstantSeq(bool seqFlag) {
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 3ed5fd5..f3354c5 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -53,68 +53,28 @@ namespace CGE2 {
 
 // From FXP.H
 class FXP { // fixed point
-	uint16 f;
-	int16 i;
-	long getJoined() const {
-		long ret = 0;
-		ret += f;
-		ret += i << 16;
-		return ret;
-	}
-	void setJoined(long joined) {
-		i = joined >> 16;
-		f = joined;
-	}
+	int32 v;
 public:
-	FXP (void): f(0), i(0) { }
-	FXP (int i0, int f0 = 0) : i(i0), f(0) { }
-	FXP& operator=(const int& x) { i = x; f = 0; return *this; }
-	FXP operator+(const FXP& x) const { FXP y; y.setJoined(getJoined() + x.getJoined()); return y; }
-	FXP operator-(const FXP& x) const { FXP y; y.setJoined(getJoined() - x.getJoined()); return y; }
-	FXP operator*(const FXP& x) const {
-		FXP y; long t;
-		y.i = i * x.i;
-		t = ((long) f * x.f) >> 16;
-		t += ((long) i * x.f) + ((long) f * x.i);
-		y.f = t & 0xFFFF;
-		y.i += t >> 16;
-		return y;
-	}
-	FXP operator/(const FXP& x) const {
-		FXP y; bool sign = false;
-		if (!x.empty()) {
-			long j = getJoined(), jx = x.getJoined();
-			if (j < 0) {
-				j = -j;
-				sign ^= 1;
-			}
-			if (jx < 0) {
-				jx = -jx;
-				sign ^= 1;
-			}
-			y.i = signed(j / jx);
-			long r = j - jx * y.i;
-			//-- binary division
-			y.f = unsigned((r << 4) / (jx >> 12));
-			//------------------
-			if (sign)
-				y.setJoined(-y.getJoined());
-		}
+	FXP(void) : v(0) {}
+	FXP (int i0, int f0 = 0) : v((i0 * 256) + ((i0 < 0) ? -f0 : f0)) {}
+	FXP& operator=(const int& x) { v = x << 8; return *this; }
+	FXP operator+(const FXP& x) const { FXP y; y.v = v + x.v; return y; }
+	FXP operator-(const FXP& x) const { FXP y; y.v = v - x.v; return y; }
+	FXP operator*(const FXP& x) const { FXP y; y.v = v * x.v / 256; return y; }
+	FXP operator/(const FXP& x) const { FXP y; y.v = (x.v == 0) ? 0 : v * 256 / x.v; return y; }
 
-		return y;
-	}
 	//int& operator = (int& a, const FXP& b) { return a = b.i; }
-	friend int& operator+=(int& a, const FXP& b) { return a += b.i; }
-	friend int& operator-=(int& a, const FXP& b) { return a -= b.i; }
-	friend FXP& operator+=(FXP& a, const int& b) { a.i += b; return a; }
-	friend FXP& operator-=(FXP& a, const int& b) { a.i -= b; return a; }
-	friend bool operator==(const FXP &a, const FXP &b) { return (a.i == b.i) && (a.f == b.f); }
-	friend bool operator!=(const FXP &a, const FXP &b) { return (a.i != b.i) || (a.f != b.f); }
-	friend bool operator<(const FXP &a, const FXP &b) { return (a.i < b.i) || ((a.i == b.i) && (a.f < b.f)); }
-	friend bool operator>(const FXP &a, const FXP &b) { return (a.i > b.i) || ((a.i == b.i) && (a.f > b.f)); }
-	int trunc(void) const { return i; }
-	int round(void) const { return i + (f > 0x7FFF); }
-	bool empty() const { return i == 0 && f == 0; }
+	friend int& operator+=(int& a, const FXP& b) { return a += b.trunc(); }
+	friend int& operator-=(int& a, const FXP& b) { return a -= b.trunc(); }
+	friend FXP& operator+=(FXP& a, const int& b) { a.v += b << 8; return a; }
+	friend FXP& operator-=(FXP& a, const int& b) { a.v -= b << 8; return a; }
+	friend bool operator==(const FXP &a, const FXP &b) { return a.v == b.v; }
+	friend bool operator!=(const FXP &a, const FXP &b) { return a.v != b.v; }
+	friend bool operator<(const FXP &a, const FXP &b) { return a.v < b.v; }
+	friend bool operator>(const FXP &a, const FXP &b) { return a.v > b.v; }
+	int trunc(void) const { return v >> 8; }
+	int round(void) const { return (v + 0x80) >> 8; }
+	bool empty() const { return v == 0; }
 	void sync(Common::Serializer &s);
 };
 


Commit: 6b48172ae1b6fe1f40709b7d70283deaed9bf86d
    https://github.com/scummvm/scummvm/commit/6b48172ae1b6fe1f40709b7d70283deaed9bf86d
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-30T09:01:18+02:00

Commit Message:
CGE2: Disable checking the sound options while the intro animation is running.

Since there are no toolbar during the intro, checking it's buttons would cause a crash.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9bdd57a..c1a47b8 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -523,7 +523,8 @@ void CGE2Engine::showBak(int ref) {
 }
 
 void CGE2Engine::mainLoop() {
-	checkSounds();
+	if (_startupMode == 0)
+		checkSounds();
 
 	_vga->show();
 	_commandHandlerTurbo->runCommand();


Commit: 06144cee4bcdcba00550b9bbee391f1ef22479fd
    https://github.com/scummvm/scummvm/commit/06144cee4bcdcba00550b9bbee391f1ef22479fd
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-30T09:05:07+02:00

Commit Message:
CGE2: Remove dummies from save header and change save checksum.

The old saves are broken by our new FXP implementation anyway.

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 63abe3a..4a9da88 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -42,7 +42,7 @@
 
 namespace CGE2 {
 
-#define kSavegameCheckSum (1997 + _now + kWorldHeight)
+#define kSavegameCheckSum (1997 + _now + _sex + kWorldHeight)
 #define kBadSVG           99
 
 struct SavegameHeader {
@@ -291,17 +291,11 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS
 }
 
 void CGE2Engine::syncHeader(Common::Serializer &s) {
-	int dummy = 0;
-
 	s.syncAsUint16LE(_now);
 	s.syncAsUint16LE(_sex);
 	s.syncAsUint16LE(_vga->_rot._len);
 	s.syncAsUint16LE(_waitSeq);
 	s.syncAsUint16LE(_waitRef);
-	s.syncAsUint16LE(dummy); // _sayCap
-	s.syncAsUint16LE(dummy); // _sayVox
-	for (int i = 0; i < 4; i++)
-		s.syncAsUint16LE(dummy); // _flag
 
 	if (s.isSaving()) {
 		// Write checksum


Commit: 733f72d810b6f28992e1b9d42050544ade35da14
    https://github.com/scummvm/scummvm/commit/733f72d810b6f28992e1b9d42050544ade35da14
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-30T19:15:59+02:00

Commit Message:
CGE2: Fix sunset() and sunrise().

Now they really do the fade-in/fade-out effect.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 105fd3f..9340abf 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -994,6 +994,7 @@ void Vga::sunrise(Dac *tab) {
 		setColors(tab, i);
 		waitVR();
 		updateColors();
+		g_system->updateScreen();
 	}
 }
 
@@ -1004,6 +1005,7 @@ void Vga::sunset() {
 		setColors(tab, i);
 		waitVR();
 		updateColors();
+		g_system->updateScreen();
 	}
 }
 


Commit: 6a38671cc27e91e9da9d0e214a8da639546b1d9e
    https://github.com/scummvm/scummvm/commit/6a38671cc27e91e9da9d0e214a8da639546b1d9e
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-30T19:34:37+02:00

Commit Message:
CGE2: Rearrange showTitle() and add some delay to the display.

Now the splash screen doesn't vanish almost immediately right after it's drawn.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index c1a47b8..b4dd812 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -808,16 +808,15 @@ bool CGE2Engine::showTitle(const char *name) {
 	Sprite D(this, LB, 1);
 	D._flags._kill = true;
 	D.gotoxyz(kScrWidth >> 1, -(kPanHeight >> 1));
-	_vga->sunset();
 
+	_vga->sunset();
 	D.show(2);
-
 	_vga->copyPage(1, 2);
 	_vga->copyPage(0, 1);
-
 	_vga->sunrise(_vga->_sysPal);
-
 	_vga->update();
+
+	g_system->delayMillis(2500);
 	
 	return true;
 }


Commit: 6d278157e16927f483d6cc397c0fe2d959cf22bb
    https://github.com/scummvm/scummvm/commit/6d278157e16927f483d6cc397c0fe2d959cf22bb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-07-30T21:13:47+02:00

Commit Message:
CGE2: Comment out delay in the splash screen during testing.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index b4dd812..127405a 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -816,8 +816,9 @@ bool CGE2Engine::showTitle(const char *name) {
 	_vga->sunrise(_vga->_sysPal);
 	_vga->update();
 
+#if 0
 	g_system->delayMillis(2500);
-	
+#endif
 	return true;
 }
 


Commit: 0d662566bd2706919e8ed9c7abf79c5f0767f591
    https://github.com/scummvm/scummvm/commit/0d662566bd2706919e8ed9c7abf79c5f0767f591
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-08-01T11:16:39-04:00

Commit Message:
CGE2: Further fixes to FXP operators to fix pathfinding

Changed paths:
    engines/cge2/vga13h.cpp
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 9340abf..cdf683d 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -45,6 +45,51 @@ void V3D::sync(Common::Serializer &s) {
 	_z.sync(s);
 }
 
+FXP FXP::operator*(const FXP& x) const { 
+	FXP y; 
+	int32 t1 = (v >> 8) * x.v;
+	int32 t2 = (v & 0xFF) * x.v;
+
+	y.v = t1 + t2;
+	return y; 
+}
+
+FXP FXP::operator/(const FXP& x) const {
+	FXP y;
+	if (x.v != 0) {
+		int32 v1 = this->v;
+		int32 v2 = x.v;
+		bool negFlag = false;
+
+		if (v1 < 0) {
+			v1 = -v1;
+			negFlag = true;
+		}
+		if (v2 < 0) {
+			v2 = -v2;
+			negFlag ^= true;
+		}
+
+		int32 v3 = v1 / v2;
+		v1 -= v3 * v2;
+		v3 <<= 8;
+
+		if (v1 < 0xFFFFFF) {
+			v1 <<= 8;
+		} else {
+			v2 >>= 8;
+		}
+		v3 += v1 / v2;
+
+		if (negFlag)
+			v3 = -v3;
+
+		y.v = v3;
+	}
+
+	return y;
+}
+
 void FXP::sync(Common::Serializer &s) {
 	s.syncAsSint32LE(v);
 }
diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index f3354c5..52efd39 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -60,8 +60,8 @@ public:
 	FXP& operator=(const int& x) { v = x << 8; return *this; }
 	FXP operator+(const FXP& x) const { FXP y; y.v = v + x.v; return y; }
 	FXP operator-(const FXP& x) const { FXP y; y.v = v - x.v; return y; }
-	FXP operator*(const FXP& x) const { FXP y; y.v = v * x.v / 256; return y; }
-	FXP operator/(const FXP& x) const { FXP y; y.v = (x.v == 0) ? 0 : v * 256 / x.v; return y; }
+	FXP operator*(const FXP& x) const;
+	FXP operator/(const FXP& x) const;
 
 	//int& operator = (int& a, const FXP& b) { return a = b.i; }
 	friend int& operator+=(int& a, const FXP& b) { return a += b.trunc(); }


Commit: c012c762d014c4c77ab5165b0c45b3c51ec34149
    https://github.com/scummvm/scummvm/commit/c012c762d014c4c77ab5165b0c45b3c51ec34149
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-01T19:22:12+02:00

Commit Message:
CGE2: Remove moveHi() and moveLo() from bitmap

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/bitmap.h
    engines/cge2/hero.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 2c7c010..6629919 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -398,16 +398,6 @@ void Bitmap::xLatPos(V2D& p) {
 	p.y = kWorldHeight - p.y - _h;
 }
 
-bool Bitmap::moveHi() {
-	// No implementation needed in ScummVM
-	return true;
-}
-
-bool Bitmap::moveLo() {
-	// No implementation needed in ScummVM
-	return true;
-}
-
 #define	_    kPixelTransp,
 #define L               1,
 #define G               2,
@@ -466,9 +456,11 @@ uint8 *Bitmap::makeSpeechBubbleTail(int which, uint8 colorSet[][4]) {
 		break;
 	}
 
-	for (int i = 0; i < kDesignSize; i++)
+	for (int i = 0; i < kDesignSize; i++) {
 		if (des[i] >= 1 && des[i] <= 3)
 			des[i] = colorSet[kCBSay][des[i]];
+	}
+
 	return des;
 }
 
diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 8643c37..30b8f48 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -82,8 +82,6 @@ public:
 	void show(V2D pos);
 	bool solidAt(V2D pos);
 	void xLatPos(V2D& p);
-	bool moveHi();
-	bool moveLo();
 
 	static uint8 *makeSpeechBubbleTail(int des, uint8 colorSet[][4]);
 };
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 0b8e227..821b738 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -173,8 +173,6 @@ Sprite *Hero::expand() {
 						char *q = p;
 						q[1] = '0' + i;
 						Bitmap b(_vm, q);
-						if (!b.moveHi())
-							error("No EMS %s", q);
 						_dim[i][shpcnt] = b;
 						if (!shpcnt)
 							_hig[i] = b._h;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index cdf683d..1895c31 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -422,8 +422,6 @@ Sprite *Sprite::expand() {
 					break;
 				case kIdPhase:
 					shplist[shpcnt] = Bitmap(_vm, p);
-					if (!shplist[shpcnt].moveHi())
-						error("No EMS");
 					shpcnt++;
 					break;
 				default:
@@ -957,11 +955,11 @@ uint8 Vga::closest(Dac *pal, const uint8 colR, const uint8 colG, const uint8 col
 
 uint8 Vga::closest(Dac *pal, Dac x) {
 	int exp = (sizeof(long) * 8 - 1);
-	long D = (1 << exp) - 1; // Maximume value of long.
+	long D = (1 << exp) - 1; // Maximum value of long.
 	long R = x._r;
 	long G = x._g;
 	long B = x._b;
-	int idx;
+	int idx = 255;
 	for (int n = 0; n < 256; n++) {
 		long dR = R - pal[n]._r;
 		long dG = G - pal[n]._g;
@@ -980,8 +978,7 @@ uint8 Vga::closest(Dac *pal, Dac x) {
 uint8 *Vga::glass(Dac *pal, const uint8 colR, const uint8 colG, const uint8 colB) {
 	uint8 *x = (uint8 *)malloc(256);
 	if (x) {
-		uint16 i;
-		for (i = 0; i < 256; i++) {
+		for (uint16 i = 0; i < 256; i++) {
 			x[i] = closest(pal, ((uint16)(pal[i]._r) * colR) / 255,
 			                    ((uint16)(pal[i]._g) * colG) / 255,
 			                    ((uint16)(pal[i]._b) * colB) / 255);


Commit: 1a49887855d4b0075fa87203f3403250b308429b
    https://github.com/scummvm/scummvm/commit/1a49887855d4b0075fa87203f3403250b308429b
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-01T19:36:24+02:00

Commit Message:
CGE2: Some cosmetic changes

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index f175fce..f938b8b 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -115,18 +115,20 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 void CGE2Engine::init() {
 	// Create debugger console
 	_console = new CGE2Console(this);
-
 	_resman = new ResourceManager();
 	_vga = new Vga(this);
 	_fx = new Fx(this, 16);
 	_sound = new Sound(this);
 	_midiPlayer = new MusicPlayer(this);
 	_text = new Text(this, "CGE");
+
 	for (int i = 0; i < 2; i++)
 		_heroTab[i] = new HeroTab(this);
+
 	_eye = new V3D();
 	for (int i = 0; i < kSceneMax; i++)
 		_eyeTab[i] = new V3D();
+
 	_spare = new Spare(this);
 	_commandHandler = new CommandHandler(this, false);
 	_commandHandlerTurbo = new CommandHandler(this, true);
@@ -134,12 +136,13 @@ void CGE2Engine::init() {
 	_infoLine = new InfoLine(this, kInfoW);
 	_mouse = new Mouse(this);
 	_keyboard = new Keyboard(this);
+
 	for (int i = 0; i < kMaxPoint; i++)
 		_point[i] = new V3D();
+
 	_sys = new System(this);
 	_eventManager = new EventManager(this);
 	_map = new Map(this);
-
 	_startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1;
 }
 
@@ -156,11 +159,13 @@ void CGE2Engine::deinit() {
 	delete _sound;
 	delete _midiPlayer;
 	delete _text;
+
 	for (int i = 0; i < 2; i++)
 		delete _heroTab[i];
-	for (int i = 0; i < kSceneMax; i++) {
+
+	for (int i = 0; i < kSceneMax; i++)
 		delete _eyeTab[i];
-	}
+
 	delete _eye;
 	delete _commandHandler;
 	delete _commandHandlerTurbo;
@@ -168,20 +173,20 @@ void CGE2Engine::deinit() {
 	delete _infoLine;
 	delete _mouse;
 	delete _keyboard;
+
 	if (_talk != nullptr)
 		delete _talk;
-	for (int i = 0; i < kMaxPoint; i++) {
+
+	for (int i = 0; i < kMaxPoint; i++)
 		delete _point[i];
-	}
+
 	delete _sys;
 	delete _eventManager;
 	delete _map;
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
-	return
-		(f == kSupportsLoadingDuringRuntime) ||
-		(f == kSupportsSavingDuringRuntime);
+	return (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime);
 }
 
 Common::Error CGE2Engine::run() {
@@ -190,10 +195,9 @@ Common::Error CGE2Engine::run() {
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();
-
 	cge2_main();
-	
 	deinit();
+
 	return Common::kNoError;
 }
 
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 38b48aa..4043f15 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -282,10 +282,12 @@ public:
 	bool _dark;
 	int _waitSeq;
 	int _waitRef;
+
 	struct {
 		int *_wait;
 		int _ref[2];
 	} _soundStat;
+
 	bool _taken;
 	bool _endGame;
 	int _req;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 127405a..f3dad8b 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -134,9 +134,8 @@ char *CGE2Engine::tail(char *s) {
 int CGE2Engine::takeEnum(const char **tab, const char *text) {
 	if (text) {
 		for (const char **e = tab; *e; e++) {
-			if (scumm_stricmp(text, *e) == 0) {
+			if (scumm_stricmp(text, *e) == 0)
 				return e - tab;
-			}
 		}
 	}
 	return -1;
@@ -158,8 +157,10 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 	int shpcnt = 0;
 	int seqcnt = 0;
 	int cnt[kActions];
+
 	for (int i = 0; i < kActions; i++)
 		cnt[i] = 0;
+
 	ID section = kIdPhase;
 	bool frnt = true;
 	bool east = false;
@@ -184,8 +185,7 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 				continue;
 			Common::strlcpy(tmpStr, line.c_str(), sizeof(tmpStr));
 				
-			char *p;
-			p = token(tmpStr);
+			char *p = token(tmpStr);
 			if (*p == '@') {
 				if (label != kNoByte)
 					badLab(fname);
@@ -272,7 +272,7 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 	} else // No sprite description: mono-shaped sprite with only .BMP file.
 		++shpcnt;
 
-	// Make sprite of choosen type:
+	// Make sprite of chosen type:
 	Sprite *sprite = nullptr;
 	char c = *fname | 0x20;
 	if (c >= 'a' && c <= 'z' && fname[1] == '0' && fname[2] == '\0') {
@@ -374,8 +374,9 @@ void CGE2Engine::loadScript(const char *fname, bool onlyToolbar) {
 				_spare->dispose(sprite);
 			else
 				delete sprite;
+
 			if (_spare->count() == n)
-				error("Durplicated reference! %s", SpN);
+				error("Duplicate reference! %s", SpN);
 		}
 	}
 
@@ -397,12 +398,12 @@ void CGE2Engine::movie(const char *ext) {
 		_now = atoi(ext + 2);
 		loadScript(fn);
 		sceneUp(_now);
-
 		_keyboard->setClient(_sys);
+
 		while (!_commandHandler->idle() && !_quitFlag)
 			mainLoop();
-		_keyboard->setClient(nullptr);
 
+		_keyboard->setClient(nullptr);
 		_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 		_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
 		_spare->clear();
@@ -445,10 +446,10 @@ void CGE2Engine::sceneUp(int cav) {
 
 	if (!_dark)
 		_vga->sunset();
+
 	_vga->show();
 	_vga->copyPage(1, 0);
 	_vga->show();
-
 	_vga->sunrise(_vga->_sysPal);
 
 	_dark = false;
@@ -463,12 +464,15 @@ void CGE2Engine::sceneDown() {
 	busy(true);
 	_soundStat._wait = nullptr; // unlock snail
 	Sprite *spr = _vga->_showQ->locate((_now << 8) | 254);
+
 	if (spr)
 		feedSnail(spr, kNear, _heroTab[_sex]->_ptr);
+
 	while (!(_commandHandler->idle() && _commandHandlerTurbo->idle())) {
 		_commandHandlerTurbo->runCommand();
 		_commandHandler->runCommand();
 	}
+
 	closePocket();
 	for (int i = 0; i < 2; i++)
 		_spare->update(_vga->_showQ->remove(_heroTab[i]->_ptr));
@@ -480,10 +484,9 @@ void CGE2Engine::switchScene(int scene) {
 		return;
 
 	_req = scene;
-
 	storeHeroPos();
-	
 	*(_eyeTab[_now]) = *_eye;
+
 	if (scene < 0)
 		_commandHandler->addCallback(kCmdExec, -1, 0, kQGame); // quit game
 	else {
@@ -630,7 +633,6 @@ void CGE2Engine::runGame() {
 		return;
 
 	loadUser();
-
 	sceneUp(_now);
 	initToolbar();
 
@@ -837,6 +839,7 @@ void CGE2Engine::switchHero(int sex) {
 			_sys->_blinkSprite->_flags._hide = false;
 			_sys->_blinkSprite = nullptr;
 		}
+
 		if (scene >= 0) {
 			_commandHandler->addCommand(kCmdSeq, -1, 2, _heroTab[_sex]->_face);
 			_sex ^= 1;
@@ -875,6 +878,7 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 						if (_vm->_sex == sex) {
 							if (_vm->_sys->_blinkSprite)
 								_vm->_sys->_blinkSprite->_flags._hide = false;
+
 							if (_vm->_sys->_blinkSprite == this)
 								_vm->_sys->_blinkSprite = nullptr;
 							else


Commit: 96ab1d5d83950e764be4e13248584498e4d79c7c
    https://github.com/scummvm/scummvm/commit/96ab1d5d83950e764be4e13248584498e4d79c7c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2014-08-02T10:23:43-04:00

Commit Message:
CGE2: Further FXP multiply fix to fix hero scaling

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 1895c31..33d5ba1 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -48,7 +48,7 @@ void V3D::sync(Common::Serializer &s) {
 FXP FXP::operator*(const FXP& x) const { 
 	FXP y; 
 	int32 t1 = (v >> 8) * x.v;
-	int32 t2 = (v & 0xFF) * x.v;
+	int32 t2 = ((v & 0xFF) * x.v) >> 8;
 
 	y.v = t1 + t2;
 	return y; 


Commit: 0eb7e52490b3b7c66f68e65d65a9880fa7e13492
    https://github.com/scummvm/scummvm/commit/0eb7e52490b3b7c66f68e65d65a9880fa7e13492
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-02T19:04:41+02:00

Commit Message:
CGE2: Update comment concerning a workaround for a non-fixable issue

Changed paths:
    engines/cge2/fileio.cpp



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 41ea1c1..73b6cda 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -157,7 +157,7 @@ BtKeypack *ResourceManager::find(const char *key) {
 					break;
 			}
 
-			// FIXME: Terrible hack to work around a mix between 24piram_ and 24pirami
+			// Hack to work around a mix between 24piram_ and 24pirami
 			if (!strcmp(key, "24piram_.SPR") && (scumm_stricmp((const char *)key, (const char *)pg->_leaf[i]._key) < 0))
 				++i;
 			//


Commit: 3376ab4f622c0ff1998bfe792efa9e030783b047
    https://github.com/scummvm/scummvm/commit/3376ab4f622c0ff1998bfe792efa9e030783b047
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-02T19:05:30+02:00

Commit Message:
CGE2: Update the comment about another non-fixable workaround

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f3dad8b..6a6066e 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -890,7 +890,7 @@ void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 		} else { // sprite NOT in pocket
 			Hero *h = _vm->_heroTab[_vm->_sex]->_ptr;
 			if (!_vm->_talk) {
-				// HACK: the "+3" is a ugly hack used to compensate a pathfinding issue. To be fixed!!
+				// the "+3" is a hack used to work around a script issue in scene 5
 				if ((_ref & 0xFF) < 200 && h->distance(this) > (h->_maxDist << 1) + 3)
 					h->walkTo(this);
 				else if (_vm->_sys->_blinkSprite) {


Commit: f2de89c7bc3be8c6e77946c005ea7973276b5e0f
    https://github.com/scummvm/scummvm/commit/f2de89c7bc3be8c6e77946c005ea7973276b5e0f
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-02T22:26:00+02:00

Commit Message:
CGE2: Fix CppCheck warnings by reducing variable scope

Changed paths:
    engines/cge2/hero.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 821b738..3bb7c82 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -72,11 +72,7 @@ Sprite *Hero::expand() {
 			_dim[i][j].setVM(_vm);
 	}
 
-	int cnt[kActions],
-		shpcnt = 0,
-		seqcnt = 0,
-		maxnow = 0,
-		maxnxt = 0;
+	int cnt[kActions];
 
 	for (int i = 0; i < kActions; i++)
 		cnt[i] = 0;
@@ -108,6 +104,10 @@ Sprite *Hero::expand() {
 		ID id;
 		Common::String line;
 		char tmpStr[kLineMax + 1];
+		int shpcnt = 0;
+		int seqcnt = 0;
+		int maxnow = 0;
+		int maxnxt = 0;
 
 		for (line = sprf.readLine(); !sprf.eos(); line = sprf.readLine()) {
 			if (line.empty())


Commit: d44ff5491281fb9bcd4cc8f4534988b0b2bcb052
    https://github.com/scummvm/scummvm/commit/d44ff5491281fb9bcd4cc8f4534988b0b2bcb052
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-02T23:17:25+02:00

Commit Message:
CGE2: Fix error message in makeSpeechBubbleTail().

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 6629919..60e7a80 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -452,7 +452,7 @@ uint8 *Bitmap::makeSpeechBubbleTail(int which, uint8 colorSet[][4]) {
 		memcpy(des, kSRDesign, sizeof(kSRDesign));
 		break;
 	default:
-		error("Wrong parameter in Bitmap::paint!");
+		error("Wrong parameter in Bitmap::makeSpeechBubbleTail!");
 		break;
 	}
 


Commit: 9dc06870e79edd637280ef9a81391adca1eafabc
    https://github.com/scummvm/scummvm/commit/9dc06870e79edd637280ef9a81391adca1eafabc
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-03T01:51:33+02:00

Commit Message:
CGE2: Start removing the checks on the return value of new

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/events.cpp
    engines/cge2/hero.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 60e7a80..289e156 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -84,7 +84,6 @@ Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
 	uint16 psiz = _h * lsiz;                         // - last gape, but + plane trailer
 	uint8 *v = new uint8[4 * psiz + _h * sizeof(*_b)];// the same for 4 planes
 	                                                // + room for wash table
-	assert(v != nullptr);
 
 	WRITE_LE_UINT16(v, (kBmpCPY | dsiz));                 // data chunk hader
 	memset(v + 2, fill, dsiz);                      // data bytes
@@ -122,7 +121,6 @@ Bitmap::Bitmap(CGE2Engine *vm, const Bitmap &bmp) : _w(bmp._w), _h(bmp._h), _v(n
 	uint16 vsiz = (uint8 *)(bmp._b) - (uint8 *)(v0);
 	uint16 siz = vsiz + _h * sizeof(HideDesc);
 	uint8 *v1 = new uint8[siz];
-	assert(v1 != nullptr);
 	memcpy(v1, v0, siz);
 	_b = (HideDesc *)((_v = v1) + vsiz);
 }
@@ -149,13 +147,10 @@ Bitmap &Bitmap::operator=(const Bitmap &bmp) {
 	delete[] _v;
 	_v = nullptr;
 
-	if (v0 == nullptr) {
-		_v = nullptr;
-	} else {
+	if (v0) {
 		uint16 vsiz = (uint8 *)bmp._b - (uint8 *)v0;
 		uint16 siz = vsiz + _h * sizeof(HideDesc);
 		uint8 *v1 = new uint8[siz];
-		assert(v1 != nullptr);
 		memcpy(v1, v0, siz);
 		_b = (HideDesc *)((_v = v1) + vsiz);
 	}
@@ -265,8 +260,6 @@ BitmapPtr Bitmap::code(uint8 *map) {
 
 		uint16 sizV = (uint16)(im - 2 - _v);
 		_v = new uint8[sizV + _h * sizeof(*_b)];
-		assert(_v != nullptr);
-
 		_b = (HideDesc *)(_v + sizV);
 	}
 	cnt = 0;
@@ -383,8 +376,7 @@ bool Bitmap::loadVBM(EncryptedStream *f) {
 				f->seek(f->pos() + kPalSize);
 		}
 	}
-	if ((_v = new uint8[n]) == nullptr)
-		return false;
+	_v = new uint8[n];
 
 	if (!f->err())
 		f->read(_v, n);
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 6a6066e..e945fbf 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -277,14 +277,11 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 	char c = *fname | 0x20;
 	if (c >= 'a' && c <= 'z' && fname[1] == '0' && fname[2] == '\0') {
 		h = new Hero(this);
-		if (h) {
-			h->gotoxyz(pos);
-			sprite = h;
-		}
+		h->gotoxyz(pos);
+		sprite = h;
 	} else {
 		sprite = new Sprite(this);
-		if (sprite)
-			sprite->gotoxyz(pos);
+		sprite->gotoxyz(pos);
 	}
 
 	if (sprite) {
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index ccddc25..cf6d3b0 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -166,9 +166,8 @@ void Mouse::on() {
 
 void Mouse::off() {
 	if (_seqPtr == 0) {
-		if (_exist) {
+		if (_exist)
 			_active = false;
-		}
 
 		step(1);
 		if (_busy)
diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 3bb7c82..91f6354 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -53,9 +53,8 @@ Sprite *Hero::expand() {
 
 	if (_ext != nullptr)
 		delete _ext;
+
 	_ext = new SprExt(_vm);
-	if (_ext == nullptr)
-		error("No core %s", fname);
 
 	if (!*_file)
 		return this;
@@ -79,21 +78,15 @@ Sprite *Hero::expand() {
 
 	for (int i = 0; i < kActions; i++) {
 		byte n = _actionCtrl[i]._cnt;
-		if (n) {
+		if (n)
 			_ext->_actions[i] = new CommandHandler::Command[n];
-			if (_ext->_actions[i] == nullptr)
-				error("No core %s", fname);
-		} else
+		else
 			_ext->_actions[i] = nullptr;
 	}
 
-	Seq *curSeq;
-	if (_seqCnt) {
+	Seq *curSeq = nullptr;
+	if (_seqCnt)
 		curSeq = new Seq[_seqCnt];
-		if (curSeq == nullptr)
-			error("No core %s", fname);
-	} else
-		curSeq = nullptr;
 
 	if (_vm->_resman->exist(fname)) { // sprite description file exist
 		EncryptedStream sprf(_vm, fname);
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 33d5ba1..03e6b3f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -224,7 +224,6 @@ void Sprite::setName(char *newName) {
 	}
 	if (newName) {
 		_ext->_name = new char[strlen(newName) + 1];
-		assert(_ext->_name != nullptr);
 		strcpy(_ext->_name, newName);
 	}
 }
@@ -308,8 +307,6 @@ Sprite *Sprite::expand() {
 	if (_ext != nullptr)
 		delete _ext;
 	_ext = new SprExt(_vm);
-	if (_ext == nullptr)
-		error("No core %s", fname);
 
 	if (!*_file)
 		return this;
@@ -327,21 +324,15 @@ Sprite *Sprite::expand() {
 
 	for (int i = 0; i < kActions; i++){
 		byte n = _actionCtrl[i]._cnt;
-		if (n) {
+		if (n)
 			_ext->_actions[i] = new CommandHandler::Command[n];
-			if (_ext->_actions[i] == nullptr)
-				error("No core %s", fname);
-		} else
+		else
 			_ext->_actions[i] = nullptr;
 	}
 
-	Seq *curSeq;
-	if (_seqCnt) {
+	Seq *curSeq = nullptr;
+	if (_seqCnt)
 		curSeq = new Seq[_seqCnt];
-		if (curSeq == nullptr)
-			error("No core %s", fname);
-	} else
-		curSeq = nullptr;
 
 	if (_vm->_resman->exist(fname)) { // sprite description file exist
 		EncryptedStream sprf(_vm, fname);
@@ -698,11 +689,9 @@ BitmapPtr Sprite::ghost() {
 		return nullptr;
 
 	BitmapPtr bmp = new Bitmap(_vm, 0, 0, (uint8 *)nullptr);
-	assert(bmp != nullptr);
 	bmp->_w = e->_b1->_w;
 	bmp->_h = e->_b1->_h;
 	bmp->_b = new HideDesc[bmp->_h];
-	assert(bmp->_b != nullptr);
 	memcpy(bmp->_b, e->_b1->_b, sizeof(HideDesc)* bmp->_h);
 	uint8 *v = new uint8;
 	*v = (e->_p1.y << 16) + e->_p1.x;


Commit: 2b60bb9cc376f9e8e7866f07cb2012a6bf748914
    https://github.com/scummvm/scummvm/commit/2b60bb9cc376f9e8e7866f07cb2012a6bf748914
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T09:27:47+02:00

Commit Message:
CGE2: Fix possible null pointer dereference.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 03e6b3f..812aabf 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -664,9 +664,10 @@ void Sprite::show() {
 		e->_b0 = e->_b1;
 		e->_p1 = _pos2D;
 		e->_b1 = getShp();
+
+		if (!_flags._hide)
+			e->_b1->show(e->_p1);
 	}
-	if (!_flags._hide)
-		e->_b1->show(e->_p1);
 }
 
 void Sprite::show(uint16 pg) {


Commit: 6558581d68c740d380e695cb9c150c81fc082bb8
    https://github.com/scummvm/scummvm/commit/6558581d68c740d380e695cb9c150c81fc082bb8
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-03T10:33:37+02:00

Commit Message:
CGE2: Remove more checks on the return value of new

Changed paths:
    engines/cge2/talk.cpp
    engines/cge2/text.cpp
    engines/cge2/vmenu.cpp



diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index f6321d3..dbdfc0d 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -48,7 +48,6 @@ Font::Font(CGE2Engine *vm) : _vm(vm) {
 	_pos = new uint16[kPosSize];
 	_widthArr = new uint8[kWidSize];
 
-	assert((_map != nullptr) && (_pos != nullptr) && (_widthArr != nullptr));
 	load();
 }
 
@@ -136,8 +135,6 @@ uint8 *Talk::box(V2D siz) {
 	if (siz.y < 8)
 		siz.y = 8;
 	uint8 *b = new uint8[n = siz.area()];
-	if (!b)
-		error("No core!");
 	memset(b, bg, n);
 
 	if (_mode) {
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 9989dab..ca4c336 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -140,8 +140,6 @@ void Text::say(const char *text, Sprite *spr) {
 	_vm->killText();
 
 	_vm->_talk = new Talk(_vm, text, kTBRound, kCBSay);
-	if (!_vm->_talk)
-		return;
 
 	Speaker *speaker = new Speaker(_vm);
 
@@ -186,12 +184,10 @@ void Text::say(const char *text, Sprite *spr) {
 void CGE2Engine::inf(const char *text, ColorBank col) {
 	killText();
 	_talk = new Talk(this, text, kTBRect, col, true);
-	if (_talk) {
-		_talk->_flags._kill = true;
-		_talk->setName(_text->getText(kInfName));
-		_talk->center();
-		_vga->_showQ->append(_talk);
-	}
+	_talk->_flags._kill = true;
+	_talk->setName(_text->getText(kInfName));
+	_talk->center();
+	_vga->_showQ->append(_talk);
 }
 
 void Text::sayTime(Sprite *spr) {
diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
index fa4c29c..a84078f 100644
--- a/engines/cge2/vmenu.cpp
+++ b/engines/cge2/vmenu.cpp
@@ -100,15 +100,14 @@ char *VMenu::vmGather(Common::Array<Choice *> list) {
 		++h;
 	}
 	_vmgt = new char[len + h];
-	if (_vmgt) {
-		*_vmgt = '\0';
-		for (uint i = 0; i < list.size(); i++) {
-			if (*_vmgt)
-				strcat(_vmgt, "|");
-			strcat(_vmgt, list[i]->_text);
-			++h;
-		}
+	*_vmgt = '\0';
+	for (uint i = 0; i < list.size(); i++) {
+		if (*_vmgt)
+			strcat(_vmgt, "|");
+		strcat(_vmgt, list[i]->_text);
+		++h;
 	}
+
 	return _vmgt;
 }
 


Commit: 239fa2a5cfee7a71b909ad338d14a54c5f44ca95
    https://github.com/scummvm/scummvm/commit/239fa2a5cfee7a71b909ad338d14a54c5f44ca95
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T10:50:53+02:00

Commit Message:
CGE2: Rename classes representing quit menu choices.

Changed paths:
    engines/cge2/toolbar.cpp
    engines/cge2/vmenu.cpp
    engines/cge2/vmenu.h



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 51614af..be9f73e 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -130,13 +130,13 @@ void CGE2Engine::checkMusicSwitch() {
 
 void CGE2Engine::quit() {
 	Common::Array<Choice *> quitMenu; // Deleted in VMenu's destructor.
-	quitMenu.push_back(new StartCountDownChoice(this));
-	quitMenu.push_back(new ResetQSwitchChoice(this));
+	quitMenu.push_back(new ExitGameChoice(this));
+	quitMenu.push_back(new ReturnToGameChoice(this));
 
 	if (_commandHandler->idle()) {
 		if (VMenu::_addr) {
 			_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, VMenu::_addr);
-			ResetQSwitchChoice rqsChoice(this);
+			ReturnToGameChoice rqsChoice(this);
 			rqsChoice.proc();
 		} else {
 			quitMenu[0]->_text = _text->getText(kQuitText);
diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
index a84078f..ceb69f0 100644
--- a/engines/cge2/vmenu.cpp
+++ b/engines/cge2/vmenu.cpp
@@ -31,11 +31,11 @@
 
 namespace CGE2 {
 
-void StartCountDownChoice::proc() {
+void ExitGameChoice::proc() {
 	_vm->switchScene(-1);
 }
 
-void ResetQSwitchChoice::proc() {
+void ReturnToGameChoice::proc() {
 	_vm->_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
 	_vm->keyClick();
 }
diff --git a/engines/cge2/vmenu.h b/engines/cge2/vmenu.h
index 724fb5d..e28eee7 100644
--- a/engines/cge2/vmenu.h
+++ b/engines/cge2/vmenu.h
@@ -48,15 +48,15 @@ public:
 	virtual ~Choice() {}
 };
 
-class StartCountDownChoice : public Choice {
+class ExitGameChoice : public Choice {
 public:
-	StartCountDownChoice(CGE2Engine *vm) : Choice(vm) {}
+	ExitGameChoice(CGE2Engine *vm) : Choice(vm) {}
 	void proc();
 };
 
-class ResetQSwitchChoice : public Choice {
+class ReturnToGameChoice : public Choice {
 public:
-	ResetQSwitchChoice(CGE2Engine *vm) : Choice(vm) {}
+	ReturnToGameChoice(CGE2Engine *vm) : Choice(vm) {}
 	void proc();
 };
 


Commit: 8eae09afcac8c33ac0d7c8282001692f4f6df749
    https://github.com/scummvm/scummvm/commit/8eae09afcac8c33ac0d7c8282001692f4f6df749
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T11:36:56+02:00

Commit Message:
CGE2: Fix memory leak concerning the quit menu.

Changed paths:
    engines/cge2/toolbar.cpp
    engines/cge2/vmenu.cpp
    engines/cge2/vmenu.h



diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index be9f73e..5880dfc 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -129,18 +129,15 @@ void CGE2Engine::checkMusicSwitch() {
 }
 
 void CGE2Engine::quit() {
-	Common::Array<Choice *> quitMenu; // Deleted in VMenu's destructor.
-	quitMenu.push_back(new ExitGameChoice(this));
-	quitMenu.push_back(new ReturnToGameChoice(this));
-
 	if (_commandHandler->idle()) {
 		if (VMenu::_addr) {
 			_commandHandlerTurbo->addCommand(kCmdKill, -1, 0, VMenu::_addr);
 			ReturnToGameChoice rqsChoice(this);
 			rqsChoice.proc();
 		} else {
-			quitMenu[0]->_text = _text->getText(kQuitText);
-			quitMenu[1]->_text = _text->getText(kNoQuitText);
+			Common::Array<Choice *> quitMenu; // Deleted in VMenu's destructor.
+			quitMenu.push_back(new ExitGameChoice(this));
+			quitMenu.push_back(new ReturnToGameChoice(this));
 			(new VMenu(this, quitMenu, V2D(this, -1, -1), kCBMnu))->setName(_text->getText(kQuitTitle));
 			_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 0, nullptr);
 			keyClick();
diff --git a/engines/cge2/vmenu.cpp b/engines/cge2/vmenu.cpp
index ceb69f0..6afe5e9 100644
--- a/engines/cge2/vmenu.cpp
+++ b/engines/cge2/vmenu.cpp
@@ -25,16 +25,26 @@
  * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
  */
 
-#include "cge2/cge2.h"
+#include "cge2/text.h"
 #include "cge2/vmenu.h"
 #include "cge2/events.h"
 
 namespace CGE2 {
 
+Choice::Choice(CGE2Engine *vm) : _vm(vm), _text(nullptr) {}
+
+ExitGameChoice::ExitGameChoice(CGE2Engine *vm) : Choice(vm) {
+	_text = _vm->_text->getText(kQuitText);
+}
+
 void ExitGameChoice::proc() {
 	_vm->switchScene(-1);
 }
 
+ReturnToGameChoice::ReturnToGameChoice(CGE2Engine *vm) : Choice(vm) {
+	_text = _vm->_text->getText(kNoQuitText);
+}
+
 void ReturnToGameChoice::proc() {
 	_vm->_commandHandlerTurbo->addCommand(kCmdSeq, kPowerRef, 1, nullptr);
 	_vm->keyClick();
diff --git a/engines/cge2/vmenu.h b/engines/cge2/vmenu.h
index e28eee7..60796e7 100644
--- a/engines/cge2/vmenu.h
+++ b/engines/cge2/vmenu.h
@@ -33,6 +33,7 @@
 #define kLt                      3
 #define kRb                      1
 
+#include "cge2/cge2.h"
 #include "cge2/talk.h"
 
 namespace CGE2 {
@@ -42,21 +43,21 @@ protected:
 	CGE2Engine *_vm;
 public:
 	char *_text;
+
 	virtual void proc() = 0;
 
-	Choice(CGE2Engine *vm) : _vm(vm), _text(nullptr) {}
-	virtual ~Choice() {}
+	Choice(CGE2Engine *vm);
 };
 
 class ExitGameChoice : public Choice {
 public:
-	ExitGameChoice(CGE2Engine *vm) : Choice(vm) {}
+	ExitGameChoice(CGE2Engine *vm);
 	void proc();
 };
 
 class ReturnToGameChoice : public Choice {
 public:
-	ReturnToGameChoice(CGE2Engine *vm) : Choice(vm) {}
+	ReturnToGameChoice(CGE2Engine *vm);
 	void proc();
 };
 


Commit: 241d07ff07c0002481fb81938066c675c5139df5
    https://github.com/scummvm/scummvm/commit/241d07ff07c0002481fb81938066c675c5139df5
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T11:53:28+02:00

Commit Message:
CGE2: Silence GCC warning concerning destructors of Choice's children.

Changed paths:
    engines/cge2/vmenu.h



diff --git a/engines/cge2/vmenu.h b/engines/cge2/vmenu.h
index 60796e7..f34812d 100644
--- a/engines/cge2/vmenu.h
+++ b/engines/cge2/vmenu.h
@@ -47,6 +47,7 @@ public:
 	virtual void proc() = 0;
 
 	Choice(CGE2Engine *vm);
+	virtual ~Choice() {};
 };
 
 class ExitGameChoice : public Choice {


Commit: 00bb645e5411d00fb3cfe7bbbe530507d5157a23
    https://github.com/scummvm/scummvm/commit/00bb645e5411d00fb3cfe7bbbe530507d5157a23
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T11:59:55+02:00

Commit Message:
CGE2: Fix mismatched new/delete pair in Sprite::ghost() and snGhost().

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 812aabf..486a422 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -694,7 +694,7 @@ BitmapPtr Sprite::ghost() {
 	bmp->_h = e->_b1->_h;
 	bmp->_b = new HideDesc[bmp->_h];
 	memcpy(bmp->_b, e->_b1->_b, sizeof(HideDesc)* bmp->_h);
-	uint8 *v = new uint8;
+	uint8 *v = new uint8[1];
 	*v = (e->_p1.y << 16) + e->_p1.x;
 	bmp->_v = v;
 	bmp->_map = (e->_p1.y << 16) + e->_p1.x;


Commit: 61083e5caba5d28689aaec8fd1f912df37eb0cf0
    https://github.com/scummvm/scummvm/commit/61083e5caba5d28689aaec8fd1f912df37eb0cf0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T12:15:07+02:00

Commit Message:
CGE2: Add RTL support.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index f938b8b..9c16bd4 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -186,7 +186,8 @@ void CGE2Engine::deinit() {
 }
 
 bool CGE2Engine::hasFeature(EngineFeature f) const {
-	return (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime);
+	return (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime)
+		|| (f == kSupportsRTL);
 }
 
 Common::Error CGE2Engine::run() {
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e945fbf..a7cbe01 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -645,6 +645,8 @@ void CGE2Engine::runGame() {
 	_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 	_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
 	_mouse->off();
+
+	_vga->sunset();
 }
 
 void CGE2Engine::loadUser() {


Commit: 60a77ae6d76195180707dfe67a3d34eb95b8ca74
    https://github.com/scummvm/scummvm/commit/60a77ae6d76195180707dfe67a3d34eb95b8ca74
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T14:46:11+02:00

Commit Message:
CGE2: Add autosave functionality.

Changed paths:
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp
    engines/cge2/snail.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 4043f15..fc097b9 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -142,6 +142,7 @@ private:
 	void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
 	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
 	void syncHeader(Common::Serializer &s);
+	void saveGame(int slotNumber, const Common::String &desc);
 	bool loadGame(int slotNumber);
 	void resetGame();
 	void syncSpeechSettings();
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index a7cbe01..e945fbf 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -645,8 +645,6 @@ void CGE2Engine::runGame() {
 	_commandHandler->addCommand(kCmdClear, -1, 0, nullptr);
 	_commandHandlerTurbo->addCommand(kCmdClear, -1, 0, nullptr);
 	_mouse->off();
-
-	_vga->sunset();
 }
 
 void CGE2Engine::loadUser() {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 4a9da88..b95210e 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -129,6 +129,11 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
 			desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
 			desc.setSaveTime(header.saveHour, header.saveMinutes);
 
+			// Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
+			// we prevent it from being deleted or overwritten by accident.
+			desc.setDeletableFlag(slot != 0);
+			desc.setWriteProtectedFlag(slot == 0);
+
 			return desc;
 		}
 	}
@@ -186,8 +191,15 @@ bool CGE2Engine::canLoadGameStateCurrently() {
 }
 
 Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
+	storeHeroPos();
+	saveGame(slot, desc);
+	sceneUp(_now);
+	return Common::kNoError;
+}
+
+void CGE2Engine::saveGame(int slotNumber, const Common::String &desc) {
 	// Set up the serializer
-	Common::String slotName = generateSaveName(slot);
+	Common::String slotName = generateSaveName(slotNumber);
 	Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(slotName);
 
 	// Write out the ScummVM savegame header
@@ -197,16 +209,12 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 	writeSavegameHeader(saveFile, header);
 
 	// Write out the data of the savegame
-	storeHeroPos();
 	sceneDown();
 	syncGame(nullptr, saveFile);
-	sceneUp(_now);
 
 	// Finish writing out game data
 	saveFile->finalize();
 	delete saveFile;
-
-	return Common::kNoError;
 }
 
 /**
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 48e8ffd..2974767 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -691,7 +691,11 @@ Sprite *CGE2Engine::expandSprite(Sprite *spr) {
 }
 
 void CGE2Engine::qGame() {
-	warning("STUB: CGE2Engine::qGame()");
+	// Write out the user's progress
+	saveGame(0, Common::String("Automatic Savegame"));
+	
+	busy(false);
+	_vga->sunset();
 	_endGame = true;
 }
 


Commit: 2697c71301caaad90436b89dfd911e8a7d911457
    https://github.com/scummvm/scummvm/commit/2697c71301caaad90436b89dfd911e8a7d911457
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-03T14:47:25+02:00

Commit Message:
CGE2: Misc cleanup

Changed paths:
    engines/cge2/hero.cpp
    engines/cge2/text.cpp
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/hero.cpp b/engines/cge2/hero.cpp
index 91f6354..e8267b5 100644
--- a/engines/cge2/hero.cpp
+++ b/engines/cge2/hero.cpp
@@ -254,13 +254,11 @@ Sprite *Hero::setContact() {
 	Sprite *spr;
 	int md = _maxDist << 1;
 	for (spr = _vm->_vga->_showQ->first(); spr; spr = spr->_next) {
-		if (spr->_actionCtrl[kNear]._cnt && (spr->_ref & 255) != 255) {
-			if (distance(spr) <= md) {
-				if (spr == _contact)
-					return nullptr;
-				else
-					break;
-			}
+		if (spr->_actionCtrl[kNear]._cnt && ((spr->_ref & 255) != 255) && (distance(spr) <= md)) {
+			if (spr == _contact)
+				return nullptr;
+			else
+				break;
 		}
 	}
 	return (_contact = spr);
@@ -321,8 +319,10 @@ void Hero::tick() {
 	}
 	if (_flags._trim)
 		gotoxyz_(_pos2D);
+
 	if (_pos3D._z.trunc() != z)
 		_flags._zmov = true;
+
 	if (--_funDel == 0)
 		fun();
 }
@@ -345,12 +345,11 @@ int Hero::distance(Sprite *spr) {
 			pos._x = _pos3D._x;
 		else
 			pos._x += mdx;
-	} else {
-		if (dx < mdx)
-			pos._x = _pos3D._x;
-		else
-			pos._x += mdx;
-	}
+	} else if (dx < mdx)
+		pos._x = _pos3D._x;
+	else
+		pos._x += mdx;
+
 	return distance(pos);
 }
 
@@ -419,15 +418,14 @@ int Hero::len(V2D v) {
 bool Hero::findWay(){
 	V2D p0(_vm, _pos3D._x.round(), _pos3D._z.round());
 	V2D p1(_vm, _trace[_tracePtr]._x.round(), _trace[_tracePtr]._z.round());
-	bool pvOk;
-	bool phOk;
 	V2D ph(_vm, p1.x, p0.y);
 	V2D pv(_vm, p0.x, p1.y);
-	pvOk = (!mapCross(p0, pv) && !mapCross(pv, p1));
-	phOk = (!mapCross(p0, ph) && !mapCross(ph, p1));
+	bool pvOk = (!mapCross(p0, pv) && !mapCross(pv, p1));
+	bool phOk = (!mapCross(p0, ph) && !mapCross(ph, p1));
 	int md = (_maxDist >> 1);
 	if (pvOk && (len(ph - p0) <= md || len(p1 - ph) <= md))
 		return true;
+
 	if (phOk && (len(pv - p0) <= md || len(p1 - pv) <= md))
 		return true;
 
@@ -435,16 +433,17 @@ bool Hero::findWay(){
 		_trace[++_tracePtr] = V3D(pv.x, 0, pv.y);
 		return true;
 	}
+
 	if (phOk) {
 		_trace[++_tracePtr] = V3D(ph.x, 0, ph.y);
 		return true;
 	}
+
 	return false;
 }
 
 int Hero::snap(int p, int q, int grid) {
-	int d = q - p;
-	d = ((d >= 0) ? d : -d) % grid;
+	int d = abs(q - p) % grid;
 	if (d > (grid >> 1))
 		d -= grid;
 	return (q >= p) ? (q - d) : (q + d);
@@ -453,6 +452,7 @@ int Hero::snap(int p, int q, int grid) {
 void Hero::walkTo(V3D pos) {
 	if (distance(pos) <= _maxDist)
 		return;
+
 	int stp = stepSize();
 	pos._x = snap(_pos3D._x.round(), pos._x.round(), stp);
 	pos._y = 0;
@@ -512,26 +512,21 @@ int Hero::cross(const V2D &a, const V2D &b) {
 }
 
 bool CGE2Engine::cross(const V2D &a, const V2D &b, const V2D &c, const V2D &d) {
-	if (contain(a, b, c))
-		return true;
-	if (contain(a, b, d))
-		return true;
-	if (contain(c, d, a))
-		return true;
-	if (contain(c, d, b))
+	if (contain(a, b, c) || contain(a, b, d) || contain(c, d, a) || contain(c, d, b))
 		return true;
+
 	return sgn(det(a, b, c)) != sgn(det(a, b, d)) && sgn(det(c, d, a)) != sgn(det(c, d, b));
 }
 
 bool CGE2Engine::contain(const V2D &a, const V2D &b, const V2D &p) {
 	if (det(a, b, p))
 		return false;
+
 	return ((long)(a.x - p.x) * (p.x - b.x) >= 0 && (long)(a.y - p.y) * (p.y - b.y) >= 0);
 }
 
 long CGE2Engine::det(const V2D &a, const V2D &b, const V2D &c) {
-	long n = ((long)a.x * b.y + (long)b.x * c.y + (long)c.x * a.y) - ((long)c.x * b.y + (long)b.x * a.y + (long)a.x * c.y);
-	return n;
+	return ((long)a.x * b.y + (long)b.x * c.y + (long)c.x * a.y) - ((long)c.x * b.y + (long)b.x * a.y + (long)a.x * c.y);
 }
 
 int CGE2Engine::sgn(long n) {
@@ -543,6 +538,7 @@ int Hero::mapCross(const V2D &a, const V2D &b) {
 	int n = (o->_scene == _scene) ? o->cross(a, b) : 0;
 	if (!_ignoreMap)
 		n += _vm->mapCross(a, b);
+
 	return n;
 }
 
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index ca4c336..605eed0 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -157,10 +157,9 @@ void Text::say(const char *text, Sprite *spr) {
 	if (east) {
 		if (pos.x + sw + kTextRoundCorner + kCaptionSide >= kScrWidth)
 			east = false;
-	} else {
-		if (pos.x <= kCaptionSide + kTextRoundCorner - sw)
-			east = true;
-	}
+	} else if (pos.x <= kCaptionSide + kTextRoundCorner - sw)
+		east = true;
+
 	if (east != (d.x > 0)) {
 		d.x = -d.x;
 		sw = -sw;
diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 486a422..424138f 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -74,11 +74,11 @@ FXP FXP::operator/(const FXP& x) const {
 		v1 -= v3 * v2;
 		v3 <<= 8;
 
-		if (v1 < 0xFFFFFF) {
+		if (v1 < 0xFFFFFF)
 			v1 <<= 8;
-		} else {
+		else
 			v2 >>= 8;
-		}
+
 		v3 += v1 / v2;
 
 		if (negFlag)
@@ -231,14 +231,16 @@ void Sprite::setName(char *newName) {
 int Sprite::labVal(Action snq, int lab) {
 	int lv = -1;
 	if (active()) {
-		int n = _actionCtrl[snq]._cnt;
+		int count = _actionCtrl[snq]._cnt;
 		CommandHandler::Command *com = snList(snq);
 
-		int i;
-		for (i = 0; i < n; i++)
+		int i = 0;
+		for (; i < count; i++) {
 			if (com[i]._lab == lab)
 				break;
-		if (i < n)
+		}
+
+		if (i < count)
 			return i;
 	} else {
 		char tmpStr[kLineMax + 1];
@@ -431,7 +433,7 @@ Sprite *Sprite::expand() {
 	if (curSeq) {
 		if (maxnow >= shpcnt)
 			error("Bad PHASE in SEQ %s", fname);
-		if (maxnxt && maxnxt >= seqcnt)
+		if (maxnxt && (maxnxt >= seqcnt))
 			error("Bad JUMP in SEQ %s", fname);
 		setSeq(curSeq);
 	} else {
@@ -811,9 +813,10 @@ void Queue::insert(Sprite *spr) {
 		return; // We only queue it if it's not already queued.
 
 	Sprite *s;
-	for (s = _head; s; s = s->_next)
+	for (s = _head; s; s = s->_next) {
 		if (s->_pos3D._z < spr->_pos3D._z)
 			break;
+	}
 
 	if (s)
 		insert(spr, s);
@@ -829,12 +832,16 @@ inline bool contains(const Common::List<T> &l, const T &v) {
 Sprite *Queue::remove(Sprite *spr) {
 	if (spr == _head)
 		_head = spr->_next;
+
 	if (spr == _tail)
 		_tail = spr->_prev;
+
 	if (spr->_next)
 		spr->_next->_prev = spr->_prev;
+
 	if (spr->_prev)
 		spr->_prev->_next = spr->_next;
+
 	spr->_prev = nullptr;
 	spr->_next = nullptr;
 	return spr;
@@ -850,9 +857,11 @@ Sprite *Queue::locate(int ref) {
 
 bool Queue::locate(Sprite *spr) {
 	Sprite *s;
-	for (s = _head; s; s = s->_next)
+	for (s = _head; s; s = s->_next) {
 		if (s == spr)
 			return true;
+	}
+
 	return false;
 }
 
@@ -889,6 +898,7 @@ Vga::~Vga() {
 	free(_newColors);
 	if (_msg)
 		buffer = Common::String(_msg);
+
 	if (_name)
 		buffer = buffer + " [" + _name + "]";
 
@@ -1005,7 +1015,7 @@ void Vga::setColors(Dac *tab, int lum) {
 	if (_mono) {
 		destP = _newColors;
 		for (int idx = 0; idx < kPalCount; idx++, destP++) {
-			// Form a greyscalce color from 30% R, 59% G, 11% B
+			// Form a grayscale color from 30% R, 59% G, 11% B
 			uint8 intensity = (((int)destP->_r * 77) + ((int)destP->_g * 151) + ((int)destP->_b * 28)) >> 8;
 			destP->_r = intensity;
 			destP->_g = intensity;


Commit: 7dfb2b01f1b1655622d0537ceaac3d2c91c699ad
    https://github.com/scummvm/scummvm/commit/7dfb2b01f1b1655622d0537ceaac3d2c91c699ad
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T15:04:00+02:00

Commit Message:
CGE2: Rearrange content of saveload.cpp and cge2.h a bit.

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



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index fc097b9..630be47 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -140,12 +140,12 @@ private:
 
 	Common::String generateSaveName(int slot);
 	void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
-	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
-	void syncHeader(Common::Serializer &s);
 	void saveGame(int slotNumber, const Common::String &desc);
 	bool loadGame(int slotNumber);
-	void resetGame();
+	void syncHeader(Common::Serializer &s);
+	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
 	void syncSpeechSettings();
+	void resetGame();
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
 	virtual bool hasFeature(EngineFeature f) const;
@@ -154,11 +154,13 @@ public:
 	virtual Common::Error saveGameState(int slot, const Common::String &desc);
 	virtual Common::Error loadGameState(int slot);
 	virtual Common::Error run();
+
+	static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+
 	GUI::Debugger *getDebugger() {
 		return _console;
 	}
 
-	static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
 	bool showTitle(const char *name);
 	void cge2_main();
 	char *mergeExt(char *buf, const char *name, const char *ext);
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index b95210e..b535596 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -141,35 +141,6 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
 	return SaveStateDescriptor();
 }
 
-bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
-	header.thumbnail = nullptr;
-
-	// Get the savegame version
-	header.version = in->readByte();
-	if (header.version > kSavegameVersion)
-		return false;
-
-	// Read in the string
-	header.saveName.clear();
-	char ch;
-	while ((ch = (char)in->readByte()) != '\0')
-		header.saveName += ch;
-
-	// Get the thumbnail
-	header.thumbnail = Graphics::loadThumbnail(*in);
-	if (!header.thumbnail)
-		return false;
-
-	// Read in save date/time
-	header.saveYear = in->readSint16LE();
-	header.saveMonth = in->readSint16LE();
-	header.saveDay = in->readSint16LE();
-	header.saveHour = in->readSint16LE();
-	header.saveMinutes = in->readSint16LE();
-
-	return true;
-}
-
 void CGE2MetaEngine::removeSaveState(const char *target, int slot) const {
 	Common::String fileName = Common::String::format("%s.%03d", target, slot);
 	g_system->getSavefileManager()->removeSavefile(fileName);
@@ -186,10 +157,6 @@ bool CGE2Engine::canSaveGameStateCurrently() {
 		_commandHandler->idle() && isHeroVisible;
 }
 
-bool CGE2Engine::canLoadGameStateCurrently() {
-	return (_startupMode == 0) && _mouse->_active;
-}
-
 Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
 	storeHeroPos();
 	saveGame(slot, desc);
@@ -217,12 +184,76 @@ void CGE2Engine::saveGame(int slotNumber, const Common::String &desc) {
 	delete saveFile;
 }
 
-/**
-* Support method that generates a savegame name
-* @param slot		Slot number
-*/
-Common::String CGE2Engine::generateSaveName(int slot) {
-	return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+bool CGE2Engine::canLoadGameStateCurrently() {
+	return (_startupMode == 0) && _mouse->_active;
+}
+
+Common::Error CGE2Engine::loadGameState(int slot) {
+	_commandHandler->clear();
+	_commandHandlerTurbo->clear();
+	sceneDown();
+	if (!loadGame(slot))
+		return Common::kReadingFailed;
+	sceneUp(_now);
+	initToolbar();
+	return Common::kNoError;
+}
+
+bool CGE2Engine::loadGame(int slotNumber) {
+	Common::MemoryReadStream *readStream;
+
+	// Open up the savegame file
+	Common::String slotName = generateSaveName(slotNumber);
+	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName);
+
+	// Read the data into a data buffer
+	int size = saveFile->size();
+	byte *dataBuffer = (byte *)malloc(size);
+	saveFile->read(dataBuffer, size);
+	readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES);
+	delete saveFile;
+	
+	// Check to see if it's a ScummVM savegame or not
+	char buffer[kSavegameStrSize + 1];
+	readStream->read(buffer, kSavegameStrSize + 1);
+
+	if (strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) != 0) {
+		delete readStream;
+		return false;
+	} else {
+		SavegameHeader saveHeader;
+
+		if (!readSavegameHeader(readStream, saveHeader)) {
+			delete readStream;
+			return false;
+		}
+
+		// Delete the thumbnail
+		saveHeader.thumbnail->free();
+		delete saveHeader.thumbnail;
+	}
+
+	resetGame();
+
+	// Get in the savegame
+	syncGame(readStream, nullptr);
+	delete readStream;
+
+	syncSpeechSettings();
+
+	loadHeroes();
+	
+	return true;
+}
+
+void CGE2Engine::resetGame() {
+	_busyPtr = nullptr;
+	busy(false);
+	_spare->clear();
+	_vga->_showQ->clear();
+	loadScript("CGE.INI", true);
+	delete _infoLine;
+	_infoLine = new InfoLine(this, kInfoW);
 }
 
 void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header) {
@@ -242,7 +273,7 @@ void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &h
 	for (int i = 0; i < 2; i++)
 		_heroTab[i]->_ptr->park();
 	_vga->show();
-	
+
 	// Create a thumbnail and save it
 	Graphics::Surface *thumb = new Graphics::Surface();
 	Graphics::Surface *s = _vga->_page[0];
@@ -261,6 +292,35 @@ void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &h
 	out->writeSint16LE(td.tm_min);
 }
 
+bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
+	header.thumbnail = nullptr;
+
+	// Get the savegame version
+	header.version = in->readByte();
+	if (header.version > kSavegameVersion)
+		return false;
+
+	// Read in the string
+	header.saveName.clear();
+	char ch;
+	while ((ch = (char)in->readByte()) != '\0')
+		header.saveName += ch;
+
+	// Get the thumbnail
+	header.thumbnail = Graphics::loadThumbnail(*in);
+	if (!header.thumbnail)
+		return false;
+
+	// Read in save date/time
+	header.saveYear = in->readSint16LE();
+	header.saveMonth = in->readSint16LE();
+	header.saveDay = in->readSint16LE();
+	header.saveHour = in->readSint16LE();
+	header.saveMinutes = in->readSint16LE();
+
+	return true;
+}
+
 void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream) {
 	Common::Serializer s(readStream, writeStream);
 
@@ -318,72 +378,12 @@ void CGE2Engine::syncHeader(Common::Serializer &s) {
 	}
 }
 
-Common::Error CGE2Engine::loadGameState(int slot) {
-	_commandHandler->clear();
-	_commandHandlerTurbo->clear();
-	sceneDown();
-	if (!loadGame(slot))
-		return Common::kReadingFailed;
-	sceneUp(_now);
-	initToolbar();
-	return Common::kNoError;
-}
-
-void CGE2Engine::resetGame() {
-	_busyPtr = nullptr;
-	busy(false);
-	_spare->clear();
-	_vga->_showQ->clear();
-	loadScript("CGE.INI", true);
-	delete _infoLine;
-	_infoLine = new InfoLine(this, kInfoW);
-}
-
-bool CGE2Engine::loadGame(int slotNumber) {
-	Common::MemoryReadStream *readStream;
-
-	// Open up the savegame file
-	Common::String slotName = generateSaveName(slotNumber);
-	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName);
-
-	// Read the data into a data buffer
-	int size = saveFile->size();
-	byte *dataBuffer = (byte *)malloc(size);
-	saveFile->read(dataBuffer, size);
-	readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES);
-	delete saveFile;
-	
-	// Check to see if it's a ScummVM savegame or not
-	char buffer[kSavegameStrSize + 1];
-	readStream->read(buffer, kSavegameStrSize + 1);
-
-	if (strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) != 0) {
-		delete readStream;
-		return false;
-	} else {
-		SavegameHeader saveHeader;
-
-		if (!readSavegameHeader(readStream, saveHeader)) {
-			delete readStream;
-			return false;
-		}
-
-		// Delete the thumbnail
-		saveHeader.thumbnail->free();
-		delete saveHeader.thumbnail;
-	}
-
-	resetGame();
-
-	// Get in the savegame
-	syncGame(readStream, nullptr);
-	delete readStream;
-
-	syncSpeechSettings();
-
-	loadHeroes();
-	
-	return true;
+/**
+* Support method that generates a savegame name
+* @param slot		Slot number
+*/
+Common::String CGE2Engine::generateSaveName(int slot) {
+	return Common::String::format("%s.%03d", _targetName.c_str(), slot);
 }
 
 } // End of namespace CGE2


Commit: 41fece64878ff982dc63a2b63d6f7e552c8fe6f3
    https://github.com/scummvm/scummvm/commit/41fece64878ff982dc63a2b63d6f7e552c8fe6f3
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T15:18:44+02:00

Commit Message:
CGE2: Remove #if 0-s.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index e945fbf..8ee3d78 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -749,9 +749,8 @@ void CGE2Engine::cge2_main() {
 	}
 
 	if (showTitle("WELCOME")) {
-#if 0
 		movie(kIntroExt);
-#endif
+
 		if (_text->getText(255) != nullptr) {
 			runGame();
 			_startupMode = 2;
@@ -815,9 +814,8 @@ bool CGE2Engine::showTitle(const char *name) {
 	_vga->sunrise(_vga->_sysPal);
 	_vga->update();
 
-#if 0
 	g_system->delayMillis(2500);
-#endif
+
 	return true;
 }
 


Commit: b8b3e5af04f349ec353cffd73f399e21c4301f78
    https://github.com/scummvm/scummvm/commit/b8b3e5af04f349ec353cffd73f399e21c4301f78
Author: Strangerke (strangerke at scummvm.org)
Date: 2014-08-03T15:44:20+02:00

Commit Message:
CGE2: Some more minor cleanup

Changed paths:
    engines/cge2/bitmap.cpp
    engines/cge2/cge2_main.cpp
    engines/cge2/detection.cpp
    engines/cge2/events.cpp
    engines/cge2/inventory.cpp
    engines/cge2/snail.cpp
    engines/cge2/sound.cpp
    engines/cge2/spare.cpp
    engines/cge2/talk.cpp
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 289e156..bcc9e98 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -201,14 +201,14 @@ BitmapPtr Bitmap::code(uint8 *map) {
 				uint8 pix;
 				for (j = bpl; j < _w; j += 4) {
 					pix = bm[j];
-					if (_v && pix != kPixelTransp) {
+					if (_v && (pix != kPixelTransp)) {
 						if (j < _b[i]._skip)
 							_b[i]._skip = j;
 
 						if (j >= _b[i]._hide)
 							_b[i]._hide = j + 1;
 					}
-					if ((pix == kPixelTransp) != skip || cnt >= 0x3FF0) { // end of block
+					if (((pix == kPixelTransp) != skip) || (cnt >= 0x3FF0)) { // end of block
 						cnt |= (skip) ? kBmpSKP : kBmpCPY;
 						if (_v)
 							WRITE_LE_UINT16(cp, cnt); // store block description uint16
@@ -228,9 +228,9 @@ BitmapPtr Bitmap::code(uint8 *map) {
 
 				bm += _w;
 				if (_w < kScrWidth) {
-					if (skip) {
+					if (skip)
 						cnt += (kScrWidth - j + 3) / 4;
-					} else {
+					else {
 						cnt |= kBmpCPY;
 						if (_v)
 							WRITE_LE_UINT16(cp, cnt);
@@ -333,7 +333,7 @@ bool Bitmap::solidAt(V2D pos) {
 			break;
 		case kBmpREP:
 		case kBmpCPY:
-			if (n - w <= n0 && n > n0)
+			if ((n - w <= n0) && (n > n0))
 				return true;
 			break;
 		}
@@ -449,7 +449,7 @@ uint8 *Bitmap::makeSpeechBubbleTail(int which, uint8 colorSet[][4]) {
 	}
 
 	for (int i = 0; i < kDesignSize; i++) {
-		if (des[i] >= 1 && des[i] <= 3)
+		if ((des[i] >= 1) && (des[i] <= 3))
 			des[i] = colorSet[kCBSay][des[i]];
 	}
 
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 8ee3d78..cdf2aa6 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -266,9 +266,8 @@ Sprite *CGE2Engine::loadSprite(const char *fname, int ref, int scene, V3D &pos)
 			label = kNoByte;
 		}
 
-		if (!shpcnt) {
+		if (!shpcnt)
 			error("No shapes - %s", fname);
-		}
 	} else // No sprite description: mono-shaped sprite with only .BMP file.
 		++shpcnt;
 
@@ -596,12 +595,10 @@ void CGE2Engine::tick() {
 
 	for (Sprite *spr = _vga->_showQ->first(); spr; spr = spr->_next) {
 		if (spr->_time && (--spr->_time == 0))
-				spr->tick();
+			spr->tick();
 		
-		if (_waitRef) {
-			if (_waitRef == spr->_ref && spr->seqTest(_waitSeq))
-					_waitRef = 0;
-		}
+		if (_waitRef && (_waitRef == spr->_ref) && spr->seqTest(_waitSeq))
+			_waitRef = 0;
 	}
 
 	_mouse->tick();
@@ -951,10 +948,8 @@ Sprite *CGE2Engine::spriteAt(V2D pos) {
 	Sprite *spr;
 
 	for (spr = _vga->_showQ->last(); spr; spr = spr->_prev) {
-		if (!spr->_flags._hide && !spr->_flags._tran) {
-			if (spr->getShp()->solidAt(pos - spr->_pos2D))
-				break;
-		}
+		if (!spr->_flags._hide && !spr->_flags._tran && (spr->getShp()->solidAt(pos - spr->_pos2D)))
+			break;
 	}
 
 	return spr;
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 5fcbe2e..a7b25d1 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -30,9 +30,9 @@
 namespace CGE2 {
 
 bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
-	if (desc) {
+	if (desc)
 		*engine = new CGE2::CGE2Engine(syst, desc);
-	}
+
 	return desc != 0;
 }
 
@@ -50,14 +50,13 @@ const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles,
 	static ADGameDescription desc;
 
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
-		if (file->isDirectory()) {
+		if (file->isDirectory())
 			continue;
-		}
+
 		if (file->getName().equalsIgnoreCase("lang.eng")) {
 			Common::File dataFile;
-			if (!dataFile.open(*file)) {
+			if (!dataFile.open(*file))
 				continue;
-			}
 			
 			desc.gameid = "sfinx";
 			desc.extra = "Sfinx English Alfa v0.1";
diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index cf6d3b0..7dd254d 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -54,7 +54,7 @@ Sprite *Keyboard::setClient(Sprite *spr) {
 bool Keyboard::getKey(Common::Event &event) {
 	Common::KeyCode keycode = event.kbd.keycode;
 
-	if (((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) && event.type == Common::EVENT_KEYDOWN)
+	if (((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) && (event.type == Common::EVENT_KEYDOWN))
 		_keyAlt = true;
 	else
 		_keyAlt = false;
@@ -117,7 +117,7 @@ void Keyboard::newKeyboard(Common::Event &event) {
 	if (!getKey(event))
 		return;
 
-	if ((event.type == Common::EVENT_KEYDOWN) && (_client)) {
+	if ((event.type == Common::EVENT_KEYDOWN) && _client) {
 		CGE2Event &evt = _vm->_eventManager->getNextEvent();
 		evt._x = 0;
 		evt._y = 0;
@@ -253,7 +253,7 @@ void EventManager::handleEvents() {
 				e._spritePtr = _vm->spriteAt(_vm->_mouse->_point);
 				e._x += (_vm->_mouse->_siz.x >> 1);
 				e._y -= _vm->_mouse->_siz.y;
-				if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold) {
+				if (_vm->_mouse->_hold && (e._spritePtr != _vm->_mouse->_hold)) {
 					_vm->_mouse->_hold->touch(e._mask | kEventAttn,
 						V2D(_vm, e._x - _vm->_mouse->_hold->_pos2D.x, e._y - _vm->_mouse->_hold->_pos2D.y), e._keyCode);
 				}
@@ -281,9 +281,10 @@ void EventManager::handleEvents() {
 
 void EventManager::clearEvent(Sprite *spr) {
 	if (spr) {
-		for (uint16 e = _eventQueueTail; e != _eventQueueHead; e = (e + 1) % kEventMax)
+		for (uint16 e = _eventQueueTail; e != _eventQueueHead; e = (e + 1) % kEventMax) {
 			if (_eventQueue[e]._spritePtr == spr)
 				_eventQueue[e]._mask = 0;
+		}
 	} else
 		_eventQueueTail = _eventQueueHead;
 }
diff --git a/engines/cge2/inventory.cpp b/engines/cge2/inventory.cpp
index 7029a64..e62aa01 100644
--- a/engines/cge2/inventory.cpp
+++ b/engines/cge2/inventory.cpp
@@ -34,7 +34,7 @@ int CGE2Engine::findActivePocket(int ref) {
 	for (int i = 0; i < kPocketMax; i++) {
 		Sprite *spr = _heroTab[_sex]->_pocket[i];
 		if (ref >= 0) {
-			if (spr && spr->_ref == ref)
+			if (spr && (spr->_ref == ref))
 				return i;
 		} else if (!spr)
 			return i;
@@ -45,13 +45,12 @@ int CGE2Engine::findActivePocket(int ref) {
 void CGE2Engine::selectPocket(int n) {
 	Sprite **p = _heroTab[_sex]->_pocket;
 	int &pp = _heroTab[_sex]->_pocPtr;
-	if (n < 0 || pp == n) {
+	if ((n < 0) || (pp == n)) {
 		n = findActivePocket(-1);
 		if (n >= 0)
 			pp = n;
-	} else if (p[n]) {
+	} else if (p[n])
 		pp = n;
-	}
 }
 
 void CGE2Engine::pocFul() {
diff --git a/engines/cge2/snail.cpp b/engines/cge2/snail.cpp
index 2974767..2cd5aca 100644
--- a/engines/cge2/snail.cpp
+++ b/engines/cge2/snail.cpp
@@ -57,17 +57,16 @@ void CommandHandler::runCommand() {
 	if (!_turbo && _vm->_soundStat._wait) {
 		if (*(_vm->_soundStat._wait))
 			return;
-		else {
-			++_vm->_soundStat._ref[0];
-			if (_vm->_fx->exist(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0])) {
-				int16 oldRepeat = _vm->_sound->getRepeat();
-				_vm->_sound->setRepeat(1);
-				_vm->_sound->play(Audio::Mixer::kSFXSoundType, _vm->_fx->load(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0]), _vm->_sound->_smpinf._span);
-				_vm->_sound->setRepeat(oldRepeat);
-				return;
-			}
-			_vm->_soundStat._wait = nullptr;
+
+		++_vm->_soundStat._ref[0];
+		if (_vm->_fx->exist(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0])) {
+			int16 oldRepeat = _vm->_sound->getRepeat();
+			_vm->_sound->setRepeat(1);
+			_vm->_sound->play(Audio::Mixer::kSFXSoundType, _vm->_fx->load(_vm->_soundStat._ref[1], _vm->_soundStat._ref[0]), _vm->_sound->_smpinf._span);
+			_vm->_sound->setRepeat(oldRepeat);
+			return;
 		}
+		_vm->_soundStat._wait = nullptr;
 	}
 
 	uint8 tmpHead = _head;
@@ -77,6 +76,7 @@ void CommandHandler::runCommand() {
 		if (!_turbo) { // only for the slower one
 			if (_vm->_waitRef)
 				break;
+
 			if (_timerExpiry) {
 				// Delay in progress
 				if (_timerExpiry > g_system->getMillis())
@@ -103,11 +103,12 @@ void CommandHandler::runCommand() {
 			spr = (tailCmd._ref < 0) ? ((Sprite *)tailCmd._spritePtr) : _vm->locate(tailCmd._ref);
 
 		Common::String sprStr;
-		if (spr && spr->_file && tailCmd._commandType != kCmdGhost)
+		if (spr && spr->_file && (tailCmd._commandType != kCmdGhost))
 			// In case of kCmdGhost _spritePtr stores a pointer to a Bitmap, not to a Sprite...
 			sprStr = Common::String(spr->_file);
 		else
 			sprStr = "None";
+
 		if (sprStr.empty())
 			sprStr = "None";
 		debugC(1, kCGE2DebugOpcode, "Command: %s; Ref: %d; Val: %d; Sprite: %s;", getComStr(tailCmd._commandType), tailCmd._ref, tailCmd._val, sprStr.c_str());
@@ -316,7 +317,7 @@ void CGE2Engine::snMidi(int val) {
 
 void CGE2Engine::snSeq(Sprite *spr, int val) {
 	if (spr) {
-		if (isHero(spr) && val == 0)
+		if (isHero(spr) && (val == 0))
 			((Hero*)spr)->park();
 		else
 			spr->step(val);
@@ -344,9 +345,8 @@ void CGE2Engine::snSend(Sprite *spr, int val) {
 			// deactivating
 			hide1(spr);
 			spr->_flags._slav = false;
-			if (spr == _heroTab[_sex]->_ptr)
-				if (_heroTab[!_sex]->_ptr->_scene == _now)
-					switchHero(!_sex);
+			if ((spr == _heroTab[_sex]->_ptr) && (_heroTab[!_sex]->_ptr->_scene == _now))
+				switchHero(!_sex);
 			_spare->dispose(spr);
 		} else {
 			// activating
@@ -496,9 +496,8 @@ void CGE2Engine::snGoto(Sprite *spr, int val) {
 }
 
 void CGE2Engine::snPort(Sprite *spr, int port) {
-	if (spr) {
+	if (spr)
 		spr->_flags._port = (port < 0) ? !spr->_flags._port : (port != 0);
-	}
 }
 
 void CGE2Engine::snMouse(bool on) {
@@ -547,9 +546,8 @@ void CGE2Engine::snRmFTake(Sprite *spr) {
 }
 
 void CGE2Engine::snSetRef(Sprite *spr, int val) {
-	if (spr) {
+	if (spr)
 		spr->_ref = val;
-	}
 }
 
 void CGE2Engine::snFlash(bool on) {
@@ -812,10 +810,9 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 		}
 
 		while (c < q) {
-			if (c->_commandType == kCmdWalk || c->_commandType == kCmdReach) {
-				if (c->_val == -1)
-					c->_val = spr->_ref;
-			}
+			if ((c->_val == -1) && (c->_commandType == kCmdWalk || c->_commandType == kCmdReach))
+				c->_val = spr->_ref;
+
 			if (c->_commandType == kCmdNext) {
 				Sprite *s;
 
@@ -831,29 +828,28 @@ void CGE2Engine::feedSnail(Sprite *spr, Action snq, Hero *hero) {
 					break;
 				}
 
-				if (s) {
-					if (s->_actionCtrl[snq]._cnt) {
-						int v;
-						switch (c->_val) {
-						case -1:
-							v = int(c - comtab + 1);
-							break;
-						case -2:
-							v = int(c - comtab);
-							break;
-						case -3:
-							v = -1;
-							break;
-						default:
-							v = c->_val;
-							if ((v > 255) && s)
-								v = s->labVal(snq, v >> 8);
-							break;
-						}
-						if (v >= 0)
-							s->_actionCtrl[snq]._ptr = v;
+				if (s && s->_actionCtrl[snq]._cnt) {
+					int v;
+					switch (c->_val) {
+					case -1:
+						v = int(c - comtab + 1);
+						break;
+					case -2:
+						v = int(c - comtab);
+						break;
+					case -3:
+						v = -1;
+						break;
+					default:
+						v = c->_val;
+						if ((v > 255) && s)
+							v = s->labVal(snq, v >> 8);
+						break;
 					}
+					if (v >= 0)
+						s->_actionCtrl[snq]._ptr = v;
 				}
+
 				if (s == spr)
 					break;
 			}
diff --git a/engines/cge2/sound.cpp b/engines/cge2/sound.cpp
index cc148d6..c34eb00 100644
--- a/engines/cge2/sound.cpp
+++ b/engines/cge2/sound.cpp
@@ -250,7 +250,7 @@ void MusicPlayer::sndMidiStart() {
 }
 
 void MusicPlayer::send(uint32 b) {
-	if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+	if (((b & 0xF0) == 0xC0) && !_isGM && !_nativeMT32) {
 		b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
 	}
 
diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp
index 4ca2900..53f99e4 100644
--- a/engines/cge2/spare.cpp
+++ b/engines/cge2/spare.cpp
@@ -37,9 +37,10 @@ void Spare::sync(Common::Serializer &s) {
 				size++;
 		s.syncAsSint16LE(size);
 
-		for (uint i = 0; i < _container.size(); i++)
+		for (uint i = 0; i < _container.size(); i++) {
 			if (_container[i]->_ref >= 141)
 				_container[i]->sync(s);
+		}
 	} else {
 		int size;
 		s.syncAsSint16LE(size);
diff --git a/engines/cge2/talk.cpp b/engines/cge2/talk.cpp
index dbdfc0d..c39e064 100644
--- a/engines/cge2/talk.cpp
+++ b/engines/cge2/talk.cpp
@@ -186,7 +186,7 @@ void Talk::update(const char *text) {
 		mh = 2 * vmarg + kFontHigh;
 		mw = 0;
 		for (const char *p = text; *p; p++) {
-			if (*p == '|' || *p == '\n') {
+			if ((*p == '|') || (*p == '\n')) {
 				mh += kFontHigh + kTextLineSpace;
 				if (k > mw)
 					mw = k;
@@ -208,9 +208,9 @@ void Talk::update(const char *text) {
 	m = map + ln * mw + hmarg;
 
 	while (*text) {
-		if (*text == '|' || *text == '\n') {
+		if ((*text == '|') || (*text == '\n'))
 			m = map + (ln += kFontHigh + kTextLineSpace) * mw + hmarg;
-		} else {
+		else {
 			int cw = _vm->_font->_widthArr[(unsigned char)*text];
 			uint8 *f = _vm->_font->_map + _vm->_font->_pos[(unsigned char)*text];
 
@@ -254,7 +254,7 @@ InfoLine::InfoLine(CGE2Engine *vm, uint16 w, ColorBank color)
 }
 
 void InfoLine::update(const char *text) {
-	if (!_realTime && text == _oldText)
+	if (!_realTime && (text == _oldText))
 		return;
 
 	_oldText = text;
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 5880dfc..4b328df 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -115,17 +115,17 @@ void CGE2Engine::checkMusicSwitch() {
 	bool mute = false;
 	if (ConfMan.hasKey("mute"))
 		mute = ConfMan.getBool("mute");
+
 	bool musicMuted = mute;
 	int musicVolume = ConfMan.getInt("music_volume");
 	if (!musicMuted)
 		musicMuted = musicVolume == 0;
 
-	if (!musicMuted && !_music) {
+	if (!musicMuted && !_music)
 		switchMusic(_music = true);
-	}
-	if (musicMuted && _music) {
+
+	if (musicMuted && _music)
 		switchMusic(_music = false);
-	}
 }
 
 void CGE2Engine::quit() {
@@ -148,7 +148,7 @@ void CGE2Engine::quit() {
 void CGE2Engine::setVolume(int idx, int cnt) {
 	if (cnt && _vol[idx]) {
 		int p = _vol[idx]->_seqPtr + cnt;
-		if (p >= 0 && p < _vol[idx]->_seqCnt) {
+		if ((p >= 0) && (p < _vol[idx]->_seqCnt)) {
 			_vol[idx]->step(p);
 			int newVolume = p * kSoundStatetoNumRate;
 			switch (idx) {
@@ -171,28 +171,29 @@ void CGE2Engine::checkVolumeSwitches() {
 	bool mute = false;
 	if (ConfMan.hasKey("mute"))
 		mute = ConfMan.getBool("mute");
+
 	bool musicMuted = mute;
 	int musicVolume = ConfMan.getInt("music_volume");
 	if (!musicMuted)
 		musicMuted = musicVolume == 0;
+
 	bool sfxMuted = mute;
 	int sfxVolume = ConfMan.getInt("sfx_volume");
 	if (!sfxMuted)
 		sfxMuted = sfxVolume == 0;
 	
-	if ((!musicMuted && !_music) ||
-		(musicVolume != _oldMusicVolume && !musicMuted)) {
+	if ((!musicMuted && !_music) || (musicVolume != _oldMusicVolume && !musicMuted))
 		_vol[1]->step(musicVolume / kSoundNumtoStateRate);
-	}
-	if (musicMuted && _music) {
+
+	if (musicMuted && _music)
 		_vol[1]->step(0);
-	}
 
 	if ((!sfxMuted && !_sfx) || (sfxVolume != _oldSfxVolume)) {
 		_vol[0]->step(sfxVolume / kSoundNumtoStateRate);
 		_oldSfxVolume = sfxVolume;
 		_sfx = true;
 	}
+
 	if (sfxMuted && _sfx) {
 		_vol[0]->step(0);
 		_sfx = false;
@@ -220,9 +221,9 @@ void CGE2Engine::switchVox() {
 }
 
 void CGE2Engine::updateSpeechVolume() {
-	if (_sayVox) {
+	if (_sayVox)
 		ConfMan.setInt("speech_volume", _oldSpeechVolume);
-	} else {
+	else {
 		_oldSpeechVolume = ConfMan.getInt("speech_volume");
 		ConfMan.setInt("speech_volume", 0);
 	}
@@ -237,18 +238,18 @@ void CGE2Engine::checkSaySwitch() {
 	bool mute = false;
 	if (ConfMan.hasKey("mute"))
 		mute = ConfMan.getBool("mute");
+
 	bool speechMuted = mute;
 	if (!speechMuted) {
 		int speechVolume = ConfMan.getInt("speech_volume");
 		speechMuted = speechVolume == 0;
 	}
 
-	if (!speechMuted && !_sayVox) {
+	if (!speechMuted && !_sayVox)
 		switchVox();
-	}
-	if (speechMuted && _sayVox) {
+
+	if (speechMuted && _sayVox)
 		switchVox();
-	}
 }
 
 void CGE2Engine::initToolbar() {
@@ -279,6 +280,7 @@ void CGE2Engine::initToolbar() {
 
 	if (_vol[0])
 		initVolumeSwitch(_vol[0]);
+
 	if (_vol[1])
 		initVolumeSwitch(_vol[1]);
 }


Commit: 07fc3fb3c368ad4c801fb3c0a804eb9a7a127685
    https://github.com/scummvm/scummvm/commit/07fc3fb3c368ad4c801fb3c0a804eb9a7a127685
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T19:16:18+02:00

Commit Message:
CGE2: Some repair in Bitmap::code().

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index bcc9e98..6d38f33 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -183,21 +183,20 @@ BitmapPtr Bitmap::code(uint8 *map) {
 	while (true) {                                  // at most 2 times: for (V == NULL) & for allocated block;
 		uint8 *im = _v + 2;
 		uint16 *cp = (uint16 *) _v;
-		int bpl;
 
 		if (_v) {                                      // 2nd pass - fill the hide table
-			for (uint16 i = 0; i < _h; i++) {
+			for (uint i = 0; i < _h; i++) {
 				_b[i]._skip = 0xFFFF;
 				_b[i]._hide = 0x0000;
 			}
 		}
-		for (bpl = 0; bpl < 4; bpl++) {              // once per each bitplane
+		for (int bpl = 0; bpl < 4; bpl++) {              // once per each bitplane
 			uint8 *bm = map;
 			bool skip = (bm[bpl] == kPixelTransp);
 			uint16 j;
 
 			cnt = 0;
-			for (uint16 i = 0; i < _h; i++) {                  // once per each line
+			for (uint i = 0; i < _h; i++) {                  // once per each line
 				uint8 pix;
 				for (j = bpl; j < _w; j += 4) {
 					pix = bm[j];
@@ -263,7 +262,7 @@ BitmapPtr Bitmap::code(uint8 *map) {
 		_b = (HideDesc *)(_v + sizV);
 	}
 	cnt = 0;
-	for (uint16 i = 0; i < _h; i++) {
+	for (uint i = 0; i < _h; i++) {
 		if (_b[i]._skip == 0xFFFF) {                    // whole line is skipped
 			_b[i]._skip = (cnt + kScrWidth) >> 2;
 			cnt = 0;


Commit: 11d2cf66b60799c12bec5279f801c402d90f1476
    https://github.com/scummvm/scummvm/commit/11d2cf66b60799c12bec5279f801c402d90f1476
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T22:23:55+02:00

Commit Message:
CGE2: Rework the handling of the sound buttons on the toolbar.

Also keep in sync the volume settings and the audio mode of the game and the settings in the Launcher.

Changed paths:
    engines/cge2/cge2.cpp
    engines/cge2/cge2.h
    engines/cge2/cge2_main.cpp
    engines/cge2/saveload.cpp
    engines/cge2/toolbar.cpp



diff --git a/engines/cge2/cge2.cpp b/engines/cge2/cge2.cpp
index 9c16bd4..f3bc1de 100644
--- a/engines/cge2/cge2.cpp
+++ b/engines/cge2/cge2.cpp
@@ -96,15 +96,12 @@ CGE2Engine::CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription)
 	_midiNotify = nullptr;
 	_spriteNotify = nullptr;
 	
-	_enaCap = true;
-	_enaVox = true;
-	_sayCap = true;
-	_sayVox = true;
+	_sayCap = ConfMan.getBool("subtitles");
+	_sayVox = !ConfMan.getBool("speech_mute");
 	if (ConfMan.getBool("mute")) {
-		_oldSpeechVolume = _oldMusicVolume = _oldSfxVolume = 0;
+		_oldMusicVolume = _oldSfxVolume = 0;
 		_music = _sfx = false;
 	} else {
-		_oldSpeechVolume = ConfMan.getInt("speech_volume");
 		_oldMusicVolume = ConfMan.getInt("music_volume");
 		_oldSfxVolume = ConfMan.getInt("sfx_volume");
 		_music = _oldMusicVolume != 0;
@@ -192,20 +189,17 @@ bool CGE2Engine::hasFeature(EngineFeature f) const {
 
 Common::Error CGE2Engine::run() {
 	syncSoundSettings();
-	syncSpeechSettings();
 	initGraphics(kScrWidth, kScrHeight, false);
 
 	init();
 	cge2_main();
 	deinit();
 
-	return Common::kNoError;
-}
+	ConfMan.setBool("subtitles", _sayCap);
+	ConfMan.setBool("speech_mute", !_sayVox);
+	ConfMan.flushToDisk();
 
-void CGE2Engine::syncSpeechSettings() {
-	_enaCap = _sayCap = ConfMan.getBool("subtitles");
-	_enaVox = _sayVox = !ConfMan.getBool("speech_mute");
+	return Common::kNoError;
 }
 
-
 } // End of namespace CGE2
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 630be47..8b2a238 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -144,7 +144,6 @@ private:
 	bool loadGame(int slotNumber);
 	void syncHeader(Common::Serializer &s);
 	void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
-	void syncSpeechSettings();
 	void resetGame();
 public:
 	CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription);
@@ -209,17 +208,13 @@ public:
 
 	void optionTouch(int opt, uint16 mask);
 	void switchColorMode();
-	void switchMusic(bool on);
-	void updateMusicVolume();
-	void checkMusicSwitch();
+	void switchMusic();
 	void quit();
 	void setVolume(int idx, int cnt);
 	void checkVolumeSwitches();
 	void switchCap();
 	void switchVox();
-	void updateSpeechVolume();
 	void switchSay();
-	void checkSaySwitch();
 	void initToolbar();
 	void initVolumeSwitch(Sprite *volSwitch);
 
@@ -298,11 +293,8 @@ public:
 	NotifyFunctionType _spriteNotify;
 	int _startGameSlot;
 
-	bool _enaCap;
-	bool _enaVox;
 	bool _sayCap;
 	bool _sayVox;
-	int _oldSpeechVolume;
 	int _oldMusicVolume;
 	int _oldSfxVolume;
 	bool _music;
diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index cdf2aa6..9b4b1af 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -541,9 +541,7 @@ void CGE2Engine::mainLoop() {
 
 void CGE2Engine::checkSounds() {
 	_sound->checkSoundHandles();
-	checkSaySwitch();
 	checkVolumeSwitches();
-	checkMusicSwitch();
 	_midiPlayer->syncVolume();
 }
 
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index b535596..a7d04bb 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -239,8 +239,6 @@ bool CGE2Engine::loadGame(int slotNumber) {
 	syncGame(readStream, nullptr);
 	delete readStream;
 
-	syncSpeechSettings();
-
 	loadHeroes();
 	
 	return true;
diff --git a/engines/cge2/toolbar.cpp b/engines/cge2/toolbar.cpp
index 4b328df..3972df9 100644
--- a/engines/cge2/toolbar.cpp
+++ b/engines/cge2/toolbar.cpp
@@ -54,10 +54,8 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			switchColorMode();
 		break;
 	case 2:
-		if ((mask & kMouseLeftUp) && notMuted) {
-			switchMusic(_music = !_music);
-			updateMusicVolume();
-		}
+		if ((mask & kMouseLeftUp) && notMuted)
+			switchMusic();
 		break;
 	case 3:
 		if (mask & kMouseLeftUp)
@@ -72,14 +70,12 @@ void CGE2Engine::optionTouch(int opt, uint16 mask) {
 			setVolume(opt - 4, (mask & kMouseLeftUp) ? 1 : -1);
 		break;
 	case 8:
-		if (mask & kMouseLeftUp)
+		if ((mask & kMouseLeftUp) && notMuted)
 			switchCap();
 		break;
 	case 9:
-		if ((mask & kMouseLeftUp) && notMuted) {
+		if ((mask & kMouseLeftUp) && notMuted)
 			switchVox();
-			updateSpeechVolume();
-		}
 		break;
 	default:
 		break;
@@ -94,38 +90,12 @@ void CGE2Engine::switchColorMode() {
 	_vga->setColors(_vga->_sysPal, 64);
 }
 
-void CGE2Engine::switchMusic(bool on) {
-	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, on, nullptr);
+void CGE2Engine::switchMusic() {
+	_music = !_music;
+	_mixer->muteSoundType(Audio::Mixer::kMusicSoundType, !_music);
+	_commandHandlerTurbo->addCommand(kCmdSeq, kMusicRef, _music, nullptr);
 	keyClick();
-	_commandHandlerTurbo->addCommand(kCmdMidi, -1, on ? (_now << 8) : -1, nullptr);
-}
-
-void CGE2Engine::updateMusicVolume() {
-	if (_music) {
-		ConfMan.setInt("music_volume", _oldMusicVolume);
-		_vol[1]->step(_oldMusicVolume / kSoundNumtoStateRate);
-	} else {
-		_oldMusicVolume = ConfMan.getInt("music_volume");
-		ConfMan.setInt("music_volume", 0);
-		_vol[1]->step(0);
-	}
-}
-
-void CGE2Engine::checkMusicSwitch() {
-	bool mute = false;
-	if (ConfMan.hasKey("mute"))
-		mute = ConfMan.getBool("mute");
-
-	bool musicMuted = mute;
-	int musicVolume = ConfMan.getInt("music_volume");
-	if (!musicMuted)
-		musicMuted = musicVolume == 0;
-
-	if (!musicMuted && !_music)
-		switchMusic(_music = true);
-
-	if (musicMuted && _music)
-		switchMusic(_music = false);
+	_commandHandlerTurbo->addCommand(kCmdMidi, -1, _music ? (_now << 8) : -1, nullptr);
 }
 
 void CGE2Engine::quit() {
@@ -168,65 +138,33 @@ void CGE2Engine::setVolume(int idx, int cnt) {
 }
 
 void CGE2Engine::checkVolumeSwitches() {
-	bool mute = false;
-	if (ConfMan.hasKey("mute"))
-		mute = ConfMan.getBool("mute");
-
-	bool musicMuted = mute;
 	int musicVolume = ConfMan.getInt("music_volume");
-	if (!musicMuted)
-		musicMuted = musicVolume == 0;
-
-	bool sfxMuted = mute;
-	int sfxVolume = ConfMan.getInt("sfx_volume");
-	if (!sfxMuted)
-		sfxMuted = sfxVolume == 0;
-	
-	if ((!musicMuted && !_music) || (musicVolume != _oldMusicVolume && !musicMuted))
+	if (musicVolume != _oldMusicVolume)
 		_vol[1]->step(musicVolume / kSoundNumtoStateRate);
 
-	if (musicMuted && _music)
-		_vol[1]->step(0);
-
-	if ((!sfxMuted && !_sfx) || (sfxVolume != _oldSfxVolume)) {
+	int sfxVolume = ConfMan.getInt("sfx_volume");
+	if (sfxVolume != _oldSfxVolume) {
 		_vol[0]->step(sfxVolume / kSoundNumtoStateRate);
 		_oldSfxVolume = sfxVolume;
 		_sfx = true;
 	}
-
-	if (sfxMuted && _sfx) {
-		_vol[0]->step(0);
-		_sfx = false;
-	}
 }
 
 void CGE2Engine::switchCap() {
-	if (_enaCap && _enaVox) {
-		_sayCap = !_sayCap;
-		if (!_sayCap && _enaVox)
-			_sayVox = true;
-		keyClick();
-		switchSay();
-	}
+	_sayCap = !_sayCap;
+	if (!_sayCap)
+		_sayVox = true;
+	keyClick();
+	switchSay();
 }
 
 void CGE2Engine::switchVox() {
-	if (_enaVox && _enaCap) {
-		_sayVox = !_sayVox;
-		if (!_sayVox && _enaCap)
-			_sayCap = true;
-		keyClick();
-		switchSay();
-	}
-}
-
-void CGE2Engine::updateSpeechVolume() {
-	if (_sayVox)
-		ConfMan.setInt("speech_volume", _oldSpeechVolume);
-	else {
-		_oldSpeechVolume = ConfMan.getInt("speech_volume");
-		ConfMan.setInt("speech_volume", 0);
-	}
+	_mixer->muteSoundType(Audio::Mixer::kSpeechSoundType, _sayVox);
+	_sayVox = !_sayVox;
+	if (!_sayVox)
+		_sayCap = true;
+	keyClick();
+	switchSay();
 }
 
 void CGE2Engine::switchSay() {
@@ -234,24 +172,6 @@ void CGE2Engine::switchSay() {
 	_commandHandlerTurbo->addCommand(kCmdSeq, 128, _sayCap, nullptr);
 }
 
-void CGE2Engine::checkSaySwitch() {
-	bool mute = false;
-	if (ConfMan.hasKey("mute"))
-		mute = ConfMan.getBool("mute");
-
-	bool speechMuted = mute;
-	if (!speechMuted) {
-		int speechVolume = ConfMan.getInt("speech_volume");
-		speechMuted = speechVolume == 0;
-	}
-
-	if (!speechMuted && !_sayVox)
-		switchVox();
-
-	if (speechMuted && _sayVox)
-		switchVox();
-}
-
 void CGE2Engine::initToolbar() {
 	selectPocket(-1);
 


Commit: 69b9a3fdffe5d13b9d200b612559320eda80851f
    https://github.com/scummvm/scummvm/commit/69b9a3fdffe5d13b9d200b612559320eda80851f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T22:49:43+02:00

Commit Message:
CGE2: Properly fade out if the player exits during the intro too.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 9b4b1af..f3a76d8 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -749,8 +749,9 @@ void CGE2Engine::cge2_main() {
 		if (_text->getText(255) != nullptr) {
 			runGame();
 			_startupMode = 2;
-		} else
-			_vga->sunset();
+		}
+		
+		_vga->sunset();
 	} else
 		_vga->sunset();
 }


Commit: 010a806a195f492119e2f0066d6ae398d74f3d28
    https://github.com/scummvm/scummvm/commit/010a806a195f492119e2f0066d6ae398d74f3d28
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-03T22:50:16+02:00

Commit Message:
CGE2: Rework canSaveGameStateCurrently().

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index a7d04bb..0fb3fb2 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -147,14 +147,8 @@ void CGE2MetaEngine::removeSaveState(const char *target, int slot) const {
 }
 
 bool CGE2Engine::canSaveGameStateCurrently() {
-	bool isHeroVisible = false;
-	for (int i = 0; i < 2; i++) {
-		isHeroVisible = !_heroTab[i]->_ptr->_flags._hide;
-		if (isHeroVisible)
-			break;
-	}
 	return (_startupMode == 0) && _mouse->_active &&
-		_commandHandler->idle() && isHeroVisible;
+		_commandHandler->idle() && !(*_soundStat._wait);
 }
 
 Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {


Commit: 59bc45e79fa5d15dda7b777e310ade2f35f87610
    https://github.com/scummvm/scummvm/commit/59bc45e79fa5d15dda7b777e310ade2f35f87610
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-06T17:44:12+02:00

Commit Message:
CGE2: Get rid of _keyAlt.

Changed paths:
    engines/cge2/events.cpp
    engines/cge2/events.h



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 7dd254d..3941492 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -40,7 +40,6 @@ namespace CGE2 {
 /*----------------- KEYBOARD interface -----------------*/
 
 Keyboard::Keyboard(CGE2Engine *vm) : _client(nullptr), _vm(vm) {
-	_keyAlt = false;
 }
 
 Keyboard::~Keyboard() {
@@ -54,11 +53,6 @@ Sprite *Keyboard::setClient(Sprite *spr) {
 bool Keyboard::getKey(Common::Event &event) {
 	Common::KeyCode keycode = event.kbd.keycode;
 
-	if (((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) && (event.type == Common::EVENT_KEYDOWN))
-		_keyAlt = true;
-	else
-		_keyAlt = false;
-
 	switch (keycode) {
 	case Common::KEYCODE_F1:
 		if (event.type == Common::EVENT_KEYUP)
diff --git a/engines/cge2/events.h b/engines/cge2/events.h
index 2522c34..d1aaca2 100644
--- a/engines/cge2/events.h
+++ b/engines/cge2/events.h
@@ -55,7 +55,6 @@ private:
 	CGE2Engine *_vm;
 public:
 	Sprite *_client;
-	bool _keyAlt;
 
 	void newKeyboard(Common::Event &event);
 	Sprite *setClient(Sprite *spr);


Commit: 895f8a5e595f0786a79b229810aba9d0a0e7b1ed
    https://github.com/scummvm/scummvm/commit/895f8a5e595f0786a79b229810aba9d0a0e7b1ed
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-09T13:51:31+02:00

Commit Message:
CGE2: Remove commented out code from text.cpp.

Changed paths:
    engines/cge2/text.cpp



diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 605eed0..1da310c 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -25,11 +25,7 @@
  * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
  */
 
-//#include "cge/general.h"
 #include "cge2/text.h"
-//#include "cge/talk.h"
-//#include "cge/game.h"
-//#include "cge/snail.h"
 #include "common/str.h"
 
 namespace CGE2 {


Commit: 58822b47a73b8d733ceb0eee629bcbd557e4c6dc
    https://github.com/scummvm/scummvm/commit/58822b47a73b8d733ceb0eee629bcbd557e4c6dc
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-09T13:54:20+02:00

Commit Message:
CGE2: Use spaces instead of tabs.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index 424138f..d8ecf55 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -128,7 +128,7 @@ Seq Sprite::_stdSeq8[] =
 SprExt::SprExt(CGE2Engine *vm)
 	: _p0(vm, 0, 0), _p1(vm, 0, 0),
      _b0(nullptr), _b1(nullptr), _shpList(nullptr),
-	 _location(0), _seq(nullptr), _name(nullptr) {
+     _location(0), _seq(nullptr), _name(nullptr) {
 	for (int i = 0; i < kActions; i++)
 		_actions[i] = nullptr;
 }
@@ -136,8 +136,8 @@ SprExt::SprExt(CGE2Engine *vm)
 Sprite::Sprite(CGE2Engine *vm)
 	: _siz(_vm, 0, 0), _seqPtr(kNoSeq), _seqCnt(0), _shpCnt(0),
       _next(nullptr), _prev(nullptr), _time(0),
-	  _ext(nullptr), _ref(-1), _scene(0), _vm(vm),
-	  _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
+      _ext(nullptr), _ref(-1), _scene(0), _vm(vm),
+      _pos2D(_vm, kScrWidth >> 1, 0), _pos3D(kScrWidth >> 1, 0, 0) {
 	memset(_actionCtrl, 0, sizeof(_actionCtrl));
 	memset(_file, 0, sizeof(_file));
 	memset(&_flags, 0, sizeof(_flags));


Commit: 0ea126894005a2523e0b8a3bb48853e532aa518f
    https://github.com/scummvm/scummvm/commit/0ea126894005a2523e0b8a3bb48853e532aa518f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-09T17:22:19+02:00

Commit Message:
CGE2: Fix canSaveGameStateCurrently().

Changed paths:
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 0fb3fb2..309de33 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -148,7 +148,7 @@ void CGE2MetaEngine::removeSaveState(const char *target, int slot) const {
 
 bool CGE2Engine::canSaveGameStateCurrently() {
 	return (_startupMode == 0) && _mouse->_active &&
-		_commandHandler->idle() && !(*_soundStat._wait);
+		_commandHandler->idle() && (_soundStat._wait == nullptr);
 }
 
 Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {


Commit: 01950e1b1cb03281d2f3aa89462e496034ae05ee
    https://github.com/scummvm/scummvm/commit/01950e1b1cb03281d2f3aa89462e496034ae05ee
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T14:48:33+02:00

Commit Message:
CGE2: Remove unused function from vga13h.cpp.

Changed paths:
    engines/cge2/vga13h.cpp



diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp
index d8ecf55..3308831 100644
--- a/engines/cge2/vga13h.cpp
+++ b/engines/cge2/vga13h.cpp
@@ -824,11 +824,6 @@ void Queue::insert(Sprite *spr) {
 		append(spr);
 }
 
-template<typename T>
-inline bool contains(const Common::List<T> &l, const T &v) {
-	return (Common::find(l.begin(), l.end(), v) != l.end());
-}
-
 Sprite *Queue::remove(Sprite *spr) {
 	if (spr == _head)
 		_head = spr->_next;


Commit: e709be446c1a3cac123aa6c6eb45be563deb99f4
    https://github.com/scummvm/scummvm/commit/e709be446c1a3cac123aa6c6eb45be563deb99f4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T14:53:49+02:00

Commit Message:
CGE2: Remove unnecessary #pragma before Sprite::touch().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index f3a76d8..02efdfe 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -842,7 +842,6 @@ void CGE2Engine::switchHero(int sex) {
 		_commandHandler->addCommand(kCmdSeq, -1, 1, face);
 }
 
-#pragma argsused
 void Sprite::touch(uint16 mask, V2D pos, Common::KeyCode keyCode) {
 	if ((mask & kEventAttn) != 0)
 		return;


Commit: 1224d79e533325435c2d655b650bc7faf0c08b4f
    https://github.com/scummvm/scummvm/commit/1224d79e533325435c2d655b650bc7faf0c08b4f
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T14:54:47+02:00

Commit Message:
CGE2: Fix typo in detection.cpp.

Changed paths:
    engines/cge2/detection.cpp



diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index a7b25d1..1f0b67c 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -59,7 +59,7 @@ const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles,
 				continue;
 			
 			desc.gameid = "sfinx";
-			desc.extra = "Sfinx English Alfa v0.1";
+			desc.extra = "Sfinx English Alpha v0.1";
 			desc.language = Common::EN_ANY;
 			desc.platform = Common::kPlatformDOS;
 			desc.flags = ADGF_NO_FLAGS;


Commit: 411e8ac5c8609631ba5e2a78d3603c32fc974e18
    https://github.com/scummvm/scummvm/commit/411e8ac5c8609631ba5e2a78d3603c32fc974e18
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:03:24+02:00

Commit Message:
CGE2: Change return type of readSint16LE().

Changed paths:
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 73b6cda..52a00ac 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -222,7 +222,7 @@ uint32 EncryptedStream::read(byte *dataPtr, uint32 dataSize) {
 	return _readStream->read(dataPtr, dataSize);
 }
 
-signed EncryptedStream::readSint16LE() {
+int16 EncryptedStream::readSint16LE() {
 	return _readStream->readSint16LE();
 }
 
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 0f3755b..67b3754 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -120,7 +120,7 @@ public:
 	int32 pos();
 	int32 size();
 	uint32 read(byte *dataPtr, uint32 dataSize);
-	signed readSint16LE();
+	int16 readSint16LE();
 	uint32 readUint32LE();
 	Common::String readLine();
 	int getLineCount() { return _lineCount; }


Commit: eb13d6ece1fe580a573896127eb390728e7be47a
    https://github.com/scummvm/scummvm/commit/eb13d6ece1fe580a573896127eb390728e7be47a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:13:24+02:00

Commit Message:
CGE2: Add necessary tabs in detection.cpp.

Changed paths:
    engines/cge2/detection.cpp



diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 1f0b67c..4acef7d 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -74,7 +74,7 @@ const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles,
 } // End of namespace CGE2
 
 #if PLUGIN_ENABLED_DYNAMIC(CGE2)
-REGISTER_PLUGIN_DYNAMIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
+	REGISTER_PLUGIN_DYNAMIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
 #else
-REGISTER_PLUGIN_STATIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
+	REGISTER_PLUGIN_STATIC(CGE2, PLUGIN_TYPE_ENGINE, CGE2::CGE2MetaEngine);
 #endif


Commit: 854849f57ae515ee84640f18881ffcd4e3b72846
    https://github.com/scummvm/scummvm/commit/854849f57ae515ee84640f18881ffcd4e3b72846
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:28:43+02:00

Commit Message:
CGE2: Get rid of detection.h, move things to detection.cpp.

Changed paths:
  R engines/cge2/detection.h
    engines/cge2/cge2.h
    engines/cge2/detection.cpp
    engines/cge2/saveload.cpp



diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 8b2a238..4fc19a8 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -114,6 +114,14 @@ struct SavegameHeader;
 
 #define kColorNum           6
 
+struct SavegameHeader {
+	uint8 version;
+	Common::String saveName;
+	Graphics::Surface *thumbnail;
+	int saveYear, saveMonth, saveDay;
+	int saveHour, saveMinutes;
+};
+
 enum ColorBank { kCBRel, kCBStd, kCBSay, kCBInf, kCBMnu, kCBWar };
 
 // our engine debug channels
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index 4acef7d..c032e23 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -25,10 +25,71 @@
  * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
  */
 
-#include "cge2/detection.h"
+#include "cge2/cge2.h"
+#include "engines/advancedDetector.h"
+#include "common/translation.h"
+#include "graphics/surface.h"
 
 namespace CGE2 {
 
+#define GAMEOPTION_COLOR_BLIND_DEFAULT_OFF  GUIO_GAMEOPTIONS1
+
+static const PlainGameDescriptor CGE2Games[] = {
+		{ "sfinx", "Sfinx" },
+		{ 0, 0 }
+};
+
+static const ADGameDescription gameDescriptions[] = {
+		{
+			"sfinx", "Sfinx Freeware",
+			{
+				{ "vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024 },
+				{ "vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844 },
+				AD_LISTEND
+			},
+			Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
+		},
+		AD_TABLE_END_MARKER
+};
+
+static const ADExtraGuiOptionsMap optionsList[] = {
+		{
+			GAMEOPTION_COLOR_BLIND_DEFAULT_OFF,
+			{
+				_s("Color Blind Mode"),
+				_s("Enable Color Blind Mode by default"),
+				"enable_color_blind",
+				false
+			}
+		},
+
+		AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
+class CGE2MetaEngine : public AdvancedMetaEngine {
+public:
+	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games, optionsList) {
+		_singleid = "sfinx";
+	}
+
+	virtual const char *getName() const {
+		return "CGE2";
+	}
+
+	virtual const char *getOriginalCopyright() const {
+		return "Sfinx (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon";
+	}
+
+	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual bool hasFeature(MetaEngineFeature f) const;
+	virtual int getMaximumSaveSlot() const;
+	virtual SaveStateList listSaves(const char *target) const;
+	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+	virtual void removeSaveState(const char *target, int slot) const;
+
+	const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
+};
+
 bool CGE2MetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
 	if (desc)
 		*engine = new CGE2::CGE2Engine(syst, desc);
@@ -71,6 +132,99 @@ const ADGameDescription *CGE2MetaEngine::fallbackDetect(const FileMap &allFiles,
 	return 0;
 }
 
+int CGE2MetaEngine::getMaximumSaveSlot() const {
+	return 99;
+}
+
+SaveStateList CGE2MetaEngine::listSaves(const char *target) const {
+	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+	Common::StringArray filenames;
+	Common::String pattern = target;
+	pattern += ".???";
+
+	filenames = saveFileMan->listSavefiles(pattern);
+	sort(filenames.begin(), filenames.end());   // Sort (hopefully ensuring we are sorted numerically..)
+
+	SaveStateList saveList;
+	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
+		// Obtain the last 3 digits of the filename, since they correspond to the save slot
+		int slotNum = atoi(filename->c_str() + filename->size() - 3);
+
+		if (slotNum >= 0 && slotNum <= 99) {
+
+			Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
+			if (file) {
+				CGE2::SavegameHeader header;
+
+				// Check to see if it's a ScummVM savegame or not
+				char buffer[kSavegameStrSize + 1];
+				file->read(buffer, kSavegameStrSize + 1);
+
+				if (!strncmp(buffer, kSavegameStr, kSavegameStrSize + 1)) {
+					// Valid savegame
+					if (CGE2::CGE2Engine::readSavegameHeader(file, header)) {
+						saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
+						if (header.thumbnail) {
+							header.thumbnail->free();
+							delete header.thumbnail;
+						}
+					}
+				} else {
+					// Must be an original format savegame
+					saveList.push_back(SaveStateDescriptor(slotNum, "Unknown"));
+				}
+
+				delete file;
+			}
+		}
+	}
+
+	return saveList;
+}
+
+SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s.%03d", target, slot);
+	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
+
+	if (f) {
+		CGE2::SavegameHeader header;
+
+		// Check to see if it's a ScummVM savegame or not
+		char buffer[kSavegameStrSize + 1];
+		f->read(buffer, kSavegameStrSize + 1);
+
+		bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
+			CGE2::CGE2Engine::readSavegameHeader(f, header);
+		delete f;
+
+		if (!hasHeader) {
+			// Original savegame perhaps?
+			SaveStateDescriptor desc(slot, "Unknown");
+			return desc;
+		} else {
+			// Create the return descriptor
+			SaveStateDescriptor desc(slot, header.saveName);
+			desc.setThumbnail(header.thumbnail);
+			desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
+			desc.setSaveTime(header.saveHour, header.saveMinutes);
+
+			// Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
+			// we prevent it from being deleted or overwritten by accident.
+			desc.setDeletableFlag(slot != 0);
+			desc.setWriteProtectedFlag(slot == 0);
+
+			return desc;
+		}
+	}
+
+	return SaveStateDescriptor();
+}
+
+void CGE2MetaEngine::removeSaveState(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s.%03d", target, slot);
+	g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
 } // End of namespace CGE2
 
 #if PLUGIN_ENABLED_DYNAMIC(CGE2)
diff --git a/engines/cge2/detection.h b/engines/cge2/detection.h
deleted file mode 100644
index 51e2988..0000000
--- a/engines/cge2/detection.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* 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.
- *
- */
-
-/*
- * This code is based on original Sfinx source code
- * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
- */
-
-#ifndef CGE2_DETECTION_H
-#define CGE2_DETECTION_H
-
-#include "cge2/cge2.h"
-#include "engines/advancedDetector.h"
-#include "common/translation.h"
-
-namespace CGE2 {
-
-#define GAMEOPTION_COLOR_BLIND_DEFAULT_OFF  GUIO_GAMEOPTIONS1
-
-static const PlainGameDescriptor CGE2Games[] = {
-	{ "sfinx", "Sfinx" },
-	{ 0, 0 }
-};
-
-static const ADGameDescription gameDescriptions[] = {
-	{
-		"sfinx", "Sfinx Freeware",
-		{
-			{ "vol.cat", 0, "21197b287d397c53261b6616bf0dd880", 129024 },
-			{ "vol.dat", 0, "de14291869a8eb7c2732ab783c7542ef", 34180844 },
-			AD_LISTEND
-		},
-		Common::PL_POL, Common::kPlatformDOS, ADGF_NO_FLAGS, GUIO1(GAMEOPTION_COLOR_BLIND_DEFAULT_OFF)
-	},
-	AD_TABLE_END_MARKER
-};
-
-static const ADExtraGuiOptionsMap optionsList[] = {
-		{
-			GAMEOPTION_COLOR_BLIND_DEFAULT_OFF,
-			{
-				_s("Color Blind Mode"),
-				_s("Enable Color Blind Mode by default"),
-				"enable_color_blind",
-				false
-			}
-		},
-
-		AD_EXTRA_GUI_OPTIONS_TERMINATOR
-};
-
-class CGE2MetaEngine : public AdvancedMetaEngine {
-public:
-	CGE2MetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(ADGameDescription), CGE2Games, optionsList) {
-		_singleid = "sfinx";
-	}
-
-	virtual const char *getName() const {
-		return "CGE2";
-	}
-
-	virtual const char *getOriginalCopyright() const {
-		return "Sfinx (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon";
-	}
-
-	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-	virtual bool hasFeature(MetaEngineFeature f) const;
-	virtual int getMaximumSaveSlot() const;
-	virtual SaveStateList listSaves(const char *target) const;
-	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
-	virtual void removeSaveState(const char *target, int slot) const;
-
-	const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
-};
-
-} // End of namespace CGE2
-
-#endif // CGE2_DETECTION_H
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index 309de33..c9cedff 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -25,7 +25,6 @@
  * Copyright (c) 1994-1997 Janus B. Wisniewski and L.K. Avalon
  */
 
-#include "cge2/detection.h"
 #include "common/config-manager.h"
 #include "common/savefile.h"
 #include "common/system.h"
@@ -45,107 +44,6 @@ namespace CGE2 {
 #define kSavegameCheckSum (1997 + _now + _sex + kWorldHeight)
 #define kBadSVG           99
 
-struct SavegameHeader {
-	uint8 version;
-	Common::String saveName;
-	Graphics::Surface *thumbnail;
-	int saveYear, saveMonth, saveDay;
-	int saveHour, saveMinutes;
-};
-
-int CGE2MetaEngine::getMaximumSaveSlot() const {
-	return 99;
-}
-
-SaveStateList CGE2MetaEngine::listSaves(const char *target) const {
-	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
-	Common::StringArray filenames;
-	Common::String pattern = target;
-	pattern += ".???";
-
-	filenames = saveFileMan->listSavefiles(pattern);
-	sort(filenames.begin(), filenames.end());   // Sort (hopefully ensuring we are sorted numerically..)
-
-	SaveStateList saveList;
-	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
-		// Obtain the last 3 digits of the filename, since they correspond to the save slot
-		int slotNum = atoi(filename->c_str() + filename->size() - 3);
-
-		if (slotNum >= 0 && slotNum <= 99) {
-
-			Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
-			if (file) {
-				CGE2::SavegameHeader header;
-
-				// Check to see if it's a ScummVM savegame or not
-				char buffer[kSavegameStrSize + 1];
-				file->read(buffer, kSavegameStrSize + 1);
-
-				if (!strncmp(buffer, kSavegameStr, kSavegameStrSize + 1)) {
-					// Valid savegame
-					if (CGE2::CGE2Engine::readSavegameHeader(file, header)) {
-						saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
-						if (header.thumbnail) {
-							header.thumbnail->free();
-							delete header.thumbnail;
-						}
-					}
-				} else {
-					// Must be an original format savegame
-					saveList.push_back(SaveStateDescriptor(slotNum, "Unknown"));
-				}
-
-				delete file;
-			}
-		}
-	}
-
-	return saveList;
-}
-
-SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int slot) const {
-	Common::String fileName = Common::String::format("%s.%03d", target, slot);
-	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
-
-	if (f) {
-		CGE2::SavegameHeader header;
-
-		// Check to see if it's a ScummVM savegame or not
-		char buffer[kSavegameStrSize + 1];
-		f->read(buffer, kSavegameStrSize + 1);
-
-		bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
-			CGE2::CGE2Engine::readSavegameHeader(f, header);
-		delete f;
-
-		if (!hasHeader) {
-			// Original savegame perhaps?
-			SaveStateDescriptor desc(slot, "Unknown");
-			return desc;
-		} else {
-			// Create the return descriptor
-			SaveStateDescriptor desc(slot, header.saveName);
-			desc.setThumbnail(header.thumbnail);
-			desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
-			desc.setSaveTime(header.saveHour, header.saveMinutes);
-
-			// Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
-			// we prevent it from being deleted or overwritten by accident.
-			desc.setDeletableFlag(slot != 0);
-			desc.setWriteProtectedFlag(slot == 0);
-
-			return desc;
-		}
-	}
-
-	return SaveStateDescriptor();
-}
-
-void CGE2MetaEngine::removeSaveState(const char *target, int slot) const {
-	Common::String fileName = Common::String::format("%s.%03d", target, slot);
-	g_system->getSavefileManager()->removeSavefile(fileName);
-}
-
 bool CGE2Engine::canSaveGameStateCurrently() {
 	return (_startupMode == 0) && _mouse->_active &&
 		_commandHandler->idle() && (_soundStat._wait == nullptr);


Commit: 85101525454bf613aa35d72a356c506d2f7600c4
    https://github.com/scummvm/scummvm/commit/85101525454bf613aa35d72a356c506d2f7600c4
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:31:34+02:00

Commit Message:
CGE2: Rename XCrpyt() to xCrypt().

Changed paths:
    engines/cge2/fileio.cpp
    engines/cge2/fileio.h



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index 52a00ac..ea21864 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -90,7 +90,7 @@ ResourceManager::~ResourceManager() {
 		delete _buff[i]._page;
 }
 
-void ResourceManager::XCrypt(byte *buf, uint16 length) {
+void ResourceManager::xCrypt(byte *buf, uint16 length) {
 	byte *b = buf;
 
 	for (uint16 i = 0; i < length; i++)
@@ -108,7 +108,7 @@ uint16 ResourceManager::read(byte *buf, uint16 length) {
 	uint16 bytesRead = _datFile->read(buf, length);
 	if (!bytesRead)
 		error("Read %s - %d bytes", _datFile->getName(), length);
-	XCrypt(buf, length);
+	xCrypt(buf, length);
 	return bytesRead;
 }
 
@@ -180,7 +180,7 @@ uint16 ResourceManager::catRead(byte *buf, uint16 length) {
 	uint16 bytesRead = _catFile->read(buf, length);
 	if (!bytesRead)
 		error("Read %s - %d bytes", _catFile->getName(), length);
-	XCrypt(buf, length);
+	xCrypt(buf, length);
 	return bytesRead;
 }
 
diff --git a/engines/cge2/fileio.h b/engines/cge2/fileio.h
index 67b3754..e236c73 100644
--- a/engines/cge2/fileio.h
+++ b/engines/cge2/fileio.h
@@ -94,7 +94,7 @@ private:
 	uint16 catRead(byte *buf, uint16 length);
 	Common::File *_catFile;
 	Common::File *_datFile;
-	void XCrypt(byte *buf, uint16 length);
+	void xCrypt(byte *buf, uint16 length);
 public:
 	ResourceManager();
 	~ResourceManager();


Commit: c3a5a9177b162beb70f28aa1f9408559f9482cbb
    https://github.com/scummvm/scummvm/commit/c3a5a9177b162beb70f28aa1f9408559f9482cbb
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:38:28+02:00

Commit Message:
CGE2: Fix comment in runGame().

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 02efdfe..c8c3a1e 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -632,7 +632,8 @@ void CGE2Engine::runGame() {
 	while (!_endGame && !_quitFlag)
 		mainLoop();
 
-	// If finishing game due to closing ScummVM window, explicitly save the game
+	// If leaving the game (close window, return to launcher, etc.
+	// - except finishing the game), explicitly save it's state:
 	if (!_endGame && canSaveGameStateCurrently())
 		qGame();
 


Commit: f8e60e467fdcff8b36eb0bfad2a4c53459462fe6
    https://github.com/scummvm/scummvm/commit/f8e60e467fdcff8b36eb0bfad2a4c53459462fe6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:42:55+02:00

Commit Message:
CGE2: Make movie() safer.

Changed paths:
    engines/cge2/cge2_main.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index c8c3a1e..7900eef 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -387,7 +387,7 @@ void CGE2Engine::movie(const char *ext) {
 		return;
 
 	char fn[12];
-	sprintf(fn, "CGE.%s", (*ext == '.') ? ext + 1 : ext);
+	sprintf(fn, "CGE%s", ext);
 
 	if (_resman->exist(fn)) {
 		int now = _now;


Commit: 0d47893d5143dac35686890360591558eef7a72a
    https://github.com/scummvm/scummvm/commit/0d47893d5143dac35686890360591558eef7a72a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:44:55+02:00

Commit Message:
CGE2: Make matrixes static constants in makeSpeechBubbleTail().

Changed paths:
    engines/cge2/bitmap.cpp



diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp
index 6d38f33..01e97eb 100644
--- a/engines/cge2/bitmap.cpp
+++ b/engines/cge2/bitmap.cpp
@@ -396,7 +396,7 @@ void Bitmap::xLatPos(V2D& p) {
 #define kDesignSize   240
 
 uint8 *Bitmap::makeSpeechBubbleTail(int which, uint8 colorSet[][4]) {
-	uint8 kSLDesign[kDesignSize] = {
+	static const uint8 kSLDesign[kDesignSize] = {
 		G G G G G G G G G _ _ _ _ _ _
 		L G G G G G G G G D _ _ _ _ _
 		_ L G G G G G G G D _ _ _ _ _
@@ -415,7 +415,7 @@ uint8 *Bitmap::makeSpeechBubbleTail(int which, uint8 colorSet[][4]) {
 		_ _ _ _ _ _ _ _ _ _ _ _ _ _ D
 	};
 
-	uint8 kSRDesign[kDesignSize] = {
+	static const uint8 kSRDesign[kDesignSize] = {
 		_ _ _ _ _ _ G G G G G G G G G
 		_ _ _ _ _ L G G G G G G G G D
 		_ _ _ _ _ L G G G G G G G D _


Commit: 25ebfe461f576d26e3c01bcdfa0151dc9d1fc7fa
    https://github.com/scummvm/scummvm/commit/25ebfe461f576d26e3c01bcdfa0151dc9d1fc7fa
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:54:38+02:00

Commit Message:
CGE2: Remove unnecessary comments from vga13h.h.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 52efd39..a31da57 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -51,8 +51,7 @@ namespace CGE2 {
 #define kPalCount        256
 #define kPalSize         (kPalCount * 3)
 
-// From FXP.H
-class FXP { // fixed point
+class FXP {
 	int32 v;
 public:
 	FXP(void) : v(0) {}
@@ -78,7 +77,6 @@ public:
 	void sync(Common::Serializer &s);
 };
 
-// From CGETYPE.H:
 class V3D {
 public:
 	FXP _x, _y, _z;


Commit: 7dfd108f68f5e7f99df3b290c48a9d485cb9c3b7
    https://github.com/scummvm/scummvm/commit/7dfd108f68f5e7f99df3b290c48a9d485cb9c3b7
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T15:56:20+02:00

Commit Message:
CGE2: Remove unused functions from V2D.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index a31da57..cb82364 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -127,8 +127,6 @@ public:
 		FXP posy = m * y;
 		return V2D(_vm, posx.trunc(), posy.trunc());
 	}
-	static double trunc(double d) { return (d > 0) ? floor(d) : ceil(d); }
-	static double round(double number) { return number < 0.0 ? ceil(number) : floor(number); }
 };
 
 struct Seq {


Commit: b3fed6c36904287713ca82c08606b882ceaeff68
    https://github.com/scummvm/scummvm/commit/b3fed6c36904287713ca82c08606b882ceaeff68
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T16:03:38+02:00

Commit Message:
CGE2: Return value instead of reference in FXP's operator=.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index cb82364..4d2d637 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -56,7 +56,7 @@ class FXP {
 public:
 	FXP(void) : v(0) {}
 	FXP (int i0, int f0 = 0) : v((i0 * 256) + ((i0 < 0) ? -f0 : f0)) {}
-	FXP& operator=(const int& x) { v = x << 8; return *this; }
+	FXP operator=(const int& x) { v = x << 8; return *this; }
 	FXP operator+(const FXP& x) const { FXP y; y.v = v + x.v; return y; }
 	FXP operator-(const FXP& x) const { FXP y; y.v = v - x.v; return y; }
 	FXP operator*(const FXP& x) const;


Commit: 5e375d0796b4da822ceb8e3d4294d9189101241a
    https://github.com/scummvm/scummvm/commit/5e375d0796b4da822ceb8e3d4294d9189101241a
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T16:06:10+02:00

Commit Message:
CGE2: Fix formatting of operators' return values in vga13h.h.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 4d2d637..652727c 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -63,10 +63,10 @@ public:
 	FXP operator/(const FXP& x) const;
 
 	//int& operator = (int& a, const FXP& b) { return a = b.i; }
-	friend int& operator+=(int& a, const FXP& b) { return a += b.trunc(); }
-	friend int& operator-=(int& a, const FXP& b) { return a -= b.trunc(); }
-	friend FXP& operator+=(FXP& a, const int& b) { a.v += b << 8; return a; }
-	friend FXP& operator-=(FXP& a, const int& b) { a.v -= b << 8; return a; }
+	friend int &operator+=(int& a, const FXP& b) { return a += b.trunc(); }
+	friend int &operator-=(int& a, const FXP& b) { return a -= b.trunc(); }
+	friend FXP &operator+=(FXP& a, const int& b) { a.v += b << 8; return a; }
+	friend FXP &operator-=(FXP& a, const int& b) { a.v -= b << 8; return a; }
 	friend bool operator==(const FXP &a, const FXP &b) { return a.v == b.v; }
 	friend bool operator!=(const FXP &a, const FXP &b) { return a.v != b.v; }
 	friend bool operator<(const FXP &a, const FXP &b) { return a.v < b.v; }
@@ -97,7 +97,7 @@ public:
 class V2D : public Common::Point {
 	CGE2Engine *_vm;
 public:
-	V2D& operator=(const V3D &p3) {
+	V2D &operator=(const V3D &p3) {
 		FXP m = _vm->_eye->_z / (p3._z - _vm->_eye->_z);
 		FXP posx = _vm->_eye->_x + (_vm->_eye->_x - p3._x) * m;
 		x = posx.round();


Commit: 9c5bdc6dde233011a22dd85f42d37f01f29809b0
    https://github.com/scummvm/scummvm/commit/9c5bdc6dde233011a22dd85f42d37f01f29809b0
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T16:07:29+02:00

Commit Message:
CGE2: Fix formatting in bitmap.h.

Changed paths:
    engines/cge2/bitmap.h



diff --git a/engines/cge2/bitmap.h b/engines/cge2/bitmap.h
index 30b8f48..613222f 100644
--- a/engines/cge2/bitmap.h
+++ b/engines/cge2/bitmap.h
@@ -81,7 +81,7 @@ public:
 	void hide(V2D pos);
 	void show(V2D pos);
 	bool solidAt(V2D pos);
-	void xLatPos(V2D& p);
+	void xLatPos(V2D &p);
 
 	static uint8 *makeSpeechBubbleTail(int des, uint8 colorSet[][4]);
 };


Commit: 235e3d396e0aa9d8a0ad1427d189a5e9eb243344
    https://github.com/scummvm/scummvm/commit/235e3d396e0aa9d8a0ad1427d189a5e9eb243344
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T16:09:04+02:00

Commit Message:
CGE2: Fix formatting in events.cpp.

Changed paths:
    engines/cge2/events.cpp



diff --git a/engines/cge2/events.cpp b/engines/cge2/events.cpp
index 3941492..ed1ec66 100644
--- a/engines/cge2/events.cpp
+++ b/engines/cge2/events.cpp
@@ -206,7 +206,7 @@ void Mouse::newMouse(Common::Event &event) {
 
 /*----------------- EventManager interface -----------------*/
 
-EventManager::EventManager(CGE2Engine *vm) : _vm(vm){
+EventManager::EventManager(CGE2Engine *vm) : _vm(vm) {
 	_eventQueueHead = 0;
 	_eventQueueTail = 0;
 	memset(&_eventQueue, 0, kEventMax * sizeof(CGE2Event));


Commit: 3e3430ed5de5155fadd6d23ea719f413bcc4e6e6
    https://github.com/scummvm/scummvm/commit/3e3430ed5de5155fadd6d23ea719f413bcc4e6e6
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T16:10:14+02:00

Commit Message:
CGE2: Fix EncryptedStream::err().

Changed paths:
    engines/cge2/fileio.cpp



diff --git a/engines/cge2/fileio.cpp b/engines/cge2/fileio.cpp
index ea21864..6f80097 100644
--- a/engines/cge2/fileio.cpp
+++ b/engines/cge2/fileio.cpp
@@ -231,7 +231,7 @@ uint32 EncryptedStream::readUint32LE() {
 }
 
 bool EncryptedStream::err() {
-	return (_error & _readStream->err());
+	return (_error || _readStream->err());
 }
 
 bool EncryptedStream::eos() {


Commit: 02f3418d6f0382791c44dec8a5e232caa12109e9
    https://github.com/scummvm/scummvm/commit/02f3418d6f0382791c44dec8a5e232caa12109e9
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T20:32:56+02:00

Commit Message:
CGE2: Fix some more formatting in vga13h.h.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 652727c..749374f 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -56,17 +56,17 @@ class FXP {
 public:
 	FXP(void) : v(0) {}
 	FXP (int i0, int f0 = 0) : v((i0 * 256) + ((i0 < 0) ? -f0 : f0)) {}
-	FXP operator=(const int& x) { v = x << 8; return *this; }
-	FXP operator+(const FXP& x) const { FXP y; y.v = v + x.v; return y; }
-	FXP operator-(const FXP& x) const { FXP y; y.v = v - x.v; return y; }
-	FXP operator*(const FXP& x) const;
-	FXP operator/(const FXP& x) const;
+	FXP operator=(const int &x) { v = x << 8; return *this; }
+	FXP operator+(const FXP &x) const { FXP y; y.v = v + x.v; return y; }
+	FXP operator-(const FXP &x) const { FXP y; y.v = v - x.v; return y; }
+	FXP operator*(const FXP &x) const;
+	FXP operator/(const FXP &x) const;
 
 	//int& operator = (int& a, const FXP& b) { return a = b.i; }
-	friend int &operator+=(int& a, const FXP& b) { return a += b.trunc(); }
-	friend int &operator-=(int& a, const FXP& b) { return a -= b.trunc(); }
-	friend FXP &operator+=(FXP& a, const int& b) { a.v += b << 8; return a; }
-	friend FXP &operator-=(FXP& a, const int& b) { a.v -= b << 8; return a; }
+	friend int &operator+=(int &a, const FXP &b) { return a += b.trunc(); }
+	friend int &operator-=(int &a, const FXP &b) { return a -= b.trunc(); }
+	friend FXP &operator+=(FXP &a, const int &b) { a.v += b << 8; return a; }
+	friend FXP &operator-=(FXP &a, const int &b) { a.v -= b << 8; return a; }
 	friend bool operator==(const FXP &a, const FXP &b) { return a.v == b.v; }
 	friend bool operator!=(const FXP &a, const FXP &b) { return a.v != b.v; }
 	friend bool operator<(const FXP &a, const FXP &b) { return a.v < b.v; }
@@ -108,9 +108,9 @@ public:
 	V2D(CGE2Engine *vm) : _vm(vm) { }
 	V2D(CGE2Engine *vm, const V3D &p3) : _vm(vm) { *this = p3; }
 	V2D(CGE2Engine *vm, int posx, int posy) : _vm(vm), Common::Point(posx, posy) { }
-	bool operator<(const V2D &p) const { return (x <  p.x) && (y <  p.y); }
+	bool operator<(const V2D &p) const { return (x < p.x) && (y <  p.y); }
 	bool operator<=(const V2D &p) const { return (x <= p.x) && (y <= p.y); }
-	bool operator>(const V2D &p) const { return (x >  p.x) && (y >  p.y); }
+	bool operator>(const V2D &p) const { return (x > p.x) && (y >  p.y); }
 	bool operator>=(const V2D &p) const { return (x >= p.x) && (y >= p.y); }
 	V2D operator+(const V2D &p) const { return V2D(_vm, x + p.x, y + p.y); }
 	V2D operator-(const V2D &p) const { return V2D(_vm, x - p.x, y - p.y); }


Commit: e488da5757a44fed4fda5c15fb8ab4f37e0ee350
    https://github.com/scummvm/scummvm/commit/e488da5757a44fed4fda5c15fb8ab4f37e0ee350
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T20:34:18+02:00

Commit Message:
CGE2: Remove unnecessary commented out code.

Changed paths:
    engines/cge2/vga13h.h



diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h
index 749374f..346d140 100644
--- a/engines/cge2/vga13h.h
+++ b/engines/cge2/vga13h.h
@@ -62,7 +62,6 @@ public:
 	FXP operator*(const FXP &x) const;
 	FXP operator/(const FXP &x) const;
 
-	//int& operator = (int& a, const FXP& b) { return a = b.i; }
 	friend int &operator+=(int &a, const FXP &b) { return a += b.trunc(); }
 	friend int &operator-=(int &a, const FXP &b) { return a -= b.trunc(); }
 	friend FXP &operator+=(FXP &a, const int &b) { a.v += b << 8; return a; }


Commit: ae037b23153d60b19c95960c0c6e1e1ee61a906b
    https://github.com/scummvm/scummvm/commit/ae037b23153d60b19c95960c0c6e1e1ee61a906b
Author: uruk (koppirnyo at gmail.com)
Date: 2014-08-11T20:43:08+02:00

Commit Message:
CGE2: Use snprintf() instead of sprintf().

Changed paths:
    engines/cge2/cge2_main.cpp
    engines/cge2/text.cpp



diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp
index 7900eef..7c4a111 100644
--- a/engines/cge2/cge2_main.cpp
+++ b/engines/cge2/cge2_main.cpp
@@ -387,7 +387,7 @@ void CGE2Engine::movie(const char *ext) {
 		return;
 
 	char fn[12];
-	sprintf(fn, "CGE%s", ext);
+	snprintf(fn, 12, "CGE%s", ext);
 
 	if (_resman->exist(fn)) {
 		int now = _now;
diff --git a/engines/cge2/text.cpp b/engines/cge2/text.cpp
index 1da310c..d51c048 100644
--- a/engines/cge2/text.cpp
+++ b/engines/cge2/text.cpp
@@ -190,7 +190,7 @@ void Text::sayTime(Sprite *spr) {
 	_vm->_system->getTimeAndDate(curTime);
 
 	char t[6];
-	sprintf(t, "%d:%02d", curTime.tm_hour, curTime.tm_min);
+	snprintf(t, 6, "%d:%02d", curTime.tm_hour, curTime.tm_min);
 	say(t, spr);
 }
 


Commit: c6033e046751c1699c600252d756218220ff484a
    https://github.com/scummvm/scummvm/commit/c6033e046751c1699c600252d756218220ff484a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-08-12T08:09:28+02:00

Commit Message:
Merge pull request #488 from urukgit/cge2

CGE2: Add Sfinx engine

Changed paths:
  A engines/cge2/bitmap.cpp
  A engines/cge2/bitmap.h
  A engines/cge2/cge2.cpp
  A engines/cge2/cge2.h
  A engines/cge2/cge2_main.cpp
  A engines/cge2/cge2_main.h
  A engines/cge2/configure.engine
  A engines/cge2/console.cpp
  A engines/cge2/console.h
  A engines/cge2/detection.cpp
  A engines/cge2/events.cpp
  A engines/cge2/events.h
  A engines/cge2/fileio.cpp
  A engines/cge2/fileio.h
  A engines/cge2/general.h
  A engines/cge2/hero.cpp
  A engines/cge2/hero.h
  A engines/cge2/inventory.cpp
  A engines/cge2/map.cpp
  A engines/cge2/map.h
  A engines/cge2/module.mk
  A engines/cge2/saveload.cpp
  A engines/cge2/snail.cpp
  A engines/cge2/snail.h
  A engines/cge2/sound.cpp
  A engines/cge2/sound.h
  A engines/cge2/spare.cpp
  A engines/cge2/spare.h
  A engines/cge2/talk.cpp
  A engines/cge2/talk.h
  A engines/cge2/text.cpp
  A engines/cge2/text.h
  A engines/cge2/toolbar.cpp
  A engines/cge2/vga13h.cpp
  A engines/cge2/vga13h.h
  A engines/cge2/vmenu.cpp
  A engines/cge2/vmenu.h
    engines/cge/cge.h
    engines/cge/detection.cpp









More information about the Scummvm-git-logs mailing list