DungeonCrawl
Loading...
Searching...
No Matches
draw_light.c File Reference

Implements functionality fro drawing light on player. More...

#include "draw_light.h"
#include <stdlib.h>

Go to the source code of this file.

Functions

int need_loop_break (const int x, const int y, const vector2d_t dir, int j, int *prev_wall_at)
 This is a helper function to check if the loop needs to break with this specific edge case.
int process_tile (int x, int y, int *prev_wall_at, const vector2d_t dir, int j)
 This function processes the tile at the given coordinates and updates the revealed_map_arr array.
int check_and_process_tile (int x, int y, int *prev_wall_at, const vector2d_t dir, int j, const vector2d_t diagonal_check, const vector2d_t reverse_check)
 This function checks if the tile at the given coordinates is valid and processes it.
void process_light_in_direction (const vector2d_t player, const vector2d_t dir, const vector2d_t diagonal_check, const vector2d_t reverse_check, const int light_radius)
 Processes light in a specific direction and updates the revealed map_arr.
void draw_light_on_player (map_tile_t *arr1, map_tile_t *arr2, int height, int width, vector2d_t player, const int light_radius)
 Draws light around the player.

Variables

map_tile_t * map_arr
map_tile_t * revealed_map_arr
int map_height
int map_width
vector2d_t player_position
int radius
const vector2d_t checks_vector [4][2]
 Each array row corresponds to the vector in the directions array.

Detailed Description

Implements functionality fro drawing light on player.

Definition in file draw_light.c.

Function Documentation

◆ check_and_process_tile()

int check_and_process_tile ( int x,
int y,
int * prev_wall_at,
const vector2d_t dir,
int j,
const vector2d_t diagonal_check,
const vector2d_t reverse_check )

This function checks if the tile at the given coordinates is valid and processes it.

Parameters
xcurrent tile x-coordinates
ycurrent tile y-coordinates
prev_wall_atindex of the previous wall tile
dirthe direction to check
jloop counter
diagonal_checkthe diagonal check vector
reverse_checkthe reverse check vector
Returns
1 if loops must break, 0 when not

Definition at line 88 of file draw_light.c.

89 {
90 int quit = 0;
91 //calculated access index
92 const int access_idx = x * map_height + y;
93
94 if (x < 0 || x >= map_width || y < 0 || y >= map_height) {
95 //calculated x or y is out of bounds
96 quit = 1;
97 } else {
98 if (revealed_map_arr[access_idx] == HIDDEN) {
99 //initialize the relative diagonal and reverse tiles based on the y and x values
100 const int rel_diagonal = map_arr[(x + diagonal_check.dx) * map_height + y + diagonal_check.dy];
101 const int rel_reverse = map_arr[(x + reverse_check.dx) * map_height + y + reverse_check.dy];
102
103 if (rel_diagonal == WALL && rel_reverse == WALL && j > 1) {
104 //if the diagonal and reverse tiles are walls and the distance from the player is greater than 1
105 // then the tile must be hidden because reverse tile is blocking the view
106 quit = 1;
107 } else {
108 quit = process_tile(x, y, prev_wall_at, dir, j);
109 }
110 } else if (revealed_map_arr[access_idx] == WALL && need_loop_break(x, y, dir, j, prev_wall_at)) {
111 quit = 1;
112 }
113 }
114 return quit;
115}
int need_loop_break(const int x, const int y, const vector2d_t dir, int j, int *prev_wall_at)
This is a helper function to check if the loop needs to break with this specific edge case.
Definition draw_light.c:39
int process_tile(int x, int y, int *prev_wall_at, const vector2d_t dir, int j)
This function processes the tile at the given coordinates and updates the revealed_map_arr array.
Definition draw_light.c:63

◆ draw_light_on_player()

void draw_light_on_player ( map_tile_t * arr1,
map_tile_t * arr2,
int height,
int width,
vector2d_t player,
int light_radius )

Draws light around the player.

Parameters
arr1The pointer to the 2D array containing all the map tiles (no Hidden tiles)
arr2The pointer to the 2D array to reveal the arr1, based on the player's position and light radius
heightThe height of the map
widthThe width of the map
playerThe player's position on the map
light_radiusThe radius of the light around the player

Definition at line 156 of file draw_light.c.

157 {
158 map_arr = arr1;
159 revealed_map_arr = arr2;
160 map_height = height;
161 map_width = width;
162 player_position = player;
163 radius = light_radius;
164
165 if (light_radius <= 0) {
166 //light radius is negative or 0, do nothing
167 return;
168 }
169
170 for (int i = 0; i < 4; i++) {
171 const vector2d_t dir = directions[i];
172 const vector2d_t diagonal_check = checks_vector[i][0];
173 const vector2d_t reverse_check = checks_vector[i][1];
174
175 process_light_in_direction(player, dir, diagonal_check, reverse_check, light_radius);
176 }
177}
const vector2d_t checks_vector[4][2]
Each array row corresponds to the vector in the directions array.
Definition draw_light.c:22
void process_light_in_direction(const vector2d_t player, const vector2d_t dir, const vector2d_t diagonal_check, const vector2d_t reverse_check, const int light_radius)
Processes light in a specific direction and updates the revealed map_arr.
Definition draw_light.c:126
2-dimensional vector struct
Definition common.h:164

