diff options
Diffstat (limited to 'src/uqm/planets/cargo.c')
-rw-r--r-- | src/uqm/planets/cargo.c | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/src/uqm/planets/cargo.c b/src/uqm/planets/cargo.c new file mode 100644 index 0000000..147d95a --- /dev/null +++ b/src/uqm/planets/cargo.c @@ -0,0 +1,356 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "../colors.h" +#include "../controls.h" +#include "../gamestr.h" +#include "../shipcont.h" +#include "../setup.h" +#include "../sounds.h" +#include "../util.h" +#include "../sis.h" + // for ClearSISRect(), DrawStatusMessage() +#include "planets.h" +#include "libs/graphics/drawable.h" + // for GetFrameBounds() + + +#define ELEMENT_ORG_Y 35 +#define FREE_ORG_Y (ELEMENT_ORG_Y + (NUM_ELEMENT_CATEGORIES \ + * ELEMENT_SPACING_Y)) +#define BIO_ORG_Y 119 +#define ELEMENT_SPACING_Y 9 + +#define ELEMENT_COL_0 7 +#define ELEMENT_COL_1 32 +#define ELEMENT_COL_2 58 + +#define ELEMENT_SEL_ORG_X (ELEMENT_COL_0 + 7 + 5) +#define ELEMENT_SEL_WIDTH (ELEMENT_COL_2 - ELEMENT_SEL_ORG_X + 1) + +#define TEXT_BASELINE 6 + + +void +ShowRemainingCapacity (void) +{ + RECT r; + TEXT t; + CONTEXT OldContext; + UNICODE buf[40]; + + OldContext = SetContext (StatusContext); + SetContextFont (TinyFont); + + r.corner.x = 40; + r.corner.y = FREE_ORG_Y; + + snprintf (buf, sizeof buf, "%u", + GetStorageBayCapacity () - GLOBAL_SIS (TotalElementMass)); + t.baseline.x = ELEMENT_COL_2 + 1; + t.baseline.y = r.corner.y + TEXT_BASELINE; + t.align = ALIGN_RIGHT; + t.pStr = buf; + t.CharCount = (COUNT)~0; + + r.extent.width = t.baseline.x - r.corner.x + 1; + r.extent.height = ELEMENT_SPACING_Y - 2; + + BatchGraphics (); + // erase previous free amount + SetContextForeGroundColor (CARGO_BACK_COLOR); + DrawFilledRectangle (&r); + // print the new free amount + SetContextForeGroundColor (CARGO_WORTH_COLOR); + font_DrawText (&t); + UnbatchGraphics (); + + SetContext (OldContext); +} + +static void +DrawElementAmount (COUNT element, bool selected) +{ + RECT r; + TEXT t; + UNICODE buf[40]; + + r.corner.x = ELEMENT_SEL_ORG_X; + r.extent.width = ELEMENT_SEL_WIDTH; + r.extent.height = ELEMENT_SPACING_Y - 2; + + if (element == NUM_ELEMENT_CATEGORIES) + r.corner.y = BIO_ORG_Y; + else + r.corner.y = ELEMENT_ORG_Y + (element * ELEMENT_SPACING_Y); + + // draw line background + SetContextForeGroundColor (selected ? + CARGO_SELECTED_BACK_COLOR : CARGO_BACK_COLOR); + DrawFilledRectangle (&r); + + t.align = ALIGN_RIGHT; + t.pStr = buf; + t.baseline.y = r.corner.y + TEXT_BASELINE; + + if (element == NUM_ELEMENT_CATEGORIES) + { // Bio + snprintf (buf, sizeof buf, "%u", GLOBAL_SIS (TotalBioMass)); + } + else + { // Element + // print element's worth + SetContextForeGroundColor (selected ? + CARGO_SELECTED_WORTH_COLOR : CARGO_WORTH_COLOR); + t.baseline.x = ELEMENT_COL_1; + snprintf (buf, sizeof buf, "%u", GLOBAL (ElementWorth[element])); + t.CharCount = (COUNT)~0; + font_DrawText (&t); + + snprintf (buf, sizeof buf, "%u", GLOBAL_SIS (ElementAmounts[element])); + } + + // print the element/bio amount + SetContextForeGroundColor (selected ? + CARGO_SELECTED_AMOUNT_COLOR : CARGO_AMOUNT_COLOR); + t.baseline.x = ELEMENT_COL_2; + t.CharCount = (COUNT)~0; + font_DrawText (&t); +} + +static void +DrawCargoDisplay (void) +{ + STAMP s; + TEXT t; + RECT r; + COORD cy; + COUNT i; + + r.corner.x = 2; + r.extent.width = FIELD_WIDTH + 1; + r.corner.y = 20; + // XXX: Shouldn't the height be 1 less? This draws the bottom border + // 1 pixel too low. Or if not, why do we need another box anyway? + r.extent.height = 129 - r.corner.y; + DrawStarConBox (&r, 1, + SHADOWBOX_MEDIUM_COLOR, SHADOWBOX_DARK_COLOR, + TRUE, CARGO_BACK_COLOR); + + // draw the "CARGO" title + SetContextFont (StarConFont); + t.baseline.x = (STATUS_WIDTH >> 1) - 1; + t.baseline.y = 27; + t.align = ALIGN_CENTER; + t.pStr = GAME_STRING (CARGO_STRING_BASE); + t.CharCount = (COUNT)~0; + SetContextForeGroundColor (CARGO_SELECTED_AMOUNT_COLOR); + font_DrawText (&t); + + SetContextFont (TinyFont); + + s.frame = SetAbsFrameIndex (MiscDataFrame, + (NUM_SCANDOT_TRANSITIONS * 2) + 3); + r.corner.x = ELEMENT_COL_0; + r.extent = GetFrameBounds (s.frame); + s.origin.x = r.corner.x + (r.extent.width >> 1); + + cy = ELEMENT_ORG_Y; + + // print element column headings + t.align = ALIGN_RIGHT; + t.baseline.y = cy - 1; + t.CharCount = (COUNT)~0; + + SetContextForeGroundColor (CARGO_WORTH_COLOR); + t.baseline.x = ELEMENT_COL_1; + t.pStr = "$"; + font_DrawText (&t); + + t.baseline.x = ELEMENT_COL_2; + t.pStr = "#"; + font_DrawText (&t); + + // draw element icons and print amounts + for (i = 0; i < NUM_ELEMENT_CATEGORIES; ++i, cy += ELEMENT_SPACING_Y) + { + // erase background under an element icon + SetContextForeGroundColor (BLACK_COLOR); + r.corner.y = cy; + DrawFilledRectangle (&r); + + // draw an element icon + s.origin.y = r.corner.y + (r.extent.height >> 1); + DrawStamp (&s); + s.frame = SetRelFrameIndex (s.frame, 5); + + DrawElementAmount (i, false); + } + + // erase background under the Bio icon + SetContextForeGroundColor (BLACK_COLOR); + r.corner.y = BIO_ORG_Y; + DrawFilledRectangle (&r); + + // draw the Bio icon + s.origin.y = r.corner.y + (r.extent.height >> 1); + s.frame = SetAbsFrameIndex (s.frame, 68); + DrawStamp (&s); + + // print the Bio amount + DrawElementAmount (NUM_ELEMENT_CATEGORIES, false); + + // draw the line over the Bio amount + r.corner.x = 4; + r.corner.y = BIO_ORG_Y - 2; + r.extent.width = FIELD_WIDTH - 3; + r.extent.height = 1; + SetContextForeGroundColor (CARGO_SELECTED_BACK_COLOR); + DrawFilledRectangle (&r); + + // print "Free" + t.baseline.x = 5; + t.baseline.y = FREE_ORG_Y + TEXT_BASELINE; + t.align = ALIGN_LEFT; + t.pStr = GAME_STRING (CARGO_STRING_BASE + 1); + t.CharCount = (COUNT)~0; + font_DrawText (&t); + + ShowRemainingCapacity (); +} + +void +DrawCargoStrings (BYTE OldElement, BYTE NewElement) +{ + CONTEXT OldContext; + + OldContext = SetContext (StatusContext); + SetContextFont (TinyFont); + + BatchGraphics (); + + if (OldElement > NUM_ELEMENT_CATEGORIES) + { // Asked for the initial display + DrawCargoDisplay (); + + // do not draw unselected again this time + OldElement = NewElement; + } + + if (OldElement != NewElement) + { // unselect the previous element + DrawElementAmount (OldElement, false); + } + + if (NewElement != (BYTE)~0) + { // select the new element + DrawElementAmount (NewElement, true); + } + + UnbatchGraphics (); + SetContext (OldContext); +} + +static void +DrawElementDescription (COUNT element) +{ + DrawStatusMessage (GAME_STRING (element + (CARGO_STRING_BASE + 2))); +} + +static BOOLEAN +DoDiscardCargo (MENU_STATE *pMS) +{ + BYTE NewState; + BOOLEAN select, cancel, back, forward; + + select = PulsedInputState.menu[KEY_MENU_SELECT]; + cancel = PulsedInputState.menu[KEY_MENU_CANCEL]; + back = PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_LEFT]; + forward = PulsedInputState.menu[KEY_MENU_DOWN] || PulsedInputState.menu[KEY_MENU_RIGHT]; + + if (GLOBAL (CurrentActivity) & CHECK_ABORT) + return FALSE; + + if (cancel) + { + return FALSE; + } + else if (select) + { + if (GLOBAL_SIS (ElementAmounts[pMS->CurState])) + { + --GLOBAL_SIS (ElementAmounts[pMS->CurState]); + DrawCargoStrings (pMS->CurState, pMS->CurState); + + --GLOBAL_SIS (TotalElementMass); + ShowRemainingCapacity (); + } + else + { // no element left in cargo hold + PlayMenuSound (MENU_SOUND_FAILURE); + } + } + else + { + NewState = pMS->CurState; + if (back) + { + if (NewState == 0) + NewState += NUM_ELEMENT_CATEGORIES; + --NewState; + } + else if (forward) + { + ++NewState; + if (NewState == NUM_ELEMENT_CATEGORIES) + NewState = 0; + } + + if (NewState != pMS->CurState) + { + DrawCargoStrings (pMS->CurState, NewState); + DrawElementDescription (NewState); + pMS->CurState = NewState; + } + } + + SleepThread (ONE_SECOND / 30); + + return (TRUE); +} + +void +CargoMenu (void) +{ + MENU_STATE MenuState; + + memset (&MenuState, 0, sizeof MenuState); + + // draw the initial cargo display + DrawCargoStrings ((BYTE)~0, MenuState.CurState); + DrawElementDescription (MenuState.CurState); + + SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); + + MenuState.InputFunc = DoDiscardCargo; + DoInput (&MenuState, TRUE); + + // erase the cargo display + ClearSISRect (DRAW_SIS_DISPLAY); +} + |