From 43d741660f6377392a789da76a5cabe62769d5b6 Mon Sep 17 00:00:00 2001 From: ketmar Date: Fri, 27 Dec 2013 23:07:09 +0200 Subject: [PATCH] shadowcasting sux; back to the basics --- src/main.c | 2 +- src/zlight.c | 73 +++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/main.c b/src/main.c index 5f76382..fa3355c 100644 --- a/src/main.c +++ b/src/main.c @@ -308,7 +308,7 @@ static void rebuild_screen (void) { render_lights(); /* sample light */ //light_dump = 1; - for (int tt = 10; tt > 0; --tt) { + for (int tt = 20*0+1; tt > 0; --tt) { renderlight_sector(light_x, light_y, light_radius, light_as, light_ae, light_color); } //light_dump = 0; diff --git a/src/zlight.c b/src/zlight.c index 3b4303f..f9665ba 100644 --- a/src/zlight.c +++ b/src/zlight.c @@ -168,6 +168,9 @@ static void realize_lightmask (void) { //////////////////////////////////////////////////////////////////////////////// +static int lrad_sqr; + + static int trace_point_count; static struct { int x; @@ -195,6 +198,7 @@ void t_draw_line_no_last (int x0, int y0, int x1, int y1) { static void trace_start (void) { + lrad_sqr = lrad*lrad; trace_point_count = 0; prepare_lightmask(); } @@ -228,7 +232,7 @@ static void trace_to_point (int x1, int y1) { int dx = K8ABS(x1-x0), sx = (x0 < x1 ? 1 : -1); int dy = -K8ABS(y1-y0), sy = (y0 < y1 ? 1 : -1); int err = dx+dy, e2; /* error value e_xy */ - int ox = x0, oy = y0, dst = lrad*lrad; + int ox = x0, oy = y0, dst = lrad_sqr; for (;;) { if ((x0-lcx)*(x0-lcx)+(y0-lcy)*(y0-lcy) >= dst) { trace_add_point(x0, y0); @@ -323,40 +327,34 @@ static inline int light_is_blocked (int x, int y) { } +static int lsc_xx, lsc_xy, lsc_yx, lsc_yy; + + // recursive lightcasting function -static void light_octant (int cx, int cy, int row, double start, double end, int radius, int octant) { +static void light_octant (int cx, int cy, int row, double start, double end) { if (start >= end) { - // multipliers for transforming coordinates to other octants - static const int mult[4][8] = { - {1, 0, 0,-1,-1, 0, 0, 1}, - {0, 1,-1, 0, 0,-1, 1, 0}, - {0, 1, 1, 0, 0,-1,-1, 0}, - {1, 0, 0, 1,-1, 0, 0,-1}, - }; - int xx = mult[0][octant]; - int xy = mult[1][octant]; - int yx = mult[2][octant]; - int yy = mult[3][octant]; - int radius_sqr = radius*radius; - for (int j = row; j <= radius; ++j) { + double new_start; + double l_slope, r_slope; + int dst = lrad_sqr; + int xx = lsc_xx, xy = lsc_xy, yx = lsc_yx, yy = lsc_yy; + for (int j = row; j <= lrad; ++j) { int dx = -j-1; - int dy = -j, dysqr = dy*dy; + int dy = -j; + int dysqr = dy*dy; int blocked = 0; - double new_start = 666.666; int x = cx+dx*xx+dy*xy; int y = cy+dx*yx+dy*yy; double dyp5 = dy+0.5; double dym5 = dy-0.5; - while (dx <= 0) { - ++dx; + while (dx++ <= 0) { // translate the dx, dy coordinates into map coordinates x += xx; y += yx; // l_slope and r_slope store the slopes of the left and right // extremities of the tile we're considering - double l_slope = (dx-0.5)/dyp5; - double r_slope = (dx+0.5)/dym5; + l_slope = (dx-0.5)/dyp5; if (end > l_slope) break; + r_slope = (dx+0.5)/dym5; if (start >= r_slope) { // our light beam is touching this tile; light it int blk = light_is_blocked(x, y); @@ -367,16 +365,18 @@ static void light_octant (int cx, int cy, int row, double start, double end, int } else { blocked = 0; start = new_start; - if (dx*dx+dysqr < radius_sqr) lb_light_plot(x, y); + if (dx*dx+dysqr < dst) lb_light_plot(x, y); } } else { - if (blk && j < radius) { - // this is a blocking tile, start a child scan - blocked = 1; - light_octant(cx, cy, j+1, start, l_slope, radius, octant); - new_start = r_slope; + if (blk) { + if (j < lrad) { + // this is a blocking tile, start a child scan + blocked = 1; + light_octant(cx, cy, j+1, start, l_slope); + new_start = r_slope; + } } else { - if (!blk && dx*dx+dysqr < radius_sqr) lb_light_plot(x, y); + if (dx*dx+dysqr < dst) lb_light_plot(x, y); } } } @@ -402,7 +402,7 @@ static void trace_light (int as, int ae) { trace_start(); if (asx == aex) { /* do full circle (square, actually) */ -#if 0 +#if 1 /* top */ for (int d = -lrad; d < lrad; ++d) trace_to_point(lcx+d, lcy-lrad); /* right */ @@ -412,7 +412,20 @@ static void trace_light (int as, int ae) { /* left */ for (int d = lrad; d > -lrad; --d) trace_to_point(lcx-lrad, lcy+d); #else - for (int oct = 0; oct < 8; ++oct) light_octant(lcx, lcy, 1, 1.0, 0.0, lrad, oct); + // multipliers for transforming coordinates to other octants + static const int mult[4][8] = { + {1, 0, 0,-1,-1, 0, 0, 1}, + {0, 1,-1, 0, 0,-1, 1, 0}, + {0, 1, 1, 0, 0,-1,-1, 0}, + {1, 0, 0, 1,-1, 0, 0,-1}, + }; + for (int oct = 0; oct < 8; ++oct) { + lsc_xx = mult[0][oct]; + lsc_xy = mult[1][oct]; + lsc_yx = mult[2][oct]; + lsc_yy = mult[3][oct]; + light_octant(lcx, lcy, 1, 1.0, 0.0); + } lb_light_plot(lcx, lcy); #endif } else { -- 2.11.4.GIT