Rework minimap rendering

This commit is contained in:
Eduardo Bart
2013-01-20 21:17:56 -02:00
parent 18a37393c5
commit ae731ddefc
23 changed files with 531 additions and 148 deletions

View File

@@ -44,6 +44,8 @@ set(client_SOURCES ${client_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/mapio.cpp
${CMAKE_CURRENT_LIST_DIR}/mapview.cpp
${CMAKE_CURRENT_LIST_DIR}/mapview.h
${CMAKE_CURRENT_LIST_DIR}/minimap.cpp
${CMAKE_CURRENT_LIST_DIR}/minimap.h
${CMAKE_CURRENT_LIST_DIR}/lightview.cpp
${CMAKE_CURRENT_LIST_DIR}/lightview.h
${CMAKE_CURRENT_LIST_DIR}/missile.cpp
@@ -92,6 +94,8 @@ set(client_SOURCES ${client_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/uiitem.h
${CMAKE_CURRENT_LIST_DIR}/uimap.cpp
${CMAKE_CURRENT_LIST_DIR}/uimap.h
${CMAKE_CURRENT_LIST_DIR}/uiminimap.cpp
${CMAKE_CURRENT_LIST_DIR}/uiminimap.h
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.cpp
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h

View File

@@ -28,6 +28,7 @@
#include "map.h"
#include "shadermanager.h"
#include "spritemanager.h"
#include "minimap.h"
#include <framework/core/configmanager.h>
Client g_client;
@@ -38,6 +39,7 @@ void Client::init(std::vector<std::string>& args)
registerLuaFunctions();
g_map.init();
g_minimap.init();
g_game.init();
g_shaders.init();
g_things.init();
@@ -84,6 +86,7 @@ void Client::terminate()
g_creatures.terminate();
g_game.terminate();
g_map.terminate();
g_minimap.terminate();
g_things.terminate();
g_sprites.terminate();
g_shaders.terminate();

View File

@@ -502,7 +502,7 @@ void Creature::updateWalkingTile()
// recache visible tiles in map views
if(newWalkingTile->isEmpty())
g_map.notificateTileUpdateToMapViews(newWalkingTile->getPosition());
g_map.notificateTileUpdate(newWalkingTile->getPosition());
}
m_walkingTile = newWalkingTile;
}

View File

@@ -92,11 +92,13 @@ typedef stdext::shared_object_ptr<ProtocolLogin> ProtocolLoginPtr;
class UIItem;
class UICreature;
class UIMap;
class UIMinimap;
class UIProgressRect;
typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr;
typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;
#endif

View File

@@ -43,6 +43,7 @@
#include "uiitem.h"
#include "uicreature.h"
#include "uimap.h"
#include "uiminimap.h"
#include "uiprogressrect.h"
#include "outfit.h"
@@ -548,7 +549,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIMap>("setAutoViewMode", &UIMap::setAutoViewMode);
g_lua.bindClassMemberFunction<UIMap>("setDrawFlags", &UIMap::setDrawFlags);
g_lua.bindClassMemberFunction<UIMap>("setDrawTexts", &UIMap::setDrawTexts);
g_lua.bindClassMemberFunction<UIMap>("setDrawMinimapColors", &UIMap::setDrawMinimapColors);
g_lua.bindClassMemberFunction<UIMap>("setDrawLights", &UIMap::setDrawLights);
g_lua.bindClassMemberFunction<UIMap>("setAnimated", &UIMap::setAnimated);
g_lua.bindClassMemberFunction<UIMap>("setKeepAspectRatio", &UIMap::setKeepAspectRatio);
@@ -557,7 +557,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIMap>("isMultifloor", &UIMap::isMultifloor);
g_lua.bindClassMemberFunction<UIMap>("isAutoViewModeEnabled", &UIMap::isAutoViewModeEnabled);
g_lua.bindClassMemberFunction<UIMap>("isDrawingTexts", &UIMap::isDrawingTexts);
g_lua.bindClassMemberFunction<UIMap>("isDrawingMinimapColors", &UIMap::isDrawingMinimapColors);
g_lua.bindClassMemberFunction<UIMap>("isDrawingLights", &UIMap::isDrawingLights);
g_lua.bindClassMemberFunction<UIMap>("isAnimating", &UIMap::isAnimating);
g_lua.bindClassMemberFunction<UIMap>("isKeepAspectRatioEnabled", &UIMap::isKeepAspectRatioEnabled);
@@ -574,6 +573,25 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<UIMap>("getMapShader", &UIMap::getMapShader);
g_lua.bindClassMemberFunction<UIMap>("getMinimumAmbientLight", &UIMap::getMinimumAmbientLight);
g_lua.registerClass<UIMinimap, UIWidget>();
g_lua.bindClassStaticFunction<UIMinimap>("create", []{ return UIMinimapPtr(new UIMinimap); });
g_lua.bindClassMemberFunction<UIMinimap>("zoomIn", &UIMinimap::zoomIn);
g_lua.bindClassMemberFunction<UIMinimap>("zoomOut", &UIMinimap::zoomOut);
g_lua.bindClassMemberFunction<UIMinimap>("setZoom", &UIMinimap::setZoom);
g_lua.bindClassMemberFunction<UIMinimap>("setMixZoom", &UIMinimap::setMinZoom);
g_lua.bindClassMemberFunction<UIMinimap>("setMaxZoom", &UIMinimap::setMaxZoom);
g_lua.bindClassMemberFunction<UIMinimap>("setCameraPosition", &UIMinimap::setCameraPosition);
g_lua.bindClassMemberFunction<UIMinimap>("setCross", &UIMinimap::setCross);
g_lua.bindClassMemberFunction<UIMinimap>("followCreature", &UIMinimap::followCreature);
g_lua.bindClassMemberFunction<UIMinimap>("getPosition", &UIMinimap::getPosition);
g_lua.bindClassMemberFunction<UIMinimap>("getCameraPosition", &UIMinimap::getCameraPosition);
g_lua.bindClassMemberFunction<UIMinimap>("getFollowingCreature", &UIMinimap::getFollowingCreature);
g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getZoom", &UIMinimap::getZoom);
g_lua.bindClassMemberFunction<UIMinimap>("getCross", &UIMinimap::getCross);
g_lua.bindClassMemberFunction<UIMinimap>("getScale", &UIMinimap::getScale);
g_lua.registerClass<UIProgressRect, UIWidget>();
g_lua.bindClassStaticFunction<UIProgressRect>("create", []{ return UIProgressRectPtr(new UIProgressRect); } );
g_lua.bindClassMemberFunction<UIProgressRect>("setPercent", &UIProgressRect::setPercent);

View File

@@ -28,6 +28,7 @@
#include "missile.h"
#include "statictext.h"
#include "mapview.h"
#include "minimap.h"
#include <framework/core/eventdispatcher.h>
#include <framework/core/application.h>
@@ -57,10 +58,14 @@ void Map::removeMapView(const MapViewPtr& mapView)
m_mapViews.erase(it);
}
void Map::notificateTileUpdateToMapViews(const Position& pos)
void Map::notificateTileUpdate(const Position& pos)
{
if(!pos.isMapPosition())
return;
for(const MapViewPtr& mapView : m_mapViews)
mapView->onTileUpdate(pos);
g_minimap.updateTile(pos, getTile(pos));
}
void Map::clean()
@@ -159,7 +164,7 @@ void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
thing->onAppear();
}
notificateTileUpdateToMapViews(pos);
notificateTileUpdate(pos);
}
ThingPtr Map::getThing(const Position& pos, int stackPos)
@@ -174,7 +179,7 @@ bool Map::removeThing(const ThingPtr& thing)
if(!thing)
return false;
notificateTileUpdateToMapViews(thing->getPosition());
notificateTileUpdate(thing->getPosition());
if(thing->isMissile()) {
MissilePtr missile = thing->static_self_cast<Missile>();
@@ -288,7 +293,7 @@ void Map::cleanTile(const Position& pos)
if(tile->canErase())
block.remove(pos);
notificateTileUpdateToMapViews(pos);
notificateTileUpdate(pos);
}
}
for(auto it = m_staticTexts.begin();it != m_staticTexts.end();) {

View File

@@ -139,7 +139,7 @@ public:
void addMapView(const MapViewPtr& mapView);
void removeMapView(const MapViewPtr& mapView);
void notificateTileUpdateToMapViews(const Position& pos);
void notificateTileUpdate(const Position& pos);
bool loadOtcm(const std::string& fileName);
void saveOtcm(const std::string& fileName);

View File

@@ -440,6 +440,8 @@ bool Map::loadOtcm(const std::string& fileName)
if(item->isValid())
tile->addThing(item, stackPos++);
}
g_map.notificateTileUpdate(pos);
}
fin->close();

