Пример #1
0
InventoryDialog::InventoryDialog() {
	// Determine the maximum size of the image of any item in the player's inventory
	int imgWidth = 0, imgHeight = 0;

	SynchronizedList<InvObject *>::iterator i;
	for (i = RING_INVENTORY._itemList.begin(); i != RING_INVENTORY._itemList.end(); ++i) {
		InvObject *invObject = *i;
		if (invObject->inInventory()) {
			// Get the image for the item
			GfxSurface itemSurface = surfaceFromRes(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);

			// Maintain the dimensions of the largest item image
			imgWidth = MAX(imgWidth, (int)itemSurface.getBounds().width());
			imgHeight = MAX(imgHeight, (int)itemSurface.getBounds().height());

			// Add the item to the display list
			GfxInvImage *img = new GfxInvImage();
			_images.push_back(img);
			img->setDetails(invObject->_displayResNum, invObject->_rlbNum, invObject->_cursorNum);
			img->_invObject = invObject;
			add(img);
		}
	}
	assert(_images.size() > 0);

	// Figure out the number of columns/rows to show all the items
	int cellsSize = 3;
	while ((cellsSize * cellsSize) < (int)_images.size())
		++cellsSize;

	// Set the position of each inventory item to be displayed
	int cellX = 0;
	Common::Point pt(0, 0);

	for (uint idx = 0; idx < _images.size(); ++idx) {
		if (cellX == cellsSize) {
			// Move to the start of the next line
			pt.x = 0;
			pt.y += imgHeight + 2;
			cellX = 0;
		}

		_images[idx]->_bounds.moveTo(pt.x, pt.y);

		pt.x += imgWidth + 2;
		++cellX;
	}

	// Set up the buttons
	pt.y += imgHeight + 2;
	_btnOk.setText(OK_BTN_STRING);
	_btnOk._bounds.moveTo((imgWidth + 2) * cellsSize - _btnOk._bounds.width(), pt.y);
	_btnLook.setText(LOOK_BTN_STRING);
	_btnLook._bounds.moveTo(_btnOk._bounds.left - _btnLook._bounds.width() - 2, _btnOk._bounds.top);
	addElements(&_btnLook, &_btnOk, NULL);

	frame();
	setCenter(SCREEN_CENTER_X, SCREEN_CENTER_Y);
}
Пример #2
0
void EventsClass::setCursor(GfxSurface &cursor) {
	Graphics::Surface s = cursor.lockSurface();

	const byte *cursorData = (const byte *)s.getPixels();
	CursorMan.replaceCursor(cursorData, cursor.getBounds().width(), cursor.getBounds().height(),
		cursor._centroid.x, cursor._centroid.y, cursor._transColor);

	_lastCursor = CURSOR_NONE;
}
Пример #3
0
void UIElements::add(UIElement *obj) {
	// Add object
	assert(_objList.size() < 12);
	_objList.push_back(obj);

	obj->setPosition(Common::Point(_bounds.left + obj->_position.x, _bounds.top + obj->_position.y));
	obj->reposition();

	GfxSurface s = obj->getFrame();
	s.draw(obj->_position);
}
Пример #4
0
/**
 * Translates a raw image resource into a graphics surface. The caller is then responsible
 * for managing and destroying the surface when done with it
 *
 * @imgData Raw image resource
 * @size Size of the resource
 */
