maptileclient.cpp from FreePop at Krugle
Show maptileclient.cpp syntax highlighted
/***************************************************************************
maptile.cpp - description
-------------------
begin : Mon Aug 5 2002
copyright : (C) 2002 by Brendon Higgins
email : freepop-devel@lists.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include <client.h>
#include <corner.h>
#include <mappos.h>
#include <maptileclient.h>
#include <maptilepos.h>
#include <misc.h>
#include <rules.h>
#include <worldpos.h>
#include <ClanLib/display.h>
#include <cassert>
const int MapTileClient::PICWIDTH = 128;
const int MapTileClient::PICHEIGHT = 64;
CL_Sprite** MapTileClient::sprites = 0;
MapTileClient::MapTileClient() {
}
MapTileClient::MapTileClient(const MapTileClient& t): MapTile(t) {
}
MapTileClient::~MapTileClient() {
}
MapTileClient& MapTileClient::operator=(const MapTileClient& copy) {
z = copy.z;
s = copy.s;
return *this;
}
MapTileClient& MapTileClient::operator*=(const Rotation& r) {
MapTile::operator*=(r);
return *this;
}
CL_Point MapTileClient::getOffset() const {
return offset;
}
CL_Point MapTileClient::calcOffset(const MapPos& p) {
offset = CL_Point(picWidth() * (p.getX() - p.getY()) / 2,
picHeight() * (p.getX() + p.getY() - int(z)) / 2);
return offset;
}
Corner MapTileClient::calcNearestScreenCorner(const CL_Point& p) const {
CL_Point a = findPosSlope(Corner::NORTH) - p;
CL_Point b = findPosSlope(Corner::EAST) - p;
CL_Point c = findPosSlope(Corner::SOUTH) - p;
CL_Point d = findPosSlope(Corner::WEST) - p;
int ad = a.x * a.x + a.y * a.y;
int bd = b.x * b.x + b.y * b.y;
int cd = c.x * c.x + c.y * c.y;
int dd = d.x * d.x + d.y * d.y;
int m = min(ad, bd, cd, dd);
if (m == ad) return Corner::NORTH;
else if (m == bd) return Corner::EAST;
else if (m == cd) return Corner::SOUTH;
else return Corner::WEST;
}
MapTilePos MapTileClient::findPos(const CL_Point& gp) const {
return findPosSlope(gp - getOffset());
}
CL_Point MapTileClient::findPosSlope(const MapTilePos& p) const {
switch (getSlope().getRaw()) {
case 0:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()) / 2);
case 1:
if (p.getX() + p.getY() >= 1.0f) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()));
}
case 2:
if (p.getX() <= p.getY()) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getY() - 0.5f) * picHeight()));
}
case 3:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + 2.0f * p.getY() - 2.0f) * picHeight()) / 2);
case 4:
if (p.getX() + p.getY() >= 1.0f) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2, 0);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()) / 2);
}
case 5:
if (p.getX() + p.getY() >= 1.0f) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2, 0);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()));
}
case 6:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getY() - 1.0f) * picHeight()) / 2);
case 7:
if (p.getX() >= p.getY()) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 2.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getY() - 1.0f) * picHeight()));
}
case 8:
// HACK, A little bit of a
if (p.getX() >= p.getY()) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() - 0.5f) * picHeight()));
}
case 9:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getY() + 2.0f * p.getX() - 2.0f) * picHeight()) / 2);
case 10:
if (p.getX() >= p.getY()) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getY() - 0.5f) * picHeight()));
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() - 0.5f) * picHeight()));
}
case 11:
if (p.getX() + p.getY() <= 1.0f) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 2.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.5f) * picHeight()));
}
case 12:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() - 1.0f) * picHeight()) / 2);
case 13:
if (p.getX() <= p.getY()) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 2.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() - 1.0f) * picHeight()));
}
case 14:
if (p.getX() + p.getY() >= 1.0f) {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 2.0f) * picHeight()) / 2);
} else {
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
picHeight() / -2); // Any position produces this y.
}
//case 15: There is no 15th slope.
case 16:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() + p.getY() - 1.5f) * picHeight()));
case 17:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getY() - 1.0f) * picHeight()));
case 18:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
picHeight() / -2); // Any position produces this y.
case 19:
return CL_Point(int((p.getX() - p.getY()) * picWidth()) / 2,
int((p.getX() - 1.0f) * picHeight()));
default:
// This should never happen.
assert(0 && "Bad slope state in switch.");
return CL_Point(0, 0);
}
}
CL_Point MapTileClient::findPosSlope(const Corner& c) const {
switch (getSlope().getRaw()) {
case 0:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 1:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 2:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 3:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), -picHeightOn2());
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 4:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 5:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 6:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 7:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 8:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 9:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 10:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 11:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 12:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 13:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 14:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
//case 15: There is no 15th slope.
case 16:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, 3 * picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, picHeightOn2());
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 17:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), -picHeight());
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), 0);
}
case 18:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, picHeightOnNeg2());
case 1: return CL_Point(picWidthOn2(), picHeightOnNeg2());
case 2: return CL_Point(0, picHeightOnNeg2());
case 3: return CL_Point(picWidthOnNeg2(), picHeightOnNeg2());
}
case 19:
switch (c.getCornerNum()) {
case 0: return CL_Point(0, -picHeight());
case 1: return CL_Point(picWidthOn2(), 0);
case 2: return CL_Point(0, 0);
case 3: return CL_Point(picWidthOnNeg2(), -picHeight());
}
default:
// This should never happen.
assert(0 && "Bad slope state in switch.");
return CL_Point(0, 0);
}
}
MapTilePos MapTileClient::findPosSlope(const CL_Point& p) const {
// Must be careful to return an invalid pos when the position is outside.
const float xow = float(p.x) / picWidth();
const float yoh = float(p.y) / picHeight();
switch (getSlope().getRaw()) {
case 0:
return MapTilePos(xow + yoh + 0.5f, yoh - xow + 0.5f);
case 1:
if (p.y >= 0) {
return MapTilePos(xow + yoh + 0.5f, yoh - xow + 0.5f);
} else {
return MapTilePos(xow + yoh / 2.0f + 0.5f, yoh / 2.0f - xow + 0.5f);
}
case 2:
if (p.x <= 0) {
return MapTilePos(xow + yoh + 0.5f, yoh - xow + 0.5f);
} else {
return MapTilePos(xow * 2.0f + yoh + 0.5f, yoh + 0.5f);
}
case 3: {
const float twoThirds = 2.0f / 3.0f;
return MapTilePos((xow * 2.0f + yoh + 1.0f) * twoThirds,
(yoh - xow + 1.0f) * twoThirds);
}
case 4:
if (p.y <= 0) {
return MapTilePos(xow + yoh + 0.5f, yoh - xow + 0.5f);
} else {
return MapTilePos(-1.0f, -1.0f);
}
case 5:
if (p.y <= 0) {
return MapTilePos(xow + yoh / 2.0f + 0.5f, yoh / 2.0f - xow + 0.5f);
} else {
return MapTilePos(-1.0f, -1.0f);
}
case 6:
return MapTilePos(xow * 2.0f + yoh * 2.0f + 1.0f, yoh * 2.0f + 1.0f);
case 7:
if (p.x >= 0) {
return MapTilePos(xow + yoh + 1.0f, yoh - xow + 1.0f);
} else {
return MapTilePos(xow * 2.0f + yoh + 1.0f, yoh + 1.0f);
}
case 8:
if (p.x >= 0) {
return MapTilePos(xow + yoh + 0.5f, yoh - xow + 0.5f);
} else {
return MapTilePos(yoh + 0.5f, yoh - xow * 2.0f + 0.5f);
}
case 9:
return MapTilePos((2.0f * xow + 2.0f * yoh + 2.0f) / 3.0f,
(2.0f * yoh - 4.0f * xow + 2.0f) / 3.0f);
case 10:
if (p.x >= 0) {
return MapTilePos(2.0f * xow + yoh + 0.5f, yoh + 0.5f);
} else {
return MapTilePos(yoh + 0.5f, yoh - 2.0f * xow + 0.5f);
}
case 11:
if (yoh <= -0.5f) {
return MapTilePos(xow + yoh + 1.0f, 1.0f - xow + yoh);
} else {
return MapTilePos(xow + yoh / 2.0f + 0.75f,
yoh / 2.0f - xow + 0.75f);
}
case 12:
return MapTilePos(2.0f * yoh + 1.0f, 2.0f * yoh - 2.0f * xow + 1.0f);
case 13:
if (p.x <= 0) {
return MapTilePos(yoh + xow + 1.0f, yoh - xow + 1.0f);
} else {
return MapTilePos(yoh + 1.0f, yoh - 2.0f * xow + 1.0f);
}
case 14:
if (yoh >= -0.5f) {
return MapTilePos(yoh + xow + 1.0f, yoh - xow + 1.0f);
} else {
return MapTilePos(-1.0f, -1.0f);
}
//case 15: There is no 15th slope... so don't make one.
case 16:
return MapTilePos(xow + yoh / 2.0f + 0.75f, yoh / 2.0f - xow + 0.75f);
case 17:
return MapTilePos(xow * 2.0f + yoh + 1.0f, yoh + 1.0f);
case 18:
// This slope produces a line of possible positions,
// so just default to [-1, -1], ie invalid. (You can't even SELECT
// a slope like this!)
return MapTilePos(-1.0f, -1.0f);
case 19:
return MapTilePos(yoh + 1.0f, yoh - xow * 2.0f + 1.0f);
default:
// This should never happen.
assert(0 && "Bad slope state in switch.");
break;
}
}
void MapTileClient::draw() const {
CL_Point p = getOffset();
sprites[getSpriteNum()]->draw(p.x, p.y);
}
int MapTileClient::picWidth() {
return PICWIDTH;
}
int MapTileClient::picHeight() {
return PICHEIGHT;
}
int MapTileClient::picWidthOn2() {
static int ret = picWidth() / 2;
return ret;
}
int MapTileClient::picHeightOn2() {
static int ret = picHeight() / 2;
return ret;
}
int MapTileClient::picWidthOnNeg2() {
static int ret = -picWidthOn2();
return ret;
}
int MapTileClient::picHeightOnNeg2() {
static int ret = -picHeightOn2();
return ret;
}
std::string MapTileClient::getSpriteName(Rules* r, int n, bool s) {
std::string ret;
switch (n) {
case 0: ret = "00"; break;
case 1: ret = "01"; break;
case 2: ret = "02"; break;
case 3: ret = "03"; break;
case 4: ret = "04"; break;
case 5: ret = "05"; break;
case 6: ret = "06"; break;
case 7: ret = "07"; break;
case 8: ret = "08"; break;
case 9: ret = "09"; break;
case 10: ret = "10"; break;
case 11: ret = "11"; break;
case 12: ret = "12"; break;
case 13: ret = "13"; break;
case 14: ret = "14"; break;
case 16: ret = "16"; break;
case 17: ret = "17"; break;
case 18: ret = "18"; break;
case 19: ret = "19"; break;
default:
// This should never happen.
assert(0 && "Bad slope state in switch.");
break;
}
if (s) return "tiles/" + r->theater + "/sea/" + ret;
else return "tiles/" + r->theater + "/land/" + ret;
}
int MapTileClient::getSpriteNum() const {
if (isAtSeaLevel()) {
return getSlope().getRaw() + 20;
} else {
return getSlope().getRaw();
}
}
void MapTileClient::loadSprites(Rules* r) {
sprites = new CL_Sprite*[40];
for (int i = 0; i < 20; ++i) {
if (i != 15) {
sprites[i] = new CL_Sprite(getSpriteName(r, i, false),
app.getResources());
}
}
for (int i = 0; i < 20; ++i) {
if (i != 15) {
sprites[i + 20] = new CL_Sprite(getSpriteName(r, i, true),
app.getResources());
}
}
}
void MapTileClient::freeSprites() {
for (int i = 0; i < 40; ++i) {
if (i != 15 && i != 35) {
delete sprites[i];
}
}
delete [] sprites;
}
See more files for this project here