/* * Sift a node down from its current position to satisfy the heap * property. */ static void sift_down(binaryheap *heap, int node_off) { while (true) { int left_off = left_offset(node_off); int right_off = right_offset(node_off); int swap_off = 0; /* Is the left child larger than the parent? */ if (left_off < heap->bh_size && heap->bh_compare(heap->bh_nodes[node_off], heap->bh_nodes[left_off], heap->bh_arg) < 0) swap_off = left_off; /* Is the right child larger than the parent? */ if (right_off < heap->bh_size && heap->bh_compare(heap->bh_nodes[node_off], heap->bh_nodes[right_off], heap->bh_arg) < 0) { /* swap with the larger child */ if (!swap_off || heap->bh_compare(heap->bh_nodes[left_off], heap->bh_nodes[right_off], heap->bh_arg) < 0) swap_off = right_off; } /* * If we didn't find anything to swap, the heap condition is * satisfied, and we're done. */ if (!swap_off) break; /* * Otherwise, swap the node with the child that violates the heap * property; then go on to check its children. */ swap_nodes(heap, swap_off, node_off); node_off = swap_off; } }
// -------------------------------------------------------------------------- // t_combat_object_model_base class // -------------------------------------------------------------------------- t_compound_object_model::t_compound_object_model( t_combat_object_model_24 const& source, double scale ) { t_bitmap_group bitmaps; m_type = source.get_type(); if (scale == 1.0) { bitmaps = t_bitmap_group( source.get_frames() ); } else { t_bitmap_group_24 frames = source.get_frames(); frames.offset( source.get_offset() ); scale_group( frames, bitmaps, scale ); bitmaps.offset( -source.get_offset() ); } int segment_size; m_footprint_size = source.get_footprint_size(); // determine size of subchunks. 1 for passable objects, as large as possible for // others if (source.blocks_movement() || source.is_underlay() || source.get_type() == k_obstacle_special || source.get_type() == k_obstacle_castle_tower) segment_size = greatest_common_divisor( m_footprint_size.row, m_footprint_size.column ); else segment_size = 1; // handle case where this isn't really compound if ((segment_size == m_footprint_size.row && segment_size == m_footprint_size.column) || m_footprint_size.row == 0 || m_footprint_size.column == 0 ) { t_object_segment* segment; segment = new t_object_segment( source, segment_size, t_map_point_2d(0,0), source, bitmaps ); m_segments.push_back( segment ); return; } t_map_point_3d cell_offset(0,0,0); t_screen_rect image_rect = bitmaps.get_rect(); t_screen_point shape_origin; t_screen_point base_point; t_screen_point left_tile_base; t_screen_point right_tile_base; t_screen_point bottom_tile_base; t_bitmap_line line; t_bitmap_line_array lines; int i; int center; int width; int image_width = image_rect.width(); int half_segment_height; int segment_height; t_map_point_2d left_offset( segment_size, 0 ); t_map_point_2d right_offset( 0, segment_size ); t_map_point_2d down_offset( segment_size, segment_size ); // chop image up into segment_size x segment_size chunks cell_offset.height = source.get_height(); for (cell_offset.row = 0; cell_offset.row < m_footprint_size.row; cell_offset.row += segment_size) { for (cell_offset.column = 0; cell_offset.column < m_footprint_size.column; cell_offset.column += segment_size) { // find screen coordinate of top of tile base_point = get_base_point( cell_offset, scale ) - source.get_offset(); left_tile_base = get_base_point( cell_offset + left_offset, scale ) - source.get_offset(); right_tile_base = get_base_point( cell_offset + right_offset, scale ) - source.get_offset(); bottom_tile_base = get_base_point( cell_offset + down_offset, scale ) - source.get_offset(); lines.clear(); shape_origin.x = image_rect.left; center = base_point.x - shape_origin.x; left_tile_base.x -= image_rect.left; right_tile_base.x -= image_rect.left; if (cell_offset.row == 0 && cell_offset.column == 0) { // for the topmost tile only, include all the lines above half the height shape_origin.y = image_rect.top; line.left = 0; line.right = image_width; for (i = shape_origin.y; i < base_point.y; i++) lines.push_back( line ); } else { shape_origin.y = base_point.y; } // create top half of mask half_segment_height = left_tile_base.y - base_point.y; for (i = 0; i < half_segment_height; i++) { width = 2 * (i + 1) * scale; if (cell_offset.column == 0) line.left = 0; else line.left = center - width; if (cell_offset.row == 0) line.right = image_width; else line.right = center + width; lines.push_back( line ); } // create bottom half of mask segment_height = bottom_tile_base.y - base_point.y - half_segment_height; for (i = 0; i < segment_height; i++) { width = 2 * (i + 1) * scale; if (cell_offset.row + segment_size != m_footprint_size.row) line.left = left_tile_base.x + width; else if (cell_offset.column == 0) line.left = 0; else line.left = left_tile_base.x; if (cell_offset.column + segment_size != m_footprint_size.column) line.right = right_tile_base.x - width; else if (cell_offset.row == 0) line.right = image_width; else line.right = right_tile_base.x; lines.push_back( line ); } if (cell_offset.row + segment_size == m_footprint_size.row || cell_offset.column + segment_size == m_footprint_size.column) { if (cell_offset.row + segment_size != m_footprint_size.row) line.left = center; else if (cell_offset.column == 0) line.left = 0; else line.left = left_tile_base.x; if (cell_offset.column + segment_size != m_footprint_size.column) line.right = center; else if (cell_offset.row == 0) line.right = image_width; else line.right = right_tile_base.x; for (i = base_point.y + segment_height + half_segment_height; i < image_rect.bottom; i++) lines.push_back( line ); } t_bitmap_group segment_bitmaps; t_object_segment* segment; copy_bitmaps( bitmaps, segment_bitmaps, shape_origin, lines ); if (segment_bitmaps.get_rect().width() == 0) continue; segment = new t_object_segment( source, segment_size, cell_offset << k_battlefield_subcell_shift, source, segment_bitmaps ); base_point.y += cell_offset.height * scale; segment->set_offset( -base_point ); m_segments.push_back( segment ); } } }