[Scummvm-cvs-logs] CVS: residual actor.cpp,1.51,1.52 driver.h,1.11,1.12 driver_gl.cpp,1.52,1.53 driver_gl.h,1.24,1.25 driver_tinygl.cpp,1.20,1.21 driver_tinygl.h,1.11,1.12 font.cpp,1.2,1.3 font.h,1.4,1.5 lua.cpp,1.139,1.140 primitives.cpp,1.3,1.4 primitives.h,1.3,1.4 textobject.cpp,1.26,1.27 textobject.h,1.14,1.15

Pawel Kolodziejski aquadran at users.sourceforge.net
Thu May 5 14:24:13 CEST 2005


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

Modified Files:
	actor.cpp driver.h driver_gl.cpp driver_gl.h driver_tinygl.cpp 
	driver_tinygl.h font.cpp font.h lua.cpp primitives.cpp 
	primitives.h textobject.cpp textobject.h 
Log Message:
- patch from Erich Hoover
- some uint -> int changes

Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/actor.cpp,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- actor.cpp	3 Apr 2005 11:33:28 -0000	1.51
+++ actor.cpp	5 May 2005 21:23:17 -0000	1.52
@@ -320,6 +320,16 @@
 	_sayLineText->setDefaults(&sayLineDefaults);
 	_sayLineText->setText((char *)msg);
 	_sayLineText->setFGColor(&_talkColor);
+	// if the actor isn't visible render their text at the bottom
+	// of the screen
+	if (!visible() || !inSet(g_engine->currScene()->name())) {
+		_sayLineText->setX(640 / 2);
+		_sayLineText->setY(440);
+	} else {
+		// render at the top for active actors for now
+		_sayLineText->setX(640 / 2);
+		_sayLineText->setY(0);
+	}
 	_sayLineText->createBitmap();
 	g_engine->registerTextObject(_sayLineText);
 }

Index: driver.h
===================================================================
RCS file: /cvsroot/scummvm/residual/driver.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- driver.h	8 Apr 2005 18:29:12 -0000	1.11
+++ driver.h	5 May 2005 21:23:17 -0000	1.12
@@ -92,6 +92,7 @@
 	virtual void destroyTextBitmap(TextObjectHandle *handle) = 0;
 
 	virtual void drawRectangle(PrimitiveObject *primitive) = 0;
+	virtual void drawLine(PrimitiveObject *primitive) = 0;
 
 	virtual void prepareSmushFrame(int width, int height, byte *bitmap) = 0;
 	virtual void drawSmushFrame(int offsetX, int offsetY) = 0;

Index: driver_gl.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/driver_gl.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- driver_gl.cpp	9 Apr 2005 05:03:39 -0000	1.52
+++ driver_gl.cpp	5 May 2005 21:23:17 -0000	1.53
@@ -734,3 +734,37 @@
 	glEnable(GL_DEPTH_TEST);
 	glEnable(GL_LIGHTING);
 }
+
+void DriverGL::drawLine(PrimitiveObject *primitive) {
+	int x1 = primitive->getX1();
+	int x2 = primitive->getX2();
+	int y1 = primitive->getY1();
+	int y2 = primitive->getY2();
+
+	Color color = primitive->getColor();
+
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glOrtho(0, 640, 480, 0, 0, 1);
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+
+	glDisable(GL_LIGHTING);
+	glDisable(GL_DEPTH_TEST);
+	glDepthMask(GL_FALSE);
+
+	glColor3f(color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f);
+
+	glBegin(GL_LINES);
+	glVertex2f(x1, y1);
+	glVertex2f(x2, y1);
+	glVertex2f(x2, y2);
+	glVertex2f(x1, y2);
+	glEnd();
+
+	glColor3f(1.0f, 1.0f, 1.0f);
+
+	glDepthMask(GL_TRUE);
+	glEnable(GL_DEPTH_TEST);
+	glEnable(GL_LIGHTING);
+}

