/* ポリゴン描画 */ 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; }
/* * 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); } }