void TCOD_map_compute_fov_circular_raycastingi(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { int xo,yo; map_t *m = (map_t *)map; /* circular ray casting */ int xmin=0, ymin=0, xmax=m->width, ymax=m->height; int c; int r2=max_radius*max_radius; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } xo=xmin; yo=ymin; while ( xo < xmax ) { cast_ray(m,player_x,player_y,xo++,yo,r2,light_walls); } xo=xmax-1;yo=ymin+1; while ( yo < ymax ) { cast_ray(m,player_x,player_y,xo,yo++,r2,light_walls); } xo=xmax-2;yo=ymax-1; while ( xo >= 0 ) { cast_ray(m,player_x,player_y,xo--,yo,r2,light_walls); } xo=xmin;yo=ymax-2; while ( yo > 0 ) { cast_ray(m,player_x,player_y,xo,yo--,r2,light_walls); } if ( light_walls ) { /* post-processing artefact fix */ TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } }
void TCOD_map_compute_fov_diamond_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { map_t *m = (map_t *)map; TCOD_list_t perim=TCOD_list_allocate(m->nbcells); cell_t *c; ray_data_t **r; int nbcells; int r2=max_radius*max_radius; perimidx=0; raymap=(ray_data_t **)calloc(sizeof(ray_data_t*),m->nbcells); raymap2=(ray_data_t *)calloc(sizeof(ray_data_t),m->nbcells); origx=player_x; origy=player_y; expandPerimeterFrom(m,perim,new_ray(m,0,0)); while ( perimidx < TCOD_list_size(perim) ) { ray_data_t *ray=(ray_data_t *)TCOD_list_get(perim,perimidx); int distance = 0; if ( r2 > 0 ) distance = ((ray->xloc * ray->xloc) + (ray->yloc * ray->yloc)); perimidx++; if ( distance <= r2) { merge_input(m, ray); if ( !ray->ignore ) expandPerimeterFrom(m,perim,ray); } else ray->ignore=true; } // set fov data c=m->cells; r=raymap; nbcells=m->nbcells; while ( nbcells!= 0 ) { if ( *r == NULL || (*r)->ignore || ((*r)->xerr > 0 && (*r)->xerr <= (*r)->xob ) || ((*r)->yerr > 0 && (*r)->yerr <= (*r)->yob ) ) { c->fov=0; } else { c->fov=1; } c++; r++; nbcells--; } m->cells[origx+origy*m->width].fov=1; // light walls if ( light_walls ) { int xmin=0, ymin=0, xmax=m->width, ymax=m->height; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } free(raymap); free(raymap2); TCOD_list_delete(perim); }