View File

@@ -130,19 +130,10 @@ void MapView::draw(const Rect& rect)
else
++it;
if(!m_drawMinimapColors)
tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags, m_lightView.get());
else {
uint8 c = tile->getMinimapColorByte();
if(c == 0)
continue;
g_painter->setColor(Color::from8bit(c));
g_painter->drawFilledRect(Rect(transformPositionTo2D(tilePos, cameraPosition), tileSize));
}
tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags, m_lightView.get());
}
if(drawFlags & Otc::DrawMissiles && !m_drawMinimapColors) {
if(drawFlags & Otc::DrawMissiles) {
for(const MissilePtr& missile : g_map.getFloorMissiles(z)) {
missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), scaleFactor, drawFlags & Otc::DrawAnimations, m_lightView.get());
}
@@ -283,36 +274,6 @@ void MapView::draw(const Rect& rect)
p += rect.topLeft();
animatedText->drawText(p, rect);
}
} else if(m_viewMode > NEAR_VIEW) {
// draw a cross in the center instead of our creature
/*
Known Issue: Changing Z axis causes the cross to go off a little bit.
*/
Rect vRect(0, 0, 2, 10);
Rect hRect(0, 0, 10, 2);
g_painter->setColor(Color::white);
if(!m_follow && m_followingCreature)
{
Position pos = m_followingCreature->getPosition();
Point p = transformPositionTo2D(pos, cameraPosition) - drawOffset;
p.x = p.x * horizontalStretchFactor;
p.y = p.y * verticalStretchFactor;
p += rect.topLeft();
vRect.setX(p.x); vRect.setY(p.y - 4);
hRect.setX(p.x - 4); hRect.setY(p.y);
hRect.setWidth(10); hRect.setHeight(2);
vRect.setWidth(2); vRect.setHeight(10);
}
else {
vRect.moveCenter(rect.center());
hRect.moveCenter(rect.center());
}
g_painter->drawFilledRect(vRect);
g_painter->drawFilledRect(hRect);
}
}
@@ -453,25 +414,20 @@ void MapView::updateGeometry(const Size& visibleDimension, const Size& optimized
int tileSize = 0;
Size bufferSize;
if(!m_drawMinimapColors) {
int possiblesTileSizes[] = {1,2,4,8,16,32};
for(int candidateTileSize : possiblesTileSizes) {
bufferSize = (visibleDimension + Size(3,3)) * candidateTileSize;
if(bufferSize.width() > g_graphics.getMaxTextureSize() || bufferSize.height() > g_graphics.getMaxTextureSize())
break;
int possiblesTileSizes[] = {1,2,4,8,16,32};
for(int candidateTileSize : possiblesTileSizes) {
bufferSize = (visibleDimension + Size(3,3)) * candidateTileSize;
if(bufferSize.width() > g_graphics.getMaxTextureSize() || bufferSize.height() > g_graphics.getMaxTextureSize())
break;
tileSize = candidateTileSize;
if(optimizedSize.width() < bufferSize.width() - 3*candidateTileSize && optimizedSize.height() < bufferSize.height() - 3*candidateTileSize)
break;
}
tileSize = candidateTileSize;
if(optimizedSize.width() < bufferSize.width() - 3*candidateTileSize && optimizedSize.height() < bufferSize.height() - 3*candidateTileSize)
break;
}
if(tileSize == 0) {
g_logger.traceError("reached max zoom out");
return;
}
} else {
tileSize = 1;
bufferSize = visibleDimension + Size(3,3);
if(tileSize == 0) {
g_logger.traceError("reached max zoom out");
return;
}
Size drawDimension = visibleDimension + Size(3,3);
@@ -518,8 +474,7 @@ void MapView::updateGeometry(const Size& visibleDimension, const Size& optimized
void MapView::onTileUpdate(const Position& pos)
{
if(!m_drawMinimapColors)
requestVisibleTilesCacheUpdate();
requestVisibleTilesCacheUpdate();
}
void MapView::onMapCenterChange(const Position& pos)
@@ -682,17 +637,6 @@ Position MapView::getCameraPosition()
return m_customCameraPosition;
}
void MapView::setDrawMinimapColors(bool enable)
{
if(m_drawMinimapColors == enable)
return;
m_drawMinimapColors = enable;
updateGeometry(m_visibleDimension, m_optimizedSize);
requestVisibleTilesCacheUpdate();
m_smooth = !enable;
m_framebuffer->setSmooth(m_smooth);
}
void MapView::setShader(const PainterShaderProgramPtr& shader, float fadein, float fadeout)
{
if((m_shader == shader && m_shaderSwitchDone) || (m_nextShader == shader && !m_shaderSwitchDone))

View File

@@ -98,9 +98,6 @@ public:
void setDrawTexts(bool enable) { m_drawTexts = enable; }
bool isDrawingTexts() { return m_drawTexts; }
void setDrawMinimapColors(bool enable);
bool isDrawingMinimapColors() { return m_drawMinimapColors; }
void setAnimated(bool animated) { m_animated = animated; requestVisibleTilesCacheUpdate(); }
bool isAnimating() { return m_animated; }
@@ -139,7 +136,6 @@ private:
stdext::boolean<true> m_autoViewMode;
stdext::boolean<true> m_drawTexts;
stdext::boolean<true> m_smooth;
stdext::boolean<false> m_drawMinimapColors;
stdext::boolean<false> m_drawLights;
stdext::boolean<true> m_follow;
std::vector<TilePtr> m_cachedVisibleTiles;

View File

@@ -22,4 +22,200 @@
#include "minimap.h"
#include "tile.h"
#include <framework/graphics/image.h>
#include <framework/graphics/texture.h>
#include <framework/graphics/painter.h>
#include <framework/graphics/framebuffermanager.h>
#include <boost/concept_check.hpp>
Minimap g_minimap;
void MinimapBlock::updateImage()
{
if(!m_image)
m_image = ImagePtr(new Image(Size(MMBLOCK_SIZE, MMBLOCK_SIZE)));
else
m_image->resize(Size(MMBLOCK_SIZE, MMBLOCK_SIZE));
for(int x=0;x<MMBLOCK_SIZE;++x)
for(int y=0;y<MMBLOCK_SIZE;++y)
m_image->setPixel(x, y, Color::from8bit(getTile(x, y).color).rgba());
}
void MinimapBlock::updateTexture()
{
if(!m_image)
return;
if(!m_texture) {
m_texture = TexturePtr(new Texture(m_image, true));
} else {
m_texture->uploadPixels(m_image, true);
}
}
void MinimapBlock::clean()
{
m_tiles.fill(MinimapTile());
m_image.reset();
m_texture.reset();
m_shouldDraw = false;
m_mustUpdate = false;
}
void MinimapBlock::update()
{
if(!m_mustUpdate)
return;
if(m_shouldDraw) {
updateImage();
updateTexture();
}
m_mustUpdate = false;
}
void MinimapBlock::updateTile(int x, int y, const MinimapTile& tile)
{
if(!(m_tiles[getTileIndex(x,y)] == tile)) {
m_tiles[getTileIndex(x,y)] = tile;
if(tile.color != 0)
m_shouldDraw = true;
m_mustUpdate = true;
}
}
void Minimap::init()
{
}
void Minimap::terminate()
{
clean();
}
void Minimap::clean()
{
for(int i=0;i<=Otc::MAX_Z;++i)
m_tileBlocks[i].clear();
}
void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scale)
{
if(screenRect.isEmpty())
return;
if(MMBLOCK_SIZE*scale <= 1)
return;
Size mapSize = screenRect.size() / scale;
while(mapSize.width() > 8192 || mapSize.height() > 8192) {
scale *= 2;
mapSize = screenRect.size() / scale;
}
Rect mapRect(0, 0, mapSize);
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
g_painter->saveState();
g_painter->setColor(Color::black);
g_painter->drawFilledRect(screenRect);
g_painter->resetColor();
g_painter->setClipRect(screenRect);
g_painter->translate(screenRect.topLeft());
Point p = getBlockOffset(mapRect.topLeft() - Point(1,1));
g_painter->translate(-(mapRect.topLeft() - p)*scale);
if(scale > 1.0f)
g_painter->translate(Point(1,1) * scale * 0.5f);
for(int y = p.y, ys = 0;y<=mapRect.bottom();y += MMBLOCK_SIZE, ys += MMBLOCK_SIZE*scale) {
if(y < 0 || y >= 65536 - MMBLOCK_SIZE)
continue;
for(int x = p.x, xs = 0;x<=mapRect.right();x += MMBLOCK_SIZE, xs += MMBLOCK_SIZE*scale) {
if(x < 0 || x >= 65536 - MMBLOCK_SIZE)
continue;
MinimapBlock& block = getBlock(Position(x, y, mapCenter.z));
block.update();
if(block.shouldDraw()) {
Rect src(0, 0, MMBLOCK_SIZE, MMBLOCK_SIZE);
Rect dest(Point(xs,ys), src.size() * scale);
const TexturePtr& tex = block.getTexture();
tex->setSmooth(scale < 1.0f);
g_painter->drawTexturedRect(dest, tex, src);
}
}
}
g_painter->restoreSavedState();
}
Position Minimap::getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale)
{
if(screenRect.isEmpty())
return Position();
if(MMBLOCK_SIZE*scale <= 1)
return Position();
Position pos(mapCenter);
Size mapSize = screenRect.size() / scale;
while(mapSize.width() > 8192 || mapSize.height() > 8192) {
scale *= 2;
mapSize = screenRect.size() / scale;
}
Rect mapRect(0, 0, mapSize);
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
Point p = (point - screenRect.topLeft() - Point(1,1) * scale * 0.5f)/scale + mapRect.topLeft();
pos.x = p.x;
pos.y = p.y;
return pos;
}
void Minimap::updateTile(const Position& pos, const TilePtr& tile)
{
MinimapBlock& block = getBlock(pos);
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
MinimapTile minimapTile;
if(tile) {
minimapTile.color = tile->getMinimapColorByte();
if(tile->isWalkable())
minimapTile.flags |= MinimapTileWalkable;
if(tile->isPathable())
minimapTile.flags |= MinimapTilePathable;
if(tile->changesFloor())
minimapTile.flags |= MinimapTileChangesFloor;
}
block.updateTile(pos.x - offsetPos.x, pos.y - offsetPos.y, minimapTile);
}
bool Minimap::checkTileProperty(const Position& pos, int flags)
{
MinimapBlock& block = getBlock(pos);
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
return block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y).flags & flags;
}
void Minimap::loadOtmm(const std::string& fileName)
{
}
void Minimap::saveOtmm(const std::string& fileName)
{
}

