コード例 #1
0
ファイル: tspit.cpp プロジェクト: AReim1982/scummvm
void TSpit::xtakeit(const ArgumentArray &args) {
	// Pick up and move a marble

	// First, let's figure out what marble we're now holding
	uint32 &marble = _vm->_vars["themarble"];
	marble = 0;

	for (uint32 i = 0; i < kMarbleCount; i++) {
		RivenHotspot *marbleHotspot = _vm->getCard()->getHotspotByName(s_marbleNames[i]);
		if (marbleHotspot->containsPoint(getMousePosition())) {
			marble = i + 1;
			break;
		}
	}

	// xtakeit() shouldn't be called if we're not on a marble hotspot
	assert(marble != 0);

	// Redraw the background
	_vm->getCard()->drawPicture(1);

	// Loop until the player lets go (or quits)
	while (mouseIsDown() && !_vm->hasGameEnded()) {
		_vm->doFrame();
	}

	// Check if we landed in a valid location and no other marble has that location
	uint32 &marblePos = _vm->_vars[s_marbleNames[marble - 1]];

	bool foundMatch = false;
	for (int y = 0; y < 25 && !foundMatch; y++) {
		for (int x = 0; x < 25 && !foundMatch; x++) {
			Common::Rect testHotspot = generateMarbleGridRect(x, y);

			// Let's try to place the marble!
			if (testHotspot.contains(getMousePosition())) {
				// Set this as the position
				setMarbleX(marblePos, x);
				setMarbleY(marblePos, y);

				// Let's make sure no other marble is in this spot...
				for (uint16 i = 0; i < kMarbleCount; i++)
					if (i != marble - 1 && _vm->_vars[s_marbleNames[i]] == marblePos)
						marblePos = 0;

				// We have a match
				foundMatch = true;
			}
		}
	}

	// If we still don't have a match, reset it to the original location
	if (!foundMatch)
		marblePos = 0;

	// Check the new hotspots and refresh everything
	marble = 0;
	setMarbleHotspots();
	drawMarbles();
}
コード例 #2
0
ファイル: render.cpp プロジェクト: michailBs/scummvm
void Render::addDirtyRect(Common::Rect r) {
	if (_fullRefresh)
		return;

	// Clip rectangle
	r.clip(_backGroundSurface.w, _backGroundSurface.h);

	// If it is empty after clipping, we are done
	if (r.isEmpty())
		return;

	// Check if the new rectangle is contained within another in the list
	Common::List<Common::Rect>::iterator it;
	for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ) {
		// If we find a rectangle which fully contains the new one,
		// we can abort the search.
		if (it->contains(r))
			return;

		// Conversely, if we find rectangles which are contained in
		// the new one, we can remove them
		if (r.contains(*it))
			it = _dirtyRects.erase(it);
		else
			++it;
	}

	// If we got here, we can safely add r to the list of dirty rects.
	if (_vm->_interface->getFadeMode() != kFadeOut)
		_dirtyRects.push_back(r);
}
コード例 #3
0
ファイル: cstime_ui.cpp プロジェクト: Termimad/scummvm
void CSTimeHelp::mouseMove(Common::Point &pos) {
	bool mouseIsDown = _vm->getEventManager()->getButtonState() & 1;

	for (uint i = 0; i < _qars.size(); i++) {
		Common::Rect thisRect = _vm->getInterface()->_dialogTextRect;
		thisRect.top += 1 + i*15;
		thisRect.bottom = thisRect.top + 15;
		if (!thisRect.contains(pos))
			continue;

		if (mouseIsDown) {
			if (i != _currEntry)
				break;
			highlightLine(i);
		}

		_vm->getInterface()->cursorOverHotspot();
		_currHover = i;
		return;
	}

	if (_currHover != 0xffff) {
		if (_vm->getInterface()->cursorGetShape() != 3) {
			unhighlightLine(_currHover);
			_vm->getInterface()->cursorSetShape(1);
		}
		_currHover = 0xffff;
	}
}
コード例 #4
0
ファイル: ThemeEngine.cpp プロジェクト: megaboy/scummvm
void ThemeEngine::addDirtyRect(Common::Rect r) {
	// Clip the rect to screen coords
	r.clip(_screen.w, _screen.h);

	// If it is empty after clipping, we are done
	if (r.isEmpty())
		return;

	// Check if the new rectangle is contained within another in the list
	Common::List<Common::Rect>::iterator it;
	for (it = _dirtyScreen.begin(); it != _dirtyScreen.end();) {
		// If we find a rectangle which fully contains the new one,
		// we can abort the search.
		if (it->contains(r))
			return;

		// Conversely, if we find rectangles which are contained in
		// the new one, we can remove them
		if (r.contains(*it))
			it = _dirtyScreen.erase(it);
		else
			++it;
	}

	// If we got here, we can safely add r to the list of dirty rects.
	_dirtyScreen.push_back(r);
}
コード例 #5
0
ファイル: script.cpp プロジェクト: havlenapetr/Scummvm
bool Script::hotspot(Common::Rect rect, uint16 address, uint8 cursor) {
	// Test if the current mouse position is contained in the specified rectangle
	Common::Point mousepos = _vm->_system->getEventManager()->getMousePos();
	bool contained = rect.contains(mousepos);

	// Show hotspots when debugging
	if (Common::isDebugChannelEnabled(kGroovieDebugHotspots) ||
	    Common::isDebugChannelEnabled(kGroovieDebugAll)) {
		rect.translate(0, -80);
		_vm->_graphicsMan->_foreground.frameRect(rect, 250);
		_vm->_system->copyRectToScreen((byte*)_vm->_graphicsMan->_foreground.getBasePtr(0, 0), 640, 0, 80, 640, 320);
		_vm->_system->updateScreen();
	}

	// If there's an already planned action, do nothing
	if (_inputAction != -1) {
		return false;
	}

	if (contained) {
		// Change the mouse cursor
		if (_newCursorStyle == 5) {
			_newCursorStyle = cursor;
		}

		// If clicked with the mouse, jump to the specified address
		if (_mouseClicked) {
			_inputAction = address;
		}
	}

	return contained;
}
コード例 #6
0
ファイル: gui_br.cpp プロジェクト: AlbanBedel/scummvm
	MenuInputState *run() {
		if (_vm->_input->getLastButtonEvent() != kMouseLeftUp) {
			return this;
		}

		int cell = -1;

		Common::Point p;
		_vm->_input->getCursorPos(p);
		if (_menuRect.contains(p)) {
			cell = (p.x - _menuRect.left) / _cellW + 3 * ((p.y - _menuRect.top) / _cellH);
		}

		bool close = false;

		switch (cell) {
		case 4:	// resume
		case -1: // invalid cell
			close = true;
			break;

		case 0:	// toggle music
			if (_mscStatus != -1) {
				_vm->enableMusic(!_mscStatus);
				_mscStatus = _vm->getMusicStatus();
				_vm->_gfx->setItemFrame(_mscMenuObjId, frameFromStatus(_mscStatus));
			}
			break;

		case 1:	// toggle sfx
			if (_sfxStatus != -1) {
				_vm->enableSfx(!_sfxStatus);
				_sfxStatus = _vm->getSfxStatus();
				_vm->_gfx->setItemFrame(_sfxMenuObjId, frameFromStatus(_sfxStatus));
			}
			break;

		case 2:	// save
			warning("Saving is not supported yet");
			_vm->_saveLoad->saveGame();
			break;

		case 3:	// load
			warning("Loading is not supported yet");
			close = _vm->_saveLoad->loadGame();
			break;

		case 5:	// quit
			return _helper->getState("quitdialog");
		}

		if (close) {
			_vm->_gfx->freeDialogueObjects();
			return 0;
		}

		_vm->_input->setArrowCursor();
		return this;
	}
