/* 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 { void DreamGenContext::printboth(const Frame *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 DreamGenContext::getnextword(const Frame *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 = engine->modifyChar(firstChar); if (firstChar != 255) { uint8 secondChar = *string; uint8 width = charSet[firstChar - 32 + data.word(kCharshift)].width; width = kernchars(firstChar, secondChar, width); *totalWidth += width; } } } void DreamGenContext::printchar() { uint16 x = di; uint8 width, height; printchar((const Frame *)ds.ptr(0, 0), &x, bx, al, ah, &width, &height); di = x; cl = width; ch = height; } void DreamGenContext::printchar(const Frame *charSet, uint16* x, uint16 y, uint8 c, uint8 nextChar, uint8 *width, uint8 *height) { if (c == 255) return; push(si); push(di); if (data.byte(kForeignrelease) != 0) y -= 3; uint16 tmp = c - 32 + data.word(kCharshift); showframe(charSet, *x, y, tmp & 0x1ff, (tmp >> 8) & 0xfe, width, height); di = pop(); si = pop(); _cmp(data.byte(kKerning), 0); if (flags.z()) *width = kernchars(c, nextChar, *width); (*x) += *width; } void DreamGenContext::printslow() { al = printslow(es.ptr(si, 0), di, bx, dl, (bool)(dl & 1)); } uint8 DreamGenContext::printslow(const uint8 *string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { data.byte(kPointerframe) = 1; data.byte(kPointermode) = 3; const Frame* charSet = (const Frame *)segRef(data.word(kCharset1)).ptr(0, 0); do { uint16 offset = x; uint16 charCount = getnumber(charSet, string, maxWidth, centered, &offset); do { uint8 c0 = string[0]; uint8 c1 = string[1]; uint8 c2 = string[2]; c0 = engine->modifyChar(c0); printboth(charSet, &offset, y, c0, c1); if ((c1 == 0) || (c1 == ':')) { return 0; } if (charCount != 1) { c1 = engine->modifyChar(c1); data.word(kCharshift) = 91; uint16 offset2 = offset; printboth(charSet, &offset2, y, c1, c2); data.word(kCharshift) = 0; for (int i=0; i<2; ++i) { uint16 mouseState = waitframes(); if (data.byte(kQuitrequested)) return 0; if (mouseState == 0) continue; if (mouseState != data.word(kOldbutton)) { return 1; } } } ++string; --charCount; } while (charCount); y += 10; } while (true); } void DreamGenContext::printdirect() { uint16 y = bx; uint16 initialSi = si; const uint8 *initialString = es.ptr(si, 0); const uint8 *string = initialString; printdirect(&string, di, &y, dl, (bool)(dl & 1)); si = initialSi + (string - initialString); bx = y; } void DreamGenContext::printdirect(const uint8* string, uint16 x, uint16 y, uint8 maxWidth, bool centered) { printdirect(&string, x, &y, maxWidth, centered); } void DreamGenContext::printdirect(const uint8** string, uint16 x, uint16 *y, uint8 maxWidth, bool centered) { data.word(kLastxpos) = x; const Frame *charSet = (const Frame *)segRef(data.word(kCurrentset)).ptr(0, 0); while (true) { uint16 offset = x; uint8 charCount = getnumber(charSet, *string, maxWidth, centered, &offset); uint16 i = offset; do { uint8 c = (*string)[0]; uint8 nextChar = (*string)[1]; ++(*string); if ((c == 0) || (c == ':')) { return; } c = engine->modifyChar(c); uint8 width, height; printchar(charSet, &i, *y, c, nextChar, &width, &height); data.word(kLastxpos) = i; --charCount; } while(charCount); *y += data.word(kLinespacing); } } void DreamGenContext::getnumber() { uint16 offset = di; cl = getnumber((Frame *)ds.ptr(0, 0), es.ptr(si, 0), dl, (bool)(dl & 1), &offset); di = offset; } uint8 DreamGenContext::getnumber(const Frame *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; if (done == 1) { //endoftext ax = totalWidth + wordTotalWidth - 10; if (ax < maxWidth) { totalWidth += wordTotalWidth; charCount += wordCharCount; } if (centered) { ax = (maxWidth & 0xfe) + 2 + 20 - totalWidth; ax /= 2; } else { ax = 0; } *offset += ax; return charCount; } ax = totalWidth + wordTotalWidth - 10; if (ax >= maxWidth) { //gotoverend if (centered) { ax = (maxWidth & 0xfe) - totalWidth + 20; ax /= 2; } else { ax = 0; } *offset += ax; return charCount; } totalWidth += wordTotalWidth; charCount += wordCharCount; } } uint8 DreamGenContext::kernchars(uint8 firstChar, uint8 secondChar, uint8 width) { if ((firstChar == 'a') || (al == 'u')) { if ((secondChar == 'n') || (secondChar == 't') || (secondChar == 'r') || (secondChar == 'i') || (secondChar == 'l')) return width-1; } return width; } uint16 DreamGenContext::waitframes() { readmouse(); showpointer(); vsync(); dumppointer(); delpointer(); return data.word(kMousebutton); } } /*namespace dreamgen */