View File

@@ -24,19 +24,51 @@
#ifndef MINIMAP_H
#define MINIMAP_H
#include "global.h"
#include <framework/graphics/image.h>
/*
#include "declarations.h"
#include <framework/graphics/declarations.h>
enum {
MINIMAP_AREA_SIZE = 32
MMBLOCK_SIZE = 64
};
struct MinimapArea
enum MinimapTileFlags {
MinimapTilePathable = 1,
MinimapTileWalkable = 2,
MinimapTileChangesFloor = 4
};
#pragma pack(push,1) // disable memory alignment
struct MinimapTile
{
ImagePtr img;
TexturePtr tex;
uint8 colors[MINIMAP_AREA_SIZE][MINIMAP_AREA_SIZE];
stdext::boolean<true> mustUpdate;
MinimapTile() : flags(0), color(0) { }
uint8 flags;
uint8 color;
bool operator==(const MinimapTile& other) { return color == other.color && flags == other.flags; }
};
#pragma pack(pop)
class MinimapBlock
{
public:
void updateImage();
void updateTexture();
void clean();
void update();
void updateTile(int x, int y, const MinimapTile& tile);
MinimapTile& getTile(int x, int y) { return m_tiles[getTileIndex(x,y)]; }
void resetTile(int x, int y) { m_tiles[getTileIndex(x,y)] = MinimapTile(); }
uint getTileIndex(int x, int y) { return ((y % MMBLOCK_SIZE) * MMBLOCK_SIZE) + (x % MMBLOCK_SIZE); }
const TexturePtr& getTexture() { return m_texture; }
std::array<MinimapTile, MMBLOCK_SIZE *MMBLOCK_SIZE> getTiles() { return m_tiles; }
bool shouldDraw() { return m_shouldDraw; }
private:
ImagePtr m_image;
TexturePtr m_texture;
stdext::boolean<false> m_shouldDraw;
std::array<MinimapTile, MMBLOCK_SIZE *MMBLOCK_SIZE> m_tiles;
stdext::boolean<true> m_mustUpdate;
};
class Minimap
@@ -46,21 +78,25 @@ public:
void init();
void terminate();
void loadOtmm();
void saveOtmm();
void clean();
void updateTile(const Position& pos, uint8 color);
void draw(const Rect& screenRect, const Position& mapCenter, float scale);
Position getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale);
void updateTile(const Position& pos, const TilePtr& tile);
bool checkTileProperty(const Position& pos, int flags);
void loadOtmm(const std::string& fileName);
void saveOtmm(const std::string& fileName);
private:
struct MinimaAreaHasher : std::unary_function<Position, std::size_t> {
std::size_t operator()(const Position& pos) const {
return ((pos.x/MINIMAP_AREA_SIZE) * 0x8000 + (pos.y/MINIMAP_AREA_SIZE)) * 16 + pos.z;
}
};
std::unordered_map<Position, ImagePtr, MinimaAreaHasher> m_areas;
MinimapBlock& getBlock(const Position& pos) { return m_tileBlocks[pos.z][getBlockIndex(pos)]; }
Point getBlockOffset(const Point& pos) { return Point(pos.x - pos.x % MMBLOCK_SIZE,
pos.y - pos.y % MMBLOCK_SIZE); }
uint getBlockIndex(const Position& pos) { return ((pos.y / MMBLOCK_SIZE) * (65536 / MMBLOCK_SIZE)) + (pos.x / MMBLOCK_SIZE); }
std::unordered_map<uint, MinimapBlock> m_tileBlocks[Otc::MAX_Z+1];
};
extern Minimap g_minimap;
*/
#endif

