/* 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 . * */ #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