2011-07-25 22:34:41 +00:00
|
|
|
/* 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 "dreamweb/dreamweb.h"
|
|
|
|
|
|
|
|
namespace DreamGen {
|
|
|
|
|
2011-12-07 22:45:33 +00:00
|
|
|
void DreamBase::printBoth(const Frame *charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) {
|
2011-07-25 22:34:41 +00:00
|
|
|
uint16 newX = *x;
|
|
|
|
uint8 width, height;
|
2011-12-01 19:43:43 +00:00
|
|
|
printChar(charSet, &newX, y, c, nextChar, &width, &height);
|
|
|
|
multiDump(*x, y, width, height);
|
2011-07-25 22:34:41 +00:00
|
|
|
*x = newX;
|
|
|
|
}
|
|
|
|
|
2011-12-06 18:59:52 +00:00
|
|
|
uint8 DreamBase::getNextWord(const Frame *charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount) {
|
2011-07-25 22:34:41 +00:00
|
|
|
*totalWidth = 0;
|
|
|
|
*charCount = 0;
|
2011-12-08 09:02:51 +00:00
|
|
|
while (true) {
|
2011-07-25 22:34:41 +00:00
|
|
|
uint8 firstChar = *string;
|
|
|
|
++string;
|
|
|
|
++*charCount;
|
|
|
|
if ((firstChar == ':') || (firstChar == 0)) { //endall
|
|
|
|
*totalWidth += 6;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (firstChar == 32) { //endword
|
|
|
|
*totalWidth += 6;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
firstChar = engine->modifyChar(firstChar);
|
|
|
|
if (firstChar != 255) {
|
|
|
|
uint8 secondChar = *string;
|
2011-12-06 19:55:59 +00:00
|
|
|
uint8 width = charSet[firstChar - 32 + data.word(kCharshift)].width;
|
2011-12-01 19:43:43 +00:00
|
|
|
width = kernChars(firstChar, secondChar, width);
|
2011-07-25 22:34:41 +00:00
|
|
|
*totalWidth += width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-07 22:45:33 +00:00
|
|
|
void DreamBase::printChar(const Frame *charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
|
2011-07-25 22:34:41 +00:00
|
|
|
if (c == 255)
|
|
|
|
return;
|
2011-11-18 07:29:50 +00:00
|
|
|
|
|
|
|
uint8 dummyWidth, dummyHeight;
|
|
|
|
if (width == NULL)
|
|
|
|
width = &dummyWidth;
|
|
|
|
if (height == NULL)
|
|
|
|
height = &dummyHeight;
|
|
|
|
if (data.byte(kForeignrelease))
|
2011-07-25 22:34:41 +00:00
|
|
|
y -= 3;
|
|
|
|
uint16 tmp = c - 32 + data.word(kCharshift);
|
2011-12-01 19:43:43 +00:00
|
|
|
showFrame(charSet, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height);
|
2011-11-18 07:29:50 +00:00
|
|
|
if (data.byte(kKerning), 0)
|
2011-12-01 19:43:43 +00:00
|
|
|
*width = kernChars(c, nextChar, *width);
|
2011-07-25 22:34:41 +00:00
|
|
|
(*x) += *width;
|
|
|
|
}
|
|
|
|
|
2011-12-07 22:45:33 +00:00
|
|
|
void DreamBase::printChar(const Frame *charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
|
2011-12-01 19:43:43 +00:00
|
|
|
printChar(charSet, &x, y, c, nextChar, width, height);
|
2011-11-18 07:29:50 +00:00
|
|
|
}
|
|
|
|
|
2011-12-08 14:21:42 +00:00
|
|
|
uint8 DreamBase::printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
|
2011-07-25 22:34:41 +00:00
|
|
|
data.byte(kPointerframe) = 1;
|
|
|
|
data.byte(kPointermode) = 3;
|
2011-12-02 15:29:16 +00:00
|
|
|
const Frame* charSet = (const Frame *)getSegment(data.word(kCharset1)).ptr(0, 0);
|
2011-07-25 22:34:41 +00:00
|
|
|
do {
|
|
|
|
uint16 offset = x;
|
2011-12-01 19:43:43 +00:00
|
|
|
uint16 charCount = getNumber(charSet, string, maxWidth, centered, &offset);
|
2011-07-25 22:34:41 +00:00
|
|
|
do {
|
2011-08-11 01:19:51 +00:00
|
|
|
uint8 c0 = string[0];
|
|
|
|
uint8 c1 = string[1];
|
|
|
|
uint8 c2 = string[2];
|
2011-07-25 22:34:41 +00:00
|
|
|
c0 = engine->modifyChar(c0);
|
2011-12-01 19:43:43 +00:00
|
|
|
printBoth(charSet, &offset, y, c0, c1);
|
2011-07-25 22:34:41 +00:00
|
|
|
if ((c1 == 0) || (c1 == ':')) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (charCount != 1) {
|
|
|
|
c1 = engine->modifyChar(c1);
|
|
|
|
data.word(kCharshift) = 91;
|
|
|
|
uint16 offset2 = offset;
|
2011-12-01 19:43:43 +00:00
|
|
|
printBoth(charSet, &offset2, y, c1, c2);
|
2011-07-25 22:34:41 +00:00
|
|
|
data.word(kCharshift) = 0;
|
|
|
|
for (int i=0; i<2; ++i) {
|
2011-12-01 19:43:43 +00:00
|
|
|
uint16 mouseState = waitFrames();
|
2011-12-27 03:08:43 +00:00
|
|
|
if (_quitRequested)
|
2011-09-08 07:11:16 +00:00
|
|
|
return 0;
|
2011-08-25 06:03:27 +00:00
|
|
|
if (mouseState == 0)
|
2011-07-25 22:34:41 +00:00
|
|
|
continue;
|
2011-08-25 06:03:27 +00:00
|
|
|
if (mouseState != data.word(kOldbutton)) {
|
2011-07-25 22:34:41 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-11 01:19:51 +00:00
|
|
|
++string;
|
2011-07-25 22:34:41 +00:00
|
|
|
--charCount;
|
|
|
|
} while (charCount);
|
|
|
|
y += 10;
|
|
|
|
} while (true);
|
|
|
|
}
|
|
|
|
|
2011-12-07 22:45:33 +00:00
|
|
|
uint8 DreamBase::printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
|
2011-12-01 19:43:43 +00:00
|
|
|
return printDirect(&string, x, &y, maxWidth, centered);
|
2011-09-07 01:58:04 +00:00
|
|
|
}
|
|
|
|
|
2011-12-07 22:45:33 +00:00
|
|
|
uint8 DreamBase::printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) {
|
2011-07-25 22:34:41 +00:00
|
|
|
data.word(kLastxpos) = x;
|
2011-12-04 17:44:58 +00:00
|
|
|
const Frame *charSet = engine->currentCharset();
|
2011-07-25 22:34:41 +00:00
|
|
|
while (true) {
|
|
|
|
uint16 offset = x;
|
2011-12-01 19:43:43 +00:00
|
|
|
uint8 charCount = getNumber(charSet, *string, maxWidth, centered, &offset);
|
2011-07-25 22:34:41 +00:00
|
|
|
uint16 i = offset;
|
|
|
|
do {
|
2011-08-10 15:12:26 +00:00
|
|
|
uint8 c = (*string)[0];
|
|
|
|
uint8 nextChar = (*string)[1];
|
|
|
|
++(*string);
|
2011-07-25 22:34:41 +00:00
|
|
|
if ((c == 0) || (c == ':')) {
|
2011-11-28 14:11:46 +00:00
|
|
|
return c;
|
2011-07-25 22:34:41 +00:00
|
|
|
}
|
|
|
|
c = engine->modifyChar(c);
|
|
|
|
uint8 width, height;
|
2011-12-01 19:43:43 +00:00
|
|
|
printChar(charSet, &i, *y, c, nextChar, &width, &height);
|
2011-07-25 22:34:41 +00:00
|
|
|
data.word(kLastxpos) = i;
|
|
|
|
--charCount;
|
2011-12-08 09:02:51 +00:00
|
|
|
} while (charCount);
|
2011-07-25 22:34:41 +00:00
|
|
|
*y += data.word(kLinespacing);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-06 18:59:52 +00:00
|
|
|
uint8 DreamBase::getNumber(const Frame *charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16* offset) {
|
2011-07-25 22:34:41 +00:00
|
|
|
uint8 totalWidth = 0;
|
|
|
|
uint8 charCount = 0;
|
|
|
|
while (true) {
|
|
|
|
uint8 wordTotalWidth, wordCharCount;
|
2011-12-01 19:43:43 +00:00
|
|
|
uint8 done = getNextWord(charSet, string, &wordTotalWidth, &wordCharCount);
|
2011-08-10 15:03:02 +00:00
|
|
|
string += wordCharCount;
|
2011-07-25 22:34:41 +00:00
|
|
|
|
2011-12-04 23:37:19 +00:00
|
|
|
uint16 tmp = totalWidth + wordTotalWidth - 10;
|
2011-07-25 22:34:41 +00:00
|
|
|
if (done == 1) { //endoftext
|
2011-12-04 23:37:19 +00:00
|
|
|
if (tmp < maxWidth) {
|
2011-07-25 22:34:41 +00:00
|
|
|
totalWidth += wordTotalWidth;
|
|
|
|
charCount += wordCharCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (centered) {
|
2011-12-04 23:37:19 +00:00
|
|
|
tmp = (maxWidth & 0xfe) + 2 + 20 - totalWidth;
|
|
|
|
tmp /= 2;
|
2011-07-25 22:34:41 +00:00
|
|
|
} else {
|
2011-12-04 23:37:19 +00:00
|
|
|
tmp = 0;
|
2011-07-25 22:34:41 +00:00
|
|
|
}
|
2011-12-04 23:37:19 +00:00
|
|
|
*offset += tmp;
|
2011-07-25 22:34:41 +00:00
|
|
|
return charCount;
|
|
|
|
}
|
2011-12-04 23:37:19 +00:00
|
|
|
if (tmp >= maxWidth) { //gotoverend
|
2011-07-25 22:34:41 +00:00
|
|
|
if (centered) {
|
2011-12-04 23:37:19 +00:00
|
|
|
tmp = (maxWidth & 0xfe) - totalWidth + 20;
|
|
|
|
tmp /= 2;
|
2011-07-25 22:34:41 +00:00
|
|
|
} else {
|
2011-12-04 23:37:19 +00:00
|
|
|
tmp = 0;
|
2011-07-25 22:34:41 +00:00
|
|
|
}
|
2011-12-04 23:37:19 +00:00
|
|
|
*offset += tmp;
|
2011-07-25 22:34:41 +00:00
|
|
|
return charCount;
|
|
|
|
}
|
|
|
|
totalWidth += wordTotalWidth;
|
|
|
|
charCount += wordCharCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-06 18:59:52 +00:00
|
|
|
uint8 DreamBase::kernChars(uint8 firstChar, uint8 secondChar, uint8 width) {
|
2011-12-04 13:16:30 +00:00
|
|
|
if ((firstChar == 'a') || (firstChar == 'u')) {
|
2011-07-25 22:34:41 +00:00
|
|
|
if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l'))
|
|
|
|
return width-1;
|
|
|
|
}
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
2011-12-08 14:21:42 +00:00
|
|
|
uint16 DreamBase::waitFrames() {
|
2011-12-01 19:43:43 +00:00
|
|
|
readMouse();
|
|
|
|
showPointer();
|
|
|
|
vSync();
|
|
|
|
dumpPointer();
|
|
|
|
delPointer();
|
2011-08-25 06:03:27 +00:00
|
|
|
return data.word(kMousebutton);
|
|
|
|
}
|
|
|
|
|
2011-12-08 14:21:42 +00:00
|
|
|
const char *DreamBase::monPrint(const char *string) {
|
2011-11-18 17:17:16 +00:00
|
|
|
data.byte(kKerning) = 1;
|
|
|
|
uint16 x = data.word(kMonadx);
|
2011-12-04 17:44:58 +00:00
|
|
|
Frame *charset = engine->tempCharset();
|
2011-11-18 17:17:16 +00:00
|
|
|
const char *iterator = string;
|
2011-11-19 18:17:04 +00:00
|
|
|
bool done = false;
|
|
|
|
while (!done) {
|
|
|
|
|
2011-12-01 19:43:43 +00:00
|
|
|
uint16 count = getNumber(charset, (const uint8 *)iterator, 166, false, &x);
|
2011-11-19 18:17:04 +00:00
|
|
|
do {
|
2011-11-18 17:17:16 +00:00
|
|
|
char c = *iterator++;
|
|
|
|
if (c == ':')
|
|
|
|
break;
|
2011-11-19 18:17:04 +00:00
|
|
|
if ((c == 0) || (c == '"') || (c == '=')) {
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
}
|
2011-11-18 17:17:16 +00:00
|
|
|
if (c == '%') {
|
|
|
|
data.byte(kLasttrigger) = *iterator;
|
|
|
|
iterator += 2;
|
2011-11-19 18:17:04 +00:00
|
|
|
done = true;
|
|
|
|
break;
|
2011-11-18 17:17:16 +00:00
|
|
|
}
|
|
|
|
c = engine->modifyChar(c);
|
2011-12-01 19:43:43 +00:00
|
|
|
printChar(charset, &x, data.word(kMonady), c, 0, NULL, NULL);
|
2011-11-18 17:17:16 +00:00
|
|
|
data.word(kCurslocx) = x;
|
|
|
|
data.word(kCurslocy) = data.word(kMonady);
|
|
|
|
data.word(kMaintimer) = 1;
|
2011-12-01 19:43:43 +00:00
|
|
|
printCurs();
|
|
|
|
vSync();
|
|
|
|
lockMon();
|
|
|
|
delCurs();
|
2011-11-19 18:17:04 +00:00
|
|
|
} while (--count);
|
|
|
|
|
2011-11-18 17:17:16 +00:00
|
|
|
x = data.word(kMonadx);
|
2011-12-01 19:43:43 +00:00
|
|
|
scrollMonitor();
|
2011-11-18 17:17:16 +00:00
|
|
|
data.word(kCurslocx) = data.word(kMonadx);
|
|
|
|
}
|
2011-11-19 18:17:04 +00:00
|
|
|
|
2011-11-18 17:17:16 +00:00
|
|
|
data.byte(kKerning) = 0;
|
|
|
|
return iterator;
|
|
|
|
}
|
|
|
|
|
2011-12-26 01:15:47 +00:00
|
|
|
void DreamBase::rollEndCreditsGameWon() {
|
|
|
|
playChannel0(16, 255);
|
|
|
|
data.byte(kVolume) = 7;
|
|
|
|
data.byte(kVolumeto) = 0;
|
|
|
|
data.byte(kVolumedirection) = (byte)-1;
|
|
|
|
|
|
|
|
multiGet(mapStore(), 75, 20, 160, 160);
|
|
|
|
|
|
|
|
const uint8 *string = getTextInFile1(3);
|
|
|
|
const int linespacing = data.word(kLinespacing);
|
|
|
|
|
|
|
|
for (int i = 0; i < 254; ++i) {
|
|
|
|
// Output the text, initially with an offset of 10 pixels,
|
|
|
|
// then move it up one pixel until we shifted it by a complete
|
|
|
|
// line of text.
|
|
|
|
for (int j = 0; j < linespacing; ++j) {
|
|
|
|
vSync();
|
|
|
|
multiPut(mapStore(), 75, 20, 160, 160);
|
|
|
|
vSync();
|
|
|
|
|
|
|
|
// Output up to 18 lines of text
|
|
|
|
uint16 y = 10 - j;
|
|
|
|
const uint8 *tmp_str = string;
|
|
|
|
for (int k = 0; k < 18; ++k) {
|
|
|
|
DreamBase::printDirect(&tmp_str, 75, &y, 160 + 1, true);
|
|
|
|
y += linespacing;
|
|
|
|
}
|
|
|
|
|
|
|
|
vSync();
|
|
|
|
multiDump(75, 20, 160, 160);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip to the next text line
|
|
|
|
byte c;
|
|
|
|
do {
|
|
|
|
c = *string++;
|
|
|
|
} while (c != ':' && c != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
hangOn(100);
|
|
|
|
panelToMap();
|
|
|
|
fadeScreenUpHalf();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DreamBase::rollEndCreditsGameLost() {
|
|
|
|
multiGet(mapStore(), 25, 20, 160, 160);
|
|
|
|
|
|
|
|
const uint8 *string = getTextInFile1(49);
|
|
|
|
const int linespacing = data.word(kLinespacing);
|
|
|
|
|
|
|
|
for (int i = 0; i < 80; ++i) {
|
|
|
|
// Output the text, initially with an offset of 10 pixels,
|
|
|
|
// then move it up one pixel until we shifted it by a complete
|
|
|
|
// line of text.
|
|
|
|
for (int j = 0; j < linespacing; ++j) {
|
|
|
|
vSync();
|
|
|
|
multiPut(mapStore(), 25, 20, 160, 160);
|
|
|
|
vSync();
|
|
|
|
|
|
|
|
// Output up to 18 lines of text
|
|
|
|
uint16 y = 10 - j;
|
|
|
|
const uint8 *tmp_str = string;
|
|
|
|
for (int k = 0; k < 18; ++k) {
|
|
|
|
DreamBase::printDirect(&tmp_str, 25, &y, 160 + 1, true);
|
|
|
|
y += linespacing;
|
|
|
|
}
|
|
|
|
|
|
|
|
vSync();
|
|
|
|
multiDump(25, 20, 160, 160);
|
|
|
|
|
|
|
|
if (data.byte(kLasthardkey) == 1)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip to the next text line
|
|
|
|
byte c;
|
|
|
|
do {
|
|
|
|
c = *string++;
|
|
|
|
} while (c != ':' && c != 0);
|
|
|
|
|
|
|
|
if (data.byte(kLasthardkey) == 1)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
hangOne(120);
|
|
|
|
}
|
|
|
|
|
2011-12-06 16:43:23 +00:00
|
|
|
} // End of namespace DreamGen
|