215 lines
4.6 KiB
C++
215 lines
4.6 KiB
C++
|
/*
|
||
|
** tilequad.cpp
|
||
|
**
|
||
|
** This file is part of mkxp.
|
||
|
**
|
||
|
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
|
||
|
**
|
||
|
** mkxp 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.
|
||
|
**
|
||
|
** mkxp 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 mkxp. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "tilequad.h"
|
||
|
|
||
|
#include "gl-util.h"
|
||
|
#include "quad.h"
|
||
|
|
||
|
namespace TileQuads
|
||
|
{
|
||
|
|
||
|
int oneDimCount(int tileDimension,
|
||
|
int destDimension)
|
||
|
{
|
||
|
if (tileDimension <= 0)
|
||
|
return 0;
|
||
|
|
||
|
int fullCount = destDimension / tileDimension;
|
||
|
int partSize = destDimension % tileDimension;
|
||
|
|
||
|
return fullCount + (partSize ? 1 : 0);
|
||
|
}
|
||
|
|
||
|
int twoDimCount(int tileW, int tileH,
|
||
|
int destW, int destH)
|
||
|
{
|
||
|
return oneDimCount(tileW, destW) *
|
||
|
oneDimCount(tileH, destH);
|
||
|
}
|
||
|
|
||
|
int buildH(const IntRect &sourceRect,
|
||
|
int width, int x, int y,
|
||
|
Vertex *verts)
|
||
|
{
|
||
|
if (width <= 0)
|
||
|
return 0;
|
||
|
|
||
|
int fullCount = width / sourceRect.w;
|
||
|
int partSize = width % sourceRect.w;
|
||
|
|
||
|
FloatRect _sourceRect(sourceRect);
|
||
|
FloatRect destRect(x, y, sourceRect.w, sourceRect.h);
|
||
|
|
||
|
/* Full size quads */
|
||
|
for (int x = 0; x < fullCount; ++x)
|
||
|
{
|
||
|
Vertex *vert = &verts[x*4];
|
||
|
|
||
|
Quad::setTexRect(vert, _sourceRect);
|
||
|
Quad::setPosRect(vert, destRect);
|
||
|
|
||
|
destRect.x += sourceRect.w;
|
||
|
}
|
||
|
|
||
|
if (partSize)
|
||
|
{
|
||
|
Vertex *vert = &verts[fullCount*4];
|
||
|
|
||
|
_sourceRect.w = partSize;
|
||
|
destRect.w = partSize;
|
||
|
|
||
|
Quad::setTexRect(vert, _sourceRect);
|
||
|
Quad::setPosRect(vert, destRect);
|
||
|
}
|
||
|
|
||
|
return fullCount + (partSize ? 1 : 0);
|
||
|
}
|
||
|
|
||
|
int buildV(const IntRect &sourceRect,
|
||
|
int height, int ox, int oy,
|
||
|
Vertex *verts)
|
||
|
{
|
||
|
if (height <= 0)
|
||
|
return 0;
|
||
|
|
||
|
int fullCount = height / sourceRect.h;
|
||
|
int partSize = height % sourceRect.h;
|
||
|
|
||
|
FloatRect _sourceRect(sourceRect);
|
||
|
FloatRect destRect(ox, oy, sourceRect.w, sourceRect.h);
|
||
|
|
||
|
/* Full size quads */
|
||
|
for (int y = 0; y < fullCount; ++y)
|
||
|
{
|
||
|
Vertex *vert = &verts[y*4];
|
||
|
|
||
|
Quad::setTexRect(vert, _sourceRect);
|
||
|
Quad::setPosRect(vert, destRect);
|
||
|
|
||
|
destRect.y += sourceRect.h;
|
||
|
}
|
||
|
|
||
|
if (partSize)
|
||
|
{
|
||
|
Vertex *vert = &verts[fullCount*4];
|
||
|
|
||
|
_sourceRect.h = partSize;
|
||
|
destRect.h = partSize;
|
||
|
|
||
|
Quad::setTexRect(vert, _sourceRect);
|
||
|
Quad::setPosRect(vert, destRect);
|
||
|
}
|
||
|
|
||
|
return fullCount + (partSize ? 1 : 0);
|
||
|
}
|
||
|
|
||
|
int build(const IntRect &sourceRect,
|
||
|
const IntRect &destRect,
|
||
|
Vertex *verts)
|
||
|
{
|
||
|
int ox = destRect.x;
|
||
|
int oy = destRect.y;
|
||
|
int width = destRect.w;
|
||
|
int height = destRect.h;
|
||
|
|
||
|
if (width <= 0 || height <= 0)
|
||
|
return 0;
|
||
|
|
||
|
int fullCount = height / sourceRect.h;
|
||
|
int partSize = height % sourceRect.h;
|
||
|
|
||
|
int rowTileCount = oneDimCount(sourceRect.w, width);
|
||
|
|
||
|
int qCount = 0;
|
||
|
|
||
|
int v = 0;
|
||
|
for (int i = 0; i < fullCount; ++i)
|
||
|
{
|
||
|
qCount += buildH(sourceRect, width, ox, oy, &verts[v]);
|
||
|
|
||
|
v += rowTileCount*4;
|
||
|
oy += sourceRect.h;
|
||
|
}
|
||
|
|
||
|
if (partSize)
|
||
|
{
|
||
|
IntRect partSourceRect = sourceRect;
|
||
|
partSourceRect.h = partSize;
|
||
|
|
||
|
qCount += buildH(partSourceRect, width, ox, oy, &verts[v]);
|
||
|
}
|
||
|
|
||
|
return qCount;
|
||
|
}
|
||
|
|
||
|
static void buildFrameInt(const IntRect &rect,
|
||
|
FloatRect *quadRects /* 9 big */)
|
||
|
{
|
||
|
int w = rect.w; int h = rect.h;
|
||
|
int x1 = rect.x; int x2 = x1 + w;
|
||
|
int y1 = rect.y; int y2 = y1 + h;
|
||
|
|
||
|
int i = 0;
|
||
|
/* Corners - tl, tr, br, bl */
|
||
|
quadRects[i++] = FloatRect(x1, y1, 2, 2);
|
||
|
quadRects[i++] = FloatRect(x2-2, y1, 2, 2);
|
||
|
quadRects[i++] = FloatRect(x2-2, y2-2, 2, 2);
|
||
|
quadRects[i++] = FloatRect(x1, y2-2, 2, 2);
|
||
|
|
||
|
/* Sides - l, r, t, b */
|
||
|
quadRects[i++] = FloatRect(x1, y1+2, 2, h-4);
|
||
|
quadRects[i++] = FloatRect(x2-2, y1+2, 2, h-4);
|
||
|
quadRects[i++] = FloatRect(x1+2, y1, w-4, 2);
|
||
|
quadRects[i++] = FloatRect(x1+2, y2-2, w-4, 2);
|
||
|
|
||
|
/* Center */
|
||
|
quadRects[i++] = FloatRect(x1+2, y1+2, w-4, h-4);
|
||
|
}
|
||
|
|
||
|
int buildFrameSource(const IntRect &rect,
|
||
|
Vertex *vert /* 36 big */)
|
||
|
{
|
||
|
FloatRect quadRects[9];
|
||
|
|
||
|
buildFrameInt(rect, quadRects);
|
||
|
|
||
|
for (int i = 0; i < 9; ++i)
|
||
|
Quad::setTexRect(&vert[i*4], quadRects[i]);
|
||
|
|
||
|
return 9;
|
||
|
}
|
||
|
|
||
|
int buildFrame(const IntRect &rect,
|
||
|
Vertex *vert /* 36 big */)
|
||
|
{
|
||
|
FloatRect quadRects[9];
|
||
|
|
||
|
buildFrameInt(rect, quadRects);
|
||
|
|
||
|
for (int i = 0; i < 9; ++i)
|
||
|
Quad::setPosRect(&vert[i*4], quadRects[i]);
|
||
|
|
||
|
return 9;
|
||
|
}
|
||
|
|
||
|
}
|