View File

@@ -179,8 +179,6 @@ void UIMap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleN
setAutoViewMode(node->value<bool>());
else if(node->tag() == "draw-texts")
setDrawTexts(node->value<bool>());
else if(node->tag() == "draw-minimap-colors")
setDrawMinimapColors(node->value<bool>());
else if(node->tag() == "draw-lights")
setDrawLights(node->value<bool>());
else if(node->tag() == "animated")

View File

@@ -51,7 +51,6 @@ public:
void setAutoViewMode(bool enable) { m_mapView->setAutoViewMode(enable); }
void setDrawFlags(Otc::DrawFlags drawFlags) { m_mapView->setDrawFlags(drawFlags); }
void setDrawTexts(bool enable) { m_mapView->setDrawTexts(enable); }
void setDrawMinimapColors(bool enable) { m_mapView->setDrawMinimapColors(enable); }
void setDrawLights(bool enable) { m_mapView->setDrawLights(enable); }
void setAnimated(bool enable) { m_mapView->setAnimated(enable); }
void setKeepAspectRatio(bool enable);
@@ -61,7 +60,6 @@ public:
bool isMultifloor() { return m_mapView->isMultifloor(); }
bool isAutoViewModeEnabled() { return m_mapView->isAutoViewModeEnabled(); }
bool isDrawingTexts() { return m_mapView->isDrawingTexts(); }
bool isDrawingMinimapColors() { return m_mapView->isDrawingMinimapColors(); }
bool isDrawingLights() { return m_mapView->isDrawingLights(); }
bool isAnimating() { return m_mapView->isAnimating(); }
bool isKeepAspectRatioEnabled() { return m_aspectRatio != 0.0f; }