Index: driver_gl.h
===================================================================
RCS file: /cvsroot/scummvm/residual/driver_gl.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- driver_gl.h	8 Apr 2005 18:29:13 -0000	1.24
+++ driver_gl.h	5 May 2005 21:23:17 -0000	1.25
@@ -76,6 +76,7 @@
 	void destroyTextBitmap(TextObjectHandle *handle);
 
 	void drawRectangle(PrimitiveObject *primitive);
+	void drawLine(PrimitiveObject *primitive);
 
 	void prepareSmushFrame(int width, int height, byte *bitmap);
 	void drawSmushFrame(int offsetX, int offsetY);

Index: driver_tinygl.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/driver_tinygl.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- driver_tinygl.cpp	9 Apr 2005 05:03:39 -0000	1.20
+++ driver_tinygl.cpp	5 May 2005 21:23:17 -0000	1.21
@@ -525,3 +525,21 @@
 		}
 	}
 }
+
+void DriverTinyGL::drawLine(PrimitiveObject *primitive) {
+	uint16 *dst = (uint16 *)_screen->pixels;
+	int x1 = primitive->getX1();
+	int x2 = primitive->getX2();
+	int y1 = primitive->getY1();
+	int y2 = primitive->getY2();
+	float m = (y2 - y1) / (x2 - x1);
+	int b = -m * x1 + y1;
+
+	Color color = primitive->getColor();
+	uint16 c = ((color.red() & 0xF8) << 8) | ((color.green() & 0xFC) << 3) | (color.blue() >> 3);
+
+	for (int x = x1; x <= x2; x++) {
+		int y = (int) (m * x) + b;
+		WRITE_LE_UINT16(dst + 640 * y + x, c);
+	}
+}

Index: driver_tinygl.h
===================================================================
RCS file: /cvsroot/scummvm/residual/driver_tinygl.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- driver_tinygl.h	8 Apr 2005 18:29:13 -0000	1.11
+++ driver_tinygl.h	5 May 2005 21:23:17 -0000	1.12
@@ -78,6 +78,7 @@
 	void destroyTextBitmap(TextObjectHandle *handle);
 
 	void drawRectangle(PrimitiveObject *primitive);
+	void drawLine(PrimitiveObject *primitive);
 
 	void prepareSmushFrame(int width, int height, byte *bitmap);
 	void drawSmushFrame(int offsetX, int offsetY);

Index: font.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/font.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- font.cpp	20 Mar 2005 15:48:58 -0000	1.2
+++ font.cpp	5 May 2005 21:23:17 -0000	1.3
@@ -64,7 +64,7 @@
 		_charHeaders[i].width = READ_LE_UINT32(data + 8);
 		_charHeaders[i].height = READ_LE_UINT32(data + 12);
 		data += 16;
-		_charHeaders[i].logicalWidth = MAX((uint32) _charHeaders[i].logicalWidth, _charHeaders[i].width);
+		_charHeaders[i].logicalWidth = MAX((int32) _charHeaders[i].logicalWidth, _charHeaders[i].width);
 		//printf("%c. width: %d. logical width: %d. startCol: %d\n", i, _charHeaders[i].width, _charHeaders[i].logicalWidth, _charHeaders[i].startingCol);
 	}
 

Index: font.h
===================================================================
RCS file: /cvsroot/scummvm/residual/font.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- font.h	20 Mar 2005 11:49:21 -0000	1.4
+++ font.h	5 May 2005 21:23:17 -0000	1.5
@@ -28,24 +28,24 @@
 	Font(const char *filename, const char *data, int len);
 	~Font();
 
