|
Android: Rotation issues and Soft keys |
alehbeer
Member #12,996
July 2011
|
Two questions: I am running now on a real Nexus7 rather than an emulator, and I am now seeing two issues I had not yet seen. 1) How do you work with the softkeys? Can I treat them as keys being pressed, with an event que? I ask because pressing back can lock up the device for a moment, after which I am asked if the program should be shutdown for not responding or not - and if no is pressed, the demo becomes a background behind all the icons. 2) What ever orientation the device starts in is fine, but after rotating the device the aspect becomes very warped. Rotating the device into the orientation it was when the program started makes everything right again. What code or condition checks am I missing? I am running the allegro example. Any ideas?
|
Thomas Fjellstrom
Member #476
June 2000
|
All keys should come through as keyboard events. Some work should probably be done to make sure the keyboard event handling doesn't lock up the java thread. That backgrounding issue has been brought up before. Not sure what is causing that, other than the device supporting multiple GL contexts, and the user thread continuing to run in the background drawing under the main ui.. At least thats my guess. I'll have to do some testing on my Nexus 7. -- |
alehbeer
Member #12,996
July 2011
|
I just updated from The background bug persists, and can now be repeated via: The rotation bug seems fixed. Let me know if you can replicate either - if so I will add it to the bug tracker.
|
Thomas Fjellstrom
Member #476
June 2000
|
Ah, you were using 4.0? That isn't even possible. There was no Android port in 4.0 afaik. But please try the latest 4.1 release, and Git if possible. Git especially, that's probably the most important. -- |
AMCerasoli
Member #11,955
May 2010
|
Isn't he talking about Android? Android 4.1, Jelly Bean?
|
alehbeer
Member #12,996
July 2011
|
I meant android 4.1 to 4.1.1
|
Thomas Fjellstrom
Member #476
June 2000
|
OH. Heh. My bad. What version of Allegro are you trying? -- |
alehbeer
Member #12,996
July 2011
|
Allegro 5.1.3
|
Thomas Fjellstrom
Member #476
June 2000
|
Would it be possible to try the version from the git repo? That may have some fixes for what you're seeing. (I can't remember for sure) -- |
Trent Gamblin
Member #261
April 2000
|
You MUST handle ALLEGRO_EVENT_DISPLAY_HALT/RESUME_DRAWING and should handle ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/IN also. Take a look at the Allegro demo for Android to see what you need to do: http://www.nooskewl.com/content/open-source/. EDIT: I'll try to break it down as best I can remember (in the way I prefer to do it). 1) When you get a HALT_DRAWING, you should set up a condition variable and start a thread with al_run_detached_thread. The code in this thread is pretty simple: 1// Some "global" data, or in some way accessible to both threads
2ALLEGRO_COND *cond;
3ALLEGRO_MUTEX *mutex;
4// This is the event queue your display is registered to
5ALLEGRO_EVENT_QUEUE *queue;
6
7// Here's the thread function
8void *thread_proc(void *data)
9{
10 (void)data;
11
12 while (true) {
13 ALLEGRO_EVENT e;
14 al_wait_for_event(queue, &e);
15 if (e.type == ALLEGRO_EVENT_RESUME_DRAWING) {
16 al_broadcast_cond(cond);
17 break;
18 }
19 }
20
21 return NULL;
22}
23
24// Got HALT_DRAWING here
25cond = al_create_cond();
26mutex = al_create_mutex();
27al_run_detached_thread(...);
28al_acknowledge_drawing_halt(...);
29al_wait_cond(cond, mutex);
30al_acknowledge_drawing_resume(...);
31al_destroy_cond(cond);
32al_destroy_mutex(mutex);
33// ... Back to your regularly scheduled programming
|
Thomas Fjellstrom
Member #476
June 2000
|
I'm wondering why that is required. Can't the main thread just not run things when it knows it can't draw? -- |
Trent Gamblin
Member #261
April 2000
|
Yes, but then you mess up your main loop. Like I said, way I prefer to do it. EDIT: And it's impossible to wait on a condition in the main thread, because you have to wait on events, so you'll be spinning cycles needlessly.
|
Thomas Fjellstrom
Member #476
June 2000
|
Ah. I personally wouldn't find it would mess up the main loop. I'd probably just stop my timer and call it a day. That way no updates at all should happen till the resume drawing event, where you'd start the timer back up. -- |
Trent Gamblin
Member #261
April 2000
|
You can't. Read my edit. Well you can but it's better my way.
|
Thomas Fjellstrom
Member #476
June 2000
|
I wouldn't wait on a condition. Just wait for the resume event to come back, and set things back up. Basically with the timer[s] stopped, no more events should be able to come back, other than the resume drawing event. so you wait on that, rather than a condition. -- |
Trent Gamblin
Member #261
April 2000
|
Whatever. Won't argue with you. You're "The Android Guy" after all. .
|
Thomas Fjellstrom
Member #476
June 2000
|
Trent Gamblin said: Whatever. Won't argue with you. You're "The Android Guy" after all. . I have to say you've done at least as much work, so you're like a partner in crime. I could be missing something. Some quirk of android or allegro's interaction with it that needs something that fancy. -- |
alehbeer
Member #12,996
July 2011
|
I am a little confused how you would add that code into this. I tried, but now I can't get graphics and it doesn't open immediately like it used to - which I believe is possibly caused by my new and not quite clear understanding of ALLEGRO_EVENTS. Here is the example main.c from the allegro5 git. 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_image.h>
3#include <allegro5/allegro_primitives.h>
4#include <allegro5/allegro_android.h> /* al_android_set_apk_file_interface */
5
6ALLEGRO_DEBUG_CHANNEL("main")
7
8#define MAX_TOUCH 10
9
10struct touch {
11 bool down;
12 double x, y;
13} touch[MAX_TOUCH];
14
15/* debugging */
16#define print_standard_path(std) \
17 do { \
18 ALLEGRO_PATH *path = al_get_standard_path(std); \
19 ALLEGRO_DEBUG(#std ": %s", al_path_cstr(path, '/')); \
20 } while (0)
21
22static void print_standard_paths(void)
23{
24 print_standard_path(ALLEGRO_RESOURCES_PATH);
25 print_standard_path(ALLEGRO_TEMP_PATH);
26 print_standard_path(ALLEGRO_USER_DATA_PATH);
27 print_standard_path(ALLEGRO_USER_HOME_PATH);
28 print_standard_path(ALLEGRO_USER_SETTINGS_PATH);
29 print_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
30 print_standard_path(ALLEGRO_EXENAME_PATH);
31}
32
33static void set_transform(ALLEGRO_DISPLAY *dpy)
34{
35 ALLEGRO_TRANSFORM t;
36 int w = al_get_display_width(dpy);
37 int h = al_get_display_height(dpy);
38
39 // XXX we shouldn't need this in user code
40 // glViewport(0, 0, w, h);
41
42 al_identity_transform(&t);
43 al_ortho_transform(&t, 0, w, h, 0, -1, 1);
44 al_set_projection_transform(dpy, &t);
45}
46
47static void draw_touches(void)
48{
49 int i;
50
51 for (i = 0; i < MAX_TOUCH; i++) {
52 if (touch[i].down) {
53 al_draw_filled_rectangle(
54 touch[i].x-40, touch[i].y-40,
55 touch[i].x+40, touch[i].y+40,
56 al_map_rgb(100+i*20, 40+i*20, 40+i*20));
57 }
58 }
59}
60
61int main(int argc, char **argv)
62{
63 ALLEGRO_DISPLAY *dpy;
64 ALLEGRO_EVENT_QUEUE *queue;
65 ALLEGRO_EVENT event;
66 ALLEGRO_TIMER *timer;
67 ALLEGRO_BITMAP *image;
68
69 (void) argc;
70 (void) argv;
71
72 ALLEGRO_DEBUG("init allegro!");
73 if (!al_init()) {
74 return 1;
75 }
76
77 ALLEGRO_DEBUG("init primitives");
78 al_init_primitives_addon();
79
80 ALLEGRO_DEBUG("init image addon");
81 al_init_image_addon();
82
83 ALLEGRO_DEBUG("init touch input");
84 al_install_touch_input();
85
86 ALLEGRO_DEBUG("init keyboard");
87 al_install_keyboard();
88
89 ALLEGRO_DEBUG("creating display");
90 dpy = al_create_display(800, 480);
91 if (!dpy) {
92 ALLEGRO_ERROR("failed to create display!");
93 return 1;
94 }
95
96 print_standard_paths();
97
98 /* This is loaded from assets in the apk. */
99 al_android_set_apk_file_interface();
100 image = al_load_bitmap("alexlogo.png");
101 if (!image) {
102 ALLEGRO_DEBUG("failed to load alexlogo.png");
103 return 1;
104 }
105 al_set_standard_file_interface();
106
107 al_convert_mask_to_alpha(image, al_map_rgb(255,0,255));
108
109 queue = al_create_event_queue();
110 al_register_event_source(queue, al_get_display_event_source(dpy));
111 al_register_event_source(queue, al_get_touch_input_event_source());
112 al_register_event_source(queue, al_get_keyboard_event_source());
113
114 timer = al_create_timer(1/60.0);
115 al_register_event_source(queue, al_get_timer_event_source(timer));
116 al_start_timer(timer);
117
118 bool draw = true;
119 bool running = true;
120 bool paused = false;
121 int count = 0;
122
123 while (running) {
124 al_wait_for_event(queue, &event);
125
126 switch (event.type) {
127 case ALLEGRO_EVENT_TOUCH_BEGIN:
128 //ALLEGRO_DEBUG("touch %i begin", event.touch.id);
129 touch[event.touch.id].down = true;
130 touch[event.touch.id].x = event.touch.x;
131 touch[event.touch.id].y = event.touch.y;
132 break;
133
134 case ALLEGRO_EVENT_TOUCH_END:
135 //ALLEGRO_DEBUG("touch %i end", event.touch.id);
136 touch[event.touch.id].down = false;
137 touch[event.touch.id].x = 0.0;
138 touch[event.touch.id].y = 0.0;
139 break;
140
141 case ALLEGRO_EVENT_TOUCH_MOVE:
142 //ALLEGRO_DEBUG("touch %i move: %fx%f", event.touch.id, event.touch.x, event.touch.y);
143 touch[event.touch.id].x = event.touch.x;
144 touch[event.touch.id].y = event.touch.y;
145 break;
146
147 case ALLEGRO_EVENT_TOUCH_CANCEL:
148 //ALLEGRO_DEBUG("touch %i canceled", event.touch.id);
149 break;
150
151 case ALLEGRO_EVENT_KEY_UP:
152 if (event.keyboard.keycode == ALLEGRO_KEY_BACK) {
153 ALLEGRO_DEBUG("back key pressed, exit!");
154 running = false;
155 }
156 else {
157 ALLEGRO_DEBUG("%i key pressed", event.keyboard.keycode);
158 }
159 break;
160
161 case ALLEGRO_EVENT_TIMER:
162 draw = true;
163 if (count == 60) {
164 ALLEGRO_DEBUG("tick");
165 count = 0;
166 }
167 count++;
168 break;
169
170 case ALLEGRO_EVENT_DISPLAY_CLOSE:
171 ALLEGRO_DEBUG("display close");
172 running = false;
173 break;
174
175 case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
176 ALLEGRO_DEBUG("halt drawing");
177 // Stop the timer so we don't run at all while our display isn't
178 // active.
179 al_stop_timer(timer);
180 //al_set_target_backbuffer(0);
181 ALLEGRO_DEBUG("after set target");
182 paused = true;
183 draw = false;
184 al_acknowledge_drawing_halt(dpy);
185 break;
186
187 case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
188 ALLEGRO_DEBUG("resume drawing");
189
190 al_acknowledge_drawing_resume(dpy, NULL);
191 ALLEGRO_DEBUG("done waiting for surface recreated");
192
193 al_start_timer(timer);
194 //al_set_target_backbuffer(dpy);
195 //_al_android_setup_opengl_view(dpy);
196 paused = false;
197 break;
198
199 case ALLEGRO_EVENT_DISPLAY_RESIZE:
200 ALLEGRO_DEBUG("display resize");
201 al_acknowledge_resize(dpy);
202 ALLEGRO_DEBUG("done resize");
203 set_transform(dpy);
204 break;
205
206 case ALLEGRO_EVENT_DISPLAY_ORIENTATION:
207 set_transform(dpy);
208 break;
209 }
210
211 if (draw && al_event_queue_is_empty(queue)) {
212 draw = false;
213 al_clear_to_color(al_map_rgb(255, 255, 255));
214 if (image) {
215 al_draw_bitmap(image,
216 al_get_display_width(dpy)/2 - al_get_bitmap_width(image)/2,
217 al_get_display_height(dpy)/2 - al_get_bitmap_height(image)/2,
218 0);
219 }
220 draw_touches();
221 al_flip_display();
222 }
223 }
224
225 ALLEGRO_DEBUG("done");
226 return 0;
227}
228
229/* vim: set sts=3 sw=3 et: */
|
|