#include "duet.h" #include /* Bresenham algorithm */ void dcircle(int cx, int cy, int r0, int color, bool fill) { int x=-r0, y=0, e=2-2*r0, r=r0; do { dpixel(cx-x, cy-y, color); dpixel(cx+y, cy-x, color); dpixel(cx+x, cy+y, color); dpixel(cx-y, cy+x, color); if(fill) { dline(cx+x, cy-y, cx-x, cy-y, color); dline(cx+x, cy+y, cx-x, cy+y, color); } r = e; if(r <= y) e += (++y * 2) + 1; if(r > x || e > y) e += (++x * 2) + 1; } while(x < 0); } /* From Windmill::render_triangle_black */ static int edge_start(int x1, int y1, int x2, int y2, int px, int py) { return (y2 - y1) * (px - x1) - (x2 - x1) * (py - y1); } static int min(int x, int y) { return (x < y) ? x : y; } static int max(int x, int y) { return (x > y) ? x : y; } void dtriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color) { // calcul du rectangle circonscrit au triangle int min_x = max(0, min(x1, min(x2, x3))); int max_x = min(DWIDTH-1, max(x1, max(x2, x3))); int min_y = max(0, min(y1, min(y2, y3))); int max_y = min(DHEIGHT-1, max(y1, max(y2, y3))); // calcul des produits vectoriels int u0_start = edge_start(x2, y2, x3, y3, min_x, min_y); int u0_step_x = y3 - y2; int u0_step_y = x2 - x3; int u1_start = edge_start(x3, y3, x1, y1, min_x, min_y); int u1_step_x = y1 - y3; int u1_step_y = x3 - x1; int u2_start = edge_start(x1, y1, x2, y2, min_x, min_y); int u2_step_x = y2 - y1; int u2_step_y = x1 - x2; int u0, u1, u2; // parcours en ligne for(int x=min_x; x<=max_x; x++) { u0 = u0_start; u1 = u1_start; u2 = u2_start; // parcours en colonne for(int y=min_y; y<=max_y; y++) { // si le pixel (x;y) est dans le triangle if ((u0 | u1 | u2) > 0) { dpixel(x, y, color); } u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y; } u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x; } } void drectoid(rect_t const *r, int color) { if(r->x - max(r->w,r->h)/2 > DWIDTH || r->x + max(r->w,r->h)/2 < 0) return; float x0[4] = { r->w/2, -r->w/2, -r->w/2, r->w/2 }; float y0[4] = { -r->h/2, -r->h/2, r->h/2, r->h/2 }; if(r->r == 0) { drect(r->x+x0[1], r->y+y0[1], r->x+x0[3], r->y+y0[3], color); return; } float sin, cos; sincosf(r->r, &sin, &cos); int x[4], y[4]; for(int i = 0; i < 4; i++) { x[i] = r->x + x0[i] * cos + y0[i] * sin; y[i] = r->y - x0[i] * sin + y0[i] * cos; } dtriangle(x[0], y[0], x[1], y[1], x[2], y[2], color); dtriangle(x[2], y[2], x[3], y[3], x[0], y[0], color); } void render_player(int x, int y, float angle) { dcircle(x, y, PLAYER_R, C_RGB(10, 10, 10), false); float x1, y1, x2, y2; player_position(angle, &x1, &y1, &x2, &y2); x1 = x1 - PLAYER_X + x; y1 = y1 - DHEIGHT/2 + y; x2 = x2 - PLAYER_X + x; y2 = y2 - DHEIGHT/2 + y; dcircle(x1, y1, PLAYER_SIZE, C_RGB(0, 16, 26), true); dcircle(x2, y2, PLAYER_SIZE, C_RGB(31, 6, 0), true); }