1 | /* ncurses-minesweeper Copyright (c) 2021 Joshua 'joshuas3' Stockin |
2 | * <https://joshstock.in> |
3 | * <https://git.joshstock.in/ncurses-minesweeper> |
4 | * |
5 | * This software is licensed and distributed under the terms of the MIT License. |
6 | * See the MIT License in the LICENSE file of this project's root folder. |
7 | * |
8 | * This comment block and its contents, including this disclaimer, MUST be |
9 | * preserved in all copies or distributions of this software's source. |
10 | */ |
11 |
|
12 | // TODO: rewrite this POS |
13 |
|
14 | #include <ncurses.h> |
15 |
|
16 | #include "../state.h" |
17 | #include "../strings.h" |
18 | #include "pages.h" |
19 | #include "text.h" |
20 |
|
21 | int digit_input(int line, int col) { |
22 | // input of two digits for int |
23 | move(line, col); |
24 | clrtoeol(); |
25 |
|
26 | char in1, in2; |
27 | uint8_t n = 0; |
28 |
|
29 | // digit one (tens) |
30 | attron(A_UNDERLINE); |
31 | mvaddch(line, col, ' '); |
32 | while ((in1 = getch())) { |
33 | if (in1 >= '0' && in1 <= '9') { |
34 | n = 10 * (in1 - '0'); |
35 | break; |
36 | } else if (in1 > 0) // invalid input, beep |
37 | beep(); |
38 | } |
39 | attroff(A_UNDERLINE); |
40 | mvaddch(line, col, in1); |
41 |
|
42 | // digit two (ones) |
43 | attron(A_UNDERLINE); |
44 | mvaddch(line, col + 1, ' '); |
45 | while ((in2 = getch())) { |
46 | if (in2 >= '0' && in2 <= '9') { |
47 | n += in2 - '0'; |
48 | break; |
49 | } else if (in2 > 0) // invalid input, beep |
50 | beep(); |
51 | } |
52 | attroff(A_UNDERLINE); |
53 |
|
54 | return n; |
55 | } |
56 |
|
57 | int draw_options_screen(game_state *state, int ch) { |
58 | switch (ch) { |
59 | case -1: |
60 | return 0; |
61 | case KEY_DOWN: { |
62 | if (state->page_selection < 3) |
63 | state->page_selection++; |
64 | else |
65 | beep(); |
66 | break; |
67 | } |
68 | case KEY_UP: { |
69 | if (state->page_selection > 0) |
70 | state->page_selection--; |
71 | else |
72 | beep(); |
73 | break; |
74 | } |
75 | case KEY_RESIZE: |
76 | clear(); |
77 | break; |
78 | case ' ': |
79 | case 10: |
80 | case KEY_ENTER: { |
81 | if (state->page_selection == 3) { |
82 | clear(); |
83 | state->page = Title; |
84 | state->page_selection = 1; |
85 | return draw_title_screen(state, 0); |
86 | } |
87 | break; |
88 | } |
89 | case 0: |
90 | break; |
91 | default: |
92 | beep(); |
93 | } |
94 |
|
95 | int y = centery(); |
96 |
|
97 | attron(A_BOLD | COLOR_PAIR(1)); |
98 | mvaddstr(y - 3, centerx(options_screen_title), options_screen_title); |
99 | attroff(A_BOLD); |
100 |
|
101 | int x = (int)(COLS / 2); |
102 | mvaddstr(y - 1, x - 10, options_screen_width); |
103 | mvaddstr(y, x - 10, options_screen_height); |
104 | mvaddstr(y + 1, x - 10, options_screen_minecount); |
105 |
|
106 | if (state->page_selection == 0) attron(A_STANDOUT); |
107 | mvprintw(y - 1, x + 4, "%02d", state->board->width); |
108 | if (state->page_selection == 0) attroff(A_STANDOUT); |
109 |
|
110 | if (state->page_selection == 1) attron(A_STANDOUT); |
111 | mvprintw(y, x + 4, "%02d", state->board->height); |
112 | if (state->page_selection == 1) attroff(A_STANDOUT); |
113 |
|
114 | if (state->page_selection == 2) attron(A_STANDOUT); |
115 | mvprintw(y + 1, x + 4, "%02d", state->board->mine_count); |
116 | if (state->page_selection == 2) attroff(A_STANDOUT); |
117 |
|
118 | if (state->page_selection == 3) attron(A_STANDOUT); |
119 | mvaddstr(y + 3, centerx(options_screen_back), options_screen_back); |
120 | if (state->page_selection == 3) attroff(A_STANDOUT); |
121 |
|
122 | if (ch == ' ' || ch == 10 || ch == KEY_ENTER) { |
123 | int in = 0; |
124 | switch (state->page_selection) { |
125 | case 0: { |
126 | while ((in = digit_input(y - 1, x + 4))) { |
127 | if (state->board->mine_count < in * state->board->height - 8) |
128 | break; |
129 | else |
130 | beep(); |
131 | } |
132 | state->board->width = in; |
133 | attron(A_STANDOUT); |
134 | mvprintw(y - 1, x + 4, "%02d", state->board->width); |
135 | attroff(A_STANDOUT); |
136 | break; |
137 | } |
138 | case 1: { |
139 | while ((in = digit_input(y, x + 4))) { |
140 | if (state->board->mine_count < state->board->width * in - 8) |
141 | break; |
142 | else |
143 | beep(); |
144 | } |
145 | state->board->height = in; |
146 | attron(A_STANDOUT); |
147 | mvprintw(y, x + 4, "%02d", state->board->height); |
148 | attroff(A_STANDOUT); |
149 | break; |
150 | } |
151 | case 2: { |
152 | while ((in = digit_input(y + 1, x + 4))) { |
153 | if (in < state->board->width * state->board->height - 8) |
154 | break; |
155 | else |
156 | beep(); |
157 | } |
158 | state->board->mine_count = in; |
159 | state->board->mines_left = in; |
160 | attron(A_STANDOUT); |
161 | mvprintw(y + 1, x + 4, "%02d", state->board->mine_count); |
162 | attroff(A_STANDOUT); |
163 | break; |
164 | } |
165 | } |
166 | state->board->current_cell = state->board->width / 2; |
167 | } |
168 |
|
169 | attroff(COLOR_PAIR(1)); |
170 |
|
171 | return 0; |
172 | } |
173 |
|