static void DrawRestartMenu (BYTE OldState, BYTE NewState, FRAME f) { RECT r; TEXT t; UNICODE buf[64]; LockMutex (GraphicsLock); SetContext (ScreenContext); r.corner.x = r.corner.y = r.extent.width = r.extent.height = 0; SetContextClipRect (&r); r.corner.x = 0; r.corner.y = 0; r.extent.width = SCREEN_WIDTH; r.extent.height = SCREEN_HEIGHT; SetFlashRect (&r, SetAbsFrameIndex (f, NewState + 1)); // Put version number in the 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); UnlockMutex (GraphicsLock); (void) OldState; /* Satisfying compiler (unused parameter) */ }
static int hangar_anim_func (void *data) { DWORD TimeIn; STAMP s; Task task = (Task) data; COLORMAP ColorMap; RECT ClipRect; if (!pMenuState->CurString) { FinishTask (task); return -1; } s.origin.x = s.origin.y = 0; s.frame = SetAbsFrameIndex (pMenuState->CurFrame, 24); ClipRect = pMenuState->flash_rect1; ColorMap = SetAbsColorMapIndex (pMenuState->CurString, 0); TimeIn = GetTimeCounter (); while (!Task_ReadState (task, TASK_EXIT)) { CONTEXT OldContext; RECT OldClipRect; LockMutex (GraphicsLock); OldContext = SetContext (ScreenContext); GetContextClipRect (&OldClipRect); SetContextClipRect (&ClipRect); ColorMap = SetRelColorMapIndex (ColorMap, 1); SetColorMap (GetColorMapAddress (ColorMap)); DrawStamp (&s); SetContextClipRect (&OldClipRect); SetContext (OldContext); UnlockMutex (GraphicsLock); SleepThreadUntil (TimeIn + ONE_SECOND / HANGAR_ANIM_RATE); TimeIn = GetTimeCounter (); } FinishTask (task); return 0; }
void DoShipSpin (COUNT index, MUSIC_REF hMusic) { #ifdef WANT_SHIP_SPINS char buf[30]; BYTE clut_buf[1]; RECT old_r, r; SetGraphicUseOtherExtra (1); LoadIntoExtraScreen (0); clut_buf[0] = FadeAllToBlack; SleepThreadUntil (XFormColorMap ((COLORMAPPTR)clut_buf, ONE_SECOND / 4)); FlushColorXForms (); if (hMusic) StopMusic (); FreeHyperData (); sprintf (buf, "ship%02d", index); DoFMV (buf, "spin", FALSE); GetContextClipRect (&old_r); r.corner.x = r.corner.y = 0; r.extent.width = SCREEN_WIDTH; r.extent.height = SCREEN_HEIGHT; SetContextClipRect (&r); DrawFromExtraScreen (0); SetGraphicUseOtherExtra (0); SetContextClipRect (&old_r); if (hMusic) PlayMusic (hMusic, TRUE, 1); clut_buf[0] = FadeAllToColor; SleepThreadUntil (XFormColorMap ((COLORMAPPTR)clut_buf, ONE_SECOND / 4)); FlushColorXForms (); #else (void) index; /* Satisfy compiler */ (void) hMusic; /* Satisfy compiler */ #endif /* WANT_SHIP_SPINS */ }
// draws the oscilloscope void DrawOscilloscope (void) { STAMP s; BYTE scope_data[128]; if (oscillDisabled) return; assert ((size_t)scopeSize.width <= sizeof scope_data); assert (scopeSize.height < 256); if (GraphForegroundStream (scope_data, scopeSize.width, scopeSize.height)) { int i; CONTEXT oldContext; oldContext = SetContext (OffScreenContext); SetContextFGFrame (scopeWork); SetContextClipRect (NULL); // draw the background image s.origin.x = 0; s.origin.y = 0; s.frame = scope_frame; DrawStamp (&s); // draw the scope lines SetContextForeGroundColor (scopeColor); for (i = 0; i < scopeSize.width - 1; ++i) { LINE line; line.first.x = i + 1; line.first.y = scope_data[i] + 1; line.second.x = i + 2; line.second.y = scope_data[i + 1] + 1; DrawLine (&line); } SetContext (oldContext); s.frame = scopeWork; } else { // no data -- draw blank scope background s.frame = scope_frame; } // draw the final scope image to screen s.origin.x = 0; s.origin.y = 0; DrawStamp (&s); }
void InitSISContexts (void) { RECT r; SetContext (StatusContext); SetContext (SpaceContext); SetContextFGFrame (Screen); r.corner.x = SIS_ORG_X; r.corner.y = SIS_ORG_Y; r.extent.width = SIS_SCREEN_WIDTH; r.extent.height = SIS_SCREEN_HEIGHT; SetContextClipRect (&r); }
static void CreatePlanetContext (void) { CONTEXT oldContext; RECT r; assert (PlanetContext == NULL); LockMutex (GraphicsLock); // PlanetContext rect is relative to SpaceContext oldContext = SetContext (SpaceContext); GetContextClipRect (&r); PlanetContext = CreateContext ("PlanetContext"); SetContext (PlanetContext); SetContextFGFrame (Screen); r.extent.height -= MAP_HEIGHT + MAP_BORDER_HEIGHT; SetContextClipRect (&r); SetContext (oldContext); UnlockMutex (GraphicsLock); }
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); }
SIZE InitShips (void) { SIZE num_ships; InitSpace (); SetContext (StatusContext); SetContext (SpaceContext); InitDisplayList (); InitGalaxy (); if (inHQSpace ()) { ReinitQueue (&race_q[0]); ReinitQueue (&race_q[1]); BuildSIS (); LoadHyperspace (); num_ships = 1; } else { COUNT i; RECT r; SetContextFGFrame (Screen); r.corner.x = SAFE_X; r.corner.y = SAFE_Y; r.extent.width = SPACE_WIDTH; r.extent.height = SPACE_HEIGHT; SetContextClipRect (&r); SetContextBackGroundColor (BLACK_COLOR); { CONTEXT OldContext; OldContext = SetContext (ScreenContext); SetContextBackGroundColor (BLACK_COLOR); ClearDrawable (); SetContext (OldContext); } if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE) free_gravity_well (); else { #define NUM_ASTEROIDS 5 for (i = 0; i < NUM_ASTEROIDS; ++i) spawn_asteroid (NULL); #define NUM_PLANETS 1 for (i = 0; i < NUM_PLANETS; ++i) spawn_planet (); } num_ships = NUM_SIDES; } // FlushInput (); return (num_ships); }
BOOLEAN DoConfirmExit (void) { BOOLEAN result; if (PlayingTrack ()) PauseTrack (); LockMutex (GraphicsLock); { RECT r; STAMP s; RECT ctxRect; CONTEXT oldContext; RECT oldRect; BOOLEAN response = FALSE, done; oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); SetContextClipRect (NULL); GetContextClipRect (&ctxRect); r.extent.width = CONFIRM_WIN_WIDTH + 4; r.extent.height = CONFIRM_WIN_HEIGHT + 4; r.corner.x = (ctxRect.extent.width - r.extent.width) >> 1; r.corner.y = (ctxRect.extent.height - r.extent.height) >> 1; s = SaveContextFrame (&r); SetSystemRect (&r); DrawConfirmationWindow (response); FlushGraphics (); FlushInput (); done = FALSE; do { // Forbid recursive calls or pausing here! ExitRequested = FALSE; GamePaused = FALSE; UpdateInputState (); if (GLOBAL (CurrentActivity) & CHECK_ABORT) { // something else triggered an exit done = TRUE; response = TRUE; } else if (PulsedInputState.menu[KEY_MENU_SELECT]) { done = TRUE; PlayMenuSound (MENU_SOUND_SUCCESS); } else if (PulsedInputState.menu[KEY_MENU_CANCEL]) { done = TRUE; response = FALSE; } else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]) { response = !response; DrawConfirmationWindow (response); PlayMenuSound (MENU_SOUND_MOVE); } SleepThread (ONE_SECOND / 30); } while (!done); // Restore the screen under the confirmation window DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); ClearSystemRect (); if (response || (GLOBAL (CurrentActivity) & CHECK_ABORT)) { result = TRUE; GLOBAL (CurrentActivity) |= CHECK_ABORT; } else { result = FALSE; } ExitRequested = FALSE; GamePaused = FALSE; FlushInput (); SetContextClipRect (&oldRect); SetContext (oldContext); } UnlockMutex (GraphicsLock); if (PlayingTrack ()) ResumeTrack (); return (result); }
void DoPopupWindow (const char *msg) { stringbank *bank = StringBank_Create (); const char *lines[30]; WIDGET_LABEL label; STAMP s; CONTEXT oldContext; RECT oldRect; RECT windowRect; POPUP_STATE state; MENU_SOUND_FLAGS s0, s1; InputFrameCallback *oldCallback; if (!bank) { log_add (log_Fatal, "FATAL: Memory exhaustion when preparing popup window"); exit (EXIT_FAILURE); } label.tag = WIDGET_TYPE_LABEL; label.parent = NULL; label.handleEvent = Widget_HandleEventIgnoreAll; label.receiveFocus = Widget_ReceiveFocusRefuseFocus; label.draw = Widget_DrawLabel; label.height = Widget_HeightLabel; label.width = Widget_WidthFullScreen; label.line_count = SplitString (msg, '\n', 30, lines, bank); label.lines = lines; LockMutex (GraphicsLock); oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); SetContextClipRect (NULL); // TODO: Maybe DrawLabelAsWindow() should return a saved STAMP? // We do not know the dimensions here, and so save the whole context s = SaveContextFrame (NULL); Widget_SetFont (StarConFont); Widget_SetWindowColors (SHADOWBOX_BACKGROUND_COLOR, SHADOWBOX_DARK_COLOR, SHADOWBOX_MEDIUM_COLOR); DrawLabelAsWindow (&label, &windowRect); SetSystemRect (&windowRect); GetMenuSounds (&s0, &s1); SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); oldCallback = SetInputCallback (NULL); state.InputFunc = DoPopup; DoInput (&state, TRUE); SetInputCallback (oldCallback); ClearSystemRect (); DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); SetContextClipRect (&oldRect); SetContext (oldContext); UnlockMutex (GraphicsLock); SetMenuSounds (s0, s1); StringBank_Free (bank); }
/* This code assumes that you aren't in Character Mode. This is * currently safe because VControl doesn't see keystrokes when you * are, and thus cannot conclude that an exit is necessary. */ BOOLEAN DoConfirmExit (void) { BOOLEAN result; static BOOLEAN in_confirm = FALSE; if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && !(LastActivity & CHECK_RESTART)) SuspendGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); LockMutex (GraphicsLock); if (in_confirm) { result = FALSE; ExitRequested = FALSE; } else { RECT r; STAMP s; FRAME F; CONTEXT oldContext; RECT oldRect; BOOLEAN response = FALSE, done; in_confirm = TRUE; oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); SetContextClipRect (NULL_PTR); r.extent.width = CONFIRM_WIN_WIDTH + 4; r.extent.height = CONFIRM_WIN_HEIGHT + 4; r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1; r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1; s.origin = r.corner; F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0)); SetSystemRect (&r); DrawConfirmationWindow (response); // Releasing the lock lets the rotate_planet_task // draw a frame. PauseRotate can still allow one more frame // to be drawn, so it is safer to just not release the lock //UnlockMutex (GraphicsLock); FlushGraphics (); //LockMutex (GraphicsLock); GLOBAL (CurrentActivity) |= CHECK_ABORT; FlushInput (); done = FALSE; do { // Forbid recursive calls or pausing here! ExitRequested = FALSE; GamePaused = FALSE; UpdateInputState (); if (PulsedInputState.menu[KEY_MENU_SELECT]) { done = TRUE; PlayMenuSound (MENU_SOUND_SUCCESS); } else if (PulsedInputState.menu[KEY_MENU_CANCEL]) { done = TRUE; response = FALSE; } else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]) { response = !response; DrawConfirmationWindow (response); PlayMenuSound (MENU_SOUND_MOVE); } TaskSwitch (); } while (!done); s.frame = F; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); ClearSystemRect (); if (response) { result = TRUE; } else { result = FALSE; GLOBAL (CurrentActivity) &= ~CHECK_ABORT; } ExitRequested = FALSE; GamePaused = FALSE; FlushInput (); SetContextClipRect (&oldRect); SetContext (oldContext); } UnlockMutex (GraphicsLock); if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && !(LastActivity & CHECK_RESTART)) ResumeGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) { ResumeTrack (); if (CommData.AlienTransitionDesc.AnimFlags & TALK_DONE) do_subtitles ((void *)~0); } in_confirm = FALSE; return (result); }
void DoPopupWindow(const char *msg) { stringbank *bank = StringBank_Create (); const char *lines[30]; WIDGET_LABEL label; RECT r; STAMP s; FRAME F; CONTEXT oldContext; RECT oldRect; POPUP_STATE state; MENU_SOUND_FLAGS s0, s1; if (!bank) { log_add (log_Fatal, "FATAL: Memory exhaustion when preparing popup window"); exit (EXIT_FAILURE); } label.tag = WIDGET_TYPE_LABEL; label.parent = NULL; label.handleEvent = Widget_HandleEventIgnoreAll; label.receiveFocus = Widget_ReceiveFocusRefuseFocus; label.draw = Widget_DrawLabel; label.height = Widget_HeightLabel; label.width = Widget_WidthFullScreen; label.line_count = SplitString (msg, '\n', 30, lines, bank); label.lines = lines; LockMutex (GraphicsLock); oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); SetContextClipRect (NULL_PTR); /* TODO: Better measure of dimensions than this */ r.extent.width = SCREEN_WIDTH; r.extent.height = SCREEN_HEIGHT; r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1; r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1; F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0)); s.origin = r.corner; s.frame = F; DrawLabelAsWindow (&label); GetMenuSounds (&s0, &s1); SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); state.InputFunc = DoPopup; DoInput (&state, TRUE); DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); FlushInput (); SetContextClipRect (&oldRect); SetContext (oldContext); UnlockMutex (GraphicsLock); SetMenuSounds (s0, s1); StringBank_Free (bank); }