Initial commit
This commit is contained in:
249
engines/ultima/ultima8/gumps/minimap_gump.cpp
Normal file
249
engines/ultima/ultima8/gumps/minimap_gump.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/* 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 "ultima/ultima8/gumps/minimap_gump.h"
|
||||
#include "ultima/ultima8/world/minimap.h"
|
||||
#include "ultima/ultima8/world/current_map.h"
|
||||
#include "ultima/ultima8/world/world.h"
|
||||
#include "ultima/ultima8/world/actors/main_actor.h"
|
||||
#include "ultima/ultima8/gfx/palette.h"
|
||||
#include "ultima/ultima8/gfx/palette_manager.h"
|
||||
#include "ultima/ultima8/gfx/render_surface.h"
|
||||
#include "ultima/ultima8/gfx/texture.h"
|
||||
#include "ultima/ultima8/world/get_object.h"
|
||||
#include "ultima/ultima8/kernel/mouse.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima8 {
|
||||
|
||||
DEFINE_RUNTIME_CLASSTYPE_CODE(MiniMapGump)
|
||||
|
||||
static const uint BACKGROUND_COLOR = 0;
|
||||
static const uint NORMAL_COLOR = 53;
|
||||
static const uint HIGHLIGHT_COLOR = 52;
|
||||
static const uint KEY_COLOR = 255;
|
||||
|
||||
MiniMapGump::MiniMapGump(int x, int y) : ResizableGump(x, y, 120, 120), _minimaps(), _ax(0), _ay(0) {
|
||||
setMinSize(60, 60);
|
||||
}
|
||||
|
||||
MiniMapGump::MiniMapGump() : ResizableGump(), _minimaps(), _ax(0), _ay(0) {
|
||||
setMinSize(60, 60);
|
||||
}
|
||||
|
||||
MiniMapGump::~MiniMapGump(void) {
|
||||
for (auto &i : _minimaps) {
|
||||
delete i._value;
|
||||
}
|
||||
}
|
||||
|
||||
void MiniMapGump::run() {
|
||||
Gump::run();
|
||||
|
||||
World *world = World::get_instance();
|
||||
CurrentMap *currentmap = world->getCurrentMap();
|
||||
int mapChunkSize = currentmap->getChunkSize();
|
||||
|
||||
MainActor *actor = getMainActor();
|
||||
if (!actor || actor->isDead())
|
||||
return;
|
||||
|
||||
uint32 mapNum = currentmap->getNum();
|
||||
MiniMap *minimap = _minimaps[mapNum];
|
||||
if (!minimap) {
|
||||
minimap = new MiniMap(mapNum);
|
||||
_minimaps[mapNum] = minimap;
|
||||
}
|
||||
|
||||
Common::Point p = minimap->getItemLocation(*actor, mapChunkSize);
|
||||
|
||||
// Skip map update if location has not changed
|
||||
if (p.x == _ax && p.y == _ay)
|
||||
return;
|
||||
|
||||
_ax = p.x;
|
||||
_ay = p.y;
|
||||
|
||||
minimap->update(*currentmap);
|
||||
}
|
||||
|
||||
void MiniMapGump::generate() {
|
||||
World *world = World::get_instance();
|
||||
CurrentMap *currentmap = world->getCurrentMap();
|
||||
currentmap->setWholeMapFast();
|
||||
|
||||
uint32 mapNum = currentmap->getNum();
|
||||
|
||||
MiniMap *minimap = _minimaps[mapNum];
|
||||
if (!minimap) {
|
||||
minimap = new MiniMap(mapNum);
|
||||
_minimaps[mapNum] = minimap;
|
||||
}
|
||||
minimap->update(*currentmap);
|
||||
}
|
||||
|
||||
void MiniMapGump::clear() {
|
||||
for (auto &i : _minimaps) {
|
||||
delete i._value;
|
||||
}
|
||||
_minimaps.clear();
|
||||
}
|
||||
|
||||
bool MiniMapGump::dump(const Common::Path &filename) const {
|
||||
World *world = World::get_instance();
|
||||
CurrentMap *currentmap = world->getCurrentMap();
|
||||
|
||||
uint32 mapNum = currentmap->getNum();
|
||||
|
||||
MiniMap *minimap = _minimaps[mapNum];
|
||||
return minimap ? minimap->dump(filename) : false;
|
||||
}
|
||||
|
||||
void MiniMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
|
||||
Palette *pal = PaletteManager::get_instance()->getPalette(PaletteManager::Pal_Game);
|
||||
uint32 *map = pal->_native;
|
||||
|
||||
uint32 color = map[NORMAL_COLOR];
|
||||
if (_dragPosition != Gump::CENTER || _mousePosition != Gump::CENTER)
|
||||
color = map[HIGHLIGHT_COLOR];
|
||||
|
||||
// Draw the border
|
||||
surf->frameRect(_dims, color);
|
||||
|
||||
// Dimensions minus border
|
||||
Common::Rect32 dims = _dims;
|
||||
dims.grow(-1);
|
||||
|
||||
// Fill the background
|
||||
surf->fillRect(dims, map[BACKGROUND_COLOR]);
|
||||
|
||||
// Center on avatar
|
||||
int sx = _ax - dims.width() / 2;
|
||||
int sy = _ay - dims.height() / 2;
|
||||
int dx = 1;
|
||||
int dy = 1;
|
||||
|
||||
World *world = World::get_instance();
|
||||
CurrentMap *currentmap = world->getCurrentMap();
|
||||
uint32 mapNum = currentmap->getNum();
|
||||
|
||||
MiniMap *minimap = _minimaps[mapNum];
|
||||
if (!minimap) {
|
||||
minimap = new MiniMap(mapNum);
|
||||
_minimaps[mapNum] = minimap;
|
||||
}
|
||||
|
||||
const Graphics::Surface *ms = minimap->getSurface();
|
||||
Common::Rect r(sx, sy, sx + dims.width(), sy + dims.height());
|
||||
|
||||
if (r.left < 0) {
|
||||
dx -= r.left;
|
||||
r.left = 0;
|
||||
}
|
||||
if (r.right > ms->w) {
|
||||
r.right = ms->w;
|
||||
}
|
||||
|
||||
if (r.top < 0) {
|
||||
dy -= r.top;
|
||||
r.top = 0;
|
||||
}
|
||||
if (r.bottom > ms->h) {
|
||||
r.bottom = ms->h;
|
||||
}
|
||||
|
||||
if (!r.isEmpty()) {
|
||||
surf->CrossKeyBlitMap(*ms, r, dx, dy, map, KEY_COLOR);
|
||||
}
|
||||
|
||||
int32 ax = _ax - sx;
|
||||
int32 ay = _ay - sy;
|
||||
|
||||
// Paint the avatar position marker
|
||||
surf->drawLine(ax - 1, ay + 1, ax, ay + 1, color);
|
||||
surf->drawLine(ax + 1, ay - 1, ax + 1, ay, color);
|
||||
surf->drawLine(ax + 2, ay + 1, ax + 3, ay + 1, color);
|
||||
surf->drawLine(ax + 1, ay + 2, ax + 1, ay + 3, color);
|
||||
}
|
||||
|
||||
Gump *MiniMapGump::onMouseDown(int button, int32 mx, int32 my) {
|
||||
Gump *handled = Gump::onMouseDown(button, mx, my);
|
||||
if (handled)
|
||||
return handled;
|
||||
|
||||
// only interested in left clicks
|
||||
if (button == Mouse::BUTTON_LEFT)
|
||||
return this;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MiniMapGump::onMouseDouble(int button, int32 mx, int32 my) {
|
||||
if (button == Mouse::BUTTON_LEFT) {
|
||||
HideGump();
|
||||
}
|
||||
}
|
||||
|
||||
void MiniMapGump::saveData(Common::WriteStream *ws) {
|
||||
Gump::saveData(ws);
|
||||
|
||||
ws->writeUint32LE(static_cast<uint32>(_minimaps.size()));
|
||||
for (const auto &i : _minimaps) {
|
||||
const MiniMap *minimap = i._value;
|
||||
ws->writeUint32LE(i._key);
|
||||
minimap->save(ws);
|
||||
}
|
||||
}
|
||||
|
||||
bool MiniMapGump::loadData(Common::ReadStream *rs, uint32 version) {
|
||||
if (!Gump::loadData(rs, version))
|
||||
return false;
|
||||
|
||||
_ax = 0;
|
||||
_ay = 0;
|
||||
|
||||
clear();
|
||||
|
||||
if (version >= 6) {
|
||||
uint32 mapcount = rs->readUint32LE();
|
||||
for (uint32 i = 0; i < mapcount; ++i) {
|
||||
uint32 mapNum = rs->readUint32LE();
|
||||
MiniMap *minimap = new MiniMap(mapNum);
|
||||
if (!minimap->load(rs, version))
|
||||
return false;
|
||||
_minimaps[mapNum] = minimap;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16 MiniMapGump::TraceObjId(int32 mx, int32 my) {
|
||||
uint16 objId = Gump::TraceObjId(mx, my);
|
||||
|
||||
if (!objId || objId == 65535)
|
||||
if (PointOnGump(mx, my))
|
||||
objId = getObjId();
|
||||
|
||||
return objId;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima8
|
||||
} // End of namespace Ultima
|
||||
Reference in New Issue
Block a user