コード例 #7
0
ファイル: inventory.cpp プロジェクト: havlenapetr/Scummvm
ItemPosition InventoryRenderer::hitTest(const Common::Point &p) const {
    Common::Rect r;
    getRect(r);
    if (!r.contains(p))
        return -1;

    return ((p.x - _pos.x) / _props->_itemWidth) + (_props->_itemsPerLine * ((p.y - _pos.y) / _props->_itemHeight));
}
コード例 #8
0
ファイル: objects.cpp プロジェクト: AlbanBedel/scummvm
bool Animation::hitFrameRect(int x, int y) const {
	if (!gfxobj) {
		return false;
	}
	Common::Rect r;
	getFrameRect(r);
	return r.contains(x, y);
}
コード例 #9
0
ファイル: cstime_ui.cpp プロジェクト: Termimad/scummvm
void CSTimeHelp::mouseDown(Common::Point &pos) {
	for (uint i = 0; i < _qars.size(); i++) {
		Common::Rect thisRect = _vm->getInterface()->_dialogTextRect;
		thisRect.top += 1 + i*15;
		thisRect.bottom = thisRect.top + 15;
		if (!thisRect.contains(pos))
			continue;

		_currEntry = i;
		highlightLine(i);
		_vm->getInterface()->cursorSetShape(5);
	}
}
コード例 #10
0
ファイル: cstime_ui.cpp プロジェクト: Termimad/scummvm
void CSTimeHelp::mouseUp(Common::Point &pos) {
	if (_currEntry == 0xffff || _qars[_currEntry].speech == 0) {
		_vm->getInterface()->cursorSetShape(1);
		end();
		return;
	}

	Common::Rect thisRect = _vm->getInterface()->_dialogTextRect;
	thisRect.top += 1 + _currEntry*15;
	thisRect.bottom = thisRect.top + 15;
	if (!thisRect.contains(pos))
		return;

	_vm->addEvent(CSTimeEvent(kCSTimeEventCharStartFlapping, _vm->getCase()->getCurrScene()->getHelperId(), 5900 + _qars[_currEntry].speech));
	_nextToProcess = _currEntry;
	_askedAlready.push_back(_qars[_currEntry].text);
}
コード例 #11
0
ファイル: processroom.cpp プロジェクト: 86400/scummvm
const CloseData *LabEngine::getObject(Common::Point pos, const CloseData *closePtr) {
	const CloseDataList *list;
	if (!closePtr)
		list = &(getViewData(_roomNum, _direction)->_closeUps);
	else
		list = &(closePtr->_subCloseUps);

	CloseDataList::const_iterator wrkClosePtr;

	for (wrkClosePtr = list->begin(); wrkClosePtr != list->end(); ++wrkClosePtr) {
		Common::Rect objRect;
		objRect = _utils->rectScale(wrkClosePtr->_x1, wrkClosePtr->_y1, wrkClosePtr->_x2, wrkClosePtr->_y2);
		if (objRect.contains(pos))
			return &(*wrkClosePtr);
	}

	return nullptr;
}
コード例 #12
0
ファイル: hotspot.cpp プロジェクト: Harrypoppins/grim_mouse
int32 HotSpot::isPointInRectsCube(const Common::Point &p) {
	for (uint j = 0; j < rects.size(); j++) {
		Common::Rect rect = Common::Rect(
				rects[j].centerHeading - rects[j].width / 2,
				rects[j].centerPitch - rects[j].height / 2,
				rects[j].centerHeading + rects[j].width / 2,
				rects[j].centerPitch + rects[j].height / 2);

		// Make sure heading is in the correct range
		Common::Point lookAt = p;
		if (rect.right > 360 && lookAt.x <= rect.right - 360)
			lookAt.x += 360;

		if (rect.contains(lookAt))
			return j;
	}

	return -1;
}
コード例 #13
0
ファイル: surface.cpp プロジェクト: MaddTheSane/scummvm
/**
 * @brief Marks a dirty rectangle on the surface
 * @param r The rectangle to be marked dirty
 */
