Exemplo n.º 1
0
bool AgiEngine::showPredictiveDialog() {
	GUI::PredictiveDialog predictiveDialog;

	inGameTimerPause();
	predictiveDialog.runModal();
	inGameTimerResume();

	Common::String predictiveResult(predictiveDialog.getResult());
	uint16 predictiveResultLen = predictiveResult.size();
	if (predictiveResult.size()) {
		// User actually entered something
		for (int16 resultPos = 0; resultPos < predictiveResultLen; resultPos++) {
			keyEnqueue(predictiveResult[resultPos]);
		}
		if (!cycleInnerLoopIsActive()) {
			if (_text->promptIsEnabled()) {
				// add ENTER, when the input is probably meant for the prompt
				keyEnqueue(AGI_KEY_ENTER);
			}
		} else {
			switch (_game.cycleInnerLoopType) {
			case CYCLE_INNERLOOP_GETSTRING:
			case CYCLE_INNERLOOP_GETNUMBER:
				// add ENTER, when the input is probably meant for GetString/GetNumber
				keyEnqueue(AGI_KEY_ENTER);
				break;
			default:
				break;
			}
		}
		return true;
	}
	return false;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
// We return the current key, or 0 if no key was pressed
uint16 AgiEngine::processAGIEvents() {
	uint16 key;
	ScreenObjEntry *screenObjEgo = &_game.screenObjTable[SCREENOBJECTS_EGO_ENTRY];

	wait(10);
	key = doPollKeyboard();

	// In AGI Mouse emulation mode we must update the mouse-related
	// vars in every interpreter cycle.
	//
	// We run AGIMOUSE always as a side effect
	setVar(VM_VAR_MOUSE_X, _mouse.pos.x / 2);
	setVar(VM_VAR_MOUSE_Y, _mouse.pos.y);

	if (!cycleInnerLoopIsActive()) {
		// Click-to-walk mouse interface
		if (_game.playerControl && (screenObjEgo->flags & fAdjEgoXY)) {
			int toX = screenObjEgo->move_x;
			int toY = screenObjEgo->move_y;

			// AGI Mouse games use ego's sprite's bottom left corner for mouse walking target.
			// Amiga games use ego's sprite's bottom center for mouse walking target.
			// Atari ST and Apple II GS seem to use the bottom left
			if (getPlatform() == Common::kPlatformAmiga)
				toX -= (screenObjEgo->xSize / 2); // Center ego's sprite horizontally

			// Adjust ego's sprite's mouse walking target position (These parameters are
			// controlled with the adj.ego.move.to.x.y-command). Note that these values rely
			// on the horizontal centering of the ego's sprite at least on the Amiga platform.
			toX += _game.adjMouseX;
			toY += _game.adjMouseY;

			screenObjEgo->direction = getDirection(screenObjEgo->xPos, screenObjEgo->yPos, toX, toY, screenObjEgo->stepSize);

			if (screenObjEgo->direction == 0)
				inDestination(screenObjEgo);
		}
	}

	handleMouseClicks(key);

	if (!cycleInnerLoopIsActive()) {
		// no inner loop active at the moment, regular processing

		if (key) {
			if (!handleController(key)) {
				if (key) {
					// Only set VAR_KEY, when no controller/direction was detected
					setVar(VM_VAR_KEY, key & 0xFF);
					if (_text->promptIsEnabled()) {
						_text->promptKeyPress(key);
					}
				}
			}
		}

		if (_menu->delayedExecuteActive()) {
			_menu->execute();
		}

	} else {
		// inner loop active
		// call specific workers
		switch (_game.cycleInnerLoopType) {
		case CYCLE_INNERLOOP_GETSTRING: // loop called from TextMgr::stringEdit()
		case CYCLE_INNERLOOP_GETNUMBER:
			if (key) {
				_text->stringKeyPress(key);
			}
			break;

		case CYCLE_INNERLOOP_INVENTORY: // loop called from InventoryMgr::show()
			if (key) {
				_inventory->keyPress(key);
			}
			break;

		case CYCLE_INNERLOOP_MENU_VIA_KEYBOARD:
			if (key) {
				_menu->keyPress(key);
			}
			break;

		case CYCLE_INNERLOOP_MENU_VIA_MOUSE:
			_menu->mouseEvent(key);
			break;

		case CYCLE_INNERLOOP_SYSTEMUI_SELECTSAVEDGAMESLOT:
			if (key) {
				_systemUI->savedGameSlot_KeyPress(key);
			}
			break;

		case CYCLE_INNERLOOP_SYSTEMUI_VERIFICATION:
			_systemUI->askForVerificationKeyPress(key);
			break;

		case CYCLE_INNERLOOP_MESSAGEBOX:
			if (key) {
				_text->messageBox_KeyPress(key);
			}
			break;

		default:
			break;
		}
	}

	_gfx->updateScreen();

	return key;
}