1 /* Test retrieving and settings possible modes. */
2 #include <allegro5/allegro.h>
3 #include <allegro5/allegro_font.h>
4 #include <allegro5/allegro_primitives.h>
5 #include <stdio.h>
6
7 #include "common.c"
8
9 ALLEGRO_FONT *font;
10 ALLEGRO_COLOR white;
11 int font_h;
12 int modes_count;
13 int options_count;
14 char status[256];
15 int flags, old_flags;
16
17 int visible_rows;
18 int first_visible_row;
19
20 int selected_column;
21 int selected_mode;
22 int selected_option;
23
24 #define X(x, m) {#x, ALLEGRO_##x, 0, m, 0}
25 struct {
26 char const *name;
27 int option;
28 int value, max_value;
29 int required;
30 } options[] = {
31 X(COLOR_SIZE, 32),
32 X(RED_SIZE, 8),
33 X(GREEN_SIZE, 8),
34 X(BLUE_SIZE, 8),
35 X(ALPHA_SIZE, 8),
36 X(RED_SHIFT, 32),
37 X(GREEN_SHIFT, 32),
38 X(BLUE_SHIFT, 32),
39 X(ALPHA_SHIFT, 32),
40 X(DEPTH_SIZE, 32),
41 X(FLOAT_COLOR, 1),
42 X(FLOAT_DEPTH, 1),
43 X(STENCIL_SIZE, 32),
44 X(SAMPLE_BUFFERS, 1),
45 X(SAMPLES, 8),
46 X(RENDER_METHOD, 2),
47 X(SINGLE_BUFFER, 1),
48 X(SWAP_METHOD, 1),
49 X(VSYNC, 2),
50 X(COMPATIBLE_DISPLAY, 1),
51 X(MAX_BITMAP_SIZE, 65536),
52 X(SUPPORT_NPOT_BITMAP, 1),
53 X(CAN_DRAW_INTO_BITMAP, 1),
54 X(SUPPORT_SEPARATE_ALPHA, 1),
55 };
56 #undef X
57 static char const *flag_names[32];
init_flags(void)58 static void init_flags(void)
59 {
60 int i;
61 #define X(f) if (1 << i == ALLEGRO_##f) flag_names[i] = #f;
62 for (i = 0; i < 32; i++) {
63 X(WINDOWED)
64 X(FULLSCREEN)
65 X(OPENGL)
66 X(RESIZABLE)
67 X(FRAMELESS)
68 X(GENERATE_EXPOSE_EVENTS)
69 X(FULLSCREEN_WINDOW)
70 X(MINIMIZED)
71 }
72 #undef X
73 }
74
load_font(void)75 static void load_font(void)
76 {
77 font = al_create_builtin_font();
78 if (!font) {
79 abort_example("Error creating builtin font\n");
80 }
81 font_h = al_get_font_line_height(font);
82 }
83
display_options(ALLEGRO_DISPLAY * display)84 static void display_options(ALLEGRO_DISPLAY *display)
85 {
86 int i, y = 10;
87 int x = 10;
88 int n = options_count;
89 int dw = al_get_display_width(display);
90 int dh = al_get_display_height(display);
91 ALLEGRO_COLOR c;
92
93 modes_count = al_get_num_display_modes();
94
95 c = al_map_rgb_f(0.8, 0.8, 1);
96 al_draw_textf(font, c, x, y, 0, "Create new display");
97 y += font_h;
98 for (i = first_visible_row; i < modes_count + 2 &&
99 i < first_visible_row + visible_rows; i++) {
100 ALLEGRO_DISPLAY_MODE mode;
101 if (i > 1) {
102 al_get_display_mode(i - 2, &mode);
103 }
104 else if (i == 1) {
105 mode.width = 800;
106 mode.height = 600;
107 mode.format = 0;
108 mode.refresh_rate = 0;
109 }
110 else {
111 mode.width = 800;
112 mode.height = 600;
113 mode.format = 0;
114 mode.refresh_rate = 0;
115 }
116 if (selected_column == 0 && selected_mode == i) {
117 c = al_map_rgb_f(1, 1, 0);
118 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
119 al_draw_filled_rectangle(x, y, x + 300, y + font_h, c);
120 }
121 c = al_map_rgb_f(0, 0, 0);
122 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
123 if ((i == first_visible_row && i > 0) ||
124 (i == first_visible_row + visible_rows - 1 &&
125 i < modes_count + 1)) {
126 al_draw_textf(font, c, x, y, 0, "...");
127 }
128 else {
129 al_draw_textf(font, c, x, y, 0, "%s %d x %d (fmt: %x, %d Hz)",
130 i > 1 ? "Fullscreen" : i == 0 ? "Windowed" : "FS Window",
131 mode.width, mode.height, mode.format, mode.refresh_rate);
132 }
133 y += font_h;
134 }
135
136 x = dw / 2 + 10;
137 y = 10;
138 c = al_map_rgb_f(0.8, 0.8, 1);
139 al_draw_textf(font, c, x, y, 0, "Options for new display");
140 al_draw_textf(font, c, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "(current display)");
141 y += font_h;
142 for (i = 0; i < n; i++) {
143 if (selected_column == 1 && selected_option == i) {
144 c = al_map_rgb_f(1, 1, 0);
145 al_draw_filled_rectangle(x, y, x + 300, y + font_h, c);
146 }
147
148 switch (options[i].required) {
149 case ALLEGRO_REQUIRE: c = al_map_rgb_f(0.5, 0, 0); break;
150 case ALLEGRO_SUGGEST: c = al_map_rgb_f(0, 0, 0); break;
151 case ALLEGRO_DONTCARE: c = al_map_rgb_f(0.5, 0.5, 0.5); break;
152 }
153 al_draw_textf(font, c, x, y, 0, "%s: %d (%s)", options[i].name,
154 options[i].value,
155 options[i].required == ALLEGRO_REQUIRE ? "required" :
156 options[i].required == ALLEGRO_SUGGEST ? "suggested" :
157 "ignored");
158
159 c = al_map_rgb_f(0.9, 0.5, 0.3);
160 al_draw_textf(font, c, dw - 10, y, ALLEGRO_ALIGN_RIGHT, "%d",
161 al_get_display_option(display, options[i].option));
162 y += font_h;
163 }
164
165 c = al_map_rgb_f(0, 0, 0.8);
166 x = 10;
167 y = dh - font_h - 10;
168 y -= font_h;
169 al_draw_textf(font, c, x, y, 0, "PageUp/Down: modify values");
170 y -= font_h;
171 al_draw_textf(font, c, x, y, 0, "Return: set mode or require option");
172 y -= font_h;
173 al_draw_textf(font, c, x, y, 0, "Cursor keys: change selection");
174
175 y -= font_h * 2;
176 for (i = 0; i < 32; i++) {
177 if (flag_names[i]) {
178 if (flags & (1 << i)) c = al_map_rgb_f(0.5, 0, 0);
179 else if (old_flags & (1 << i)) c = al_map_rgb_f(0.5, 0.4, 0.4);
180 else continue;
181 al_draw_text(font, c, x, y, 0, flag_names[i]);
182 x += al_get_text_width(font, flag_names[i]) + 10;
183 }
184 }
185
186 c = al_map_rgb_f(1, 0, 0);
187 al_draw_text(font, c, dw / 2, dh - font_h, ALLEGRO_ALIGN_CENTRE, status);
188 }
189
update_ui(void)190 static void update_ui(void)
191 {
192 int h = al_get_display_height(al_get_current_display());
193 visible_rows = h / font_h - 10;
194 }
195
main(int argc,char ** argv)196 int main(int argc, char **argv)
197 {
198 ALLEGRO_DISPLAY *display;
199 ALLEGRO_EVENT_QUEUE *queue;
200 ALLEGRO_TIMER *timer;
201 bool redraw = false;
202
203 (void)argc;
204 (void)argv;
205
206 if (!al_init()) {
207 abort_example("Could not init Allegro.\n");
208 }
209 init_flags();
210 al_init_primitives_addon();
211
212 white = al_map_rgba_f(1, 1, 1, 1);
213
214 al_install_keyboard();
215 al_install_mouse();
216 al_init_font_addon();
217
218 display = al_create_display(800, 600);
219 if (!display) {
220 abort_example("Could not create display.\n");
221 }
222
223 load_font();
224
225 timer = al_create_timer(1.0 / 60);
226
227 modes_count = al_get_num_display_modes();
228 options_count = sizeof(options) / sizeof(options[0]);
229
230 update_ui();
231
232 al_clear_to_color(al_map_rgb_f(1, 1, 1));
233 display_options(display);
234 al_flip_display();
235
236 queue = al_create_event_queue();
237 al_register_event_source(queue, al_get_keyboard_event_source());
238 al_register_event_source(queue, al_get_mouse_event_source());
239 al_register_event_source(queue, al_get_display_event_source(display));
240 al_register_event_source(queue, al_get_timer_event_source(timer));
241
242 al_start_timer(timer);
243
244 while (1) {
245 ALLEGRO_EVENT event;
246 al_wait_for_event(queue, &event);
247 if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
248 break;
249 }
250 if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {
251 if (event.mouse.button == 1) {
252 int dw = al_get_display_width(display);
253 int y = 10;
254 int row = (event.mouse.y - y) / font_h - 1;
255 int column = event.mouse.x / (dw / 2);
256 if (column == 0) {
257 if (row >= 0 && row <= modes_count) {
258 selected_column = column;
259 selected_mode = row;
260 redraw = true;
261 }
262 }
263 if (column == 1) {
264 if (row >= 0 && row < options_count) {
265 selected_column = column;
266 selected_option = row;
267 redraw = true;
268 }
269 }
270 }
271 }
272 if (event.type == ALLEGRO_EVENT_TIMER) {
273 int f = al_get_display_flags(display);
274 if (f != flags) {
275 redraw = true;
276 flags = f;
277 old_flags |= f;
278 }
279 }
280 if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
281 int change;
282 if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
283 break;
284 if (event.keyboard.keycode == ALLEGRO_KEY_LEFT) {
285 selected_column = 0;
286 redraw = true;
287 }
288 if (event.keyboard.keycode == ALLEGRO_KEY_RIGHT) {
289 selected_column = 1;
290 redraw = true;
291 }
292 if (event.keyboard.keycode == ALLEGRO_KEY_UP) {
293 if (selected_column == 0) selected_mode -= 1;
294 if (selected_column == 1) selected_option -= 1;
295 redraw = true;
296 }
297 if (event.keyboard.keycode == ALLEGRO_KEY_DOWN) {
298 if (selected_column == 0) selected_mode += 1;
299 if (selected_column == 1) selected_option += 1;
300 redraw = true;
301 }
302 if (event.keyboard.keycode == ALLEGRO_KEY_ENTER) {
303 if (selected_column == 0) {
304 ALLEGRO_DISPLAY_MODE mode;
305 ALLEGRO_DISPLAY *new_display;
306 if (selected_mode > 1) {
307 al_get_display_mode(selected_mode - 2, &mode);
308 al_set_new_display_flags(ALLEGRO_FULLSCREEN);
309 }
310 else if (selected_mode == 1) {
311 mode.width = 800;
312 mode.height = 600;
313 al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW);
314 }
315 else {
316 mode.width = 800;
317 mode.height = 600;
318 al_set_new_display_flags(ALLEGRO_WINDOWED);
319 }
320
321 al_destroy_font(font);
322 font = NULL;
323
324 new_display = al_create_display(
325 mode.width, mode.height);
326 if (new_display) {
327 al_destroy_display(display);
328 display = new_display;
329 al_set_target_backbuffer(display);
330 al_register_event_source(queue,
331 al_get_display_event_source(display));
332 update_ui();
333 sprintf(status, "Display creation succeeded.");
334 }
335 else {
336 sprintf(status, "Display creation failed.");
337 }
338
339 load_font();
340 }
341 if (selected_column == 1) {
342 options[selected_option].required += 1;
343 options[selected_option].required %= 3;
344 al_set_new_display_option(
345 options[selected_option].option,
346 options[selected_option].value,
347 options[selected_option].required);
348 }
349 redraw = true;
350 }
351 change = 0;
352 if (event.keyboard.keycode == ALLEGRO_KEY_PGUP) change = 1;
353 if (event.keyboard.keycode == ALLEGRO_KEY_PGDN) change = -1;
354 if (change && selected_column == 1) {
355 options[selected_option].value += change;
356 if (options[selected_option].value < 0)
357 options[selected_option].value = 0;
358 if (options[selected_option].value >
359 options[selected_option].max_value)
360 options[selected_option].value =
361 options[selected_option].max_value;
362 al_set_new_display_option(options[selected_option].option,
363 options[selected_option].value,
364 options[selected_option].required);
365 redraw = true;
366 }
367 }
368
369 if (selected_mode < 0) selected_mode = 0;
370 if (selected_mode > modes_count + 1)
371 selected_mode = modes_count + 1;
372 if (selected_option < 0) selected_option = 0;
373 if (selected_option >= options_count)
374 selected_option = options_count - 1;
375 if (selected_mode < first_visible_row)
376 first_visible_row = selected_mode;
377 if (selected_mode > first_visible_row + visible_rows - 1)
378 first_visible_row = selected_mode - visible_rows + 1;
379
380 if (redraw && al_is_event_queue_empty(queue)) {
381 redraw = false;
382 al_clear_to_color(al_map_rgb_f(1, 1, 1));
383 display_options(display);
384 al_flip_display();
385 }
386 }
387
388 al_destroy_font(font);
389
390 return 0;
391 }
392
393 /* vim: set sts=3 sw=3 et: */
394