GfxSurface surfaceFromRes(const byte *imgData) {
	Rect r(0, 0, READ_LE_UINT16(imgData), READ_LE_UINT16(imgData + 2));
	GfxSurface s;
	s.create(r.width(), r.height());
	s._centroid.x = READ_LE_UINT16(imgData + 4);
	s._centroid.y = READ_LE_UINT16(imgData + 6);
	s._transColor = *(imgData + 8);

	bool rleEncoded = (imgData[9] & 2) != 0;

	const byte *srcP = imgData + 10;
	Graphics::Surface destSurface = s.lockSurface();
	byte *destP = (byte *)destSurface.getBasePtr(0, 0);

	if (!rleEncoded) {
		Common::copy(srcP, srcP + (r.width() * r.height()), destP);
	} else {
		Common::set_to(destP, destP + (r.width() * r.height()), s._transColor);

		for (int yp = 0; yp < r.height(); ++yp) {
			int width = r.width();
			destP = (byte *)destSurface.getBasePtr(0, yp);

			while (width > 0) {
				uint8 controlVal = *srcP++;
				if ((controlVal & 0x80) == 0) {
					// Copy specified number of bytes

					Common::copy(srcP, srcP + controlVal, destP);
					width -= controlVal;
					srcP += controlVal;
					destP += controlVal;
				} else if ((controlVal & 0x40) == 0) {
					// Skip a specified number of output pixels
					destP += controlVal & 0x3f;
					width -= controlVal & 0x3f;
				} else {
					// Copy a specified pixel a given number of times
					controlVal &= 0x3f;
					int pixel = *srcP++;

					Common::set_to(destP, destP + controlVal, pixel);
					destP += controlVal;
					width -= controlVal;
				}
			}
			assert(width == 0);
		}
	}

	s.unlockSurface();
	return s;
}
Пример #5
0
void EventsClass::pushCursor(CursorType cursorType) {
	const byte *cursor;
	bool delFlag = true;
	uint size;

	switch (cursorType) {
	case CURSOR_NONE:
		// No cursor
		cursor = _resourceManager->getSubResource(4, 1, 6, &size);
		break;

	case CURSOR_LOOK:
		// Look cursor
		cursor = _resourceManager->getSubResource(4, 1, 5, &size);
		break;

	case CURSOR_USE:
		// Use cursor
		cursor = _resourceManager->getSubResource(4, 1, 4, &size);
		break;

	case CURSOR_TALK:
		// Talk cursor
		cursor = _resourceManager->getSubResource(4, 1, 3, &size);
		break;

	case CURSOR_ARROW:
		// Arrow cursor
		cursor = CURSOR_ARROW_DATA;
		delFlag = false;
		break;

	case CURSOR_WALK:
	default:
		// Walk cursor
		cursor = CURSOR_WALK_DATA;
		delFlag = false;
		break;
	}

	// Decode the cursor
	GfxSurface s = surfaceFromRes(cursor);

	Graphics::Surface surface = s.lockSurface();
	const byte *cursorData = (const byte *)surface.getBasePtr(0, 0);
	CursorMan.pushCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
	s.unlockSurface();

	if (delFlag)
		DEALLOCATE(cursor);
}
Пример #6
0
/**
 * Resizes and positions a given rect based on raw image data and a passed scaling percentage
 *
 * @frame Raw image frame
 * @xp New x position
 * @yp New y position
 * @percent Scaling percentage
 */
void Rect::resize(const GfxSurface &surface, int xp, int yp, int percent) {
	int xe = surface.getBounds().width() * percent / 100;
	int ye = surface.getBounds().height() * percent / 100;
	this->set(0, 0, xe, ye);

	if (!right) ++right;
	if (!bottom) ++bottom;

	this->moveTo(xp, yp);

	int xd = surface._centroid.x * percent / 100;
	int yd = surface._centroid.y * percent / 100;
	this->translate(-xd, -yd);
}
Пример #7
0
void Scene3700::Viewer::draw() {
	Region *priorityRegion = _globals->_sceneManager._scene->_priorities.find(1);

	for (int idx = 0; idx < 4; ++idx) {
		Visage &v = (idx == 0) ? _images1 : _images2;

		GfxSurface img = v.getFrame(_frameList[idx]);
		Rect destRect = img.getBounds();
		destRect.resize(img, (_position.x - _globals->_sceneOffset.x),
			(_position.y  - _globals->_sceneOffset.y - _yDiff), _percentList[idx]);

		destRect.translate(-_globals->_sceneManager._scene->_sceneBounds.left,
			-_globals->_sceneManager._scene->_sceneBounds.top);

		_globals->gfxManager().copyFrom(img, destRect, priorityRegion);
	}
}
Пример #8
0
/**
 * Scales a passed surface, creating a new surface with the result
 * @param srcImage		Source image to scale
 * @param NewWidth		New width for scaled image
 * @param NewHeight		New height for scaled image
 * @remarks Caller is responsible for freeing the returned surface
 */
