static void update_suit_oxygen( short time_elapsed) { static short delay_time= 0; /* Redraw the oxygen only if the interface is visible and only if enough delay has passed.. */ if(((delay_time-= time_elapsed)<0) || time_elapsed==NONE || interface_state.oxygen_is_dirty) { screen_rectangle *oxygen_rect= get_interface_rectangle(_oxygen_rect); short width, actual_width; short suit_oxygen; suit_oxygen= MIN(current_player->suit_oxygen, PLAYER_MAXIMUM_SUIT_OXYGEN); width= oxygen_rect->right-oxygen_rect->left; actual_width= (suit_oxygen*width)/PLAYER_MAXIMUM_SUIT_OXYGEN; draw_bar(oxygen_rect, actual_width, BUILD_DESCRIPTOR(_collection_interface, _oxygen_bar_right), BUILD_DESCRIPTOR(_collection_interface, _oxygen_bar), BUILD_DESCRIPTOR(_collection_interface, _empty_oxygen_bar)); delay_time= DELAY_TICKS_BETWEEN_OXYGEN_REDRAW; interface_state.oxygen_is_dirty= FALSE; } return; }
/* ---------- private code */ static void update_suit_energy( short time_elapsed) { /* time_elapsed==NONE means force redraw */ if (time_elapsed==NONE || (interface_state.shield_is_dirty)) { screen_rectangle *shield_rect= get_interface_rectangle(_shield_rect); short width= shield_rect->right-shield_rect->left; short actual_width, suit_energy; short background_shape_id, bar_shape_id, bar_top_shape_id; suit_energy = current_player->suit_energy%PLAYER_MAXIMUM_SUIT_ENERGY; if( !suit_energy && current_player->suit_energy==PLAYER_MAXIMUM_SUIT_ENERGY || current_player->suit_energy==2*PLAYER_MAXIMUM_SUIT_ENERGY || current_player->suit_energy==3*PLAYER_MAXIMUM_SUIT_ENERGY) { suit_energy= PLAYER_MAXIMUM_SUIT_ENERGY; } actual_width= (suit_energy*width)/PLAYER_MAXIMUM_SUIT_ENERGY; /* Setup the bars.. */ if(current_player->suit_energy>2*PLAYER_MAXIMUM_SUIT_ENERGY) { background_shape_id= _double_energy_bar; bar_shape_id= _triple_energy_bar; bar_top_shape_id= _triple_energy_bar_right; } else if(current_player->suit_energy>PLAYER_MAXIMUM_SUIT_ENERGY) { background_shape_id= _energy_bar; bar_shape_id= _double_energy_bar; bar_top_shape_id= _double_energy_bar_right; } else { background_shape_id= _empty_energy_bar; bar_shape_id= _energy_bar; bar_top_shape_id= _energy_bar_right; if(current_player->suit_energy<0) actual_width= 0; } draw_bar(shield_rect, actual_width, BUILD_DESCRIPTOR(_collection_interface, bar_top_shape_id), BUILD_DESCRIPTOR(_collection_interface, bar_shape_id), BUILD_DESCRIPTOR(_collection_interface, background_shape_id)); interface_state.shield_is_dirty= FALSE; } return; }
Shape_Blitter::Shape_Blitter(short collection, short texture_index, short texture_type, short clut_index) : m_type(texture_type), m_surface(NULL), m_scaled_surface(NULL), tint_color_r(1.0), tint_color_g(1.0), tint_color_b(1.0), tint_color_a(1.0), rotation(0.0) { m_src.x = m_src.y = m_src.w = m_src.h = 0; m_scaled_src.x = m_scaled_src.y = m_scaled_src.w = m_scaled_src.h = 0; crop_rect.x = crop_rect.y = crop_rect.w = crop_rect.h = 0; m_desc = BUILD_DESCRIPTOR(BUILD_COLLECTION(collection, clut_index), texture_index); byte *pixelsOut = NULL; SDL_Surface *tmp = get_shape_surface(m_desc, NONE, &pixelsOut); if (tmp) { m_src.w = m_scaled_src.w = crop_rect.w = tmp->w; m_src.h = m_scaled_src.h = crop_rect.h = tmp->h; SDL_FreeSurface(tmp); if (pixelsOut) { free(pixelsOut); } } }
static void set_control_panel_texture( struct side_data *side) { struct control_panel_definition *definition= get_control_panel_definition(side->control_panel_type); side->primary_texture.texture= BUILD_DESCRIPTOR(definition->collection, GET_CONTROL_PANEL_STATUS(side) ? definition->active_shape : definition->inactive_shape); return; }
static void draw_message_area( short time_elapsed) { if(time_elapsed==NONE) { _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _network_panel), MESSAGE_AREA_X_OFFSET, MESSAGE_AREA_Y_OFFSET); draw_player_name(); } }
void HUD_SW_Class::update_motion_sensor(short time_elapsed) { if (!(GET_GAME_OPTIONS() & _motion_sensor_does_not_work) && MotionSensorActive) { if (motion_sensor_has_changed() || time_elapsed == NONE) { render_motion_sensor(time_elapsed); ForceUpdate = true; screen_rectangle *r = get_interface_rectangle(_motion_sensor_rect); DrawShapeAtXY(BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_mount), r->left, r->top); } } }
/* ---------- these functions are all used in Vulcan */ boolean shape_is_control_panel( shape_descriptor texture) { boolean is_control_panel= FALSE; short index; for(index= 0; index<NUMBER_OF_CONTROL_PANEL_DEFINITIONS; ++index) { struct control_panel_definition *definition= get_control_panel_definition(index); if(texture==BUILD_DESCRIPTOR(definition->collection, definition->active_shape) || texture==BUILD_DESCRIPTOR(definition->collection, definition->inactive_shape)) { is_control_panel= TRUE; break; } } return is_control_panel; }
void set_interface_microphone_recording_state( boolean state) { #pragma unused (state) #ifdef OBSOLETE const short sounds[]={MICROPHONE_STOP_CLICK_SOUND, MICROPHONE_START_CLICK_SOUND}; const short shapes[]={_mike_button_unpressed, _mike_button_pressed}; screen_rectangle *rectangle= get_interface_rectangle(_microphone_rect); play_local_sound(sounds[state]); if(!game_window_is_full_screen()) { _draw_screen_shape(BUILD_DESCRIPTOR(_collection_interface, shapes[state]), rectangle, NULL); } #endif }
void initialize_game_window( void) { initialize_motion_sensor( BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_mount), BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_virgin_mount), BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_alien), BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_friend), BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_enemy), BUILD_DESCRIPTOR(_collection_interface, _network_compass_shape_nw), MOTION_SENSOR_SIDE_LENGTH); return; }
static void update_motion_sensor( short time_elapsed) { if(!(GET_GAME_OPTIONS() & _motion_sensor_does_not_work)) { if (time_elapsed==NONE) { reset_motion_sensor(current_player_index); } motion_sensor_scan(time_elapsed); if (motion_sensor_has_changed()) { screen_rectangle *destination= get_interface_rectangle(_motion_sensor_rect); _draw_screen_shape_at_x_y(BUILD_DESCRIPTOR(_collection_interface, _motion_sensor_mount), destination->left, destination->top); } } return; }
void PlayerImage::updateLegsDrawingInfo() { // Remove old data, if applicable if(mLegsSurface != NULL) { SDL_FreeSurface(mLegsSurface); mLegsSurface = NULL; } if(mLegsData != NULL) { free(mLegsData); mLegsData = NULL; } mLegsValid = false; // Get the player shape definitions player_shape_definitions* theShapeDefinitions = get_player_shape_definitions(); // tryAgain tells us whether we made any random choices in the loop. If so, a failed effort results in // another trip through the loop (hopefully with different random choices :) ). bool tryAgain = false; // For safety - don't keep looping if we seem not to be finding good data... eventually, give up as invalid. int16 theNumberOfTriesLeft = 100; do { // We're using up one of our attempts... theNumberOfTriesLeft--; // Find the leg action // We use a local here (instead of using the member directly) so we still which things to pick randomly if we loop. int16 theLegsAction = mLegsAction; if(mLegsAction == NONE) { theLegsAction = local_random() % NUMBER_OF_PLAYER_ACTIONS; tryAgain = true; } // If the user fed us a bad value, stop (with invalid data) else if(theLegsAction < 0 || theLegsAction >= NUMBER_OF_PLAYER_ACTIONS) break; // Find the high-level shape index uint16 theLegsHighLevelShapeIndex = theShapeDefinitions->legs[theLegsAction]; // Find out how many animation frames there are for the chosen legs shape_animation_data* theLegsAnimationData = get_shape_animation_data( BUILD_DESCRIPTOR(theShapeDefinitions->collection, theLegsHighLevelShapeIndex)); // If this failed, either give up or try again if(theLegsAnimationData == NULL) continue; // Find a view for the legs int16 theLegsView = mLegsView; if(theLegsView == NONE) { theLegsView = local_random() % 8;//theLegsAnimationData->number_of_views; tryAgain = true; } else if(theLegsView < 0 || theLegsView >= 8) break; // Find an animation frame int16 theLegsFrame = mLegsFrame; if(theLegsFrame == NONE) { theLegsFrame = local_random() % theLegsAnimationData->frames_per_view; tryAgain = true; } else if(theLegsFrame < 0 || theLegsFrame >= theLegsAnimationData->frames_per_view) break; // Calculate the low-level shape index index uint16 theLegsLowLevelShapeIndexIndex = theLegsAnimationData->frames_per_view * theLegsView + theLegsFrame; // Finally, we can look up the low-level shape index uint16 theLegsLowLevelShapeIndex = theLegsAnimationData->low_level_shape_indexes[theLegsLowLevelShapeIndexIndex]; // Find a legs color int16 theLegsColor = mLegsColor; if(theLegsColor == NONE) { theLegsColor = local_random() % 8; tryAgain = true; } else if(theLegsColor < 0 || theLegsColor >= 8) break; low_level_shape_definition *theLegsLowLevelShape = get_low_level_shape_definition(theShapeDefinitions->collection, theLegsLowLevelShapeIndex); if(theLegsLowLevelShape == NULL) continue; // Get the shape surfaces for the given collection, CLUT (according to color/team), and low-level shape index. if (bit_depth == 8) continue; mLegsSurface = get_shape_surface(theLegsLowLevelShapeIndex, BUILD_COLLECTION(theShapeDefinitions->collection, theLegsColor), &mLegsData, mLegsBrightness); if(mLegsSurface == NULL) continue; // Fill in rect information mLegsRect.x = -theLegsLowLevelShape->key_x; mLegsRect.y = -theLegsLowLevelShape->key_y; mLegsRect.w = mLegsSurface->w; mLegsRect.h = mLegsSurface->h; // We're clear. Copy our temporary variables into the data members. mLegsAction = theLegsAction; mLegsView = theLegsView; mLegsFrame = theLegsFrame; mLegsColor = theLegsColor; // We are _valid_. Sweet. mLegsValid = true; // Success - get me outta here! break; } while(tryAgain && theNumberOfTriesLeft > 0); // Valid or not, the legs are no longer dirty. mLegsDirty = false; }
void PlayerImage::updateTorsoDrawingInfo() { // Remove old data, if applicable if(mTorsoSurface != NULL) { SDL_FreeSurface(mTorsoSurface); mTorsoSurface = NULL; } if(mTorsoData != NULL) { free(mTorsoData); mTorsoData = NULL; } mTorsoValid = false; // Get the player shape definitions player_shape_definitions* theShapeDefinitions = get_player_shape_definitions(); // tryAgain tells us whether we made any random choices in the loop. If so, a failed effort results in // another trip through the loop (hopefully with different random choices :) ). bool tryAgain = false; // For safety - don't keep looping if we seem not to be finding good data... eventually, give up as invalid. int16 theNumberOfTriesLeft = 100; do { // We're using up one of our attempts... theNumberOfTriesLeft--; // Find the torso action // We use a local here (instead of using the member directly) so we still which things to pick randomly if we loop. int16 theTorsoAction = mTorsoAction; if(mTorsoAction == NONE) { theTorsoAction = local_random() % PLAYER_TORSO_WEAPON_ACTION_COUNT; tryAgain = true; } // If the user fed us a bad value, stop (with invalid data) else if(theTorsoAction < 0 || theTorsoAction >= PLAYER_TORSO_WEAPON_ACTION_COUNT) break; // Find a torso pseudo-weapon int16 thePseudoWeapon = mPseudoWeapon; if(mPseudoWeapon == NONE) { thePseudoWeapon = local_random() % PLAYER_TORSO_SHAPE_COUNT; tryAgain = true; } else if(thePseudoWeapon < 0 || thePseudoWeapon >= PLAYER_TORSO_SHAPE_COUNT) break; // Find the high-level shape index uint16 theTorsoHighLevelShapeIndex; switch(theTorsoAction) { case _shape_weapon_firing: theTorsoHighLevelShapeIndex = theShapeDefinitions->firing_torsos[thePseudoWeapon]; break; case _shape_weapon_idle: theTorsoHighLevelShapeIndex = theShapeDefinitions->torsos[thePseudoWeapon]; break; case _shape_weapon_charging: theTorsoHighLevelShapeIndex = theShapeDefinitions->charging_torsos[thePseudoWeapon]; break; default: // This staves off a compiler warning theTorsoHighLevelShapeIndex = 0; assert(false); } // Find out how many animation frames there are for the chosen torso shape_animation_data* theTorsoAnimationData = get_shape_animation_data( BUILD_DESCRIPTOR(theShapeDefinitions->collection, theTorsoHighLevelShapeIndex)); // If this failed, either give up or try again if(theTorsoAnimationData == NULL) continue; // Find a view for the torso int16 theTorsoView = mTorsoView; if(theTorsoView == NONE) { theTorsoView = local_random() % 8;//theTorsoAnimationData->number_of_views; tryAgain = true; } else if(theTorsoView < 0 || theTorsoView >= 8) break; // Find an animation frame int16 theTorsoFrame = mTorsoFrame; if(theTorsoFrame == NONE) { theTorsoFrame = local_random() % theTorsoAnimationData->frames_per_view; tryAgain = true; } else if(theTorsoFrame < 0 || theTorsoFrame >= theTorsoAnimationData->frames_per_view) break; // Calculate the low-level shape index index uint16 theTorsoLowLevelShapeIndexIndex = theTorsoAnimationData->frames_per_view * theTorsoView + theTorsoFrame; // Finally, we can look up the low-level shape index uint16 theTorsoLowLevelShapeIndex = theTorsoAnimationData->low_level_shape_indexes[theTorsoLowLevelShapeIndexIndex]; // Find a torso color int16 theTorsoColor = mTorsoColor; if(theTorsoColor == NONE) { theTorsoColor = local_random() % 8; tryAgain = true; } else if(theTorsoColor < 0 || theTorsoColor >= 8) break; low_level_shape_definition *theTorsoLowLevelShape = get_low_level_shape_definition(theShapeDefinitions->collection, theTorsoLowLevelShapeIndex); if(theTorsoLowLevelShape == NULL) continue; // Get the shape surfaces for the given collection, CLUT (according to color/team), and low-level shape index. if (bit_depth == 8) continue; mTorsoSurface = get_shape_surface(theTorsoLowLevelShapeIndex, BUILD_COLLECTION(theShapeDefinitions->collection, theTorsoColor), &mTorsoData, mTorsoBrightness); // Argh, it failed. Why don't we wait for backup? if(mTorsoSurface == NULL) continue; // Fill in rect information mTorsoRect.x = -theTorsoLowLevelShape->origin_x; mTorsoRect.y = -theTorsoLowLevelShape->origin_y; mTorsoRect.w = mTorsoSurface->w; mTorsoRect.h = mTorsoSurface->h; // We're clear. Copy our temporary variables into the data members. mTorsoAction = theTorsoAction; mPseudoWeapon = thePseudoWeapon; mTorsoView = theTorsoView; mTorsoFrame = theTorsoFrame; mTorsoColor = theTorsoColor; // We are _valid_. Sweet. mTorsoValid = true; // Success - get me outta here! break; } while(tryAgain && theNumberOfTriesLeft > 0); // Valid or not, the torso is no longer dirty. mTorsoDirty = false; }
/* A change of weapon has occurred, change the weapon display panel */ static void update_weapon_panel( boolean force_redraw) { if(force_redraw || interface_state.weapon_is_dirty) { char weapon_name[90]; struct weapon_interface_data *definition; screen_rectangle *destination= get_interface_rectangle(_weapon_display_rect); screen_rectangle source; short desired_weapon= get_player_desired_weapon(current_player_index); /* Now we have to erase, because the panel won't do it for us.. */ _fill_rect(destination, _inventory_background_color); if(desired_weapon != NONE) { assert(desired_weapon>=0 && desired_weapon<MAXIMUM_WEAPON_INTERFACE_DEFINITIONS); definition= weapon_interface_definitions+desired_weapon; /* Check if it is a multi weapon - actually special cased for the magnum... */ if(definition->multi_weapon) { #define MAGNUM_DELTA_X 97 if(definition->item_id==_i_magnum) { /* Either way, draw the single */ _draw_screen_shape_at_x_y(definition->weapon_panel_shape, definition->standard_weapon_panel_left, definition->standard_weapon_panel_top); if(current_player->items[definition->item_id]>1) { _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _left_magnum), definition->standard_weapon_panel_left-MAGNUM_DELTA_X, definition->standard_weapon_panel_top); } else { /* Draw the empty one.. */ _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _left_magnum_unusable), definition->standard_weapon_panel_left-MAGNUM_DELTA_X, definition->standard_weapon_panel_top); } } else if(definition->item_id==_i_shotgun) { if(current_player->items[definition->item_id]>1) { _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _double_shotgun), definition->standard_weapon_panel_left, definition->standard_weapon_panel_top-12); } else { _draw_screen_shape_at_x_y(definition->weapon_panel_shape, definition->standard_weapon_panel_left, definition->standard_weapon_panel_top); } } } else { /* Slam it to the screen! */ if(definition->weapon_panel_shape != NONE) { _draw_screen_shape_at_x_y(definition->weapon_panel_shape, definition->standard_weapon_panel_left, definition->standard_weapon_panel_top); } } /* Get the weapon name.. */ if(desired_weapon != _weapon_ball) { #define strWEAPON_NAME_LIST 137 getcstr(weapon_name, strWEAPON_NAME_LIST, desired_weapon); } else { short item_index; /* Which ball do they actually have? */ for(item_index= BALL_ITEM_BASE; item_index<BALL_ITEM_BASE+MAXIMUM_NUMBER_OF_PLAYERS; ++item_index) { if(current_player->items[item_index]>0) break; } assert(item_index != BALL_ITEM_BASE+MAXIMUM_NUMBER_OF_PLAYERS); get_item_name(weapon_name, item_index, FALSE); } /* Draw the weapon name.. */ source= *destination; source.top= definition->weapon_name_start_y; source.bottom= definition->weapon_name_end_y; if(definition->weapon_name_start_x != NONE) { source.left= definition->weapon_name_start_x; } if(definition->weapon_name_end_x != NONE) { source.right= definition->weapon_name_end_x; } _draw_screen_text(weapon_name, &source, _center_horizontal|_center_vertical|_wrap_text, _weapon_name_font, _inventory_text_color); /* And make sure that the ammo knows it needs to update */ interface_state.ammo_is_dirty= TRUE; } interface_state.weapon_is_dirty= FALSE; } }
_i_knife, NONE, 433, 432, NONE, NONE, 0, 0, FALSE, { { _unused_interface_data, 0, 0, 0, 0, 0, 0, NONE, NONE, TRUE}, { _unused_interface_data, 0, 0, 0, 0, 0, 0, NONE, NONE, TRUE} } }, /* Harry, the .44 */ { _i_magnum, BUILD_DESCRIPTOR(_collection_interface, _magnum_panel), 432, 444, 420, NONE, 366, 517, TRUE, { { _uses_bullets, 517, 412, 8, 1, 5, 14, BUILD_DESCRIPTOR(_collection_interface, _magnum_bullet), BUILD_DESCRIPTOR(_collection_interface, _magnum_casing), FALSE}, { _uses_bullets, 452, 412, 8, 1, 5, 14, BUILD_DESCRIPTOR(_collection_interface, _magnum_bullet), BUILD_DESCRIPTOR(_collection_interface, _magnum_casing), TRUE} } }, /* Ripley, the plasma pistol. */ { _i_plasma_pistol, BUILD_DESCRIPTOR(_collection_interface, _zeus_panel), 431, 443,
void Shape_Blitter::OGL_Draw(const Image_Rect& dst) { #ifdef HAVE_OPENGL // Set up texture TextureManager TMgr; TMgr.ShapeDesc = BUILD_DESCRIPTOR(m_coll, 0); TMgr.LowLevelShape = m_frame; extended_get_shape_bitmap_and_shading_table(m_coll, m_frame, &TMgr.Texture, &TMgr.ShadingTables, _shading_normal); TMgr.IsShadeless = false; TMgr.TransferMode = _shadeless_transfer; switch (m_type) { case Shape_Texture_Wall: TMgr.TextureType = OGL_Txtr_Wall; break; case Shape_Texture_Landscape: { TMgr.TextureType = OGL_Txtr_Landscape; LandscapeOptions *LandOpts = View_GetLandscapeOptions(TMgr.ShapeDesc); TMgr.LandscapeVertRepeat = LandOpts->VertRepeat; TMgr.Landscape_AspRatExp = LandOpts->OGL_AspRatExp; } break; case Shape_Texture_Sprite: TMgr.TextureType = OGL_Txtr_Inhabitant; break; case Shape_Texture_WeaponInHand: case Shape_Texture_Interface: TMgr.TextureType = OGL_Txtr_WeaponsInHand; break; } if (!TMgr.Setup()) return; // Get dimensions GLdouble U_Scale = TMgr.U_Scale; GLdouble V_Scale = TMgr.V_Scale; GLdouble U_Offset = TMgr.U_Offset; GLdouble V_Offset = TMgr.V_Offset; // Draw shape if (Wanting_sRGB && TMgr.TextureType != OGL_Txtr_WeaponsInHand) { glEnable(GL_FRAMEBUFFER_SRGB_EXT); Using_sRGB = true; } SglColor4f(tint_color_r, tint_color_g, tint_color_b, tint_color_a); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); TMgr.SetupTextureMatrix(); TMgr.RenderNormal(); bool rotating = (rotation > 0.1 || rotation < -0.1); if (rotating) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef((dst.x + dst.w/2.0), (dst.y + dst.h/2.0), 0.0); glRotatef(rotation, 0.0, 0.0, 1.0); glTranslatef(-(dst.x + dst.w/2.0), -(dst.y + dst.h/2.0), 0.0); } if (m_type == Shape_Texture_Interface) { if (crop_rect.x > 0) U_Offset += crop_rect.x * U_Scale / static_cast<double>(m_scaled_src.w); if (crop_rect.y > 0) V_Offset += crop_rect.y * V_Scale / static_cast<double>(m_scaled_src.h); if (crop_rect.w < m_scaled_src.w) U_Scale *= crop_rect.w / static_cast<double>(m_scaled_src.w); if (crop_rect.h < m_scaled_src.h) V_Scale *= crop_rect.h / static_cast<double>(m_scaled_src.h); OGL_RenderTexturedRect(dst.x, dst.y, dst.w, dst.h, U_Offset, V_Offset, U_Offset + U_Scale, V_Offset + V_Scale); } else if (m_type == Shape_Texture_Landscape) { U_Scale = -TMgr.Texture->width / static_cast<double>(TMgr.Texture->height); U_Offset = 0.5 - U_Scale/2.0; if (crop_rect.x > 0) V_Offset += crop_rect.x * V_Scale / static_cast<double>(m_scaled_src.w); if (crop_rect.y > 0) U_Offset += crop_rect.y * U_Scale / static_cast<double>(m_scaled_src.h); if (crop_rect.w < m_scaled_src.w) V_Scale *= crop_rect.w / static_cast<double>(m_scaled_src.w); if (crop_rect.h < m_scaled_src.h) U_Scale *= crop_rect.h / static_cast<double>(m_scaled_src.h); OGL_RenderTexturedRect(dst.x, dst.y, dst.w, dst.h, V_Offset, U_Offset, V_Offset + V_Scale, U_Offset + U_Scale); } else { shape_information_data *info = extended_get_shape_information(m_coll, m_frame); if (info->flags & _X_MIRRORED_BIT) { V_Offset += V_Scale; V_Scale = -V_Scale; } if (info->flags & _Y_MIRRORED_BIT) { U_Offset += U_Scale; U_Scale = -U_Scale; } if (crop_rect.x > 0) V_Offset += crop_rect.x * V_Scale / static_cast<double>(m_scaled_src.w); if (crop_rect.y > 0) U_Offset += crop_rect.y * U_Scale / static_cast<double>(m_scaled_src.h); if (crop_rect.w < m_scaled_src.w) V_Scale *= crop_rect.w / static_cast<double>(m_scaled_src.w); if (crop_rect.h < m_scaled_src.h) U_Scale *= crop_rect.h / static_cast<double>(m_scaled_src.h); GLfloat texcoords[8] = { U_Offset, V_Offset, U_Offset, V_Offset + V_Scale, U_Offset + U_Scale, V_Offset + V_Scale, U_Offset + U_Scale, V_Offset }; GLfloat vertices[8] = { dst.x, dst.y, dst.x + dst.w, dst.y, dst.x + dst.w, dst.y + dst.h, dst.x, dst.y + dst.h }; glVertexPointer(2, GL_FLOAT, 0, vertices); glTexCoordPointer(2, GL_FLOAT, 0, texcoords); glDrawArrays(GL_POLYGON, 0, 4); } if (rotating) glPopMatrix(); if (TMgr.IsGlowMapped()) TMgr.RenderGlowing(); TMgr.RestoreTextureMatrix(); if (Using_sRGB) { glDisable(GL_FRAMEBUFFER_SRGB_EXT); Using_sRGB = false; } #endif }
short new_projectile( world_point3d *origin, short polygon_index, world_point3d *_vector, angle delta_theta, /* ±¶theta is added (in a circle) to the angle before firing */ short type, short owner_index, short owner_type, short intended_target_index, /* can be NONE */ _fixed damage_scale) { struct projectile_definition *definition; struct projectile_data *projectile; short projectile_index; type= adjust_projectile_type(origin, polygon_index, type, owner_index, owner_type, intended_target_index, damage_scale); definition= get_projectile_definition(type); for (projectile_index= 0, projectile= projectiles; projectile_index<MAXIMUM_PROJECTILES_PER_MAP; ++projectile_index, ++projectile) { if (SLOT_IS_FREE(projectile)) { angle facing, elevation; short object_index; struct object_data *object; facing= arctangent(_vector->x, _vector->y); elevation= arctangent(isqrt(_vector->x*_vector->x+_vector->y*_vector->y), _vector->z); if (delta_theta) { if (!(definition->flags&_no_horizontal_error)) facing= normalize_angle(facing+global_random()%(2*delta_theta)-delta_theta); if (!(definition->flags&_no_vertical_error)) elevation= (definition->flags&_positive_vertical_error) ? normalize_angle(elevation+global_random()%delta_theta) : normalize_angle(elevation+global_random()%(2*delta_theta)-delta_theta); } object_index= new_map_object3d(origin, polygon_index, definition->collection==NONE ? NONE : BUILD_DESCRIPTOR(definition->collection, definition->shape), facing); if (object_index!=NONE) { object= get_object_data(object_index); projectile->type= (definition->flags&_alien_projectile) ? (alien_projectile_override==NONE ? type : alien_projectile_override) : (human_projectile_override==NONE ? type : human_projectile_override); projectile->object_index= object_index; projectile->owner_index= owner_index; projectile->target_index= intended_target_index; projectile->owner_type= owner_type; projectile->flags= 0; projectile->gravity= 0; projectile->ticks_since_last_contrail= projectile->contrail_count= 0; projectile->elevation= elevation; projectile->distance_travelled= 0; projectile->damage_scale= damage_scale; MARK_SLOT_AS_USED(projectile); SET_OBJECT_OWNER(object, _object_is_projectile); object->sound_pitch= definition->sound_pitch; L_Call_Projectile_Created(projectile_index); } else { projectile_index= NONE; } break; } } if (projectile_index==MAXIMUM_PROJECTILES_PER_MAP) projectile_index= NONE; return projectile_index; }