108
src/client/uiminimap.cpp Normal file
View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "uiminimap.h"
#include "minimap.h"
#include "game.h"
#include <framework/graphics/painter.h>
UIMinimap::UIMinimap()
{
m_crossEnabled = true;
m_zoom = 0;
m_minZoom = -5;
m_maxZoom = 5;
}
void UIMinimap::drawSelf(Fw::DrawPane drawPane)
{
UIWidget::drawSelf(drawPane);
if((drawPane & Fw::ForegroundPane) == 0)
return;
g_minimap.draw(getPaddingRect(), getCameraPosition(), m_scale);
// draw a cross in the center
Rect vRect(0, 0, 2, 10);
Rect hRect(0, 0, 10, 2);
vRect.moveCenter(m_rect.center());
hRect.moveCenter(m_rect.center());
g_painter->setColor(Color::white);
g_painter->drawFilledRect(vRect);
g_painter->drawFilledRect(hRect);
}
bool UIMinimap::setZoom(int zoom)
{
if(zoom < m_minZoom || zoom > m_maxZoom)
return false;
m_zoom = zoom;
if(m_zoom < 0)
m_scale = 1.0f / (1 << std::abs(zoom));
else if(m_zoom > 0)
m_scale = 1.0f * (1 << std::abs(zoom));
else
m_scale = 1;
return true;
}
void UIMinimap::followCreature(const CreaturePtr& creature)
{
m_followingCreature = creature;
m_cameraPosition = Position();
}
void UIMinimap::setCameraPosition(const Position& pos)
{
m_followingCreature = nullptr;
m_cameraPosition = pos;
}
Position UIMinimap::getPosition(const Point& mousePos)
{
return g_minimap.getPosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale);
}
Position UIMinimap::getCameraPosition()
{
if(m_followingCreature)
return m_followingCreature->getPosition();
else
return m_cameraPosition;
}
void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
UIWidget::onStyleApply(styleName, styleNode);
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "zoom")
setZoom(node->value<int>());
else if(node->tag() == "max-zoom")
setMaxZoom(node->value<int>());
else if(node->tag() == "min-zoom")
setMinZoom(node->value<int>());
else if(node->tag() == "cross")
setCross(node->value<bool>());
}
}