void Surface::markDirtyRect(Common::Rect r) {
	Common::List<Common::Rect>::iterator it;

	r.clip(w, h);

	if (r.isEmpty())
		return;

	it = _dirtyRects.begin();
	while (it != _dirtyRects.end()) {
		if (it->contains(r))
			return;

		if (r.contains(*it))
			it = _dirtyRects.erase(it);
		else
			++it;
	}

	_dirtyRects.push_back(r);
}
コード例 #14
0
ファイル: hotspot.cpp プロジェクト: Botje/residualvm
int32 HotSpot::isPointInRectsFrame(GameState *state, const Common::Point &p) {
	for (uint j = 0; j < rects.size(); j++) {
		int16 x = rects[j].centerPitch;
		int16 y = rects[j].centerHeading;
		int16 w = rects[j].width;
		int16 h = rects[j].height;

		if (y < 0) {
			x = state->getVar(x);
			y = state->getVar(-y);
			h = -h;
		}

		Common::Rect rect = Common::Rect(w, h);
		rect.translate(x, y);
		if (rect.contains(p))
			return j;
	}

	return -1;
}
コード例 #15
0
ファイル: processroom.cpp プロジェクト: 86400/scummvm
bool LabEngine::takeItem(Common::Point pos) {
	const CloseDataList *list;
	if (!_closeDataPtr) {
		list = &(getViewData(_roomNum, _direction)->_closeUps);
	} else if (_closeDataPtr->_closeUpType < 0) {
		_conditions->inclElement(abs(_closeDataPtr->_closeUpType));
		return true;
	} else
		list = &(_closeDataPtr->_subCloseUps);

	CloseDataList::const_iterator closePtr;
	for (closePtr = list->begin(); closePtr != list->end(); ++closePtr) {
		Common::Rect objRect;
		objRect = _utils->rectScale(closePtr->_x1, closePtr->_y1, closePtr->_x2, closePtr->_y2);
		if (objRect.contains(pos) && (closePtr->_closeUpType < 0)) {
			_conditions->inclElement(abs(closePtr->_closeUpType));
			return true;
		}
	}

	return false;
}
コード例 #16
0
ファイル: processroom.cpp プロジェクト: 86400/scummvm
void LabEngine::setCurrentClose(Common::Point pos, const CloseData **closePtrList, bool useAbsoluteCoords, bool next) {
	const CloseDataList *list;

	if (!*closePtrList)
		list = &(getViewData(_roomNum, _direction)->_closeUps);
	else
		list = &((*closePtrList)->_subCloseUps);

	CloseDataList::const_iterator closePtr;
	for (closePtr = list->begin(); closePtr != list->end(); ++closePtr) {
		Common::Rect target;
		if (!useAbsoluteCoords)
			target = Common::Rect(closePtr->_x1, closePtr->_y1, closePtr->_x2, closePtr->_y2);
		else
			target = _utils->rectScale(closePtr->_x1, closePtr->_y1, closePtr->_x2, closePtr->_y2);

		if (target.contains(pos) && (next || !closePtr->_graphicName.empty())) {

			if (next) {
				// cycle to the next one
				++closePtr;
				if (closePtr == list->end())
					closePtr = list->begin();
			}
			*closePtrList = &(*closePtr);

			return;
		}
	}

	// If we got here, no match was found. If we want the "next" close-up,
	// return the first one in the list, if any.
	if (next) {
		if (!list->empty())
			*closePtrList = &(*list->begin());
	}
}
コード例 #17
0
ファイル: widget_verbs.cpp プロジェクト: winterheart/scummvm
void WidgetVerbs::highlightVerbControls() {
	Events &events = *_vm->_events;
	Screen &screen = *_vm->_screen;
	Common::Point mousePos = events.mousePos();

	// Get highlighted verb
	_selector = -1;
	Common::Rect bounds = _bounds;
	bounds.grow(-3);
	if (bounds.contains(mousePos))
		_selector = (mousePos.y - bounds.top) / (screen.fontHeight() + 7);

	// See if a new verb is being pointed at
	if (_selector != _oldSelector) {
		// Redraw the verb list
		for (int idx = 0; idx < (int)_verbCommands.size(); ++idx) {
			byte color = (idx == _selector) ? (byte)COMMAND_HIGHLIGHTED : (byte)INFO_TOP;
			_surface.writeString(_verbCommands[idx], Common::Point((_bounds.width() - screen.stringWidth(_verbCommands[idx])) / 2,
				(screen.fontHeight() + 7) * idx + 5), color);
		}

		_oldSelector = _selector;
	}
}
コード例 #18
0
ファイル: ospit.cpp プロジェクト: BenCastricum/scummvm
void OSpit::xbookclick(const ArgumentArray &args) {
	// Let's hook onto our video
	RivenVideo *video = _vm->_video->getSlot(args[0]);

	// Convert from the standard QuickTime base time to milliseconds
	// The values are in terms of 1/600 of a second.
	// Have I said how much I just *love* QuickTime? </sarcasm>
	uint32 startTime = args[1] * 1000 / 600;
	uint32 endTime = args[2] * 1000 / 600;

	// Track down our hotspot
	Common::String hotspotName = Common::String::format("touchBook%d", args[3]);
	RivenHotspot *hotspot = _vm->getCard()->getHotspotByName(hotspotName);
	Common::Rect hotspotRect = hotspot->getRect();

	debug(0, "xbookclick:");
	debug(0, "\tVideo Code = %d", args[0]);
	debug(0, "\tStart Time = %dms", startTime);
	debug(0, "\tEnd Time   = %dms", endTime);
	debug(0, "\tHotspot    = %d -> %s", args[3], hotspotName.c_str());

	// Just let the video play while we wait until Gehn opens the trap book for us
	while (video->getTime() < startTime && !_vm->hasGameEnded()) {
		_vm->doFrame();
	}

	// Break out if we're quitting
	if (_vm->hasGameEnded())
		return;

	// OK, Gehn has opened the trap book and has asked us to go in. Let's watch
	// and see what the player will do...
	while (video->getTime() < endTime && !_vm->hasGameEnded()) {
		if (hotspotRect.contains(getMousePosition()))
			_vm->_cursor->setCursor(kRivenOpenHandCursor);
		else
			_vm->_cursor->setCursor(kRivenMainCursor);

		if (mouseIsDown()) {
			if (hotspotRect.contains(getMousePosition())) {
				// OK, we've used the trap book! We go for ride lady!
				_vm->_video->closeVideos();                          // Stop all videos
				_vm->_cursor->setCursor(kRivenHideCursor);          // Hide the cursor
				_vm->_gfx->scheduleTransition(kRivenTransitionBlend);
				_vm->getCard()->drawPicture(3);                  // Black out the screen
				_vm->_sound->playSound(0);                          // Play the link sound
				_vm->delay(12000);
				_vm->getCard()->playMovie(7);    // Activate Gehn Link Video
				RivenVideo *linkVideo = _vm->_video->openSlot(1);             // Play Gehn Link Video
				linkVideo->playBlocking();
				_vm->_vars["ocage"] = 1;
				_vm->_vars["agehn"] = 4;                            // Set Gehn to the trapped state
				_vm->_vars["atrapbook"] = 1;                        // We've got the trap book again
				_vm->_sound->playSound(0);                          // Play the link sound again
				_vm->_gfx->scheduleTransition(kRivenTransitionBlend);
				_vm->changeToCard(_vm->getStack()->getCardStackId(0x2885));    // Link out!
				_vm->_inventory->forceVisible(true);
				_vm->delay(2000);
				_vm->_inventory->forceVisible(false);
				_vm->_scriptMan->stopAllScripts();                  // Stop all running scripts (so we don't remain in the cage)
				return;
			}
		}

		_vm->doFrame();
	}

	// Break out if we're quitting
	if (_vm->hasGameEnded())
		return;

	// If there was no click and this is the third time Gehn asks us to
	// use the trap book, he will shoot the player. Dead on arrival.
	// Run the credits from here.
	if (_vm->_vars["agehn"] == 3) {
		runCredits(args[0], 5000, 995);
		return;
	}

	// There was no click, so just play the rest of the video.
	video->playBlocking();
}
コード例 #19
0
ファイル: events.cpp プロジェクト: Templier/scummvm-test
TestExitStatus EventTests::mouseEvents() {

	Testsuite::clearScreen();
	Common::String info = "Testing Mouse events.\n "
	"Any movement/click generated by L/R/M mouse buttons or the mouse wheel should be detected.\n"
	"Press X to exit";

	if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
		Testsuite::logPrintf("Info! Skipping test : keyboard events\n");
		return kTestSkipped;
	}

	Common::EventManager *eventMan = g_system->getEventManager();

	Common::Point pt(0, 30);
	Common::Rect rectInfo = Testsuite::writeOnScreen("Generate mouse events make L/R/M button clicks, move wheel", pt);
	pt.y += 15;
	Testsuite::writeOnScreen("Press X to exit", pt);
	pt.y = 70;
	Common::Rect rectLB = Testsuite::writeOnScreen("Left-button click : Not tested", pt);
	pt.y += 15;
	Common::Rect rectRB = Testsuite::writeOnScreen("Right-button click : Not tested", pt);
	pt.y += 15;
	Common::Rect rectMB = Testsuite::writeOnScreen("Middle-button click : Not tested", pt);
	pt.y += 15;
	Common::Rect rectWheel = Testsuite::writeOnScreen("Wheel Movements : Not tested", pt);


	// Init Mouse Palette
	GFXtests::initMousePalette();
	Common::Rect finishZone = drawFinishZone();

	bool quitLoop = false;
	TestExitStatus passed = kTestPassed;
	// handle all mouse events
	Common::Event event;
	while (!quitLoop) {
		// Show mouse
		CursorMan.showMouse(true);
		g_system->updateScreen();

		while (eventMan->pollEvent(event)) {
			// Quit if explicitly requested
			if (Engine::shouldQuit()) {
				return passed;
			}
			switch (event.type) {
			case Common::EVENT_MOUSEMOVE:
				// Movements havee already been tested in GFX
				break;
			case Common::EVENT_LBUTTONDOWN:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse left-button pressed", Common::Point(rectInfo.left, rectInfo.top));
				break;
			case Common::EVENT_RBUTTONDOWN:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse right-button pressed", Common::Point(rectInfo.left, rectInfo.top));
				break;
			case Common::EVENT_WHEELDOWN:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse wheel moved down", Common::Point(rectInfo.left, rectInfo.top));
				Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top));
				break;
			case Common::EVENT_MBUTTONDOWN:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse middle-button pressed ", Common::Point(rectInfo.left, rectInfo.top));
				break;
			case Common::EVENT_LBUTTONUP:
				Testsuite::clearScreen(rectInfo);
				if (finishZone.contains(eventMan->getMousePos())) {
					quitLoop = true;
				}
				Testsuite::writeOnScreen("Mouse left-button released", Common::Point(rectInfo.left, rectInfo.top));
				Testsuite::writeOnScreen("Left-button clicks : Done!", Common::Point(rectLB.left, rectLB.top));
				break;
			case Common::EVENT_RBUTTONUP:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse right-button released", Common::Point(rectInfo.left, rectInfo.top));
				Testsuite::writeOnScreen("Right-button clicks : Done!", Common::Point(rectRB.left, rectRB.top));
				break;
			case Common::EVENT_WHEELUP:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse wheel moved up", Common::Point(rectInfo.left, rectInfo.top));
				Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top));
				break;
			case Common::EVENT_MBUTTONUP:
				Testsuite::clearScreen(rectInfo);
				Testsuite::writeOnScreen("Mouse middle-button released ", Common::Point(rectInfo.left, rectInfo.top));
				Testsuite::writeOnScreen("Middle-button clicks : Done!", Common::Point(rectMB.left, rectMB.top));
				break;
			case Common::EVENT_KEYDOWN:
				if (event.kbd.keycode == Common::KEYCODE_x) {
					Testsuite::clearScreen(rectInfo);
					Testsuite::writeOnScreen("Exit requested", Common::Point(rectInfo.left, rectInfo.top));
					quitLoop = true;
				}
				break;
			default:
				break;
			}

		}
	}

	CursorMan.showMouse(false);

	// Verify results now!
	if (Testsuite::handleInteractiveInput("Were mouse clicks (L/R/M buttons) and wheel movements identfied ?", "Yes", "No", kOptionRight)) {
		Testsuite::logDetailedPrintf("Mouse clicks (L/R/M buttons) and wheel movements failed");
		passed = kTestFailed;
	}

	return passed;
}
コード例 #20
0
ファイル: keyboard.cpp プロジェクト: NickPepper/scummvm
bool AgiEngine::handleMouseClicks(uint16 &key) {
	// No mouse click? -> exit
	if (key != AGI_MOUSE_BUTTON_LEFT)
		return false;

	if (!cycleInnerLoopIsActive()) {
		// Only do this, when no inner loop is currently active
		Common::Rect displayLineRect = _gfx->getFontRectForDisplayScreen(0, 0, FONT_COLUMN_CHARACTERS, 1);
//		Common::Rect displayLineRect(_gfx->getDisplayScreenWidth(), _gfx->getDisplayFontHeight());

		if (displayLineRect.contains(_mouse.pos)) {
			// Mouse is inside first line of the screen
			if (getFlag(VM_FLAG_MENUS_ACCESSIBLE) && _menu->isAvailable()) {
				_menu->delayedExecuteViaMouse();
				key = 0; // eat event
				return true;
			}
		}

		if (_text->promptIsEnabled()) {
			// Prompt is currently enabled
			int16 promptRow = _text->promptRow_Get();

			displayLineRect.moveTo(0, promptRow * _gfx->getDisplayFontHeight());

			if (displayLineRect.contains(_mouse.pos)) {
				// and user clicked within the line of the prompt
				showPredictiveDialog();

				key = 0; // eat event
				return true;
			}
		}
	}

	if (cycleInnerLoopIsActive()) {
		// inner loop active, check what kind of loop it is. Then process / forward it
		switch (_game.cycleInnerLoopType) {
		case CYCLE_INNERLOOP_GETSTRING:
		case CYCLE_INNERLOOP_GETNUMBER: {
			// process in here
			int16 stringRow, stringColumn, stringMaxLen;

			_text->stringPos_Get(stringRow, stringColumn);
			stringMaxLen = _text->stringGetMaxLen();

			Common::Rect displayRect = _gfx->getFontRectForDisplayScreen(stringColumn, stringRow, stringMaxLen, 1);
			if (displayRect.contains(_mouse.pos)) {
				// user clicked inside the input space
				showPredictiveDialog();

				key = 0; // eat event
				return true;
			}
			break;
		}
		case CYCLE_INNERLOOP_INVENTORY:
			// TODO: forward
			break;

		case CYCLE_INNERLOOP_MENU_VIA_KEYBOARD:
			_menu->mouseEvent(key);
			key = 0; // eat event
			break;

		case CYCLE_INNERLOOP_SYSTEMUI_SELECTSAVEDGAMESLOT:
			// TODO: forward
			break;

		default:
			break;
		}
	}
	return false;
}
コード例 #21
0
ファイル: map.cpp プロジェクト: Cruel/scummvm
void LabEngine::processMap(uint16 curRoom) {
	byte place = 1;
	uint16 curMsg = curRoom;
	uint16 curFloor = _maps[curRoom]._pageNumber;

	while (1) {
		IntuiMessage *msg = _event->getMsg();
		if (shouldQuit()) {
			_quitLab = true;
			return;
		}

		updateEvents();
		_graphics->screenUpdate();
		_system->delayMillis(10);

		if (!msg) {
			updateEvents();

			byte newcolor[3];

			if (place <= 14) {
				newcolor[0] = 14 << 2;
				newcolor[1] = place << 2;
				newcolor[2] = newcolor[1];
			} else {
				newcolor[0] = 14 << 2;
				newcolor[1] = (28 - place) << 2;
				newcolor[2] = newcolor[1];
			}

			waitTOF();
			_graphics->writeColorRegs(newcolor, 1, 1);
			_interface->handlePressedButton();
			waitTOF();

			place++;

			if (place >= 28)
				place = 1;

		} else {
			uint32 msgClass  = msg->_msgClass;
			uint16 msgCode   = msg->_code;
			uint16 mouseX    = msg->_mouse.x;
			uint16 mouseY    = msg->_mouse.y;

			if ((msgClass == kMessageRightClick) || ((msgClass == kMessageRawKey) && (msgCode == Common::KEYCODE_ESCAPE)))
				return;

			if (msgClass == kMessageButtonUp) {
				if (msgCode == 0) {
					// Quit menu button
					return;
				} else if (msgCode == 1) {
					// Up arrow
					uint16 upperFloor = getUpperFloor(curFloor);
					if (upperFloor != kFloorNone) {
						curFloor = upperFloor;
						_graphics->fade(false);
						drawMap(curRoom, curMsg, curFloor, false);
						_graphics->fade(true);
					}
				} else if (msgCode == 2) {
					// Down arrow
					uint16 lowerFloor = getLowerFloor(curFloor);
					if (lowerFloor != kFloorNone) {
						curFloor = lowerFloor;
						_graphics->fade(false);
						drawMap(curRoom, curMsg, curFloor, false);
						_graphics->fade(true);
					}
				}
			} else if (msgClass == kMessageLeftClick) {
				if ((curFloor == kFloorLower) && _utils->mapRectScale(538, 277, 633, 352).contains(mouseX, mouseY)
					  && floorVisited(kFloorSurMaze)) {
					curFloor = kFloorSurMaze;

					_graphics->fade(false);
					drawMap(curRoom, curMsg, curFloor, false);
					_graphics->fade(true);
				} else if ((curFloor == kFloorMiddle) && _utils->mapRectScale(358, 71, 452, 147).contains(mouseX, mouseY)
							&& floorVisited(kFloorCarnival)) {
					curFloor = kFloorCarnival;

					_graphics->fade(false);
					drawMap(curRoom, curMsg, curFloor, false);
					_graphics->fade(true);
				} else if ((curFloor == kFloorMiddle) && _utils->mapRectScale(557, 325, 653, 401).contains(mouseX, mouseY)
							&& floorVisited(kFloorMedMaze)) {
					curFloor = kFloorMedMaze;

					_graphics->fade(false);
					drawMap(curRoom, curMsg, curFloor, false);
					_graphics->fade(true);
				} else if ((curFloor == kFloorUpper) && _utils->mapRectScale(524, 97, 645, 207).contains(mouseX, mouseY)
							&& floorVisited(kFloorHedgeMaze)) {
					curFloor = kFloorHedgeMaze;

					_graphics->fade(false);
					drawMap(curRoom, curMsg, curFloor, false);
					_graphics->fade(true);
				} else if (mouseX > _utils->mapScaleX(314)) {
					uint16 oldMsg = curMsg;
					Common::Rect curCoords;

					for (int i = 1; i <= _maxRooms; i++) {
						curCoords = roomCoords(i);

						if ((_maps[i]._pageNumber == curFloor)
							  && _roomsFound->in(i) && curCoords.contains(Common::Point(mouseX, mouseY))) {
							curMsg = i;
						}
					}

					if (oldMsg != curMsg) {
						if (!_rooms[curMsg]._roomMsg.empty())
							_resource->readViews(curMsg);

						const char *sptr;
						if ((sptr = _rooms[curMsg]._roomMsg.c_str())) {
							_graphics->rectFillScaled(13, 148, 135, 186, 3);
							_graphics->flowText(_msgFont, 0, 5, 3, true, true, true, true, _utils->vgaRectScale(14, 148, 134, 186), sptr);

							if (_maps[oldMsg]._pageNumber == curFloor)
								drawRoomMap(oldMsg, (bool)(oldMsg == curRoom));

							curCoords = roomCoords(curMsg);
							int right = (curCoords.left + curCoords.right) / 2;
							int left = right - 1;
							int top, bottom;
							top = bottom = (curCoords.top + curCoords.bottom) / 2;

							if ((curMsg != curRoom) && (_maps[curMsg]._pageNumber == curFloor))
								_graphics->rectFill(left, top, right, bottom, 1);
						}
					}
				}
			}

			_graphics->screenUpdate();
		}
	}	// while
}
コード例 #22
0
uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
	if (numEntries == 0) return 0xffff;
	LureEngine &engine = LureEngine::getReference();
	Events &e = Events::getReference();
	Mouse &mouse = Mouse::getReference();
	OSystem &system = *g_system;
	Screen &screen = Screen::getReference();
	Common::Rect r;
	bool isEGA = LureEngine::getReference().isEGA();
	byte bgColour = isEGA ? EGA_DIALOG_BG_COLOUR : 0;
	byte textColour = isEGA ? EGA_DIALOG_TEXT_COLOUR : VGA_DIALOG_TEXT_COLOUR;
	byte whiteColour = isEGA ? EGA_DIALOG_WHITE_COLOUR : VGA_DIALOG_WHITE_COLOUR;


	const uint16 yMiddle = FULL_SCREEN_HEIGHT / 2;
