Initial commit
This commit is contained in:
502
engines/bladerunner/ui/kia_section_crimes.cpp
Normal file
502
engines/bladerunner/ui/kia_section_crimes.cpp
Normal file
@@ -0,0 +1,502 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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_flags.h"
|
||||
#include "bladerunner/game_info.h"
|
||||
#include "bladerunner/shape.h"
|
||||
#include "bladerunner/script/kia_script.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/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, 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;
|
||||
for (int i = 0; i < kClueCount; ++i) {
|
||||
_acquiredClues[i].clueId = -1;
|
||||
_acquiredClues[i].actorId = -1;
|
||||
}
|
||||
|
||||
_crimeSelected = -1;
|
||||
_crimesFoundCount = 0;
|
||||
_crimesFound.resize(_vm->_gameInfo->getCrimeCount());
|
||||
|
||||
_suspectSelected = -1;
|
||||
_suspectPhotoShapeId = -1;
|
||||
_suspectPhotoNotUsed = -1;
|
||||
_suspectPhotoShapes = new Shapes(vm);
|
||||
_suspectsFoundCount = 0;
|
||||
_suspectsFound.resize(_vm->_gameInfo->getSuspectCount());
|
||||
_suspectsWithIdentity.resize(_vm->_gameInfo->getSuspectCount());
|
||||
}
|
||||
|
||||
KIASectionCrimes::~KIASectionCrimes() {
|
||||
delete _suspectPhotoShapes;
|
||||
|
||||
_uiContainer->clear();
|
||||
|
||||
delete _cluesScrollBox;
|
||||
delete _buttons;
|
||||
delete _uiContainer;
|
||||
}
|
||||
|
||||
void KIASectionCrimes::reset() {
|
||||
_acquiredClueCount = 0;
|
||||
_crimesFoundCount = 0;
|
||||
_suspectsFoundCount = 0;
|
||||
_mouseX = 0;
|
||||
_mouseY = 0;
|
||||
_suspectSelected = -1;
|
||||
_crimeSelected = -1;
|
||||
_suspectPhotoShapeId = -1;
|
||||
_suspectPhotoNotUsed = -1;
|
||||
}
|
||||
|
||||
void KIASectionCrimes::open() {
|
||||
_scheduledSwitch = false;
|
||||
|
||||
_suspectPhotoShapes->load("photos.shp");
|
||||
|
||||
_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();
|
||||
_suspectPhotoShapes->unload();
|
||||
}
|
||||
|
||||
void KIASectionCrimes::draw(Graphics::Surface &surface) {
|
||||
const char *text = nullptr;
|
||||
if (_suspectPhotoShapeId != -1) {
|
||||
const Shape *shape = _suspectPhotoShapes->get(_suspectPhotoShapeId);
|
||||
shape->draw(surface, 201 - shape->getWidth() / 2, 223 - shape->getHeight() / 2);
|
||||
}
|
||||
if (_suspectPhotoShapeId == 14 || _suspectPhotoShapeId == 13) {
|
||||
text = _vm->_textKIA->getText(49);
|
||||
_vm->_mainFont->drawString(&surface, text, 201 - _vm->_mainFont->getStringWidth(text) / 2, 218, surface.w, surface.format.RGBToColor(255, 255, 255));
|
||||
}
|
||||
|
||||
surface.fillRect(Common::Rect(120, 134, 250, 145), 0);
|
||||
surface.hLine(120, 133, 250, surface.format.RGBToColor(48, 40, 40));
|
||||
surface.hLine(120, 146, 250, surface.format.RGBToColor(88, 80, 96));
|
||||
surface.vLine(119, 134, 145, surface.format.RGBToColor(48, 40, 40));
|
||||
surface.vLine(251, 134, 145, surface.format.RGBToColor(88, 80, 96));
|
||||
surface.hLine(251, 146, 251, surface.format.RGBToColor(72, 64, 72));
|
||||
|
||||
if (_crimeSelected == -1) {
|
||||
text = _vm->_textKIA->getText(49);
|
||||
} else {
|
||||
text = _vm->_textCrimes->getText(_crimeSelected);
|
||||
}
|
||||
|
||||
_vm->_mainFont->drawString(&surface, text, 185 - _vm->_mainFont->getStringWidth(text) / 2, 136, surface.w, surface.format.RGBToColor(136, 168, 255));
|
||||
|
||||
surface.fillRect(Common::Rect(136, 304, 266, 315), 0);
|
||||
surface.hLine(136, 303, 266, surface.format.RGBToColor(48, 40, 40));
|
||||
surface.hLine(136, 316, 266, surface.format.RGBToColor(88, 80, 96));
|
||||
surface.vLine(135, 304, 315, surface.format.RGBToColor(48, 40, 40));
|
||||
surface.vLine(267, 304, 315, surface.format.RGBToColor(88, 80, 96));
|
||||
surface.hLine(267, 316, 267, surface.format.RGBToColor(72, 64, 72));
|
||||
|
||||
Common::String generatedText;
|
||||
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()) {
|
||||
generatedText = Common::String::format("%s %s", _vm->_textKIA->getText(20), _vm->_kia->scrambleSuspectsName(suspectName));
|
||||
text = generatedText.c_str();
|
||||
} else {
|
||||
generatedText = Common::String::format("%s %s", _vm->_textKIA->getText(21), _vm->_kia->scrambleSuspectsName(suspectName));
|
||||
text = generatedText.c_str();
|
||||
}
|
||||
}
|
||||
_vm->_mainFont->drawString(&surface, text, 201 - _vm->_mainFont->getStringWidth(text) / 2, 306, surface.w, surface.format.RGBToColor(136, 168, 255));
|
||||
|
||||
_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::handleMouseScroll(int direction) {
|
||||
_uiContainer->handleMouseScroll(direction);
|
||||
}
|
||||
|
||||
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(kSfxBEEP15), 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) {
|
||||
int clueId = i;
|
||||
if (_clues->isAcquired(clueId)) {
|
||||
_acquiredClues[_acquiredClueCount].clueId = clueId;
|
||||
_acquiredClues[_acquiredClueCount].actorId = _clues->getFromActorId(clueId);
|
||||
++_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 (int i = 0; i < kClueCount; ++i) {
|
||||
int clueId = i;
|
||||
if (_vm->_crimesDatabase->getAssetType(clueId) != kClueTypeIntangible
|
||||
&& _vm->_crimesDatabase->getCrime(clueId) == _crimeSelected
|
||||
&& _clues->isAcquired(clueId)
|
||||
) {
|
||||
int flags = 0x30;
|
||||
#if BLADERUNNER_ORIGINAL_BUGS
|
||||
if (_clues->isPrivate(clueId)) {
|
||||
flags = 0x08;
|
||||
} else if (_clues->isViewed(clueId)) {
|
||||
flags = 0x10;
|
||||
}
|
||||
#else
|
||||
if (_clues->isPrivate(clueId)) {
|
||||
flags |= 0x08;
|
||||
}
|
||||
if (_clues->isViewed(clueId)) {
|
||||
flags &= ~0x20;
|
||||
}
|
||||
if (_vm->_cutContent && _clues->isSharedWithMainframe(clueId)) {
|
||||
flags |= 0x40;
|
||||
}
|
||||
#endif // BLADERUNNER_ORIGINAL_BUGS
|
||||
_cluesScrollBox->addLine(_vm->_crimesDatabase->getClueText(clueId), clueId, flags);
|
||||
}
|
||||
}
|
||||
_cluesScrollBox->sortLines();
|
||||
}
|
||||
}
|
||||
|
||||
void KIASectionCrimes::updateSuspectPhoto() {
|
||||
if (_suspectSelected == -1) {
|
||||
_suspectPhotoShapeId = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
SuspectDatabaseEntry *suspect = _vm->_suspectsDatabase->get(_suspectSelected);
|
||||
|
||||
_suspectPhotoShapeId = -1;
|
||||
_suspectPhotoNotUsed = -1;
|
||||
int photoCluesCount = suspect->getPhotoCount();
|
||||
if (photoCluesCount > 0) {
|
||||
for (int i = 0 ; i < photoCluesCount; ++i) {
|
||||
//TODO: weird stuff going on here... original game is using internal clue index instead id
|
||||
if (_clues->isAcquired(suspect->getPhotoClueId(i))) {
|
||||
_suspectPhotoShapeId = suspect->getPhotoShapeId(i);
|
||||
_suspectPhotoNotUsed = suspect->getPhotoNotUsed(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_suspectPhotoShapeId == -1 && _suspectPhotoNotUsed == -1) {
|
||||
if (suspect->getSex()) {
|
||||
_suspectPhotoShapeId = 14;
|
||||
} else {
|
||||
_suspectPhotoShapeId = 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user