diff options
author | Filippos Karapetis | 2008-04-20 14:47:37 +0000 |
---|---|---|
committer | Filippos Karapetis | 2008-04-20 14:47:37 +0000 |
commit | 7ca439f410ac1c46a387567b30271ae4e4a2ed30 (patch) | |
tree | 4d4154169b074293581ad6a11ee821290418f4fb /engines/m4/m4_views.cpp | |
parent | d0590a09eac68d5cde64d37fb2e5bbd1471a676a (diff) | |
download | scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.tar.gz scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.tar.bz2 scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.zip |
Initial import of the work in progress M4 engine
svn-id: r31600
Diffstat (limited to 'engines/m4/m4_views.cpp')
-rw-r--r-- | engines/m4/m4_views.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/engines/m4/m4_views.cpp b/engines/m4/m4_views.cpp new file mode 100644 index 0000000000..9bf964ee96 --- /dev/null +++ b/engines/m4/m4_views.cpp @@ -0,0 +1,345 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "m4/m4_views.h" +#include "m4/events.h" +#include "m4/font.h" +#include "m4/globals.h" +#include "m4/m4.h" + +namespace M4 { + +GUIInventory::GUIInventory(View *owner, M4Engine *vm, const Common::Rect &bounds, int horizCells, + int vertCells, int cellWidth, int cellHeight, int tag): GUIRect(owner, bounds, tag) { + + _vm = vm; + _cellCount.x = horizCells; + _cellCount.y = vertCells; + _cellSize.x = cellWidth; + _cellSize.y = cellHeight; + + // Validate the cell settings + if ((_cellCount.x * _cellSize.x > _bounds.width()) || + (_cellCount.y * _cellSize.y > _bounds.height())) + error("Cell settings for inventory display exceeded control size"); + + _visible = true; + _scrollPosition = 0; + _scrollable = false; + _highlightedIndex = -1; + _selectedIndex = -1; +} + +void GUIInventory::onRefresh() { + _parent->fillRect(_bounds, _vm->_palette->BLACK); + //_parent->frameRect(_bounds, _vm->_palette->LIGHT_GRAY); + + if (_visible) { + //kernel_trigger_dispatch(kernel_trigger_create(TRIG_INV_CLICK)); + + _scrollable = false; + + // Get to the starting inventory position for display + ItemsIterator i = _inventoryItems.begin(); + int index = _scrollPosition; + while (index-- > 0) ++i; + + // Loop through displaying entries + for (index = 0; (i != _inventoryItems.end()) && (index < _cellCount.x * _cellCount.y); ++index, ++i) { + GUIInventoryItem *item = (*i).get(); + const Common::Point cellPos = getCellPosition(index); +/* Common::Rect cellBounds(_bounds.left + cellPos.x + xOffset, + _bounds.top + cellPos.y + yOffset, + _bounds.left + cellPos.x + xOffset + _cellSize.x, + _bounds.top + cellPos.y + _cellSize.y);*/ + Common::Rect cellBounds(_bounds.left + cellPos.x, _bounds.top + cellPos.y, + _bounds.left + cellPos.x + _cellSize.x, _bounds.top + cellPos.y + _cellSize.y); + + Common::Point iconPt( + cellBounds.left + (cellBounds.width() - item->icon->width()) / 2, + cellBounds.top + (cellBounds.height() - item->icon->height()) / 2); + + item->icon->copyTo(_parent, iconPt.x, iconPt.y, 0); + + if (_highlightedIndex == index) + _parent->frameRect(Common::Rect(iconPt.x - 2, iconPt.y - 2, + iconPt.x + item->icon->width() + 2, iconPt.y + item->icon->height() + 2), + _vm->_palette->LIGHT_GRAY); + } + } +} + +bool GUIInventory::onEvent(M4EventType eventType, int param, int x, int y, GUIObject *¤tItem) { + bool result = false; + int overIndex = getInsideIndex(x, y); + bool isPressed = (eventType == MEVENT_LEFT_CLICK) || (eventType == MEVENT_LEFT_HOLD) || + (eventType == MEVENT_LEFT_DRAG); + ItemsIterator curItem = _inventoryItems.begin(); + + if (isPressed) { + if (_selectedIndex == -1 && overIndex != -1) { + setHighlight(overIndex); + _selectedIndex = overIndex; + for (int i = 0; i < _scrollPosition + _selectedIndex; i++) + ++curItem; + if (_scrollPosition + _selectedIndex < (int)_inventoryItems.size()) + _vm->_mouse->setCursorNum(curItem->get()->iconIndex); + result = true; + } else { + // We are over something being tracked + if (_selectedIndex == overIndex) { + setHighlight(overIndex); + result = true; + } else { + // Otherwise reset highlighting + setHighlight(-1); + result = false; + } + } + } else { + // No button pressed + if (_selectedIndex == overIndex) { + result = (_selectedIndex != -1); + } else { + result = (overIndex + _scrollPosition < (int)_inventoryItems.size()); + if (result) { + for (int i = 0; i < overIndex + _scrollPosition; i++) + ++curItem; + _vm->_interfaceView->setStatusText(curItem->get()->name); + } + } + + // Stop tracking anything + setHighlight(overIndex); + } + + return result; +} + +void GUIInventory::add(const char *name, const char *verb, M4Surface *icon, int iconIndex) { + // First scan through the list to prevent duplicate objects + for (ItemsIterator i = _inventoryItems.begin(); i != _inventoryItems.end(); ++i) { + if (!strcmp(name, ((*i).get())->name)) + return; + } + + _inventoryItems.push_back(InventoryList::value_type(new GUIInventoryItem(name, verb, icon, iconIndex))); +} + +bool GUIInventory::remove(const char *name) { + for (ItemsIterator i = _inventoryItems.begin(); i != _inventoryItems.end(); ++i) { + if (!strcmp(name, ((*i).get())->name)) { + _inventoryItems.erase(i); + _scrollPosition = 0; + return true; + } + } + + return false; +} + +int GUIInventory::getInsideIndex(int x, int y) { + if (!_bounds.contains(x, y)) + return -1; + + int localX = x - _bounds.left; + int localY = y - _bounds.top; + return (localX / _cellSize.x) * _cellCount.y + (localY / _cellSize.y); +} + +const char *GUIInventory::getSelectedObjectName() { + if (_selectedIndex != -1) { + ItemsIterator curItem = _inventoryItems.begin(); + for (int i = 0; i < _selectedIndex; i++) + ++curItem; + return curItem->get()->name; + } else { + return NULL; + } +} + +const Common::Point &GUIInventory::getCellPosition(int index) { + static Common::Point result; + + if (_cellCount.x > _cellCount.y) { + // Horizontal orientation + result.x = (index / _cellCount.y) * _cellSize.x; + result.y = (index % _cellCount.y) * _cellSize.x; + } else { + // Vertical orientation + result.x = (index / _cellCount.x) * _cellSize.y; + result.y = (index % _cellCount.x) * _cellSize.y; + } + + return result; +} + +void GUIInventory::setHighlight(int index) { + if (_highlightedIndex == index) + return; + + _highlightedIndex = index; +} + +void GUIInventory::setScrollPosition(int value) { + if (value < 0) + return; + else if (value >= (int)_inventoryItems.size() - (_cellCount.x * _cellCount.y)) + return; + + _scrollPosition = value; +} + +//-------------------------------------------------------------------------- + +const char *INTERFACE_SERIES = "999intr"; + +#define SPR(x) _sprites->getFrame(x) + +GameInterfaceView::GameInterfaceView(M4Engine *vm): + View(vm, Common::Rect(0, vm->_screen->height() - INTERFACE_HEIGHT, + vm->_screen->width(), vm->_screen->height())), + _statusText(GUITextField(this, Common::Rect(200, 1, 450, 21))), + _inventory(GUIInventory(this, vm, Common::Rect(188, 22, 539, 97), 9, 1, 39, 75, 3)) { + + _screenType = VIEWID_INTERFACE; + _screenFlags.layer = LAYER_INTERFACE; + _screenFlags.visible = false; + _screenFlags.get = SCREVENT_MOUSE; + _highlightedIndex = -1; + _selected = false; + + Common::SeekableReadStream *data = _vm->res()->get(INTERFACE_SERIES); + RGB8 *palette; + + _sprites = new SpriteAsset(_vm, data, data->size(), INTERFACE_SERIES); + palette = _sprites->getPalette(); + + //Palette.setPalette(palette, 0, _sprites->getColorCount()); + + _vm->res()->toss(INTERFACE_SERIES); + + // Setup the interface buttons + + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(15, 35, 47, 66), 0, SPR(0), SPR(1), SPR(2)))); // look + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(60, 35, 92, 66), 1, SPR(3), SPR(4), SPR(5)))); // take + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(105, 35, 137, 66), 2, SPR(6), SPR(7), SPR(8)))); // manipulate + + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(580, 10, 620, 69), 3, SPR(69), SPR(70), SPR(71)))); // abduction + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(582, 70, 619, 105), 4, SPR(76), SPR(77), SPR(78)))); // menu + + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(168, 22, 188, 97), 5, SPR(60), SPR(61), SPR(62)))); // Scroll left + _buttons.push_back(ButtonList::value_type(new GUIButton(this, Common::Rect(539, 22, 559, 97), 6, SPR(64), SPR(65), SPR(66)))); // Scroll right +} + +#undef SPR + +GameInterfaceView::~GameInterfaceView() { + delete _sprites; +} + +void GameInterfaceView::setHighlightedButton(int index) { + if (index == _highlightedIndex) + return; + + _selected = (index == -1); + _highlightedIndex = index; +} + +bool GameInterfaceView::onEvent(M4EventType eventType, int param, int x, int y, bool &captureEvents) { + static bool selectionFlag = false; + if (eventType == MEVENT_LEFT_RELEASE) + selectionFlag = false; + + captureEvents = isInside(x, y); + if (!captureEvents) + return false; + + int localX = x - _coords.left; + int localY = y - _coords.top; + GUIObject *currentItem; + + _statusText.onEvent(eventType, param, localX, localY, currentItem); + _inventory.onEvent(eventType, param, localX, localY, currentItem); + + if (_vm->_mouse->getCursorNum() != CURSOR_LOOK && + _vm->_mouse->getCursorNum() != CURSOR_TAKE && + _vm->_mouse->getCursorNum() != CURSOR_USE && + _vm->_interfaceView->_inventory.getSelectedIndex() == -1) { + if (_vm->_mouse->getCursorNum() != 0) + _vm->_mouse->setCursorNum(0); + } + + for (ButtonsIterator i = _buttons.begin(); i != _buttons.end(); ++i) { + GUIButton *btn = (*i).get(); + btn->onEvent(eventType, param, localX, localY, currentItem); + if ((btn->getState() == BUTTON_PRESSED) && !selectionFlag) { + selectionFlag = true; + _highlightedIndex = btn->getTag(); + + switch (_highlightedIndex) { + case 0: + _vm->_mouse->setCursorNum(CURSOR_LOOK); + break; + case 1: + _vm->_mouse->setCursorNum(CURSOR_TAKE); + break; + case 2: + _vm->_mouse->setCursorNum(CURSOR_USE); + break; + case 3: + // TODO: Jump to abduction + break; + case 4: + _vm->loadMenu(GAME_MENU); + break; + case 5: + _inventory.scrollLeft(); + break; + case 6: + _inventory.scrollRight(); + break; + default: + break; + } + } + } + + return true; +} + +void GameInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) { + empty(); + + _statusText.onRefresh(); + _inventory.onRefresh(); + for (ButtonsIterator i = _buttons.begin(); i != _buttons.end(); ++i) + ((*i).get())->onRefresh(); + + View::onRefresh(rects, destSurface); +} + + +} // End of namespace M4 |