[Scummvm-cvs-logs] CVS: scummvm/kyra kyra.cpp,1.38,1.39 kyra.h,1.13,1.14 module.mk,1.6,1.7 resource.cpp,1.15,1.16 resource.h,1.11,1.12 screen.cpp,1.6,1.7 screen.h,1.4,1.5 staticres.cpp,1.2,1.3 cpsimage.cpp,1.10,NONE font.cpp,1.13,NONE palette.cpp,1.10,NONE

Gregory Montoir cyx at users.sourceforge.net
Thu Sep 8 12:11:02 CEST 2005


Update of /cvsroot/scummvm/scummvm/kyra
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14414/kyra

Modified Files:
	kyra.cpp kyra.h module.mk resource.cpp resource.h screen.cpp 
	screen.h staticres.cpp 
Removed Files:
	cpsimage.cpp font.cpp palette.cpp 
Log Message:
some WIP code, moved Font stuff to Screen class

Index: kyra.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- kyra.cpp	2 Sep 2005 18:35:01 -0000	1.38
+++ kyra.cpp	8 Sep 2005 19:09:52 -0000	1.39
@@ -184,6 +184,9 @@
 
 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 @@
 
 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 @@
 
 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 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::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 @@
 	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::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 @@
 	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 @@
 				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;

Index: kyra.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- kyra.h	2 Sep 2005 11:12:09 -0000	1.13
+++ kyra.h	8 Sep 2005 19:09:52 -0000	1.14
@@ -62,6 +62,11 @@
 class KyraEngine : public Engine {
 public:
 
+	enum {
+		TALK_SUBSTRING_LEN = 80,
+		TALK_SUBSTRING_NUM = 3
+	};
+
 	KyraEngine(GameDetector *detector, OSystem *system);
 	~KyraEngine();
 	
@@ -74,6 +79,8 @@
 	
 	Common::RandomSource _rnd;
 
+	typedef void (KyraEngine::*IntroProc)();
+
 protected:
 
 	int go();
@@ -96,6 +103,10 @@
 	
 	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 @@
 	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 @@
 	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[];

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/module.mk,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- module.mk	19 Aug 2005 22:12:09 -0000	1.6
+++ module.mk	8 Sep 2005 19:09:52 -0000	1.7
@@ -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 \

Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/resource.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- resource.cpp	19 Aug 2005 22:12:09 -0000	1.15
+++ resource.cpp	8 Sep 2005 19:09:52 -0000	1.16
@@ -130,32 +130,6 @@
 	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);

Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/resource.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- resource.h	19 Aug 2005 22:12:09 -0000	1.11
+++ resource.h	8 Sep 2005 19:09:52 -0000	1.12
@@ -59,9 +59,6 @@
 };
 
 // some resource types
-class Palette;
-class CPSImage;
-class Font;
 class Movie;
 class VMContext;
 
@@ -73,9 +70,6 @@
 
 	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 @@
 	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

Index: screen.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/screen.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- screen.cpp	2 Sep 2005 18:35:01 -0000	1.6
+++ screen.cpp	8 Sep 2005 19:09:52 -0000	1.7
@@ -36,12 +36,25 @@
 			_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 @@
 		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::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 @@
 	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::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
 }

Index: screen.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/screen.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- screen.h	2 Sep 2005 11:12:09 -0000	1.4
+++ screen.h	8 Sep 2005 19:09:52 -0000	1.5
@@ -28,7 +28,6 @@
 
 namespace Kyra {
 
-class CPSImage;
 class KyraEngine;
 
 struct ScreenDim {
@@ -42,9 +41,39 @@
 	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 @@
 	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 @@
 	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 @@
 	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;
 };

Index: staticres.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/staticres.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- staticres.cpp	31 Aug 2005 20:14:20 -0000	1.2
+++ staticres.cpp	8 Sep 2005 19:09:52 -0000	1.3
@@ -39,6 +39,8 @@
 	{ 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 }
 };
 
+const int Screen::_screenDimTableCount = ARRAYSIZE(_screenDimTable);
+
 const Screen::DrawShapePlotPixelCallback Screen::_drawShapePlotPixelTable[] = {
 	&Screen::drawShapePlotPixelCallback1
 	// XXX

--- cpsimage.cpp DELETED ---

--- font.cpp DELETED ---

--- palette.cpp DELETED ---





More information about the Scummvm-git-logs mailing list