From 5a5fe344a0f26f164b4908109bbf7cfa39e6c47f Mon Sep 17 00:00:00 2001 From: uruk Date: Tue, 10 Jun 2014 17:27:59 +0200 Subject: CGE2: Implement display of speech bubbles. The sound code connected to them is still gappy. --- engines/cge2/bitmap.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++- engines/cge2/bitmap.h | 9 ++++++- engines/cge2/cge2.cpp | 2 ++ engines/cge2/cge2.h | 3 +++ engines/cge2/general.h | 2 -- engines/cge2/snail.cpp | 21 ++++++++++++++-- engines/cge2/text.cpp | 45 ++++++++++++++++++++++++++++++++- engines/cge2/vga13h.cpp | 10 +++++++- 8 files changed, 150 insertions(+), 8 deletions(-) diff --git a/engines/cge2/bitmap.cpp b/engines/cge2/bitmap.cpp index ff7c3e1998..7a7a88430c 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 bcc51d874f..8bff8fe99c 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 b32ca76489..565615c9ed 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 ebee2edbd7..a3d6f99a22 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 0239402ea3..7213c2e24d 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 6957f8f50e..aa0988f293 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 ac222f9030..83088eab25 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 486db29061..61b367b7a5 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) { -- cgit v1.2.3