#include #include #include "lighting.h" static void find_vlines_helper(Polygon* poly, va_list ap); static void draw_vlines_helper(VLine* vline, va_list ap); /* Returns a fresh vline */ VLine* create_vline(void) { return calloc(1, sizeof(VLine)); } /* Deallocates a vline */ void destroy_vline(VLine* vline) { free(vline); } /* Makes a vline for every applicable edge in the world list of polygons */ void find_vlines(Heap* lines, Heap* world) { empty_heap(lines); process_heap_va(world, PROC_VA(find_vlines_helper), lines); } /* Renders the list of vlines to bmp */ void draw_vlines(BITMAP* bmp, int x, int y, Heap* lines, int color) { // int r, g, b; void** data = lines->data; void** data_end = data + lines->count; VLine* vline; // color = -1; // drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0); // text_mode(-1); for (; data < data_end; data++) { vline = *data; // color++; if (vline->vtx_count != 2) { // if (vline->vtx_count == 1) // circle(buffer, vline->xa, vline->ya, 2, // 0xffffff); continue; } triangle(bmp, x, y, vline->xa, vline->ya, vline->xb, vline->yb, color); // hsv_to_rgb(color * 360.0 / 6.0, 1.0, 0.5, &r, &g, &b); // triangle(buffer, x, y, vline->xa, vline->ya, vline->xb, // vline->yb, makecol32(r, g, b)); // textprintf_centre(buffer, font, (vline->x1 + vline->x2) / 2, // (vline->y1 + vline->y2) / 2 - 4, // makecol32(r, g, b), "%i", color); // line(buffer, vline->xa, vline->ya, vline->xb, vline->yb, // 0xffffff); } // drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0); // process_heap_va(lines, PROC_VA(draw_vlines_helper), bmp, x, y, color); } /* Adds a vertex to the given vline */ void add_vertex_to_vline(VLine* vline, int x, int y) { static int recurse = 0; switch (vline->vtx_count) { case 0: vline->xa = x; vline->ya = y; vline->vtx_count = 1; break; case 1: if (vline->xa == x && vline->ya == y) break; vline->xb = x; vline->yb = y; vline->vtx_count = 2; break; case 2: switch (middle_point(x, y, vline->xa, vline->ya, vline->xb, vline->yb)) { case 2: vline->xa = x; vline->ya = y; break; case 3: vline->xb = x; vline->yb = y; break; } break; } if (recurse == 0 && vline->next != NULL) { recurse = 1; if (vline->x1 == x && vline->y1 == y) add_vertex_to_vline(vline->prev, x, y); else if (vline->x2 == x && vline->y2 == y) add_vertex_to_vline(vline->next, x, y); recurse = 0; } } /* Make a set of vlines for a polygon */ static void find_vlines_helper(Polygon* poly, va_list ap) { int i, x, y; VLine* new_line; VLine* first_line; VLine* prev_line = NULL; Heap* lines = va_arg(ap, Heap*); if (poly->vtx_count < 3) return; x = poly->vtx[0].x; y = poly->vtx[0].y; for (i = 1; i <= poly->vtx_count; i++) { new_line = new_from_heap(lines); new_line->x1 = x; new_line->y1 = y; new_line->x2 = x = poly->vtx[i < poly->vtx_count ? i : 0].x; new_line->y2 = y = poly->vtx[i < poly->vtx_count ? i : 0].y; new_line->vtx_count = 0; new_line->skip = 0; if (prev_line == NULL) first_line = new_line; else { new_line->prev = prev_line; prev_line->next = new_line; } prev_line = new_line; } first_line->prev = prev_line; prev_line->next = first_line; } /* Draw a single VLine */ static void draw_vlines_helper(VLine* vline, va_list ap) { if (vline->vtx_count == 2) { BITMAP* bmp; int x, y, color; bmp = va_arg(ap, BITMAP*); x = va_arg(ap, int); y = va_arg(ap, int); color = va_arg(ap, int); triangle(bmp, x, y, vline->xa, vline->ya, vline->xb, vline->yb, color); triangle(buffer, x, y, vline->xa, vline->ya, vline->xb, vline->yb, 0x3f3f3f); line(buffer, x, y, vline->xa, vline->ya, 0x7f7f7f); line(buffer, x, y, vline->xb, vline->yb, 0x7f7f7f); line(buffer, vline->xa, vline->ya, vline->xb, vline->yb, 0xffffff); } }