static GfxSurface ResizeSurface(GfxSurface &src, int xSize, int ySize, int transIndex) {
	GfxSurface s;
	s.create(xSize, ySize);

	Graphics::Surface srcImage = src.lockSurface();
	Graphics::Surface destImage = s.lockSurface();

	int *horizUsage = scaleLine(xSize, srcImage.w);
	int *vertUsage = scaleLine(ySize, srcImage.h);

	// Loop to create scaled version
	for (int yp = 0; yp < ySize; ++yp) {
		byte *destP = (byte *)destImage.getBasePtr(0, yp);

		if (vertUsage[yp] == -1) {
			Common::set_to(destP, destP + xSize, transIndex);
		} else {
			const byte *srcP = (const byte *)srcImage.getBasePtr(0, vertUsage[yp]);

			for (int xp = 0; xp < xSize; ++xp) {
				if (horizUsage[xp] != -1) {
					const byte *tempSrcP = srcP + horizUsage[xp];
					*destP++ = *tempSrcP++;
				} else {
					// Pixel overrun at the end of the line
					*destP++ = transIndex;
				}
			}
		}
	}

	// Unlock surfaces
	src.unlockSurface();
	s.unlockSurface();

	// Delete arrays and return surface
	delete[] horizUsage;
	delete[] vertUsage;
	return s;
}
Пример #9
0
/**
 * Copys an area from one GfxSurface to another
 */
void GfxSurface::copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, Region *priorityRegion) {
	GfxSurface srcImage;
	if (srcBounds.isEmpty())
		return;

	if (srcBounds == src.getBounds())
		srcImage = src;
	else {
		// Set the source image to be the subset specified by the source bounds
		Graphics::Surface srcSurface = src.lockSurface();

		srcImage.create(srcBounds.width(), srcBounds.height());
		Graphics::Surface destSurface = srcImage.lockSurface();

		const byte *srcP = (const byte *)srcSurface.getBasePtr(srcBounds.left, srcBounds.top);
		byte *destP = (byte *)destSurface.pixels;
		for (int yp = srcBounds.top; yp < srcBounds.bottom; ++yp, srcP += srcSurface.pitch, destP += destSurface.pitch) {
			Common::copy(srcP, srcP + srcBounds.width(), destP);
		}

		srcImage.unlockSurface();
		src.unlockSurface();
	}

	if ((destBounds.width() != srcBounds.width()) || (destBounds.height() != srcBounds.height()))
		srcImage = ResizeSurface(srcImage, destBounds.width(), destBounds.height(), src._transColor);

	Graphics::Surface srcSurface = srcImage.lockSurface();
	Graphics::Surface destSurface = lockSurface();

	// Adjust bounds to ensure destination will be on-screen
	int srcX = 0, srcY = 0;
	if (destBounds.left < 0) {
		srcX = -destBounds.left;
		destBounds.left = 0;
	}
	if (destBounds.top < 0) {
		srcY = -destBounds.top;
		destBounds.top = 0;
	}
	if (destBounds.right > destSurface.w)
		destBounds.right = destSurface.w;
	if (destBounds.bottom > destSurface.h)
		destBounds.bottom = destSurface.h;

	if (destBounds.isValidRect()) {
		const byte *pSrc = (const byte *)srcSurface.getBasePtr(srcX, srcY);
		byte *pDest = (byte *)destSurface.getBasePtr(destBounds.left, destBounds.top);

		for (int y = 0; y < destBounds.height(); ++y, pSrc += srcSurface.pitch, pDest += destSurface.pitch) {

			if (!priorityRegion && (src._transColor == -1))
				Common::copy(pSrc, pSrc + destBounds.width(), pDest);
			else {
				const byte *tempSrc = pSrc;
				byte *tempDest = pDest;
				int xp = destBounds.left;

				while (tempSrc < (pSrc + destBounds.width())) {
					if (!priorityRegion || !priorityRegion->contains(Common::Point(
							xp + _globals->_sceneManager._scene->_sceneBounds.left,
							destBounds.top + y + _globals->_sceneManager._scene->_sceneBounds.top))) {
						if (*tempSrc != src._transColor)
							*tempDest = *tempSrc;
					}
					++tempSrc;
					++tempDest;
					++xp;
				}
			}
		}
	}

	unlockSurface();
	srcImage.unlockSurface();
}
Пример #10
0
/**
 * Sets the specified cursor
 *
 * @cursorType Specified cursor number
 */