-	uint32 getCharWidth(char c) { return _charHeaders[_charIndex[c]].width; }
-	uint32 getCharHeight(char c) { return _charHeaders[_charIndex[c]].height; }
-	uint32 getCharLogicalWidth(char c) { return _charHeaders[_charIndex[c]].logicalWidth; }
-	uint32 getCharStartingCol(char c) { return _charHeaders[_charIndex[c]].startingCol; }
-	uint32 getCharStartingLine(char c) { return _charHeaders[_charIndex[c]].startingLine; }
+	int32 getCharWidth(char c) { return _charHeaders[_charIndex[c]].width; }
+	int32 getCharHeight(char c) { return _charHeaders[_charIndex[c]].height; }
+	int32 getCharLogicalWidth(char c) { return _charHeaders[_charIndex[c]].logicalWidth; }
+	int32 getCharStartingCol(char c) { return _charHeaders[_charIndex[c]].startingCol; }
+	int32 getCharStartingLine(char c) { return _charHeaders[_charIndex[c]].startingLine; }
 	const byte *getCharData(char c) { return _fontData + (_charHeaders[_charIndex[c]].offset); }
 
 	static const uint8 Font::emerFont[][13];
 private:
 
 	struct CharHeader {
-		uint32 offset;
-		uint32 unknown;
-		uint8  logicalWidth;
-		uint8  startingCol;
-		uint8  startingLine;
-		uint32 width;
-		uint32 height;
+		int32 offset;
+		int32 unknown;
+		int8  logicalWidth;
+		int8  startingCol;
+		int8  startingLine;
+		int32 width;
+		int32 height;
 	};
 
 	uint32 _numChars;

Index: lua.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/lua.cpp,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -d -r1.139 -r1.140
--- lua.cpp	10 Apr 2005 03:08:29 -0000	1.139
+++ lua.cpp	5 May 2005 21:23:17 -0000	1.140
@@ -112,6 +112,14 @@
 	return NULL;
 }
 
+static inline PrimitiveObject *check_primobject(int num) {
+	lua_Object param = lua_getparam(num);
+	if (lua_isuserdata(param) && lua_tag(param) == MKID('PRIM'))
+		return static_cast<PrimitiveObject *>(lua_getuserdata(param));
+	luaL_argerror(num, "primitive (rectangle) expected");
+	return NULL;
+} 
+
 static inline TextObject *check_textobject(int num) {
 	lua_Object param = lua_getparam(num);
 	if (lua_isuserdata(param) && lua_tag(param) == MKID('TEXT'))
@@ -287,6 +295,13 @@
 	lua_pushusertag(new Actor(name), MKID('ACTR'));
 }
 
