1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "sherlock/journal.h"
24 #include "sherlock/sherlock.h"
25 #include "sherlock/scalpel/scalpel_fixed_text.h"
26 #include "sherlock/scalpel/scalpel_journal.h"
27 #include "sherlock/scalpel/scalpel_screen.h"
28 #include "sherlock/scalpel/scalpel.h"
29 #include "sherlock/tattoo/tattoo_journal.h"
30
31 namespace Sherlock {
32
33 namespace Scalpel {
34
35 #define JOURNAL_BUTTONS_Y 178
36 #define JOURNAL_SEARCH_LEFT 15
37 #define JOURNAL_SEARCH_TOP 186
38 #define JOURNAL_SEARCH_RIGHT 296
39 #define JOURNAL_SEACRH_MAX_CHARS 50
40
41 // Positioning of buttons in the journal view
42 static const int JOURNAL_POINTS[9][3] = {
43 { 6, 68, 37 },
44 { 69, 131, 100 },
45 { 132, 192, 162 },
46 { 193, 250, 221 },
47 { 251, 313, 281 },
48 { 6, 82, 44 },
49 { 83, 159, 121 },
50 { 160, 236, 198 },
51 { 237, 313, 275 }
52 };
53
54 static const int SEARCH_POINTS[3][3] = {
55 { 51, 123, 86 },
56 { 124, 196, 159 },
57 { 197, 269, 232 }
58 };
59
60 /*----------------------------------------------------------------*/
61
ScalpelJournal(SherlockEngine * vm)62 ScalpelJournal::ScalpelJournal(SherlockEngine *vm) : Journal(vm) {
63 if (_vm->_interactiveFl) {
64 // Load the journal directory and location names
65 loadLocations();
66 }
67
68 _fixedTextWatsonsJournal = FIXED(Journal_WatsonsJournal);
69 _fixedTextExit = FIXED(Journal_Exit);
70 _fixedTextBack10 = FIXED(Journal_Back10);
71 _fixedTextUp = FIXED(Journal_Up);
72 _fixedTextDown = FIXED(Journal_Down);
73 _fixedTextAhead10 = FIXED(Journal_Ahead10);
74 _fixedTextSearch = FIXED(Journal_Search);
75 _fixedTextFirstPage = FIXED(Journal_FirstPage);
76 _fixedTextLastPage = FIXED(Journal_LastPage);
77 _fixedTextPrintText = FIXED(Journal_PrintText);
78
79 _hotkeyExit = toupper(_fixedTextExit[0]);
80 _hotkeyBack10 = toupper(_fixedTextBack10[0]);
81 _hotkeyUp = toupper(_fixedTextUp[0]);
82 _hotkeyDown = toupper(_fixedTextDown[0]);
83 _hotkeyAhead10 = toupper(_fixedTextAhead10[0]);
84 _hotkeySearch = toupper(_fixedTextSearch[0]);
85 _hotkeyFirstPage = toupper(_fixedTextFirstPage[0]);
86 _hotkeyLastPage = toupper(_fixedTextLastPage[0]);
87 _hotkeyPrintText = toupper(_fixedTextPrintText[0]);
88
89 _fixedTextSearchExit = FIXED(JournalSearch_Exit);
90 _fixedTextSearchBackward = FIXED(JournalSearch_Backward);
91 _fixedTextSearchForward = FIXED(JournalSearch_Forward);
92 _fixedTextSearchNotFound = FIXED(JournalSearch_NotFound);
93
94 _hotkeySearchExit = toupper(_fixedTextSearchExit[0]);
95 _hotkeySearchBackward = toupper(_fixedTextSearchBackward[0]);
96 _hotkeySearchForward = toupper(_fixedTextSearchForward[0]);
97 }
98
loadLocations()99 void ScalpelJournal::loadLocations() {
100 Resources &res = *_vm->_res;
101
102 _directory.clear();
103 _locations.clear();
104
105
106 Common::SeekableReadStream *dir = res.load("talk.lib");
107 dir->skip(4); // Skip header
108
109 // Get the numer of entries
110 _directory.resize(dir->readUint16LE());
111
112 // Read in each entry
113 char buffer[17];
114 for (uint idx = 0; idx < _directory.size(); ++idx) {
115 dir->read(buffer, 17);
116 buffer[16] = '\0';
117
118 _directory[idx] = Common::String(buffer);
119 }
120
121 delete dir;
122
123 if (IS_3DO) {
124 // 3DO: storage of locations is currently unknown TODO
125 return;
126 }
127
128 // Load in the locations stored in journal.txt
129 Common::SeekableReadStream *loc = res.load("journal.txt");
130
131 while (loc->pos() < loc->size()) {
132 Common::String line;
133 char c;
134 while ((c = loc->readByte()) != 0)
135 line += c;
136
137 // WORKAROUND: Special fixes for faulty translations
138 // Was obviously not done in the original interpreter
139 if (_vm->getLanguage() == Common::ES_ESP) {
140 // Spanish version
141 // We fix all sorts of typos
142 // see bug #6931
143 if (line == "En el cajellon destras del teatro Regency") {
144 line = "En el callejon detras del teatro Regency";
145 } else if (line == "En el apartamente de Simon Kingsley") {
146 line = "En el apartamento de Simon Kingsley";
147 } else if (line == "Bajo la muelle de Savoy Pier") {
148 line = "Bajo el muelle de Savoy Pier";
149 } else if (line == "En le viejo Sherman") {
150 line = "En el viejo Sherman";
151 } else if (line == "En la entrada de la cada de Anna Carroway") {
152 line = "En la entrada de la casa de Anna Carroway";
153 }
154 }
155
156 _locations.push_back(line);
157 }
158
159 delete loc;
160 }
161
drawFrame()162 void ScalpelJournal::drawFrame() {
163 Resources &res = *_vm->_res;
164 ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
165 byte palette[PALETTE_SIZE];
166
167 // Load in the journal background
168 Common::SeekableReadStream *bg = res.load("journal.lbv");
169 bg->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCREEN_HEIGHT);
170 bg->read(palette, PALETTE_SIZE);
171 delete bg;
172
173 // Translate the palette for display
174 for (int idx = 0; idx < PALETTE_SIZE; ++idx)
175 palette[idx] = VGA_COLOR_TRANS(palette[idx]);
176
177 // Set the palette and print the title
178 screen.setPalette(palette);
179 screen.gPrint(Common::Point(111, 18), BUTTON_BOTTOM, "%s", _fixedTextWatsonsJournal.c_str());
180 screen.gPrint(Common::Point(110, 17), INV_FOREGROUND, "%s", _fixedTextWatsonsJournal.c_str());
181
182 // Draw the buttons
183 screen.makeButton(Common::Rect(JOURNAL_POINTS[0][0], JOURNAL_BUTTONS_Y,
184 JOURNAL_POINTS[0][1], JOURNAL_BUTTONS_Y + 10),
185 JOURNAL_POINTS[0][2], _fixedTextExit);
186 screen.makeButton(Common::Rect(JOURNAL_POINTS[1][0], JOURNAL_BUTTONS_Y,
187 JOURNAL_POINTS[1][1], JOURNAL_BUTTONS_Y + 10),
188 JOURNAL_POINTS[1][2], _fixedTextBack10);
189 screen.makeButton(Common::Rect(JOURNAL_POINTS[2][0], JOURNAL_BUTTONS_Y,
190 JOURNAL_POINTS[2][1], JOURNAL_BUTTONS_Y + 10),
191 JOURNAL_POINTS[2][2], _fixedTextUp);
192 screen.makeButton(Common::Rect(JOURNAL_POINTS[3][0], JOURNAL_BUTTONS_Y,
193 JOURNAL_POINTS[3][1], JOURNAL_BUTTONS_Y + 10),
194 JOURNAL_POINTS[3][2], _fixedTextDown);
195 screen.makeButton(Common::Rect(JOURNAL_POINTS[4][0], JOURNAL_BUTTONS_Y,
196 JOURNAL_POINTS[4][1], JOURNAL_BUTTONS_Y + 10),
197 JOURNAL_POINTS[4][2], _fixedTextAhead10);
198 screen.makeButton(Common::Rect(JOURNAL_POINTS[5][0], JOURNAL_BUTTONS_Y + 11,
199 JOURNAL_POINTS[5][1], JOURNAL_BUTTONS_Y + 21),
200 JOURNAL_POINTS[5][2], _fixedTextSearch);
201 screen.makeButton(Common::Rect(JOURNAL_POINTS[6][0], JOURNAL_BUTTONS_Y + 11,
202 JOURNAL_POINTS[6][1], JOURNAL_BUTTONS_Y + 21),
203 JOURNAL_POINTS[6][2], _fixedTextFirstPage);
204 screen.makeButton(Common::Rect(JOURNAL_POINTS[7][0], JOURNAL_BUTTONS_Y + 11,
205 JOURNAL_POINTS[7][1], JOURNAL_BUTTONS_Y + 21),
206 JOURNAL_POINTS[7][2], _fixedTextLastPage);
207
208 // WORKAROUND: Draw Print Text button as disabled, since we don't support it in ScummVM
209 screen.makeButton(Common::Rect(JOURNAL_POINTS[8][0], JOURNAL_BUTTONS_Y + 11,
210 JOURNAL_POINTS[8][1], JOURNAL_BUTTONS_Y + 21),
211 JOURNAL_POINTS[8][2], _fixedTextPrintText);
212 screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11),
213 COMMAND_NULL, false, _fixedTextPrintText);
214 }
215
drawInterface()216 void ScalpelJournal::drawInterface() {
217 ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
218
219 drawFrame();
220
221 if (_journal.empty()) {
222 _up = _down = 0;
223 } else {
224 drawJournal(0, 0);
225 }
226
227 doArrows();
228
229 // Show the entire screen
230 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
231 }
232
doArrows()233 void ScalpelJournal::doArrows() {
234 ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
235 byte color;
236
237 color = (_page > 1) ? COMMAND_FOREGROUND : COMMAND_NULL;
238 screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextBack10);
239 screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextUp);
240
241 color = _down ? COMMAND_FOREGROUND : COMMAND_NULL;
242 screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextDown);
243 screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), color, false, _fixedTextAhead10);
244 screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, false, _fixedTextLastPage);
245
246 color = _journal.size() > 0 ? COMMAND_FOREGROUND : COMMAND_NULL;
247 screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, false, _fixedTextSearch);
248 screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, false, _fixedTextPrintText);
249
250 color = _page > 1 ? COMMAND_FOREGROUND : COMMAND_NULL;
251 screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, false, _fixedTextFirstPage);
252 }
253
getHighlightedButton(const Common::Point & pt)254 JournalButton ScalpelJournal::getHighlightedButton(const Common::Point &pt) {
255 if (pt.x > JOURNAL_POINTS[0][0] && pt.x < JOURNAL_POINTS[0][1] && pt.y >= JOURNAL_BUTTONS_Y &&
256 pt.y < (JOURNAL_BUTTONS_Y + 10))
257 return BTN_EXIT;
258
259 if (pt.x > JOURNAL_POINTS[1][0] && pt.x < JOURNAL_POINTS[1][1] && pt.y >= JOURNAL_BUTTONS_Y &&
260 pt.y < (JOURNAL_BUTTONS_Y + 10) && _page > 1)
261 return BTN_BACK10;
262
263 if (pt.x > JOURNAL_POINTS[2][0] && pt.x < JOURNAL_POINTS[2][1] && pt.y >= JOURNAL_BUTTONS_Y &&
264 pt.y < (JOURNAL_BUTTONS_Y + 10) && _up)
265 return BTN_UP;
266
267 if (pt.x > JOURNAL_POINTS[3][0] && pt.x < JOURNAL_POINTS[3][1] && pt.y >= JOURNAL_BUTTONS_Y &&
268 pt.y < (JOURNAL_BUTTONS_Y + 10) && _down)
269 return BTN_DOWN;
270
271 if (pt.x > JOURNAL_POINTS[4][0] && pt.x < JOURNAL_POINTS[4][1] && pt.y >= JOURNAL_BUTTONS_Y &&
272 pt.y < (JOURNAL_BUTTONS_Y + 10) && _down)
273 return BTN_AHEAD110;
274
275 if (pt.x > JOURNAL_POINTS[5][0] && pt.x < JOURNAL_POINTS[5][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
276 pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty())
277 return BTN_SEARCH;
278
279 if (pt.x > JOURNAL_POINTS[6][0] && pt.x < JOURNAL_POINTS[6][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
280 pt.y < (JOURNAL_BUTTONS_Y + 20) && _up)
281 return BTN_FIRST_PAGE;
282
283 if (pt.x > JOURNAL_POINTS[7][0] && pt.x < JOURNAL_POINTS[7][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
284 pt.y < (JOURNAL_BUTTONS_Y + 20) && _down)
285 return BTN_LAST_PAGE;
286
287 if (pt.x > JOURNAL_POINTS[8][0] && pt.x < JOURNAL_POINTS[8][1] && pt.y >= (JOURNAL_BUTTONS_Y + 11) &&
288 pt.y < (JOURNAL_BUTTONS_Y + 20) && !_journal.empty())
289 return BTN_PRINT_TEXT;
290
291 return BTN_NONE;
292 }
293
handleEvents(int key)294 bool ScalpelJournal::handleEvents(int key) {
295 Events &events = *_vm->_events;
296 ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
297 bool doneFlag = false;
298
299 Common::Point pt = events.mousePos();
300 JournalButton btn = getHighlightedButton(pt);
301 byte color;
302
303 if (events._pressed || events._released) {
304 // Exit button
305 color = (btn == BTN_EXIT) ? COMMAND_HIGHLIGHTED : COMMAND_FOREGROUND;
306 screen.buttonPrint(Common::Point(JOURNAL_POINTS[0][2], JOURNAL_BUTTONS_Y), color, true, _fixedTextExit);
307
308 // Back 10 button
309 if (btn == BTN_BACK10) {
310 screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextBack10);
311 } else if (_page > 1) {
312 screen.buttonPrint(Common::Point(JOURNAL_POINTS[1][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextBack10);
313 }
314
315 // Up button
316 if (btn == BTN_UP) {
317 screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextUp);
318 } else if (_up) {
319 screen.buttonPrint(Common::Point(JOURNAL_POINTS[2][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextUp);
320 }
321
322 // Down button
323 if (btn == BTN_DOWN) {
324 screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextDown);
325 } else if (_down) {
326 screen.buttonPrint(Common::Point(JOURNAL_POINTS[3][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextDown);
327 }
328
329 // Ahead 10 button
330 if (btn == BTN_AHEAD110) {
331 screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_HIGHLIGHTED, true, _fixedTextAhead10);
332 } else if (_down) {
333 screen.buttonPrint(Common::Point(JOURNAL_POINTS[4][2], JOURNAL_BUTTONS_Y), COMMAND_FOREGROUND, true, _fixedTextAhead10);
334 }
335
336 // Search button
337 if (btn == BTN_SEARCH) {
338 color = COMMAND_HIGHLIGHTED;
339 } else if (_journal.empty()) {
340 color = COMMAND_NULL;
341 } else {
342 color = COMMAND_FOREGROUND;
343 }
344 screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), color, true, _fixedTextSearch);
345
346 // First Page button
347 if (btn == BTN_FIRST_PAGE) {
348 color = COMMAND_HIGHLIGHTED;
349 } else if (_up) {
350 color = COMMAND_FOREGROUND;
351 } else {
352 color = COMMAND_NULL;
353 }
354 screen.buttonPrint(Common::Point(JOURNAL_POINTS[6][2], JOURNAL_BUTTONS_Y + 11), color, true, _fixedTextFirstPage);
355
356 // Last Page button
357 if (btn == BTN_LAST_PAGE) {
358 color = COMMAND_HIGHLIGHTED;
359 } else if (_down) {
360 color = COMMAND_FOREGROUND;
361 } else {
362 color = COMMAND_NULL;
363 }
364 screen.buttonPrint(Common::Point(JOURNAL_POINTS[7][2], JOURNAL_BUTTONS_Y + 11), color, true, _fixedTextLastPage);
365
366 // Print Text button
367 screen.buttonPrint(Common::Point(JOURNAL_POINTS[8][2], JOURNAL_BUTTONS_Y + 11), COMMAND_NULL, true, _fixedTextPrintText);
368 }
369
370 if (btn == BTN_EXIT && events._released) {
371 // Exit button pressed
372 doneFlag = true;
373
374 } else if (((btn == BTN_BACK10 && events._released) || key == _hotkeyBack10) && (_page > 1)) {
375 // Scrolll up 10 pages
376 if (_page < 11)
377 drawJournal(1, (_page - 1) * LINES_PER_PAGE);
378 else
379 drawJournal(1, 10 * LINES_PER_PAGE);
380
381 doArrows();
382 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
383
384 } else if (((btn == BTN_UP && events._released) || key == _hotkeyUp) && _up) {
385 // Scroll up
386 drawJournal(1, LINES_PER_PAGE);
387 doArrows();
388 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
389
390 } else if (((btn == BTN_DOWN && events._released) || key == _hotkeyDown) && _down) {
391 // Scroll down
392 drawJournal(2, LINES_PER_PAGE);
393 doArrows();
394 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
395
396 } else if (((btn == BTN_AHEAD110 && events._released) || key == _hotkeyAhead10) && _down) {
397 // Scroll down 10 pages
398 if ((_page + 10) > _maxPage)
399 drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE);
400 else
401 drawJournal(2, 10 * LINES_PER_PAGE);
402
403 doArrows();
404 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
405
406 } else if (((btn == BTN_SEARCH && events._released) || key == _hotkeySearch) && !_journal.empty()) {
407 screen.buttonPrint(Common::Point(JOURNAL_POINTS[5][2], JOURNAL_BUTTONS_Y + 11), COMMAND_FOREGROUND, true, _fixedTextSearch);
408 bool notFound = false;
409
410 do {
411 int dir;
412 if ((dir = getSearchString(notFound)) != 0) {
413 int savedIndex = _index;
414 int savedSub = _sub;
415 int savedPage = _page;
416
417 if (drawJournal(dir + 2, 1000 * LINES_PER_PAGE) == 0) {
418 _index = savedIndex;
419 _sub = savedSub;
420 _page = savedPage;
421
422 drawFrame();
423 drawJournal(0, 0);
424 notFound = true;
425 } else {
426 doneFlag = true;
427 }
428
429 doArrows();
430 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
431 } else {
432 doneFlag = true;
433 }
434 } while (!doneFlag);
435 doneFlag = false;
436
437 } else if (((btn == BTN_FIRST_PAGE && events._released) || key == _hotkeyFirstPage) && _up) {
438 // First page
439 _index = _sub = 0;
440 _up = _down = false;
441 _page = 1;
442
443 drawFrame();
444 drawJournal(0, 0);
445 doArrows();
446 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
447
448 } else if (((btn == BTN_LAST_PAGE && events._released) || key == _hotkeyLastPage) && _down) {
449 // Last page
450 if ((_page + 10) > _maxPage)
451 drawJournal(2, (_maxPage - _page) * LINES_PER_PAGE);
452 else
453 drawJournal(2, 1000 * LINES_PER_PAGE);
454
455 doArrows();
456 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
457 }
458
459 events.wait(2);
460
461 return doneFlag;
462 }
463
getSearchString(bool printError)464 int ScalpelJournal::getSearchString(bool printError) {
465 enum Button { BTN_NONE, BTN_EXIT, BTN_BACKWARD, BTN_FORWARD };
466
467 Events &events = *_vm->_events;
468 ScalpelScreen &screen = *(ScalpelScreen *)_vm->_screen;
469 Talk &talk = *_vm->_talk;
470 int xp;
471 int yp = 174;
472 bool flag = false;
473 Common::String name;
474 int done = 0;
475 byte color;
476
477 // Draw search panel
478 screen.makePanel(Common::Rect(6, 171, 313, 199));
479 screen.makeButton(Common::Rect(SEARCH_POINTS[0][0], yp, SEARCH_POINTS[0][1], yp + 10),
480 SEARCH_POINTS[0][2], _fixedTextSearchExit);
481 screen.makeButton(Common::Rect(SEARCH_POINTS[1][0], yp, SEARCH_POINTS[1][1], yp + 10),
482 SEARCH_POINTS[1][2], _fixedTextSearchBackward);
483 screen.makeButton(Common::Rect(SEARCH_POINTS[2][0], yp, SEARCH_POINTS[2][1], yp + 10),
484 SEARCH_POINTS[2][2], _fixedTextSearchForward);
485
486 screen.makeField(Common::Rect(12, 185, 307, 196));
487
488 if (printError) {
489 screen.gPrint(Common::Point((SHERLOCK_SCREEN_WIDTH - screen.stringWidth(_fixedTextSearchNotFound)) / 2, 185),
490 INV_FOREGROUND, "%s", _fixedTextSearchNotFound.c_str());
491 } else if (!_find.empty()) {
492 // There's already a search term, display it already
493 screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str());
494 name = _find;
495 }
496
497 screen.slamArea(6, 171, 307, 28);
498
499 if (printError) {
500 // Give time for user to see the message
501 events.setButtonState();
502 for (int idx = 0; idx < 40 && !_vm->shouldQuit() && !events.kbHit() && !events._released; ++idx) {
503 events.pollEvents();
504 events.setButtonState();
505 events.wait(2);
506 }
507
508 events.clearKeyboard();
509 screen._backBuffer1.fillRect(Common::Rect(13, 186, 306, 195), BUTTON_MIDDLE);
510
511 if (!_find.empty()) {
512 screen.gPrint(Common::Point(15, 185), TALK_FOREGROUND, "%s", _find.c_str());
513 name = _find;
514 }
515
516 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
517 }
518
519 xp = JOURNAL_SEARCH_LEFT + screen.stringWidth(name);
520 yp = JOURNAL_SEARCH_TOP;
521
522 do {
523 events._released = false;
524 Button found = BTN_NONE;
525
526 while (!_vm->shouldQuit() && !events.kbHit() && !events._released) {
527 found = BTN_NONE;
528 if (talk._talkToAbort)
529 return 0;
530
531 // Check if key or mouse button press has occurred
532 events.setButtonState();
533 Common::Point pt = events.mousePos();
534
535 flag = !flag;
536 screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), flag ? INV_FOREGROUND : BUTTON_MIDDLE);
537
538 if (events._pressed || events._released) {
539 if (pt.x > SEARCH_POINTS[0][0] && pt.x < SEARCH_POINTS[0][1] && pt.y > 174 && pt.y < 183) {
540 found = BTN_EXIT;
541 color = COMMAND_HIGHLIGHTED;
542 } else {
543 color = COMMAND_FOREGROUND;
544 }
545 screen.buttonPrint(Common::Point(SEARCH_POINTS[0][0], SEARCH_POINTS[0][2]), color, false, _fixedTextSearchExit);
546
547 if (pt.x > SEARCH_POINTS[1][0] && pt.x < SEARCH_POINTS[1][1] && pt.y > 174 && pt.y < 183) {
548 found = BTN_BACKWARD;
549 color = COMMAND_HIGHLIGHTED;
550 } else {
551 color = COMMAND_FOREGROUND;
552 }
553 screen.buttonPrint(Common::Point(SEARCH_POINTS[1][0], SEARCH_POINTS[1][2]), color, false, _fixedTextSearchBackward);
554
555 if (pt.x > SEARCH_POINTS[2][0] && pt.x < SEARCH_POINTS[2][1] && pt.y > 174 && pt.y < 183) {
556 found = BTN_FORWARD;
557 color = COMMAND_HIGHLIGHTED;
558 } else {
559 color = COMMAND_FOREGROUND;
560 }
561 screen.buttonPrint(Common::Point(SEARCH_POINTS[2][0], SEARCH_POINTS[2][2]), color, false, _fixedTextSearchForward);
562 }
563
564 events.wait(2);
565 }
566
567 if (events.kbHit()) {
568 Common::KeyState keyState = events.getKey();
569
570 if ((keyState.keycode == Common::KEYCODE_BACKSPACE) && (name.size() > 0)) {
571 screen.vgaBar(Common::Rect(xp - screen.charWidth(name.lastChar()), yp, xp + 8, yp + 9), BUTTON_MIDDLE);
572 xp -= screen.charWidth(name.lastChar());
573 screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), INV_FOREGROUND);
574 name.deleteLastChar();
575
576 } else if (keyState.keycode == Common::KEYCODE_RETURN) {
577 done = 1;
578
579 } else if (keyState.keycode == Common::KEYCODE_ESCAPE) {
580 screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE);
581 done = -1;
582
583 } else if (keyState.ascii >= ' ' && keyState.ascii <= 'z' && keyState.keycode != Common::KEYCODE_AT &&
584 name.size() < JOURNAL_SEACRH_MAX_CHARS && (xp + screen.charWidth(keyState.ascii)) < JOURNAL_SEARCH_RIGHT) {
585 char ch = toupper(keyState.ascii);
586 screen.vgaBar(Common::Rect(xp, yp, xp + 8, yp + 9), BUTTON_MIDDLE);
587 screen.print(Common::Point(xp, yp), TALK_FOREGROUND, "%c", ch);
588 xp += screen.charWidth(ch);
589 name += ch;
590 }
591 }
592
593 if (events._released) {
594 switch (found) {
595 case BTN_EXIT:
596 done = -1; break;
597 case BTN_BACKWARD:
598 done = 2; break;
599 case BTN_FORWARD:
600 done = 1; break;
601 default:
602 break;
603 }
604 }
605 } while (!done && !_vm->shouldQuit());
606
607 if (done != -1) {
608 _find = name;
609 } else {
610 done = 0;
611 }
612
613 // Redisplay the journal screen
614 drawFrame();
615 drawJournal(0, 0);
616 screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
617
618 return done;
619 }
620
resetPosition()621 void ScalpelJournal::resetPosition() {
622 _index = _sub = _up = _down = 0;
623 _page = 1;
624 }
625
record(int converseNum,int statementNum,bool replyOnly)626 void ScalpelJournal::record(int converseNum, int statementNum, bool replyOnly) {
627 // there seems to be no journal in the 3DO version
628 if (!IS_3DO)
629 Journal::record(converseNum, statementNum, replyOnly);
630 }
631
632 } // End of namespace Scalpel
633
634 } // End of namespace Sherlock
635