aboutsummaryrefslogtreecommitdiff
path: root/kyra
diff options
context:
space:
mode:
authorGregory Montoir2005-09-08 19:09:52 +0000
committerGregory Montoir2005-09-08 19:09:52 +0000
commit53a884dc17ed6ef4b5f827629f735fa21544bbf5 (patch)
tree22ce8f134d3b178a964233c2c92bc5a3722a7789 /kyra
parentb17c47f74a04865a2e88acd2585a43717ab372d4 (diff)
downloadscummvm-rg350-53a884dc17ed6ef4b5f827629f735fa21544bbf5.tar.gz
scummvm-rg350-53a884dc17ed6ef4b5f827629f735fa21544bbf5.tar.bz2
scummvm-rg350-53a884dc17ed6ef4b5f827629f735fa21544bbf5.zip
some WIP code, moved Font stuff to Screen class
svn-id: r18790
Diffstat (limited to 'kyra')
-rw-r--r--kyra/cpsimage.cpp189
-rw-r--r--kyra/font.cpp337
-rw-r--r--kyra/kyra.cpp194
-rw-r--r--kyra/kyra.h19
-rw-r--r--kyra/module.mk3
-rw-r--r--kyra/palette.cpp57
-rw-r--r--kyra/resource.cpp26
-rw-r--r--kyra/resource.h106
-rw-r--r--kyra/screen.cpp251
-rw-r--r--kyra/screen.h68
-rw-r--r--kyra/staticres.cpp2
11 files changed, 442 insertions, 810 deletions
diff --git a/kyra/cpsimage.cpp b/kyra/cpsimage.cpp
deleted file mode 100644
index db4df6ea1b..0000000000
--- a/kyra/cpsimage.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2005 The ScummVM project
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/stream.h"
-#include "kyra/resource.h"
-#include "kyra/screen.h"
-
-namespace Kyra {
-
-struct CPSResource {
- uint32 size;
- uint16 width;
-};
-
-static const CPSResource CPSResourceTable[] = {
- { 64000, 320 }, { 7740, 180 }, { 46080, 320 }, { 0, 0 }
-};
-
-static int16 getWidthFromCPSRes(uint32 size) {
- int16 c = 0;
-
- for (; CPSResourceTable[c].size; ++c) {
- if (CPSResourceTable[c].size == size)
- return CPSResourceTable[c].width;
- }
-
- return -1;
-}
-
-CPSImage::CPSImage(uint8* buffer, uint32 size) {
- if (!buffer) {
- error("resource created without data");
- }
- _ownPalette = 0;
- Common::MemoryReadStream bufferstream(buffer, size);
-
- // reads in the Header
- _cpsHeader._filesize = bufferstream.readUint16LE() + 2;
- _cpsHeader._format = bufferstream.readUint16LE();
- _cpsHeader._imagesize = bufferstream.readUint16LE();
- _cpsHeader._pal = bufferstream.readUint32LE();
-
- // lets check a bit
- if (_cpsHeader._pal == 0x3000000) {
- // if this was a compressed palette you should have strange graphics
-
- uint8* palbuffer = new uint8[768];
- assert(palbuffer);
-
- bufferstream.read(palbuffer, 768 * sizeof(uint8));
-
- _ownPalette = new Palette(palbuffer, 768);
- assert(palbuffer);
- }
-
- _image = new uint8[_cpsHeader._imagesize];
- assert(_image);
-
- uint8* imagebuffer = &buffer[bufferstream.pos()];
- assert(imagebuffer);
- switch (_cpsHeader._format) {
- case 0:
- memcpy(_image, imagebuffer, _cpsHeader._imagesize);
- break;
- case 3:
- Screen::decodeFrame3(imagebuffer, _image, _cpsHeader._imagesize);
- break;
- case 4:
- Screen::decodeFrame4(imagebuffer, _image, _cpsHeader._imagesize);
- break;
- default:
- break;
- }
-
- int16 width = getWidthFromCPSRes(_cpsHeader._imagesize);
-
- if (width == -1) {
- warning("unknown CPS width(imagesize: %d)", _cpsHeader._imagesize);
- delete [] buffer;
- return;
- }
-
- _width = (uint16)width;
- _height = _cpsHeader._imagesize / _width;
-
- _transparency = -1;
-
- delete [] buffer;
-}
-
-CPSImage::~CPSImage() {
- delete [] _image;
- delete _ownPalette;
-}
-
-void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y) {
- uint8* src = _image;
- uint8* dst = &plane[y * planepitch + x];
- uint32 copysize = planepitch - x;
-
- if (copysize > _width)
- copysize = _width;
-
- if (_transparency == -1) {
- // 'fast' blitting
- for (uint16 y_ = 0; y_ < _height && y + y_ < planeheight; ++y_) {
- memcpy(dst, src, copysize * sizeof(uint8));
- dst += planepitch;
- src += _width;
- }
-
- } else {
- // oh no! we have transparency so we have a very slow copy :/
-
- for (uint16 yadd = 0; yadd < _height; ++yadd) {
- for (uint16 xadd = 0; xadd < copysize; ++xadd) {
- if (*src == _transparency) {
- ++dst;
- ++src;
- } else {
- *dst++ = *src++;
- }
- }
-
- src += _width - copysize;
- dst += planepitch - copysize;
- }
- }
-}
-
-void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
- uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight) {
- uint8* src = &_image[srcy * _width + srcx];
- uint8* dst = &plane[y * planepitch + x];
- uint32 copysize = planepitch - x;
-
- if (srcwidth > _width)
- srcwidth = _width;
-
- if (copysize > srcwidth)
- copysize = srcwidth;
-
- if (_transparency == -1) {
- // 'fast' blitting
- for (uint16 y_ = 0; y_ < srcheight && y + y_ < planeheight; ++y_) {
- memcpy(dst, src, copysize * sizeof(uint8));
- dst += planepitch;
- src += _width;
- }
-
- } else {
- // oh no! we have transparency so we have a very slow copy :/
-
- for (uint16 yadd = 0; yadd < srcheight; ++yadd) {
- for (uint16 xadd = 0; xadd < copysize; ++xadd) {
- if (*src == _transparency) {
- ++dst;
- ++src;
- } else {
- *dst++ = *src++;
- }
- }
-
- dst += planepitch - copysize;
- src += _width - copysize;
- }
- }
-}
-
-} // end of namespace Kyra
diff --git a/kyra/font.cpp b/kyra/font.cpp
deleted file mode 100644
index 6651ba0011..0000000000
--- a/kyra/font.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2005 The ScummVM project
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/stream.h"
-#include "common/array.h"
-#include "kyra/resource.h"
-
-#ifdef DUMP_FILES
-#include <cstdio>
-#endif
-
-namespace Kyra {
-const uint16 FontHeader_Magic1 = 0x0500;
-const uint16 FontHeader_Magic2 = 0x000e;
-const uint16 FontHeader_Magic3 = 0x0014;
-
-Font::Font(uint8* buffer, uint32 size) {
- if (!buffer) {
- error("resource created without data");
- }
-
- _buffer = buffer;
-
- Common::MemoryReadStream bufferstream(buffer, size);
-
- _fontHeader._size = bufferstream.readUint16LE();
- _fontHeader._magic1 = bufferstream.readUint16LE();
- _fontHeader._magic2 = bufferstream.readUint16LE();
- _fontHeader._magic3 = bufferstream.readUint16LE();
- _fontHeader._charWidthOffset = bufferstream.readUint16LE();
- _fontHeader._charBitsOffset = bufferstream.readUint16LE();
- _fontHeader._charHeightOffset = bufferstream.readUint16LE();
- _fontHeader._version = bufferstream.readUint16LE();
- _fontHeader._countChars = bufferstream.readUint16LE();
- _fontHeader._width = bufferstream.readByte();
- _fontHeader._height = bufferstream.readByte();
-
- // tests for the magic values
- if (_fontHeader._magic1 != FontHeader_Magic1 || _fontHeader._magic2 != FontHeader_Magic2 ||
- _fontHeader._magic3 != FontHeader_Magic3) {
- error("magic vars in the fontheader are corrupt\n"
- "_magic1 = 0x%x, _magic2 = 0x%x, _magic3 = 0x%x",
- _fontHeader._magic1, _fontHeader._magic2, _fontHeader._magic3);
- }
-
- // init all the pointers
- _offsetTable = (uint16*)&buffer[bufferstream.pos()];
- _charWidth = &buffer[_fontHeader._charWidthOffset];
- _charHeight = (uint16*)&buffer[_fontHeader._charHeightOffset];
- _charBits = &buffer[_fontHeader._charBitsOffset];
-
- // now prerender =)
- preRenderAllChars(bufferstream.pos());
-
- // This value seems to be a version or language variable
- // Known Values
- // ------------
- // Russian Floppy: 0x1010
- // German Floppy and English/German CD: 0x1011
- debug("Font::_version = 0x%x", _fontHeader._version);
-
- delete [] _buffer;
- _buffer = 0;
- _offsetTable = 0;
- _charHeight = 0;
- _charWidth = 0;
- _charBits = 0;
-}
-
-Font::~Font() {
- // FIXME: Release memory of the prerendered chars
-}
-
-uint32 Font::getStringWidth(const char* string, char terminator) {
- uint32 strsize;
-
- for (strsize = 0; string[strsize] != terminator && string[strsize] != '\0'; ++strsize)
- ;
-
- uint32 stringwidth = 0;
-
- for (uint32 pos = 0; pos < strsize; ++pos) {
- stringwidth += _preRenderedChars[string[pos]].width;
- }
-
- return stringwidth;
-}
-
-const uint8* Font::getChar(char c, uint8* width, uint8* height, uint8* heightadd) {
- PreRenderedChar& c_ = _preRenderedChars[c];
-
- *width = c_.width;
- *height = c_.height;
- *heightadd = c_.heightadd;
-
- return c_.c;
-}
-
-// splits up the String in a word
-const char* Font::getNextWord(const char* string, uint32* size) {
- uint32 startpos = 0;
- *size = 0;
-
- // gets start of the word
- for (; string[startpos] == ' '; ++startpos)
- ;
-
- // not counting size
- for (*size = 0; string[startpos + *size] != ' ' && string[startpos + *size] != '\0'; ++(*size))
- ;
-
- ++(*size);
-
- return &string[startpos];
-}
-
-// Move this to Font declaration?
-struct WordChunk {
- const char* _string;
- uint32 _size;
-};
-
-void Font::drawStringToPlane(const char* string,
- uint8* plane, uint16 planewidth, uint16 planeheight,
- uint16 x, uint16 y, uint8 color) {
-
- // lets do it word after word
- Common::Array<WordChunk> words;
-
- uint32 lastPos = 0;
- uint32 lastSize = 0;
- uint32 strlgt = strlen(string);
-
- while (true) {
- WordChunk newchunk;
- newchunk._string = getNextWord(&string[lastPos], &lastSize);
- newchunk._size = lastSize;
- lastPos += lastSize;
-
- words.push_back(newchunk);
-
- if (lastPos >= strlgt)
- break;
- }
-
- uint16 current_x = x, current_y = y;
- uint8 heighest = 0;
-
- const uint8* src = 0;
- uint8 width = 0, height = 0, heightadd = 0;
-
- // now the have alle of these words
- for (uint32 tmp = 0; tmp < words.size(); ++tmp) {
- lastSize = getStringWidth(words[tmp]._string, ' ');
-
- // adjust x position
- if (current_x + lastSize >= planewidth) {
- // hmm lets move it a bit to the left
- if (current_x == x && (int16)planewidth - (int16)lastSize >= 0) {
- current_x = planewidth - lastSize;
- } else {
- current_x = x;
- if (heighest)
- current_y += heighest + 2;
- else // now we are using just the fist char :)
- current_y += _preRenderedChars[words[tmp]._string[0]].height;
- heighest = 0;
- }
- }
-
- // TODO: maybe test if current_y >= planeheight ?
-
- // output word :)
- for (lastPos = 0; lastPos < words[tmp]._size; ++lastPos) {
- if (words[tmp]._string[lastPos] == '\0')
- break;
-
- // gets our char :)
- src = getChar(words[tmp]._string[lastPos], &width, &height, &heightadd);
-
- // lets draw our char
- drawCharToPlane(src, color, width, height, plane, planewidth, planeheight, current_x, current_y + heightadd);
-
- current_x += width;
- heighest = MAX(heighest, height);
- }
- }
-}
-
-void Font::drawCharToPlane(const uint8* c, uint8 color, uint8 width, uint8 height,
- uint8* plane, uint16 planewidth, uint16 planeheight, uint16 x, uint16 y) {
- const uint8* src = c;
-
- // blit them to the screen
- for (uint8 yadd = 0; yadd < height; ++yadd) {
- for (uint8 xadd = 0; xadd < width; ++xadd) {
- switch(*src) {
- case 1:
- plane[(y + yadd) * planewidth + x + xadd] = color;
- break;
-
- case 2:
- plane[(y + yadd) * planewidth + x + xadd] = 14;
- break;
-
- case 3:
- plane[(y + yadd) * planewidth + x + xadd] = 0;
- break;
-
- default:
- // nothing to do now
- break;
- };
-
- ++src;
- }
- }
-}
-
-void Font::preRenderAllChars(uint16 offsetTableOffset) {
- uint16 startOffset = _offsetTable[0];
- uint16 currentOffset = offsetTableOffset;
- uint8 currentChar = 0;
-
- for (; currentOffset < startOffset; ++currentChar, currentOffset += sizeof(uint16)) {
- // lets prerender the char :)
-
- PreRenderedChar newChar;
-
- newChar.height = READ_LE_UINT16(&_charHeight[currentChar]) >> 8;
- newChar.width = _charWidth[currentChar];
- newChar.heightadd = READ_LE_UINT16(&_charHeight[currentChar]) & 0xFF;
- newChar.c = new uint8[newChar.height * newChar.width];
- assert(newChar.c);
- memset(newChar.c, 0, sizeof(uint8) * newChar.height * newChar.width);
-
- uint8* src = _buffer + READ_LE_UINT16(&_offsetTable[currentChar]);
- uint8* dst = &newChar.c[0];
- uint8 index = 0;
-
-#ifdef DUMP_FILES
- static char filename[32] = { 0 };
- sprintf(filename, "dumps/char%d.dmp", currentChar);
- FILE* dump = fopen(filename, "w+");
- assert(dump);
-
- fprintf(dump, "This should be a '%c'\n", currentChar);
-#endif
-
- // prerender the char
- for (uint8 yadd = 0; yadd < newChar.height; ++yadd) {
- for (uint8 xadd = 0; xadd < newChar.width; ++xadd) {
- if (xadd % 2) {
- index = ((*src) & 0xF0) >> 4;
- ++src;
- } else {
- index = (*src) & 0x0F;
- }
-
- switch(index) {
- case 1:
-#ifdef DUMP_FILES
- fprintf(dump, "#");
-#endif
- dst[yadd * newChar.width + xadd] = 1;
- break;
-
- case 2:
-#ifdef DUMP_FILES
- fprintf(dump, "$");
-#endif
- dst[yadd * newChar.width + xadd] = 2;
- break;
-
- case 3:
-#ifdef DUMP_FILES
- fprintf(dump, "\xA7");
-#endif
- dst[yadd * newChar.width + xadd] = 3;
- break;
-
- default:
-#ifdef DUMP_FILES
- fprintf(dump, "%d", index);
-#endif
- break;
- };
- }
-
- if (newChar.width % 2) {
- ++src;
- }
-#ifdef DUMP_FILES
- fprintf(dump, "\n");
-#endif
- }
-
-#ifdef DUMP_FILES
- fprintf(dump, "\nThis is the created map:\n");
- // now print the whole thing again
- for (uint8 yadd = 0; yadd < newChar.height; ++yadd) {
- for (uint8 xadd = 0; xadd < newChar.width; ++xadd) {
- fprintf(dump, "%d", dst[yadd * newChar.width + xadd]);
- }
- fprintf(dump, "\n");
- }
- fclose(dump);
-#endif
-
- _preRenderedChars[currentChar] = newChar;
-
- if (currentChar == 255) {
- break;
- }
- }
-}
-} // end of namespace Kyra
-
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp
index 3f3d616a95..aba3362f68 100644
--- a/kyra/kyra.cpp
+++ b/kyra/kyra.cpp
@@ -184,6 +184,9 @@ void KyraEngine::errorString(const char *buf1, char *buf2) {
int KyraEngine::go() {
_quitFlag = false;
+ uint32 sz;
+ _screen->loadFont(Screen::FID_6_FNT, _res->fileData("6.FNT", &sz));
+ _screen->loadFont(Screen::FID_8_FNT, _res->fileData("8FAT.FNT", &sz));
_screen->setScreenDim(0);
seq_intro();
return 0;
@@ -225,21 +228,38 @@ void KyraEngine::setTalkCoords(uint16 y) {
int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
- warning("KyraEngine::getCenterStringX() UNIMPLEMENTED");
- return 0;
+ _screen->_charWidth = -2;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ int strWidth = _screen->getTextWidth(str);
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ int w = x2 - x1 + 1;
+ return x1 + (w - strWidth) / 2;
}
int KyraEngine::getCharLength(const char *str, int len) {
debug(9, "KyraEngine::preprocessString('%s', %d)", str, len);
- warning("KyraEngine::preprocessString() UNIMPLEMENTED");
- return 0;
+ debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
+ int charsCount = 0;
+ if (*str) {
+ _screen->_charWidth = -2;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ int i = 0;
+ while (i <= len && *str) {
+ i += _screen->getCharWidth(*str++);
+ ++charsCount;
+ }
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ }
+ return charsCount;
}
int KyraEngine::dropCRIntoString(char *str, int offs) {
debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
int pos = 0;
while (*str) {
- if (*str == 0x20) {
+ if (*str == ' ') {
*str = 0xD;
return pos;
}
@@ -251,8 +271,37 @@ int KyraEngine::dropCRIntoString(char *str, int offs) {
char *KyraEngine::preprocessString(const char *str) {
debug(9, "KyraEngine::preprocessString('%s')", str);
- warning("KyraEngine::preprocessString() UNIMPLEMENTED");
- return 0;
+ assert(strlen(str) < sizeof(_talkBuffer) - 1);
+ strcpy(_talkBuffer, str);
+ char *p = _talkBuffer;
+ while (*p) {
+ if (*p == 0xD) {
+ return _talkBuffer;
+ }
+ ++p;
+ }
+ p = _talkBuffer;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ int textWidth = _screen->getTextWidth(p);
+ _screen->_charWidth = 0;
+ if (textWidth > 176) {
+ if (textWidth > 352) {
+ int count = getCharLength(p, textWidth / 3);
+ int offs = dropCRIntoString(p, count);
+ p += count + offs;
+ _screen->_charWidth = -2;
+ textWidth = _screen->getTextWidth(p);
+ _screen->_charWidth = 0;
+ count = getCharLength(p, textWidth / 2);
+ dropCRIntoString(p, count);
+ } else {
+ int count = getCharLength(p, textWidth / 2);
+ dropCRIntoString(p, count);
+ }
+ }
+ _screen->setFont(curFont);
+ return _talkBuffer;
}
int KyraEngine::buildMessageSubstrings(const char *str) {
@@ -261,26 +310,37 @@ int KyraEngine::buildMessageSubstrings(const char *str) {
int pos = 0;
while (*str) {
if (*str == 0xD) {
- _talkSubstrings[currentLine * 80 + pos] = 0;
+ assert(currentLine < TALK_SUBSTRING_NUM);
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = 0;
++currentLine;
pos = 0;
} else {
- _talkSubstrings[currentLine * 80 + pos] = *str;
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
++pos;
- if (pos > 78) {
- pos = 78;
+ if (pos > TALK_SUBSTRING_LEN - 2) {
+ pos = TALK_SUBSTRING_LEN - 2;
}
}
++str;
}
- _talkSubstrings[currentLine * 80 + pos] = '\0';
+ _talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
return currentLine + 1;
}
int KyraEngine::getWidestLineWidth(int linesCount) {
debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
- warning("KyraEngine::getWidestLineWidth() UNIMPLEMENTED");
- return 0;
+ int maxWidth = 0;
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+ _screen->_charWidth = -2;
+ for (int l = 0; l < linesCount; ++l) {
+ int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
+ if (maxWidth < w) {
+ maxWidth = w;
+ }
+ }
+ _screen->setFont(curFont);
+ _screen->_charWidth = 0;
+ return maxWidth;
}
void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
@@ -304,7 +364,29 @@ void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
- warning("KyraEngine::printTalkTextMessage() UNIMPLEMENTED");
+ char *str = preprocessString(text);
+ int lineCount = buildMessageSubstrings(str);
+ int top = y - lineCount * 10;
+ if (top < 0) {
+ top = 0;
+ }
+ _talkMessageY = top;
+ _talkMessageH = lineCount * 10;
+ int w = getWidestLineWidth(lineCount);
+ int x1, x2;
+ calcWidestLineBounds(x1, x2, w, x);
+ _talkCoords.x = x1;
+ _talkCoords.w = w + 2;
+ _screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
+ int curPage = _screen->_curPage;
+ _screen->_curPage = srcPage;
+ for (int i = 0; i < lineCount; ++i) {
+ top = i * 10 + _talkMessageY;
+ char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
+ int left = getCenterStringX(msg, x1, x2);
+ printText(msg, left, top, color, 0xC, 0);
+ }
+ _screen->_curPage = curPage;
_talkMessagePrinted = true;
}
@@ -312,11 +394,11 @@ void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, ui
uint8 colorMap[] = { 0, 15, 12, 12 };
colorMap[3] = c1;
_screen->setTextColor(colorMap, 0, 3);
-// const uint8 *currentFont = _screen->setupFont(_res->_8fat_fnt);
+ Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
_screen->_charWidth = -2;
_screen->printText(str, x, y, c0, c2);
_screen->_charWidth = 0;
-// _screen->setupFont(currentFont);
+ _screen->setFont(curFont);
}
void KyraEngine::waitTicks(int ticks) {
@@ -346,45 +428,32 @@ void KyraEngine::waitTicks(int ticks) {
void KyraEngine::seq_intro() {
debug(9, "KyraEngine::seq_intro()");
+ static const IntroProc introProcTable[] = {
+ &KyraEngine::seq_introLogos,
+// &KyraEngine::seq_introStory,
+ &KyraEngine::seq_introMalcomTree,
+ &KyraEngine::seq_introKallakWriting,
+ &KyraEngine::seq_introKallakMalcom
+ };
_skipIntroFlag = true; // only true if user already played the game once
_seq_copyViewOffs = 1;
-
+ _screen->setFont(Screen::FID_8_FNT);
// snd_kyraPlayTheme(0);
setTalkCoords(0x90);
-
- memset(_screen->_palette1, 0, 768);
- _screen->setScreenPalette(_screen->_palette1);
-
- seq_introLogos();
- if (!seq_skipSequence()) {
-// loadBitmap("MAIN_ENG.CPS", 3, 3, 0);
- _screen->clearPage(0); // XXX
- if (!seq_skipSequence()) {
- _screen->_curPage = 0;
- _screen->clearPage(3);
- seq_playSpecialSequence(_seq_introData_MalcomTree, true);
- seq_makeHandShapes();
- uint8 *p = (uint8 *)malloc(5060);
- _screen->setAnimBlockPtr(p, 5060);
- _screen->_charWidth = -2;
- _screen->clearPage(3);
- seq_playSpecialSequence(_seq_introData_KallakWriting, true);
- free(p);
- seq_freeHandShapes();
- _screen->clearPage(3);
- seq_playSpecialSequence(_seq_introData_KallakMalcom, true);
- setTalkCoords(0x88);
- waitTicks(0x1E);
- _seq_copyViewOffs = 0;
- }
+ _screen->setScreenPalette(_screen->_currentPalette);
+ for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) {
+ (this->*introProcTable[i])();
}
+ setTalkCoords(0x88);
+ waitTicks(0x1E);
+ _seq_copyViewOffs = 0;
}
void KyraEngine::seq_introLogos() {
debug(9, "KyraEngine::seq_introLogos()");
_screen->clearPage(0);
- loadBitmap("TOP.CPS", 7, 7, _screen->_palette1);
- loadBitmap("BOTTOM.CPS", 5, 5, _screen->_palette1);
+ loadBitmap("TOP.CPS", 7, 7, _screen->_currentPalette);
+ loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
_screen->_curPage = 0;
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
@@ -427,6 +496,37 @@ void KyraEngine::seq_introLogos() {
seq_playSpecialSequence(_seq_introData_Forest, true);
}
+void KyraEngine::seq_introStory() {
+ debug(9, "KyraEngine::seq_introStory()");
+// loadBitmap("MAIN_ENG.CPS", 3, 3, 0);
+ _screen->clearPage(0); // XXX
+}
+
+void KyraEngine::seq_introMalcomTree() {
+ debug(9, "KyraEngine::seq_introMalcomTree()");
+ _screen->_curPage = 0;
+ _screen->clearPage(3);
+ seq_playSpecialSequence(_seq_introData_MalcomTree, true);
+}
+
+void KyraEngine::seq_introKallakWriting() {
+ debug(9, "KyraEngine::seq_introKallakWriting()");
+ seq_makeHandShapes();
+ uint8 *p = (uint8 *)malloc(5060);
+ _screen->setAnimBlockPtr(p, 5060);
+ _screen->_charWidth = -2;
+ _screen->clearPage(3);
+ seq_playSpecialSequence(_seq_introData_KallakWriting, true);
+ free(p);
+ seq_freeHandShapes();
+}
+
+void KyraEngine::seq_introKallakMalcom() {
+ debug(9, "KyraEngine::seq_introKallakMalcom()");
+ _screen->clearPage(3);
+ seq_playSpecialSequence(_seq_introData_KallakMalcom, true);
+}
+
uint8 *KyraEngine::seq_setPanPages(int pageNum, int shape) {
debug(9, "KyraEngine::seq_setPanPages(%d, %d)", pageNum, shape);
uint8 *panPage = 0;
@@ -652,7 +752,7 @@ bool KyraEngine::seq_playSpecialSequence(const uint8 *seqData, bool skipSeq) {
uint8 colNum = *seqData++;
uint32 fileSize;
uint8 *srcData = _res->fileData(_seq_COLTable[colNum], &fileSize);
- memcpy(_screen->_palette1, srcData, fileSize);
+ memcpy(_screen->_currentPalette, srcData, fileSize);
delete[] srcData;
}
break;
diff --git a/kyra/kyra.h b/kyra/kyra.h
index ab0a759b17..b6d972e7b4 100644
--- a/kyra/kyra.h
+++ b/kyra/kyra.h
@@ -62,6 +62,11 @@ class Screen;
class KyraEngine : public Engine {
public:
+ enum {
+ TALK_SUBSTRING_LEN = 80,
+ TALK_SUBSTRING_NUM = 3
+ };
+
KyraEngine(GameDetector *detector, OSystem *system);
~KyraEngine();
@@ -74,6 +79,8 @@ public:
Common::RandomSource _rnd;
+ typedef void (KyraEngine::*IntroProc)();
+
protected:
int go();
@@ -96,6 +103,10 @@ protected:
void seq_intro();
void seq_introLogos();
+ void seq_introStory();
+ void seq_introMalcomTree();
+ void seq_introKallakWriting();
+ void seq_introKallakMalcom();
uint8 *seq_setPanPages(int pageNum, int shape);
void seq_makeHandShapes();
void seq_freeHandShapes();
@@ -113,7 +124,8 @@ protected:
bool _fastMode;
bool _quitFlag;
bool _skipIntroFlag;
- char _talkSubstrings[80 * 3];
+ char _talkBuffer[300];
+ char _talkSubstrings[TALK_SUBSTRING_LEN * TALK_SUBSTRING_NUM];
TalkCoords _talkCoords;
uint16 _talkMessageY;
uint16 _talkMessageH;
@@ -123,10 +135,11 @@ protected:
uint8 *_seq_handShapes[3];
uint8 *_seq_specialSequenceTempBuffer;
- MusicPlayer *_midi;
Resource *_res;
Screen *_screen;
-
+ MusicPlayer *_midi;
+
+ // these tables are specific to the floppy version
static const uint8 _seq_introData_Forest[];
static const uint8 _seq_introData_KallakWriting[];
static const uint8 _seq_introData_KyrandiaLogo[];
diff --git a/kyra/module.mk b/kyra/module.mk
index 96b84702ad..fb5e0dd487 100644
--- a/kyra/module.mk
+++ b/kyra/module.mk
@@ -1,10 +1,7 @@
MODULE := kyra
MODULE_OBJS := \
- kyra/cpsimage.o \
- kyra/font.o \
kyra/kyra.o \
- kyra/palette.o \
kyra/resource.o \
kyra/screen.o \
kyra/script_v1.o \
diff --git a/kyra/palette.cpp b/kyra/palette.cpp
deleted file mode 100644
index 65de51e652..0000000000
--- a/kyra/palette.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2004-2005 The ScummVM project
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include "common/stdafx.h"
-#include "common/stream.h"
-#include "kyra/resource.h"
-#include "kyra/screen.h"
-
-namespace Kyra {
-
-Palette::Palette(uint8* data, uint32 size) {
- if (!data) {
- error("resource created without data");
- }
-
- if (size != 768) {
- Common::MemoryReadStream datastream(data, size);
-
- datastream.readSint32LE();
- int imageSize = datastream.readSint16LE();
-
- if (imageSize != 768) {
- error("decompresed palette is not 768 byte long!");
- }
-
- // lets uncompress this palette :)
- _palette = new uint8[imageSize];
- assert(_palette);
-
- // made decompression
- Screen::decodeFrame4(data + 10, _palette, imageSize);
- delete [] data;
- } else {
- _palette = data;
- }
-}
-
-} // end of namespace Kyra
-
diff --git a/kyra/resource.cpp b/kyra/resource.cpp
index ea2dd35055..ceba14ae06 100644
--- a/kyra/resource.cpp
+++ b/kyra/resource.cpp
@@ -130,32 +130,6 @@ uint8* Resource::fileData(const char* file, uint32* size) {
return buffer;
}
-Palette* Resource::loadPalette(const char* file) {
- uint32 size = 0;
- uint8 *buffer = fileData(file, &size);
- if (!buffer) {
- warning("ResMgr: Failed loading palette %s", file);
- return 0;
- }
- return new Palette(buffer, size);
-}
-
-CPSImage* Resource::loadImage(const char* file) {
- uint32 size = 0;
- uint8 *buffer = fileData(file, &size);
- if (!buffer)
- return 0;
- return new CPSImage(buffer, size);
-}
-
-Font* Resource::loadFont(const char* file) {
- uint32 size = 0;
- uint8 *buffer = fileData(file, &size);
- if (!buffer)
- return 0;
- return new Font(buffer, size);
-}
-
VMContext* Resource::loadScript(const char* file) {
VMContext* context = new VMContext(_engine);
context->loadScript(file);
diff --git a/kyra/resource.h b/kyra/resource.h
index c0559e9876..a14096965c 100644
--- a/kyra/resource.h
+++ b/kyra/resource.h
@@ -59,9 +59,6 @@ private:
};
// some resource types
-class Palette;
-class CPSImage;
-class Font;
class Movie;
class VMContext;
@@ -73,9 +70,6 @@ public:
uint8* fileData(const char* file, uint32* size);
- Palette* loadPalette(const char* file);
- CPSImage* loadImage(const char* file);
- Font* loadFont(const char* file);
VMContext* loadScript(const char* file);
protected:
@@ -84,106 +78,6 @@ protected:
Common::List<PAKFile*> _pakfiles;
};
-class Palette {
-public:
-
- Palette(uint8* data, uint32 size);
- ~Palette() { delete [] _palette; }
-
- uint8* getData(void) { return _palette; }
-
-protected:
-
- uint8* _palette;
-};
-
-class CPSImage {
-public:
-
- CPSImage(uint8* buffer, uint32 size);
- ~CPSImage();
-
- Palette* palette(void) { return _ownPalette; }
- bool hasPalette(void) { return (_ownPalette != 0); }
-
- // if col == -1 then no transparany
- void transparency(int16 col) { _transparency = col; }
-
- void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y);
- void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
- uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight);
-
- // only for testing :)
- uint8 getColor(uint16 x, uint16 y) { return _image[y * _width + x]; }
-
- uint8& operator[](uint16 index) { if (index > _width * _height) return _image[0]; return _image[index]; }
-
-protected:
-
- struct CPSHeader {
- uint16 _filesize;
- uint16 _format;
- uint16 _imagesize;
- uint32 _pal;
- } _cpsHeader;
-
- Palette* _ownPalette;
- uint8* _image;
-
- uint16 _width, _height;
- int16 _transparency;
-};
-
-class Font {
-public:
-
- Font(uint8* buffer, uint32 size);
- ~Font();
-
- uint32 getStringWidth(const char* string, char terminator = '\0');
- void drawStringToPlane(const char* string,
- uint8* plane, uint16 planewidth, uint16 planeheight,
- uint16 x, uint16 y, uint8 color);
-
-protected:
-
- void drawCharToPlane(const uint8* c, uint8 color, uint8 width, uint8 height,
- uint8* plane, uint16 planewidth, uint16 planeheight, uint16 x, uint16 y);
- const uint8* getChar(char c, uint8* width, uint8* height, uint8* heightadd);
- const char* getNextWord(const char* string, uint32* size);
-
- void preRenderAllChars(uint16 offsetTableOffset);
-
- uint8* _buffer;
- uint16* _offsetTable;
- uint8* _charWidth;
- uint16* _charHeight;
- uint8* _charBits;
-
- // the chars I call 'prerendered' aren't really prerendered
- // they are only 'decoded'
- struct PreRenderedChar {
- uint8* c;
- uint8 width, height, heightadd;
- };
-
- Common::Map<uint8, PreRenderedChar> _preRenderedChars; // our prerendered chars :)
-
- // INFO:
- // _magic1 = 0x0500
- // _magic2 = 0x000e
- // _magic3 = 0x0014
-#pragma START_PACK_STRUCTS
- struct FontHeader {
- uint16 _size;
- uint16 _magic1, _magic2, _magic3;
- uint16 _charWidthOffset, _charBitsOffset, _charHeightOffset;
- uint16 _version;
- uint16 _countChars;
- uint8 _width, _height;
- } GCC_PACK _fontHeader;
-#pragma END_PACK_STRUCTS
-};
} // end of namespace Kyra
#endif
diff --git a/kyra/screen.cpp b/kyra/screen.cpp
index 229009986f..17f8f8cf13 100644
--- a/kyra/screen.cpp
+++ b/kyra/screen.cpp
@@ -36,12 +36,25 @@ Screen::Screen(KyraEngine *vm, OSystem *system)
_pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = pagePtr;
}
}
- _palette1 = (uint8 *)malloc(768);
- _palette3 = (uint8 *)malloc(768);
- _fadePalette = (uint8 *)malloc(768);
+ _currentPalette = (uint8 *)malloc(768);
+ if (_currentPalette) {
+ memset(_currentPalette, 0, 768);
+ }
+ _screenPalette = (uint8 *)malloc(768);
+ if (_screenPalette) {
+ memset(_screenPalette, 0, 768);
+ }
_curDim = &_screenDimTable[0];
+ _charWidth = 0;
+ _charOffset = 0;
+ memset(_fonts, 0, sizeof(_fonts));
+ for (int i = 0; i < ARRAYSIZE(_textColorsMap); ++i) {
+ _textColorsMap[i] = i;
+ }
_decodeShapeBuffer = NULL;
_decodeShapeBufferSize = 0;
+ _animBlockPtr = NULL;
+ _animBlockSize = 0;
}
Screen::~Screen() {
@@ -49,7 +62,12 @@ Screen::~Screen() {
free(_pagePtrs[pageNum]);
_pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0;
}
- free(_palette1);
+ for (int f = 0; f < ARRAYSIZE(_fonts); ++f) {
+ free(_fonts[f].fontData);
+ _fonts[f].fontData = NULL;
+ }
+ free(_currentPalette);
+ free(_screenPalette);
}
void Screen::updateScreen() {
@@ -99,18 +117,75 @@ void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) {
void Screen::fadeFromBlack() {
debug(9, "Screen::fadeFromBlack()");
- memset(_palette3, 0, 768);
- setScreenPalette(_palette1);
- warning("Screen::fadeFromBlack() UNIMPLEMENTED");
+ fadePalette(_currentPalette, 0x54);
}
void Screen::fadeToBlack() {
debug(9, "Screen::fadeToBlack()");
- warning("Screen::fadeToBlack() UNIMPLEMENTED");
+ uint8 blackPal[768];
+ memset(blackPal, 0, 768);
+ fadePalette(blackPal, 0x54);
+}
+
+void Screen::fadePalette(const uint8 *palData, int delay) {
+ debug(9, "Screen::fadePalette(0x%X, %d)", palData, delay);
+ uint8 fadePal[768];
+ memcpy(fadePal, _screenPalette, 768);
+ uint8 diff, maxDiff = 0;
+ for (int i = 0; i < 768; ++i) {
+ diff = ABS(palData[i] - fadePal[i]);
+ if (diff > maxDiff) {
+ maxDiff = diff;
+ }
+ }
+ delay <<= 8;
+ if (maxDiff != 0) {
+ delay /= maxDiff;
+ }
+ int delayInc = delay;
+ for (diff = 1; diff <= maxDiff; ++diff) {
+ if (delayInc >= 512) {
+ break;
+ }
+ delayInc += delay;
+ }
+ int delayAcc = 0;
+ while (1) {
+ delayAcc += delayInc;
+ bool needRefresh = false;
+ for (int i = 0; i < 768; ++i) {
+ int c1 = palData[i];
+ int c2 = fadePal[i];
+ if (c1 != c2) {
+ needRefresh = true;
+ if (c1 > c2) {
+ c2 += diff;
+ if (c1 < c2) {
+ c2 = c1;
+ }
+ }
+ if (c1 < c2) {
+ c2 -= diff;
+ if (c1 > c2) {
+ c2 = c1;
+ }
+ }
+ fadePal[i] = (uint8)c2;
+ }
+ }
+ if (!needRefresh) {
+ break;
+ }
+ setScreenPalette(fadePal);
+ _system->updateScreen();
+ _system->delayMillis((delayAcc >> 8) * 1000 / 60);
+ delayAcc &= 0xFF;
+ }
}
void Screen::setScreenPalette(const uint8 *palData) {
debug(9, "Screen::setScreenPalette(0x%X)", palData);
+ memcpy(_screenPalette, palData, 768);
uint8 screenPal[256 * 4];
for (int i = 0; i < 256; ++i) {
screenPal[4 * i + 0] = (palData[0] << 2) | (palData[0] & 3);
@@ -234,11 +309,10 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum)
if (pageNum == -1) {
pageNum = _curPage;
}
- uint8 *dst = getPagePtr(pageNum);
+ uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W + x1;
for (; y1 <= y2; ++y1) {
- for (; x1 <= x2; ++x1) {
- *(dst + y1 * SCREEN_W + x1) = color;
- }
+ memset(dst, color, x2 - x1 + 1);
+ dst += SCREEN_W;
}
}
@@ -260,25 +334,166 @@ void Screen::setTextColor(const uint8 *cmap, int a, int b) {
}
}
+void Screen::loadFont(FontId fontId, uint8 *fontData) {
+ debug(9, "Screen::loadFont(%d, 0x%X)", fontId, fontData);
+ Font *fnt = &_fonts[fontId];
+ assert(fontData && !fnt->fontData);
+ fnt->fontData = fontData;
+ uint16 fontSig = READ_LE_UINT16(fontData + 2);
+ if (fontSig != 0x500) {
+ error("Invalid font data");
+ }
+ fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8);
+ fnt->charBoxHeight = READ_LE_UINT16(fontData + 4);
+ fnt->charBitmapOffset = READ_LE_UINT16(fontData + 6);
+ fnt->charWidthTableOffset = READ_LE_UINT16(fontData + 8);
+ fnt->charHeightTableOffset = READ_LE_UINT16(fontData + 0xC);
+}
+
+Screen::FontId Screen::setFont(FontId fontId) {
+ debug(9, "Screen::setFont(0%d)", fontId);
+ FontId prev = _currentFont;
+ _currentFont = fontId;
+ return prev;
+}
+
int Screen::getCharWidth(uint8 c) const {
- debug(9, "Screen::getCharWidth(%c)", c);
- warning("Screen::getCharWidth() UNIMPLEMENTED");
- return 0;
+ debug(9, "Screen::getCharWidth('%c')", c);
+ return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth;
}
int Screen::getTextWidth(const char *str) const {
debug(9, "Screen::getTextWidth('%s')", str);
- warning("Screen::getTextWidth() UNIMPLEMENTED");
- return 0;
+ int curLineLen = 0;
+ int maxLineLen = 0;
+ while (1) {
+ char c = *str++;
+ if (c == 0) {
+ break;
+ } else if (c == '\r') {
+ if (curLineLen > maxLineLen) {
+ maxLineLen = curLineLen;
+ } else {
+ curLineLen = 0;
+ }
+ } else {
+ curLineLen += getCharWidth(c);
+ }
+ }
+ return MAX(curLineLen, maxLineLen);
}
void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) {
debug(9, "Screen::printText('%s', %d, %d, 0x%X, 0x%X)", str, x, y, color1, color2);
- warning("Screen::printText() UNIMPLEMENTED");
+ uint8 cmap[2];
+ cmap[0] = color2;
+ cmap[1] = color1;
+ setTextColor(cmap, 0, 1);
+
+ Font *fnt = &_fonts[_currentFont];
+ uint8 charHeight = *(fnt->fontData + fnt->charBoxHeight + 4);
+
+ if (x < 0) {
+ x = 0;
+ } else if (x >= SCREEN_W) {
+ return;
+ }
+ int x_start = x;
+ if (y < 0) {
+ y = 0;
+ } else if (y >= SCREEN_H) {
+ return;
+ }
+
+ while (1) {
+ char c = *str++;
+ if (c == 0) {
+ break;
+ } else if (c == '\r') {
+ x = x_start;
+ y += charHeight + _charOffset;
+ } else {
+ int charWidth = getCharWidth(c);
+ if (x + charWidth > SCREEN_W) {
+ x = x_start;
+ y += charHeight + _charOffset;
+ if (y >= SCREEN_H) {
+ break;
+ }
+ }
+ drawChar(c, x, y);
+ x += charWidth;
+ }
+ }
+}
+
+void Screen::drawChar(char c, int x, int y) {
+ debug(9, "Screen::drawChar('%c', %d, %d)", c, x, y);
+ Font *fnt = &_fonts[_currentFont];
+ uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x;
+ uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2);
+ if (bitmapOffset == 0) {
+ return;
+ }
+ uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c);
+ if (charWidth + x > SCREEN_W) {
+ return;
+ }
+ uint8 charH0 = *(fnt->fontData + fnt->charBoxHeight + 4);
+ if (charH0 + y > SCREEN_H) {
+ return;
+ }
+ uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2);
+ uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1);
+ charH0 -= charH1 + charH2;
+
+ const uint8 *src = fnt->fontData + bitmapOffset;
+ const int pitch = SCREEN_W - charWidth;
+
+ while (charH1--) {
+ uint8 col = _textColorsMap[0];
+ for (int i = 0; i < charWidth; ++i) {
+ if (col != 0) {
+ *dst = col;
+ }
+ ++dst;
+ }
+ dst += pitch;
+ }
+
+ while (charH2--) {
+ uint8 b = 0;
+ for (int i = 0; i < charWidth; ++i) {
+ uint8 col;
+ if (i & 1) {
+ col = _textColorsMap[b >> 4];
+ } else {
+ b = *src++;
+ col = _textColorsMap[b & 0xF];
+ }
+ if (col != 0) {
+ *dst = col;
+ }
+ ++dst;
+ }
+ dst += pitch;
+ }
+
+ while (charH0--) {
+ uint8 col = _textColorsMap[0];
+ for (int i = 0; i < charWidth; ++i) {
+ if (col != 0) {
+ *dst = col;
+ }
+ ++dst;
+ }
+ dst += pitch;
+ }
}
void Screen::setScreenDim(int dim) {
debug(9, "setScreenDim(%d)", dim);
+ assert(dim < _screenDimTableCount);
_curDim = &_screenDimTable[dim];
// XXX
}
diff --git a/kyra/screen.h b/kyra/screen.h
index 97f18cc57f..712aa39a38 100644
--- a/kyra/screen.h
+++ b/kyra/screen.h
@@ -28,7 +28,6 @@ class OSystem;
namespace Kyra {
-class CPSImage;
class KyraEngine;
struct ScreenDim {
@@ -42,9 +41,39 @@ struct ScreenDim {
uint16 unkE;
};
+struct Font {
+ uint8 *fontData;
+ uint8 *charWidthTable;
+ uint16 charBoxHeight;
+ uint16 charBitmapOffset;
+ uint16 charWidthTableOffset;
+ uint16 charHeightTableOffset;
+};
+
class Screen {
public:
+ enum {
+ SCREEN_W = 320,
+ SCREEN_H = 200,
+ SCREEN_PAGE_SIZE = 320 * 200 + 1024,
+ SCREEN_PAGE_NUM = 16
+ };
+
+ enum DrawShapeFlags {
+ DSF_X_FLIPPED = 0x01,
+ DSF_Y_FLIPPED = 0x02,
+ DSF_SCALE = 0x04,
+ DSF_WND_COORDS = 0x10,
+ DSF_CENTER = 0x20
+ };
+
+ enum FontId {
+ FID_6_FNT = 0,
+ FID_8_FNT,
+ FID_NUM
+ };
+
Screen(KyraEngine *vm, OSystem *system);
~Screen();
@@ -57,6 +86,7 @@ public:
void setPagePixel(int pageNum, int x, int y, uint8 color);
void fadeFromBlack();
void fadeToBlack();
+ void fadePalette(const uint8 *palData, int delay);
void setScreenPalette(const uint8 *palData);
void copyToPage0(int y, int h, uint8 page, uint8 *seqBuf);
void copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage);
@@ -67,9 +97,12 @@ public:
void setAnimBlockPtr(uint8 *p, int size);
void setTextColorMap(const uint8 *cmap);
void setTextColor(const uint8 *cmap, int a, int b);
+ void loadFont(FontId fontId, uint8 *fontData);
+ FontId setFont(FontId fontId);
int getCharWidth(uint8 c) const;
int getTextWidth(const char *str) const;
void printText(const char *str, int x, int y, uint8 color1, uint8 color2);
+ void drawChar(char c, int x, int y);
void setScreenDim(int dim);
void drawShapePlotPixelCallback1(uint8 *dst, uint8 color);
void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, int *flagsTable);
@@ -78,44 +111,31 @@ public:
static void decodeFrameDelta(uint8 *dst, const uint8 *src);
static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch);
- int _charOffset;
int _charWidth;
+ int _charOffset;
int _curPage;
- uint8 *_palette1;
-
- enum {
- SCREEN_W = 320,
- SCREEN_H = 200,
- SCREEN_PAGE_SIZE = 320 * 200 + 1024,
- SCREEN_PAGE_NUM = 16
- };
-
- enum DrawShapeFlags {
- DSF_X_FLIPPED = 0x01,
- DSF_Y_FLIPPED = 0x02,
- DSF_SCALE = 0x04,
- DSF_WND_COORDS = 0x10,
- DSF_CENTER = 0x20
- };
+ uint8 *_currentPalette;
typedef void (Screen::*DrawShapePlotPixelCallback)(uint8 *dst, uint8 c);
private:
- uint8 _textColorsMap[16];
- uint8 *_animBlockPtr;
- int _animBlockSize;
uint8 *_pagePtrs[16];
- uint8 *_palette3;
- uint8 *_fadePalette;
+ uint8 *_screenPalette;
const ScreenDim *_curDim;
+ FontId _currentFont;
+ Font _fonts[FID_NUM];
+ uint8 _textColorsMap[16];
uint8 *_decodeShapeBuffer;
int _decodeShapeBufferSize;
-
+ uint8 *_animBlockPtr;
+ int _animBlockSize;
+
OSystem *_system;
KyraEngine *_vm;
static const ScreenDim _screenDimTable[];
+ static const int _screenDimTableCount;
static const DrawShapePlotPixelCallback _drawShapePlotPixelTable[];
static const int _drawShapePlotPixelCount;
};
diff --git a/kyra/staticres.cpp b/kyra/staticres.cpp
index 98774824a4..399b111613 100644
--- a/kyra/staticres.cpp
+++ b/kyra/staticres.cpp
@@ -39,6 +39,8 @@ const ScreenDim Screen::_screenDimTable[] = {
{ 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 }
};
+const int Screen::_screenDimTableCount = ARRAYSIZE(_screenDimTable);
+
const Screen::DrawShapePlotPixelCallback Screen::_drawShapePlotPixelTable[] = {
&Screen::drawShapePlotPixelCallback1
// XXX