예제 #1
0
파일: light.cpp 프로젝트: netguy204/giggle
void LightCaster::compute_light_mesh(Mesh* result, Walls* walls, const Vector_& light) {
  long nwalls = walls->nwalls();
  angle = restrict_angle(angle);

  WallPoint* wall_points = (WallPoint*)GIGGLE->renderer->alloc(sizeof(WallPoint) * nwalls * 2);
  Wall** open_set = (Wall**)GIGGLE->renderer->alloc(sizeof(Wall*) * nwalls);
  long nopen_set = 0;

  for(long ii = 0; ii < nwalls; ++ii) {
    Wall* wall = &walls->walls[ii];
    float angle_start = atan2f(wall->start.y - light.y, wall->start.x - light.x);
    float angle_end = atan2f(wall->end.y - light.y, wall->end.x - light.x);

    float dangle = restrict_angle(angle_end - angle_start);

    long idx1 = 2*ii;
    long idx2 = idx1 + 1;
    wall_points[idx1].point = &wall->start;
    wall_points[idx1].wall = wall;
    wall_points[idx1].angle = angle_start;
    wall_points[idx1].begin = dangle > 0;

    wall_points[idx2].point = &wall->end;
    wall_points[idx2].wall = wall;
    wall_points[idx2].angle = angle_end;
    wall_points[idx2].begin = !wall_points[idx1].begin;
  }

  std::sort(wall_points, wall_points + (nwalls*2), WallPointCompare());

  float beginAngle = 0;

  for(int kk = 0; kk < 2; ++kk) {
    for(long ii = 0; ii < nwalls * 2; ++ii) {
      WallPoint* wp = &wall_points[ii];
      Wall* last_closest = (nopen_set == 0) ? NULL : open_set[0];
      if(wp->begin) {
        add_wall(open_set, &nopen_set, wp->wall, &light);
      } else {
        remove_wall(open_set, &nopen_set, wp->wall);
      }

      Wall* next_closest = (nopen_set == 0) ? NULL : open_set[0];
      if(last_closest != next_closest) {
        float nextAngle = wp->angle;

        if(last_closest) {
          if(kk == 1) {
            add_triangle(result, light, last_closest, beginAngle, nextAngle);
          }
          beginAngle = nextAngle;
        }
      }
    }
  }
}
예제 #2
0
DesignView::DesignView(ViewStack* vs, MapView* mapv, City* c)
: vstk(vs), mv(mapv), city(c), fdv(new FurnitureDesignView(this)), rdv(new RoomsDesignView(this))
{
  nav.register_key(KEY_Escape, "[Esc] Back", [this]() { vstk->pop(); });
  nav.register_key(KEY_space, "[Spc] Pause", [this]() { paused = !paused; });
  nav.register_key(KEY_Return, "[Ent] Build Wall", [this]() { build_wall(); });
  nav.register_key(KEY_Delete, "[Del] Remove Wall", [this]() { remove_wall(); });

  nav.register_key(KEY_r, "[r] Construct Room", [this]() { vstk->push(rdv.get()); });
  nav.register_key(KEY_f, "[f] Place Furniture", [this]() { vstk->push(fdv.get()); });

}
예제 #3
0
파일: expl.c 프로젝트: ajinkya93/netbsd-src
/*
 * showexpl:
 *	Show the explosions as they currently are
 */
void
showexpl(int y, int x, char type)
{
	PLAYER *pp;
	EXPL *ep;

	if (y < 0 || y >= HEIGHT)
		return;
	if (x < 0 || x >= WIDTH)
		return;
	ep = malloc(sizeof(*ep));
	ep->e_y = y;
	ep->e_x = x;
	ep->e_char = type;
	ep->e_next = NULL;
	if (Last_expl == NULL)
		Expl[0] = ep;
	else
		Last_expl->e_next = ep;
	Last_expl = ep;
	for (pp = Player; pp < End_player; pp++) {
		if (pp->p_maze[y][x] == type)
			continue;
		pp->p_maze[y][x] = type;
		cgoto(pp, y, x);
		outch(pp, type);
	}
#ifdef MONITOR
	for (pp = Monitor; pp < End_monitor; pp++) {
		if (pp->p_maze[y][x] == type)
			continue;
		pp->p_maze[y][x] = type;
		cgoto(pp, y, x);
		outch(pp, type);
	}
#endif
	switch (Maze[y][x]) {
	  case WALL1:
	  case WALL2:
	  case WALL3:
#ifdef RANDOM
	  case DOOR:
#endif
#ifdef REFLECT
	  case WALL4:
	  case WALL5:
#endif
		if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
			remove_wall(y, x);
		break;
	}
}
예제 #4
0
/*
 * showexpl:
 *	Show the explosions as they currently are
 */
