scummvm/engines/hdb/input.cpp

552 lines
14 KiB
C++
Raw Permalink Normal View History

2019-06-27 04:19:35 +05:30
/* 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 13:06:28 +02:00
#include "hdb/ai.h"
2019-07-24 12:01:00 +02:00
#include "hdb/gfx.h"
2019-07-24 12:43:14 +02:00
#include "hdb/input.h"
2019-07-24 12:47:13 +02:00
#include "hdb/map.h"
2019-07-24 12:56:08 +02:00
#include "hdb/sound.h"
2019-07-12 03:07:33 +05:30
#include "hdb/menu.h"
2019-07-24 12:56:08 +02:00
#include "hdb/window.h"
2019-06-27 04:19:35 +05:30
namespace HDB {
void Input::init() {
2019-06-27 04:19:35 +05:30
_stylusDown = false;
_buttons = 0;
2019-06-27 04:19:35 +05:30
_mouseX = g_hdb->_screenWidth / 2;
_mouseY = g_hdb->_screenHeight / 2;
2019-06-27 04:19:35 +05:30
}
void Input::setButtons(uint16 b) {
2019-06-29 02:47:35 +05:30
_buttons = b;
2019-06-29 05:56:05 +05:30
if (!b)
return;
// Change Game State
if ((_buttons & kButtonA) && (g_hdb->getGameState() != GAME_MENU)) {
2019-06-29 05:56:05 +05:30
if (g_hdb->_ai->cinematicsActive() && g_hdb->_ai->cineAbortable()) {
g_hdb->_ai->cineAbort();
2019-07-03 08:24:05 +05:30
g_hdb->_sound->playSound(SND_POP);
2019-06-29 05:56:05 +05:30
return;
}
if (g_hdb->getGameState() == GAME_TITLE)
2019-07-12 05:00:25 +05:30
g_hdb->_menu->changeToMenu();
2019-07-03 08:24:05 +05:30
g_hdb->_sound->playSound(SND_MENU_BACKOUT);
2019-06-29 05:56:05 +05:30
g_hdb->changeGameState();
}
2019-08-03 10:42:07 +05:30
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 05:56:05 +05:30
// Debug Mode Cycling
2019-07-14 02:54:15 +05:30
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 05:56:05 +05:30
if (g_hdb->getGameState() == GAME_PLAY) {
// Is Player Dead? Click on TRY AGAIN
if (g_hdb->_ai->playerDead()) {
2019-07-14 04:54:22 +05:30
// 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 05:56:05 +05:30
return;
}
2019-08-03 10:42:07 +05:30
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 10:42:07 +05:30
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 10:42:07 +05:30
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 23:31:02 +02:00
default:
break;
2019-08-03 10:42:07 +05:30
}
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 10:42:07 +05:30
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 10:42:07 +05:30
if (amount < 6)
2019-08-03 10:42:07 +05:30
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 10:42:07 +05:30
if (amount < 6)
2019-08-03 10:42:07 +05:30
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 05:56:05 +05:30
// Try to move the player
if (!g_hdb->_ai->playerDead())
g_hdb->_ai->movePlayer(_buttons);
}
2019-06-27 04:19:35 +05:30
}
uint16 Input::getButtons() {
2019-06-29 02:47:35 +05:30
return _buttons;
2019-06-27 04:19:35 +05:30
}
void Input::stylusDown(int x, int y) {
2019-06-28 22:02:41 +05:30
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;
GameState gs = g_hdb->getGameState();
2019-06-28 22:02:41 +05:30
switch (gs) {
case GAME_TITLE:
2019-07-12 05:00:25 +05:30
g_hdb->_menu->changeToMenu();
2019-06-28 22:02:41 +05:30
g_hdb->changeGameState();
break;
case GAME_MENU:
2019-07-12 05:00:25 +05:30
g_hdb->_menu->processInput(x, y);
2019-06-28 22:02:41 +05:30
break;
case GAME_PLAY:
2019-07-20 08:03:33 +02:00
{
2019-06-28 22:02:41 +05:30
// 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-14 04:54:22 +05:30
if (g_hdb->loadGameState(kAutoSaveSlot).getCode() == Common::kNoError) {
g_hdb->_window->clearTryAgain();
g_hdb->setGameState(GAME_PLAY);
}
}
2019-06-28 22:02:41 +05:30
return;
}
2019-08-01 11:22:11 +05:30
if (g_hdb->isPPC()) {
2019-08-03 10:42:07 +05:30
// 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 11:22:11 +05:30
}
2019-06-28 22:02:41 +05:30
// 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 22:02:41 +05:30
// Is MessageBar active?
if (g_hdb->_window->msgBarActive()) {
if (g_hdb->_window->checkMsgClose(x, y))
return;
}
2019-06-28 22:02:41 +05:30
// In a cinematic?
if (g_hdb->_ai->playerLocked())
return;
// Check for map dragging in debug Mode and place player there
2019-07-14 02:55:48 +05:30
if ((GAME_PLAY == g_hdb->getGameState()) && g_hdb->getDebug() == 2) {
int mx, my;
2019-07-14 02:55:48 +05:30
g_hdb->_map->getMapXY(&mx, &my);
2020-04-26 23:43:34 +01:00
mx = ((mx + x) / kTileWidth) * kTileWidth;
my = ((my + y) / kTileHeight) * kTileHeight;
2019-07-14 02:55:48 +05:30
g_hdb->_ai->setPlayerXY(mx, my);
g_hdb->startMoveMap(x, y);
return;
}
2019-06-28 22:02:41 +05:30
// Clicked in the world
int worldX, worldY;
2019-06-28 22:02:41 +05:30
g_hdb->_map->getMapXY(&worldX, &worldY);
worldX = ((worldX + x) / kTileWidth) * kTileWidth;
worldY = ((worldY + y) / kTileHeight) * kTileHeight;
2019-08-01 11:22:11 +05:30
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 22:02:41 +05:30
2019-08-16 14:20:29 +05:30
// Double-Clicking on the player to open inventory?
int nx, ny;
2019-06-28 22:02:41 +05:30
g_hdb->_ai->getPlayerXY(&nx, &ny);
2019-08-16 14:20:29 +05:30
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 22:02:41 +05:30
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 22:02:41 +05:30
else
g_hdb->_window->centerTextOut("Walking Speed", g_hdb->_screenHeight - 32, kRunToggleDelay * kGameFPS);
2019-07-03 08:24:05 +05:30
g_hdb->_sound->playSound(SND_SWITCH_USE);
2019-06-28 22:02:41 +05:30
}
g_hdb->setTargetXY(worldX, worldY);
break;
2019-07-20 08:03:33 +02:00
}
2019-06-28 22:02:41 +05:30
case GAME_LOADING:
break;
default:
break;
2019-06-28 22:02:41 +05:30
}
2019-06-27 04:19:35 +05:30
}
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-14 02:55:48 +05:30
if (g_hdb->getDebug() == 2)
g_hdb->moveMap(x, y);
break;
case GAME_MENU:
2019-07-12 05:00:25 +05:30
g_hdb->_menu->processInput(x, y);
break;
default:
break;
}
2019-06-27 04:19:35 +05:30
}
void Input::updateMouse(int newX, int newY) {
2019-09-19 08:05:36 +02:00
_mouseX = CLIP(newX, 0, g_hdb->_screenWidth - 1);
_mouseY = CLIP(newY, 0, g_hdb->_screenHeight - 1);
// Turn Cursor back on?
2019-09-19 08:05:36 +02:00
if (!g_hdb->_gfx->getPointer())
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(true);
// Check if LButton is being dragged
2020-04-26 23:43:34 +01:00
if (_stylusDown)
stylusMove(_mouseX, _mouseY);
}
2020-04-26 23:43:34 +01:00
void Input::updateMouseButtons(bool isDown) {
_stylusDown = isDown;
// Check if LButton has been pressed
// Check if LButton has been lifted
2020-04-26 23:43:34 +01:00
if (isDown) {
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-06 01:55:21 +05:30
g_hdb->_window->checkDlvSelect(_mouseX, _mouseY);
} else {
2019-06-29 02:06:22 +05:30
if (g_hdb->getPause() && g_hdb->getGameState() == GAME_PLAY) {
g_hdb->_window->checkPause(_mouseX, _mouseY);
return;
}
stylusDown(_mouseX, _mouseY);
}
}
}
2020-04-26 23:43:34 +01:00
void Input::updateActions(Common::Event event, bool keyDown, bool fromMouse) {
2019-09-19 08:05:36 +02:00
static bool current = false, last = false;
2019-06-29 02:47:08 +05:30
2020-04-26 23:43:34 +01:00
if (keyDown && event.customType == kHDBActionQuit) {
2019-07-15 13:02:42 +05:30
g_hdb->quitGame();
return;
}
2019-06-29 02:47:08 +05:30
uint16 buttons = getButtons();
2019-07-12 00:08:12 +05:30
// PAUSE key pressed?
last = current;
2020-04-26 23:43:34 +01:00
if (keyDown && event.customType == kHDBActionPause && g_hdb->getGameState() == GAME_PLAY) {
2019-09-19 08:05:36 +02:00
current = true;
if (!last) {
g_hdb->togglePause();
g_hdb->_sound->playSound(SND_POP);
}
} else
2019-09-19 08:05:36 +02:00
current = false;
2019-07-12 00:08:12 +05:30
2019-06-29 02:47:08 +05:30
if (!g_hdb->getPause()) {
2020-04-26 23:43:34 +01:00
if (event.customType == kHDBActionUp) {
2019-06-29 02:47:08 +05:30
if (keyDown) {
buttons |= kButtonUp;
2020-04-26 23:43:34 +01:00
if (g_hdb->_gfx->getPointer() && !fromMouse)
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(false);
2019-06-29 02:47:08 +05:30
} else {
buttons &= ~kButtonUp;
}
2020-04-26 23:43:34 +01:00
} else if (event.customType == kHDBActionDown) {
2019-06-29 02:47:08 +05:30
if (keyDown) {
buttons |= kButtonDown;
2020-04-26 23:43:34 +01:00
if (g_hdb->_gfx->getPointer() && !fromMouse)
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(false);
2019-06-29 02:47:08 +05:30
} else {
buttons &= ~kButtonDown;
}
2020-04-26 23:43:34 +01:00
} else if (event.customType == kHDBActionLeft) {
2019-06-29 02:47:08 +05:30
if (keyDown) {
buttons |= kButtonLeft;
2020-04-26 23:43:34 +01:00
if (g_hdb->_gfx->getPointer() && !fromMouse)
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(false);
2019-06-29 02:47:08 +05:30
} else {
buttons &= ~kButtonLeft;
}
2020-04-26 23:43:34 +01:00
} else if (event.customType == kHDBActionRight) {
2019-06-29 02:47:08 +05:30
if (keyDown) {
buttons |= kButtonRight;
2020-04-26 23:43:34 +01:00
if (g_hdb->_gfx->getPointer() && !fromMouse)
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(false);
2019-06-29 02:47:08 +05:30
} else {
buttons &= ~kButtonRight;
}
2020-04-26 23:43:34 +01:00
} else if (event.customType == kHDBActionUse) {
2019-06-29 02:47:08 +05:30
if (keyDown) {
buttons |= kButtonB;
2020-04-26 23:43:34 +01:00
if (g_hdb->_gfx->getPointer() && !fromMouse)
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(false);
2019-06-29 02:47:08 +05:30
} else {
buttons &= ~kButtonB;
}
2020-04-26 23:43:34 +01:00
} else if (event.customType == kHDBActionClearWaypoints) {
if (keyDown) {
g_hdb->_ai->clearWaypoints();
g_hdb->_sound->playSound(SND_POP);
}
2019-06-29 02:47:08 +05:30
}
2020-04-26 23:43:34 +01:00
// TODO: Inventory key
2019-06-29 02:47:08 +05:30
}
2020-04-26 23:43:34 +01:00
if (event.customType == kHDBActionMenu) {
2019-06-29 02:47:08 +05:30
if (keyDown) {
buttons |= kButtonA;
2019-07-02 00:48:38 +02:00
g_hdb->_gfx->showPointer(true);
2019-07-12 03:07:33 +05:30
g_hdb->_menu->setMenuKey(1);
2019-06-29 02:47:08 +05:30
} else {
buttons &= ~kButtonA;
2019-07-12 03:07:33 +05:30
g_hdb->_menu->setMenuKey(0);
2019-06-29 02:47:08 +05:30
}
2020-04-26 23:43:34 +01:00
} else if (event.customType == kHDBActionDebug) {
if (keyDown)
2019-06-29 02:47:08 +05:30
buttons |= kButtonExit;
else
2019-06-29 02:47:08 +05:30
buttons &= ~kButtonExit;
}
setButtons(buttons);
}
2019-06-28 22:02:41 +05:30
} // End of Namespace