diff options
author | Peter Kohaut | 2018-01-28 20:59:12 +0100 |
---|---|---|
committer | Peter Kohaut | 2018-01-29 18:32:09 +0100 |
commit | 0c930b06ed7030686c7774f18126b3d37a678d60 (patch) | |
tree | 04322a848f17c3d8fc4ced7e89e6ce6dbf73dcb3 /engines/bladerunner/ui/kia_section_crimes.cpp | |
parent | fa28602abffd47988dd7d797e4c48d9e3faf47ae (diff) | |
download | scummvm-rg350-0c930b06ed7030686c7774f18126b3d37a678d60.tar.gz scummvm-rg350-0c930b06ed7030686c7774f18126b3d37a678d60.tar.bz2 scummvm-rg350-0c930b06ed7030686c7774f18126b3d37a678d60.zip |
BLADERUNNER: Added KIA interfaces
Crimes interface done
Suspects interface done
Added some game constants
Fixed font rendering for other languages
Fixed anoying clang warning
Diffstat (limited to 'engines/bladerunner/ui/kia_section_crimes.cpp')
-rw-r--r-- | engines/bladerunner/ui/kia_section_crimes.cpp | 449 |
1 files changed, 446 insertions, 3 deletions
diff --git a/engines/bladerunner/ui/kia_section_crimes.cpp b/engines/bladerunner/ui/kia_section_crimes.cpp index 4cfaaedbad..b0b3d7c234 100644 --- a/engines/bladerunner/ui/kia_section_crimes.cpp +++ b/engines/bladerunner/ui/kia_section_crimes.cpp @@ -22,16 +22,459 @@ #include "bladerunner/ui/kia_section_crimes.h" +#include "bladerunner/actor_clues.h" +#include "bladerunner/audio_player.h" #include "bladerunner/bladerunner.h" +#include "bladerunner/crimes_database.h" +#include "bladerunner/font.h" +#include "bladerunner/game_constants.h" +#include "bladerunner/game_flags.h" +#include "bladerunner/game_info.h" +#include "bladerunner/shape.h" +#include "bladerunner/script/kia.h" +#include "bladerunner/suspects_database.h" +#include "bladerunner/text_resource.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_log.h" +#include "bladerunner/ui/kia_section_suspects.h" +#include "bladerunner/ui/kia_shapes.h" +#include "bladerunner/ui/ui_container.h" +#include "bladerunner/ui/ui_image_picker.h" +#include "bladerunner/ui/ui_scroll_box.h" + + +#include "graphics/surface.h" namespace BladeRunner { -KIASectionCrimes::KIASectionCrimes(BladeRunnerEngine *vm) - : KIASectionBase(vm) - , _shape(vm) { +KIASectionCrimes::KIASectionCrimes(BladeRunnerEngine *vm, ActorClues *clues) : KIASectionBase(vm) { + _uiContainer = new UIContainer(_vm); + _isOpen = false; + _clues = clues; + + _mouseX = 0; + _mouseY = 0; + + _buttons = new UIImagePicker(_vm, 5); + + _cluesScrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, 50, 1, false, Common::Rect(312, 172, 500, 376), Common::Rect(506, 160, 506, 394)); + _uiContainer->add(_cluesScrollBox); + + _acquiredClueCount = 0; + + _crimeSelected = -1; + _crimesFoundCount = 0; + _crimesFound.resize(_vm->_gameInfo->getCrimeCount()); + + _suspectSelected = -1; + _suspectPhotoShapeId = -1; + _suspectPhotoShape = nullptr; + _suspectsFoundCount = 0; + _suspectsFound.resize(_vm->_gameInfo->getSuspectCount()); + _suspectsWithIdentity.resize(_vm->_gameInfo->getSuspectCount()); } KIASectionCrimes::~KIASectionCrimes() { + delete _suspectPhotoShape; + + _uiContainer->clear(); + + delete _cluesScrollBox; + delete _buttons; + delete _uiContainer; +} + +void KIASectionCrimes::open() { + _scheduledSwitch = false; + + _buttons->resetImages(); + _buttons->defineImage(0, Common::Rect(136, 326, 185, 342), nullptr, _vm->_kia->_shapes->get(32), _vm->_kia->_shapes->get(36), _vm->_textKIA->getText(32)); + _buttons->defineImage(1, Common::Rect(218, 326, 269, 342), nullptr, _vm->_kia->_shapes->get(33), _vm->_kia->_shapes->get(37), _vm->_textKIA->getText(33)); + _buttons->defineImage(2, Common::Rect(354, 128, 404, 144), nullptr, _vm->_kia->_shapes->get(30), _vm->_kia->_shapes->get(34), _vm->_textKIA->getText(34)); + _buttons->defineImage(3, Common::Rect(425, 128, 474, 144), nullptr, _vm->_kia->_shapes->get(31), _vm->_kia->_shapes->get(35), _vm->_textKIA->getText(35)); + _buttons->defineImage(4, Common::Rect(142, 150, 260, 297), nullptr, nullptr, nullptr, _vm->_textKIA->getText(36)); + _buttons->activate(nullptr, nullptr, nullptr, mouseUpCallback, this); + + _cluesScrollBox->show(); + + populateAcquiredClues(); + populateCrimes(); + populateSuspects(); + populateVisibleClues(); + updateSuspectPhoto(); + + _isOpen = true; +} + +void KIASectionCrimes::close() { + if (!_isOpen) { + return; + } + _isOpen = false; + _buttons->deactivate(); + _cluesScrollBox->hide(); + if (_suspectPhotoShapeId != -1) { + delete _suspectPhotoShape; + _suspectPhotoShape = nullptr; + _suspectPhotoShapeId = -1; + } +} + +void KIASectionCrimes::draw(Graphics::Surface &surface) { + const char *text = nullptr; + if (_suspectPhotoShapeId != -1) { + _suspectPhotoShape->draw(surface, 201 - _suspectPhotoShape->getWidth() / 2, 223 - _suspectPhotoShape->getHeight() / 2); + } + if (_suspectPhotoShapeId == 14 || _suspectPhotoShapeId == 13) { + text = _vm->_textKIA->getText(49); + _vm->_mainFont->drawColor(text, surface, 201 - _vm->_mainFont->getTextWidth(text) / 2, 218, 0x7FFF); + } + + surface.fillRect(Common::Rect(120, 134, 250, 145), 0); + surface.hLine(120, 133, 250, 0x18A5); + surface.hLine(120, 146, 250, 0x2D4C); + surface.vLine(119, 134, 145, 0x18A5); + surface.vLine(251, 134, 145, 0x2D4C); + surface.hLine(251, 146, 251, 0x2509); + + if (_crimeSelected == -1) { + text = _vm->_textKIA->getText(49); + } else { + text = _vm->_textCrimes->getText(_crimeSelected); + } + + _vm->_mainFont->drawColor(text, surface, 185 - _vm->_mainFont->getTextWidth(text) / 2, 136, 0x46BF); + + surface.fillRect(Common::Rect(136, 304, 266, 315), 0); + surface.hLine(136, 303, 266, 0x18A5); + surface.hLine(136, 316, 266, 0x2D4C); + surface.vLine(135, 304, 315, 0x18A5); + surface.vLine(267, 304, 315, 0x2D4C); + surface.hLine(267, 316, 267, 0x2509); + + char generatedText[64]; + if (_suspectSelected == -1) { + text = _vm->_textKIA->getText(22); + } else { + const char *suspectName = _vm->_suspectsDatabase->get(_suspectSelected)->getName(); + if (_suspectsWithIdentity[_suspectSelected]) { + text = suspectName; + } else if (_vm->_suspectsDatabase->get(_suspectSelected)->getSex()) { + sprintf(generatedText, "%s %s", _vm->_textKIA->getText(20), KIASectionSuspects::scrambleSuspectsName(suspectName)); + text = generatedText; + } else { + sprintf(generatedText, "%s %s", _vm->_textKIA->getText(21), KIASectionSuspects::scrambleSuspectsName(suspectName)); + text = generatedText; + } + } + _vm->_mainFont->drawColor(text, surface, 201 - _vm->_mainFont->getTextWidth(text) / 2, 306, 0x46BF); + + _uiContainer->draw(surface); + _buttons->draw(surface); + _buttons->drawTooltip(surface, _mouseX, _mouseY); +} + +void KIASectionCrimes::handleMouseMove(int mouseX, int mouseY) { + _mouseX = mouseX; + _mouseY = mouseY; + _buttons->handleMouseAction(mouseX, mouseY, false, false, false); + _uiContainer->handleMouseMove(mouseX, mouseY); +} + +void KIASectionCrimes::handleMouseDown(bool mainButton) { + if (mainButton) { + _buttons->handleMouseAction(_mouseX, _mouseY, true, false, false); + } + _uiContainer->handleMouseDown(!mainButton); +} + +void KIASectionCrimes::handleMouseUp(bool mainButton) { + if (mainButton) { + _buttons->handleMouseAction(_mouseX, _mouseY, false, true, false); + } + _uiContainer->handleMouseUp(!mainButton); +} + +void KIASectionCrimes::saveToLog() { + int data[] = { _crimeSelected, _suspectSelected }; + _vm->_kia->_log->add(2, sizeof(data), &data); +} + +void KIASectionCrimes::loadFromLog() { + const int *data = (const int*)_vm->_kia->_log->getCurrentData(); + _crimeSelected = data[0]; + _suspectSelected = data[1]; + populateSuspects(); + populateVisibleClues(); +} + +void KIASectionCrimes::selectCrime(int crimeId) { + _crimeSelected = crimeId; + populateSuspects(); + populateVisibleClues(); + updateSuspectPhoto(); +} + +void KIASectionCrimes::scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton) { + KIASectionCrimes *self = (KIASectionCrimes *)callbackData; + + if (source == self->_cluesScrollBox && lineData >= 0) { + if (mouseButton) { + if (self->_vm->_gameFlags->query(kFlagKIAPrivacyAddon)) { + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(511), 70, 0, 0, 50, 0); + + if (self->_clues->isPrivate(lineData)) { + self->_clues->setPrivate(lineData, false); + self->_cluesScrollBox->resetFlags(lineData, 0x08); + } else { + self->_clues->setPrivate(lineData, true); + self->_cluesScrollBox->setFlags(lineData, 0x08); + } + } + } else { + self->_clues->setViewed(lineData, true); + self->_cluesScrollBox->resetHighlight(lineData); + self->_vm->_kia->_script->playClueAssetScript(0, lineData); + } + } +} + +void KIASectionCrimes::mouseUpCallback(int buttonId, void *callbackData) { + ((KIASectionCrimes *)callbackData)->onButtonPressed(buttonId); +} + +void KIASectionCrimes::onButtonPressed(int buttonId) { + switch (buttonId) { + case 0: + prevSuspect(); + break; + case 1: + nextSuspect(); + break; + case 2: + prevCrime(); + break; + case 3: + nextCrime(); + break; + case 4: + if (_suspectSelected != -1) { + _scheduledSwitch = true; + } + break; + } +} + +void KIASectionCrimes::populateAcquiredClues() { + _acquiredClueCount = 0; + for (int i = 0; i < kClueCount; ++i) { + if (_clues->isAcquired(i)) { + _acquiredClues[_acquiredClueCount].clueId = i; + _acquiredClues[_acquiredClueCount].actorId = _clues->getFromActorId(i); + ++_acquiredClueCount; + } + } + // sort clues by name, is it necessary +} + +void KIASectionCrimes::populateCrimes() { + int firstCrime = -1; + int crimeCount = _vm->_gameInfo->getCrimeCount(); + for (int i = 0; i < crimeCount; ++i) { + _crimesFound[i] = false; + } + + _crimesFoundCount = 0; + + if (!_acquiredClueCount) { + return; + } + + for (int i = 0; i < crimeCount; ++i) { + for (int j = 0; j < _acquiredClueCount; ++j) { + if (_vm->_crimesDatabase->getCrime(_acquiredClues[j].clueId) == i) { + if (firstCrime == -1) { + firstCrime = i; + } + _crimesFound[i] = true; + ++_crimesFoundCount; + } + } + } + + if (_crimesFoundCount > 0 && _crimeSelected == -1) { + _crimeSelected = firstCrime; + } +} + +void KIASectionCrimes::populateSuspects() { + int firstSuspect = -1; + int suspectCount = _vm->_gameInfo->getSuspectCount(); + + for (int i = 0; i < suspectCount; ++i) { + _suspectsFound[i] = false; + _suspectsWithIdentity[i] = false; + } + + _suspectsFoundCount = 0; + + if (!_acquiredClueCount || _crimeSelected == -1) { + return; + } + + for (int i = 0; i < suspectCount; ++i) { + for (int j = 0; j < _acquiredClueCount; ++j) { + if (_vm->_crimesDatabase->getCrime(_acquiredClues[j].clueId) == _crimeSelected + && _vm->_suspectsDatabase->get(i)->hasClue(_acquiredClues[j].clueId) + ) { + if (firstSuspect == -1) { + firstSuspect = i; + } + _suspectsFound[i] = true; + ++_suspectsFoundCount; + } + } + + if (_suspectsFound[i]) { + for (int j = 0; j < _acquiredClueCount; ++j) { + if (_vm->_suspectsDatabase->get(i)->hasIdentityClue(_acquiredClues[j].clueId)) { + _suspectsWithIdentity[i] = true; + } + } + } + } + + if (_suspectsFoundCount) { + if (_suspectSelected == -1 || !_suspectsFound[_suspectSelected]) { + _suspectSelected = firstSuspect; + } + } else { + _suspectSelected = -1; + } +} + +void KIASectionCrimes::populateVisibleClues() { + _cluesScrollBox->clearLines(); + if (_crimeSelected != -1) { + for (uint i = 0; i < _vm->_gameInfo->getClueCount(); ++i) { + if (_vm->_crimesDatabase->getAssetType(i) != -1 + && _vm->_crimesDatabase->getCrime(i) == _crimeSelected + && _clues->isAcquired(i) + ) { + int flags = 0x30; + if (_clues->isPrivate(i)) { + flags = 0x08; + } else if (_clues->isViewed(i)) { + flags = 0x10; + } + _cluesScrollBox->addLine(_vm->_crimesDatabase->getClueText(i), i, flags); + } + } + _cluesScrollBox->sortLines(); + } +} + +void KIASectionCrimes::updateSuspectPhoto() { + if (_suspectPhotoShapeId != -1) { + delete _suspectPhotoShape; + _suspectPhotoShape = nullptr; + } + + if (_suspectSelected == -1) { + _suspectPhotoShapeId = -1; + return; + } + + SuspectDatabaseEntry *suspect = _vm->_suspectsDatabase->get(_suspectSelected); + + _suspectPhotoShapeId = -1; + int photoCluesCount = suspect->getPhotoCount(); + if (photoCluesCount > 0) { + for (int i = 0 ; i < photoCluesCount; i++) { + //TODO: weird stuff going on here... it's using index instead id, also some field is used but its always -1 + if (_clues->isAcquired(suspect->getPhotoClueId(i))) { + _suspectPhotoShapeId = suspect->getPhotoShapeId(i); + break; + } + } + } + + if (_suspectPhotoShapeId == -1) { + if (suspect->getSex()) { + _suspectPhotoShapeId = 14; + } else { + _suspectPhotoShapeId = 13; + } + } + + if (_suspectPhotoShapeId != -1) { + _suspectPhotoShape = new Shape(_vm); + _suspectPhotoShape->readFromContainer("photos.shp", _suspectPhotoShapeId); + } +} + +void KIASectionCrimes::nextCrime() { + if (_crimesFoundCount >= 2) { + while (true) { + ++_crimeSelected; + if (_crimeSelected >= (int)_vm->_gameInfo->getCrimeCount()){ + _crimeSelected = 0; + } + + if (_crimesFound[_crimeSelected]) { + selectCrime(_crimeSelected); + break; + } + } + } +} + +void KIASectionCrimes::prevCrime() { + if (_crimesFoundCount >= 2) { + while (true) { + --_crimeSelected; + if (_crimeSelected < 0) { + _crimeSelected = _vm->_gameInfo->getCrimeCount() - 1; + } + + if (_crimesFound[_crimeSelected]) { + selectCrime(_crimeSelected); + break; + } + } + } +} + +void KIASectionCrimes::nextSuspect() { + if (_suspectsFoundCount >= 2) { + while (true) { + ++_suspectSelected; + if (_suspectSelected >= (int)_vm->_gameInfo->getSuspectCount()){ + _suspectSelected = 0; + } + + if (_suspectsFound[_suspectSelected]) { + updateSuspectPhoto(); + break; + } + } + } +} + +void KIASectionCrimes::prevSuspect() { + if (_suspectsFoundCount >= 2) { + while (true) { + --_suspectSelected; + if (_suspectSelected < 0){ + _suspectSelected = _vm->_gameInfo->getSuspectCount() - 1; + } + + if (_suspectsFound[_suspectSelected]) { + updateSuspectPhoto(); + break; + } + } + } } } // End of namespace BladeRunner |