1 /*
2 * Example program for the Allegro library.
3 *
4 * From left to right you should see Red, Green, Blue gradients.
5 */
6
7 #define ALLEGRO_UNSTABLE
8 #include "allegro5/allegro.h"
9
10 #include "common.c"
11
12 enum Mode
13 {
14 MODE_VIDEO,
15 MODE_MEMORY,
16 MODE_BACKBUFFER
17 };
18
fill(ALLEGRO_BITMAP * bitmap,int lock_flags)19 static void fill(ALLEGRO_BITMAP *bitmap, int lock_flags)
20 {
21 ALLEGRO_LOCKED_REGION *locked;
22 uint8_t *ptr;
23 int i, j;
24
25 /* Locking the bitmap means, we work directly with pixel data. We can
26 * choose the format we want to work with, which may imply conversions, or
27 * use the bitmap's actual format so we can work directly with the bitmap's
28 * pixel data.
29 * We use a 16-bit format and odd positions and sizes to increase the
30 * chances of uncovering bugs.
31 */
32 locked = al_lock_bitmap_region(bitmap, 193, 65, 3*127, 127,
33 ALLEGRO_PIXEL_FORMAT_RGB_565, lock_flags);
34 if (!locked)
35 return;
36
37 for (j = 0; j < 127; j++) {
38 ptr = (uint8_t *)locked->data + j * locked->pitch;
39
40 for (i = 0; i < 3*127; i++) {
41 uint8_t red;
42 uint8_t green;
43 uint8_t blue;
44 uint16_t col;
45 uint16_t *cptr = (uint16_t *)ptr;
46
47 if (j == 0 || j == 126 || i == 0 || i == 3*127-1) {
48 red = green = blue = 0;
49 }
50 else if (i < 127) {
51 red = 255;
52 green = blue = j*2;
53 }
54 else if (i < 2*127) {
55 green = 255;
56 red = blue = j*2;
57 }
58 else {
59 blue = 255;
60 red = green = j*2;
61 }
62
63 /* The RGB_555 format means, the 16 bits per pixel are laid out like
64 * this, least significant bit right: RRRRR GGGGGG BBBBB
65 * Because the byte order can vary per platform (big endian or
66 * little endian) we encode an integer and store that
67 * directly rather than storing each component separately.
68 *
69 * In READWRITE mode the light blue background should should through
70 * the stipple pattern.
71 */
72 if ((lock_flags & ALLEGRO_LOCK_WRITEONLY) || (j + i) % 2 == 1) {
73 col = ((red/8) << 11) | ((green/4) << 5) | (blue/8);
74 *cptr = col;
75 }
76 ptr += 2;
77 }
78 }
79 al_unlock_bitmap(bitmap);
80 }
81
draw(ALLEGRO_DISPLAY * display,enum Mode mode,int lock_flags)82 static void draw(ALLEGRO_DISPLAY *display, enum Mode mode, int lock_flags)
83 {
84 ALLEGRO_BITMAP *bitmap;
85
86 /* Create the bitmap to lock, or use the display backbuffer. */
87 if (mode == MODE_VIDEO) {
88 log_printf("Locking video bitmap");
89 al_clear_to_color(al_map_rgb(0, 0, 0));
90 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
91 bitmap = al_create_bitmap(3*256, 256);
92 }
93 else if (mode == MODE_MEMORY) {
94 log_printf("Locking memory bitmap");
95 al_clear_to_color(al_map_rgb(0, 0, 0));
96 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
97 bitmap = al_create_bitmap(3*256, 256);
98 }
99 else {
100 log_printf("Locking display backbuffer");
101 bitmap = al_get_backbuffer(display);
102 }
103 if (!bitmap) {
104 abort_example("Error creating bitmap");
105 }
106
107 if (lock_flags & ALLEGRO_LOCK_WRITEONLY) {
108 log_printf(" in write-only mode\n");
109 }
110 else {
111 log_printf(" in read/write mode\n");
112 }
113
114 al_set_target_bitmap(bitmap);
115 al_clear_to_color(al_map_rgb_f(0.8, 0.8, 0.9));
116 al_set_target_backbuffer(display);
117
118 fill(bitmap, lock_flags);
119
120 if (mode != MODE_BACKBUFFER) {
121 al_draw_bitmap(bitmap, 0, 0, 0);
122 al_destroy_bitmap(bitmap);
123 bitmap = NULL;
124 }
125
126 al_flip_display();
127 }
128
cycle_mode(enum Mode mode)129 static enum Mode cycle_mode(enum Mode mode)
130 {
131 switch (mode) {
132 case MODE_VIDEO:
133 return MODE_MEMORY;
134 case MODE_MEMORY:
135 return MODE_BACKBUFFER;
136 case MODE_BACKBUFFER:
137 default:
138 return MODE_VIDEO;
139 }
140 }
141
toggle_writeonly(int lock_flags)142 static int toggle_writeonly(int lock_flags)
143 {
144 return lock_flags ^ ALLEGRO_LOCK_WRITEONLY;
145 }
146
main(int argc,char ** argv)147 int main(int argc, char **argv)
148 {
149 ALLEGRO_DISPLAY *display;
150 ALLEGRO_EVENT_QUEUE *events;
151 ALLEGRO_EVENT event;
152 enum Mode mode = MODE_VIDEO;
153 int lock_flags = ALLEGRO_LOCK_WRITEONLY;
154 bool redraw = true;
155
156 (void)argc;
157 (void)argv;
158
159 if (!al_init()) {
160 abort_example("Could not init Allegro.\n");
161 }
162
163 al_install_keyboard();
164 al_install_mouse();
165 al_install_touch_input();
166
167 open_log();
168
169 /* Create a window. */
170 display = al_create_display(3*256, 256);
171 if (!display) {
172 abort_example("Error creating display\n");
173 }
174
175 events = al_create_event_queue();
176 al_register_event_source(events, al_get_keyboard_event_source());
177 al_register_event_source(events, al_get_mouse_event_source());
178 if (al_is_touch_input_installed()) {
179 al_register_event_source(events,
180 al_get_touch_input_mouse_emulation_event_source());
181 }
182
183 log_printf("Press space to change bitmap type\n");
184 log_printf("Press w to toggle WRITEONLY mode\n");
185
186 for (;;) {
187 if (redraw) {
188 draw(display, mode, lock_flags);
189 redraw = false;
190 }
191
192 al_wait_for_event(events, &event);
193 if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
194 if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
195 break;
196 if (event.keyboard.unichar == ' ') {
197 mode = cycle_mode(mode);
198 redraw = true;
199 }
200 else if (event.keyboard.unichar == 'w' || event.keyboard.unichar == 'W') {
201 lock_flags = toggle_writeonly(lock_flags);
202 redraw = true;
203 }
204 }
205 else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {
206 if (event.mouse.button == 1) {
207 if (event.mouse.x < al_get_display_width(display) / 2) {
208 mode = cycle_mode(mode);
209 }
210 else {
211 lock_flags = toggle_writeonly(lock_flags);
212 }
213 redraw = true;
214 }
215 }
216 }
217
218 close_log(false);
219 return 0;
220 }
221
222 /* vim: set sts=3 sw=3 et: */
223