Initial commit
This commit is contained in:
348
engines/dreamweb/print.cpp
Normal file
348
engines/dreamweb/print.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
/* 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 "dreamweb/sound.h"
|
||||
#include "dreamweb/dreamweb.h"
|
||||
|
||||
namespace DreamWeb {
|
||||
|
||||
void DreamWebEngine::printBoth(const GraphicsFile &charSet, uint16 *x, uint16 y, uint8 c, uint8 nextChar) {
|
||||
uint16 newX = *x;
|
||||
uint8 width, height;
|
||||
printChar(charSet, &newX, y, c, nextChar, &width, &height);
|
||||
multiDump(*x, y, width, height);
|
||||
*x = newX;
|
||||
}
|
||||
|
||||
uint8 DreamWebEngine::getNextWord(const GraphicsFile &charSet, const uint8 *string, uint8 *totalWidth, uint8 *charCount) {
|
||||
*totalWidth = 0;
|
||||
*charCount = 0;
|
||||
while (true) {
|
||||
uint8 firstChar = *string;
|
||||
++string;
|
||||
++*charCount;
|
||||
if ((firstChar == ':') || (firstChar == 0)) { //endall
|
||||
*totalWidth += 6;
|
||||
return 1;
|
||||
}
|
||||
if (firstChar == 32) { //endword
|
||||
*totalWidth += 6;
|
||||
return 0;
|
||||
}
|
||||
firstChar = modifyChar(firstChar);
|
||||
// WORKAROUND: Also filter out invalid characters here (refer to the
|
||||
// workaround in printChar() below for more info).
|
||||
if (firstChar >= 32 && firstChar != 255) {
|
||||
uint8 secondChar = *string;
|
||||
uint8 width = charSet._frames[firstChar - 32 + _charShift].width;
|
||||
width = kernChars(firstChar, secondChar, width);
|
||||
*totalWidth += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DreamWebEngine::printChar(const GraphicsFile &charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height, bool kerning) {
|
||||
// WORKAROUND: Some texts contain leftover tab characters, which will cause
|
||||
// OOB memory access when showing a character, as all the printable ones are
|
||||
// from 32 onwards. We compensate for that here by ignoring all the invalid
|
||||
// characters (0 - 31).
|
||||
if (c < 32 || c == 255)
|
||||
return;
|
||||
|
||||
uint8 dummyWidth, dummyHeight;
|
||||
if (width == nullptr)
|
||||
width = &dummyWidth;
|
||||
if (height == nullptr)
|
||||
height = &dummyHeight;
|
||||
if (_foreignRelease)
|
||||
y -= 3;
|
||||
uint16 tmp = c - 32 + _charShift;
|
||||
showFrame(charSet, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height);
|
||||
if (!kerning)
|
||||
*width = kernChars(c, nextChar, *width);
|
||||
(*x) += *width;
|
||||
}
|
||||
|
||||
void DreamWebEngine::printChar(const GraphicsFile &charSet, uint16 x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) {
|
||||
printChar(charSet, &x, y, c, nextChar, width, height);
|
||||
}
|
||||
|
||||
uint8 DreamWebEngine::printSlow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
|
||||
_pointerFrame = 1;
|
||||
_pointerMode = 3;
|
||||
do {
|
||||
uint16 offset = x;
|
||||
uint16 charCount = getNumber(_charset1, string, maxWidth, centered, &offset);
|
||||
do {
|
||||
uint8 c0 = string[0];
|
||||
uint8 c1 = string[1];
|
||||
uint8 c2 = string[2];
|
||||
c0 = modifyChar(c0);
|
||||
printBoth(_charset1, &offset, y, c0, c1);
|
||||
if ((c1 == 0) || (c1 == ':')) {
|
||||
return 0;
|
||||
}
|
||||
if (charCount != 1) {
|
||||
c1 = modifyChar(c1);
|
||||
_charShift = getLanguage() == Common::RU_RUS ? 182 : 91;
|
||||
uint16 offset2 = offset;
|
||||
printBoth(_charset1, &offset2, y, c1, c2);
|
||||
_charShift = 0;
|
||||
for (int i=0; i<2; ++i) {
|
||||
uint16 mouseState = waitFrames();
|
||||
if (_quitRequested)
|
||||
return 0;
|
||||
if (mouseState == 0)
|
||||
continue;
|
||||
if (mouseState != _oldButton) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++string;
|
||||
--charCount;
|
||||
} while (charCount);
|
||||
y += 10;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
uint8 DreamWebEngine::printDirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) {
|
||||
return printDirect(&string, x, &y, maxWidth, centered);
|
||||
}
|
||||
|
||||
uint8 DreamWebEngine::printDirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered, bool kerning) {
|
||||
_lastXPos = x;
|
||||
const GraphicsFile &charSet = *_currentCharset;
|
||||
while (true) {
|
||||
uint16 offset = x;
|
||||
uint8 charCount = getNumber(charSet, *string, maxWidth, centered, &offset);
|
||||
uint16 i = offset;
|
||||
do {
|
||||
uint8 c = (*string)[0];
|
||||
++(*string);
|
||||
if ((c == 0) || (c == ':')) {
|
||||
return c;
|
||||
}
|
||||
uint8 nextChar = (*string)[0];
|
||||
c = modifyChar(c);
|
||||
uint8 width, height;
|
||||
printChar(charSet, &i, *y, c, nextChar, &width, &height);
|
||||
_lastXPos = i;
|
||||
--charCount;
|
||||
} while (charCount);
|
||||
*y += _lineSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 DreamWebEngine::getNumber(const GraphicsFile &charSet, const uint8 *string, uint16 maxWidth, bool centered, uint16* offset) {
|
||||
uint8 totalWidth = 0;
|
||||
uint8 charCount = 0;
|
||||
while (true) {
|
||||
uint8 wordTotalWidth, wordCharCount;
|
||||
uint8 done = getNextWord(charSet, string, &wordTotalWidth, &wordCharCount);
|
||||
string += wordCharCount;
|
||||
|
||||
uint16 tmp = totalWidth + wordTotalWidth - 10;
|
||||
if (done == 1) { //endoftext
|
||||
if (tmp < maxWidth) {
|
||||
totalWidth += wordTotalWidth;
|
||||
charCount += wordCharCount;
|
||||
}
|
||||
|
||||
if (centered) {
|
||||
tmp = (maxWidth & 0xfe) + 2 + 20 - totalWidth;
|
||||
tmp /= 2;
|
||||
} else {
|
||||
tmp = 0;
|
||||
}
|
||||
*offset += tmp;
|
||||
return charCount;
|
||||
}
|
||||
if (tmp >= maxWidth) { //gotoverend
|
||||
if (centered) {
|
||||
tmp = (maxWidth & 0xfe) - totalWidth + 20;
|
||||
tmp /= 2;
|
||||
} else {
|
||||
tmp = 0;
|
||||
}
|
||||
*offset += tmp;
|
||||
return charCount;
|
||||
}
|
||||
totalWidth += wordTotalWidth;
|
||||
charCount += wordCharCount;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 DreamWebEngine::kernChars(uint8 firstChar, uint8 secondChar, uint8 width) {
|
||||
if (getLanguage() == Common::RU_RUS) {
|
||||
if ((firstChar == 'a') || (firstChar == 'u') || (firstChar == 0xa0)
|
||||
|| (firstChar == 0xa8) || (firstChar == 0xa9) || (firstChar == 0xe9)) {
|
||||
if ((secondChar == 0xe2) || (secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l'))
|
||||
return width-1;
|
||||
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
if ((firstChar == 'a') || (firstChar == 'u')) {
|
||||
if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l'))
|
||||
return width-1;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
uint16 DreamWebEngine::waitFrames() {
|
||||
readMouse();
|
||||
showPointer();
|
||||
waitForVSync();
|
||||
dumpPointer();
|
||||
delPointer();
|
||||
return _mouseButton;
|
||||
}
|
||||
|
||||
const char *DreamWebEngine::monPrint(const char *string) {
|
||||
uint16 x = _monAdX;
|
||||
const char *iterator = string;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
|
||||
uint16 count = getNumber(_monitorCharset, (const uint8 *)iterator, 166, false, &x);
|
||||
do {
|
||||
char c = *iterator++;
|
||||
if (c == ':')
|
||||
break;
|
||||
if ((c == 0) || (c == '"') || (c == '=')) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
if (c == '%') {
|
||||
_vars._lastTrigger = *iterator;
|
||||
iterator += 2;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
c = modifyChar(c);
|
||||
printChar(_monitorCharset, &x, _monAdY, c, 0, nullptr, nullptr, true);
|
||||
_cursLocX = x;
|
||||
_cursLocY = _monAdY;
|
||||
_mainTimer = 1;
|
||||
printCurs();
|
||||
waitForVSync();
|
||||
lockMon();
|
||||
delCurs();
|
||||
} while (--count);
|
||||
|
||||
x = _monAdX;
|
||||
scrollMonitor();
|
||||
_cursLocX = _monAdX;
|
||||
}
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
void DreamWebEngine::rollEndCreditsGameWon() {
|
||||
_sound->playChannel0(16, 255);
|
||||
_sound->volumeSet(7);
|
||||
_sound->volumeChange(0, -1);
|
||||
|
||||
multiGet(_mapStore, 75, 20, 160, 160);
|
||||
|
||||
const uint8 *string = getTextInFile1(3);
|
||||
const int linespacing = _lineSpacing;
|
||||
|
||||
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) {
|
||||
waitForVSync();
|
||||
multiPut(_mapStore, 75, 20, 160, 160);
|
||||
waitForVSync();
|
||||
|
||||
// Output up to 18 lines of text
|
||||
uint16 y = 10 - j;
|
||||
const uint8 *tmp_str = string;
|
||||
for (int k = 0; k < 18; ++k) {
|
||||
printDirect(&tmp_str, 75, &y, 160 + 1, true);
|
||||
y += linespacing;
|
||||
}
|
||||
|
||||
waitForVSync();
|
||||
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 DreamWebEngine::rollEndCreditsGameLost() {
|
||||
multiGet(_mapStore, 25, 20, 160, 160);
|
||||
|
||||
const uint8 *string = getTextInFile1(49);
|
||||
const int linespacing = _lineSpacing;
|
||||
|
||||
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) {
|
||||
waitForVSync();
|
||||
multiPut(_mapStore, 25, 20, 160, 160);
|
||||
waitForVSync();
|
||||
|
||||
// Output up to 18 lines of text
|
||||
uint16 y = 10 - j;
|
||||
const uint8 *tmp_str = string;
|
||||
for (int k = 0; k < 18; ++k) {
|
||||
printDirect(&tmp_str, 25, &y, 160 + 1, true);
|
||||
y += linespacing;
|
||||
}
|
||||
|
||||
waitForVSync();
|
||||
multiDump(25, 20, 160, 160);
|
||||
|
||||
if (_lastHardKey == Common::KEYCODE_ESCAPE)
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip to the next text line
|
||||
byte c;
|
||||
do {
|
||||
c = *string++;
|
||||
} while (c != ':' && c != 0);
|
||||
|
||||
if (_lastHardKey == Common::KEYCODE_ESCAPE)
|
||||
return;
|
||||
}
|
||||
|
||||
hangOne(120);
|
||||
}
|
||||
|
||||
} // End of namespace DreamWeb
|
||||
Reference in New Issue
Block a user