/src/game/minicomputer.cpp
C++ | 1995 lines | 1696 code | 214 blank | 85 comment | 210 complexity | 7afedf25f82ee21a1d4f6210c40c5531 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0
Large files files are truncated, but you can click here to view the full file
- // Copyright (C) 1997, 1999-2001, 2008 Nathan Lamont
- // Copyright (C) 2008-2012 The Antares Authors
- //
- // This file is part of Antares, a tactical space combat game.
- //
- // Antares is free software: you can redistribute it and/or modify it
- // under the terms of the Lesser GNU General Public License as published
- // by the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // Antares 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
- // Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public
- // License along with Antares. If not, see http://www.gnu.org/licenses/
- #include "game/minicomputer.hpp"
- #include <algorithm>
- #include <sfz/sfz.hpp>
- #include "config/keys.hpp"
- #include "data/string-list.hpp"
- #include "drawing/color.hpp"
- #include "drawing/pix-table.hpp"
- #include "drawing/shapes.hpp"
- #include "drawing/sprite-handling.hpp"
- #include "drawing/text.hpp"
- #include "game/admiral.hpp"
- #include "game/globals.hpp"
- #include "game/instruments.hpp"
- #include "game/messages.hpp"
- #include "game/player-ship.hpp"
- #include "game/scenario-maker.hpp"
- #include "game/space-object.hpp"
- #include "game/starfield.hpp"
- #include "math/fixed.hpp"
- #include "sound/fx.hpp"
- #include "video/driver.hpp"
- using sfz::Bytes;
- using sfz::Rune;
- using sfz::String;
- using sfz::StringSlice;
- using sfz::bin;
- using sfz::scoped_array;
- using sfz::string_to_int;
- using std::max;
- namespace macroman = sfz::macroman;
- namespace antares {
- miniComputerDataType *gMiniScreenData = NULL;
- namespace {
- const int32_t kMiniScreenCharWidth = 25;
- const int32_t kMiniScreenLeft = 12;
- const int32_t kMiniScreenTop = 320;
- const int32_t kMiniScreenRight = 121;
- const int32_t kMiniScreenBottom = 440;
- const int32_t kMiniScreenWidth = kMiniScreenRight - kMiniScreenLeft;
- const int32_t kMiniScreenLeftBuffer = 3;
- const int32_t kMiniScreenCharHeight = 10; // height of the screen in characters
- const int32_t kMiniScreenTrueLineNum = kMiniScreenCharHeight + 2;
- const int32_t kButBoxLeft = 16;
- const int32_t kButBoxTop = 450;
- const int32_t kButBoxRight = 114;
- const int32_t kButBoxBottom = 475;
- const int32_t kMiniScreenNoLineSelected = -1;
- const int16_t kMiniScreenStringID = 3000;
- const int16_t kMiniDataStringID = 3001;
- const uint8_t kMiniScreenColor = GREEN;
- const uint8_t kMiniButColor = AQUA;
- const Rune kMiniScreenSpecChar = '\\';
- const Rune kEndLineChar = 'x';
- const Rune kUnderlineEndLineChar = 'u';
- const Rune kIntoButtonChar = 'I';
- const Rune kOutOfButtonChar = 'O';
- const Rune kSelectableLineChar = 'S';
- const int32_t kNoLineButton = -1;
- const int32_t kInLineButton = kCompAcceptKeyNum;
- const int32_t kOutLineButton = kCompCancelKeyNum;
- enum {
- kMainMiniScreen = 1,
- kBuildMiniScreen = 2,
- kSpecialMiniScreen = 3,
- kMessageMiniScreen = 4,
- kStatusMiniScreen = 5,
- };
- enum {
- kMainMiniBuild = 1,
- kMainMiniSpecial = 2,
- kMainMiniMessage = 3,
- kMainMiniStatus = 4,
- };
- const int32_t kBuildScreenFirstTypeLine = 2;
- const int32_t kBuildScreenWhereNameLine = 1;
- enum {
- kSpecialMiniTransfer = 1,
- kSpecialMiniHold = 2,
- kSpecialMiniGoToMe = 3,
- kSpecialMiniFire1 = 4,
- kSpecialMiniFire2 = 5,
- kSpecialMiniFireSpecial = 6,
- };
- enum {
- kMessageMiniNext = 1,
- kMessageMiniPrevious = 2,
- kMessageMiniLast = 3,
- };
- const int32_t kStatusMiniScreenFirstLine = 1;
- enum {
- kNoStatusData = -1, // no status for this line
- kPlainTextStatus = 0,
- kTrueFalseCondition = 1, // 0 = F, 1 = T, use condition not score
- kIntegerValue = 2, // interpret score as int
- kSmallFixedValue = 3, // interpret score as fixed
- kIntegerMinusValue = 4, // value - designated score
- kSmallFixedMinusValue = 5, // small fixed - designated score
- kMaxStatusTypeValue = kSmallFixedMinusValue,
- };
- const int32_t kMiniComputerPollTime = 60;
- const int32_t kMiniObjectDataNum = 2;
- const int32_t kMiniSelectObjectNum = 0;
- const int32_t kMiniSelectTop = 180;
- const int32_t kMiniIconHeight = 22;
- const int32_t kMiniIconWidth = 24;
- const int32_t kMiniIconLeft = (kMiniScreenLeft + 2);
- const int32_t kMiniHealthLeft = (kMiniIconLeft + kMiniIconWidth + 2);
- const int32_t kMiniBarWidth = 11;
- const int32_t kMiniBarHeight = 18;
- const int32_t kMiniEnergyLeft = (kMiniHealthLeft + kMiniBarWidth + 2);
- const int32_t kMiniRightColumnLeft = 57;
- const int32_t kMiniWeapon1LineNum = 2;
- const int32_t kMiniWeapon2LineNum = 3;
- const int32_t kMiniWeapon3LineNum = 1;
- const int32_t kMiniNameLineNum = 1;
- const int32_t kMiniDestLineNum = 4;
- const int32_t kMiniTargetObjectNum = 1;
- const int32_t kMiniTargetTop = 252;
- const int32_t kMiniAmmoTop = 161;
- const int32_t kMiniAmmoBottom = 170;
- const int32_t kMiniAmmoSingleWidth = 21;
- const int32_t kMiniAmmoLeftOne = 27;
- const int32_t kMiniAmmoLeftTwo = 64;
- const int32_t kMiniAmmoLeftSpecial = 100;
- const int32_t kMiniAmmoTextHBuffer = 2;
- inline void mPlayBeep3() {
- PlayVolumeSound(kComputerBeep3, kMediumVolume, kMediumPersistence, kLowPrioritySound);
- }
- inline void mPlayBeepBad() {
- PlayVolumeSound(kWarningTone, kMediumVolume, kMediumPersistence, kLowPrioritySound);
- }
- const int32_t kMaxShipBuffer = 40;
- void pad_to(String& s, size_t width) {
- if (s.size() < width) {
- String result;
- result.append((width - s.size()) / 2, ' ');
- result.append(s);
- result.append((1 + width - s.size()) / 2, ' ');
- swap(result, s);
- }
- }
- const int32_t MiniIconMacLineTop() {
- return computer_font->height * 2;
- }
- Rect mini_screen_line_bounds(long mtop, long mlinenum, long mleft, long mright) {
- Rect mbounds;
- mbounds.left = kMiniScreenLeft + mleft;
- mbounds.top = mtop + mlinenum * computer_font->height;
- mbounds.right = kMiniScreenLeft + mright;
- mbounds.bottom = mbounds.top + computer_font->height;
- return mbounds;
- }
- inline long mGetLineNumFromV(long mV) {
- return (((mV) - (kMiniScreenTop + globals()->gInstrumentTop)) / computer_font->height);
- }
- // for copying the fields of a space object relevant to the miniscreens:
- inline void mCopyMiniSpaceObject(
- spaceObjectType& mdestobject, const spaceObjectType& msourceobject) {
- (mdestobject).id = (msourceobject).id;
- (mdestobject).beamType = (msourceobject).beamType;
- (mdestobject).pulseType = (msourceobject).pulseType;
- (mdestobject).specialType = (msourceobject).specialType;
- (mdestobject).destinationLocation.h = (msourceobject).destinationLocation.h;
- (mdestobject).destinationLocation.v = (msourceobject).destinationLocation.v;
- (mdestobject).destinationObject = (msourceobject).destinationObject;
- (mdestobject).destObjectPtr = (msourceobject).destObjectPtr;
- (mdestobject).health = (msourceobject).health;
- (mdestobject).energy = (msourceobject).energy;
- (mdestobject).whichBaseObject = (msourceobject).whichBaseObject;
- (mdestobject).pixResID = (msourceobject).pixResID;
- (mdestobject).attributes = (msourceobject).attributes;
- (mdestobject).location = (msourceobject).location;
- (mdestobject).owner = (msourceobject).owner;
- (mdestobject).nextFarObject = (msourceobject).nextFarObject;
- (mdestobject).distanceGrid = (msourceobject).distanceGrid;
- (mdestobject).nextNearObject = (msourceobject).nextNearObject;
- (mdestobject).collisionGrid = (msourceobject).collisionGrid;
- (mdestobject).remoteFriendStrength = (msourceobject).remoteFriendStrength;
- (mdestobject).remoteFoeStrength = (msourceobject).remoteFoeStrength;
- (mdestobject).escortStrength = (msourceobject).escortStrength;
- (mdestobject).baseType = (msourceobject).baseType;
- }
- inline void mCopyBlankLineString(miniScreenLineType* mline, StringSlice mstring) {
- mline->string.assign(mstring);
- if (mline->string.size() > kMiniScreenCharWidth) {
- mline->string.resize(kMiniScreenCharWidth);
- }
- }
- inline spaceObjectType* mGetMiniObjectPtr(long mwhich) {
- return globals()->gMiniScreenData.objectData.get() + mwhich;
- }
- } // namespace
- void MiniComputerSetStatusStrings( void);
- long MiniComputerGetStatusValue( long);
- void MiniComputerMakeStatusString(int32_t which_line, String& string);
- void MiniScreenInit() {
- globals()->gMiniScreenData.selectLine = kMiniScreenNoLineSelected;
- globals()->gMiniScreenData.currentScreen = kMainMiniScreen;
- globals()->gMiniScreenData.pollTime = 0;
- globals()->gMiniScreenData.buildTimeBarValue = -1;
- globals()->gMiniScreenData.clickLine = kMiniScreenNoLineSelected;
- globals()->gMiniScreenData.lineData.reset(new miniScreenLineType[kMiniScreenTrueLineNum]);
- globals()->gMiniScreenData.objectData.reset(new spaceObjectType[kMiniObjectDataNum]);
- ClearMiniScreenLines();
- ClearMiniObjectData();
- }
- void MiniScreenCleanup() {
- globals()->gMiniScreenData.lineData.reset();
- globals()->gMiniScreenData.objectData.reset();
- }
- #pragma mark -
- void SetMiniScreenStatusStrList(short strID) {
- DisposeMiniScreenStatusStrList();
- if (strID > 0) {
- globals()->gMissionStatusStrList.reset(new StringList(strID));
- }
- }
- void DisposeMiniScreenStatusStrList( void) {
- globals()->gMissionStatusStrList.reset();
- }
- void ClearMiniScreenLines() {
- miniScreenLineType* c = globals()->gMiniScreenData.lineData.get();
- for (int32_t b = 0; b < kMiniScreenTrueLineNum; b++) {
- c->string.clear();
- c->hiliteLeft = c->hiliteRight = 0;
- c->whichButton = kNoLineButton;
- c->selectable = cannotSelect;
- c->underline = false;
- c->lineKind = plainLineKind;
- c->sourceData = NULL;
- c++;
- }
- }
- void ClearMiniObjectData( void)
- {
- spaceObjectType *o;
- o = mGetMiniObjectPtr( kMiniSelectObjectNum);
- o->id = -1;
- o->beamType = -1;
- o->pulseType = -1;
- o->specialType = -1;
- o->destinationLocation.h = o->destinationLocation.v = -1;
- o->destinationObject = -1;
- o->destObjectPtr = NULL;
- o->health = 0;
- o->energy = 0;
- o->whichBaseObject = -1;
- o->pixResID = -1;
- o->attributes = 0;
- o->baseType = NULL;
- o = mGetMiniObjectPtr( kMiniTargetObjectNum);
- o->id = -1;
- o->beamType = -1;
- o->pulseType = -1;
- o->specialType = -1;
- o->destinationLocation.h = o->destinationLocation.v = -1;
- o->destinationObject = -1;
- o->destObjectPtr = NULL;
- o->health = 0;
- o->energy = 0;
- o->whichBaseObject = -1;
- o->pixResID = -1;
- o->attributes = 0;
- o->baseType = NULL;
- globals()->gMiniScreenData.buildTimeBarValue = -1;
- globals()->gMiniScreenData.pollTime = 0;
- }
- void draw_mini_screen() {
- Rect mRect;
- Rect lRect, cRect;
- miniScreenLineType *c;
- RgbColor color, lightcolor, darkcolor, textcolor;
- unsigned char lineColor = kMiniScreenColor;
- long count, lineCorrect = 0;
- lRect = Rect(kMiniScreenLeft, kMiniScreenTop + globals()->gInstrumentTop, kMiniScreenRight,
- kMiniScreenBottom + globals()->gInstrumentTop);
- color = GetRGBTranslateColorShade(kMiniScreenColor, DARKEST);
- cRect = lRect;
- VideoDriver::driver()->fill_rect(cRect, color);
- mRect.left = kMiniScreenLeft;
- mRect.top = kMiniScreenTop + globals()->gInstrumentTop;
- mRect.right = kMiniScreenRight;
- mRect.bottom = kMiniScreenBottom + globals()->gInstrumentTop;
- c = globals()->gMiniScreenData.lineData.get();
- for ( count = 0; count < kMiniScreenTrueLineNum; count++)
- {
- if ( count == kMiniScreenCharHeight)
- {
- lRect.left = mRect.left = kButBoxLeft;
- lRect.top = mRect.top = kButBoxTop + globals()->gInstrumentTop;
- lRect.right = mRect.right = kButBoxRight;
- lRect.bottom = mRect.bottom = kButBoxBottom + globals()->gInstrumentTop;
- color = GetRGBTranslateColorShade(kMiniButColor, DARKEST);
- cRect = lRect;
- VideoDriver::driver()->fill_rect(cRect, color);
- lineCorrect = -kMiniScreenCharHeight;
- lineColor = kMiniButColor;
- }
- if ( c->underline)
- {
- const RgbColor color = GetRGBTranslateColorShade(lineColor, MEDIUM);
- int32_t y = mRect.top + (count + lineCorrect) * computer_font->height
- + computer_font->ascent;
- VideoDriver::driver()->draw_line(
- Point(mRect.left, y), Point(mRect.right - 2, y), color);
- }
- if ( c->hiliteLeft < c->hiliteRight)
- {
- if ( c->selectable == selectDim)
- textcolor = GetRGBTranslateColorShade(lineColor, VERY_DARK);
- else
- textcolor = GetRGBTranslateColorShade(lineColor, VERY_LIGHT);
- switch( c->lineKind)
- {
- case plainLineKind:
- if ( c->hiliteRight > c->hiliteLeft)
- {
- cRect.left = c->hiliteLeft;
- cRect.top = mRect.top + (( count + lineCorrect) * ( computer_font->height /* * 2 */));
- cRect.right = c->hiliteRight;
- cRect.bottom = cRect.top + computer_font->height /* * 2 */;
- // color = GetTranslateColorShade( lineColor, DARK);
- color = GetRGBTranslateColorShade(lineColor, DARK);
- lightcolor = GetRGBTranslateColorShade(lineColor, MEDIUM);
- darkcolor = GetRGBTranslateColorShade(lineColor, DARKER);
- draw_shaded_rect(cRect, color, lightcolor, darkcolor);
- }
- break;
- case buttonOffLineKind:
- cRect.left = c->hiliteLeft - 2;
- cRect.top = lRect.top + (( count + lineCorrect) * ( computer_font->height /* * 2 */));
- cRect.right = c->hiliteRight + 2;
- cRect.bottom = cRect.top + computer_font->height /* * 2 */;
- color = GetRGBTranslateColorShade(lineColor, MEDIUM);
- lightcolor = GetRGBTranslateColorShade(lineColor, LIGHT);
- darkcolor = GetRGBTranslateColorShade(lineColor, DARK);
- draw_shaded_rect(cRect, color, lightcolor, darkcolor);
- break;
- case buttonOnLineKind:
- cRect.left = c->hiliteLeft - 2;
- cRect.top = lRect.top + (( count + lineCorrect) * ( computer_font->height /* * 2 */));
- cRect.right = lRect.right; //c->hiliteRight + 2;
- cRect.bottom = cRect.top + computer_font->height /* * 2 */;
- color = GetRGBTranslateColorShade(lineColor, LIGHT);
- lightcolor = GetRGBTranslateColorShade(lineColor, VERY_LIGHT);
- darkcolor = GetRGBTranslateColorShade(lineColor, MEDIUM);
- draw_shaded_rect(cRect, color, lightcolor, darkcolor);
- textcolor = RgbColor::kBlack;
- break;
- }
- } else
- {
- if ( c->selectable == selectDim)
- textcolor = GetRGBTranslateColorShade(lineColor, MEDIUM);
- else
- textcolor = GetRGBTranslateColorShade(lineColor, VERY_LIGHT);
- }
- computer_font->draw_sprite(
- Point(
- mRect.left + kMiniScreenLeftBuffer,
- mRect.top + (count + lineCorrect) * computer_font->height + computer_font->ascent),
- c->string, textcolor);
- c++;
- }
- draw_mini_ship_data(*mGetMiniObjectPtr(kMiniSelectObjectNum), YELLOW, kMiniSelectTop, kMiniSelectObjectNum + 1);
- draw_mini_ship_data(*mGetMiniObjectPtr(kMiniTargetObjectNum), SKY_BLUE, kMiniTargetTop, kMiniTargetObjectNum + 1);
- }
- void MakeMiniScreenFromIndString(short whichString) {
- Rect mRect(kMiniScreenLeft, kMiniScreenTop, kMiniScreenRight, kMiniScreenBottom);
- mRect.offset(0, globals()->gInstrumentTop);
- ClearMiniScreenLines();
- globals()->gMiniScreenData.currentScreen = whichString;
- globals()->gMiniScreenData.selectLine = kMiniScreenNoLineSelected;
- StringList string_list(kMiniScreenStringID);
- StringSlice string = string_list.at(whichString - 1);
- miniScreenLineType* const line_begin = globals()->gMiniScreenData.lineData.get();
- miniScreenLineType* const line_switch = line_begin + kMiniScreenCharHeight;
- miniScreenLineType* const line_end = line_begin + kMiniScreenTrueLineNum;
- miniScreenLineType* line = line_begin;
- bool escape = false;
- SFZ_FOREACH(Rune r, string, {
- if (escape) {
- escape = false;
- switch (r) {
- case kUnderlineEndLineChar:
- line->underline = true;
- // fall through.
- case kEndLineChar:
- ++line;
- if (line == line_end) {
- return;
- } else if (line == line_switch) {
- mRect = Rect(kButBoxLeft, kButBoxTop, kButBoxRight, kButBoxBottom);
- mRect.offset(0, globals()->gInstrumentTop);
- }
- break;
- case kSelectableLineChar:
- line->selectable = selectable;
- if (globals()->gMiniScreenData.selectLine == kMiniScreenNoLineSelected) {
- globals()->gMiniScreenData.selectLine = line - line_begin;
- line->hiliteLeft = mRect.left;
- line->hiliteRight = mRect.right;
- }
- break;
- case kIntoButtonChar:
- {
- line->lineKind = buttonOffLineKind;
- line->whichButton = kInLineButton;
- line->hiliteLeft
- = mRect.left + kMiniScreenLeftBuffer
- + computer_font->logicalWidth * line->string.size();
- sfz::String key_name;
- GetKeyNumName(Preferences::preferences()->key(kCompAcceptKeyNum), &key_name);
- pad_to(key_name, kKeyNameLength);
- line->string.append(key_name);
- line->hiliteRight
- = mRect.left + kMiniScreenLeftBuffer
- + computer_font->logicalWidth * line->string.size() - 1;
- }
- break;
- case kOutOfButtonChar:
- {
- line->lineKind = buttonOffLineKind;
- line->whichButton = kOutLineButton;
- line->hiliteLeft
- = mRect.left + kMiniScreenLeftBuffer
- + computer_font->logicalWidth * line->string.size();
- sfz::String key_name;
- GetKeyNumName(
- Preferences::preferences()->key(kCompCancelKeyNum), &key_name);
- pad_to(key_name, kKeyNameLength);
- line->string.append(key_name);
- line->hiliteRight
- = mRect.left + kMiniScreenLeftBuffer
- + computer_font->logicalWidth * line->string.size() - 1;
- }
- break;
- case kMiniScreenSpecChar:
- line->string.append(1, kMiniScreenSpecChar);
- break;
- }
- } else if (r == kMiniScreenSpecChar) {
- escape = true;
- } else {
- line->string.append(1, r);
- }
- while (line->string.size() > kMiniScreenCharWidth) {
- String excess(line->string.slice(kMiniScreenCharWidth));
- line->string.resize(kMiniScreenCharWidth);
- ++line;
- if (line == line_end) {
- return;
- } else if (line == line_switch) {
- mRect = Rect(kButBoxLeft, kButBoxTop, kButBoxRight, kButBoxBottom);
- mRect.offset(0, globals()->gInstrumentTop);
- }
- line->string.assign(excess);
- }
- });
- }
- void MiniComputerHandleKeys( unsigned long theseKeys, unsigned long lastKeys)
- {
- miniScreenLineType *line;
- long count, scrap;
- Rect mRect;
- if (( theseKeys | lastKeys) & kCompAcceptKey)
- {
- // find out which line, if any, contains this button
- line = globals()->gMiniScreenData.lineData.get();
- count = 0;
- while (( line->whichButton !=kInLineButton) && ( count < kMiniScreenTrueLineNum))
- {
- count++;
- line++;
- }
- // hilite/unhilite this button
- if ( count < kMiniScreenTrueLineNum)
- {
- if (( theseKeys & kCompAcceptKey) && ( line->lineKind != buttonOnLineKind))
- {
- line->lineKind = buttonOnLineKind;
- mPlayBeep3();
- } else if ((!( theseKeys & kCompAcceptKey)) && ( line->lineKind != buttonOffLineKind))
- {
- line->lineKind = buttonOffLineKind;
- MiniComputerDoAccept();
- }
- }
- }
- if (( theseKeys | lastKeys) & kCompCancelKey)
- {
- // find out which line, if any, contains this button
- line = globals()->gMiniScreenData.lineData.get();
- count = 0;
- while (( line->whichButton !=kOutLineButton) && ( count < kMiniScreenTrueLineNum))
- {
- count++;
- line++;
- }
- if ( count < kMiniScreenCharHeight)
- {
- mRect = Rect(kMiniScreenLeft, kMiniScreenTop + globals()->gInstrumentTop, kMiniScreenRight,
- kMiniScreenBottom + globals()->gInstrumentTop);
- } else
- {
- mRect = Rect(kButBoxLeft, kButBoxTop + globals()->gInstrumentTop, kButBoxRight,
- kButBoxBottom + globals()->gInstrumentTop);
- }
- // hilite/unhilite this button
- if ( count < kMiniScreenTrueLineNum)
- {
- if (( theseKeys & kCompCancelKey) && ( line->lineKind != buttonOnLineKind))
- {
- line->lineKind = buttonOnLineKind;
- mPlayBeep3();
- } else if ((!( theseKeys & kCompCancelKey)) && ( line->lineKind != buttonOffLineKind))
- {
- line->lineKind = buttonOffLineKind;
- MiniComputerDoCancel();
- }
- }
- }
- if (( theseKeys & kCompUpKey) && ( !(lastKeys & kCompUpKey)) && ( globals()->gMiniScreenData.selectLine !=
- kMiniScreenNoLineSelected))
- {
- scrap = globals()->gMiniScreenData.selectLine;
- line = globals()->gMiniScreenData.lineData.get() + globals()->gMiniScreenData.selectLine;
- line->hiliteLeft = line->hiliteRight = 0;
- do
- {
- line--;
- globals()->gMiniScreenData.selectLine--;
- if ( globals()->gMiniScreenData.selectLine < 0)
- {
- globals()->gMiniScreenData.selectLine = kMiniScreenTrueLineNum - 1;
- line = globals()->gMiniScreenData.lineData.get() + kMiniScreenTrueLineNum - 1L;
- }
- } while ( line->selectable == cannotSelect);
- if ( globals()->gMiniScreenData.selectLine < kMiniScreenCharHeight)
- {
- mRect = Rect(kMiniScreenLeft, kMiniScreenTop + globals()->gInstrumentTop, kMiniScreenRight,
- kMiniScreenBottom + globals()->gInstrumentTop);
- } else
- {
- mRect = Rect(kButBoxLeft, kButBoxTop + globals()->gInstrumentTop, kButBoxRight,
- kButBoxBottom + globals()->gInstrumentTop);
- }
- line->hiliteLeft = mRect.left;
- line->hiliteRight = mRect.right;
- }
- if (( theseKeys & kCompDownKey) && ( !(lastKeys & kCompDownKey)) && ( globals()->gMiniScreenData.selectLine !=
- kMiniScreenNoLineSelected))
- {
- scrap = globals()->gMiniScreenData.selectLine;
- line = globals()->gMiniScreenData.lineData.get() + globals()->gMiniScreenData.selectLine;
- line->hiliteLeft = line->hiliteRight = 0;
- do
- {
- line++;
- globals()->gMiniScreenData.selectLine++;
- if ( globals()->gMiniScreenData.selectLine >= kMiniScreenTrueLineNum)
- {
- globals()->gMiniScreenData.selectLine = 0;
- line = globals()->gMiniScreenData.lineData.get();
- }
- } while ( line->selectable == cannotSelect);
- if ( globals()->gMiniScreenData.selectLine < kMiniScreenCharHeight)
- {
- mRect = Rect(kMiniScreenLeft, kMiniScreenTop + globals()->gInstrumentTop, kMiniScreenRight,
- kMiniScreenBottom + globals()->gInstrumentTop);
- } else
- {
- mRect = Rect(kButBoxLeft, kButBoxTop + globals()->gInstrumentTop, kButBoxRight,
- kButBoxBottom + globals()->gInstrumentTop);
- }
- line->hiliteLeft = mRect.left;
- line->hiliteRight = mRect.right;
- }
- }
- void MiniComputerHandleNull( long unitsToDo)
- {
- destBalanceType *buildAtObject = NULL;
- long count;
- spaceObjectType *realObject = NULL, *myObject = NULL, newObject;
- globals()->gMiniScreenData.pollTime += unitsToDo;
- if ( globals()->gMiniScreenData.pollTime > kMiniComputerPollTime)
- {
- globals()->gMiniScreenData.pollTime = 0;
- UpdateMiniScreenLines();
- // handle control/command/selected object
- myObject = mGetMiniObjectPtr( kMiniSelectObjectNum);
- count = GetAdmiralConsiderObject( globals()->gPlayerAdmiralNumber);
- if ( count >= 0)
- {
- realObject = gSpaceObjectData.get() + count;
- mCopyMiniSpaceObject( newObject, *realObject);
- } else
- {
- newObject.id = -1;
- newObject.beamType = -1;
- newObject.pulseType = -1;
- newObject.specialType = -1;
- newObject.destinationLocation.h = newObject.destinationLocation.v = -1;
- newObject.destinationObject = -1;
- newObject.destObjectPtr = NULL;
- newObject.health = 0;
- newObject.energy = 0;
- newObject.whichBaseObject = -1;
- newObject.pixResID = -1;
- newObject.attributes = 0;
- newObject.baseType = NULL;
- }
- mCopyMiniSpaceObject(*myObject, newObject);
- myObject = mGetMiniObjectPtr( kMiniTargetObjectNum);
- count = GetAdmiralDestinationObject( globals()->gPlayerAdmiralNumber);
- if ( count >= 0)
- {
- realObject = gSpaceObjectData.get() + count;
- mCopyMiniSpaceObject( newObject, *realObject);
- } else
- {
- newObject.id = -1;
- newObject.beamType = -1;
- newObject.pulseType = -1;
- newObject.specialType = -1;
- newObject.destinationLocation.h = newObject.destinationLocation.v = -1;
- newObject.destinationObject = -1;
- newObject.destObjectPtr = NULL;
- newObject.health = 0;
- newObject.energy = 0;
- newObject.whichBaseObject = -1;
- newObject.pixResID = -1;
- newObject.attributes = 0;
- newObject.baseType = NULL;
- }
- mCopyMiniSpaceObject(*myObject, newObject);
- int build_at = GetAdmiralBuildAtObject(globals()->gPlayerAdmiralNumber);
- if (build_at >= 0) {
- buildAtObject = mGetDestObjectBalancePtr(build_at);
- if (buildAtObject->totalBuildTime > 0) {
- int progress = buildAtObject->buildTime * kMiniBuildTimeHeight;
- progress /= buildAtObject->totalBuildTime;
- globals()->gMiniScreenData.buildTimeBarValue = progress;
- } else {
- globals()->gMiniScreenData.buildTimeBarValue = 0;
- }
- } else {
- globals()->gMiniScreenData.buildTimeBarValue = -1;
- }
- }
- }
- // only for updating volitile lines--doesn't draw whole screen!
- void UpdateMiniScreenLines( void)
- {
- admiralType *admiral = NULL;
- miniScreenLineType *line = NULL;
- baseObjectType *buildObject = NULL;
- long lineNum, count;
- Rect mRect;
- mRect = Rect(kMiniScreenLeft, kMiniScreenTop + globals()->gInstrumentTop, kMiniScreenRight,
- kMiniScreenBottom + globals()->gInstrumentTop);
- switch( globals()->gMiniScreenData.currentScreen)
- {
- case kBuildMiniScreen:
- admiral = globals()->gAdmiralData.get() + globals()->gPlayerAdmiralNumber;
- line = globals()->gMiniScreenData.lineData.get() +
- kBuildScreenWhereNameLine;
- if ( line->value !=
- GetAdmiralBuildAtObject( globals()->gPlayerAdmiralNumber))
- {
- if ( globals()->gMiniScreenData.selectLine !=
- kMiniScreenNoLineSelected)
- {
- line = globals()->gMiniScreenData.lineData.get()
- + globals()->gMiniScreenData.selectLine;
- line->hiliteLeft = line->hiliteRight = 0;
- globals()->gMiniScreenData.selectLine =
- kMiniScreenNoLineSelected;
- }
- MiniComputerSetBuildStrings();
- } else if ( GetAdmiralBuildAtObject( globals()->gPlayerAdmiralNumber)
- >= 0)
- {
- line = globals()->gMiniScreenData.lineData.get() + kBuildScreenFirstTypeLine;
- lineNum = kBuildScreenFirstTypeLine;
- for ( count = 0; count < kMaxShipCanBuild; count++)
- {
- buildObject = line->sourceData;
- if ( buildObject != NULL)
- {
- if ( buildObject->price > mFixedToLong(admiral->cash))
- {
- if ( line->selectable != selectDim)
- {
- line->selectable = selectDim;
- }
- } else
- {
- if (line->selectable != selectable)
- {
- if ( globals()->gMiniScreenData.selectLine ==
- kMiniScreenNoLineSelected)
- {
- globals()->gMiniScreenData.selectLine =
- lineNum;
- line->hiliteLeft = mRect.left;
- line->hiliteRight = mRect.right;
- }
- line->selectable = selectable;
- }
- }
- }
- line++;
- lineNum++;
- }
- }
- break;
- case kStatusMiniScreen:
- for ( count = kStatusMiniScreenFirstLine; count <
- kMiniScreenCharHeight; count++)
- {
- line =
- globals()->gMiniScreenData.lineData.get() +
- count;
- lineNum = MiniComputerGetStatusValue( count);
- if ( line->value != lineNum)
- {
- line->value = lineNum;
- MiniComputerMakeStatusString(count, line->string);
- }
- }
- break;
- }
- }
- static void draw_player_ammo_in_rect(int32_t value, int8_t hue, const Rect& rect) {
- if (value >= 0) {
- const RgbColor text_color = GetRGBTranslateColorShade(hue, VERY_LIGHT);
- const char digits[] = {
- ((value % 1000) / 100) + '0',
- ((value % 100) / 10) + '0',
- (value % 10) + '0',
- '\0',
- };
- Point origin(rect.left + kMiniAmmoTextHBuffer, rect.bottom - 1);
- computer_font->draw_sprite(origin, digits, text_color);
- }
- }
- void draw_player_ammo(int32_t ammo_one, int32_t ammo_two, int32_t ammo_special) {
- Rect clip(0, kMiniAmmoTop, kMiniAmmoSingleWidth, kMiniAmmoBottom);
- clip.offset(0, globals()->gInstrumentTop);
- clip.offset(kMiniAmmoLeftOne - clip.left, 0);
- draw_player_ammo_in_rect(ammo_one, RED, clip);
- clip.offset(kMiniAmmoLeftTwo - clip.left, 0);
- draw_player_ammo_in_rect(ammo_two, PALE_GREEN, clip);
- clip.offset(kMiniAmmoLeftSpecial - clip.left, 0);
- draw_player_ammo_in_rect(ammo_special, ORANGE, clip);
- }
- void draw_mini_ship_data(
- const spaceObjectType& newObject, unsigned char headerColor,
- short screenTop, short whichString) {
- Rect lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, 0, 0, kMiniScreenWidth);
- RgbColor color = GetRGBTranslateColorShade(headerColor, LIGHT);
- RgbColor lightcolor = GetRGBTranslateColorShade(headerColor, VERY_LIGHT);
- RgbColor darkcolor = GetRGBTranslateColorShade(headerColor, MEDIUM);
- draw_shaded_rect(lRect, color, lightcolor, darkcolor);
- String text(StringList(kMiniDataStringID).at(whichString - 1));
- computer_font->draw_sprite(
- Point(lRect.left + kMiniScreenLeftBuffer, lRect.top + computer_font->ascent),
- text, RgbColor::kBlack);
- if (newObject.attributes & kIsDestination) {
- lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, kMiniNameLineNum, 0, kMiniScreenWidth);
- // get the color for writing the name
- color = GetRGBTranslateColorShade(PALE_GREEN, VERY_LIGHT);
- // move to the 1st line in the selection miniscreen
- String text(GetDestBalanceName(newObject.destinationObject));
- computer_font->draw_sprite(
- Point(lRect.left + kMiniScreenLeftBuffer, lRect.top + computer_font->ascent),
- text, color);
- } else {
- lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, kMiniNameLineNum, 0, kMiniScreenWidth);
- if (newObject.whichBaseObject >= 0) {
- // get the color for writing the name
- color = GetRGBTranslateColorShade(PALE_GREEN, VERY_LIGHT);
- // move to the 1st line in the selection miniscreen, write the name
- String text(StringList(kSpaceObjectShortNameResID).at(newObject.whichBaseObject));
- computer_font->draw_sprite(
- Point(lRect.left + kMiniScreenLeftBuffer, lRect.top + computer_font->ascent),
- text, color);
- }
- }
- // set the rect for drawing the "icon" of the object type
- Rect dRect;
- dRect.left = kMiniIconLeft;
- dRect.top = screenTop + globals()->gInstrumentTop + MiniIconMacLineTop();
- dRect.right = kMiniScreenLeft + kMiniIconWidth;
- dRect.bottom = dRect.top + kMiniIconHeight;
- if ((newObject.whichBaseObject >= 0) && (newObject.pixResID >= 0)) {
- NatePixTable* pixTable = GetPixTable(newObject.pixResID);
- if (pixTable != NULL) {
- short whichShape;
- if (newObject.attributes & kIsSelfAnimated) {
- whichShape = more_evil_fixed_to_long(newObject.baseType->frame.animation.firstShape);
- } else {
- whichShape = 0;
- }
- // get the picture data
- const NatePixTable::Frame& frame = pixTable->at(whichShape);
- Rect rect(0, 0, frame.width(), frame.height());
- int32_t max_dimension = max(frame.width(), frame.height());
- if (max_dimension > kMiniIconHeight) {
- rect.right = (rect.right * (kMiniIconHeight - 4)) / max_dimension;
- rect.bottom = (rect.bottom * (kMiniIconHeight - 4)) / max_dimension;
- }
- rect.center_in(dRect);
- frame.sprite().draw(rect);
- }
- }
- color = GetRGBTranslateColorShade(PALE_GREEN, MEDIUM);
- draw_vbracket(dRect, color);
- if (newObject.baseType != NULL) {
- if ((newObject.baseType->health > 0) && (newObject.health > 0)) {
- Rect dRect;
- dRect.left = kMiniHealthLeft;
- dRect.top = screenTop + globals()->gInstrumentTop + MiniIconMacLineTop();
- dRect.right = dRect.left + kMiniBarWidth;
- dRect.bottom = dRect.top + kMiniIconHeight;
- uint32_t tlong = newObject.health * kMiniBarHeight;
- tlong /= newObject.baseType->health;
- color = GetRGBTranslateColorShade(SKY_BLUE, DARK);
- lRect.left = dRect.left + 2;
- lRect.top = dRect.top + 2;
- lRect.right = dRect.right - 2;
- lRect.bottom = dRect.bottom - 2 - tlong;
- VideoDriver::driver()->fill_rect(lRect, color);
- color = GetRGBTranslateColorShade(SKY_BLUE, LIGHT);
- lRect.top = dRect.bottom - 2 - tlong;
- lRect.bottom = dRect.bottom - 2;
- VideoDriver::driver()->fill_rect(lRect, color);
- color = GetRGBTranslateColorShade(SKY_BLUE, MEDIUM);
- draw_vbracket(dRect, color);
- }
- }
- if (newObject.baseType != NULL) {
- if ((newObject.baseType->energy > 0) && (newObject.energy > 0)) {
- Rect dRect;
- dRect.left = kMiniEnergyLeft;
- dRect.top = screenTop + globals()->gInstrumentTop + MiniIconMacLineTop();
- dRect.right = dRect.left + kMiniBarWidth;
- dRect.bottom = dRect.top + kMiniIconHeight;
- uint32_t tlong = newObject.energy * kMiniBarHeight;
- tlong /= newObject.baseType->energy;
- color = GetRGBTranslateColorShade(YELLOW, DARK);
- lRect.left = dRect.left + 2;
- lRect.top = dRect.top + 2;
- lRect.right = dRect.right - 2;
- lRect.bottom = dRect.bottom - 2 - tlong;
- VideoDriver::driver()->fill_rect(lRect, color);
- color = GetRGBTranslateColorShade(YELLOW, LIGHT);
- lRect.top = dRect.bottom - 2 - tlong;
- lRect.bottom = dRect.bottom - 2;
- VideoDriver::driver()->fill_rect(lRect, color);
- color = GetRGBTranslateColorShade(YELLOW, MEDIUM);
- draw_vbracket(dRect, color);
- }
- }
- lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, kMiniWeapon1LineNum, kMiniRightColumnLeft, kMiniScreenWidth);
- // get the color for writing the name
- color = GetRGBTranslateColorShade(PALE_GREEN, VERY_LIGHT);
- // move to the 1st line in the selection miniscreen, write the name
- if (newObject.beamType >= 0) {
- String text(StringList(kSpaceObjectShortNameResID).at(newObject.beamType));
- computer_font->draw_sprite(
- Point(lRect.left, lRect.top + computer_font->ascent), text, color);
- }
- lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, kMiniWeapon2LineNum, kMiniRightColumnLeft, kMiniScreenWidth);
- // get the color for writing the name
- color = GetRGBTranslateColorShade(PALE_GREEN, VERY_LIGHT);
- // move to the 1st line in the selection miniscreen, write the name
- if (newObject.pulseType >= 0) {
- String text(StringList(kSpaceObjectShortNameResID).at(newObject.pulseType));
- computer_font->draw_sprite(
- Point(lRect.left, lRect.top + computer_font->ascent), text, color);
- }
- // Don't show special weapons of destination objects.
- if (!(newObject.attributes & kIsDestination)) {
- lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, kMiniWeapon3LineNum, kMiniRightColumnLeft, kMiniScreenWidth);
- // get the color for writing the name
- color = GetRGBTranslateColorShade(PALE_GREEN, VERY_LIGHT);
- // move to the 1st line in the selection miniscreen, write the name
- if (newObject.specialType >= 0) {
- String text(StringList(kSpaceObjectShortNameResID).at(newObject.specialType));
- computer_font->draw_sprite(
- Point(lRect.left, lRect.top + computer_font->ascent), text, color);
- }
- }
- lRect = mini_screen_line_bounds(screenTop + globals()->gInstrumentTop, kMiniDestLineNum, 0, kMiniScreenWidth);
- // write the name
- if (newObject.destinationObject >= 0) {
- if (newObject.destObjectPtr != NULL) {
- spaceObjectType* dObject = newObject.destObjectPtr;
- // get the color for writing the name
- if (dObject->owner == globals()->gPlayerAdmiralNumber) {
- color = GetRGBTranslateColorShade(GREEN, VERY_LIGHT);
- } else {
- color = GetRGBTranslateColorShade(RED, VERY_LIGHT);
- }
- if (dObject->attributes & kIsDestination) {
- String text(GetDestBalanceName(dObject->destinationObject));
- computer_font->draw_sprite(
- Point(lRect.left, lRect.top + computer_font->ascent), text, color);
- } else {
- String text(StringList(kSpaceObjectNameResID).at(dObject->whichBaseObject));
- computer_font->draw_sprite(
- Point(lRect.left, lRect.top + computer_font->ascent), text, color);
- }
- }
- }
- }
- void MiniComputerDoAccept( void)
- {
- if (true) { // TODO(sfiera): if non-networked.
- MiniComputerExecute( globals()->gMiniScreenData.currentScreen,
- globals()->gMiniScreenData.selectLine, globals()->gPlayerAdmiralNumber);
- } else {
- #ifdef NETSPROCKET_AVAILABLE
- if ( !SendMenuMessage( globals()->gGameTime + gNetLatency, globals()->gMiniScreenData.currentScreen,
- globals()->gMiniScreenData.selectLine))
- StopNetworking();
- #endif NETSPROCKET_AVAILABLE
- }
- }
- void MiniComputerExecute( long whichPage, long whichLine, long whichAdmiral)
- {
- spaceObjectType *anObject, *anotherObject;
- long l;
- switch ( whichPage)
- {
- case kMainMiniScreen:
- if ( whichAdmiral == globals()->gPlayerAdmiralNumber)
- {
- switch ( whichLine)
- {
- case kMainMiniBuild:
- MakeMiniScreenFromIndString( kBuildMiniScreen);
- MiniComputerSetBuildStrings();
- break;
- case kMainMiniSpecial:
- MakeMiniScreenFromIndString( kSpecialMiniScreen);
- break;
- case kMainMiniMessage:
- MakeMiniScreenFromIndString( kMessageMiniScreen);
- break;
- case kMainMiniStatus:
- MakeMiniScreenFromIndString( kStatusMiniScreen);
- MiniComputerSetStatusStrings();
- break;
- default:
- break;
- }
- }
- break;
- case kBuildMiniScreen:
- if ( globals()->keyMask & kComputerBuildMenu) return;
- if ( whichLine != kMiniScreenNoLineSelected)
- {
- if ( CountObjectsOfBaseType( -1, -1) <
- (kMaxSpaceObject - kMaxShipBuffer))
- {
- if (AdmiralScheduleBuild( whichAdmiral,
- whichLine - kBuildScreenFirstTypeLine) == false)
- {
- if ( whichAdmiral == globals()->gPlayerAdmiralNumber)
- mPlayBeepBad();
- }
- } else
- {
- if ( whichAdmiral == globals()->gPlayerAdmiralNumber)
- {
- SetStatusString("Maximum number of ships built", ORANGE);
- }
- }
- }
- break;
- case kSpecialMiniScreen:
- if ( globals()->keyMask & kComputerSpecialMenu) return;
- switch ( whichLine)
- {
- case kSpecialMiniTransfer:
- l = GetAdmiralConsiderObject( whichAdmiral);
- anObject = GetAdmiralFlagship( whichAdmiral);
- if ( anObject != NULL)
- {
- if ( l != kNoShip)
- {
- anotherObject = gSpaceObjectData.get() + l;
- if (( anotherObject->active != kObjectInUse) ||
- ( !(anotherObject->attributes & kCanThink)) ||
- ( anotherObject->attributes & kStaticDestination)
- || ( anotherObject->owner != anObject->owner) ||
- (!(anotherObject->attributes & kCanAcceptDestination))
- || ( !(anotherObject->attributes & kCanBeDestination))
- || ( anObject->active != kObjectInUse))
- {
- if ( whichAdmiral == globals()->gPlayerAdmiralNumber)
- mPlayBeepBad();
- } else
- {
- ChangePlayerShipNumber( whichAdmiral, l);
- }
- } else
- {
- PlayerShipBodyExpire( anObject, false);
- }
- }
- break;
- case kSpecialMiniFire1:
- l = GetAdmiralConsiderObject( whichAdmiral);
- if (( l != kNoShip))
- {
- anObject = gSpaceObjectData.get() + l;
- if (( anObject->active) &&
- (anObject->attributes & ( kCanAcceptDestination)))
- {
- anObject->keysDown |= kOneKey | kManualOverrideFlag;
- }
- }
- break;
- case kSpecialMiniFire2:
- l = GetAdmiralConsiderObject( whichAdmiral);
- if (( l != kNoShip))
- {
- anObject = gSpaceObjectData.get() + l;
- if (( anObject->active) &&
- (anObject->attributes & ( kCanAcceptDestination)))
- {
- anObject->keysDown |= kTwoKey | kManualOverrideFlag;
- }
- }
- break;
- case kSpecialMiniFireSpecial:
- l = GetAdmiralConsiderObject( whichAdmiral);
- if (( l != kNoShip))
- {
- anObject = gSpaceObjectData.get() + l;
- if (( anObject->active) &&
- (anObject->attributes & ( kCanAcceptDestination)))
- {
- anObject->keysDown |= kEnterKey | kManualOverrideFlag;
- }
- }
- break;
- case kSpecialMiniHold:
- l = GetAdmiralConsiderObject( whichAdmiral);
- if (( l != kNoShip))
- {
- anObject = gSpaceObjectData.get() + l;
- SetObjectLocationDestination( anObject, &(anObject->location));
- }
- break;
- case kSpecialMiniGoToMe:
- l = GetAdmiralConsiderObject( whichAdmiral);
- if (( l != kNoShip))
- {
- anObject = gSpaceObjectData.get() + l;
- anotherObject = GetAdmiralFlagship( whichAdmiral);
- SetObjectLocationDestination( anObject, &(anotherObject->location));
- }
- break;
- default:
- break;
- }
- break;
- case kMessageMiniScreen:
- if ( globals()->keyMask & kComputerMessageMenu) return;
- if ( whichAdmiral == globals()->gPlayerAdmiralNumber)
- {
- switch ( whichLine)
- {
- case kMessageMiniNext:
- AdvanceCurrentLongMessage();
- break;
- case kMessageMiniLast:
- ReplayLastLongMessage();
- break;
- case kMessageMiniPrevious:
- PreviousCurrentLongMessage();
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- void MiniComputerDoCancel( void)
- {
- switch ( globals()->gMiniScreenData.currentScreen)
- {
- case kBuildMiniScreen:
- case kSpecialMiniScreen:
- case kMessageMiniScreen:
- case kStatusMiniScreen:
- MakeMiniScreenFromIndString( kMainMiniScreen);
- break;
- default:
- break;
- }
- }
- void MiniComputerSetBuildStrings( void) // sets the ship type strings for the build screen
- // also sets up the values = base object num
- {
- baseObjectType *buildObject = NULL;
- admiralType *admiral = NULL;
- destBalanceType *buildAtObject = NULL;
- miniScreenLineType *line = NULL;
- long count, baseNum, lineNum, buildAtObjectNum;
- Rect mRect;
- mRect = Rect(kMiniScreenLeft, kMiniScreenTop + globals()->gInstrumentTop, k…
Large files files are truncated, but you can click here to view the full file