/*
ポリゴン描画
*/
static VALUE drawing_draw_polygon(int argc, VALUE *argv, VALUE self)
{
  VALUE vdst;
  VALUE pairs;
  VALUE mcolor;
  VALUE fill;
  VALUE aa;
  Uint8 alpha;
  Uint32 color;
  int i, vertexes;
  
  rb_scan_args(argc, argv, "32", &vdst, &pairs, &mcolor, &fill, &aa);
  
  // bitmapメソッドを持っていれば、メソッドの値をvdstとする
  VALUE methods = rb_funcall(vdst, rb_intern("methods"), 0);
  if(rb_ary_includes(methods, rb_str_intern(rb_str_new2("to_unit"))) == Qfalse &&
     rb_ary_includes(methods, rb_str_intern(rb_str_new2("bitmap"))) == Qfalse
    )
    rb_raise(eMiyakoError, "this method needs sprite have to_method or bitmap method!");
  if(rb_ary_includes(methods, rb_str_intern(rb_str_new2("to_unit"))) == Qtrue)
    vdst = rb_funcall(vdst, rb_intern("to_unit"), 0);
  vdst = rb_funcall(vdst, rb_intern("bitmap"), 0);

  vertexes = RARRAY_LEN(pairs);
  // 頂点数チェック
  if(vertexes > 65536)
    rb_raise(eMiyakoError, "too many pairs. pairs is less than 65536.");
  
  // 範囲チェック
  for(i=0; i<vertexes; i++)
  {
    VALUE vertex = *(RARRAY_PTR(pairs)+i);
    Sint16 x, y;
    get_position(vertex, &x, &y);
  }
  
	SDL_Surface  *dst = GetSurface(vdst)->surface;

  color = value_2_color(rb_funcall(cColor, rb_intern("to_rgb"), 1, mcolor), dst->format, &alpha);

  if(RTEST(fill) && RTEST(aa) && alpha < 255)
    rb_raise(eMiyakoError, "can't draw filled antialiased alpha polygon");

  Sint16 *px = (Sint16 *)malloc(sizeof(Sint16) * vertexes);
  Sint16 *py = (Sint16 *)malloc(sizeof(Sint16) * vertexes);
  for(i=0; i<vertexes; i++)
  {
    VALUE vertex = *(RARRAY_PTR(pairs)+i);
    get_position(vertex, px+i, py+i);
  }
  
  if(!RTEST(fill) && !RTEST(aa) && alpha == 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_Line(dst, px[i], py[i], px[i+1], py[i+1], color);
    sge_Line(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color);
  }
  else if(!RTEST(fill) && !RTEST(aa) && alpha < 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_LineAlpha(dst, px[i], py[i], px[i+1], py[i+1], color, alpha);
    sge_LineAlpha(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color, alpha);
  }
  else if(!RTEST(fill) && RTEST(aa) && alpha == 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_AALine(dst, px[i], py[i], px[i+1], py[i+1], color);
    sge_AALine(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color);
  }
  else if(!RTEST(fill) && RTEST(aa) && alpha < 255)
  {
    for(i=0; i<vertexes-1; i++)
      sge_AALineAlpha(dst, px[i], py[i], px[i+1], py[i+1], color, alpha);
    sge_AALineAlpha(dst, px[vertexes-1], py[vertexes-1], px[0], py[0], color, alpha);
  }
  else if(RTEST(fill) && !RTEST(aa) && alpha == 255)
    sge_FilledPolygon(dst, (Uint16)vertexes, px, py, color);
  else if(RTEST(fill) && !RTEST(aa) && alpha < 255)
    sge_FilledPolygonAlpha(dst, (Uint16)vertexes, px, py, color, alpha);
  else if(RTEST(fill) && RTEST(aa) && alpha == 255)
    sge_AAFilledPolygon(dst, (Uint16)vertexes, px, py, color);
  
  free(py);
  free(px);

  return Qnil;
}
示例#2
0
/*
 * Draws the given <unit> on the <screen>.
 */
static void draw_unit(SDL_Surface *screen, struct unit *unit)
{
  Sint16 xs[UNIT_MAX_SIDES];
  Sint16 ys[UNIT_MAX_SIDES];
  int i;
  unsigned cr, ca, xmov, ymov;
  unsigned rot = unit->rot % 360;

  for (i = 0; i < unit->desc.sides; i++){
    /* calculate the circum radius */
    cr = circum_rad(unit->desc.sides);
    /* calculate the central angle */
    ca = floor(360 / unit->desc.sides);
    /* calculate the alpha angle */
    xmov = cr * sin(RAD(rot));
    ymov = cr * cos(RAD(rot));

    xs[i] = unit->x - xmov;
    ys[i] = unit->y + ymov;

    rot += ca;
  }

  /* draw the unit */
  sge_AAFilledPolygon(screen, unit->desc.sides, xs, ys, unit->desc.color);

  unsigned loss = UNIT_HEIGHT - (UNIT_HEIGHT * unit->hp / UNIT_MAX_HP);

  /* draw the health bar's background */
  /* top left corner */
  xs[0] = unit->x - (UNIT_HEIGHT / 2) - 2;
  ys[0] = unit->y + (UNIT_HEIGHT / 2) + 14;
  /* top right corner */
  xs[1] = unit->x + (UNIT_HEIGHT / 2) + 2;
  ys[1] = unit->y + (UNIT_HEIGHT / 2) + 14;
  /* bottom right corner */
  xs[2] = unit->x + (UNIT_HEIGHT / 2) + 2;
  ys[2] = unit->y + (UNIT_HEIGHT / 2) + 24;
  /* bottom left corner */
  xs[3] = unit->x - (UNIT_HEIGHT / 2) - 2;
  ys[3] = unit->y + (UNIT_HEIGHT / 2) + 24;
  /* draw it */
  sge_AAFilledPolygon(screen, 4, xs, ys, 0x222222);

  /* draw the health bar */
  if (unit->hp > 0){
    /* just to make sure */
    if (unit->hp >= UNIT_MAX_HP)
      loss = 0;

    /* top left corner */
    xs[0] = unit->x - (UNIT_HEIGHT / 2);
    ys[0] = unit->y + (UNIT_HEIGHT / 2) + 16;
    /* top right corner */
    xs[1] = unit->x + (UNIT_HEIGHT / 2) - loss;
    ys[1] = unit->y + (UNIT_HEIGHT / 2) + 16;
    /* bottom right corner */
    xs[2] = unit->x + (UNIT_HEIGHT / 2) - loss;
    ys[2] = unit->y + (UNIT_HEIGHT / 2) + 22;
    /* bottom left corner */
    xs[3] = unit->x - (UNIT_HEIGHT / 2);
    ys[3] = unit->y + (UNIT_HEIGHT / 2) + 22;
    /* draw it */
    sge_AAFilledPolygon(screen, 4, xs, ys, 0xde3333);
  }
}