/*************************************************************** HEADER FILE CODE **************************************************************/ /*************************************************************** This program was created by Timothy Fox on January 29, 2002 My email: special_effect.geo@yahoo.com My website: www.geocities.com/hollywood/theater/1991 **************************************************************/ #ifndef _STAR_FIELD #define _STAR_FIELD //widescreen format 2700x1149 pixels #define STARFIELD_IMAGE_HEIGHT 1149 //image height in pixels #define STARFIELD_IMAGE_WIDTH 2700 //image width in pixels // 2000 stars creates a very dense starfield #define NUMBER_STARS 2000 //number of stars we produce #define XSMALL 0 #define SMALL 1 #define LARGE 3 #define MEDIUM 2 #define XLARGE 4 #ifdef _STAR_FIELD_DECLARE //where do we store the output starfield? char output_starfield_filename[] = "Krusty:starfields:starfield.out"; //percents of 100 of the total for each star size to create. Array element 0 is //the XSmall size up through array element 4 which is XLarge sized stars float star_percents[5] = { 0.15, 0.4, 0.25, 0.1, 0.1 }; unsigned char **output_starfield_image = NULL; //the 3D array which holds the actual images of each star at each size unsigned char stars_array[5][8][8] = { {{1,1,1,1,1,1,1,1}, //XSmall star {1,1,1,1,1,1,1,1}, {1,1,46,46,46,1,1,1}, {1,1,46,255,46,1,1,1}, {1,1,46,46,46,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}}, {{1,1,1,1,1,1,1,1}, //Small star {1,1,1,1,1,1,1,1}, {1,1,46,134,134,46,1,1}, {1,1,134,255,255,134,1,1}, {1,1,134,255,255,134,1,1}, {1,1,46,134,134,46,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}}, {{1,1,1,1,1,1,1,1}, //Medium star {1,1,46,134,46,1,1,1}, {1,46,134,255,134,46,1,1}, {1,134,255,255,255,134,1,1}, {1,46,134,255,134,46,1,1}, {1,1,46,134,46,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}}, {{1,1,1,30,1,1,1,1}, //Large star {1,34,134,202,134,34,1,1}, {1,134,255,255,255,134,1,1}, {30,202,255,255,255,202,30,1}, {1,134,255,255,255,134,1,1}, {1,34,134,202,134,34,1,1}, {1,1,1,30,1,1,1,1}, {1,1,1,1,1,1,1,1}}, {{1,1,1,20,20,1,1,1}, //XLarge star {1,36,117,192,192,117,36,1}, {1,117,255,255,255,255,117,1}, {21,192,255,255,255,255,192,21}, {21,192,255,255,255,255,192,21}, {1,117,255,255,255,255,117,1}, {1,36,117,192,192,117,36,1}, {1,1,1,20,20,1,1,1}} }; #else extern unsigned char stars_array[5][8][8]; extern float star_percents[5]; extern char output_starfield_filename[]; extern unsigned char **output_starfield_image; #endif /* _STAR_FIELD_DECLARE */ #endif /* _STAR_FIELD */ /*************************************************************** SOURCE FILE CODE **************************************************************/ #define _STAR_FIELD_DECLARE #include "stdio.h" #include "stdlib.h" #include "fcntl.h" #include "time.h" #include "star_field.h" void main() { FILE *output_ptr = NULL; int n_written, row, col, row_coord, col_coord, r,c, starfield_row, starfield_col; int found_star_location, star, number_stars_to_create, star_size; if (STARFIELD_IMAGE_HEIGHT * STARFIELD_IMAGE_WIDTH > 1000*1000*100) { printf("Your starfield is larger than 100MB in size.\n"); exit(1); } //get 2D array space to hold our entire output starfield image printf("Getting the starfield image array space...\n"); output_starfield_image = (unsigned char **) malloc(sizeof(unsigned char *) * STARFIELD_IMAGE_HEIGHT); output_starfield_image[0] = (unsigned char *) malloc(sizeof(unsigned char) * (STARFIELD_IMAGE_HEIGHT * STARFIELD_IMAGE_WIDTH)); //assign the pointer array to point to the various rows of the array for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++) output_starfield_image[row] = output_starfield_image[0] + (row*STARFIELD_IMAGE_WIDTH); //make sure the output starfield image starts out all black printf("Blacking out the starfield image...\n"); for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++) for(col=0; col < STARFIELD_IMAGE_WIDTH; col++) output_starfield_image[row][col] = 0; //now lets create all the stars in the image //first we initialize our random number generator srand((unsigned) time(NULL)); printf("Placing stars in the starfield image...\n"); //lets process stars from extra small up to extra large for (star_size = XSMALL; star_size < = XLARGE; star_size++) { //how many stars should we create for the selected star size number_stars_to_create = star_percents[star_size] * NUMBER_STARS; //lets try to create the required number of stars of the selected size for (star = 1; star < = number_stars_to_create; star++) { //we start by saying we haven't yet found the stars location on the image found_star_location = 0; //while we have not yet found the stars ending location while (!found_star_location) { //lets figure out where the star should be placed col_coord = (rand() % (STARFIELD_IMAGE_WIDTH - 5)); row_coord = (rand() % (STARFIELD_IMAGE_HEIGHT - 4)); //is the stars center location off the images left or top edges? //if so then lets find another location for the star if ((col_coord < 3) || (row_coord < 4)) continue; //now lets figure out if we have already placed another star at this location //if so lets select another location if ((output_starfield_image[row_coord-4][col_coord-3] > 0) || //top left (output_starfield_image[row_coord-4][col_coord+4] > 0) || //top right (output_starfield_image[row_coord+3][col_coord-3] > 0) || //bottom left (output_starfield_image[row_coord+3][col_coord+4] > 0)) //bottom right continue; found_star_location = 1; //otherwise we have found a new star location //now lets plop a new star into the starfield for (starfield_row = row_coord-4, r=0; starfield_row < = row_coord + 3; starfield_row++, r++) for (starfield_col = col_coord-3, c=0; starfield_col < = col_coord + 4; starfield_col++, c++) output_starfield_image[starfield_row][starfield_col] = stars_array[star_size][r][c]; } } } printf("Searching starfield image for flag pixels to return to black...\n"); //now lets go through the entire image and return pixel values of 1 back to 0 for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++) for(col=0; col < STARFIELD_IMAGE_WIDTH; col++) if (output_starfield_image[row][col] == 1) output_starfield_image[row][col] = 0; //now lets write our starfield out to disk output_ptr = fopen(output_starfield_filename, "wb"); //open an output file if (output_ptr == NULL) { free(output_starfield_image[0]); free(output_starfield_image); return; } printf("Writing output starfield file %s...\n", output_starfield_filename); //go through the starfield array and output each row of the image for (row=0; row < STARFIELD_IMAGE_HEIGHT; row++) { //write a row of the image out to the disk file n_written = fwrite((void *) &(output_starfield_image[row][0]), sizeof(unsigned char), STARFIELD_IMAGE_WIDTH, output_ptr); //were we successful at writing out the correct number of pixels? if (n_written != STARFIELD_IMAGE_WIDTH) { printf("wrong number of starfield column pixels written to disk\n"); printf("row %d (base 0), number of columns attemped = %d\n", row, n_written); fclose(output_ptr); free(output_starfield_image[0]); free(output_starfield_image); return; } } fclose(output_ptr); output_ptr = NULL; free(output_starfield_image[0]); //free the pixel array free(output_starfield_image); //free the pointer array printf("The program has finished.\n"); }