void
showexpl(int y, int x, char type)
{
	PLAYER	*pp;
	EXPL	*ep;

	if (y < 0 || y >= HEIGHT)
		return;
	if (x < 0 || x >= WIDTH)
		return;
	ep = (EXPL *) malloc(sizeof (EXPL));	/* NOSTRICT */
	if (ep == NULL) {
		logit(LOG_ERR, "malloc");
		return;
	}
	ep->e_y = y;
	ep->e_x = x;
	ep->e_char = type;
	ep->e_next = NULL;
	if (Last_expl == NULL)
		Expl[0] = ep;
	else
		Last_expl->e_next = ep;
	Last_expl = ep;
	for (pp = Player; pp < End_player; pp++) {
		if (pp->p_maze[y][x] == type)
			continue;
		pp->p_maze[y][x] = type;
		cgoto(pp, y, x);
		outch(pp, type);
	}
	for (pp = Monitor; pp < End_monitor; pp++) {
		if (pp->p_maze[y][x] == type)
			continue;
		pp->p_maze[y][x] = type;
		cgoto(pp, y, x);
		outch(pp, type);
	}
	switch (Maze[y][x]) {
	  case WALL1:
	  case WALL2:
	  case WALL3:
	  case DOOR:
	  case WALL4:
	  case WALL5:
		if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
			remove_wall(y, x);
		break;
	}
}
예제 #5
0
/** Build the maze by removing walls according to Prim's algorithm.
 *
 *  @param maze a maze with all walls present.
 */
static void build_prim(maze_t* maze) {
    // MST edges and cells.  If (a, b) in mst_edges, then (b, a) not in
    // mst_edges.  (a, b) in mst_edges iff a, b both in mst_cells.
    list356_t* mst_edges = make_list() ;
    list356_t* mst_cells = make_list() ;

    // The frontier.  This is the collection of edges between cells in the MST
    // and cells not in the MST.  If (a, b) in frontier, then a in mst_cells
    // and b not in mst_cells.
    list356_t* frontier = make_list() ;

    // Choose two adjacent cells at random to put into the MST, then
    // populate the frontier accordinately.  For simplicitly, choose a
    // cell in the interior of the maze, then randomly choose a direction
    // for the other cell.
    cell_t* start = 
        get_cell(maze, random_limit(1, maze->nrows-1), 
                random_limit(1, maze->ncols-1));
    unsigned char direction = 1 << random_limit(0, 4) ;

    cell_t* next = get_neighbor(maze, start, direction) ;
    /*
    debug("Removing (%d, %d) - (%d, %d).\n",
            start->r, start->c, next->r, next->c) ;
    */
    remove_wall(maze, start, direction) ;

    edge_t init_edge = (edge_t){start, next} ;
    lst_add(mst_edges, &init_edge) ;
    lst_add(mst_cells, start) ;
    lst_add(mst_cells, next) ;

    for (int d=0; d<4; ++d) {
        if (directions[d] != direction && is_cell(maze, start, directions[d])) {
            cell_t* c = get_neighbor(maze, start, directions[d]) ;
            edge_t* e = malloc(sizeof(edge_t)) ;
            e->a = start ; e->b = c ;
            lst_add(frontier, e) ;
        }
    }

    for (int d=0; d<4; ++d) {
        if (directions[d] != opposite(direction) 
                && is_cell(maze, next, directions[d])) {
            cell_t* c = get_neighbor(maze, next, directions[d]) ;
            edge_t* e = malloc(sizeof(edge_t)) ;
            e->a = next ; e->b = c ;
            lst_add(frontier, e) ;
        }
    }

    // As long as we don't have all the cells in the MST, choose an
    // edge in the frontier at random.  Put the edge in the MST
    // and compute the new edges to add to the frontier.
    while (lst_size(mst_cells) < (maze->nrows)*(maze->ncols)) {
        int p = random_limit(0, lst_size(frontier)) ;
        edge_t* edge = lst_get(frontier, p) ;
        cell_t* old_cell = edge->a ;
        cell_t* new_cell = edge->b ;
        /*
        debug("Removing (%d, %d) - (%d, %d).\n",
                old_cell->r, old_cell->c, new_cell->r, new_cell->c) ;
        */
        remove_wall(maze, old_cell, get_direction(old_cell, new_cell)) ;

        lst_add(mst_edges, edge) ;
        lst_add(mst_cells, new_cell) ;

        for (int d=0; d<4; ++d) {
            unsigned char dir = directions[d] ;
            if (is_cell(maze, new_cell, dir)) {
                cell_t* adj_cell = get_neighbor(maze, new_cell, dir) ;
                edge_t* edge2 = malloc(sizeof(edge_t)) ;
                edge2->a = new_cell ; edge2->b = adj_cell ;
                if (lst_contains(mst_cells, adj_cell, cell_cmp)) {
                    lst_remove(frontier, edge2, edge_cmp) ;
                    if (adj_cell != old_cell) free(edge2) ;
                }
                else {
                    lst_add(frontier, edge2) ;
                }
            }
        }
    }


}