+static void GetActorTimeScale() {
+	stubWarning("GetActorTimeScale");
+	// return 1 so the game doesn't halt when Manny attempts
+	// to pick up the fire extinguisher
+	lua_pushnumber(1);
+}
+
 static void SetSelectedActor() {
 	Actor *act = check_actor(1);
 	g_engine->setSelectedActor(act);
@@ -309,7 +324,7 @@
 		if (lua_isnil(key)) 
 			break;
 
-		key_text = lua_getstring(key);		
+		key_text = lua_getstring(key);
 		if (strmatch(key_text, "font"))
 			sayLineDefaults.font = check_font(2);
 		else
@@ -1396,6 +1411,7 @@
 	PrimitiveObject *p = new PrimitiveObject();
 	p->createBitmap(bitmap, x, y, transparent);
 	g_engine->registerPrimitiveObject(p);
+	lua_pushusertag(p, MKID('PRIM'));
 }
 
 void getTextObjectParams(TextObject *textObject, lua_Object table_obj) {
@@ -1497,12 +1513,33 @@
 	else
 		return;
 
-	// get the item list
+	// get the keycode
+	key = atoi(lua_getstring(keycode));
+
+	// get the item list for most menus
 	itemTable = getTableValue(menuTable, "menu");
-	if (!lua_istable(itemTable))
-		return;
+	if (!lua_istable(itemTable)) {
+		// 3D Acceleration Menu
+		itemTable = getTableValue(menuTable, "active_menu");
+		if (!lua_istable(itemTable)) {
+			// Control Help menu
+			lua_Object nextPage = getTableValue(menuTable, "next_page");
+			lua_Object prevPage = getTableValue(menuTable, "prev_page");
 
-	key = atoi(lua_getstring(keycode));
+			if (lua_isfunction(nextPage) && key == SDLK_RIGHT) {
+				lua_beginblock();
+				lua_pushobject(menuTable);
+				lua_callfunction(nextPage);
+				lua_endblock();
+			} else if (lua_isfunction(prevPage) && key == SDLK_LEFT) {
+				lua_beginblock();
+				lua_pushobject(menuTable);
+				lua_callfunction(prevPage);
+				lua_endblock();
+			}
+			return;
+		}
+	}
 
 	// get the current item
 	menuItem = atoi(lua_getstring(getTableValue(itemTable, "cur_item")));
@@ -1532,10 +1569,14 @@
 	/* if we're running the menu then we need to manually handle
 	 * a lot of the operations necessary to use the menu
 	 */
-	bool menuChanged = false, sliderChanged = false;
+	bool menuChanged = false;
 	switch (key) {
 		case SDLK_ESCAPE:
 		{
+			// only use ESC to exit the main menu 
+			if (lua_isnil(getTableFunction(menuTable, "return_to_game")))
+				return;
+
 			lua_Object close = getTableFunction(menuTable, "cancel");
 			lua_Object destroy = getTableFunction(menuTable, "destroy");
 
@@ -1636,7 +1677,14 @@
  */
 static void ChangeTextObject() {
 	TextObject *modifyObject, *textObject = check_textobject(1);
-	lua_Object tableObj = lua_getparam(2);
+	lua_Object tableObj;
+
+	// when called in certain instances (such as don's computer)
+	// the second parameter is the string and the third is the table
+	if (lua_isstring(lua_getparam(2)))
+		tableObj = lua_getparam(3);
+	else
+		tableObj = lua_getparam(2);
 
 	modifyObject = TextObjectExists((char *)textObject->name());
 	if (!modifyObject) {
@@ -1681,7 +1729,7 @@
 	char *line = lua_getstring(lua_getparam(1));
 	std::string text = line;
 	lua_Object tableObj = lua_getparam(2);
-         
+
 	textObject = new TextObject();
 	textObject->setDefaults(&textObjectDefaults);
          
@@ -1781,7 +1829,80 @@
 	g_smush->pause(lua_isnil(lua_getparam(1)) != 0);
 }
 
-static void BlastRect() {
+static void PurgePrimitiveQueue() {
+	g_engine->killPrimitiveObjects();
+}
+
+static void DrawPolygon() {
+	stubWarning("DrawPolygon");
+}
+
+static void DrawLine() {
+	int x1 = check_int(1);
+	int y1 = check_int(2);
+	int x2 = check_int(3);
+	int y2 = check_int(4);
+	lua_Object tableObj = lua_getparam(5);
+	Color color;
+	color._vals[0] = 255;
+	color._vals[1] = 255;
+	color._vals[2] = 255;
+
+	if (lua_istable(tableObj)){
+		lua_pushobject(tableObj);
+		lua_pushstring("color");
+		lua_Object colorObj = lua_gettable();
+		if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
+			color = static_cast<Color *>(lua_getuserdata(colorObj));
+		}
+	}
+
+	PrimitiveObject *p = new PrimitiveObject();
+	p->createLine(x1, x2, y1, y2, color);
+	g_engine->registerPrimitiveObject(p);
+	lua_pushusertag(p, MKID('PRIM'));
+}
+
+static void ChangePrimitive() {
+	PrimitiveObject *psearch, *pmodify = NULL;
+	lua_Object tableObj = lua_getparam(2);
+	Color color;
+
+	color._vals[0] = 255;
+	color._vals[1] = 255;
+	color._vals[2] = 255;
+
+	if (lua_isnil(lua_getparam(1)) || !lua_istable(tableObj))
+		return;
+
+	psearch = check_primobject(1);
+	for (Engine::PrimitiveListType::const_iterator i = g_engine->primitivesBegin(); i != g_engine->primitivesEnd(); i++) {
+		PrimitiveObject *p = *i;
+		if (p->getX1() == psearch->getX1() && p->getX2() == psearch->getX2() && p->getY1() == psearch->getY1() && p->getY2() == psearch->getY2()) {
+			pmodify = p;
+			break;
+		}
+	}
+	if(!pmodify)
+		error("Primitive object not found.");
+
+	lua_pushobject(tableObj);
+	lua_pushstring("color");
+	lua_Object colorObj = lua_gettable();
+	if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
+		color = static_cast<Color *>(lua_getuserdata(colorObj));
+		pmodify->setColor(color);
+	}
+	lua_pushobject(tableObj);
+	lua_pushstring("y");
+	lua_Object yObj = lua_gettable();
+	if (!lua_isnil(yObj)) {
+		pmodify->setY1(atoi(lua_getstring(yObj)));
+		pmodify->setY2(atoi(lua_getstring(yObj)));
+	}
+}
+
+static void DrawRectangle() {
 	int x1 = check_int(1);
 	int y1 = check_int(2);
 	int x2 = check_int(3);
@@ -1811,6 +1932,14 @@
 	PrimitiveObject *p = new PrimitiveObject();
 	p->createRectangle(x1, x2, y1, y2, color, filled);
 	g_engine->registerPrimitiveObject(p);
+	lua_pushusertag(p, MKID('PRIM'));
+}
+
+static void BlastRect() {
+	// BlastRect is specifically for the menu thread;
+	// however, we don't need to handle the menu in a 
+	// separate thread so this works fine
+	DrawRectangle();
 }
 
 static void DimScreen() {
@@ -2199,18 +2328,12 @@
 STUB_FUNC(GetActorRect)
 STUB_FUNC(GetActorNodeLocation)
 STUB_FUNC(SetActorTimeScale)
-STUB_FUNC(GetActorTimeScale)
 STUB_FUNC(SetActorScale)
 STUB_FUNC(SetActorColormap)
 STUB_FUNC(GetTranslationMode)
 STUB_FUNC(SetTranslationMode)
 STUB_FUNC(PrintLine)
-STUB_FUNC(PurgePrimitiveQueue)
 STUB_FUNC(KillPrimitive)
-STUB_FUNC(ChangePrimitive)
-STUB_FUNC(DrawRectangle)
-STUB_FUNC(DrawPolygon)
-STUB_FUNC(DrawLine)
 STUB_FUNC(WalkActorToAvoiding)
 STUB_FUNC(GetActorChores)
 STUB_FUNC(Exit)

Index: primitives.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/primitives.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- primitives.cpp	8 Apr 2005 11:16:57 -0000	1.3
+++ primitives.cpp	5 May 2005 21:23:17 -0000	1.4
@@ -62,6 +62,15 @@
 	g_driver->createBitmap(_bitmap);
 }
 
+void PrimitiveObject::createLine(int x1, int x2, int y1, int y2, Color color) {
+	_x1 = x1;
+	_y1 = y1;
+	_x2 = x2;
+	_y2 = y2;
+	_color = color;
+	_type = 3;
+}
+
 void PrimitiveObject::draw() {
 	assert(_type);
 
@@ -69,4 +78,6 @@
 		g_driver->drawRectangle(this);
 	else if (_type == 2)
 		g_driver->drawBitmap(_bitmap);
+	else if (_type == 3)
+		g_driver->drawLine(this);
 }

Index: primitives.h
===================================================================
RCS file: /cvsroot/scummvm/residual/primitives.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- primitives.h	8 Apr 2005 11:16:57 -0000	1.3
+++ primitives.h	5 May 2005 21:23:17 -0000	1.4
@@ -34,11 +34,14 @@
 
 	void createRectangle(int x1, int x2, int y1, int y2, Color color, bool filled);
 	void createBitmap(Bitmap *bitmap, int x, int y, bool transparent);
+	void createLine(int x1, int x2, int y1, int y2, Color color);
 	int getX1() { return _x1; }
 	int getX2() { return _x2; }
 	int getY1() { return _y1; }
 	int getY2() { return _y2; }
-	Color getColor() { return _color; }
+	void setY1(int coord) { _y1 = coord; }
+	void setY2(int coord) { _y2 = coord; }
+	void setColor(Color color) { _color = color; } 	Color getColor() { return _color; }
 	bool isFilled() { return _filled; }
 	void draw();
 	bool isBitmap() { return _type == 2; }

Index: textobject.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/textobject.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- textobject.cpp	8 Apr 2005 22:29:06 -0000	1.26
+++ textobject.cpp	5 May 2005 21:23:17 -0000	1.27
@@ -29,8 +29,9 @@
 
 TextObject::TextObject() :
 		_created(false), _x(0), _y(0), _width(0), _height(0), _justify(0),
-		_font(NULL), _textBitmap(NULL), _bitmapWidth(0),
-		_bitmapHeight(0), _disabled(false), _textObjectHandle(NULL) {
+		_font(NULL), _textBitmap(NULL), _bitmapWidthPtr(NULL),
+		_bitmapHeightPtr(NULL), _disabled(false), _textObjectHandle(NULL),
+		_numberLines(1) {
 	memset(_textID, 0, sizeof(_textID));
 	_fgColor._vals[0] = 0;
 	_fgColor._vals[1] = 0;
@@ -56,19 +57,42 @@
 void TextObject::setDefaults(TextObjectDefaults *defaults) {
 	_x = defaults->x;
 	_y = defaults->x;
-	_width = defaults->width;
-	_height = defaults->height;
 	_font = defaults->font;
 	_fgColor = defaults->fgColor;
 	_justify = defaults->justify;
 	_disabled = defaults->disabled;
 }
 
+int TextObject::getBitmapWidth() {
+	if (_bitmapWidthPtr == NULL)
+		return 0;
+
+	int width = 0;
+
+	for (int i = 0; i < _numberLines; i++) {
+		if (_bitmapWidthPtr[i] > width)
+			width = _bitmapWidthPtr[i];
+	}
+	return width;
+}
+
+int TextObject::getBitmapHeight() {
+	if (_bitmapHeightPtr == NULL)
+		return 0;
+
+	uint height = 0;
+
+	for (int i = 0; i < _numberLines; i++) {
+		height += _bitmapHeightPtr[i];
+	}
+	return height;
+}
+
 int TextObject::getTextCharPosition(int pos) {
 	int width = 0;
 	std::string msg = parseMsgText(_textID, NULL);
 	for (int i = 0; (msg[i] != '\0') && (i < pos); ++i) {
-		width += _font->getCharLogicalWidth(msg[i]) + _font->getCharStartingCol(msg[i]);
+		width += _font->getCharLogicalWidth(msg[i]);
 	}
 
 	return width;
@@ -79,10 +103,10 @@
 		destroyBitmap();
 
 	std::string msg = parseMsgText(_textID, NULL);
+	std::string message;
 	char *c = (char *)msg.c_str();
 
-	_bitmapWidth = 0;
-	_bitmapHeight = 0;
+	int lineWidth = 0;
 
 	// remove spaces (NULL_TEXT) from the end of the string,
 	// while this helps make the string unique it screws up
@@ -90,70 +114,123 @@
 	for(int i = (int) msg.length() - 1; c[i] == TEXT_NULL; i--)
 		msg.erase(msg.length() - 1, msg.length());
 
+	// format the output message to incorporate line wrapping
+	// (if necessary) for the text object
+	_numberLines = 1;
+	lineWidth = 0;
 	for (int i = 0; msg[i] != '\0'; ++i) {
-		_bitmapWidth += _font->getCharLogicalWidth(msg[i]) + _font->getCharStartingCol(msg[i]);
-
-		uint h = _font->getCharHeight(msg[i]) + _font->getCharStartingLine(msg[i]);
-		if (h > _bitmapHeight)
-			_bitmapHeight = h;
+		lineWidth += _font->getCharLogicalWidth(msg[i]);
+		if ((_width != 0 && lineWidth > (_width - _x))
+				|| (_justify == CENTER && (_x - lineWidth/2 < 0 || _x + lineWidth/2 > 640))
+				|| (_justify == LJUSTIFY && (_x + lineWidth > 640))
+				|| (_justify == RJUSTIFY && (_x - lineWidth < 0))) {
+			lineWidth = 0;
+			for (; msg[i] != ' '; i--)
+				message.erase(message.length() - 1, message.length());
+			message += '\n';
+			_numberLines++;
+			continue; // don't add the space back
+		}
+		message += msg[i];
 	}
+	_textObjectHandle = (Driver::TextObjectHandle **) malloc(sizeof(long) * _numberLines);
+	_bitmapWidthPtr = (int *)malloc(sizeof(int) * _numberLines);
+	_bitmapHeightPtr = (int *)malloc(sizeof(int) * _numberLines);
 
-	//printf("creating textobject: %s\nheight: %d\nwidth: %d\n", msg.c_str(), _bitmapHeight, _bitmapWidth);
+	for (int j = 0; j < _numberLines; j++) {
+		int nextLinePos = message.find_first_of('\n');
+		std::string currentLine = message.substr(0, nextLinePos);
 
-	_textBitmap = new uint8[_bitmapHeight * _bitmapWidth];
-	memset(_textBitmap, 0, _bitmapHeight * _bitmapWidth);
+		_bitmapWidthPtr[j] = 0;
+		_bitmapHeightPtr[j] = 0;
+		for (int i = 0; currentLine[i] != '\0'; ++i) {
+			_bitmapWidthPtr[j] += _font->getCharLogicalWidth(currentLine[i]);
+			int h = _font->getCharHeight(currentLine[i]) + _font->getCharStartingLine(currentLine[i]);
+			if (h > _bitmapHeightPtr[j])
+				_bitmapHeightPtr[j] = h;
+		}
+		//printf("creating textobject: %s\nheight: %d\nwidth: %d\n", currentLine.c_str(), _bitmapHeight[j], _bitmapWidth[j]);
 
-	// Fill bitmap
-	int offset = 0;
-	for (uint line = 0; line < _bitmapHeight; ++line) {
-		for (int c = 0; msg[c] != '\0'; ++c) {
-			uint32 charWidth = _font->getCharWidth(msg[c]);
-			uint32 charLogicalWidth = _font->getCharLogicalWidth(msg[c]);
-			uint8 startingCol = _font->getCharStartingCol(msg[c]);
-			uint8 startingLine = _font->getCharStartingLine(msg[c]);
+		_textBitmap = new uint8[_bitmapHeightPtr[j] * _bitmapWidthPtr[j]];
+		memset(_textBitmap, 0, _bitmapHeightPtr[j] * _bitmapWidthPtr[j]);
 
-			if (startingLine < line + 1 && _font->getCharHeight(msg[c]) + startingLine > line) {
-				memcpy(&_textBitmap[offset + startingCol],
-					_font->getCharData(msg[c]) + charWidth * (line - startingLine), charWidth);
-			}
+		// Fill bitmap
+		int offset = 0;
+		for (int line = 0; line < _bitmapHeightPtr[j]; ++line) {
+			for (int c = 0; currentLine[c] != '\0'; ++c) {
+				int32 charWidth = _font->getCharWidth(currentLine[c]);
+				int32 charLogicalWidth = _font->getCharLogicalWidth(currentLine[c]);
+				int8 startingCol = _font->getCharStartingCol(currentLine[c]);
+				int8 startingLine = _font->getCharStartingLine(currentLine[c]);
 
-			offset += charLogicalWidth + startingCol;
+				if (startingLine < line + 1 && _font->getCharHeight(currentLine[c]) + startingLine > line) {
+					memcpy(&_textBitmap[offset + startingCol],
+						_font->getCharData(currentLine[c]) + charWidth * (line - startingLine), charWidth);
+				}
+
+				offset += charLogicalWidth;
+			}
 		}
+		_textObjectHandle[j] = g_driver->createTextBitmap(_textBitmap, _bitmapWidthPtr[j], _bitmapHeightPtr[j], _fgColor);
+		delete[] _textBitmap;
+		message = message.substr(nextLinePos+1, message.length()-(nextLinePos+1));
 	}
-
-	_textObjectHandle = g_driver->createTextBitmap(_textBitmap, _bitmapWidth, _bitmapHeight, _fgColor);
-
-	delete[] _textBitmap;
 	_created = true;
 }
 
 void TextObject::destroyBitmap() {
 	_created = false;
 	if (_textObjectHandle) {
-		g_driver->destroyTextBitmap(_textObjectHandle);
-		delete _textObjectHandle;
+		for (int i = 0; i < _numberLines; i++) {
+			g_driver->destroyTextBitmap(_textObjectHandle[i]);
+			delete _textObjectHandle[i];
+		}
+		free(_textObjectHandle);
 		_textObjectHandle = NULL;
 	}
+	if (_bitmapWidthPtr) {
+		free(_bitmapWidthPtr);
+		_bitmapWidthPtr = NULL;
+	}
+	if (_bitmapHeightPtr) {
+		free(_bitmapHeightPtr);
+		_bitmapHeightPtr = NULL;
+	}
 }
 
 void TextObject::draw() {
+	int height = 0;
+
 	if (!_created)
 		return;
+	// render multi-line (wrapped) text
+	for (int i = 0; i < _numberLines; i++) {
+		int y;
 
-	if (_justify == LJUSTIFY || _justify == NONE)
-		g_driver->drawTextBitmap(_x, _y, _textObjectHandle);
-	else if (_justify == CENTER) {
-		int x = _x - (1 / 2.0) * _bitmapWidth;
-		if (x < 0)
-			x = 0;
+		if (_height != 0)
+			y = (int) (_y - _bitmapHeightPtr[i] / 2.0);
+		else
+			y = _y;
+		if (y < 0)
+			y = 0;
+		
+		if (_justify == LJUSTIFY || _justify == NONE)
+			g_driver->drawTextBitmap(_x, height + y, _textObjectHandle[i]);
+		else if (_justify == CENTER) {
+			int x = (int) (_x - (1 / 2.0) * _bitmapWidthPtr[i]);
+			if (x < 0)
+				x = 0;
 
-		g_driver->drawTextBitmap(x, _y, _textObjectHandle);
-	} else if (_justify == RJUSTIFY) {
-		int x = _x - _bitmapWidth;
-		if (x < 0)
-			x = 0;
+			g_driver->drawTextBitmap(x, height + y, _textObjectHandle[i]);
+		} else if (_justify == RJUSTIFY) {
+			int x = _x - getBitmapWidth();
+			if (x < 0)
+				x = 0;
 
-		g_driver->drawTextBitmap(x, _y, _textObjectHandle);
-	} else
-		warning("TextObject::draw: Unknown justification code (%d)!", _justify);
+			g_driver->drawTextBitmap(x, height + _y, _textObjectHandle[i]);
+		} else
+			warning("TextObject::draw: Unknown justification code (%d)!", _justify);
+
+		height += _bitmapHeightPtr[i];
+	}
 }

Index: textobject.h
===================================================================
RCS file: /cvsroot/scummvm/residual/textobject.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- textobject.h	5 Apr 2005 13:50:54 -0000	1.14
+++ textobject.h	5 May 2005 21:23:17 -0000	1.15
@@ -57,8 +57,8 @@
 	void setFont(Font *font) { _font = font; }
 	void setJustify(int justify) { _justify = justify; }
 	void setDisabled(bool disabled) { _disabled = disabled; }
-	int getBitmapWidth() { return _bitmapWidth; }
-	int getBitmapHeight() { return _bitmapHeight; }
+	int getBitmapWidth();
+	int getBitmapHeight();
 	int getTextCharPosition(int pos);
 
 	const char *name() const { return _textID; }
@@ -75,14 +75,14 @@
 	bool _created;
 	Color _fgColor;
 	int _x, _y;
-	uint _width, _height;
-	int _justify;
+	int _width, _height;
+	int _justify, _numberLines;
 	bool _disabled;
 	Font *_font;
 	char _textID[32];
 	uint8 *_textBitmap;
-	uint _bitmapWidth, _bitmapHeight;
-	Driver::TextObjectHandle *_textObjectHandle;
+	int *_bitmapWidthPtr, *_bitmapHeightPtr;
+	Driver::TextObjectHandle **_textObjectHandle;
 };
 
 #endif





More information about the Scummvm-git-logs mailing list