#ifndef LURE_CLICKABLE_MENUS
	uint16 oldX = mouse.x();
	uint16 oldY = mouse.y();
	mouse.cursorOff();
	mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);

	// Round up number of lines in dialog to next odd number
	uint16 numLines = (numEntries / 2) * 2 + 1;
	if (numLines > 5) numLines = 5;
#else
	mouse.pushCursorNum(CURSOR_ARROW);

	// In WinCE, the whole menu is shown and the items are click-selectable
	uint16 numLines = numEntries;
#endif

	// Figure out the character width
	uint16 numCols = 0;
	for (int ctr = 0; ctr < numEntries; ++ctr) {
		int len = strlen(actions[ctr]);
		if (len > numCols)
			numCols = len;
	}

	// Create the dialog surface
	Common::Point size;
	Surface::getDialogBounds(size, numCols, numLines, false);
	Surface *s = new Surface(size.x, size.y);
	s->createDialog(true);

	int selectedIndex = 0;
	bool refreshFlag = true;
	r.left = Surface::textX();
	r.right = s->width() - Surface::textX() + 1;
	r.top = Surface::textY();
	r.bottom = s->height() - Surface::textY() + 1;

	for (;;) {
		if (refreshFlag) {
			// Set up the contents of the menu
			s->fillRect(r, bgColour);

			for (int index = 0; index < numLines; ++index) {
#ifndef LURE_CLICKABLE_MENUS
				int actionIndex = selectedIndex - (numLines / 2) + index;
#else
				int actionIndex = index;
#endif
				if ((actionIndex >= 0) && (actionIndex < numEntries)) {
					s->writeString(Surface::textX(), Surface::textY() + index * FONT_HEIGHT,
						actions[actionIndex], true,
#ifndef LURE_CLICKABLE_MENUS
						(index == (numLines / 2)) ? whiteColour : textColour,
#else
						(index == selectedIndex) ? whiteColour : textColour,
#endif
						false);
				}
			}

			s->copyToScreen(0, yMiddle-(s->height() / 2));
			system.updateScreen();
			refreshFlag = false;
		}

		while (e.pollEvent()) {
			if (engine.shouldQuit()) {
				selectedIndex = 0xffff;
				goto bail_out;

			} else if (e.type() == Common::EVENT_WHEELUP) {
				// Scroll upwards
				if (selectedIndex > 0) {
					--selectedIndex;
					refreshFlag = true;
				}
			} else if (e.type() == Common::EVENT_WHEELDOWN) {
				// Scroll downwards
				if (selectedIndex < numEntries - 1) {
					++selectedIndex;
					refreshFlag = true;
				}
			} else if (e.type() == Common::EVENT_KEYDOWN) {
				uint16 keycode = e.event().kbd.keycode;

				if (((keycode == Common::KEYCODE_KP8) || (keycode == Common::KEYCODE_UP)) && (selectedIndex > 0)) {
					--selectedIndex;
					refreshFlag = true;
				} else if (((keycode == Common::KEYCODE_KP2) || (keycode == Common::KEYCODE_DOWN)) &&
						(selectedIndex < numEntries-1)) {
					++selectedIndex;
					refreshFlag = true;
				} else if ((keycode == Common::KEYCODE_RETURN) || (keycode == Common::KEYCODE_KP_ENTER)) {
					goto bail_out;
				} else if (keycode == Common::KEYCODE_ESCAPE) {
					selectedIndex = 0xffff;
					goto bail_out;
				}

#ifdef LURE_CLICKABLE_MENUS
			} else if (e.type() == Common::EVENT_LBUTTONDOWN || e.type() == Common::EVENT_MOUSEMOVE) {
				int16 x = mouse.x();
				int16 y = mouse.y() - yMiddle + (s->height() / 2);
				refreshFlag = true;

				if (r.contains(x, y)) {
					selectedIndex = (y - r.top) / FONT_HEIGHT;
					if (e.type() == Common::EVENT_LBUTTONDOWN)
						goto bail_out;
				}
#else
			} else if ((e.type() == Common::EVENT_LBUTTONDOWN) ||
					(e.type() == Common::EVENT_MBUTTONDOWN)) {
				//mouse.waitForRelease();
				goto bail_out;
#endif
			} else if (e.type() == Common::EVENT_RBUTTONDOWN) {
				mouse.waitForRelease();
				selectedIndex = 0xffff;
				goto bail_out;
			}
		}

#ifndef LURE_CLICKABLE_MENUS
		// Warping the mouse to "neutral" even if the top/bottom menu
		// entry has been reached has both pros and cons. It makes the
		// menu behave a bit more sensibly, but it also makes it harder
		// to move the mouse pointer out of the ScummVM window.

		if (mouse.y() < yMiddle - POPMENU_CHANGE_SENSITIVITY) {
			if (selectedIndex > 0) {
				--selectedIndex;
				refreshFlag = true;
			}
			mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
		} else if (mouse.y() > yMiddle + POPMENU_CHANGE_SENSITIVITY) {
			if (selectedIndex < numEntries - 1) {
				++selectedIndex;
				refreshFlag = true;
			}
			mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
		}
#endif

		system.delayMillis(20);
	}

bail_out:
	delete s;

#ifndef LURE_CLICKABLE_MENUS
	mouse.setPosition(oldX, oldY);
	mouse.cursorOn();
#else
	mouse.popCursor();
#endif
	screen.update();
	return selectedIndex;
}
コード例 #23
0
ファイル: clicktext.cpp プロジェクト: Botje/residualvm
bool ClickText::containsPoint(const Common::Point &point) const {
	Common::Rect r = _bbox;
	r.translate(_position.x, _position.y);
	return r.contains(point);
}