Skip to content

Commit

Permalink
PEGASUS: Add the Shuttle HUD
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Hoops committed Oct 27, 2011
1 parent 015d81b commit e29d00e
Show file tree
Hide file tree
Showing 3 changed files with 308 additions and 0 deletions.
1 change: 1 addition & 0 deletions engines/pegasus/module.mk
Expand Up @@ -65,6 +65,7 @@ MODULE_OBJS = \
neighborhood/mars/reactor.o \
neighborhood/mars/robotship.o \
neighborhood/mars/shuttleenergymeter.o \
neighborhood/mars/shuttlehud.o \
neighborhood/mars/shuttleweapon.o \
neighborhood/mars/spacechase3d.o \
neighborhood/mars/spacejunk.o \
Expand Down
246 changes: 246 additions & 0 deletions engines/pegasus/neighborhood/mars/shuttlehud.cpp
@@ -0,0 +1,246 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#include "pegasus/pegasus.h"
#include "pegasus/neighborhood/mars/mars.h"
#include "pegasus/neighborhood/mars/robotship.h"
#include "pegasus/neighborhood/mars/shuttlehud.h"

namespace Pegasus {

const tCoordType kHUDTargetGridLeft = kShuttleWindowLeft + 16;
const tCoordType kHUDTargetGridTop = kShuttleWindowTop + 8;
const tCoordType kHUDTargetGridWidth = 328;
const tCoordType kHUDTargetGridHeight = 206;

const tCoordType kHUDRS232Left = kHUDTargetGridLeft + 264;
const tCoordType kHUDRS232Top = kHUDTargetGridTop + 2;

const tCoordType kHUDLockLeft = kShuttleWindowLeft + 101;
const tCoordType kHUDLockTop = kShuttleWindowTop + 49;
const tCoordType kHUDLockWidth = 145;
const tCoordType kHUDLockHeight = 124;

const tCoordType kTractorLockWidth = 50;
const tCoordType kTractorLockHeight = 30;

const tCoordType kTractorLockLeft = kShuttleWindowMidH - kTractorLockWidth / 2;
const tCoordType kTractorLockTop = kShuttleWindowMidV - kTractorLockHeight / 2;
const tCoordType kTractorLockRight = kTractorLockLeft + kTractorLockWidth;
const tCoordType kTractorLockBottom = kTractorLockTop + kTractorLockHeight;

static const uint16 s_RS232Data[] = {
0xF0E1, 0xCE70,
0xF9E1, 0xEF78,
0x4900, 0x2108,
0x79C0, 0xE738,
0x70E1, 0xC770,
0x5821, 0x0140,
0x4DE1, 0xEF78,
0x45C1, 0xEE78
};

static const uint16 s_lockData[] = {
0xE007, 0xFE1F, 0xF8E0, 0x7000,
0xE00F, 0xFF3F, 0xFCE0, 0xE000,
0xE00E, 0x0738, 0x1CE1, 0xC000,
0xE00E, 0x0738, 0x00FF, 0x8000,
0xE00E, 0x0738, 0x00FF, 0x0000,
0xE00E, 0x0738, 0x00E3, 0x8000,
0xE00E, 0x0738, 0x1CE1, 0xC000,
0xFFCF, 0xFF3F, 0xFCE0, 0xE000,
0xFFC7, 0xFE1F, 0xF8E0, 0x7000
};

#define drawHUDLockLine(x1, y1, x2, y2, penX, penY, color) \
screen->drawThickLine((x1) + kHUDLockLeft, (y1) + kHUDLockTop, \
(x2) + kHUDLockLeft, (y2) + kHUDLockTop, penX, penY, color)

#define drawHUDLockArrows(offset, color) \
drawHUDLockLine(63, 0 + (offset), 68, 5 + (offset), 1, 3, color); \
drawHUDLockLine(71, 8 + (offset), 77, 14 + (offset), 1, 3, color); \
drawHUDLockLine(78, 14 + (offset), 84, 8 + (offset), 1, 3, color); \
drawHUDLockLine(87, 5 + (offset), 92, 0 + (offset), 1, 3, color); \
drawHUDLockLine(63, 121 - (offset), 68, 116 - (offset), 1, 3, color); \
drawHUDLockLine(71, 113 - (offset), 77, 107 - (offset), 1, 3, color); \
drawHUDLockLine(78, 107 - (offset), 84, 113 - (offset), 1, 3, color); \
drawHUDLockLine(87, 116 - (offset), 92, 121 - (offset), 1, 3, color); \
\
drawHUDLockLine(13 + (offset), 47, 18 + (offset), 52, 3, 1, color); \
drawHUDLockLine(21 + (offset), 55, 27 + (offset), 61, 3, 1, color); \
drawHUDLockLine(27 + (offset), 62, 21 + (offset), 68, 3, 1, color); \
drawHUDLockLine(18 + (offset), 71, 13 + (offset), 76, 3, 1, color); \
drawHUDLockLine(142 - (offset), 47, 137 - (offset), 52, 3, 1, color); \
drawHUDLockLine(134 - (offset), 55, 128 - (offset), 61, 3, 1, color); \
drawHUDLockLine(128 - (offset), 62, 134 - (offset), 68, 3, 1, color); \
drawHUDLockLine(137 - (offset), 71, 142 - (offset), 76, 3, 1, color)

ShuttleHUD::ShuttleHUD() : DisplayElement(kNoDisplayElement) {
_lightGreen = g_system->getScreenFormat().RGBToColor(0, 204, 0);
_gridDarkGreen = g_system->getScreenFormat().RGBToColor(0, 85, 0);
_lockDarkGreen1 = g_system->getScreenFormat().RGBToColor(0, 68, 0);
_lockDarkGreen2 = g_system->getScreenFormat().RGBToColor(0, 65, 0);

_targetLocked = false;
setBounds(kShuttleWindowLeft, kShuttleWindowTop, kShuttleWindowLeft + kShuttleWindowWidth,
kShuttleWindowTop + kShuttleWindowHeight);
setDisplayOrder(kShuttleHUDOrder);
}

void ShuttleHUD::initShuttleHUD() {
startDisplaying();
startIdling();
}

void ShuttleHUD::cleanUpShuttleHUD() {
stopIdling();
stopDisplaying();
}

void ShuttleHUD::showTargetGrid() {
show();
}

void ShuttleHUD::hideTargetGrid() {
hide();
unlockOnTarget();
}

void ShuttleHUD::useIdleTime() {
if (isVisible()) {
Common::Rect r;
g_robotShip->getShuttleBounds(r);
if (r.left < kTractorLockRight && r.right > kTractorLockLeft && r.top < kTractorLockBottom && r.bottom > kTractorLockTop)
lockOnTarget();
else
unlockOnTarget();
}
}

void ShuttleHUD::lockOnTarget() {
if (!_targetLocked) {
_targetLocked = true;
triggerRedraw();
}
}

void ShuttleHUD::unlockOnTarget() {
if (_targetLocked) {
_targetLocked = false;
triggerRedraw();
}
}

void ShuttleHUD::draw(const Common::Rect &) {
Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getWorkArea();

for (int y = 0; y < 35; y++) {
Common::Rect r;

if (y & 1) {
if (y == 17) {
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 12, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);

r = Common::Rect(0, 0, 6, 2);
r.moveTo(kHUDTargetGridLeft + 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);

r = Common::Rect(0, 0, 23, 2);
r.moveTo(kHUDTargetGridLeft + 12, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 35, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _lightGreen);
} else if (y == 1 || y == 15 || y == 19 || y == 33) {
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 6, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);

r = Common::Rect(0, 0, 15, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 23, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
} else {
r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 6, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);

r = Common::Rect(0, 0, 10, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 18, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
}
} else {
r = Common::Rect(0, 0, 2, 2);
r.moveTo(kHUDTargetGridLeft, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 2, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);

r = Common::Rect(0, 0, 4, 2);
r.moveTo(kHUDTargetGridLeft + 8, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
r.moveTo(kHUDTargetGridLeft + kHUDTargetGridWidth - 12, y * 6 + kHUDTargetGridTop);
screen->fillRect(r, _gridDarkGreen);
}
}

drawOneBitImageOr(screen, s_lockData, 4, Common::Rect(kHUDRS232Left, kHUDRS232Top,
kHUDRS232Left + 29, kHUDRS232Top + 8), _gridDarkGreen);

if (_targetLocked) {
drawHUDLockArrows(0, _lockDarkGreen2);
drawHUDLockArrows(12, _lockDarkGreen1);
drawHUDLockArrows(24, _lightGreen);
drawOneBitImageOr(screen, s_lockData, 8, Common::Rect(kHUDLockLeft, kHUDLockTop + 115,
kHUDLockLeft + 52, kHUDLockTop + 115 + 9), _lightGreen);
}
}

void ShuttleHUD::drawOneBitImageOr(Graphics::Surface *screen, const uint16 *data, int pitch, const Common::Rect &bounds, uint32 color) {
for (int y = 0; y < bounds.height(); y++) {
for (int x = 0; x < bounds.width(); x++) {
if ((data[y * pitch + x / 16] & (1 << (15 - (x % 16)))) != 0) {
if (screen->format.bytesPerPixel == 2)
WRITE_UINT16((byte *)screen->getBasePtr(x + bounds.left, y + bounds.top), color);
else
WRITE_UINT32((byte *)screen->getBasePtr(x + bounds.left, y + bounds.top), color);
}
}
}
}

} // End of namespace Pegasus
61 changes: 61 additions & 0 deletions engines/pegasus/neighborhood/mars/shuttlehud.h
@@ -0,0 +1,61 @@
/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#ifndef PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEHUD_H
#define PEGASUS_NEIGHBORHOOD_MARS_SHUTTLEHUD_H

#include "pegasus/elements.h"
#include "pegasus/timers.h"

namespace Pegasus {

class ShuttleHUD : public DisplayElement, public Idler {
public:
ShuttleHUD();
virtual ~ShuttleHUD();

void showTargetGrid();
void hideTargetGrid();

void initShuttleHUD();
void cleanUpShuttleHUD();

bool isTargetLocked() { return _targetLocked; }

void draw(const Common::Rect &);

protected:
void useIdleTime();
void lockOnTarget();
void unlockOnTarget();
void drawOneBitImageOr(Graphics::Surface *, const uint16 *, int, const Common::Rect &, uint32);

bool _targetLocked;
uint32 _lightGreen, _gridDarkGreen, _lockDarkGreen1, _lockDarkGreen2;
};

} // End of namespace Pegasus

#endif

0 comments on commit e29d00e

Please sign in to comment.