Mercurial > public > algo-animator
comparison src/main.c @ 30:f945bcc3571f
refactor
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Thu, 29 Jun 2023 17:48:36 +0100 |
parents | dae463bbf5ca |
children | 61104b22a25d |
comparison
equal
deleted
inserted
replaced
29:dae463bbf5ca | 30:f945bcc3571f |
---|---|
1 #include "algorithms.h" | 1 #include "algorithms.h" |
2 #include <GL/glut.h> | |
3 #include <pthread.h> | |
4 #include <ft2build.h> | |
5 #include FT_FREETYPE_H | |
6 | 2 |
7 | 3 |
8 int window_width = 1920; | 4 int window_width = 1920; |
9 int window_height = 1080; | 5 int window_height = 1080; |
10 int vpadding = 150; | 6 int vpadding = 150; |
11 int rect_width = 5; | 7 int rect_width = 30; |
12 int space = 1; | 8 int space = 1; |
13 | 9 |
14 struct Algo algos[1]; | 10 struct Algo algos[2]; |
15 int selected_algo = 0; | 11 int selected_algo = 0; |
12 int algos_size; | |
16 | 13 |
17 struct AlgoArgs algo_args; | 14 struct AlgoArgs algo_args; |
15 struct ThreadState thread_state; | |
18 | 16 |
19 FT_Library ft_library; | 17 FT_Library ft_library; |
20 FT_Face ft_face; | 18 FT_Face ft_face; |
21 | |
22 pthread_t thread_id; | |
23 | 19 |
24 | 20 |
25 void render_text(int x, int y, char* text) { | 21 void render_text(int x, int y, char* text) { |
26 for (const char *c = text; *c; c++) { | 22 for (const char *c = text; *c; c++) { |
27 | 23 |
47 | 43 |
48 FT_GlyphSlot slot = ft_face->glyph; | 44 FT_GlyphSlot slot = ft_face->glyph; |
49 FT_Bitmap* glyph_bitmap = &slot->bitmap; | 45 FT_Bitmap* glyph_bitmap = &slot->bitmap; |
50 | 46 |
51 // Flip the bitmap vertically | 47 // Flip the bitmap vertically |
52 unsigned char* flipped_bitmap = (unsigned char*)malloc(glyph_bitmap->width * glyph_bitmap->rows); | 48 unsigned char* flipped_bitmap = (unsigned char*)malloc( |
49 glyph_bitmap->width * glyph_bitmap->rows); | |
53 | 50 |
54 for (int row = 0; row < glyph_bitmap->rows; row++) { | 51 for (int row = 0; row < glyph_bitmap->rows; row++) { |
55 unsigned char* src_row = glyph_bitmap->buffer + (row * glyph_bitmap->width); | 52 unsigned char* src_row = glyph_bitmap->buffer + (row * glyph_bitmap->width); |
56 unsigned char* dest_row = flipped_bitmap + ((glyph_bitmap->rows - row - 1) * glyph_bitmap->width); | 53 unsigned char* dest_row = flipped_bitmap + ((glyph_bitmap->rows - row - 1) * |
54 glyph_bitmap->width); | |
55 | |
57 memcpy(dest_row, src_row, glyph_bitmap->width); | 56 memcpy(dest_row, src_row, glyph_bitmap->width); |
58 } | 57 } |
59 | 58 |
60 glyph_bitmap->buffer = flipped_bitmap; | 59 glyph_bitmap->buffer = flipped_bitmap; |
61 | 60 |
62 // Calculate the adjusted y position based on the glyph's bearing | 61 // Calculate the adjusted y position based on the glyph's bearing |
63 int adjusted_y = y + (slot->bitmap_top - glyph_bitmap->rows); | 62 int adjusted_y = y + (slot->bitmap_top - glyph_bitmap->rows); |
64 | 63 |
65 glRasterPos2f(x, adjusted_y); | 64 glRasterPos2f(x, adjusted_y); |
66 glDrawPixels(glyph_bitmap->width, glyph_bitmap->rows, GL_LUMINANCE, GL_UNSIGNED_BYTE, glyph_bitmap->buffer); | 65 glDrawPixels(glyph_bitmap->width, glyph_bitmap->rows, GL_LUMINANCE, |
66 GL_UNSIGNED_BYTE, glyph_bitmap->buffer); | |
67 | 67 |
68 x += slot->advance.x / 64; | 68 x += slot->advance.x / 64; |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
74 glClear(GL_COLOR_BUFFER_BIT); | 74 glClear(GL_COLOR_BUFFER_BIT); |
75 | 75 |
76 glBegin(GL_QUADS); | 76 glBegin(GL_QUADS); |
77 | 77 |
78 int x = 0; | 78 int x = 0; |
79 for (int i = 0; i < algo_args.arr_size; i++) { | 79 for (int i = 0; i < algo_args.arr_size - 1; i++) { |
80 | 80 |
81 if (algo_args.arr[i].current) { | 81 if (algo_args.arr[i].current) { |
82 glColor3f(1.0, 1.0, 1.0); | 82 glColor3f(1.0, 1.0, 1.0); |
83 } else { | 83 } else { |
84 glColor3f(1.0, 0.7569, 0.0); | 84 glColor3f(1.0, 0.7569, 0.0); |
95 | 95 |
96 // Bottom right | 96 // Bottom right |
97 glVertex2f(x + rect_width, vpadding); | 97 glVertex2f(x + rect_width, vpadding); |
98 | 98 |
99 x += rect_width + space; | 99 x += rect_width + space; |
100 | |
101 algo_args.arr[i].current = false; | |
102 } | 100 } |
103 | 101 |
104 glEnd(); | 102 glEnd(); |
105 | 103 |
106 // Render text | 104 // Render text |
117 sprintf(text, "Number of elements: %i", algo_args.arr_size); | 115 sprintf(text, "Number of elements: %i", algo_args.arr_size); |
118 render_text(500, window_height - 50, text); | 116 render_text(500, window_height - 50, text); |
119 | 117 |
120 sprintf(text, "Comparisons: %i", algo_args.comparisons); | 118 sprintf(text, "Comparisons: %i", algo_args.comparisons); |
121 render_text(500, window_height - 80, text); | 119 render_text(500, window_height - 80, text); |
120 | |
121 // Top: Column 3 | |
122 if (algo_args.pause && !algo_args.sequentially) { | |
123 sprintf(text, "PAUSED"); | |
124 render_text(window_width - 400, window_height - 50, text); | |
125 } | |
126 | |
127 if (algo_args.sequentially) { | |
128 sprintf(text, "SEQUENTIAL MODE"); | |
129 render_text(window_width - 400, window_height - 80, text); | |
130 } | |
122 | 131 |
123 // Bottom: Column 1 | 132 // Bottom: Column 1 |
124 render_text(20, vpadding - 50, "Press a or s to select an algorithm."); | 133 render_text(20, vpadding - 50, "Press a or s to select an algorithm."); |
125 render_text(20, vpadding - 80, "Press u or d to modify speed."); | 134 render_text(20, vpadding - 80, "Press u or d to modify speed."); |
126 render_text(20, vpadding - 110, "Press r to randomize the array."); | 135 render_text(20, vpadding - 110, "Press r to randomize the array."); |
127 | 136 |
128 // Bottom: Column 2 | 137 // Bottom: Column 2 |
129 render_text(800, vpadding - 50, "Press enter to run the algorithm."); | 138 render_text(800, vpadding - 50, "Press enter to run the algorithm."); |
130 render_text(800, vpadding - 80, "Press p to pause the algorithm."); | 139 render_text(800, vpadding - 80, "Press p to pause the algorithm."); |
140 render_text(800, vpadding - 110, "Press q to enable or disable sequential mode."); | |
131 | 141 |
132 glutSwapBuffers(); | 142 glutSwapBuffers(); |
133 } | 143 } |
134 | 144 |
135 | 145 |
140 | 150 |
141 void keyboard(unsigned char key, int x, int y) { | 151 void keyboard(unsigned char key, int x, int y) { |
142 | 152 |
143 // s: Next algorithm | 153 // s: Next algorithm |
144 if (key == 115) { | 154 if (key == 115) { |
145 | 155 algorithm_selector(algos, algos_size, 1, &selected_algo); |
146 } | 156 } |
147 | 157 |
148 // a: Previous algorithm | 158 // a: Previous algorithm |
149 if (key == 97) { | 159 if (key == 97) { |
150 | 160 algorithm_selector(algos, algos_size, -1, &selected_algo); |
151 } | 161 } |
152 | 162 |
153 // r: Reset state | 163 // r: Reset state |
154 if (key == 114) { | 164 if (key == 114) { |
155 randomize_array(algo_args.arr, algo_args.arr_size); | 165 reset_state(&algo_args, &thread_state); |
156 } | 166 } |
157 | 167 |
158 // u: Increase speed | 168 // u: Increase speed |
159 if (key == 117) { | 169 if (key == 117) { |
160 algo_args.delay += 10; | 170 change_speed(&algo_args, 10); |
161 } | 171 } |
162 | 172 |
163 // d: reduce speed | 173 // d: reduce speed |
164 if (key == 100) { | 174 if (key == 100) { |
165 if (algo_args.delay > 10) { | 175 change_speed(&algo_args, -10); |
166 algo_args.delay -= 10; | |
167 } | |
168 } | 176 } |
169 | 177 |
170 // enter: Run program | 178 // enter: Run program |
171 if (key == 13) { | 179 if (key == 13) { |
172 pthread_create(&thread_id, NULL, algos[selected_algo].function, (void *)&algo_args); | 180 run(&algo_args, algos, selected_algo, &thread_state); |
173 } | 181 } |
174 | 182 |
175 // p: Pause program | 183 // p: Pause program |
176 if (key == 112) { | 184 if (key == 112) { |
177 | 185 algo_args.pause = true; |
186 } | |
187 | |
188 // q: Enable sequential mode | |
189 if (key == 113) { | |
190 algo_args.sequentially = !algo_args.sequentially; | |
178 } | 191 } |
179 } | 192 } |
180 | 193 |
181 | 194 |
182 void setup_gl() { | 195 void setup_gl() { |
234 } | 247 } |
235 } | 248 } |
236 | 249 |
237 | 250 |
238 int main(int argc, char** argv) { | 251 int main(int argc, char** argv) { |
252 algo_args.arr_size = window_width / (rect_width + space); | |
253 algo_args.arr = malloc(algo_args.arr_size * sizeof(struct Element)); | |
239 algo_args.comparisons = 0; | 254 algo_args.comparisons = 0; |
255 algo_args.pause = false; | |
256 algo_args.sequentially = false; | |
240 algo_args.delay = 100; | 257 algo_args.delay = 100; |
241 | 258 |
242 strcpy(algos[0].name, "Bubble sort"); | 259 strcpy(algos[0].name, "Bubble sort"); |
243 algos[0].function = bubble_sort; | 260 algos[0].function = bubble_sort; |
244 | 261 |
245 algo_args.arr_size = window_width / (rect_width + space); | 262 strcpy(algos[1].name, "Selection sort"); |
246 algo_args.arr = malloc(algo_args.arr_size * sizeof(struct Element)); | 263 algos[1].function = selection_sort; |
264 | |
265 algos_size = sizeof(algos) / sizeof(algos[0]); | |
247 | 266 |
248 create_array(algo_args.arr, algo_args.arr_size, window_height, vpadding); | 267 create_array(algo_args.arr, algo_args.arr_size, window_height, vpadding); |
249 randomize_array(algo_args.arr, algo_args.arr_size); | 268 randomize_array(algo_args.arr, algo_args.arr_size); |
250 | 269 |
251 glutInit(&argc, argv); | 270 glutInit(&argc, argv); |