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 (); }
// Auxiliary function for DrawFileStrings // If drawShips is set the ships themselves are drawn, in addition to the // fleet name and value; if not, only the fleet name and value are drawn. // If highlite is set the text is drawn in the color used for highlighting. static void DrawFileString (const MeleeTeam *team, const POINT *origin, BOOLEAN drawShips, BOOLEAN highlite) { SetContextForeGroundColor (highlite ? LOAD_TEAM_NAME_TEXT_COLOR_HILITE : LOAD_TEAM_NAME_TEXT_COLOR); // Print the name of the fleet { TEXT Text; Text.baseline = *origin; Text.align = ALIGN_LEFT; Text.pStr = MeleeTeam_getTeamName(team); Text.CharCount = (COUNT)~0; font_DrawText (&Text); } // Print the value of the fleet { TEXT Text; UNICODE buf[60]; sprintf (buf, "%u", MeleeTeam_getValue (team)); Text.baseline = *origin; Text.baseline.x += NUM_MELEE_COLUMNS * (LOAD_MELEE_BOX_WIDTH + LOAD_MELEE_BOX_SPACE) - 1; Text.align = ALIGN_RIGHT; Text.pStr = buf; Text.CharCount = (COUNT)~0; font_DrawText (&Text); } // Draw the ships for the fleet if (drawShips) { STAMP s; FleetShipIndex slotI; s.origin.x = origin->x + RES_SCALE(1); // JMS_GFX s.origin.y = origin->y + RES_STAT_SCALE(4); // JMS_GFX for (slotI = 0; slotI < MELEE_FLEET_SIZE; slotI++) { BYTE StarShip; StarShip = team->ships[slotI]; if (StarShip != MELEE_NONE) { s.frame = GetShipIconsFromIndex (StarShip); DrawStamp (&s); s.origin.x += RES_SCALE(17); // JMS_GFX } } } }
// Pre: called does not hold the graphics lock static void PickMelee_ChangedSelection (GETMELEE_STATE *gms, COUNT playerI) { RECT r; r.corner.x = PICK_X_OFFS + ((ICON_WIDTH + RES_SCALE(2)) * gms->player[playerI].col); // JMS_GFX r.corner.y = PICK_Y_OFFS + ((ICON_HEIGHT + RES_SCALE(2)) * gms->player[playerI].row) // JMS_GFX + ((1 - playerI) * PICK_SIDE_OFFS); r.extent.width = (ICON_WIDTH + RES_SCALE(2)); r.extent.height = (ICON_HEIGHT + RES_SCALE(2)); Flash_setRect (gms->player[playerI].flashContext, &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 (); }
// Pre: caller holds the graphics lock. static void DrawPickMeleeFrame (COUNT which_player) { CONTEXT oldContext; STAMP s; oldContext = SetContext (SpaceContext); s.frame = SetAbsFrameIndex (PickMeleeFrame, which_player); s.origin.x = PICK_X_OFFS - RES_SCALE(3); // JMS_GFX s.origin.y = PICK_Y_OFFS - RES_SCALE(9) + ((1 - which_player) * PICK_SIDE_OFFS); DrawStamp (&s); // Draw the selection box to screen. SetContext (oldContext); }
static COUNT initialize_test_pump_up (ELEMENT *ShipPtr, HELEMENT PumpUpArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; //ELEMENT *PumpUpPtr; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = MELNORME_OFFSET; MissileBlock.speed = RES_SCALE(PUMPUP_SPEED); MissileBlock.hit_points = PUMPUP_DAMAGE; MissileBlock.damage = PUMPUP_DAMAGE; MissileBlock.life = PUMPUP_LIFE; MissileBlock.preprocess_func = 0; MissileBlock.blast_offs = 0; PumpUpArray[0] = initialize_missile (&MissileBlock); return (1); }
RACE_DESC* init_melnorme (void) { RACE_DESC *RaceDescPtr; if (RESOLUTION_FACTOR == HD) { melnorme_desc.characteristics.max_thrust = RES_SCALE(MAX_THRUST); melnorme_desc.characteristics.thrust_increment = RES_SCALE(THRUST_INCREMENT); melnorme_desc.cyborg_control.WeaponRange = PUMPUP_SPEED_HD * PUMPUP_LIFE; } melnorme_desc.postprocess_func = melnorme_postprocess; melnorme_desc.init_weapon_func = initialize_pump_up; melnorme_desc.cyborg_control.intelligence_func = melnorme_intelligence; RaceDescPtr = &melnorme_desc; return (RaceDescPtr); }
// Cross out the icon for the dead ship. // 'frame' is the PickMeleeFrame for the player. // 'shipI' is the index in the ship list. // Pre: caller holds the graphics lock. static void CrossOutShip (FRAME frame, COUNT shipNr) { CONTEXT OldContext; STAMP s; BYTE row = PickMelee_GetShipRow (shipNr); BYTE col = PickMelee_GetShipColumn (shipNr); OldContext = SetContext (OffScreenContext); SetContextFGFrame (frame); s.origin.x = RES_SCALE(3) + ((ICON_WIDTH + RES_SCALE(2)) * col); // JMS_GFX s.origin.y = RES_SCALE(9) + ((ICON_HEIGHT + RES_SCALE(2)) * row); // JMS_GFX s.frame = SetAbsFrameIndex (StatusFrame, 3); // Cross for through the ship image. DrawStamp (&s); SetContext (OldContext); }
static COUNT initialize_horn (ELEMENT *ShipPtr, HELEMENT HornArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = THRADDASH_OFFSET; MissileBlock.speed = RES_SCALE(MISSILE_SPEED); MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; HornArray[0] = initialize_missile (&MissileBlock); return (1); }
// Draw the value of the fleet in the top right of the PickMeleeFrame. // Pre: caller holds the graphics lock. static void UpdatePickMeleeFleetValue (FRAME frame, COUNT which_player) { CONTEXT OldContext; COUNT value; RECT r; TEXT t; UNICODE buf[40]; value = GetRaceQueueValue (&race_q[which_player]); OldContext = SetContext (OffScreenContext); SetContextFGFrame (frame); // Erase the old value text. GetFrameRect (frame, &r); r.extent.width -= RES_SCALE(4); t.baseline.x = r.extent.width; r.corner.x = r.extent.width - RES_SCALE(6 * 3); // JMS_GFX r.corner.y = RES_SCALE(2); // JMS_GFX r.extent.width = RES_SCALE(6 * 3); // JMS_GFX r.extent.height = RES_SCALE(7 - 2) + RESOLUTION_FACTOR; // JMS_GFX SetContextForeGroundColor (PICK_BG_COLOR); DrawFilledRectangle (&r); // Draw the new value text. sprintf (buf, "%d", value); t.baseline.y = RES_SCALE(7); t.align = ALIGN_RIGHT; t.pStr = buf; t.CharCount = (COUNT)~0; SetContextFont (TinyFont); SetContextForeGroundColor (PICK_VALUE_COLOR); font_DrawText (&t); SetContext (OldContext); }
static BOOLEAN DoConvSummary (SUMMARY_STATE *pSS) { #define DELTA_Y_SUMMARY RES_SCALE(8) // JMS_GFX //#define MAX_SUMM_ROWS ((SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT) / DELTA_Y_SUMMARY #define MAX_SUMM_ROWS (SLIDER_Y / DELTA_Y_SUMMARY) - 1 // JMS_GFX if (!pSS->Initialized) { pSS->PrintNext = TRUE; pSS->NextSub = GetFirstTrackSubtitle (); pSS->LeftOver = NULL; pSS->InputFunc = DoConvSummary; pSS->Initialized = TRUE; DoInput (pSS, FALSE); } else if (GLOBAL (CurrentActivity) & CHECK_ABORT) { return FALSE; // bail out } else if (PulsedInputState.menu[KEY_MENU_SELECT] || PulsedInputState.menu[KEY_MENU_CANCEL] || PulsedInputState.menu[KEY_MENU_RIGHT]) { if (pSS->NextSub) { // we want the next page pSS->PrintNext = TRUE; } else { // no more, we are done return FALSE; } } else if (pSS->PrintNext) { // print the next page RECT r; TEXT t; int row; r.corner.x = 0; r.corner.y = 0; r.extent.width = SIS_SCREEN_WIDTH; r.extent.height = SLIDER_Y; //SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT + RES_SCALE(2) + 16 * RESOLUTION_FACTOR; // JMS_GFX SetContext (AnimContext); SetContextForeGroundColor (COMM_HISTORY_BACKGROUND_COLOR); DrawFilledRectangle (&r); SetContextForeGroundColor (COMM_HISTORY_TEXT_COLOR); r.extent.width -= 2 + 2; t.baseline.x = RES_SCALE(2); // JMS_GFX t.align = ALIGN_LEFT; t.baseline.y = DELTA_Y_SUMMARY; SetContextFont (TinyFont); for (row = 0; row < MAX_SUMM_ROWS && pSS->NextSub; ++row, pSS->NextSub = GetNextTrackSubtitle (pSS->NextSub)) { const char *next = NULL; if (pSS->LeftOver) { // some text left from last subtitle t.pStr = pSS->LeftOver; pSS->LeftOver = NULL; } else { t.pStr = GetTrackSubtitleText (pSS->NextSub); if (!t.pStr) continue; } t.CharCount = (COUNT)~0; for ( ; row < MAX_SUMM_ROWS && !getLineWithinWidth (&t, &next, r.extent.width, (COUNT)~0); ++row) { if (CommData.AlienConv == ORZ_CONVERSATION) { // MB: nasty hack: remove '$'s from conversation for Orz UNICODE my_copy[128]; strcpy(my_copy, t.pStr); remove_char_from_string(my_copy, '$'); t.pStr = my_copy; font_DrawText(&t); } else { // Normal mode font_DrawText(&t); } t.baseline.y += DELTA_Y_SUMMARY; t.pStr = next; t.CharCount = (COUNT)~0; } if (row >= MAX_SUMM_ROWS) { // no more space on screen, but some text left over // from the current subtitle pSS->LeftOver = next; break; } // this subtitle fit completely if (CommData.AlienConv == ORZ_CONVERSATION) { // MB: nasty hack: remove '$'s from conversation for Orz UNICODE my_copy[128]; strcpy(my_copy, t.pStr); remove_char_from_string(my_copy, '$'); t.pStr = my_copy; font_DrawText(&t); } else { // Normal mode font_DrawText(&t); } t.baseline.y += DELTA_Y_SUMMARY; } if (row >= MAX_SUMM_ROWS && (pSS->NextSub || pSS->LeftOver)) { // draw *MORE* TEXT mt; UNICODE buffer[128]; mt.baseline.x = SIS_SCREEN_WIDTH >> 1; mt.baseline.y = t.baseline.y; mt.align = ALIGN_CENTER; snprintf (buffer, sizeof (buffer), "%s%s%s", // "MORE" STR_MIDDLE_DOT, GAME_STRING (FEEDBACK_STRING_BASE + 1), STR_MIDDLE_DOT); if (CommData.AlienConv == ORZ_CONVERSATION) { // MB: nasty hack: remove '$'s from conversation for Orz remove_char_from_string(buffer, '$'); } mt.pStr = buffer; SetContextForeGroundColor (COMM_MORE_TEXT_COLOR); font_DrawText (&mt); }
// 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); }
// 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 (); }
// Put the ship icons in the PickMeleeFrame, and create a queue // for each player. // XXX TODO: split off creating the queue into a separate function. void FillPickMeleeFrame (MeleeSetup *setup) { COUNT i; CONTEXT OldContext; OldContext = SetContext (OffScreenContext); for (i = 0; i < NUM_SIDES; ++i) { COUNT side; COUNT sideI; RECT r; TEXT t; STAMP s; UNICODE buf[30]; FleetShipIndex index; sideI = GetPlayerOrder (i); side = !sideI; s.frame = SetAbsFrameIndex (PickMeleeFrame, side); SetContextFGFrame (s.frame); GetFrameRect (s.frame, &r); t.baseline.x = r.extent.width >> 1; t.baseline.y = r.extent.height - NAME_AREA_HEIGHT + RES_SCALE(4); r.corner.x += RES_SCALE(2); r.corner.y += RES_SCALE(2); r.extent.width -= RES_SCALE((2 * 2) + (RES_DESCALE(ICON_WIDTH) + 2) + 1); // JMS_GFX r.extent.height -= RES_SCALE(2 * 2) + NAME_AREA_HEIGHT; // JMS_GFX SetContextForeGroundColor (PICK_BG_COLOR); DrawFilledRectangle (&r); r.corner.x += RES_SCALE(2); // JMS_GFX r.extent.width += RES_SCALE((RES_DESCALE(ICON_WIDTH) + 2) - (2 * 2)); // JMS_GFX r.corner.y += r.extent.height; r.extent.height = NAME_AREA_HEIGHT; DrawFilledRectangle (&r); // Team name at the bottom of the frame: t.align = ALIGN_CENTER; t.pStr = MeleeSetup_getTeamName (setup, sideI); t.CharCount = (COUNT) ~0; SetContextFont (TinyFont); SetContextForeGroundColor (PICKSHIP_TEAM_NAME_TEXT_COLOR); font_DrawText (&t); // Total team value of the starting team: sprintf (buf, "%u", MeleeSetup_getFleetValue (setup, sideI)); t.baseline.x = RES_SCALE(4); t.baseline.y = RES_SCALE(7); t.align = ALIGN_LEFT; t.pStr = buf; t.CharCount = (COUNT)~0; SetContextForeGroundColor (PICKSHIP_TEAM_START_VALUE_COLOR); font_DrawText (&t); assert (CountLinks (&race_q[side]) == 0); for (index = 0; index < MELEE_FLEET_SIZE; index++) { MeleeShip StarShip; StarShip = MeleeSetup_getShip (setup, sideI, index); if (StarShip == MELEE_NONE) continue; { BYTE row, col; BYTE ship_cost; HMASTERSHIP hMasterShip; HSTARSHIP hBuiltShip; MASTER_SHIP_INFO *MasterPtr; STARSHIP *BuiltShipPtr; BYTE captains_name_index; hMasterShip = GetStarShipFromIndex (&master_q, StarShip); MasterPtr = LockMasterShip (&master_q, hMasterShip); captains_name_index = NameCaptain (&race_q[side], MasterPtr->SpeciesID); hBuiltShip = Build (&race_q[side], MasterPtr->SpeciesID); // Draw the icon. row = PickMelee_GetShipRow (index); col = PickMelee_GetShipColumn (index); s.origin.x = RES_SCALE(4) + ((ICON_WIDTH + RES_SCALE(2)) * col); // JMS_GFX s.origin.y = RES_SCALE(10) + ((ICON_HEIGHT + RES_SCALE(2)) * row); s.frame = MasterPtr->ShipInfo.icons; DrawStamp (&s); ship_cost = MasterPtr->ShipInfo.ship_cost; UnlockMasterShip (&master_q, hMasterShip); BuiltShipPtr = LockStarShip (&race_q[side], hBuiltShip); BuiltShipPtr->index = index; BuiltShipPtr->ship_cost = ship_cost; BuiltShipPtr->playerNr = side; BuiltShipPtr->captains_name_index = captains_name_index; // The next ones are not used in Melee BuiltShipPtr->crew_level = 0; BuiltShipPtr->max_crew = 0; BuiltShipPtr->race_strings = 0; BuiltShipPtr->icons = 0; BuiltShipPtr->RaceDescPtr = 0; UnlockStarShip (&race_q[side], hBuiltShip); } } } SetContext (OldContext); }
BOOLEAN CalculateGravity (ELEMENT *ElementPtr) { BOOLEAN retval, HasGravity; HELEMENT hTestElement, hSuccElement; retval = FALSE; HasGravity = (BOOLEAN)(CollidingElement (ElementPtr) && GRAVITY_MASS (ElementPtr->mass_points + 1)); for (hTestElement = GetHeadElement (); hTestElement != 0; hTestElement = hSuccElement) { BOOLEAN TestHasGravity; ELEMENT *TestElementPtr; LockElement (hTestElement, &TestElementPtr); if (TestElementPtr != ElementPtr && CollidingElement (TestElementPtr) && (TestHasGravity = GRAVITY_MASS (TestElementPtr->mass_points + 1)) != HasGravity) { COUNT abs_dx, abs_dy; SIZE dx, dy; if (!(ElementPtr->state_flags & PRE_PROCESS)) { dx = ElementPtr->current.location.x - TestElementPtr->current.location.x; dy = ElementPtr->current.location.y - TestElementPtr->current.location.y; } else { dx = ElementPtr->next.location.x - TestElementPtr->next.location.x; dy = ElementPtr->next.location.y - TestElementPtr->next.location.y; } #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) { log_add (log_Debug, "CalculateGravity:"); log_add (log_Debug, "\tdx = %d, dy = %d", dx, dy); } #endif /* DEBUG_GRAVITY */ dx = WRAP_DELTA_X (dx); dy = WRAP_DELTA_Y (dy); #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) log_add (log_Debug, "\twrap_dx = %d, wrap_dy = %d", dx, dy); #endif /* DEBUG_GRAVITY */ abs_dx = dx >= 0 ? dx : -dx; abs_dy = dy >= 0 ? dy : -dy; abs_dx = WORLD_TO_DISPLAY (abs_dx); abs_dy = WORLD_TO_DISPLAY (abs_dy); #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) log_add (log_Debug, "\tdisplay_dx = %d, display_dy = %d", abs_dx, abs_dy); #endif /* DEBUG_GRAVITY */ if (abs_dx <= GRAVITY_THRESHOLD && abs_dy <= GRAVITY_THRESHOLD) { DWORD dist_squared; dist_squared = (DWORD)(abs_dx * abs_dx) + (DWORD)(abs_dy * abs_dy); if (dist_squared <= (DWORD)(GRAVITY_THRESHOLD * GRAVITY_THRESHOLD)) { #ifdef NEVER COUNT magnitude; #define DIFUSE_GRAVITY RES_SCALE(175) // JMS_GFX: Because of the ifdef NEVER this is actually never run. Well, changed it for consistency dist_squared += (DWORD)abs_dx * (DIFUSE_GRAVITY << 1) + (DWORD)abs_dy * (DIFUSE_GRAVITY << 1) + ((DWORD)(DIFUSE_GRAVITY * DIFUSE_GRAVITY) << 1); if ((magnitude = (COUNT)((DWORD)(GRAVITY_THRESHOLD * GRAVITY_THRESHOLD) / dist_squared)) == 0) magnitude = 1; #define MAX_MAGNITUDE RES_SCALE(6) // JMS_GFX: Because of the ifdef NEVER this is actually never run. Well, changed it for consistency else if (magnitude > MAX_MAGNITUDE) magnitude = MAX_MAGNITUDE; log_add (log_Debug, "magnitude = %u", magnitude); #endif /* NEVER */ #ifdef DEBUG_GRAVITY if (TestElementPtr->state_flags & PLAYER_SHIP) log_add (log_Debug, "dist_squared = %lu", dist_squared); #endif /* DEBUG_GRAVITY */ if (TestHasGravity) { retval = TRUE; UnlockElement (hTestElement); break; } else { COUNT angle; angle = ARCTAN (dx, dy); DeltaVelocityComponents (&TestElementPtr->velocity, COSINE (angle, WORLD_TO_VELOCITY (RES_SCALE(1))), SINE (angle, WORLD_TO_VELOCITY (RES_SCALE(1)))); // JMS_GFX if (TestElementPtr->state_flags & PLAYER_SHIP) { STARSHIP *StarShipPtr; GetElementStarShip (TestElementPtr, &StarShipPtr); StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED; StarShipPtr->cur_status_flags |= SHIP_IN_GRAVITY_WELL; } } } } } hSuccElement = GetSuccElement (TestElementPtr); UnlockElement (hTestElement); } return (retval); }
static void pump_up_postprocess (ELEMENT *ElementPtr) { if (ElementPtr->state_flags & APPEARING) { ZeroVelocityComponents (&ElementPtr->velocity); } else { HELEMENT hPumpUp; ELEMENT *EPtr; ELEMENT *ShipPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); LockElement (StarShipPtr->hShip, &ShipPtr); initialize_pump_up (ShipPtr, &hPumpUp); DeltaEnergy (ShipPtr, 0); UnlockElement (StarShipPtr->hShip); LockElement (hPumpUp, &EPtr); EPtr->current.image.frame = ElementPtr->current.image.frame; EPtr->turn_wait = ElementPtr->turn_wait; EPtr->thrust_wait = ElementPtr->thrust_wait; if (--EPtr->thrust_wait == 0) { if ((EPtr->turn_wait & ~REVERSE_DIR) < MAX_PUMP - 1) { ++EPtr->turn_wait; EPtr->current.image.frame = SetRelFrameIndex ( EPtr->current.image.frame, NUM_PUMP_ANIMS); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), EPtr); } if (antiCheat(ElementPtr, FALSE)) { EPtr->thrust_wait = 5; } else { EPtr->thrust_wait = LEVEL_COUNTER; } } EPtr->mass_points = EPtr->hit_points = (PUMPUP_DAMAGE << (ElementPtr->turn_wait & ~REVERSE_DIR)); SetElementStarShip (EPtr, StarShipPtr); if (EPtr->thrust_wait & 1) { COUNT frame_index; frame_index = GetFrameIndex (EPtr->current.image.frame); if (((EPtr->turn_wait & REVERSE_DIR) && (frame_index % NUM_PUMP_ANIMS) != 0) || (!(EPtr->turn_wait & REVERSE_DIR) && ((frame_index + 1) % NUM_PUMP_ANIMS) == 0)) { --frame_index; EPtr->turn_wait |= REVERSE_DIR; } else { ++frame_index; EPtr->turn_wait &= ~REVERSE_DIR; } EPtr->current.image.frame = SetAbsFrameIndex ( EPtr->current.image.frame, frame_index); } if (StarShipPtr->cur_status_flags & StarShipPtr->old_status_flags & WEAPON) { StarShipPtr->weapon_counter = WEAPON_WAIT; } else { COUNT angle; EPtr->life_span = PUMPUP_LIFE; EPtr->preprocess_func = pump_up_preprocess; EPtr->postprocess_func = 0; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing); SetVelocityComponents (&EPtr->velocity, COSINE (angle, WORLD_TO_VELOCITY (RES_SCALE(PUMPUP_SPEED))), SINE (angle, WORLD_TO_VELOCITY (RES_SCALE(PUMPUP_SPEED)))); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), EPtr); } UnlockElement (hPumpUp); PutElement (hPumpUp); SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], NO_PRIM); ElementPtr->state_flags |= NONSOLID; } }