-
Notifications
You must be signed in to change notification settings - Fork 0
/
fruit.c
155 lines (146 loc) · 6.76 KB
/
fruit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#define _POSIX_C_SOURCE 200112L
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include "mzapo_parlcd.h"
#include "mzapo_phys.h"
#include "mzapo_regs.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include "fruit.h"
// guarantee that fruit will not spawn inside of snake is not implemented - depending on snake representation
void generate_fruit(unsigned char **frame_buffer, int* last_fruit_x_coord, int* last_fruit_y_coord, int snake_size) {
// variables
int width = 480;
int height = 320;
//Erase picked up fruit
for (int i = 0; i < snake_size*2; i++) {
for (int j = 0; j < snake_size*2; j++) {
if (frame_buffer[*(last_fruit_x_coord) - snake_size + i][*(last_fruit_y_coord) - snake_size + j] == 10) {
frame_buffer[*(last_fruit_x_coord) - snake_size + i][*(last_fruit_y_coord) - snake_size + j] = 0;
}
}
}
// generate random coords
int random_x_coord = rand() % (width - 1);
int random_y_coord = rand() % (height - 1);
//calculate distance from previous fruit
double x_distance = abs(*(last_fruit_x_coord) - random_x_coord);
double y_distance = abs(*(last_fruit_y_coord) - random_y_coord);
int fruit_distance = sqrt(pow(x_distance, 2) + pow(y_distance, 2));
//place fruit into buffer
if(fruit_distance >= 7) {
if(frame_buffer[random_x_coord][random_y_coord] == 0) {
frame_buffer[random_x_coord][random_y_coord] = 10;
random_x_coord = random_x_coord - snake_size / 2;
random_y_coord = random_y_coord - snake_size / 2;
for (int i = 0; i < snake_size; i++) {
for (int j = 0; j < snake_size; j++) {
frame_buffer[random_x_coord + i][random_y_coord + j] = 10;
}
}
*(last_fruit_x_coord) = random_x_coord;
*(last_fruit_y_coord) = random_y_coord;
} else {
generate_fruit(frame_buffer, last_fruit_x_coord, last_fruit_y_coord, snake_size);
}
} else {
generate_fruit(frame_buffer, last_fruit_x_coord, last_fruit_y_coord, snake_size);
}
}
//Triggers when a snake eats a fruit
void fruit_get(unsigned int* red_score, unsigned int* blue_score, unsigned char* mem_base, struct timespec* clock, bool is_two_players, int player) {
//The game progessively gets faster when fruit is picked up
timer_decrement(clock);
//If two player mode is enabled, each player takes one half of the led display and one RGB diode
if (is_two_players) {
if (player == 1) {
if (((*(red_score) >> 1) & 0x0000FFFF) > 0) {
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = 0x00FFFF00;
for (int i = 0; i < 8; i++) {
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x11111111;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x22222222;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x44444444;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x88888888;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
}
*(red_score) = 0x80000000;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = *(red_score) | *(blue_score);
} else {
if (*(red_score) == 0) {
*(red_score) = 0x80000000;
} else {
*(red_score)>>=1;
*(red_score) += 0x80000000;
}
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = *(red_score) | *(blue_score);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = 0x0000FF00;
}
} else if (player == 2) {
if (((*(blue_score) << 1) & 0xFFFF0000) > 0) {
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = 0x00FFFF00;
for (int i = 0; i < 8; i++) {
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x11111111;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x22222222;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x44444444;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x88888888;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
}
*(blue_score) = 1;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = *(blue_score) | *(red_score);
} else {
if (*(blue_score) == 0) {
*(blue_score) = 1;
} else {
*(blue_score)<<=1;
*(blue_score) += 0x1;
}
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = *(blue_score) | *(red_score);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = 0x0000FF00;
}
}
} else {
//If score reached max, celebrate, then reset score
if (*(red_score) >= 0xFFFFFFFF) {
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = 0x00FFFF00;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = 0x00FFFF00;
for (int i = 0; i < 8; i++) {
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x11111111;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x22222222;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x44444444;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = 0x88888888;
clock_nanosleep(CLOCK_MONOTONIC, 0 , clock, NULL);
}
*(red_score) = 1;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = *(red_score);
} else {
if (*(red_score) == 0) {
*(red_score) = 1;
} else {
*(red_score)<<=1;
*(red_score) += 0x1;
}
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_LINE_o) = *(red_score);
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB1_o) = 0x0000FF00;
*(volatile uint32_t*)(mem_base + SPILED_REG_LED_RGB2_o) = 0x0000FF00;
}
}
}
void timer_decrement(struct timespec* clock) {
clock->tv_nsec = clock->tv_nsec - 30000;
}