◆ need_loop_break()

int need_loop_break ( const int x,
const int y,
const vector2d_t dir,
int j,
int * prev_wall_at )

This is a helper function to check if the loop needs to break with this specific edge case.

Parameters
xcurrent tile x-coordinates
ycurrent tile y-coordinates
dirthe direction to check
jloop counter
prev_wall_atpointer to variable, which should be written
Returns
1 if loops must break, 0 when not

Definition at line 39 of file draw_light.c.

39 {
40 if (j == 0) {
41 //gets the x or y value of the calculated coordinates
42 *prev_wall_at = abs(y * dir.dy + x * dir.dx);
43 return 1;
44 }
45 if (*prev_wall_at == abs(y * dir.dy + x * dir.dx)) {
46 //if the previous j-loop had a wall at x or y coordinate, the loop must break
47 //or else diagonals tiles (behind a wall and not visible by the player) are revealed
48 return 1;
49 }
50 return 0;
51}

◆ process_light_in_direction()

void process_light_in_direction ( const vector2d_t player,
const vector2d_t dir,
const vector2d_t diagonal_check,
const vector2d_t reverse_check,
const int light_radius )

Processes light in a specific direction and updates the revealed map_arr.

Parameters
playerthe player's position on the map_arr
dirthe direction vector
diagonal_checkthe diagonal check vector
reverse_checkthe reverse check vector
light_radiusthe radius of the light around the player

Definition at line 126 of file draw_light.c.

127 {
128 int correction = 0;
129 int prev_wall_at = -1;
130
131 for (int j = 0; j <= light_radius; j++) {
132 const int start_x = player.dx + j * dir.dy;
133 int start_y = player.dy + j * dir.dx;
134
135 if (dir.dx != 0) {
136 //if the direction is vertical negate the subtrahend
137 start_y = player.dy - j * dir.dx;
138 }
139
140 if (start_x < 0 || start_x >= map_width || start_y < 0 || start_y >= map_height) {
141 //start position is out of bounds, skip to the next direction
142 break;
143 }
144 for (int k = 1; k <= light_radius - correction; k++) {
145 const int x = start_x + k * dir.dx;
146 const int y = start_y + k * dir.dy;
147
148 if (check_and_process_tile(x, y, &prev_wall_at, dir, j, diagonal_check, reverse_check)) {
149 break;
150 }
151 }
152 correction++;
153 }
154}
int check_and_process_tile(int x, int y, int *prev_wall_at, const vector2d_t dir, int j, const vector2d_t diagonal_check, const vector2d_t reverse_check)
This function checks if the tile at the given coordinates is valid and processes it.
Definition draw_light.c:88

◆ process_tile()

int process_tile ( int x,
int y,
int * prev_wall_at,
const vector2d_t dir,
int j )

This function processes the tile at the given coordinates and updates the revealed_map_arr array.

Parameters
xcurrent tile x-coordinates
ycurrent tile y-coordinates
prev_wall_atindex of the previous wall tile
dirthe direction to check
jloop counter
Returns

Definition at line 63 of file draw_light.c.

63 {
64 int break_loop = 0;
65 //calculated access index
66 const int access_idx = x * map_height + y;
67
68 revealed_map_arr[access_idx] = map_arr[access_idx];
69
70 if (map_arr[access_idx] == WALL) {
71 break_loop = need_loop_break(x, y, dir, j, prev_wall_at);
72 }
73 return break_loop;
74}

Variable Documentation

◆ checks_vector

const vector2d_t checks_vector[4][2]
Initial value:
= {
{{1, 1}, {1, 0}},
{{-1, -1}, {-1, 0}},
{{1, -1}, {0, -1}},
{{-1, 1}, {0, 1}},
}

Each array row corresponds to the vector in the directions array.

A row contains:

  • the diagonal check vector
  • the reverse check vector

Definition at line 22 of file draw_light.c.

22 {
23 {{1, 1}, {1, 0}}, // for up
24 {{-1, -1}, {-1, 0}},// for down
25 {{1, -1}, {0, -1}}, // for left
26 {{-1, 1}, {0, 1}}, // for right
27};

◆ map_arr

map_tile_t* map_arr

Definition at line 9 of file draw_light.c.

◆ map_height

int map_height

Definition at line 11 of file draw_light.c.

◆ map_width

int map_width

Definition at line 12 of file draw_light.c.

◆ player_position

vector2d_t player_position

Definition at line 13 of file draw_light.c.

◆ radius

int radius

Definition at line 14 of file draw_light.c.

◆ revealed_map_arr

map_tile_t* revealed_map_arr

Definition at line 10 of file draw_light.c.