scummvm/engines/hdb/input.cpp
2019-09-03 17:17:24 +02:00

405 lines
9.8 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "hdb/hdb.h"
#include "hdb/menu.h"
namespace HDB {
bool Input::init() {
_stylusDown = false;
_buttons = 0;
_keyUp = Common::KEYCODE_UP;
_keyDown = Common::KEYCODE_DOWN;
_keyLeft = Common::KEYCODE_LEFT;
_keyRight = Common::KEYCODE_RIGHT;
_keyMenu = Common::KEYCODE_ESCAPE;
_keyUse = Common::KEYCODE_RETURN;
_keyInv = Common::KEYCODE_SPACE;
_keyDebug = Common::KEYCODE_F1;
_keyQuit = Common::KEYCODE_F10;
_mouseX = kScreenWidth / 2;
_mouseY = kScreenHeight / 2;
_mouseLButton = _mouseMButton = _mouseRButton = 0;
return true;
}
void Input::setButtons(uint16 b) {
static int changeState = 0;
_buttons = b;
if (!b)
return;
// Change Game State
if ((_buttons & kButtonA) && !changeState && (g_hdb->getGameState() != GAME_MENU)) {
if (g_hdb->_ai->cinematicsActive() && g_hdb->_ai->cineAbortable()) {
g_hdb->_ai->cineAbort();
g_hdb->_sound->playSound(SND_POP);
return;
}
if (g_hdb->getGameState() == GAME_TITLE)
g_hdb->_menu->changeToMenu();
g_hdb->_sound->playSound(SND_MENU_BACKOUT);
g_hdb->changeGameState();
}
// Debug Mode Cycling
if ((_buttons & kButtonExit) && g_hdb->getCheatingOn()) {
int debugFlag = g_hdb->getDebug();
debugFlag++;
if (debugFlag > 2)
debugFlag = 0;
g_hdb->setDebug(debugFlag);
if (debugFlag == 2)
g_hdb->_ai->clearWaypoints();
if (!debugFlag && g_hdb->getGameState() == GAME_PLAY) {
int x, y;
g_hdb->_ai->getPlayerXY(&x, &y);
g_hdb->_map->centerMapXY(x + 16, y + 16); // point to center of player
}
}
if (g_hdb->getGameState() == GAME_PLAY) {
// Is Player Dead? Click on TRY AGAIN
if (g_hdb->_ai->playerDead()) {
// TRY AGAIN is onscreen...
if (_buttons & kButtonB) {
if (g_hdb->loadGameState(kAutoSaveSlot).getCode() == Common::kNoError) {
g_hdb->_window->clearTryAgain();
g_hdb->setGameState(GAME_PLAY);
}
}
return;
}
// Choose from DialogChoice
if (g_hdb->_window->dialogChoiceActive()) {
if (_buttons & kButtonUp)
g_hdb->_window->dialogChoiceMoveup();
else if (_buttons & kButtonDown)
g_hdb->_window->dialogChoiceMovedown();
else if (_buttons & kButtonB)
g_hdb->_window->closeDialogChoice();
return;
}
// Try to move the player
if (!g_hdb->_ai->playerDead())
g_hdb->_ai->movePlayer(_buttons);
}
}
uint16 Input::getButtons() {
return _buttons;
}
void Input::stylusDown(int x, int y) {
int worldX, worldY;
GameState gs;
static uint32 delay = 0, time;
// Don't let the screen get clicked too fast
time = g_system->getMillis();
if (time - delay < 100)
return;
time = delay;
_stylusDown = true;
_stylusDownX = x;
_stylusDownY = y;
gs = g_hdb->getGameState();
switch (gs) {
case GAME_TITLE:
g_hdb->_menu->changeToMenu();
g_hdb->changeGameState();
break;
case GAME_MENU:
g_hdb->_menu->processInput(x, y);
break;
case GAME_PLAY:
// Is Player Dead? Click on TRY AGAIN
if (g_hdb->_ai->playerDead()) {
if (y >= kTryRestartY && y <= kTryRestartY + 24) {
if (g_hdb->loadGameState(kAutoSaveSlot).getCode() == Common::kNoError) {
g_hdb->_window->clearTryAgain();
g_hdb->setGameState(GAME_PLAY);
}
}
return;
}
// Is Dialog Active?
if (g_hdb->_window->dialogActive()) {
g_hdb->_window->closeDialog();
if (!g_hdb->_ai->cinematicsActive())
return;
}
// Is a Choice Dialog Active?
if (g_hdb->_window->dialogChoiceActive()) {
if (!g_hdb->_window->checkDialogChoiceClose(x, y))
return;
if (!g_hdb->_ai->cinematicsActive())
return;
}
// Is MessageBar active?
if (g_hdb->_window->msgBarActive())
if (g_hdb->_window->checkMsgClose(x, y))
return;
// In a cinematic?
if (g_hdb->_ai->playerLocked())
return;
// Check for map dragging in debug Mode and place player there
if ((GAME_PLAY == g_hdb->getGameState()) && g_hdb->getDebug() == 2) {
int mx, my;
g_hdb->_map->getMapXY(&mx, &my);
mx = ((mx + _stylusDownY) / kTileWidth) * kTileWidth;
my = ((my + _stylusDownY) / kTileHeight) * kTileHeight;
g_hdb->_ai->setPlayerXY(mx, my);
g_hdb->startMoveMap(x, y);
return;
}
// Clicked in the world
g_hdb->_map->getMapXY(&worldX, &worldY);
worldX = ((worldX + x) / kTileWidth) * kTileWidth;
worldY = ((worldY + y) / kTileHeight) * kTileHeight;
// Don't allow a click into INV/DELIVERIES area to go into the world
if (x >= (kScreenWidth - 32 * 5))
return;
// Toggle Walk Speed if we clicked Player
int nx, ny;
static uint32 lastRunning = g_system->getMillis();
g_hdb->_ai->getPlayerXY(&nx, &ny);
if (nx == worldX && ny == worldY) {
if (lastRunning > g_system->getMillis())
return;
lastRunning = g_system->getMillis() + 1000 * kRunToggleDelay;
g_hdb->_ai->togglePlayerRunning();
if (g_hdb->_ai->playerRunning())
g_hdb->_window->centerTextOut("Running Speed", kScreenHeight - 32, kRunToggleDelay * kGameFPS);
else
g_hdb->_window->centerTextOut("Walking Speed", kScreenHeight - 32, kRunToggleDelay * kGameFPS);
g_hdb->_sound->playSound(SND_SWITCH_USE);
}
g_hdb->setTargetXY(worldX, worldY);
break;
case GAME_LOADING:
break;
}
}
void Input::stylusUp(int x, int y) {
_stylusDown = false;
}
void Input::stylusMove(int x, int y) {
// In a cinematic?
if (g_hdb->_ai->playerLocked() || g_hdb->_ai->playerDead())
return;
switch (g_hdb->getGameState()) {
case GAME_PLAY:
if (g_hdb->getDebug() == 2)
g_hdb->moveMap(x, y);
break;
case GAME_MENU:
g_hdb->_menu->processInput(x, y);
break;
default:
break;
}
}
void Input::updateMouse(int newX, int newY) {
_mouseX = newX;
_mouseY = newY;
if (_mouseX < 0)
_mouseX = 0;
else if (_mouseX >= kScreenWidth)
_mouseX = kScreenWidth - 1;
if (_mouseY < 0)
_mouseY = 0;
else if (_mouseY >= kScreenHeight)
_mouseY = kScreenHeight - 1;
// Turn Cursor back on?
if (!g_hdb->_gfx->getPointer()) {
g_hdb->_gfx->showPointer(true);
}
// Check if LButton is being dragged
if (_mouseLButton) {
stylusMove(_mouseX, _mouseY);
}
}
void Input::updateMouseButtons(int l, int m, int r) {
_mouseLButton += l;
_mouseMButton += m;
_mouseRButton += r;
// Check if LButton has been pressed
// Check if LButton has been lifted
if (_mouseLButton) {
if (_mouseX > (kScreenWidth - 32 * 5) && _mouseY < 240) {
g_hdb->_window->checkInvSelect(_mouseX, _mouseY);
} else if (_mouseX > (kScreenWidth - 32 * 5) && _mouseY >= 240) {
g_hdb->_window->checkDlvSelect(_mouseX, _mouseY);
} else {
if (g_hdb->getPause() && g_hdb->getGameState() == GAME_PLAY) {
g_hdb->_window->checkPause(_mouseX, _mouseY);
return;
}
stylusDown(_mouseX, _mouseY);
}
} else if (!_mouseLButton) {
stylusUp(_mouseX, _mouseY);
}
// Check if MButton has been pressed
if (_mouseMButton) {
if (g_hdb->getPause() && g_hdb->getGameState() == GAME_PLAY)
return;
g_hdb->_ai->clearWaypoints();
g_hdb->_sound->playSound(SND_POP);
}
// Check if RButton has been pressed
if (_mouseRButton) {
if (g_hdb->getPause() && g_hdb->getGameState() == GAME_PLAY)
return;
uint16 buttons = getButtons() | kButtonB;
setButtons(buttons);
}
}
void Input::updateKeys(Common::Event event, bool keyDown) {
if (keyDown && event.kbd.keycode == _keyQuit) {
g_hdb->quitGame();
return;
}
uint16 buttons = getButtons();
// PAUSE key pressed?
{
static int current = 0, last = 0;
last = current;
if (keyDown && event.kbd.keycode == Common::KEYCODE_p && g_hdb->getGameState() == GAME_PLAY) {
current = 1;
if (!last) {
g_hdb->togglePause();
g_hdb->_sound->playSound(SND_POP);
}
} else
current = 0;
}
if (!g_hdb->getPause()) {
if (event.kbd.keycode == _keyUp) {
if (keyDown) {
buttons |= kButtonUp;
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
} else {
buttons &= ~kButtonUp;
}
} else if (event.kbd.keycode == _keyDown) {
if (keyDown) {
buttons |= kButtonDown;
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
} else {
buttons &= ~kButtonDown;
}
} else if (event.kbd.keycode == _keyLeft) {
if (keyDown) {
buttons |= kButtonLeft;
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
} else {
buttons &= ~kButtonLeft;
}
} else if (event.kbd.keycode == _keyRight) {
if (keyDown) {
buttons |= kButtonRight;
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
} else {
buttons &= ~kButtonRight;
}
} else if (event.kbd.keycode == _keyUse) {
if (keyDown) {
buttons |= kButtonB;
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
} else {
buttons &= ~kButtonB;
}
}
}
if (event.kbd.keycode == _keyMenu) {
if (keyDown) {
buttons |= kButtonA;
g_hdb->_gfx->showPointer(true);
g_hdb->_menu->setMenuKey(1);
} else {
buttons &= ~kButtonA;
g_hdb->_menu->setMenuKey(0);
}
} else if (event.kbd.keycode == _keyDebug) {
if (keyDown) {
buttons |= kButtonExit;
} else {
buttons &= ~kButtonExit;
}
}
setButtons(buttons);
}
} // End of Namespace