/**************************** pr_helpers.c *************************/ /* * Copyright 1987 by Mark Weiser. * Permission to reproduce and use in any manner whatsoever on Suns is granted * so long as this copyright and other identifying marks of authorship * in the code and the game remain intact and visible. Use of this code * in other products is reserved to me--I'm working on Mac and IBM versions. */ /* These routines are pure pixrect operators, used mostly for city operations */ #include "sdi.h" #include "sdi_color.h" static char tmp_image_place[4096]; mpr_static(helpers_tmp_pr, 64, 64, 8, tmp_image_place); static short pattern[] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; static short *end_of_pattern_ptr = &pattern[16]; #define lefthalf(x) (((x) & 0xff00) >> 8) #define righthalf(x) ((x) & 0xff) /* * Does an incremental melt of old into target, replacing * old, by dropping pixels down until they hit target * pixels. Melts 'speed' pixels per call. * Probably won't work as written for color. */ melt(old, target, speed) Xv_Window old, target; int speed; { if (speed >= 64 || speed <= 0) return; xv_rop(old, 0, speed, 64, 64-speed, PIX_SRC, old, 0, speed); xv_rop(old, 0, 0, 64, 64, PIX_SRC | PIX_DST, target, 0, 0); } static lookup[] = { #include "lookup.h" }; xv_count_pixels(pw, xviewpixel) Xv_Window pw; { int pixelval; xv_read(&helpers_tmp_pr, 0, 0, 64, 64, PIX_SRC, pw, 0, 0); if (use_color) { pixelval = xv_get(sdi_colormap, CMS_PIXEL, xviewpixel); } else { pixelval = 1; } return count_bits(&helpers_tmp_pr, pixelval); } /* * Count the number of bits in a pixrect. */ count_bits(pr, pixelval) struct pixrect *pr; /* should be a memory pixrect for dvc ind. */ { register short x_count, y_count, count, base = 0, num_shorts; struct mpr_data *mpr = mpr_d(pr); if (mpr->md_offset.x != 0 || mpr->md_offset.y != 0) { /* Never leave here */ printf("Can't handle region pixrects in 'count_bits'.\n"); abort(); }; if (pr->pr_depth != 8 && pr->pr_depth != 1) { printf("Can only handle depth 8 or 1 pixrects in 'count_bits'.\n"); abort(); } count = 0; num_shorts = mpr->md_linebytes / 2; for(y_count = 0; y_count < pr->pr_size.y; y_count++) { for (x_count = 0; x_count < num_shorts; x_count += 1) { if (pr->pr_depth == 8) { count += (lefthalf(mpr->md_image[base+x_count]) == pixelval ? 1 : 0); count += (righthalf(mpr->md_image[base+x_count]) == pixelval ? 1 : 0); } else { count += lookup[lefthalf(mpr->md_image[base+x_count])] +lookup[righthalf(mpr->md_image[base+x_count])]; } } base += num_shorts; } return count; } /* * Grow could, and possibly should, be made to work like melt, and * grow only at the edge of black areas, but growing linearly up * from the bottom looks ok too. (Which is not true in revese for melting!). * Unfortunately they are now asymmetrical, because grow needs a 'position' * parameter which says how far from the bottom we are. * * Grow only works for 64x64 bit pixrects (because of hardwired constants), * unlike melt which can melt anything. */ grow(old, target, position) struct pixrect *old, *target; { extern struct pixrect *default_city_pr; if (position < 1 || position > 64) return; xv_rop(old, 0, 64 - position, 64, position, PIX_SRC, target, 0, 64 - position); }