69
src/client/uiminimap.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef UIMINIMAP_H
#define UIMINIMAP_H
#include "declarations.h"
#include <framework/ui/uiwidget.h>
class UIMinimap : public UIWidget
{
public:
UIMinimap();
void drawSelf(Fw::DrawPane drawPane);
bool zoomIn() { return setZoom(m_zoom-1); }
bool zoomOut() { return setZoom(m_zoom+1); }
bool setZoom(int zoom);
void setMinZoom(int minZoom) { m_minZoom = minZoom; }
void setMaxZoom(int maxZoom) { m_maxZoom = maxZoom; }
void setCameraPosition(const Position& pos);
void setCross(bool enable) { m_crossEnabled = enable; }
void followCreature(const CreaturePtr& creature);
Position getPosition(const Point& mousePos);
Position getCameraPosition();
CreaturePtr getFollowingCreature() { return m_followingCreature; }
int getMinZoom() { return m_minZoom; }
int getMaxZoom() { return m_maxZoom; }
int getZoom() { return m_zoom; }
bool getCross() { return m_crossEnabled; }
float getScale() { return m_scale; }
protected:
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
private:
Rect m_mapArea;
bool m_crossEnabled;
CreaturePtr m_followingCreature;
Position m_cameraPosition;
float m_scale;
int m_zoom;
int m_minZoom;
int m_maxZoom;
};
#endif

