scummvm/engines/hdb/input.cpp

597 lines
15 KiB
C++
Raw Normal View History

2019-06-26 22:49:35 +00:00
/* 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"
2019-07-24 11:06:28 +00:00
#include "hdb/ai.h"
2019-07-24 10:01:00 +00:00
#include "hdb/gfx.h"
2019-07-24 10:43:14 +00:00
#include "hdb/input.h"
2019-07-24 10:47:13 +00:00
#include "hdb/map.h"
2019-07-24 10:56:08 +00:00
#include "hdb/sound.h"
2019-07-11 21:37:33 +00:00
#include "hdb/menu.h"
2019-07-24 10:56:08 +00:00
#include "hdb/window.h"
2019-06-26 22:49:35 +00:00
namespace HDB {
void Input::init() {
2019-06-26 22:49:35 +00:00
_stylusDown = false;
_buttons = 0;
2019-06-26 22:49:35 +00:00
2019-06-28 21:17:08 +00:00
_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;
2019-06-26 22:49:35 +00:00
_mouseX = g_hdb->_screenWidth / 2;
_mouseY = g_hdb->_screenHeight / 2;
2019-06-26 22:49:35 +00:00
2019-06-28 19:12:24 +00:00
_mouseLButton = _mouseMButton = _mouseRButton = 0;
2019-06-26 22:49:35 +00:00
}
void Input::setButtons(uint16 b) {
2019-06-28 21:17:35 +00:00
_buttons = b;
2019-06-29 00:26:05 +00:00
if (!b)
return;
// Change Game State
if ((_buttons & kButtonA) && (g_hdb->getGameState() != GAME_MENU)) {
2019-06-29 00:26:05 +00:00
if (g_hdb->_ai->cinematicsActive() && g_hdb->_ai->cineAbortable()) {
g_hdb->_ai->cineAbort();
2019-07-03 02:54:05 +00:00
g_hdb->_sound->playSound(SND_POP);
2019-06-29 00:26:05 +00:00
return;
}
if (g_hdb->getGameState() == GAME_TITLE)
2019-07-11 23:30:25 +00:00
g_hdb->_menu->changeToMenu();
2019-07-03 02:54:05 +00:00
g_hdb->_sound->playSound(SND_MENU_BACKOUT);
2019-06-29 00:26:05 +00:00
g_hdb->changeGameState();
}
2019-08-03 05:12:07 +00:00
if (g_hdb->isPPC()) {
if (_buttons & kButtonD) {
if (g_hdb->_window->inventoryActive()) {
g_hdb->_window->closeInv();
g_hdb->_window->openDeliveries(false);
} else if (g_hdb->_window->deliveriesActive()) {
g_hdb->_window->closeDlvs();
} else {
g_hdb->_window->openInventory();
}
return;
}
}
2019-06-29 00:26:05 +00:00
// Debug Mode Cycling
2019-07-13 21:24:15 +00:00
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
}
}
2019-06-29 00:26:05 +00:00
if (g_hdb->getGameState() == GAME_PLAY) {
// Is Player Dead? Click on TRY AGAIN
if (g_hdb->_ai->playerDead()) {
2019-07-13 23:24:22 +00:00
// TRY AGAIN is onscreen...
if (_buttons & kButtonB) {
if (g_hdb->loadGameState(kAutoSaveSlot).getCode() == Common::kNoError) {
g_hdb->_window->clearTryAgain();
g_hdb->setGameState(GAME_PLAY);
}
}
2019-06-29 00:26:05 +00:00
return;
}
2019-08-03 05:12:07 +00:00
if (g_hdb->isPPC()) {
// Deliveries screen?
if (g_hdb->_window->deliveriesActive() && !g_hdb->_window->animatingDelivery()) {
if (_buttons & kButtonLeft) {
int amount = g_hdb->_ai->getDeliveriesAmount();
int current = g_hdb->_window->getSelectedDelivery();
if (!current)
current = amount - 1;
else
current--;
g_hdb->_window->setSelectedDelivery(current);
} else if (_buttons & kButtonRight) {
int amount = g_hdb->_ai->getDeliveriesAmount();
int current = g_hdb->_window->getSelectedDelivery();
2019-08-03 05:12:07 +00:00
current++;
if (current == amount)
current = 0;
g_hdb->_window->setSelectedDelivery(current);
} else if (_buttons & kButtonB)
g_hdb->_window->closeDlvs();
return;
}
//
// Resources screen? Move select cursor around
//
if (g_hdb->_window->inventoryActive()) {
// select weapon?
if (_buttons & kButtonB) {
static AIType lastWeaponSelected = AI_NONE;
if (!g_hdb->getActionMode()) {
g_hdb->_window->closeInv();
return;
}
AIType t = g_hdb->_ai->getInvItemType(g_hdb->_window->getInvSelect());
Tile *gfx = g_hdb->_ai->getInvItemGfx(g_hdb->_window->getInvSelect());
2019-08-03 05:12:07 +00:00
switch (t) {
case ITEM_CLUB:
case ITEM_ROBOSTUNNER:
case ITEM_SLUGSLINGER:
g_hdb->_ai->setPlayerWeapon(t, gfx);
if (t == lastWeaponSelected) {
g_hdb->_window->closeInv();
return;
}
lastWeaponSelected = t;
g_hdb->_sound->playSound(SND_MENU_ACCEPT);
return;
2019-08-03 21:31:02 +00:00
default:
break;
2019-08-03 05:12:07 +00:00
}
g_hdb->_sound->playSound(SND_CELLHOLDER_USE_REJECT);
return;
}
if (_buttons & kButtonLeft) {
int amount = g_hdb->_ai->getInvMax();
int current = g_hdb->_window->getInvSelect();
if (!amount)
return;
if (current == 5)
current = amount - 1;
else if (!current && amount > 5)
current = 4;
else if (!current)
current = amount - 1;
else
current--;
g_hdb->_sound->playSound(SND_MENU_SLIDER);
g_hdb->_window->setInvSelect(current);
} else if (_buttons & kButtonRight) {
int amount = g_hdb->_ai->getInvMax();
int current = g_hdb->_window->getInvSelect();
2019-08-03 05:12:07 +00:00
if (!amount)
return;
if (amount > 5) {
if (current == amount - 1)
current = 5;
else if (current == 4)
current = 0;
else
current++;
} else if (current == amount - 1)
current = 0;
else
current++;
g_hdb->_sound->playSound(SND_MENU_SLIDER);
g_hdb->_window->setInvSelect(current);
} else if (_buttons & kButtonUp) {
int amount = g_hdb->_ai->getInvMax();
int current = g_hdb->_window->getInvSelect();
2019-08-03 05:12:07 +00:00
if (amount < 6)
2019-08-03 05:12:07 +00:00
return;
if (current - 5 >= 0)
current -= 5;
g_hdb->_sound->playSound(SND_MENU_SLIDER);
g_hdb->_window->setInvSelect(current);
} else if (_buttons & kButtonDown) {
int amount = g_hdb->_ai->getInvMax();
int current = g_hdb->_window->getInvSelect();
2019-08-03 05:12:07 +00:00
if (amount < 6)
2019-08-03 05:12:07 +00:00
return;
if (current + 5 < amount)
current += 5;
else if (current < 5)
current = amount - 1;
g_hdb->_sound->playSound(SND_MENU_SLIDER);
g_hdb->_window->setInvSelect(current);
}
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;
}
2019-06-29 00:26:05 +00:00
// Try to move the player
if (!g_hdb->_ai->playerDead())
g_hdb->_ai->movePlayer(_buttons);
}
2019-06-26 22:49:35 +00:00
}
uint16 Input::getButtons() {
2019-06-28 21:17:35 +00:00
return _buttons;
2019-06-26 22:49:35 +00:00
}
void Input::stylusDown(int x, int y) {
2019-06-28 16:32:41 +00:00
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;
GameState gs = g_hdb->getGameState();
2019-06-28 16:32:41 +00:00
switch (gs) {
case GAME_TITLE:
2019-07-11 23:30:25 +00:00
g_hdb->_menu->changeToMenu();
2019-06-28 16:32:41 +00:00
g_hdb->changeGameState();
break;
case GAME_MENU:
2019-07-11 23:30:25 +00:00
g_hdb->_menu->processInput(x, y);
2019-06-28 16:32:41 +00:00
break;
case GAME_PLAY:
2019-07-20 06:03:33 +00:00
{
2019-06-28 16:32:41 +00:00
// Is Player Dead? Click on TRY AGAIN
if (g_hdb->_ai->playerDead()) {
if (y >= g_hdb->_window->_tryRestartY && y <= g_hdb->_window->_tryRestartY + 24) {
2019-07-13 23:24:22 +00:00
if (g_hdb->loadGameState(kAutoSaveSlot).getCode() == Common::kNoError) {
g_hdb->_window->clearTryAgain();
g_hdb->setGameState(GAME_PLAY);
}
}
2019-06-28 16:32:41 +00:00
return;
}
2019-08-01 05:52:11 +00:00
if (g_hdb->isPPC()) {
2019-08-03 05:12:07 +00:00
// is Deliveries active?
if (g_hdb->_window->deliveriesActive()) {
if (!g_hdb->_window->checkDlvsClose(x, y))
return;
if (!g_hdb->_ai->cinematicsActive())
return;
}
// is Inventory active?
if (g_hdb->_window->inventoryActive()) {
if (!g_hdb->_window->checkInvClose(x, y))
return;
if (!g_hdb->_ai->cinematicsActive())
return;
}
2019-08-01 05:52:11 +00:00
}
2019-06-28 16:32:41 +00:00
// 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;
}
2019-06-28 16:32:41 +00:00
// Is MessageBar active?
if (g_hdb->_window->msgBarActive()) {
if (g_hdb->_window->checkMsgClose(x, y))
return;
}
2019-06-28 16:32:41 +00:00
// In a cinematic?
if (g_hdb->_ai->playerLocked())
return;
// Check for map dragging in debug Mode and place player there
2019-07-13 21:25:48 +00:00
if ((GAME_PLAY == g_hdb->getGameState()) && g_hdb->getDebug() == 2) {
int mx, my;
2019-07-13 21:25:48 +00:00
g_hdb->_map->getMapXY(&mx, &my);
2019-07-13 21:25:48 +00:00
mx = ((mx + _stylusDownY) / kTileWidth) * kTileWidth;
my = ((my + _stylusDownY) / kTileHeight) * kTileHeight;
g_hdb->_ai->setPlayerXY(mx, my);
g_hdb->startMoveMap(x, y);
return;
}
2019-06-28 16:32:41 +00:00
// Clicked in the world
int worldX, worldY;
2019-06-28 16:32:41 +00:00
g_hdb->_map->getMapXY(&worldX, &worldY);
worldX = ((worldX + x) / kTileWidth) * kTileWidth;
worldY = ((worldY + y) / kTileHeight) * kTileHeight;
2019-08-01 05:52:11 +00:00
if (!g_hdb->isPPC()) {
// Don't allow a click into INV/DELIVERIES area to go into the world
if (x >= (g_hdb->_screenWidth - 32 * 5))
return;
}
2019-06-28 16:32:41 +00:00
2019-08-16 08:50:29 +00:00
// Double-Clicking on the player to open inventory?
int nx, ny;
2019-06-28 16:32:41 +00:00
g_hdb->_ai->getPlayerXY(&nx, &ny);
2019-08-16 08:50:29 +00:00
if (g_hdb->isPPC()) {
if (nx == worldX && ny == worldY) {
static uint32 dblClickTimer = 0;
if (dblClickTimer && ((int)(g_system->getMillis() - dblClickTimer) < (int)(kGameFPS * 1000 / 60))) {
g_hdb->_window->openInventory();
dblClickTimer = 0;
g_hdb->_ai->togglePlayerRunning();
if (g_hdb->_ai->playerRunning())
g_hdb->_window->centerTextOut("Running Speed", g_hdb->_screenHeight - 32, kRunToggleDelay * kGameFPS);
else
g_hdb->_window->centerTextOut("Walking Speed", g_hdb->_screenHeight - 32, kRunToggleDelay * kGameFPS);
g_hdb->_sound->playSound(SND_SWITCH_USE);
return;
} else
dblClickTimer = g_system->getMillis();
}
}
// Toggle Walk Speed if we clicked Player
static uint32 lastRunning = g_system->getMillis();
2019-06-28 16:32:41 +00:00
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", g_hdb->_screenHeight - 32, kRunToggleDelay * kGameFPS);
2019-06-28 16:32:41 +00:00
else
g_hdb->_window->centerTextOut("Walking Speed", g_hdb->_screenHeight - 32, kRunToggleDelay * kGameFPS);
2019-07-03 02:54:05 +00:00
g_hdb->_sound->playSound(SND_SWITCH_USE);
2019-06-28 16:32:41 +00:00
}
g_hdb->setTargetXY(worldX, worldY);
break;
2019-07-20 06:03:33 +00:00
}
2019-06-28 16:32:41 +00:00
case GAME_LOADING:
break;
}
2019-06-26 22:49:35 +00:00
}
void Input::stylusUp(int x, int y) {
_stylusDown = false;
2019-06-26 22:49:35 +00:00
}
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:
2019-07-13 21:25:48 +00:00
if (g_hdb->getDebug() == 2)
g_hdb->moveMap(x, y);
break;
case GAME_MENU:
2019-07-11 23:30:25 +00:00
g_hdb->_menu->processInput(x, y);
break;
default:
break;
}
2019-06-26 22:49:35 +00:00
}
void Input::updateMouse(int newX, int newY) {
_mouseX = newX;
_mouseY = newY;
if (_mouseX < 0)
_mouseX = 0;
else if (_mouseX >= g_hdb->_screenWidth)
_mouseX = g_hdb->_screenWidth - 1;
if (_mouseY < 0)
_mouseY = 0;
else if (_mouseY >= g_hdb->_screenHeight)
_mouseY = g_hdb->_screenHeight - 1;
// Turn Cursor back on?
2019-07-01 22:48:38 +00:00
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 (g_hdb->isPPC()) {
stylusDown(_mouseX, _mouseY);
return;
}
if (_mouseX > (g_hdb->_screenWidth - 32 * 5) && _mouseY < 240) {
g_hdb->_window->checkInvSelect(_mouseX, _mouseY);
} else if (_mouseX > (g_hdb->_screenWidth - 32 * 5) && _mouseY >= 240) {
2019-07-05 20:25:21 +00:00
g_hdb->_window->checkDlvSelect(_mouseX, _mouseY);
} else {
2019-06-28 20:36:22 +00:00
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) {
2019-06-28 20:36:22 +00:00
if (g_hdb->getPause() && g_hdb->getGameState() == GAME_PLAY)
return;
g_hdb->_ai->clearWaypoints();
2019-07-03 02:54:05 +00:00
g_hdb->_sound->playSound(SND_POP);
}
// Check if RButton has been pressed
if (_mouseRButton) {
2019-06-28 20:36:22 +00:00
if (g_hdb->getPause() && g_hdb->getGameState() == GAME_PLAY)
return;
uint16 buttons = getButtons() | kButtonB;
setButtons(buttons);
}
}
2019-06-28 21:17:08 +00:00
void Input::updateKeys(Common::Event event, bool keyDown) {
static int current = 0, last = 0;
2019-06-28 21:17:08 +00:00
2019-07-15 07:32:42 +00:00
if (keyDown && event.kbd.keycode == _keyQuit) {
g_hdb->quitGame();
return;
}
2019-06-28 21:17:08 +00:00
uint16 buttons = getButtons();
2019-07-11 18:38:12 +00:00
// PAUSE key pressed?
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;
2019-07-11 18:38:12 +00:00
2019-06-28 21:17:08 +00:00
if (!g_hdb->getPause()) {
if (event.kbd.keycode == _keyUp) {
if (keyDown) {
buttons |= kButtonUp;
2019-07-01 22:48:38 +00:00
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
2019-06-28 21:17:08 +00:00
} else {
buttons &= ~kButtonUp;
}
} else if (event.kbd.keycode == _keyDown) {
if (keyDown) {
buttons |= kButtonDown;
2019-07-01 22:48:38 +00:00
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
2019-06-28 21:17:08 +00:00
} else {
buttons &= ~kButtonDown;
}
} else if (event.kbd.keycode == _keyLeft) {
if (keyDown) {
buttons |= kButtonLeft;
2019-07-01 22:48:38 +00:00
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
2019-06-28 21:17:08 +00:00
} else {
buttons &= ~kButtonLeft;
}
} else if (event.kbd.keycode == _keyRight) {
if (keyDown) {
buttons |= kButtonRight;
2019-07-01 22:48:38 +00:00
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
2019-06-28 21:17:08 +00:00
} else {
buttons &= ~kButtonRight;
}
} else if (event.kbd.keycode == _keyUse) {
if (keyDown) {
buttons |= kButtonB;
2019-07-01 22:48:38 +00:00
if (g_hdb->_gfx->getPointer())
g_hdb->_gfx->showPointer(false);
2019-06-28 21:17:08 +00:00
} else {
buttons &= ~kButtonB;
}
}
}
if (event.kbd.keycode == _keyMenu) {
if (keyDown) {
buttons |= kButtonA;
2019-07-01 22:48:38 +00:00
g_hdb->_gfx->showPointer(true);
2019-07-11 21:37:33 +00:00
g_hdb->_menu->setMenuKey(1);
2019-06-28 21:17:08 +00:00
} else {
buttons &= ~kButtonA;
2019-07-11 21:37:33 +00:00
g_hdb->_menu->setMenuKey(0);
2019-06-28 21:17:08 +00:00
}
} else if (event.kbd.keycode == _keyDebug) {
if (keyDown)
2019-06-28 21:17:08 +00:00
buttons |= kButtonExit;
else
2019-06-28 21:17:08 +00:00
buttons &= ~kButtonExit;
}
setButtons(buttons);
}
2019-06-28 16:32:41 +00:00
} // End of Namespace