#include #include "lighting.h" static void process_vwedge_vis_helper(VLine* vline, va_list ap); /* Returns a new vwedge */ VWedge* create_vwedge() { VWedge* wedge = malloc(sizeof(VWedge)); create_heap(&wedge->vis, 5, 5, create_vline, destroy_vline); return wedge; } /* Frees a vwedge */ void destroy_vwedge(VWedge* wedge) { destroy_heap(&wedge->vis); free(wedge); } /* Fill out the vis field of wedge */ void process_vwedge_vis(VWedge* wedge) { /* Cast rays at regular intervals */ /* Cast a ray toward every world vertex */ process_heap_va(&wedge->vis, PROC_VA(process_vwedge_vis_helper), wedge); } /* Renders the vwedge to bmp */ void draw_vwedge(BITMAP* bmp, VWedge* wedge, int color) { draw_vlines(bmp, wedge->x, wedge->y, &wedge->vis, color); } /* The most important function! */ static void process_vwedge_vis_helper(VLine* l, va_list ap) { VWedge* w = va_arg(ap, VWedge*); VLine* l2; VLine** lines = (VLine**)w->vis.data; int x, y, r, i, x2, y2, r2, i2; if (same_side(w->x, w->y, l->x1, l->y1, l->prev->x1, l->prev->y1, l->x2, l->y2)) l->skip = l->prev->skip = 1; /* Cast a ray toward each vertex and find which line intercepts it */ x = l->x1; y = l->y1; r = -1; for (i2 = 0; i2 < w->vis.count; i2++) { l2 = lines[i2]; if (l2->skip) continue; if (intersection(w->x, w->y, l->x1, l->y1, l2->x1, l2->y1, l2->x2, l2->y2, &x2, &y2, !l->skip)) { r2 = sqr_dist(w->x, w->y, x2, y2); if (r == -1 || r >= r2) { r = r2; x = x2; y = y2; i = i2; } } } if (l->skip) { l->skip = l->prev->skip = 0; if (r == -1 || r >= sqr_dist(w->x, w->y, l->x1, l->y1)) add_vertex_to_vline(l, l->x1, l->y1); } if (r > -1) add_vertex_to_vline(lines[i], x, y); }