mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-04 01:07:22 +00:00
387 lines
10 KiB
C++
387 lines
10 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "chewy/cursor.h"
|
|
#include "chewy/defines.h"
|
|
#include "chewy/detail.h"
|
|
#include "chewy/events.h"
|
|
#include "chewy/font.h"
|
|
#include "chewy/globals.h"
|
|
#include "chewy/main.h"
|
|
#include "chewy/mcga_graphics.h"
|
|
#include "chewy/menus.h"
|
|
|
|
namespace Chewy {
|
|
|
|
void plotMainMenu() {
|
|
static const int IMAGES[] = { 7, 8, 9, 10, 12, 11 };
|
|
int16 zoomX, zoomY;
|
|
|
|
if (_G(menu_item) != _G(tmp_menu)) {
|
|
_G(m_flip) = 0;
|
|
_G(tmp_menu) = _G(menu_item);
|
|
}
|
|
|
|
// Don't allow the mouse to warp past the right edge, as this messes
|
|
// up the menu screen
|
|
if (g_events->_mousePos.x > 266)
|
|
g_events->warpMouse(Common::Point(266, g_events->_mousePos.y));
|
|
|
|
const int16 x = MAX(g_events->_mousePos.x - 32, 0);
|
|
_G(menu_item) = (x / (MOUSE_MENU_MAX_X / 5));
|
|
|
|
int16 *correction = (int16 *)_G(menutaf)->correction;
|
|
|
|
for (int16 i = MENU_START_SPRITE; i < MAX_MENU_SPRITE; i++) {
|
|
int deltaX = 0;
|
|
|
|
if (i <= 8) {
|
|
zoomX = 0;
|
|
zoomY = 0;
|
|
} else {
|
|
zoomX = -3;
|
|
zoomY = -3;
|
|
|
|
if (i == 11)
|
|
deltaX = 40;
|
|
else if (i == 12)
|
|
deltaX = -40;
|
|
}
|
|
|
|
_G(out)->scale_set(_G(menutaf)->image[i],
|
|
MENU_X + deltaX + correction[i * 2],
|
|
_G(gameState).MainMenuY + correction[i * 2 + 1],
|
|
zoomX, zoomY, 0);
|
|
}
|
|
|
|
zoomX = 16;
|
|
zoomY = 16;
|
|
++_G(m_flip);
|
|
if (_G(m_flip) < 12 * (_G(gameState).DelaySpeed + 1)) {
|
|
int deltaX = 0;
|
|
if (_G(menu_item) == CUR_SAVE)
|
|
deltaX = -40;
|
|
else if (_G(menu_item) == CUR_INVENT)
|
|
deltaX = 40;
|
|
|
|
int img = IMAGES[_G(menu_item)];
|
|
_G(out)->scale_set(_G(menutaf)->image[img],
|
|
MENU_X + deltaX + correction[img * 2] - 5,
|
|
_G(gameState).MainMenuY + correction[img * 2 + 1] - 10,
|
|
zoomX, zoomY, 0);
|
|
} else {
|
|
if (_G(m_flip) > 15 * (_G(gameState).DelaySpeed + 1))
|
|
_G(m_flip) = 0;
|
|
}
|
|
}
|
|
|
|
void calcTxtXy(int16 *x, int16 *y, char *txtAdr, int16 txtCount) {
|
|
int16 len = 0;
|
|
for (int16 i = 0; i < txtCount; i++) {
|
|
int16 tmpLen = strlen(_G(txt)->strPos(txtAdr, i));
|
|
if (tmpLen > len)
|
|
len = tmpLen;
|
|
}
|
|
len = len * _G(fontMgr)->getFont()->getDataWidth();
|
|
int16 pixLen = len / 2;
|
|
*x = *x - pixLen + 12;
|
|
if (*x > (SCREEN_WIDTH - len))
|
|
*x = SCREEN_WIDTH - len;
|
|
else if (*x < 0)
|
|
*x = 0;
|
|
*y = *y - (10 * txtCount);
|
|
if (*y < 0)
|
|
*y = 0;
|
|
}
|
|
|
|
void calcTxtXy(int16 *x, int16 *y, Common::StringArray &textList) {
|
|
int16 len = 0;
|
|
for (int16 i = 0; i < (int16)textList.size(); i++) {
|
|
if ((int16)textList[i].size() > len)
|
|
len = textList[i].size();
|
|
}
|
|
len = len * _G(fontMgr)->getFont()->getDataWidth();
|
|
int16 pixLen = len / 2;
|
|
*x = *x - pixLen + 12;
|
|
if (*x > (SCREEN_WIDTH - len))
|
|
*x = SCREEN_WIDTH - len;
|
|
else if (*x < 0)
|
|
*x = 0;
|
|
*y = *y - (10 * textList.size());
|
|
if (*y < 0)
|
|
*y = 0;
|
|
}
|
|
|
|
void getDisplayCoord(int16 *x, int16 *y, int16 nr) {
|
|
int16 *xy = (int16 *)_G(inv_spr)[nr];
|
|
int16 x1 = 48 - xy[0];
|
|
x1 /= 2;
|
|
*x = x1;
|
|
int16 y1 = 48 - xy[1];
|
|
y1 /= 2;
|
|
*y = y1;
|
|
}
|
|
|
|
void buildMenu(int16 x, int16 y, int16 xNr, int16 yNr, int16 col, int16 mode) {
|
|
#define BUILDING_MENU_CORNER_LO 15
|
|
#define BUILDING_MENU_CORNER_RO 16
|
|
#define BUILDING_MENU_CORNER_LU 17
|
|
#define BUILDING_MENU_CORNER_RU 18
|
|
#define BUILDING_MENU_BELOW 19
|
|
#define BUILDING_MENU_SIDE_L 20
|
|
#define BUILDING_MENU_SIDE_R 21
|
|
#define BUILDING_MENU_ABOVE 22
|
|
#define BUILDING_MENU_ABOVE_L 23
|
|
#define BUILDING_MENU_ABOVE_R 24
|
|
#define BUILDING_MENU_ABOVE_M 25
|
|
int16 i, j;
|
|
int16 xy[4][2] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
|
|
uint8 spriteCornerNr[4] = { BUILDING_MENU_CORNER_LO, BUILDING_MENU_CORNER_RO, BUILDING_MENU_CORNER_LU, BUILDING_MENU_CORNER_RU };
|
|
|
|
xy[0][0] = x;
|
|
xy[0][1] = y;
|
|
xy[1][0] = x + 16 * (xNr - 1);
|
|
xy[1][1] = y;
|
|
xy[2][0] = x;
|
|
xy[2][1] = y + 16 * (yNr - 1);
|
|
xy[3][0] = x + 16 * (xNr - 1);
|
|
xy[3][1] = y + 16 * (yNr - 1);
|
|
|
|
for (i = 0; i < 4; i++)
|
|
_G(out)->spriteSet(_G(menutaf)->image[(int16)spriteCornerNr[i]],
|
|
xy[i][0], xy[i][1], _G(scr_width));
|
|
|
|
int16 s_nr = BUILDING_MENU_SIDE_L;
|
|
for (j = 0; j < 2; j++) {
|
|
y = xy[j][1] + 16;
|
|
for (i = 0; i < yNr - 2; i++) {
|
|
_G(out)->spriteSet(_G(menutaf)->image[s_nr], xy[j][0], y + i * 16, _G(scr_width));
|
|
}
|
|
++s_nr;
|
|
}
|
|
|
|
s_nr = BUILDING_MENU_ABOVE;
|
|
for (j = 0; j < 2; j++) {
|
|
x = xy[j * 2][0] + 16;
|
|
if ((!mode) || (mode == 1 && j == 1)) {
|
|
for (i = 0; i < xNr - 2; i++) {
|
|
_G(out)->spriteSet(_G(menutaf)->image[s_nr], x + i * 16, xy[j * 2][1], _G(scr_width));
|
|
}
|
|
}
|
|
s_nr -= 3;
|
|
}
|
|
|
|
if (mode) {
|
|
int16 leer = 0;
|
|
int16 center;
|
|
i = xNr - 7;
|
|
if (i == 0)
|
|
center = 1;
|
|
else if (i < 6)
|
|
center = i + 1;
|
|
else if (i < 8) {
|
|
leer = 1;
|
|
center = i - 1;
|
|
} else {
|
|
leer = 2;
|
|
center = i - 3;
|
|
}
|
|
|
|
x = xy[0][0] + 16;
|
|
for (j = 0; j < 2; j++) {
|
|
for (i = 0; i < leer; i++)
|
|
_G(out)->spriteSet(_G(menutaf)->image[BUILDING_MENU_ABOVE], x + i * 16, xy[0][1], _G(scr_width));
|
|
x = xy[1][0] - leer * 16;
|
|
}
|
|
_G(out)->spriteSet(_G(menutaf)->image[BUILDING_MENU_ABOVE_L], xy[0][0] + 16 + leer * 16, xy[0][1], _G(scr_width));
|
|
|
|
x = xy[0][0] + 16 + leer * 16 + 32;
|
|
for (i = 0; i < center; i++)
|
|
_G(out)->spriteSet(_G(menutaf)->image[BUILDING_MENU_ABOVE_M], x + i * 16, xy[0][1], _G(scr_width));
|
|
_G(out)->spriteSet(_G(menutaf)->image[BUILDING_MENU_ABOVE_R], x + i * 16, xy[0][1], _G(scr_width));
|
|
}
|
|
|
|
_G(out)->boxFill(xy[0][0] + 16, xy[0][1] + 16, xy[0][0] + 16 + (xNr - 2) * 16, xy[0][1] + 16 + (yNr - 2) * 16, col);
|
|
}
|
|
|
|
void autoMenu(int16 *x, int16 *y, int16 lineNr, int16 height, char *text, int16 mode) {
|
|
int16 tmp;
|
|
|
|
int16 x_pix = 0;
|
|
for (int16 i = 0; i < lineNr; i++) {
|
|
tmp = strlen(_G(txt)->strPos(text, i));
|
|
if (x_pix < tmp)
|
|
x_pix = tmp;
|
|
}
|
|
x_pix *= _G(font8)->getDataWidth();
|
|
x_pix += 12;
|
|
tmp = x_pix;
|
|
if (x_pix % 16)
|
|
tmp += 16;
|
|
int16 tmp1 = lineNr * height + 6 + 11;
|
|
if (tmp1 % 16)
|
|
tmp1 += 16;
|
|
*x -= ((tmp / 16) * 16) / 2;
|
|
*y -= ((tmp1 / 16) * 16) / 2;
|
|
buildMenu(*x, *y, tmp / 16, tmp1 / 16, 60, mode);
|
|
*x += 6 + (((tmp / 16) * 16) - x_pix) / 2;
|
|
*y += 5 + ((((tmp1 / 16) * 16) - 4) - (lineNr * height)) / 2;
|
|
}
|
|
|
|
#define ADS_WIN 0,153,20,3,60,1
|
|
|
|
void handleDialogCloseupMenu() {
|
|
int16 curYStart;
|
|
int16 col;
|
|
|
|
if (_G(flags).DialogCloseup) {
|
|
_G(flags).ShowAtsInvTxt = false;
|
|
_G(flags).MainInput = false;
|
|
if (_G(ads_item_nr) > 4)
|
|
curYStart = 190;
|
|
else
|
|
curYStart = 190 - (4 - _G(ads_item_nr)) * 10;
|
|
int16 curY = g_events->_mousePos.y;
|
|
if (curY < 160 || curY > curYStart + 10)
|
|
curY = 255;
|
|
else
|
|
curY = (curYStart + 8 - curY) / 10;
|
|
|
|
if (_G(atds)->aadGetStatus() == -1 && _G(ads_push) == false &&
|
|
_G(flags).NoDiaBox == false) {
|
|
|
|
buildMenu(ADS_WIN);
|
|
_G(fontMgr)->setFont(_G(font6));
|
|
if (_G(ads_item_nr) > 4)
|
|
curYStart = 190;
|
|
else
|
|
curYStart = 190 - (4 - _G(ads_item_nr)) * 10;
|
|
for (int16 i = 0; i < _G(ads_item_nr) && i < 4; i++) {
|
|
if (curY == i)
|
|
col = 255;
|
|
else
|
|
col = 14;
|
|
_G(out)->printxy(4, curYStart - i * 10, col, 300, 0, _G(dialogCloseupItemPtr)[i]);
|
|
}
|
|
}
|
|
|
|
switch (g_events->getSwitchCode()) {
|
|
case Common::MOUSE_BUTTON_LEFT:
|
|
case Common::KEYCODE_RETURN:
|
|
if (curY < _G(ads_item_nr) && curY >= 0 && _G(ads_push) == false) {
|
|
_G(ads_push) = true;
|
|
g_events->_mousePos.y = 159;
|
|
DialogCloseupNextBlock *an_blk = _G(atds)->dialogCloseupItemChoice(_G(ads_dia_nr), _G(ads_blk_nr), curY);
|
|
if (an_blk->_blkNr == -1) {
|
|
selectDialogOption(_G(ads_dia_nr), _G(ads_blk_nr), an_blk->_endNr);
|
|
endDialogCloseup(_G(ads_dia_nr), _G(ads_blk_nr), an_blk->_endNr);
|
|
stopDialogCloseupDialog();
|
|
} else {
|
|
an_blk = _G(atds)->calcNextDialogCloseupBlock(_G(ads_dia_nr), _G(ads_blk_nr), curY);
|
|
selectDialogOption(_G(ads_dia_nr), _G(ads_blk_nr), an_blk->_endNr);
|
|
_G(ads_blk_nr) = an_blk->_blkNr;
|
|
_G(dialogCloseupItemPtr) = _G(atds)->dialogCloseupItemPtr(_G(ads_dia_nr), _G(ads_blk_nr), &_G(ads_item_nr));
|
|
}
|
|
_G(det)->stopDetail(_G(talk_start_ani));
|
|
_G(det)->showStaticSpr(_G(talk_hide_static));
|
|
_G(talk_start_ani) = -1;
|
|
_G(talk_hide_static) = -1;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
_G(ads_push) = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void stopDialogCloseupDialog() {
|
|
aadWait(-1);
|
|
_G(gameState).DispFlag = _G(ads_tmp_dsp);
|
|
_G(flags).ShowAtsInvTxt = true;
|
|
_G(flags).MainInput = true;
|
|
_G(flags).DialogCloseup = false;
|
|
_G(mouseLeftClick) = false;
|
|
_G(atds)->stopDialogCloseup();
|
|
if (_G(minfo).button)
|
|
_G(flags).mainMouseFlag = 1;
|
|
}
|
|
|
|
void cur_2_inventory() {
|
|
if (_G(cur)->usingInventoryCursor()) {
|
|
invent_2_slot(_G(cur)->getInventoryCursor());
|
|
_G(cur)->setInventoryCursor(-1);
|
|
_G(menu_item) = CUR_WALK;
|
|
cursorChoice(_G(menu_item));
|
|
}
|
|
_G(cur)->setInventoryCursor(-1);
|
|
}
|
|
|
|
void inventory_2_cur(int16 nr) {
|
|
if (!_G(cur)->usingInventoryCursor() && _G(obj)->checkInventory(nr)) {
|
|
del_invent_slot(nr);
|
|
_G(menu_item) = CUR_USE;
|
|
_G(cur)->setInventoryCursor(nr);
|
|
getDisplayCoord(&_G(gameState).DispZx, &_G(gameState).DispZy, _G(cur)->getInventoryCursor());
|
|
}
|
|
}
|
|
|
|
void new_invent_2_cur(int16 inv_nr) {
|
|
cur_2_inventory();
|
|
_G(obj)->addInventory(inv_nr, &_G(room_blk));
|
|
inventory_2_cur(inv_nr);
|
|
}
|
|
|
|
void invent_2_slot(int16 nr) {
|
|
for (int16 i = 0; i < MAX_MOV_OBJ; i++) {
|
|
if (_G(gameState).InventSlot[i] == -1) {
|
|
_G(gameState).InventSlot[i] = nr;
|
|
break;
|
|
}
|
|
}
|
|
_G(obj)->addInventory(nr, &_G(room_blk));
|
|
}
|
|
|
|
int16 del_invent_slot(int16 nr) {
|
|
int16 ok = -1;
|
|
for (int16 i = 0; i < MAX_MOV_OBJ; i++) {
|
|
if (_G(gameState).InventSlot[i] == nr) {
|
|
_G(gameState).InventSlot[i] = -1;
|
|
if (ok == -1)
|
|
ok = i;
|
|
}
|
|
}
|
|
|
|
return ok;
|
|
}
|
|
|
|
void remove_inventory(int16 nr) {
|
|
if (nr == _G(cur)->getInventoryCursor()) {
|
|
delInventory(nr);
|
|
} else {
|
|
_G(obj)->delInventory(nr, &_G(room_blk));
|
|
del_invent_slot(nr);
|
|
}
|
|
}
|
|
|
|
} // namespace Chewy
|