Initial commit
This commit is contained in:
399
engines/agos/charset.cpp
Normal file
399
engines/agos/charset.cpp
Normal file
@@ -0,0 +1,399 @@
|
||||
/* 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 "common/system.h"
|
||||
|
||||
#include "agos/agos.h"
|
||||
#include "agos/intern.h"
|
||||
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace AGOS {
|
||||
|
||||
#ifdef ENABLE_AGOS2
|
||||
void AGOSEngine_Feeble::doOutput(const byte *src, uint len) {
|
||||
if (_textWindow == NULL)
|
||||
return;
|
||||
|
||||
while (len-- != 0 && !shouldQuit()) {
|
||||
if (getBitFlag(93)) {
|
||||
if (_curWindow == 3) {
|
||||
if ((_newLines >= _textWindow->scrollY) && (_newLines < (_textWindow->scrollY + 3)))
|
||||
sendWindow(*src);
|
||||
if (*src == '\n') // Do two top lines of text only
|
||||
_newLines++;
|
||||
src++;
|
||||
}
|
||||
} else {
|
||||
if (getBitFlag(94)) {
|
||||
if (_curWindow == 3) {
|
||||
if (_newLines == (_textWindow->scrollY + 7))
|
||||
sendWindow(*src);
|
||||
if (*src == '\n') // Do two top lines of text only
|
||||
_newLines++;
|
||||
src++;
|
||||
}
|
||||
} else {
|
||||
if (getBitFlag(92))
|
||||
delay(50);
|
||||
sendWindow(*src++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void AGOSEngine::doOutput(const byte *src, uint len) {
|
||||
uint idx;
|
||||
|
||||
if (_textWindow == nullptr)
|
||||
return;
|
||||
|
||||
while (len-- != 0) {
|
||||
if (*src != 12 && _textWindow->iconPtr != nullptr &&
|
||||
_fcsData1[idx = getWindowNum(_textWindow)] != 2) {
|
||||
|
||||
_fcsData1[idx] = 2;
|
||||
_fcsData2[idx] = 1;
|
||||
}
|
||||
|
||||
sendWindow(*src++);
|
||||
}
|
||||
}
|
||||
|
||||
void AGOSEngine::clsCheck(WindowBlock *window) {
|
||||
uint index = getWindowNum(window);
|
||||
tidyIconArray(index);
|
||||
_fcsData1[index] = 0;
|
||||
}
|
||||
|
||||
void AGOSEngine::tidyIconArray(uint i) {
|
||||
WindowBlock *window;
|
||||
|
||||
if (_fcsData2[i]) {
|
||||
mouseOff();
|
||||
window = _windowArray[i];
|
||||
drawIconArray(i, window->iconPtr->itemRef, window->iconPtr->line, window->iconPtr->classMask);
|
||||
_fcsData2[i] = 0;
|
||||
mouseOn();
|
||||
}
|
||||
}
|
||||
|
||||
void AGOSEngine::showMessageFormat(const char *s, ...) {
|
||||
char buf[STRINGBUFLEN];
|
||||
char *str;
|
||||
va_list va;
|
||||
|
||||
va_start(va, s);
|
||||
vsnprintf(buf, STRINGBUFLEN, s, va);
|
||||
va_end(va);
|
||||
|
||||
if (!_fcsData1[_curWindow]) {
|
||||
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
|
||||
if (_showMessageFlag) {
|
||||
if (_windowArray[_curWindow]->flags & 128) {
|
||||
haltAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
openTextWindow();
|
||||
if (!_showMessageFlag) {
|
||||
_windowArray[0] = _textWindow;
|
||||
justifyStart();
|
||||
}
|
||||
_showMessageFlag = true;
|
||||
_fcsData1[_curWindow] = 1;
|
||||
}
|
||||
|
||||
for (str = buf; *str; str++)
|
||||
justifyOutPut(*str);
|
||||
}
|
||||
|
||||
void AGOSEngine::justifyStart() {
|
||||
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
||||
_printCharCurPos = _textWindow->textColumn;
|
||||
_printCharMaxPos = _textWindow->width;
|
||||
} else {
|
||||
_printCharCurPos = _textWindow->textLength;
|
||||
_printCharMaxPos = _textWindow->textMaxLength;
|
||||
}
|
||||
_printCharPixelCount = 0;
|
||||
_numLettersToPrint = 0;
|
||||
_newLines = 0;
|
||||
}
|
||||
|
||||
void AGOSEngine::justifyOutPut(byte chr) {
|
||||
if (chr == 12) {
|
||||
_numLettersToPrint = 0;
|
||||
_printCharCurPos = 0;
|
||||
_printCharPixelCount = 0;
|
||||
doOutput(&chr, 1);
|
||||
clsCheck(_textWindow);
|
||||
} else if (getLanguage() == Common::JA_JPN && !_forceAscii) {
|
||||
// Japanese has no word wrapping
|
||||
_lettersToPrintBuf[0] = chr;
|
||||
_lettersToPrintBuf[1] = '\0';
|
||||
doOutput(_lettersToPrintBuf, 1);
|
||||
} else if (chr == 0 || chr == ' ' || chr == 10) {
|
||||
bool fit;
|
||||
|
||||
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
||||
fit = _printCharMaxPos - _printCharCurPos > _printCharPixelCount;
|
||||
} else {
|
||||
fit = _printCharMaxPos - _printCharCurPos >= _printCharPixelCount;
|
||||
}
|
||||
|
||||
if (fit) {
|
||||
_printCharCurPos += _printCharPixelCount;
|
||||
doOutput(_lettersToPrintBuf, _numLettersToPrint);
|
||||
|
||||
if (_printCharCurPos == _printCharMaxPos) {
|
||||
_printCharCurPos = 0;
|
||||
} else {
|
||||
if (chr)
|
||||
doOutput(&chr, 1);
|
||||
if (chr == 10)
|
||||
_printCharCurPos = 0;
|
||||
else if (chr != 0)
|
||||
_printCharCurPos += (getGameType() == GType_FF || getGameType() == GType_PP) ? getFeebleFontSize(chr) : 1;
|
||||
}
|
||||
} else {
|
||||
const byte newline_character = 10;
|
||||
_printCharCurPos = _printCharPixelCount;
|
||||
doOutput(&newline_character, 1);
|
||||
doOutput(_lettersToPrintBuf, _numLettersToPrint);
|
||||
if (chr == ' ') {
|
||||
doOutput(&chr, 1);
|
||||
_printCharCurPos += (getGameType() == GType_FF || getGameType() == GType_PP) ? getFeebleFontSize(chr) : 1;
|
||||
} else {
|
||||
doOutput(&chr, 1);
|
||||
_printCharCurPos = 0;
|
||||
}
|
||||
}
|
||||
_numLettersToPrint = 0;
|
||||
_printCharPixelCount = 0;
|
||||
} else {
|
||||
_lettersToPrintBuf[_numLettersToPrint++] = chr;
|
||||
_printCharPixelCount += (getGameType() == GType_FF || getGameType() == GType_PP) ? getFeebleFontSize(chr) : 1;
|
||||
}
|
||||
}
|
||||
|
||||
void AGOSEngine::openTextWindow() {
|
||||
if (_textWindow) {
|
||||
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
|
||||
if (_textWindow->flags & 0x80)
|
||||
clearWindow(_textWindow);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (getGameType() == GType_FF || getGameType() == GType_PP)
|
||||
_textWindow = openWindow(64, 96, 384, 172, 1, 0, 15);
|
||||
else
|
||||
_textWindow = openWindow(8, 144, 24, 6, 1, 0, 15);
|
||||
}
|
||||
|
||||
void AGOSEngine_PN::windowPutChar(WindowBlock *window, byte c, byte b) {
|
||||
if (_mousePrintFG || _wiped)
|
||||
return;
|
||||
AGOSEngine::windowPutChar(window, c, b);
|
||||
}
|
||||
|
||||
void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) {
|
||||
byte width = 6;
|
||||
byte textColumnWidth = 8;
|
||||
|
||||
if (c == 12) {
|
||||
clearWindow(window);
|
||||
} else if (c == 13 || c == 10) {
|
||||
windowNewLine(window);
|
||||
} else if ((c == 1 && _language != Common::HE_ISR) || (c == 8)) {
|
||||
if (_language == Common::HE_ISR) {
|
||||
if (b >= 64 && b < 91)
|
||||
width = _hebrewCharWidths [b - 64];
|
||||
|
||||
if (window->textLength != 0) {
|
||||
window->textLength--;
|
||||
window->textColumnOffset += width;
|
||||
if (window->textColumnOffset >= 8) {
|
||||
window->textColumnOffset -= 8;
|
||||
window->textColumn--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int8 val = (c == 8) ? 6 : 4;
|
||||
|
||||
if (window->textLength != 0) {
|
||||
window->textLength--;
|
||||
window->textColumnOffset -= val;
|
||||
if ((int8)window->textColumnOffset < val) {
|
||||
window->textColumnOffset += 8;
|
||||
window->textColumn--;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (c >= 32) {
|
||||
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
||||
// Ignore invalid characters
|
||||
if (c - 32 > 195)
|
||||
return;
|
||||
|
||||
windowDrawChar(window, window->textColumn + window->x, window->textRow + window->y, c);
|
||||
window->textColumn += getFeebleFontSize(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_language == Common::JA_JPN && !_forceAscii)
|
||||
textColumnWidth = width = 4;
|
||||
else if (c - 32 > 98) // Ignore invalid characters
|
||||
return;
|
||||
|
||||
if (window->textLength == window->textMaxLength) {
|
||||
windowNewLine(window);
|
||||
} else if (window->textRow == window->height) {
|
||||
windowNewLine(window);
|
||||
window->textRow--;
|
||||
}
|
||||
|
||||
if (_language == Common::HE_ISR) {
|
||||
if (c >= 64 && c < 91)
|
||||
width = _hebrewCharWidths [c - 64];
|
||||
window->textColumnOffset -= width;
|
||||
if (window->textColumnOffset >= width) {
|
||||
window->textColumnOffset += 8;
|
||||
window->textColumn++;
|
||||
}
|
||||
windowDrawChar(window, (window->width + window->x - window->textColumn) * 8, window->textRow * 8 + window->y, c);
|
||||
window->textLength++;
|
||||
} else {
|
||||
windowDrawChar(window, window->x * 8 + window->textColumn * textColumnWidth, window->textRow * 8 + window->y, c);
|
||||
window->textLength++;
|
||||
window->textColumnOffset += width;
|
||||
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
||||
if (c == 'i' || c == 'l')
|
||||
window->textColumnOffset -= 2;
|
||||
}
|
||||
if (window->textColumnOffset >= textColumnWidth) {
|
||||
window->textColumnOffset -= textColumnWidth;
|
||||
window->textColumn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AGOS2
|
||||
void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {
|
||||
if (_noOracleScroll == 0) {
|
||||
if (window->height < window->textRow + 30) {
|
||||
if (!getBitFlag(94)) {
|
||||
_noOracleScroll = 1;
|
||||
if (getBitFlag(92)) {
|
||||
_noOracleScroll = 0;
|
||||
checkLinkBox();
|
||||
scrollOracle();
|
||||
linksUp();
|
||||
window->scrollY++;
|
||||
_oracleMaxScrollY++;
|
||||
} else {
|
||||
_oracleMaxScrollY++;
|
||||
checkLinkBox();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
window->textRow += 15;
|
||||
checkLinkBox();
|
||||
}
|
||||
} else {
|
||||
_oracleMaxScrollY++;
|
||||
checkLinkBox();
|
||||
}
|
||||
|
||||
window->textColumn = 0;
|
||||
window->textColumnOffset = 0;
|
||||
window->textLength = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void AGOSEngine::windowNewLine(WindowBlock *window) {
|
||||
window->textColumn = 0;
|
||||
window->textColumnOffset = (getGameType() == GType_ELVIRA2) ? 4 : 0;
|
||||
window->textLength = 0;
|
||||
|
||||
if (getGameType() == GType_PN) {
|
||||
window->textRow++;
|
||||
if (window->textRow == window->height) {
|
||||
windowScroll(window);
|
||||
window->textRow--;
|
||||
}
|
||||
} else {
|
||||
if (window->textRow == window->height) {
|
||||
if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 ||
|
||||
getGameType() == GType_WW) {
|
||||
windowScroll(window);
|
||||
}
|
||||
} else {
|
||||
window->textRow++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AGOSEngine::windowScroll(WindowBlock *window) {
|
||||
_videoLockOut |= 0x8000;
|
||||
|
||||
if (window->height != 1) {
|
||||
Graphics::Surface *screen = getBackendSurface();
|
||||
|
||||
byte *src, *dst;
|
||||
uint16 w1, h1, w2, h2;
|
||||
|
||||
w1 = w2 = window->width * 8;
|
||||
h1 = h2 = (window->height -1) * 8;
|
||||
|
||||
dst = (byte *)screen->getBasePtr(window->x * 8, window->y);
|
||||
src = dst + 8 * screen->pitch;
|
||||
|
||||
do {
|
||||
memcpy(dst, src, w1);
|
||||
src += screen->pitch;
|
||||
dst += screen->pitch;
|
||||
} while (--h1);
|
||||
|
||||
if (getGameId() == GID_ELVIRA1 && getPlatform() == Common::kPlatformPC98) {
|
||||
w1 = w2 << 1;
|
||||
h1 = h2 << 1;
|
||||
dst = (byte *)_scaleBuf->getBasePtr(window->x * 16, window->y * 2);
|
||||
src = dst + 16 * screen->pitch;
|
||||
do {
|
||||
memcpy(dst, src, w1);
|
||||
src += screen->pitch;
|
||||
dst += screen->pitch;
|
||||
} while (--h1);
|
||||
}
|
||||
|
||||
Common::Rect dirtyRect(window->x * 8, window->y, window->x * 8 + w2, window->y + h2);
|
||||
updateBackendSurface(&dirtyRect);
|
||||
}
|
||||
|
||||
colorBlock(window, window->x * 8, (window->height - 1) * 8 + window->y, window->width * 8, 8);
|
||||
|
||||
_videoLockOut &= ~0x8000;
|
||||
}
|
||||
} // End of namespace AGOS
|
||||
Reference in New Issue
Block a user