186 lines
5.1 KiB
C++
186 lines
5.1 KiB
C++
/* 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
|
|
* 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 "common/util.h"
|
|
#include "ags/plugins/ags_waves/ags_waves.h"
|
|
|
|
namespace AGS3 {
|
|
namespace Plugins {
|
|
namespace AGSWaves {
|
|
|
|
|
|
void AGSWaves::ReturnNewHeight(ScriptMethodParams ¶ms) {
|
|
params._result = _newHeight;
|
|
}
|
|
|
|
void AGSWaves::ReturnNewWidth(ScriptMethodParams ¶ms) {
|
|
params._result = _newWidth;
|
|
}
|
|
|
|
void AGSWaves::Warper(ScriptMethodParams ¶ms) {
|
|
PARAMS5(int, swarp, int, sadjust, int, x1, int, y1, int, x2);
|
|
|
|
ix = 0.0;
|
|
iy = 0.0;
|
|
ua = 0.0;
|
|
// some precautions against non-positive values for width and height
|
|
|
|
float ax = float(x1), ay = float(y1);
|
|
float bx = float(x2), by = float(_y2);
|
|
float cx = float(_x3), cy = float(_y3);
|
|
float dx = float(_x4), dy = float(_y4);
|
|
|
|
int w = int(max4(ax, bx, cx, dx)) + 1;
|
|
int h = int(max4(ay, by, cy, dy)) + 1;
|
|
|
|
BITMAP *refsrc = _engine->GetSpriteGraphic(swarp);
|
|
int32 refsrc_width = 640;
|
|
int32 refsrc_height = 360;
|
|
int32 refsrc_depth = 32;
|
|
_engine->GetBitmapDimensions(refsrc, &refsrc_width, &refsrc_height, &refsrc_depth);
|
|
unsigned int **refsprite_pixels = (unsigned int **)_engine->GetRawBitmapSurface(refsrc);
|
|
_engine->ReleaseBitmapSurface(refsrc);
|
|
|
|
|
|
// create temporary sprite holding the warped version
|
|
BITMAP *resizeb = _engine->GetSpriteGraphic(sadjust);
|
|
int32 src_width = 640;
|
|
int32 src_height = 360;
|
|
int32 src_depth = 32;
|
|
_engine->GetBitmapDimensions(resizeb, &src_width, &src_height, &src_depth);
|
|
unsigned int **sprite_pixels = (unsigned int **)_engine->GetRawBitmapSurface(resizeb);
|
|
|
|
|
|
int ow = refsrc_width, oh = refsrc_height;
|
|
|
|
int x, y; // pixel coords
|
|
float fx, fy; // original sprite's in between pixel coords
|
|
|
|
int il;
|
|
|
|
// calculate intersections of opposing sides
|
|
float orx_x, orx_y, ory_x, ory_y;
|
|
bool xp = false, yp = false; // parallel sides?
|
|
|
|
// AC and BD to get intersection of all "vertical lines"
|
|
|
|
il = IntersectLines(ax, ay, cx, cy, bx, by, dx, dy);
|
|
if (il == 0) {
|
|
// parallel sides, store directional vector
|
|
orx_x = cx - ax;
|
|
orx_y = cy - ay;
|
|
xp = true;
|
|
} else {
|
|
// store intersection of sides
|
|
orx_x = ix;
|
|
orx_y = iy;
|
|
}
|
|
// AB and CD to get intersection of all "horizontal lines"
|
|
il = IntersectLines(ax, ay, bx, by, cx, cy, dx, dy);
|
|
if (il == 0) {
|
|
// parallel sides, store directional vector
|
|
ory_x = bx - ax;
|
|
ory_y = by - ay;
|
|
yp = true;
|
|
} else {
|
|
// store intersection of sides
|
|
ory_x = ix;
|
|
ory_y = iy;
|
|
}
|
|
|
|
int xm = int(min4(ax, bx, cx, dx)); // x loop starts here
|
|
|
|
y = int(min4(ay, by, cy, dy));
|
|
while (y < h) {
|
|
x = xm;
|
|
while (x < w) {
|
|
|
|
// calculate original pixel
|
|
|
|
// x:
|
|
if (xp) il = IntersectLines(ax, ay, bx, by, float(x), float(y), float(x) + orx_x, float(y) + orx_y);
|
|
else il = IntersectLines(ax, ay, bx, by, float(x), float(y), orx_x, orx_y);
|
|
fx = float(ow - 1) * ua;
|
|
|
|
float ux = ua;
|
|
|
|
// y:
|
|
if (yp) il = IntersectLines(ax, ay, cx, cy, float(x), float(y), float(x) + ory_x, float(y) + ory_y);
|
|
else il = IntersectLines(ax, ay, cx, cy, float(x), float(y), ory_x, ory_y);
|
|
fy = float(oh - 1) * ua;
|
|
|
|
// only draw if within original sprite
|
|
if (ux >= 0.0 && ux <= 1.0 && ua >= 0.0 && ua <= 1.0) {
|
|
int refY = (int)CLIP(fy, (float)0.0, float(refsrc_height - 1));
|
|
int refX = (int)CLIP(fx, (float)0.0, float(refsrc_width - 1));
|
|
|
|
int setcolor = refsprite_pixels[refY][refX];
|
|
|
|
int setY = (int)CLIP((float)y, (float)0.0, (float)(src_height - 1));
|
|
int setX = (int)CLIP((float)x, (float)0.0, (float)(src_width - 1));
|
|
|
|
sprite_pixels[setY][setX] = setcolor;
|
|
}
|
|
|
|
x++;
|
|
}
|
|
|
|
y++;
|
|
}
|
|
|
|
_newWidth = w;
|
|
_newHeight = h;
|
|
_engine->ReleaseBitmapSurface(resizeb);
|
|
}
|
|
|
|
void AGSWaves::SetWarper(ScriptMethodParams ¶ms) {
|
|
//PARAMS5(int, y2x, int, x3x, int, y3x, int, x4x, int, y4x);
|
|
}
|
|
|
|
|
|
int AGSWaves::IntersectLines(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
|
|
// check a
|
|
if (x1 == x2 && y1 == y2)
|
|
return -1;
|
|
// check b
|
|
if (x3 == x4 && y3 == y4)
|
|
return -1;
|
|
float den = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
|
float num12 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
|
|
float num34 = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
|
|
|
|
if (den == 0.0) { // no intersection
|
|
if (num12 == 0.0 && num34 == 0.0)
|
|
return 2;
|
|
return 0;
|
|
}
|
|
|
|
ua = num12 / den;
|
|
ix = x1 + ua * (x2 - x1);
|
|
iy = y1 + ua * (y2 - y1);
|
|
|
|
return 1;
|
|
}
|
|
|
|
} // namespace AGSWaves
|
|
} // namespace Plugins
|
|
} // namespace AGS3
|