1 #include <allegro5/allegro.h>
2 #include <allegro5/allegro_image.h>
3 #include <allegro5/allegro_primitives.h>
4 #ifdef ALLEGRO_ANDROID
5 #include <allegro5/allegro_android.h> /* al_android_set_apk_file_interface */
6 #endif
7 
8 ALLEGRO_DEBUG_CHANNEL("main")
9 
10 #define MAX_TOUCH 10
11 
12 struct touch {
13    bool down;
14    double x, y;
15 } touch[MAX_TOUCH];
16 
17 /* debugging */
18 #define print_standard_path(std)                           \
19    do {                                                    \
20       ALLEGRO_PATH *path = al_get_standard_path(std);      \
21       ALLEGRO_DEBUG(#std ": %s", al_path_cstr(path, '/')); \
22    } while (0)
23 
print_standard_paths(void)24 static void print_standard_paths(void)
25 {
26    print_standard_path(ALLEGRO_RESOURCES_PATH);
27    print_standard_path(ALLEGRO_TEMP_PATH);
28    print_standard_path(ALLEGRO_USER_DATA_PATH);
29    print_standard_path(ALLEGRO_USER_HOME_PATH);
30    print_standard_path(ALLEGRO_USER_SETTINGS_PATH);
31    print_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
32    print_standard_path(ALLEGRO_EXENAME_PATH);
33 }
34 
draw_touches(void)35 static void draw_touches(void)
36 {
37    int i;
38 
39    for (i = 0; i < MAX_TOUCH; i++) {
40       if (touch[i].down) {
41          al_draw_filled_rectangle(
42             touch[i].x-40, touch[i].y-40,
43             touch[i].x+40, touch[i].y+40,
44             al_map_rgb(100+i*20, 40+i*20, 40+i*20));
45       }
46    }
47 }
48 
main(int argc,char ** argv)49 int main(int argc, char **argv)
50 {
51    ALLEGRO_DISPLAY *dpy;
52    ALLEGRO_EVENT_QUEUE *queue;
53    ALLEGRO_EVENT event;
54    ALLEGRO_TIMER *timer;
55    ALLEGRO_BITMAP *image;
56    ALLEGRO_BITMAP *image2;
57 
58    (void) argc;
59    (void) argv;
60 
61    ALLEGRO_DEBUG("init allegro!");
62    if (!al_init()) {
63       return 1;
64    }
65 
66    ALLEGRO_DEBUG("init primitives");
67    al_init_primitives_addon();
68 
69    ALLEGRO_DEBUG("init image addon");
70    al_init_image_addon();
71 
72    ALLEGRO_DEBUG("init touch input");
73    al_install_touch_input();
74 
75    ALLEGRO_DEBUG("init keyboard");
76    al_install_keyboard();
77 
78    ALLEGRO_DEBUG("creating display");
79    dpy = al_create_display(800, 480);
80    if (!dpy) {
81       ALLEGRO_ERROR("failed to create display!");
82       return 1;
83    }
84 
85    print_standard_paths();
86 
87    /* This is loaded from assets in the apk. */
88    #ifdef ALLEGRO_ANDROID
89    al_android_set_apk_file_interface();
90    #endif
91    image = al_load_bitmap("data/alexlogo.png");
92    if (!image) {
93       ALLEGRO_DEBUG("failed to load alexlogo.png");
94       return 1;
95    }
96 
97    #ifdef ALLEGRO_ANDROID
98    /* Copy the .png from the .apk into the user data area. */
99    ALLEGRO_FILE *fin = al_fopen("data/alexlogo.png", "rb");
100    al_set_standard_file_interface();
101    ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DATA_PATH);
102    al_set_path_filename(path, "alexlogo.png");
103    ALLEGRO_FILE *fout = al_fopen(al_path_cstr(path, '/'), "wb");
104    while (!al_feof(fin)) {
105       char buf[1024];
106       int n = al_fread(fin, buf, 1024);
107       al_fwrite(fout, buf, n);
108    }
109    al_fclose(fin);
110    al_fclose(fout);
111 
112    /* This is now loaded with the normal stdio file interface and not
113     * from the APK.
114     */
115    image2 = al_load_bitmap(al_path_cstr(path, '/'));
116 
117    al_destroy_path(path);
118    #else
119    image2 = image;
120    #endif
121 
122 
123    al_convert_mask_to_alpha(image, al_map_rgb(255,0,255));
124    if (image2)
125       al_convert_mask_to_alpha(image2, al_map_rgb(255,0,255));
126 
127    queue = al_create_event_queue();
128    al_register_event_source(queue, al_get_display_event_source(dpy));
129    al_register_event_source(queue, al_get_touch_input_event_source());
130    al_register_event_source(queue, al_get_keyboard_event_source());
131 
132    timer = al_create_timer(1/60.0);
133    al_register_event_source(queue, al_get_timer_event_source(timer));
134    al_start_timer(timer);
135 
136    bool draw = true;
137    bool running = true;
138    int count = 0;
139 
140    while (running) {
141       al_wait_for_event(queue, &event);
142 
143       switch (event.type) {
144          case ALLEGRO_EVENT_TOUCH_BEGIN:
145             //ALLEGRO_DEBUG("touch %i begin", event.touch.id);
146             touch[event.touch.id].down = true;
147             touch[event.touch.id].x = event.touch.x;
148             touch[event.touch.id].y = event.touch.y;
149             break;
150 
151          case ALLEGRO_EVENT_TOUCH_END:
152             //ALLEGRO_DEBUG("touch %i end", event.touch.id);
153             touch[event.touch.id].down = false;
154             touch[event.touch.id].x = 0.0;
155             touch[event.touch.id].y = 0.0;
156             break;
157 
158          case ALLEGRO_EVENT_TOUCH_MOVE:
159             //ALLEGRO_DEBUG("touch %i move: %fx%f", event.touch.id, event.touch.x, event.touch.y);
160             touch[event.touch.id].x = event.touch.x;
161             touch[event.touch.id].y = event.touch.y;
162             break;
163 
164          case ALLEGRO_EVENT_TOUCH_CANCEL:
165             //ALLEGRO_DEBUG("touch %i canceled", event.touch.id);
166             break;
167 
168          case ALLEGRO_EVENT_KEY_UP:
169             if (event.keyboard.keycode == ALLEGRO_KEY_BACK) {
170                ALLEGRO_DEBUG("back key pressed, exit!");
171                running = false;
172             }
173             else {
174                ALLEGRO_DEBUG("%i key pressed", event.keyboard.keycode);
175             }
176             break;
177 
178          case ALLEGRO_EVENT_TIMER:
179             draw = true;
180             if (count == 60) {
181                ALLEGRO_DEBUG("tick");
182                count = 0;
183             }
184             count++;
185             break;
186 
187          case ALLEGRO_EVENT_DISPLAY_CLOSE:
188             ALLEGRO_DEBUG("display close");
189             running = false;
190             break;
191 
192          case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
193             ALLEGRO_DEBUG("halt drawing");
194             // Stop the timer so we don't run at all while our display isn't
195             // active.
196             al_stop_timer(timer);
197             ALLEGRO_DEBUG("after set target");
198             draw = false;
199             al_acknowledge_drawing_halt(dpy);
200             break;
201 
202          case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
203             ALLEGRO_DEBUG("resume drawing");
204 
205             al_acknowledge_drawing_resume(dpy);
206             ALLEGRO_DEBUG("done waiting for surface recreated");
207 
208             al_start_timer(timer);
209             break;
210 
211          case ALLEGRO_EVENT_DISPLAY_RESIZE:
212             ALLEGRO_DEBUG("display resize");
213             al_acknowledge_resize(dpy);
214             ALLEGRO_DEBUG("done resize");
215             break;
216       }
217 
218       if (draw && al_event_queue_is_empty(queue)) {
219          draw = false;
220          al_clear_to_color(al_map_rgb(255, 255, 255));
221          if (image) {
222             al_draw_bitmap(image,
223                al_get_display_width(dpy)/2 - al_get_bitmap_width(image)/2,
224                al_get_display_height(dpy)/2 - al_get_bitmap_height(image)/2,
225                0);
226          }
227          if (image2) {
228             al_draw_bitmap(image2,
229                al_get_display_width(dpy)/2 - al_get_bitmap_width(image)/2,
230                al_get_display_height(dpy)/2 + al_get_bitmap_height(image)/2,
231                0);
232          }
233          draw_touches();
234          al_flip_display();
235       }
236    }
237 
238    ALLEGRO_DEBUG("done");
239    return 0;
240 }
241 
242 /* vim: set sts=3 sw=3 et: */
243