Files
scummvm-cursorfix/engines/pegasus/neighborhood/mars/tractorbeam.cpp
2026-02-02 04:50:13 +01:00

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