static void DrawDevices (DEVICES_STATE *devState, COUNT OldDevice, COUNT NewDevice) { LockMutex (GraphicsLock); BatchGraphics (); SetContext (StatusContext); if (OldDevice > NUM_DEVICES) { // Asked for the initial display or refresh DrawDevicesDisplay (devState); // do not draw unselected again this time OldDevice = NewDevice; } if (OldDevice != NewDevice) { // unselect the previous element DrawDevice (devState->list[OldDevice], OldDevice - devState->topIndex, false); } if (NewDevice < NUM_DEVICES) { // select the new element DrawDevice (devState->list[NewDevice], NewDevice - devState->topIndex, true); } UnbatchGraphics (); UnlockMutex (GraphicsLock); }
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 FeedbackPlayerPhrase (UNICODE *pStr) { SetContext (SpaceContext); BatchGraphics (); DrawSISComWindow (); if (pStr[0]) { TEXT ct; ct.baseline.x = SIS_SCREEN_WIDTH >> 1; ct.baseline.y = SLIDER_Y + SLIDER_HEIGHT + RES_SCALE(13); // JMS_GFX ct.align = ALIGN_CENTER; ct.CharCount = (COUNT)~0; ct.pStr = GAME_STRING (FEEDBACK_STRING_BASE); // "(In response to your statement)" SetContextForeGroundColor (COMM_RESPONSE_INTRO_TEXT_COLOR); font_DrawText (&ct); ct.baseline.y += RES_SCALE(16); // JMS_GFX SetContextForeGroundColor (COMM_FEEDBACK_TEXT_COLOR); ct.pStr = pStr; add_text (-4, &ct); } UnbatchGraphics (); }
static void DrawFileStrings (MELEE_STATE *pMS) { POINT origin; CONTEXT OldContext; origin.x = FILE_STRING_ORIGIN_X; origin.y = FILE_STRING_ORIGIN_Y; OldContext = SetContext (SpaceContext); SetContextFont (MicroFont); BatchGraphics (); DrawMeleeIcon (28); /* The load team frame */ if (FillFileView (pMS)) { COUNT i; for (i = pMS->load.top; i < pMS->load.bot; i++) { DrawFileString (pMS->load.view[i - pMS->load.top], &origin, TRUE, FALSE); origin.y += ENTRY_HEIGHT; } } UnbatchGraphics (); SetContext (OldContext); }
// Draw the full restart menu. Nothing is done with selections. static void DrawRestartMenuGraphic (MENU_STATE *pMS) { RECT r; STAMP s; TEXT t; UNICODE buf[64]; s.frame = pMS->CurFrame; GetFrameRect (s.frame, &r); s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1; s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1; SetContextBackGroundColor (BLACK_COLOR); BatchGraphics (); ClearDrawable (); FlushColorXForms (); DrawStamp (&s); // Put the version number in the bottom right corner. SetContextFont (TinyFont); t.pStr = buf; t.baseline.x = SCREEN_WIDTH - 3; t.baseline.y = SCREEN_HEIGHT - 2; t.align = ALIGN_RIGHT; t.CharCount = (COUNT)~0; sprintf (buf, "v%d.%d.%d%s", UQM_MAJOR_VERSION, UQM_MINOR_VERSION, UQM_PATCH_VERSION, UQM_EXTRA_VERSION); SetContextForeGroundColor (WHITE_COLOR); font_DrawText (&t); UnbatchGraphics (); }
static void DrawOrbitalDisplay (DRAW_ORBITAL_MODE Mode) { RECT r; SetContext (SpaceContext); GetContextClipRect (&r); BatchGraphics (); if (Mode != DRAW_ORBITAL_UPDATE) { SetTransitionSource (NULL); DrawSISFrame (); DrawSISMessage (NULL); DrawSISTitle (GLOBAL_SIS (PlanetName)); DrawStarBackGround (); DrawPlanetSurfaceBorder (); } if (Mode == DRAW_ORBITAL_WAIT) { STAMP s; SetContext (GetScanContext (NULL)); s.frame = CaptureDrawable (LoadGraphic (ORBENTER_PMAP_ANIM)); s.origin.x = -SAFE_X; s.origin.y = 0; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); } else if (Mode == DRAW_ORBITAL_FULL) { DrawDefaultPlanetSphere (); } if (Mode != DRAW_ORBITAL_WAIT) { SetContext (GetScanContext (NULL)); DrawPlanet (0, BLACK_COLOR); } if (Mode != DRAW_ORBITAL_UPDATE) { ScreenTransition (3, &r); } UnbatchGraphics (); // for later RepairBackRect() // JMS_GFX if (RESOLUTION_FACTOR == 0) LoadIntoExtraScreen (&r); else LoadIntoExtraScreen_Fs (&r); }
static void RefreshResponses (ENCOUNTER_STATE *pES) { COORD y; BYTE response, extra_y; // JMS_GFX SIZE leading; STAMP s; SetContext (SpaceContext); GetContextFontLeading (&leading); BatchGraphics (); DrawSISComWindow (); y = SLIDER_Y + SLIDER_HEIGHT + RES_SCALE(1); // JMS_GFX for (response = pES->top_response; response < pES->num_responses; ++response) { extra_y = (response == pES->top_response ? 0 : IF_HD(22)); // JMS_GFX pES->response_list[response].response_text.baseline.x = TEXT_X_OFFS + RES_SCALE(8); // JMS_GFX pES->response_list[response].response_text.baseline.y = y + leading + extra_y; // JMS_GFX pES->response_list[response].response_text.align = ALIGN_LEFT; if (response == pES->cur_response) y = add_text (-1, &pES->response_list[response].response_text); else y = add_text (-2, &pES->response_list[response].response_text); } if (pES->top_response) { s.origin.y = SLIDER_Y + SLIDER_HEIGHT + 1; s.frame = SetAbsFrameIndex (ActivityFrame, 6); } else if (y > SIS_SCREEN_HEIGHT) { s.origin.y = SIS_SCREEN_HEIGHT - 2; s.frame = SetAbsFrameIndex (ActivityFrame, 7); } else s.frame = 0; if (s.frame) { RECT r; GetFrameRect (s.frame, &r); s.origin.x = SIS_SCREEN_WIDTH - r.extent.width - 1; DrawStamp (&s); } UnbatchGraphics (); }
static void CommIntroTransition (void) { if (curIntroMode == CIM_CROSSFADE_SCREEN) { ScreenTransition (3, NULL); UnbatchGraphics (); } else if (curIntroMode == CIM_CROSSFADE_SPACE) { RECT r; r.corner.x = SIS_ORG_X; r.corner.y = SIS_ORG_Y; r.extent.width = SIS_SCREEN_WIDTH; r.extent.height = SIS_SCREEN_HEIGHT; ScreenTransition (3, &r); UnbatchGraphics (); } else if (curIntroMode == CIM_CROSSFADE_WINDOW) { ScreenTransition (3, &CommWndRect); UnbatchGraphics (); } else if (curIntroMode == CIM_FADE_IN_SCREEN) { UnbatchGraphics (); FadeScreen (FadeAllToColor, fadeTime); } else { // Uknown transition // Have to unbatch anyway or no more graphics, ever UnbatchGraphics (); assert (0 && "Unknown comm intro transition"); } // Reset the mode for next time. Everything that needs a // different one will let us know. curIntroMode = CIM_DEFAULT; }
static void DrawOrbitalDisplay (DRAW_ORBITAL_MODE Mode) { RECT r = { { SIS_ORG_X, SIS_ORG_Y }, { SIS_SCREEN_WIDTH, SIS_SCREEN_HEIGHT } }; BatchGraphics (); if (Mode != DRAW_ORBITAL_UPDATE) { SetTransitionSource (NULL); DrawSISFrame (); DrawSISMessage (NULL_PTR); DrawSISTitle (GLOBAL_SIS (PlanetName)); DrawStarBackGround (TRUE); } SetContext (SpaceContext); if (Mode == DRAW_ORBITAL_WAIT) { STAMP s; s.frame = CaptureDrawable ( LoadGraphic (ORBENTER_PMAP_ANIM)); s.origin.x = -SAFE_X; s.origin.y = SIS_SCREEN_HEIGHT - MAP_HEIGHT; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); } else { DrawPlanet (SIS_SCREEN_WIDTH - MAP_WIDTH, SIS_SCREEN_HEIGHT - MAP_HEIGHT, 0, 0); } if (Mode != DRAW_ORBITAL_UPDATE) { ScreenTransition (3, &r); } UnbatchGraphics (); if (Mode != DRAW_ORBITAL_WAIT) { LoadIntoExtraScreen (&r); } }
void ClearDrawable (void) { RECT ValidRect; HOT_SPOT OldHot; if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) { BatchGraphics (); ClearBackGround (&ValidRect); UnbatchGraphics (); _CurFramePtr->HotSpot = OldHot; } }
void DrawLabelAsWindow(WIDGET_LABEL *label) { COLOR oldfg = SetContextForeGroundColor (WIDGET_DIALOG_TEXT_COLOR); FONT oldfont = SetContextFont (StarConFont); FRAME oldFontEffect = SetContextFontEffect (NULL); RECT r; TEXT t; int i, win_w, win_h; /* Compute the dimensions of the label */ win_h = label->height ((WIDGET *)label) + 16; win_w = 0; for (i = 0; i < label->line_count; i++) { int len = utf8StringCount (label->lines[i]); if (len > win_w) { win_w = len; } } win_w = (win_w * 6) + 16; BatchGraphics (); r.corner.x = (SCREEN_WIDTH - win_w) >> 1; r.corner.y = (SCREEN_HEIGHT - win_h) >> 1; r.extent.width = win_w; r.extent.height = win_h; DrawShadowedBox (&r, SHADOWBOX_BACKGROUND_COLOR, SHADOWBOX_DARK_COLOR, SHADOWBOX_MEDIUM_COLOR); t.baseline.x = r.corner.x + (r.extent.width >> 1); t.baseline.y = r.corner.y + 16; for (i = 0; i < label->line_count; i++) { t.pStr = label->lines[i]; t.align = ALIGN_CENTER; t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += 8; } UnbatchGraphics (); SetContextFontEffect (oldFontEffect); SetContextFont (oldfont); SetContextForeGroundColor (oldfg); }
static void SelectFileString (MELEE_STATE *pMS, bool hilite) { CONTEXT OldContext; POINT origin; COUNT viewI; viewI = pMS->load.cur - pMS->load.top; OldContext = SetContext (SpaceContext); SetContextFont (MicroFont); BatchGraphics (); origin.x = FILE_STRING_ORIGIN_X; origin.y = FILE_STRING_ORIGIN_Y + viewI * ENTRY_HEIGHT; DrawFileString (pMS->load.view[viewI], &origin, FALSE, hilite); UnbatchGraphics (); SetContext (OldContext); }
void Slider (void) { int offs; static int last_offs = -1; if (sliderDisabled) return; offs = GetSoundInfo (sliderSpace); if (offs != last_offs || sliderChanged) { sliderChanged = FALSE; last_offs = offs; buttonStamp.origin.x = sliderStamp.origin.x + offs; BatchGraphics (); DrawStamp (&sliderStamp); DrawStamp (&buttonStamp); UnbatchGraphics (); } }
static void DrawRestartMenuGraphic (MENU_STATE *pMS) { RECT r; STAMP s; s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM)); pMS->CurFrame = s.frame; GetFrameRect (s.frame, &r); s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1; s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1; SetContextBackGroundColor (BLACK_COLOR); BatchGraphics (); ClearDrawable (); FlushColorXForms (); LockMutex (GraphicsLock); DrawStamp (&s); UnlockMutex (GraphicsLock); UnbatchGraphics (); }
static void UpdateAnimations (bool paused) { static TimeCount NextTime; CONTEXT OldContext; BOOLEAN change; if (GetTimeCounter () < NextTime) return; // too early NextTime = GetTimeCounter () + COMM_ANIM_RATE; OldContext = SetContext (AnimContext); BatchGraphics (); // Advance and draw ambient, transit and talk animations change = ProcessCommAnimations (clear_subtitles, paused); if (change) RedrawSubtitles (); UnbatchGraphics (); clear_subtitles = FALSE; SetContext (OldContext); }
static void DrawConfirmationWindow (BOOLEAN answer) { Color oldfg = SetContextForeGroundColor (MENU_TEXT_COLOR); FONT oldfont = SetContextFont (StarConFont); FRAME oldFontEffect = SetContextFontEffect (NULL); RECT r; TEXT t; BatchGraphics (); r.corner.x = (SCREEN_WIDTH - CONFIRM_WIN_WIDTH) >> 1; r.corner.y = (SCREEN_HEIGHT - CONFIRM_WIN_HEIGHT) >> 1; r.extent.width = CONFIRM_WIN_WIDTH; r.extent.height = CONFIRM_WIN_HEIGHT; DrawShadowedBox (&r, SHADOWBOX_BACKGROUND_COLOR, SHADOWBOX_DARK_COLOR, SHADOWBOX_MEDIUM_COLOR); t.baseline.x = r.corner.x + (r.extent.width >> 1); t.baseline.y = r.corner.y + (8 << RESOLUTION_FACTOR); // JMS_GFX t.pStr = GAME_STRING (QUITMENU_STRING_BASE); // "Really Quit?" t.align = ALIGN_CENTER; t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += (10 << RESOLUTION_FACTOR); // JMS_GFX t.baseline.x = r.corner.x + (r.extent.width >> 2); t.pStr = GAME_STRING (QUITMENU_STRING_BASE + 1); // "Yes" SetContextForeGroundColor (answer ? MENU_HIGHLIGHT_COLOR : MENU_TEXT_COLOR); font_DrawText (&t); t.baseline.x += (r.extent.width >> 1); t.pStr = GAME_STRING (QUITMENU_STRING_BASE + 2); // "No" SetContextForeGroundColor (answer ? MENU_TEXT_COLOR : MENU_HIGHLIGHT_COLOR); font_DrawText (&t); UnbatchGraphics (); SetContextFontEffect (oldFontEffect); SetContextFont (oldfont); SetContextForeGroundColor (oldfg); }
void DrawShadowedBox (RECT *r, Color bg, Color dark, Color medium) { RECT t; Color oldcolor; BatchGraphics (); t.corner.x = r->corner.x - 2; t.corner.y = r->corner.y - 2; t.extent.width = r->extent.width + 4; t.extent.height = r->extent.height + 4; oldcolor = SetContextForeGroundColor (dark); DrawFilledRectangle (&t); t.corner.x += 2; t.corner.y += 2; t.extent.width -= 2; t.extent.height -= 2; SetContextForeGroundColor (medium); DrawFilledRectangle (&t); t.corner.x -= 1; t.corner.y += r->extent.height + 1; t.extent.height = 1; DrawFilledRectangle (&t); t.corner.x += r->extent.width + 2; t.corner.y -= r->extent.height + 2; t.extent.width = 1; DrawFilledRectangle (&t); SetContextForeGroundColor (bg); DrawFilledRectangle (r); SetContextForeGroundColor (oldcolor); UnbatchGraphics (); }
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); }
void Widget_DrawTextEntry (WIDGET *_self, int x, int y) { WIDGET_TEXTENTRY *self = (WIDGET_TEXTENTRY *)_self; Color oldtext; Color inactive, default_color, selected; FONT oldfont = 0; FRAME oldFontEffect = SetContextFontEffect (NULL); TEXT t; if (cur_font) oldfont = SetContextFont (cur_font); default_color = WIDGET_INACTIVE_SELECTED_COLOR; selected = WIDGET_ACTIVE_COLOR; inactive = WIDGET_INACTIVE_COLOR; BatchGraphics (); t.baseline.x = x + 64 * RESOLUTION_FACTOR; // JMS_GFX t.baseline.y = y; t.align = ALIGN_LEFT; t.CharCount = ~0; t.pStr = self->category; if (widget_focus == _self) { oldtext = SetContextForeGroundColor (selected); } else { oldtext = SetContextForeGroundColor (default_color); } font_DrawText (&t); t.baseline.x -= 64 * RESOLUTION_FACTOR; // JMS_GFX /* Force string termination */ self->value[WIDGET_TEXTENTRY_WIDTH-1] = 0; t.baseline.y = y; t.CharCount = utf8StringCount (self->value); t.pStr = self->value; if (!(self->state & WTE_EDITING)) { // normal or selected state t.baseline.x = 160 << RESOLUTION_FACTOR; // JMS_GFX t.align = ALIGN_CENTER; if (widget_focus == _self) { oldtext = SetContextForeGroundColor (selected); } else { oldtext = SetContextForeGroundColor (inactive); } font_DrawText (&t); } else { // editing state COUNT i; RECT text_r; BYTE char_deltas[WIDGET_TEXTENTRY_WIDTH]; BYTE *pchar_deltas; RECT r; SIZE leading; t.baseline.x = 90 << RESOLUTION_FACTOR; // JMS_GFX t.align = ALIGN_LEFT; // calc background box dimensions // XXX: this may need some tuning, especially if a // different font is used. The font 'leading' values // are not what they should be. #define BOX_VERT_OFFSET 2 GetContextFontLeading (&leading); r.corner.x = t.baseline.x - 1; r.corner.y = t.baseline.y - leading + BOX_VERT_OFFSET; r.extent.width = ScreenWidth - r.corner.x - 10; r.extent.height = leading + 2; TextRect (&t, &text_r, char_deltas); #if 0 // XXX: this should potentially be used in ChangeCallback if ((text_r.extent.width + 2) >= r.extent.width) { // the text does not fit the input box size and so // will not fit when displayed later UnbatchGraphics (); // disallow the change return (FALSE); } #endif oldtext = SetContextForeGroundColor (selected); DrawFilledRectangle (&r); // calculate the cursor position and draw it pchar_deltas = char_deltas; for (i = self->cursor_pos; i > 0; --i) r.corner.x += (SIZE)*pchar_deltas++; if (self->cursor_pos < t.CharCount) /* cursor mid-line */ --r.corner.x; if (self->state & WTE_BLOCKCUR) { // Use block cursor for keyboardless systems if (self->cursor_pos == t.CharCount) { // cursor at end-line -- use insertion point r.extent.width = 1; } else if (self->cursor_pos + 1 == t.CharCount) { // extra pixel for last char margin r.extent.width = (SIZE)*pchar_deltas + 2; } else { // normal mid-line char r.extent.width = (SIZE)*pchar_deltas + 1; } } else { // Insertion point cursor r.extent.width = 1; } // position cursor within input field rect ++r.corner.x; ++r.corner.y; r.extent.height -= 2; SetContextForeGroundColor (WIDGET_CURSOR_COLOR); DrawFilledRectangle (&r); SetContextForeGroundColor (inactive); font_DrawText (&t); } UnbatchGraphics (); SetContextFontEffect (oldFontEffect); if (oldfont) SetContextFont (oldfont); SetContextForeGroundColor (oldtext); }
void DrawPlanetSurfaceBorder (void) { CONTEXT oldContext; RECT oldClipRect; RECT clipRect; RECT r; oldContext = SetContext (SpaceContext); GetContextClipRect (&oldClipRect); // Expand the context clip-rect so that we can tweak the existing border clipRect = oldClipRect; clipRect.corner.x -= 1; clipRect.extent.width += 2; clipRect.extent.height += 1; SetContextClipRect (&clipRect); BatchGraphics (); // Border bulk SetContextForeGroundColor ( BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x0A), 0x08)); r.corner.x = 0; r.corner.y = clipRect.extent.height - MAP_HEIGHT - MAP_BORDER_HEIGHT; r.extent.width = clipRect.extent.width; r.extent.height = MAP_BORDER_HEIGHT - 2; DrawFilledRectangle (&r); SetContextForeGroundColor (SIS_BOTTOM_RIGHT_BORDER_COLOR); // Border top shadow line r.extent.width -= 1; r.extent.height = 1; r.corner.x = 1; r.corner.y -= 1; DrawFilledRectangle (&r); // XXX: We will need bulk left and right rects here if MAP_WIDTH changes // Right shadow line r.extent.width = 1; r.extent.height = MAP_HEIGHT + 2; r.corner.y += MAP_BORDER_HEIGHT - 1; r.corner.x = clipRect.extent.width - 1; DrawFilledRectangle (&r); SetContextForeGroundColor (SIS_LEFT_BORDER_COLOR); // Left shadow line r.corner.x -= MAP_WIDTH + 1; DrawFilledRectangle (&r); // Border bottom shadow line r.extent.width = MAP_WIDTH + 2; r.extent.height = 1; DrawFilledRectangle (&r); UnbatchGraphics (); SetContextClipRect (&oldClipRect); SetContext (oldContext); }
static BOOLEAN DoModifyRoster (MENU_STATE *pMS) { ROSTER_STATE *rosterState = pMS->privData; BOOLEAN select, cancel, up, down, horiz; if (GLOBAL (CurrentActivity) & CHECK_ABORT) return FALSE; select = PulsedInputState.menu[KEY_MENU_SELECT]; cancel = PulsedInputState.menu[KEY_MENU_CANCEL]; up = PulsedInputState.menu[KEY_MENU_UP]; down = PulsedInputState.menu[KEY_MENU_DOWN]; // Left or right produces the same effect because there are 2 columns horiz = PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]; if (cancel && !rosterState->modifyingCrew) { return FALSE; } else if (select || cancel) { rosterState->modifyingCrew ^= true; if (!rosterState->modifyingCrew) { SetFlashRect (NULL); SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT); } else { drawModifiedSupportShip (rosterState); flashSupportShipCrew (); SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT | MENU_SOUND_CANCEL); } } else if (rosterState->modifyingCrew) { SIZE delta = 0; BOOLEAN failed = FALSE; if (up) { if (GLOBAL_SIS (CrewEnlisted)) delta = 1; else failed = TRUE; } else if (down) { if (GLOBAL_SIS (CrewEnlisted) < GetCrewPodCapacity ()) delta = -1; else failed = TRUE; } if (delta != 0) { failed = !DeltaSupportCrew (rosterState, delta); } if (failed) { // not enough room or crew PlayMenuSound (MENU_SOUND_FAILURE); } } else { COUNT NewState; POINT *pship_pos = rosterState->shipPos; COUNT top_right = (rosterState->count + 1) >> 1; NewState = pMS->CurState; if (rosterState->count < 2) { // no navigation allowed } else if (horiz) { if (NewState == top_right - 1) NewState = rosterState->count - 1; else if (NewState >= top_right) { NewState -= top_right; if (pship_pos[NewState].y < pship_pos[pMS->CurState].y) ++NewState; } else { NewState += top_right; if (NewState != top_right && pship_pos[NewState].y > pship_pos[pMS->CurState].y) --NewState; } } else if (down) { ++NewState; if (NewState == rosterState->count) NewState = top_right; else if (NewState == top_right) NewState = 0; } else if (up) { if (NewState == 0) NewState = top_right - 1; else if (NewState == top_right) NewState = rosterState->count - 1; else --NewState; } BatchGraphics (); SetContext (StatusContext); if (NewState != pMS->CurState) { // Draw the previous escort in unselected state drawSupportShip (rosterState, FALSE); // Select the new one selectSupportShip (rosterState, NewState); pMS->CurState = NewState; } flashSupportShip (rosterState); UnbatchGraphics (); } SleepThread (ONE_SECOND / 30); return TRUE; }
// Draw the full restart menu. Nothing is done with selections. static void DrawRestartMenuGraphic (MENU_STATE *pMS) { RECT r; STAMP s; TEXT t; UNICODE buf[64]; COUNT svn_revision = 0; // JMS //DC: Load the different menus depending on the resolution factor if (resolutionFactor < 1) s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM)); if (resolutionFactor == 1) s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM2x)); if (resolutionFactor > 1) s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM4x)); // Re-load the info box font so the text shows in correct size after changing the resolution. if (resFactorWasChanged) { DestroyFont (StarConFont); if (resolutionFactor < 1) StarConFont = LoadFont (FALLBACK_TO1X_FONT); if (resolutionFactor == 1) StarConFont = LoadFont (FALLBACK_TO2X_FONT); if (resolutionFactor > 1) StarConFont = LoadFont (FALLBACK_TO4X_FONT); } pMS->CurFrame = s.frame; GetFrameRect (s.frame, &r); s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1; s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1; SetContextBackGroundColor (BLACK_COLOR); BatchGraphics (); ClearDrawable (); FlushColorXForms (); LockMutex (GraphicsLock); DrawStamp (&s); // JMS: Hack for printing out the correct SVN revision number. { UNICODE svn_buf[64] = {0}; char *colonPtr; strcpy(svn_buf, UQMHD_SVN_REVISION); colonPtr = strchr(svn_buf, ':'); // The revision number is in format rXXX if (colonPtr == NULL) { // Let's just take the only number and be happy. svn_revision = atoi(svn_buf); } // the revision number is in format rXXX:ZZZ else { // Now we need to extract only the ZZZ number. UNICODE svn_buf2[10]; strcpy(svn_buf2, colonPtr+1); svn_revision = atoi(svn_buf2); } // Think about this for a while ;) ++svn_revision; } // Put the version number in the bottom right corner. SetContextFont (TinyFont); t.pStr = buf; t.baseline.x = SCREEN_WIDTH - 3; t.baseline.y = SCREEN_HEIGHT - 2; t.align = ALIGN_RIGHT; t.CharCount = (COUNT)~0; sprintf (buf, "v%d.%d.%d%s - SVN r%d", UQM_MAJOR_VERSION, UQM_MINOR_VERSION, UQM_PATCH_VERSION, UQM_EXTRA_VERSION, svn_revision); SetContextForeGroundColor (WHITE_COLOR); font_DrawText (&t); UnlockMutex (GraphicsLock); UnbatchGraphics (); }
BOOLEAN ProcessCommAnimations (BOOLEAN FullRedraw, BOOLEAN paused) { if (paused) { // Drive colormap xforms and nothing else XFormColorMap_step (); return FALSE; } else { COUNT i; SEQUENCE *pSeq; BOOLEAN Change; BOOLEAN CanTalk = TRUE; TimeCount CurTime; DWORD ElapsedTicks; DWORD NextActiveMask; CurTime = GetTimeCounter (); ElapsedTicks = CurTime - LastTime; LastTime = CurTime; // Process ambient animations NextActiveMask = ActiveMask; pSeq = Sequences + FirstAmbient; for (i = 0; i < CommData.NumAnimations; ++i, ++pSeq) { ANIMATION_DESC *ADPtr = pSeq->ADPtr; DWORD ActiveBit = 1L << i; if (ADPtr->AnimFlags & ANIM_DISABLED) continue; if (pSeq->Direction == NO_DIR) { // animation is paused if (!conflictsWithTalkingAnim (pSeq)) { // start it up pSeq->Direction = UP_DIR; } } else if (pSeq->Alarm > ElapsedTicks) { // not time yet pSeq->Alarm -= ElapsedTicks; } else if (ActiveMask & ADPtr->BlockMask) { // animation is blocked assert (!(ActiveMask & ActiveBit) && "Check animations' mutual blocking masks"); assert (animAtNeutralIndex (pSeq)); // reschedule pSeq->Alarm = randomRestartRate (pSeq) + 1; continue; } else { // Time to start or advance the animation if (AdvanceAmbientSequence (pSeq)) { // Animation is active this frame and the next ActiveMask |= ActiveBit; NextActiveMask |= ActiveBit; } else { // Animation remains active this frame but not the next // This keeps any conflicting animations (BlockMask) // from activating in the same frame and scribbling over // our last image. NextActiveMask &= ~ActiveBit; } } if (pSeq->AnimType == PICTURE_ANIM && pSeq->Direction != NO_DIR && conflictsWithTalkingAnim (pSeq)) { // We want to talk, but this is a running picture animation // which conflicts with the talking animation // See if it is safe to stop it now. if (animAtNeutralIndex (pSeq)) { // pause the animation pSeq->Direction = NO_DIR; NextActiveMask &= ~ActiveBit; // Talk animation is drawn last, so it's not a conflict // for this frame. The talk animation will be drawn // over the neutral frame. } else { // Otherwise, let the animation run until it's safe CanTalk = FALSE; } } // BW: to be checked. I've tried to remove what's supposed to be removed while keeping the Syreen zoom-in feature. // It may have to be re-programmed in the new commanim style. if (pSeq->AnimType == PICTURE_ANIM && (ADPtr->AnimFlags & CommData.AlienTalkDesc.AnimFlags & WAIT_TALKING) && pSeq->Direction != NO_DIR) { // JMS: Cut marked animations short when starting talk. // The animations are marked with FAST_STOP_AT_TALK_START in the races' comm source codes. if (ADPtr->AnimFlags & FAST_STOP_AT_TALK_START) { CanTalk = TRUE; //pSeq->AnimObj.CurFrame = SetAbsFrameIndex(pSeq->AnimObj.CurFrame, ADPtr->StartIndex); pSeq->Direction = NO_DIR; } } // JMS: This handles ambient animations which should occur only during talk // A lot of conditions are necessary to eliminate unwanted animations // from the duration of talk transition! if (pSeq->AnimType == PICTURE_ANIM && ADPtr->AnimFlags & WHEN_TALKING && (!(CommData.AlienTalkDesc.AnimFlags & WAIT_TALKING) || (CommData.AlienTalkDesc.AnimFlags & TALK_INTRO) || (CommData.AlienTalkDesc.AnimFlags & TALK_DONE)) && !(CommData.AlienTransitionDesc.AnimFlags & PAUSE_TALKING) && pSeq->Direction != NO_DIR) { // Stop the anim if not talking pSeq->Direction = NO_DIR; } } // All ambient animations have been processed. Advance the mask. ActiveMask = NextActiveMask; // Process the talking and transition animations if (CanTalk && haveTalkingAnim () && runningTalkingAnim ()) { BOOLEAN done = FALSE; if (signaledStopTalkingAnim () && haveTransitionAnim ()) { // Run the transition. We will clear everything // when it is done CommData.AlienTransitionDesc.AnimFlags |= TALK_DONE; } if (CommData.AlienTransitionDesc.AnimFlags & (TALK_INTRO | TALK_DONE)) { // Transitioning in or out of talking if ((CommData.AlienTransitionDesc.AnimFlags & TALK_DONE) && Transit->Direction == NO_DIR) { // This is needed when switching talking anims ResetSequence (Talk); } done = AdvanceTransitSequence (Transit, ElapsedTicks); } else if (!signaledStopTalkingAnim ()) { // Talking, transition is done AdvanceTalkingSequence (Talk, ElapsedTicks); } else { // Not talking ResetSequence (Talk); done = TRUE; } if (signaledStopTalkingAnim () && done) { clearRunTalkingAnim (); clearStopTalkingAnim (); } } else { // Not talking -- disable talking anim if it is done if (Talk->Direction == NO_DIR) TalkDesc.AnimFlags |= ANIM_DISABLED; } BatchGraphics (); // Draw all animations { BOOLEAN ColorChange = XFormColorMap_step (); if (ColorChange) FullRedraw = TRUE; // Colormap animations are processed separately // from picture anims (see XFormColorMap_step) ProcessColormapAnims (Sequences + FirstAmbient, CommData.NumAnimations); Change = DrawAlienFrame (Sequences, TotalSequences, FullRedraw); if (FullRedraw) Change = TRUE; } UnbatchGraphics (); // Post-process ambient animations pSeq = Sequences + FirstAmbient; for (i = 0; i < CommData.NumAnimations; ++i, ++pSeq) { ANIMATION_DESC *ADPtr = pSeq->ADPtr; DWORD ActiveBit = 1L << i; if (ADPtr->AnimFlags & ANIM_DISABLED) continue; // We can only disable a one-shot anim here, otherwise the // last frame will not be drawn if ((ADPtr->AnimFlags & ONE_SHOT_ANIM) && !(NextActiveMask & ActiveBit)) { // One-shot animation, inactive next frame ADPtr->AnimFlags |= ANIM_DISABLED; } } return Change; } }
// status == -1: draw highlighted player dialog option // status == -2: draw non-highlighted player dialog option // status == -4: use current context, and baseline from pTextIn // status == 1: draw alien speech; subtitle cache is used static COORD add_text (int status, TEXT *pTextIn) { COUNT maxchars, numchars; TEXT locText; TEXT *pText; SIZE leading; const char *pStr; SIZE text_width; int num_lines = 0; static COORD last_baseline; BOOLEAN eol; CONTEXT OldContext = NULL; COUNT computerOn = 0; BatchGraphics (); maxchars = (COUNT)~0; if (status == 1) { if (last_subtitle == pTextIn->pStr) { // draws cached subtitle STAMP s; s.origin.x = 0; s.origin.y = 0; s.frame = TextCacheFrame; DrawStamp (&s); UnbatchGraphics (); return last_baseline; } else { // draw to subtitle cache; prepare first OldContext = SetContext (TextCacheContext); ClearDrawable (); last_subtitle = pTextIn->pStr; } text_width = CommData.AlienTextWidth; SetContextFont (CommData.AlienFont); GetContextFontLeading (&leading); pText = pTextIn; } else if (GetContextFontLeading (&leading), status <= -4) { text_width = (SIZE) (SIS_SCREEN_WIDTH - RES_SCALE(8) - (TEXT_X_OFFS << 2)); // JMS_GFX pText = pTextIn; } else { text_width = (SIZE) (SIS_SCREEN_WIDTH - RES_SCALE(8) - (TEXT_X_OFFS << 2)); // JMS_GFX switch (status) { case -3: // Unknown. Never reached; color matches the background color. SetContextForeGroundColor ( BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); break; case -2: // Not highlighted dialog options. SetContextForeGroundColor (COMM_PLAYER_TEXT_NORMAL_COLOR); break; case -1: // Currently highlighted dialog option. SetContextForeGroundColor (COMM_PLAYER_TEXT_HIGHLIGHT_COLOR); break; } maxchars = pTextIn->CharCount; locText = *pTextIn; locText.baseline.x -= RES_SCALE(8) - 4 * RESOLUTION_FACTOR; // JMS_GFX locText.CharCount = (COUNT)~0; locText.pStr = STR_BULLET; font_DrawText (&locText); locText = *pTextIn; pText = &locText; pText->baseline.y -= leading; } numchars = 0; pStr = pText->pStr; if (status > 0 && (CommData.AlienTextValign & (VALIGN_MIDDLE | VALIGN_BOTTOM))) { num_lines = _count_lines(pText); if (CommData.AlienTextValign == VALIGN_BOTTOM) pText->baseline.y -= (leading * num_lines); else if (CommData.AlienTextValign == VALIGN_MIDDLE) pText->baseline.y -= ((leading * num_lines) / 2); if (pText->baseline.y < 0) pText->baseline.y = 0; } do { pText->pStr = pStr; pText->baseline.y += leading; eol = getLineWithinWidth (pText, &pStr, text_width, maxchars); maxchars -= pText->CharCount; if (maxchars != 0) --maxchars; numchars += pText->CharCount; if (status <= 0) { // Player dialog option or (status == -4) other non-alien // text. if (pText->baseline.y < SIS_SCREEN_HEIGHT) font_DrawText (pText); if (status < -4 && pText->baseline.y >= -status - 10) { // Never actually reached. Status is never <-4. ++pStr; break; } } else { // Alien speech if (CommData.AlienConv == ORZ_CONVERSATION) { // BW : special case for the Orz conversations // the character $ is recycled as a marker to // switch from and to computer font const char *ptr; RECT rect; COORD baselinex = pText->baseline.x; COORD width = 0; COUNT remChars = pText->CharCount; // Remaining chars until end of line within width const char *bakptr; COUNT bakChars = remChars; COUNT bakcompOn = computerOn; FONT bakFont = SetContextFont(ComputerFont); SetContextFont(bakFont); ptr = pText->pStr; bakptr = ptr; // We need to manually center the line because // the computer font is larger than the Orzfont // This loop computes the width of the line while (remChars > 0) { while ((*ptr != '$') && remChars > 0) { getCharFromString (&ptr); remChars--; } pText->CharCount -= remChars; TextRect (pText, &rect, NULL); width += rect.extent.width; if (*ptr == '$') { getCharFromString (&ptr); remChars--; computerOn = 1 - computerOn; if (computerOn) SetContextFont (ComputerFont); else SetContextFont (CommData.AlienFont); } pText->CharCount = remChars; pText->pStr = ptr; } // This to simulate a centered line pText->baseline.x = baselinex - (width >> 1); pText->align = ALIGN_LEFT; // Put everything back in place for the // actual display remChars = bakChars; pText->CharCount = bakChars; ptr = bakptr; pText->pStr = bakptr; computerOn = bakcompOn; SetContextFont(bakFont); // This loop is used to look up for $ while (remChars > 0) { while ((*ptr != '$') && remChars > 0) { getCharFromString (&ptr); remChars--; } pText->CharCount -= remChars; TextRect (pText, &rect, NULL); font_DrawTracedText (pText, CommData.AlienTextFColor, CommData.AlienTextBColor); pText->baseline.x += rect.extent.width; if (*ptr == '$') { getCharFromString (&ptr); remChars--; computerOn = 1 - computerOn; if (computerOn) SetContextFont (ComputerFont); else SetContextFont (CommData.AlienFont); } pText->CharCount = remChars; pText->pStr = ptr; } pText->baseline.x = baselinex; pText->align = ALIGN_CENTER; } else { // Normal case : other races than Orz font_DrawTracedText (pText, CommData.AlienTextFColor, CommData.AlienTextBColor); } } } while (!eol && maxchars); pText->pStr = pStr; if (status == 1) { STAMP s; // We were drawing to cache -- flush to screen SetContext (OldContext); s.origin.x = s.origin.y = 0; s.frame = TextCacheFrame; DrawStamp (&s); last_baseline = pText->baseline.y; } UnbatchGraphics (); return (pText->baseline.y); }
BOOLEAN DrawAlienFrame (SEQUENCE *Sequences, COUNT Num, BOOLEAN fullRedraw) { int i; STAMP s; BOOLEAN Change = FALSE; BatchGraphics (); s.origin.x = 0; s.origin.y = 0; if (fullRedraw) { // Draw the main frame s.frame = CommData.AlienFrame; DrawStamp (&s); // Draw any static frames (has to be in reverse) for (i = CommData.NumAnimations - 1; i >= 0; --i) { ANIMATION_DESC *ADPtr = &CommData.AlienAmbientArray[i]; if (ADPtr->AnimFlags & ANIM_MASK) continue; ADPtr->AnimFlags |= ANIM_DISABLED; if (!(ADPtr->AnimFlags & COLORXFORM_ANIM)) { // It's a static frame (e.g. Flagship picture at Starbase) s.frame = SetAbsFrameIndex (CommData.AlienFrame, ADPtr->StartIndex); DrawStamp (&s); } } } if (Sequences) { // Draw the animation sequences (has to be in reverse) for (i = Num - 1; i >= 0; --i) { SEQUENCE *pSeq = &Sequences[i]; ANIMATION_DESC *ADPtr = pSeq->ADPtr; if ((ADPtr->AnimFlags & ANIM_DISABLED) || pSeq->AnimType != PICTURE_ANIM) continue; // Draw current animation frame only if changed if (!fullRedraw && !pSeq->Change) continue; s.frame = SetAbsFrameIndex (CommData.AlienFrame, ADPtr->StartIndex + pSeq->CurIndex); DrawStamp (&s); pSeq->Change = FALSE; Change = TRUE; } } UnbatchGraphics (); return Change; }
void DrawBatch (PPRIMITIVE lpBasePrim, PRIM_LINKS PrimLinks, BATCH_FLAGS BatchFlags) { RECT ValidRect; HOT_SPOT OldHot; if (GraphicsSystemActive () && GetFrameValidRect (&ValidRect, &OldHot)) { COUNT CurIndex; PRIM_LINKS OldLinks; PPRIMITIVE lpPrim; BatchFlags &= BATCH_SINGLE | BATCH_BUILD_PAGE | BATCH_XFORM; BatchFlags |= _get_context_flags () & BATCH_CLIP_GRAPHICS; BatchGraphics (); if (BatchFlags & BATCH_BUILD_PAGE) { ClearBackGround (&ValidRect); } CurIndex = GetPredLink (PrimLinks); if (BatchFlags & BATCH_SINGLE) { if (CurIndex == END_OF_LIST) BatchFlags &= ~BATCH_SINGLE; else { lpBasePrim += CurIndex; OldLinks = GetPrimLinks (lpBasePrim); SetPrimLinks (lpBasePrim, END_OF_LIST, END_OF_LIST); CurIndex = 0; } } for (; CurIndex != END_OF_LIST; CurIndex = GetSuccLink (GetPrimLinks (lpPrim))) { GRAPHICS_PRIM PrimType; PPRIMITIVE lpWorkPrim; RECT ClipRect; TFB_Palette color; lpPrim = &lpBasePrim[CurIndex]; PrimType = GetPrimType (lpPrim); if (!ValidPrimType (PrimType)) continue; lpWorkPrim = lpPrim; switch (PrimType) { case POINT_PRIM: COLORtoPalette (GetPrimColor (lpWorkPrim), &color); TFB_Prim_Point (&lpWorkPrim->Object.Point, &color); break; case STAMP_PRIM: TFB_Prim_Stamp (&lpWorkPrim->Object.Stamp); break; case STAMPFILL_PRIM: COLORtoPalette (GetPrimColor (lpWorkPrim), &color); TFB_Prim_StampFill (&lpWorkPrim->Object.Stamp, &color); break; case LINE_PRIM: COLORtoPalette (GetPrimColor (lpWorkPrim), &color); TFB_Prim_Line (&lpWorkPrim->Object.Line, &color); break; case TEXT_PRIM: if (!TextRect (&lpWorkPrim->Object.Text, &ClipRect, NULL_PTR)) continue; _save_stamp.origin = ClipRect.corner; _text_blt (&ClipRect, lpWorkPrim); break; case RECT_PRIM: COLORtoPalette (GetPrimColor (lpWorkPrim), &color); TFB_Prim_Rect (&lpWorkPrim->Object.Rect, &color); break; case RECTFILL_PRIM: COLORtoPalette (GetPrimColor (lpWorkPrim), &color); TFB_Prim_FillRect (&lpWorkPrim->Object.Rect, &color); break; } } UnbatchGraphics (); _CurFramePtr->HotSpot = OldHot; if (BatchFlags & BATCH_SINGLE) SetPrimLinks (lpBasePrim, GetPredLink (OldLinks), GetSuccLink (OldLinks)); } }
// windowRect, if not NULL, will be filled with the dimensions of the // window drawn. void DrawLabelAsWindow (WIDGET_LABEL *label, RECT *windowRect) { Color oldfg = SetContextForeGroundColor (WIDGET_DIALOG_TEXT_COLOR); FONT oldfont = 0; FRAME oldFontEffect = SetContextFontEffect (NULL); RECT r; TEXT t; int i, win_w, win_h; if (cur_font) oldfont = SetContextFont (cur_font); /* Compute the dimensions of the label */ win_h = label->height ((WIDGET *)label) + (16 << RESOLUTION_FACTOR); // JMS_GFX win_w = 0; for (i = 0; i < label->line_count; i++) { int len = utf8StringCount (label->lines[i]); if (len > win_w) { win_w = len; } } win_w = (win_w * (6 << RESOLUTION_FACTOR)) + (16 << RESOLUTION_FACTOR); // JMS_GFX BatchGraphics (); r.corner.x = (ScreenWidth - win_w) >> 1; r.corner.y = (ScreenHeight - win_h) >> 1; r.extent.width = win_w; r.extent.height = win_h; DrawShadowedBox (&r, win_bg_clr, win_dark_clr, win_medium_clr); t.baseline.x = r.corner.x + (r.extent.width >> 1); t.baseline.y = r.corner.y + (16 << RESOLUTION_FACTOR); // JMS_GFX for (i = 0; i < label->line_count; i++) { t.pStr = label->lines[i]; t.align = ALIGN_CENTER; t.CharCount = (COUNT)~0; font_DrawText (&t); t.baseline.y += (8 << RESOLUTION_FACTOR); // JMS_GFX } UnbatchGraphics (); SetContextFontEffect (oldFontEffect); if (oldfont) SetContextFont (oldfont); SetContextForeGroundColor (oldfg); if (windowRect != NULL) { // Add the outer border added by DrawShadowedBox. // XXX: It may be nicer to add a border size parameter to // DrawShadowedBox, instead of assuming 2 here. windowRect->corner.x = r.corner.x - 2 * (1 + RESOLUTION_FACTOR); windowRect->corner.y = r.corner.y - 2 * (1 + RESOLUTION_FACTOR); windowRect->extent.width = r.extent.width + 4 * (1 + RESOLUTION_FACTOR); windowRect->extent.height = r.extent.height + 4 * (1 + RESOLUTION_FACTOR); } }
static BOOLEAN DoRestart (MENU_STATE *pMS) { static TimeCount LastInputTime; static TimeCount InactTimeOut; TimeCount TimeIn = GetTimeCounter (); /* Cancel any presses of the Pause key. */ GamePaused = FALSE; if(optSuperMelee && !optLoadGame && PacksInstalled()){ pMS->CurState = PLAY_SUPER_MELEE; PulsedInputState.menu[KEY_MENU_SELECT] = 65535; } if(optLoadGame && !optSuperMelee && PacksInstalled()){ pMS->CurState = LOAD_SAVED_GAME; PulsedInputState.menu[KEY_MENU_SELECT] = 65535; } if (pMS->Initialized) Flash_process(pMS->flashContext); if (!pMS->Initialized) { if (pMS->hMusic && !comingFromInit) { StopMusic (); DestroyMusic (pMS->hMusic); pMS->hMusic = 0; } pMS->hMusic = loadMainMenuMusic (Rando); InactTimeOut = (optMainMenuMusic ? 60 : 20) * ONE_SECOND; pMS->flashContext = Flash_createOverlay (ScreenContext, NULL, NULL); Flash_setMergeFactors (pMS->flashContext, -3, 3, 16); Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 14, 0, (6 * ONE_SECOND) / 14, 0); Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16); Flash_setState(pMS->flashContext, FlashState_fadeIn, (3 * ONE_SECOND) / 16); DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE); Flash_start (pMS->flashContext); LastInputTime = GetTimeCounter (); pMS->Initialized = TRUE; SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2)); if (!comingFromInit){ FadeMusic(0,0); PlayMusic (pMS->hMusic, TRUE, 1); if (optMainMenuMusic) FadeMusic (NORMAL_VOLUME+70, ONE_SECOND * 3); } } else if (GLOBAL (CurrentActivity) & CHECK_ABORT) { return FALSE; } else if (PulsedInputState.menu[KEY_MENU_SELECT]) { //BYTE fade_buf[1]; COUNT oldresfactor; switch (pMS->CurState) { case LOAD_SAVED_GAME: if (!RestartMessage(pMS, TimeIn)) { LastActivity = CHECK_LOAD; GLOBAL (CurrentActivity) = IN_INTERPLANETARY; optLoadGame = FALSE; } else return TRUE; break; case START_NEW_GAME: if (!RestartMessage(pMS, TimeIn)) { LastActivity = CHECK_LOAD | CHECK_RESTART; GLOBAL (CurrentActivity) = IN_INTERPLANETARY; } else return TRUE; break; case PLAY_SUPER_MELEE: if (!RestartMessage(pMS, TimeIn)) { GLOBAL (CurrentActivity) = SUPER_MELEE; optSuperMelee = FALSE; } else return TRUE; break; case SETUP_GAME: oldresfactor = resolutionFactor; Flash_pause(pMS->flashContext); Flash_setState(pMS->flashContext, FlashState_fadeIn, (3 * ONE_SECOND) / 16); SetupMenu (); SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT); InactTimeOut = (optMainMenuMusic ? 60 : 20) * ONE_SECOND; LastInputTime = GetTimeCounter (); SetTransitionSource (NULL); BatchGraphics (); DrawRestartMenuGraphic (pMS); ScreenTransition (3, NULL); // JMS_GFX: This prevents drawing an annoying wrong-sized "Setup" frame when changing resolution. if (oldresfactor < resolutionFactor) DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, TRUE); DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE); Flash_continue(pMS->flashContext); UnbatchGraphics (); return TRUE; case QUIT_GAME: SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2)); GLOBAL (CurrentActivity) = CHECK_ABORT; break; } Flash_pause(pMS->flashContext); return FALSE; } else if (PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_DOWN]) { BYTE NewState; NewState = pMS->CurState; if (PulsedInputState.menu[KEY_MENU_UP]) { if (NewState == START_NEW_GAME) NewState = QUIT_GAME; else --NewState; } else if (PulsedInputState.menu[KEY_MENU_DOWN]) { if (NewState == QUIT_GAME) NewState = START_NEW_GAME; else ++NewState; } if (NewState != pMS->CurState) { BatchGraphics (); DrawRestartMenu (pMS, NewState, pMS->CurFrame, FALSE); UnbatchGraphics (); pMS->CurState = NewState; } LastInputTime = GetTimeCounter (); } else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]) { // Does nothing, but counts as input for timeout purposes LastInputTime = GetTimeCounter (); } else if (MouseButtonDown) { Flash_pause(pMS->flashContext); DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54)); // Mouse not supported message SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT); SetTransitionSource (NULL); BatchGraphics (); DrawRestartMenuGraphic (pMS); DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE); ScreenTransition (3, NULL); UnbatchGraphics (); Flash_continue(pMS->flashContext); LastInputTime = GetTimeCounter (); } else { // No input received, check if timed out // JMS: After changing resolution mode, prevent displaying credits // (until the next time the game is restarted). This is to prevent // showing the credits with the wrong resolution mode's font&background. if (GetTimeCounter () - LastInputTime > InactTimeOut && !optRequiresRestart && PacksInstalled()) { SleepThreadUntil (FadeMusic (0, ONE_SECOND/2)); StopMusic (); FadeMusic (NORMAL_VOLUME, 0); GLOBAL (CurrentActivity) = (ACTIVITY)~0; return FALSE; } } comingFromInit = FALSE; SleepThreadUntil (TimeIn + ONE_SECOND / 30); return TRUE; }
static BOOLEAN DoRestart (MENU_STATE *pMS) { static TimeCount LastInputTime; static TimeCount InactTimeOut; TimeCount TimeIn = GetTimeCounter (); /* Cancel any presses of the Pause key. */ GamePaused = FALSE; if (pMS->Initialized) Flash_process(pMS->flashContext); if (!pMS->Initialized) { if (pMS->hMusic) { StopMusic (); DestroyMusic (pMS->hMusic); pMS->hMusic = 0; } pMS->hMusic = LoadMusic (MAINMENU_MUSIC); InactTimeOut = (pMS->hMusic ? 120 : 20) * ONE_SECOND; pMS->flashContext = Flash_createOverlay (ScreenContext, NULL, NULL); Flash_setMergeFactors (pMS->flashContext, -3, 3, 16); Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 16, 0, (6 * ONE_SECOND) / 16, 0); Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16); Flash_setState(pMS->flashContext, FlashState_fadeIn, (3 * ONE_SECOND) / 16); DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame); Flash_start (pMS->flashContext); PlayMusic (pMS->hMusic, TRUE, 1); LastInputTime = GetTimeCounter (); pMS->Initialized = TRUE; SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2)); } else if (GLOBAL (CurrentActivity) & CHECK_ABORT) { return FALSE; } else if (PulsedInputState.menu[KEY_MENU_SELECT]) { switch (pMS->CurState) { case LOAD_SAVED_GAME: LastActivity = CHECK_LOAD; GLOBAL (CurrentActivity) = IN_INTERPLANETARY; break; case START_NEW_GAME: LastActivity = CHECK_LOAD | CHECK_RESTART; GLOBAL (CurrentActivity) = IN_INTERPLANETARY; break; case PLAY_SUPER_MELEE: GLOBAL (CurrentActivity) = SUPER_MELEE; break; case SETUP_GAME: Flash_pause(pMS->flashContext); Flash_setState(pMS->flashContext, FlashState_fadeIn, (3 * ONE_SECOND) / 16); SetupMenu (); SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT); LastInputTime = GetTimeCounter (); SetTransitionSource (NULL); BatchGraphics (); DrawRestartMenuGraphic (pMS); ScreenTransition (3, NULL); DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame); Flash_continue(pMS->flashContext); UnbatchGraphics (); return TRUE; case QUIT_GAME: SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2)); GLOBAL (CurrentActivity) = CHECK_ABORT; break; } Flash_pause(pMS->flashContext); return FALSE; } else if (PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_DOWN]) { BYTE NewState; NewState = pMS->CurState; if (PulsedInputState.menu[KEY_MENU_UP]) { if (NewState == START_NEW_GAME) NewState = QUIT_GAME; else --NewState; } else if (PulsedInputState.menu[KEY_MENU_DOWN]) { if (NewState == QUIT_GAME) NewState = START_NEW_GAME; else ++NewState; } if (NewState != pMS->CurState) { BatchGraphics (); DrawRestartMenu (pMS, NewState, pMS->CurFrame); UnbatchGraphics (); pMS->CurState = NewState; } LastInputTime = GetTimeCounter (); } else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]) { // Does nothing, but counts as input for timeout purposes LastInputTime = GetTimeCounter (); } else if (MouseButtonDown) { Flash_pause(pMS->flashContext); DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54)); // Mouse not supported message SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT); SetTransitionSource (NULL); BatchGraphics (); DrawRestartMenuGraphic (pMS); DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame); ScreenTransition (3, NULL); UnbatchGraphics (); Flash_continue(pMS->flashContext); LastInputTime = GetTimeCounter (); } else { // No input received, check if timed out if (GetTimeCounter () - LastInputTime > InactTimeOut) { SleepThreadUntil (FadeMusic (0, ONE_SECOND)); StopMusic (); FadeMusic (NORMAL_VOLUME, 0); GLOBAL (CurrentActivity) = (ACTIVITY)~0; return FALSE; } } SleepThreadUntil (TimeIn + ONE_SECOND / 30); return TRUE; }
// Draw the full restart menu. Nothing is done with selections. static void DrawRestartMenuGraphic (MENU_STATE *pMS) { RECT r; STAMP s; TEXT t; char *Credit; UNICODE buf[64]; // Re-load all of the restart menu fonts so the text shows in correct size after changing the resolution. if (optRequiresRestart || !PacksInstalled()) { DestroyFont (TinyFont); DestroyFont (PlyrFont); DestroyFont (StarConFont); } // DC: Load the different menus and fonts depending on the resolution factor switch (resolutionFactor){ case 1: if (optRequiresRestart || !PacksInstalled()) { TinyFont = LoadFont (TINY_FALLBACK_TO2X_FONT); PlyrFont = LoadFont (PLYR_FALLBACK_TO2X_FONT); StarConFont = LoadFont (SCON_FALLBACK_TO2X_FONT); } pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM2x)); break; case 2: if (optRequiresRestart || !PacksInstalled()) { TinyFont = LoadFont (TINY_FALLBACK_TO4X_FONT); PlyrFont = LoadFont (PLYR_FALLBACK_TO4X_FONT); StarConFont = LoadFont (SCON_FALLBACK_TO4X_FONT); } pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM4x)); break; case 0: default: if (optRequiresRestart || !PacksInstalled()) { TinyFont = LoadFont (TINY_FALLBACK_TO1X_FONT); PlyrFont = LoadFont (PLYR_FALLBACK_TO1X_FONT); StarConFont = LoadFont (SCON_FALLBACK_TO1X_FONT); } pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM)); break; } s.frame = pMS->CurFrame; GetFrameRect (s.frame, &r); s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1; s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1; SetContextBackGroundColor (BLACK_COLOR); BatchGraphics (); ClearDrawable (); FlushColorXForms (); DrawStamp (&s); // Put the version number in the bottom right corner. SetContextFont (TinyFont); t.pStr = buf; t.baseline.x = SCREEN_WIDTH - RES_SCALE(2); t.baseline.y = SCREEN_HEIGHT - RES_SCALE(2); t.align = ALIGN_RIGHT; t.CharCount = (COUNT)~0; sprintf (buf, "v%d.%d.%d %s", UQM_MAJOR_VERSION, UQM_MINOR_VERSION, UQM_PATCH_VERSION, UQM_EXTRA_VERSION); SetContextForeGroundColor (WHITE_COLOR); font_DrawText (&t); // Put the main menu music credit in the bottom left corner. memset(&buf[0], 0, sizeof(buf)); t.baseline.x = RES_SCALE(2); t.baseline.y = SCREEN_HEIGHT - RES_SCALE(2); t.align = ALIGN_LEFT; Credit = (Rando == 0 ? "Saibuster" : (Rando == 1 ? "Rush AX" : "Mark Vera")); sprintf (buf, "Main Menu Music by %s", Credit); font_DrawText (&t); UnbatchGraphics (); }