139 lines
4.0 KiB
C++
139 lines
4.0 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.
|
|
*
|
|
* Additional copyright for this file:
|
|
* Copyright (C) 1995-1997 Presto Studios, Inc.
|
|
*
|
|
* 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 "pegasus/pegasus.h"
|
|
#include "pegasus/neighborhood/mars/constants.h"
|
|
#include "pegasus/neighborhood/mars/tractorbeam.h"
|
|
|
|
namespace Pegasus {
|
|
|
|
TractorBeam::TractorBeam() : DisplayElement(kNoDisplayElement) {
|
|
setBounds(kShuttleTractorLeft, kShuttleTractorTop, kShuttleTractorLeft + kShuttleTractorWidth,
|
|
kShuttleTractorTop + kShuttleTractorHeight);
|
|
setDisplayOrder(kShuttleTractorBeamOrder);
|
|
|
|
}
|
|
|
|
static const int kHalfWidth = kShuttleTractorWidth >> 1;
|
|
static const int kHalfHeight = kShuttleTractorHeight >> 1;
|
|
|
|
static const int kW3Vert = kHalfHeight * kHalfHeight * kHalfHeight;
|
|
static const int kW3Div2Vert = kW3Vert >> 1;
|
|
|
|
static const int kW3Horiz = kHalfWidth * kHalfWidth * kHalfWidth;
|
|
static const int kW3Div2Horiz = kW3Horiz >> 1;
|
|
|
|
static const int kMaxLevel = 50;
|
|
|
|
static const int kAVert = -2 * kMaxLevel;
|
|
static const int kBVert = 3 * kMaxLevel * kHalfHeight;
|
|
|
|
#define READ_PIXEL(ptr) \
|
|
if (screen->format.bytesPerPixel == 2) \
|
|
color = READ_UINT16(ptr); \
|
|
else \
|
|
color = READ_UINT32(ptr); \
|
|
screen->format.colorToRGB(color, r, g, b)
|
|
|
|
#define WRITE_PIXEL(ptr) \
|
|
color = screen->format.RGBToColor(r, g, b); \
|
|
if (screen->format.bytesPerPixel == 2) \
|
|
WRITE_UINT16(ptr, color); \
|
|
else \
|
|
WRITE_UINT32(ptr, color)
|
|
|
|
#define DO_BLEND(ptr) \
|
|
READ_PIXEL(ptr); \
|
|
g += (((0xff - g) * blendHoriz) >> 8); \
|
|
b += (((0xff - b) * blendHoriz) >> 8); \
|
|
WRITE_PIXEL(ptr)
|
|
|
|
void TractorBeam::draw(const Common::Rect &) {
|
|
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
|
|
|
|
// Set up vertical DDA.
|
|
int blendVert = 0;
|
|
int dVert = 0;
|
|
int d1Vert = kAVert + kBVert;
|
|
int d2Vert = 6 * kAVert + 2 * kBVert;
|
|
int d3Vert = 6 * kAVert;
|
|
|
|
byte *rowPtrTop = (byte *)screen->getBasePtr(_bounds.left, _bounds.top);
|
|
byte *rowPtrBottom = (byte *)screen->getBasePtr(_bounds.left, _bounds.top + ((kHalfHeight << 1) - 1));
|
|
|
|
for (int y = kHalfHeight; y > 0; y--) {
|
|
// Set up horizontal DDA
|
|
int A = -2 * blendVert;
|
|
int B = 3 * blendVert * kHalfWidth;
|
|
int blendHoriz = 0;
|
|
int dHoriz = 0;
|
|
int d1Horiz = A + B;
|
|
int d2Horiz = 6 * A + 2 * B;
|
|
int d3Horiz = 6 * A;
|
|
|
|
byte *pTopLeft = rowPtrTop;
|
|
byte *pTopRight = rowPtrTop + (kHalfWidth * 2 - 1) * screen->format.bytesPerPixel;
|
|
byte *pBottomLeft = rowPtrBottom;
|
|
byte *pBottomRight = rowPtrBottom + (kHalfWidth * 2 - 1) * screen->format.bytesPerPixel;
|
|
|
|
for (int x = kHalfWidth; x > 0; x--) {
|
|
byte r, g, b;
|
|
uint32 color;
|
|
|
|
DO_BLEND(pTopLeft);
|
|
DO_BLEND(pTopRight);
|
|
DO_BLEND(pBottomLeft);
|
|
DO_BLEND(pBottomRight);
|
|
|
|
pTopLeft += screen->format.bytesPerPixel;
|
|
pBottomLeft += screen->format.bytesPerPixel;
|
|
pTopRight -= screen->format.bytesPerPixel;
|
|
pBottomRight -= screen->format.bytesPerPixel;
|
|
|
|
while (dHoriz > kW3Div2Horiz) {
|
|
blendHoriz++;
|
|
dHoriz -= kW3Horiz;
|
|
}
|
|
|
|
dHoriz += d1Horiz;
|
|
d1Horiz += d2Horiz;
|
|
d2Horiz += d3Horiz;
|
|
}
|
|
|
|
rowPtrTop += screen->pitch;
|
|
rowPtrBottom -= screen->pitch;
|
|
|
|
while (dVert > kW3Div2Vert) {
|
|
blendVert++;
|
|
dVert -= kW3Vert;
|
|
}
|
|
|
|
dVert += d1Vert;
|
|
d1Vert += d2Vert;
|
|
d2Vert += d3Vert;
|
|
}
|
|
}
|
|
|
|
} // End of namespace Pegasus
|