/** * @(#)UnrollTransition.java * @version 1.51 04/06/97 * @author Robert Temple (robertt@starwave.com) */ import java.awt.image.MemoryImageSource; import java.awt.*; import java.util.Hashtable; /** * The UnrollTransition class changes one image into another by setting a roll * which is the new image on top of the old image, and then unrolling the new * image until it covers the old image. */ public class UnrollTransition extends BillTransition { // Static Members /** * The total number of CELLS this transition will show on the screen before * the new image is shown in its entirety */ final static int CELLS = 9; /** array of three pixels used to fill in the right hand side of the roll */ static int fill_pixels[] = { 0xFFFFFFFF, 0xFF000000, 0xFF000000, 0xFFFFFFFF }; /** * Creates a unroll array used later to create cells. * This array is used to determine how many verticle pixels to unroll * the image for each cell. */ private static int[] createUnrollAmountArray(int cell_h) { // The First line of the statement below determines that average // amount each cell must unroll the image in order to completely // unroll the image during the transition. Note that we add one // to the CELLS count because the drawing of the whole next // image to the screen is part of the unrolling process too. // the second line determines the location the across the x-axis // that this average will fall if the first cell starts at a // x point of 1. This is why one more is added to cells // then the top. // The divide determines the slope of the line from (0,0) to // (x_avg, y_avg) // if you are confused here, don't worry, so was I... but // it works... float unroll_increment = ((float)cell_h / (float)(CELLS + 1)) / ((float)(CELLS + 2) / 2.0f); int total = 0; int unroll_amount[] = new int[CELLS + 1]; for(int u = 0; u <= CELLS; ++u) { unroll_amount[u] = (int)(unroll_increment * (CELLS - u + 1)); total += unroll_amount[u]; } // make sure we did not round our way to unrolling more of the // image then there is to unroll if(total < 0) { unroll_amount[0] -= 1; } return unroll_amount; } /** * An array which holds the amount of verticle pixels to unroll the image * each cell. */ int[] unroll_amount; // Instance Members /** The index into the work_pixel array that the start of the roll is at */ int location; /** * Used to initialize the transition right after it is created. * creates cells * @param owner the component to be used to create images from cells */ public void init(Component owner, int[] current, int[] next) { init(owner, current, next, CELLS, 220); location = pixels_per_cell; System.arraycopy((Object)current_pixels, 0, (Object)work_pixels, 0, pixels_per_cell); // get the random array for an applet of this height from the object table. unroll_amount = (int[])object_table.get(getClass().getName() + cell_h); // if the random array is not found, create it and put it in the // object table. if(unroll_amount == null) { unroll_amount = createUnrollAmountArray(cell_h); object_table.put(getClass().getName() + cell_h, unroll_amount); } for(int c = 0; c < CELLS; ++c) { // unroll the image location -= unroll_amount[c] * cell_w; // give other threads a shot at the CPU try { Thread.sleep(150); } catch (InterruptedException e) {} // create the next cell Unroll(c); // give other threads a shot at the CPU try { Thread.sleep(100); } catch (InterruptedException e) {} // create the new cell image from the work pixels createCellFromWorkPixels(c); // copy over the new image onto where the roll last appeared System.arraycopy((Object)next_pixels, location, (Object)work_pixels, location, unroll_amount[c] * cell_w); } // we don't need the work pixels anymore work_pixels = null; } /** * Create the next cell in the work pixel array */ void Unroll(int c) { int y_flip = cell_w; // the offset is what makes the roll appear to be raised up int offset[] = new int[unroll_amount[c]]; for(int o = 0; o < unroll_amount[c]; ++o) { offset[o] = 4; } offset[0] = 2; if(unroll_amount[c] > 1) { offset[1] = 3; } if(unroll_amount[c] > 2) { offset[unroll_amount[c] - 1] = 2; } if(unroll_amount[c] > 3) { offset[unroll_amount[c] - 2] = 3; } int offset_index = 0; int end_location = location + unroll_amount[c] * cell_w; for(int p = location; p < end_location; p += cell_w) { System.arraycopy((Object)next_pixels, p - y_flip + offset[offset_index], (Object)work_pixels, p, cell_w - offset[offset_index]); // draw in the right side of the roll System.arraycopy((Object)fill_pixels, 0, (Object)work_pixels, p + cell_w - offset[offset_index], offset[offset_index]); ++offset_index; y_flip += cell_w + cell_w; } // cheesy way but kinda fast to make the roll appear more 3D. for(int x = location + cell_w - 1; x > location; --x) { work_pixels[x] |= 0xFFAAAAAA; work_pixels[x + unroll_amount[c]] &= 0xFF555555; } } }