Beispiel #1
0
/* save_indexed:
 *  Core save routine for 8 bpp images.
 * */
static int save_indexed(png_structp png_ptr, BITMAP *bmp)
{
    ASSERT(bitmap_color_depth(bmp) == 8);

    if (is_memory_bitmap(bmp)) { /* fast path */
	int y;

	for (y=0; y<bmp->h; y++) {
	    png_write_row(png_ptr, bmp->line[y]);
	}

	return 1;
    }
    else {			/* generic case */
	unsigned char *rowdata;
	int x, y;

	rowdata = (unsigned char *)malloc(bmp->w * 3);
	if (!rowdata)
	    return 0;

	for (y=0; y<bmp->h; y++) {
	    unsigned char *p = rowdata;

	    for (x=0; x<bmp->w; x++) {
		*p++ = getpixel(bmp, x, y);
	    }
	
	    png_write_row(png_ptr, rowdata);
	}
	
	free(rowdata);

	return 1;
    }
}
Beispiel #2
0
int is_route_possible(int fromx, int fromy, int tox, int toy, block wss)
{
  wallscreen = wss;
  suggestx = -1;

  // ensure it's a memory bitmap, so we can use direct access to line[] array
  if ((wss == NULL) || (!is_memory_bitmap(wss)) || (bitmap_color_depth(wss) != 8))
    quit("is_route_possible: invalid walkable areas bitmap supplied");

  if (getpixel(wallscreen, fromx, fromy) < 1)
    return 0;

  block tempw = create_bitmap_ex(8, wallscreen->w, wallscreen->h);

  if (tempw == NULL)
    quit("no memory for route calculation");
  if (!is_memory_bitmap(tempw))
    quit("tempw is not memory bitmap");

  blit(wallscreen, tempw, 0, 0, 0, 0, tempw->w, tempw->h);

  int dd, ff;
  // initialize array for finding widths of walkable areas
  int thisar, inarow = 0, lastarea = 0;
  int walk_area_times[MAX_WALK_AREAS + 1];
  for (dd = 0; dd <= MAX_WALK_AREAS; dd++) {
    walk_area_times[dd] = 0;
    walk_area_granularity[dd] = 0;
  }

  for (ff = 0; ff < tempw->h; ff++) {
    for (dd = 0; dd < tempw->w; dd++) {
      thisar = tempw->line[ff][dd];
      // count how high the area is at this point
      if ((thisar == lastarea) && (thisar > 0))
        inarow++;
      else if (lastarea > MAX_WALK_AREAS)
        quit("!Calculate_Route: invalid colours in walkable area mask");
      else if (lastarea != 0) {
        walk_area_granularity[lastarea] += inarow;
        walk_area_times[lastarea]++;
        inarow = 0;
      }
      lastarea = thisar;
    }
  }

  for (dd = 0; dd < tempw->w; dd++) {
    for (ff = 0; ff < tempw->h; ff++) {
      thisar = tempw->line[ff][dd];
      if (thisar > 0)
        putpixel(tempw, dd, ff, 1);
      // count how high the area is at this point
      if ((thisar == lastarea) && (thisar > 0))
        inarow++;
      else if (lastarea != 0) {
        walk_area_granularity[lastarea] += inarow;
        walk_area_times[lastarea]++;
        inarow = 0;
      }
      lastarea = thisar;
    }
  }

  // find the average "width" of a path in this walkable area
  for (dd = 1; dd <= MAX_WALK_AREAS; dd++) {
    if (walk_area_times[dd] == 0) {
      walk_area_granularity[dd] = MAX_GRANULARITY;
      continue;
    }

    walk_area_granularity[dd] /= walk_area_times[dd];
    if (walk_area_granularity[dd] <= 4)
      walk_area_granularity[dd] = 2;
    else if (walk_area_granularity[dd] <= 15)
      walk_area_granularity[dd] = 3;
    else
      walk_area_granularity[dd] = MAX_GRANULARITY;

    /*char toprnt[200];
       sprintf(toprnt,"area %d: Gran %d", dd, walk_area_granularity[dd]);
       winalert(toprnt); */
  }
  walk_area_granularity[0] = MAX_GRANULARITY;

  floodfill(tempw, fromx, fromy, 232);
  if (getpixel(tempw, tox, toy) != 232) 
  {
    // Destination pixel is not walkable
    // Try the 100x100 square around the target first at 3-pixel granularity
    int tryFirstX = tox - 50, tryToX = tox + 50;
    int tryFirstY = toy - 50, tryToY = toy + 50;

    if (!find_nearest_walkable_area(tempw, tryFirstX, tryFirstY, tryToX, tryToY, tox, toy, 3))
    {
      // Nothing found, sweep the whole room at 5 pixel granularity
      find_nearest_walkable_area(tempw, 0, 0, tempw->w, tempw->h, tox, toy, 5);
    }

    wfreeblock(tempw);
    return 0;
  }
  wfreeblock(tempw);

  return 1;
}