View File

@@ -37,9 +37,11 @@ public:
void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha);
void blit(const Point& dest, const ImagePtr& other);
void paste(const ImagePtr& other);
void resize(const Size& size) { m_size = size; m_pixels.resize(size.area() * m_bpp, 0); }
bool nextMipmap();
void setPixel(int x, int y, uint8 *pixel) { memcpy(&m_pixels[(y * m_size.width() + x) * m_bpp], pixel, m_bpp);}
void setPixel(int x, int y, const Color& color) { uint32 tmp = color.rgba(); setPixel(x,y,(uint8*)&tmp); }
std::vector<uint8>& getPixels() { return m_pixels; }
uint8* getPixelData() { return &m_pixels[0]; }

View File

@@ -55,6 +55,21 @@ Texture::Texture(const ImagePtr& image, bool buildMipmaps, bool compress)
createTexture();
uploadPixels(image, buildMipmaps, compress);
}
Texture::~Texture()
{
#ifndef NDEBUG
assert(!g_app.isTerminated());
#endif
// free texture from gl memory
if(g_graphics.ok() && m_id != 0)
glDeleteTextures(1, &m_id);
}
void Texture::uploadPixels(const ImagePtr& image, bool buildMipmaps, bool compress)
{
ImagePtr glImage = image;
if(m_size != m_glSize) {
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));
@@ -77,16 +92,6 @@ Texture::Texture(const ImagePtr& image, bool buildMipmaps, bool compress)
setupFilters();
}
Texture::~Texture()
{
#ifndef NDEBUG
assert(!g_app.isTerminated());
#endif
// free texture from gl memory
if(g_graphics.ok() && m_id != 0)
glDeleteTextures(1, &m_id);
}
void Texture::bind()
{
// must reset painter texture state

View File

@@ -33,6 +33,7 @@ public:
Texture(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
virtual ~Texture();
void uploadPixels(const ImagePtr& image, bool buildMipmaps = false, bool compress = false);
void bind();
void copyFromScreen(const Rect& screenRect);
virtual bool buildHardwareMipmaps();

View File

@@ -95,7 +95,7 @@ public:
}
}
}
void scale(int w, int h, Fw::AspectRatioMode mode) { scale(TSize<T>(w, h)); }
void scale(int w, int h, Fw::AspectRatioMode mode) { scale(TSize<T>(w, h), mode); }
float ratio() const { return (float)wd/ht; }
T area() const { return wd*ht; }