void EventsClass::setCursor(CursorType cursorType) {
	if (cursorType == _lastCursor)
		return;

	_lastCursor = cursorType;
	_globals->clearFlag(122);
	CursorMan.showMouse(true);

	const byte *cursor;
	bool delFlag = true;
	uint size;

	switch (cursorType) {
	case CURSOR_NONE:
		// No cursor
		_globals->setFlag(122);

		if (_vm->getFeatures() & GF_DEMO) {
			CursorMan.showMouse(false);
			return;
		}
		cursor = _resourceManager->getSubResource(4, 1, 6, &size);
		break;

	case CURSOR_LOOK:
		// Look cursor
		cursor = _resourceManager->getSubResource(4, 1, 5, &size);
		_currentCursor = CURSOR_LOOK;
		break;

	case CURSOR_USE:
		// Use cursor
		cursor = _resourceManager->getSubResource(4, 1, 4, &size);
		_currentCursor = CURSOR_USE;
		break;

	case CURSOR_TALK:
		// Talk cursor
		cursor = _resourceManager->getSubResource(4, 1, 3, &size);
		_currentCursor = CURSOR_TALK;
		break;

	case CURSOR_ARROW:
		// Arrow cursor
		cursor = CURSOR_ARROW_DATA;
		delFlag = false;
		break;

	case CURSOR_WALK:
	default:
		// Walk cursor
		cursor = CURSOR_WALK_DATA;
		_currentCursor = CURSOR_WALK;
		delFlag = false;
		break;
	}

	// Decode the cursor
	GfxSurface s = surfaceFromRes(cursor);

	Graphics::Surface surface = s.lockSurface();
	const byte *cursorData = (const byte *)surface.getBasePtr(0, 0);
	CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
	s.unlockSurface();

	if (delFlag)
		DEALLOCATE(cursor);
}
Пример #11
0
/**
 * Sets the specified cursor
 *
 * @cursorType Specified cursor number
 */
