void _draw_screen_shape_at_x_y(shape_descriptor shape_id, short x, short y) { // Convert shape to surface SDL_Surface *s = get_shape_surface(shape_id); if (s == NULL) return; // if (draw_surface->format->BitsPerPixel == 8) { // // SDL doesn't seem to be able to handle direct blits between 8-bit surfaces with different cluts // SDL_Surface *s2 = SDL_DisplayFormat(s); // SDL_FreeSurface(s); // s = s2; // } // Setup destination rectangle SDL_Rect dst_rect = {x, y, s->w, s->h}; // Blit the surface SDL_BlitSurface(s, NULL, draw_surface, &dst_rect); if (draw_surface == MainScreenSurface()) MainScreenUpdateRects(1, &dst_rect); // Free the surface SDL_FreeSurface(s); }
void _draw_screen_shape(shape_descriptor shape_id, screen_rectangle *destination, screen_rectangle *source) { // Convert rectangles SDL_Rect src_rect; if (source) { src_rect.x = source->left; src_rect.y = source->top; src_rect.w = source->right - source->left; src_rect.h = source->bottom - source->top; } SDL_Rect dst_rect = {destination->left, destination->top, destination->right - destination->left, destination->bottom - destination->top}; // Convert shape to surface SDL_Surface *s = get_shape_surface(shape_id); if (s == NULL) return; // if (draw_surface->format->BitsPerPixel == 8) { // // SDL doesn't seem to be able to handle direct blits between 8-bit surfaces with different cluts // SDL_Surface *s2 = SDL_DisplayFormat(s); // SDL_FreeSurface(s); // s = s2; // } // Blit the surface SDL_BlitSurface(s, source ? &src_rect : NULL, draw_surface, &dst_rect); if (draw_surface == MainScreenSurface()) MainScreenUpdateRects(1, &dst_rect); // Free the surface SDL_FreeSurface(s); }
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); } } }
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; }
void Shape_Blitter::SDL_Draw(SDL_Surface *dst_surface, const Image_Rect& dst) { if (!dst_surface) return; // load shape into surface if necessary if (!m_surface) { byte *pixelsOut = NULL; SDL_Surface *tmp = get_shape_surface(m_frame, m_coll, &pixelsOut, (m_type == Shape_Texture_Interface) ? -1.0 : 1.0); if (!tmp) return; if (pixelsOut) { m_surface = SDL_ConvertSurfaceFormat(tmp, SDL_PIXELFORMAT_BGRA8888, 0); SDL_FreeSurface(tmp); free(pixelsOut); pixelsOut = NULL; } else if (m_coll == 0 && m_frame >= 12 && m_frame <= 29) { // fix transparency on motion sensor blips SDL_SetColorKey(tmp, SDL_TRUE, 0); m_surface = SDL_ConvertSurfaceFormat(tmp, SDL_PIXELFORMAT_BGRA8888, 0); SDL_FreeSurface(tmp); } else m_surface = tmp; } if (!m_surface) return; if (!m_scaled_surface || m_scaled_surface->w != m_scaled_src.w || m_scaled_surface->h != m_scaled_src.h) { if (m_scaled_surface && (m_scaled_surface != m_surface)) SDL_FreeSurface(m_scaled_surface); if (m_scaled_src.w != m_src.w || m_scaled_src.h != m_src.h) m_scaled_surface = rescale_surface(m_surface, m_scaled_src.w, m_scaled_src.h); else m_scaled_surface = m_surface; if (m_type == Shape_Texture_Wall) { // rotate wall textures SDL_Surface *tmp = rotate_surface(m_scaled_surface, m_scaled_surface->w, m_scaled_surface->h); if (m_scaled_surface != m_surface) SDL_FreeSurface(m_scaled_surface); m_scaled_surface = tmp; } else if (m_type == Shape_Texture_Landscape) { // flip landscapes vertically SDL_Surface *tmp = flip_surface(m_scaled_surface, m_scaled_surface->w, m_scaled_surface->h); if (m_scaled_surface != m_surface) SDL_FreeSurface(m_scaled_surface); m_scaled_surface = tmp; } } if (!m_scaled_surface) return; SDL_Rect r = { crop_rect.x, crop_rect.y, crop_rect.w, crop_rect.h }; SDL_Rect sdst = { dst.x, dst.y, dst.w, dst.h }; SDL_BlitSurface(m_scaled_surface, &r, dst_surface, &sdst); }
void Shape_Blitter::SDL_Draw(SDL_Surface *dst_surface, SDL_Rect& dst) { if (!dst_surface) { return; } // load shape into surface if necessary if (!m_surface) { byte *pixelsOut = NULL; SDL_Surface *tmp = get_shape_surface(m_desc, NONE, &pixelsOut, (m_type == Shape_Texture_Interface) ? -1.0 : 1.0); if (!tmp) { return; } if (pixelsOut) { m_surface = SDL_DisplayFormatAlpha(tmp); SDL_FreeSurface(tmp); free(pixelsOut); pixelsOut = NULL; } else{ m_surface = tmp; } } if (!m_surface) { return; } if (!m_scaled_surface || m_scaled_surface->w != m_scaled_src.w || m_scaled_surface->h != m_scaled_src.h) { if (m_scaled_surface && (m_scaled_surface != m_surface)) { SDL_FreeSurface(m_scaled_surface); } if (m_scaled_src.w != m_src.w || m_scaled_src.h != m_src.h) { m_scaled_surface = rescale_surface(m_surface, m_scaled_src.w, m_scaled_src.h); } else{ m_scaled_surface = m_surface; } if (m_type == Shape_Texture_Wall) { // rotate wall textures SDL_Surface *tmp = rotate_surface(m_scaled_surface, m_scaled_surface->w, m_scaled_surface->h); if (m_scaled_surface != m_surface) { SDL_FreeSurface(m_scaled_surface); } m_scaled_surface = tmp; } else if (m_type == Shape_Texture_Landscape) { // flip landscapes vertically SDL_Surface *tmp = flip_surface(m_scaled_surface, m_scaled_surface->w, m_scaled_surface->h); if (m_scaled_surface != m_surface) { SDL_FreeSurface(m_scaled_surface); } m_scaled_surface = tmp; } } if (!m_scaled_surface) { return; } SDL_Rect r = crop_rect; SDL_BlitSurface(m_scaled_surface, &r, dst_surface, &dst); }