-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.c
151 lines (124 loc) · 3.76 KB
/
main.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
#include <ncurses.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <math.h>
int WINSIZE_CHANGE = 0;
int PADDLE_SIZE = 6;
// Window resize callback
void winResize(int dummyvar) {
// Set flag to indicate window size changed
WINSIZE_CHANGE = 1;
// Update terminal data so that getmaxyx uses the
// right data
struct winsize size;
if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
resize_term(size.ws_row, size.ws_col);
}
}
// Draw the paddle
void drawPaddle(int ypos, int xpos) {
for(int i = 0; i <= PADDLE_SIZE; i++) {
mvprintw(ypos + i, xpos, "*");
}
}
int main(int argc, char **argv) {
// position, screen boundaries, direction constants
int x = 11, y = 11,
maxX = 0, maxY = 0,
nextX = 0, nextY = 0,
dirX = 1, dirY = 1,
padX = 10, padY = 10;
double relposbX = 0,
relpospY = 0,
relposbY = 0;
char kbinput;
// Initialize screen
// Use non-blocking getch()
WINDOW *w = initscr();
cbreak();
nodelay(w, TRUE);
noecho();
curs_set(FALSE);
// Get max Y and X values for terminal
getmaxyx(stdscr, maxY, maxX);
// Set up signal handler in case user resizes terminal
signal(SIGWINCH, winResize);
while(true) {
// Our window size has changed
// Recalculate relative positions
if(WINSIZE_CHANGE) {
usleep(1500000);
getmaxyx(stdscr, maxY, maxX);
x = round(maxX * relposbX);
y = round(maxY * relposbY);
padY = round(maxY * relpospY);
WINSIZE_CHANGE = 0;
} else {
// Wait, then redraw at new position
usleep(50000);
clear();
printw("[ and ] to move paddle. Q to quit\n");
mvprintw(y, x, "O");
kbinput = getch();
// Very basic keyboard handling
// Use '[' and ']' to move paddle
if(kbinput != ERR) {
if(kbinput == '[' && padY >= 2) {
padY -= 2;
}
if(kbinput == ']'
&& padY < (maxY - PADDLE_SIZE - 2)) {
padY += 2;
}
if(kbinput == 'q' || kbinput == 'Q') {
endwin();
printf("Thanks for playing!\n");
return 0;
}
}
drawPaddle(padY, padX);
refresh();
// Handle bounce off of the walls
nextX = x + dirX;
nextY = y + dirY;
// Very basic paddle bounce
if(nextX == 10
&& dirX == -1
&& padY <= nextY
&& (padY + PADDLE_SIZE) >= nextY) {
dirX *= -1;
}
if(nextX == 9
&& dirX == 1
&& padY <= nextY
&& (padY + PADDLE_SIZE) >= nextY) {
dirX *= -1;
}
// Hit X boundary, change direction
if(nextX >= maxX || nextX < 0) {
dirX *= -1;
}
else {
x += dirX;
}
// Hit Y boundary, change direction
if(nextY >= maxY || nextY < 0) {
dirY *= -1;
}
else {
y += dirY;
}
if(maxX > 0 && maxY > 0) {
relposbX = (double) x / maxX;
relposbY = (double) y / maxY;
relpospY = (double) padY / maxY;
}
}
}
endwin();
return 0;
}