void EventsClass::setCursor(CursorType cursorType) {
	if (cursorType == _lastCursor)
		return;

	_lastCursor = cursorType;
	g_globals->clearFlag(122);
	CursorMan.showMouse(true);

	const byte *cursor;
	bool delFlag = true;
	uint size;
	bool questionEnabled = false;

	switch (cursorType) {
	case CURSOR_NONE:
		// No cursor
		g_globals->setFlag(122);

		if ((g_vm->getGameID() != GType_Ringworld) || ((g_vm->getGameID() == GType_Ringworld) && (g_vm->getFeatures() & GF_DEMO)))  {
			CursorMan.showMouse(false);
			return;
		}
		cursor = g_resourceManager->getSubResource(4, 1, 6, &size);
		break;

	case CURSOR_LOOK:
		// Look cursor
		if (g_vm->getGameID() == GType_BlueForce) {
			cursor = g_resourceManager->getSubResource(1, 5, 3, &size);
		} else if (g_vm->getGameID() == GType_Ringworld2) {
			cursor = g_resourceManager->getSubResource(5, 1, 5, &size);
		} else {
			cursor = g_resourceManager->getSubResource(4, 1, 5, &size);
		}
		_currentCursor = CURSOR_LOOK;
		break;

	case CURSOR_USE:
		// Use cursor
		if (g_vm->getGameID() == GType_BlueForce) {
			cursor = g_resourceManager->getSubResource(1, 5, 2, &size);
		} else if (g_vm->getGameID() == GType_Ringworld2) {
			cursor = g_resourceManager->getSubResource(5, 1, 4, &size);
		} else {
			cursor = g_resourceManager->getSubResource(4, 1, 4, &size);
		}
		_currentCursor = CURSOR_USE;
		break;

	case CURSOR_TALK:
		// Talk cursor
		if (g_vm->getGameID() == GType_BlueForce) {
			cursor = g_resourceManager->getSubResource(1, 5, 4, &size);
		} else if (g_vm->getGameID() == GType_Ringworld2) {
			cursor = g_resourceManager->getSubResource(5, 1, 6, &size);
		} else {
			cursor = g_resourceManager->getSubResource(4, 1, 3, &size);
		}
		_currentCursor = CURSOR_TALK;
		break;

	case CURSOR_EXIT:
		// Exit cursor (Blue Force)
		assert(g_vm->getGameID() == GType_BlueForce);
		cursor = g_resourceManager->getSubResource(1, 5, 7, &size);
		_currentCursor = CURSOR_EXIT;
		break;

	case CURSOR_PRINTER:
		// Printer cursor (Blue Force)
		assert(g_vm->getGameID() == GType_BlueForce);
		cursor = g_resourceManager->getSubResource(1, 7, 6, &size);
		_currentCursor = CURSOR_PRINTER;
		break;

	case CURSOR_ARROW:
		// Arrow cursor
		cursor = CURSOR_ARROW_DATA;
		delFlag = false;
		break;

	case CURSOR_WALK:
	default:
		switch (g_vm->getGameID()) {
		case GType_BlueForce:
			if (cursorType == CURSOR_WALK) {
				cursor = g_resourceManager->getSubResource(1, 5, 1, &size);
			} else {
				// Inventory icon
				cursor = g_resourceManager->getSubResource(10, ((int)cursorType - 1) / 20 + 1,
					((int)cursorType - 1) % 20 + 1, &size);
				questionEnabled = true;
			}
			_currentCursor = cursorType;
			break;
		case GType_Ringworld2:
			if (cursorType == CURSOR_WALK) {
				cursor = CURSOR_WALK_DATA;
				delFlag = false;
			} else {
				// Inventory icon
				InvObject *invObject = g_globals->_inventory->getItem((int)cursorType);
				cursor = g_resourceManager->getSubResource(6, invObject->_strip, invObject->_frame, &size);
				questionEnabled = true;
			}
			_currentCursor = cursorType;
			break;
		default:
			// For Ringworld, always treat as the walk cursor
			cursor = CURSOR_WALK_DATA;
			_currentCursor = CURSOR_WALK;
			delFlag = false;
			break;
		}
		break;

	// Ringworld 2 specific cursors
	case EXITCURSOR_N:
	case EXITCURSOR_S:
	case EXITCURSOR_W:
	case EXITCURSOR_E:
	case EXITCURSOR_LEFT_HAND:
	case CURSOR_INVALID:
	case EXITCURSOR_NE:
	case EXITCURSOR_SE:
	case EXITCURSOR_SW:
	case EXITCURSOR_NW:
	case SHADECURSOR_UP:
	case SHADECURSOR_DOWN:
	case SHADECURSOR_HAND:
		_currentCursor = cursorType;
		cursor = g_resourceManager->getSubResource(5, 1, cursorType - R2CURSORS_START, &size);
		break;

	case R2_CURSOR_ROPE:
		_currentCursor = cursorType;
		cursor = g_resourceManager->getSubResource(5, 4, 1, &size);
		break;
	}

	// Decode the cursor
	GfxSurface s = surfaceFromRes(cursor);

	Graphics::Surface surface = s.lockSurface();
	const byte *cursorData = (const byte *)surface.getPixels();
	CursorMan.replaceCursor(cursorData, surface.w, surface.h, s._centroid.x, s._centroid.y, s._transColor);
	s.unlockSurface();

	if (delFlag)
		DEALLOCATE(cursor);

	// For Blue Force and Return to Ringworld, enable the question button when an inventory icon is selected
	if (g_vm->getGameID() != GType_Ringworld)
		T2_GLOBALS._uiElements._question.setEnabled(questionEnabled);
}
Пример #12
0
void ModalDialog::drawFrame() {
	Rect origRect = _bounds;
	_bounds.collapse(-10, -10);

	if (g_vm->getGameID() == GType_Ringworld2) {
		GfxElement::drawFrame();
	} else {
		// Fill the dialog area
		g_globals->gfxManager().fillRect(origRect, 54);

		// Draw top line
		GfxSurface surface = surfaceFromRes(8, 1, 7);
		for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
			surface.draw(Common::Point(xp, _bounds.top));
		surface.draw(Common::Point(_bounds.right - 20, _bounds.top));

		surface = surfaceFromRes(8, 1, 1);
		surface.draw(Common::Point(_bounds.left, _bounds.top));

		surface = surfaceFromRes(8, 1, 4);
		surface.draw(Common::Point(_bounds.right - 10, _bounds.top));

		// Draw vertical edges
		surface = surfaceFromRes(8, 1, 2);
		for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
			surface.draw(Common::Point(_bounds.left, yp));
		surface.draw(Common::Point(_bounds.left, _bounds.bottom - 20));

		surface = surfaceFromRes(8, 1, 5);
		for (int yp = _bounds.top + 10; yp < (_bounds.bottom - 20); yp += 10)
			surface.draw(Common::Point(_bounds.right - 10, yp));
		surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 20));

		// Draw bottom line
		surface = surfaceFromRes(8, 1, 8);
		for (int xp = _bounds.left + 10; xp < (_bounds.right - 20); xp += 10)
			surface.draw(Common::Point(xp, _bounds.bottom - 10));
		surface.draw(Common::Point(_bounds.right - 20, _bounds.bottom - 10));

		surface = surfaceFromRes(8, 1, 3);
		surface.draw(Common::Point(_bounds.left, _bounds.bottom - 10));

		surface = surfaceFromRes(8, 1, 6);
		surface.draw(Common::Point(_bounds.right - 10, _bounds.bottom - 10));
	}

	// Set the dialog's manager bounds
	_gfxManager._bounds = origRect;
}