00001
00009 #include "alleggl.h"
00010 #include "allglint.h"
00011
00012 #include <allegro/internal/aintern.h>
00013
00014
00015 static struct {
00016 GLuint texture;
00017 int hidden;
00018 int xfocus;
00019 int yfocus;
00020 int width;
00021 int height;
00022 } allegro_gl_mouse = { 0, TRUE, 0, 0, 0, 0};
00023
00024
00055 int algl_do_dialog (DIALOG *dialog, int focus_obj)
00056 {
00057 DIALOG_PLAYER *player;
00058
00059 AGL_LOG(2, "allegro_gl_do_dialog\n");
00060
00061
00062
00063
00064 allegro_gl_set_allegro_mode();
00065
00066 player = init_dialog (dialog, focus_obj);
00067 show_mouse(screen);
00068
00069 while (update_dialog (player)) {
00070
00071
00072 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00073 broadcast_dialog_message (MSG_DRAW, 0);
00074
00075
00076 algl_draw_mouse();
00077
00078
00079 allegro_gl_flip();
00080 }
00081
00082 show_mouse(NULL);
00083
00084 allegro_gl_unset_allegro_mode();
00085
00086 return shutdown_dialog (player);
00087 }
00088
00089
00090
00117 int algl_popup_dialog (DIALOG *dialog, int focus_obj)
00118 {
00119 void *backdrop;
00120 DIALOG_PLAYER *player;
00121 GLint read_buffer;
00122
00123 AGL_LOG(2, "allegro_gl_popup_dialog\n");
00124
00125
00126
00127
00128 allegro_gl_set_allegro_mode();
00129
00130 glGetIntegerv(GL_READ_BUFFER, &read_buffer);
00131 glReadBuffer (GL_FRONT);
00132 glDisable(GL_DEPTH_TEST);
00133 backdrop = malloc (SCREEN_W * SCREEN_H * 3 * 4);
00134 glReadPixels (0, 0, SCREEN_W, SCREEN_H, GL_RGB, GL_UNSIGNED_BYTE, backdrop);
00135 glReadBuffer(read_buffer);
00136
00137 player = init_dialog (dialog, focus_obj);
00138 show_mouse(screen);
00139
00140 while (update_dialog (player)) {
00141
00142
00143 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00144 glRasterPos2f (0., SCREEN_H-.5);
00145 glDrawPixels (SCREEN_W, SCREEN_H, GL_RGB, GL_UNSIGNED_BYTE, backdrop);
00146 broadcast_dialog_message (MSG_DRAW, 0);
00147
00148
00149 algl_draw_mouse();
00150
00151
00152 allegro_gl_flip();
00153 }
00154
00155 glRasterPos2f (0., SCREEN_H-.5);
00156 glDrawPixels (SCREEN_W, SCREEN_H, GL_RGB, GL_UNSIGNED_BYTE, backdrop);
00157 glEnable(GL_DEPTH_TEST);
00158 free (backdrop);
00159
00160 show_mouse(NULL);
00161
00162 allegro_gl_unset_allegro_mode();
00163
00164 return shutdown_dialog (player);
00165 }
00166
00167
00168
00169
00170 static void (*__algl_user_draw_mouse)(void) = NULL;
00171
00172
00193 void algl_draw_mouse (void)
00194 {
00195 AGL_LOG(2, "allegro_gl_draw_mouse\n");
00196
00197
00198 if (!_mouse_on || allegro_gl_mouse.hidden) return;
00199
00200 if (__algl_user_draw_mouse) {
00201
00202 __algl_user_draw_mouse();
00203
00204 } else {
00205
00206 #if 0
00207 float x = mouse_x;
00208 float y = mouse_y;
00209
00210 int depth_enabled = glIsEnabled (GL_DEPTH_TEST);
00211 int cull_enabled = glIsEnabled (GL_CULL_FACE);
00212 if (depth_enabled) glDisable (GL_DEPTH_TEST);
00213 if (cull_enabled) glDisable (GL_CULL_FACE);
00214
00215 glBegin (GL_TRIANGLES);
00216
00217 #define draw(dx,dy) \
00218 glVertex2f (x + dx, y + dy); \
00219 glVertex2f (x + dx, y + dy + 10); \
00220 glVertex2f (x + dx + 7, y + dy + 7); \
00221 glVertex2f (x + dx + 1.5, y + dy + 6); \
00222 glVertex2f (x + dx + 5.5, y + dy + 14); \
00223 glVertex2f (x + dx + 7.5, y + dy + 14); \
00224 glVertex2f (x + dx + 3.5, y + dy + 6); \
00225 glVertex2f (x + dx + 1.5, y + dy + 6); \
00226 glVertex2f (x + dx + 7.5, y + dy + 14);
00227
00228 glColor3f (0, 0, 0);
00229 draw(-1,0)
00230 draw(1,0)
00231 draw(0,-1)
00232 draw(0,1)
00233
00234 glColor3f (1, 1, 1);
00235 draw(0,0)
00236
00237 #undef draw
00238
00239 glEnd();
00240
00241 if (depth_enabled) glEnable (GL_DEPTH_TEST);
00242 if (cull_enabled) glEnable (GL_CULL_FACE);
00243 #endif
00244
00245 int x = mouse_x - allegro_gl_mouse.xfocus;
00246 int y = mouse_y - allegro_gl_mouse.yfocus;
00247
00248 glPushAttrib(GL_COLOR_BUFFER_BIT);
00249 glAlphaFunc(GL_GREATER, 0.5);
00250 glEnable(GL_ALPHA_TEST);
00251
00252 glBindTexture(GL_TEXTURE_2D, allegro_gl_mouse.texture);
00253 glColor4f(1., 1., 1., 1.);
00254 glTranslatef(-0.375, -0.375, 0);
00255 glBegin(GL_QUADS);
00256 glTexCoord2f(0., 1.);
00257 glVertex2f(x, y);
00258 glTexCoord2f(0., 0.);
00259 glVertex2f(x, y + allegro_gl_mouse.height);
00260 glTexCoord2f(1., 0.);
00261 glVertex2f(x + allegro_gl_mouse.width, y + allegro_gl_mouse.height);
00262 glTexCoord2f(1., 1.);
00263 glVertex2f(x + allegro_gl_mouse.width, y);
00264 glEnd();
00265 glTranslatef(0.375, 0.375, 0);
00266 glPopAttrib();
00267 glBindTexture(GL_TEXTURE_2D, 0);
00268 }
00269 }
00270
00271
00288 void algl_set_mouse_drawer (void (*user_draw_mouse)(void))
00289 {
00290 AGL_LOG(2, "allegro_gl_set_mouse_drawer\n");
00291
00292 __algl_user_draw_mouse = user_draw_mouse;
00293 }
00294
00295
00296
00297
00298
00299 static DIALOG alert_dialog[] =
00300 {
00301
00302 { _gui_shadow_box_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
00303 { _gui_ctext_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
00304 { _gui_ctext_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
00305 { _gui_ctext_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
00306 { _gui_button_proc, 0, 0, 0, 0, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL },
00307 { _gui_button_proc, 0, 0, 0, 0, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL },
00308 { _gui_button_proc, 0, 0, 0, 0, 0, 0, 0, D_EXIT, 0, 0, NULL, NULL, NULL },
00309 { d_yield_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
00310 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
00311 };
00312
00313
00314 #define A_S1 1
00315 #define A_S2 2
00316 #define A_S3 3
00317 #define A_B1 4
00318 #define A_B2 5
00319 #define A_B3 6
00320
00321
00322
00333 int algl_alert3(AL_CONST char *s1, AL_CONST char *s2, AL_CONST char *s3, AL_CONST char *b1, AL_CONST char *b2, AL_CONST char *b3, int c1, int c2, int c3)
00334 {
00335 char tmp[16];
00336 int avg_w, avg_h;
00337 int len1, len2, len3;
00338 int maxlen = 0;
00339 int buttons = 0;
00340 int b[3];
00341 int c;
00342
00343 AGL_LOG(2, "allegro_gl_alert3\n");
00344
00345 #define SORT_OUT_BUTTON(x) { \
00346 if (b##x) { \
00347 alert_dialog[A_B##x].flags &= ~D_HIDDEN; \
00348 alert_dialog[A_B##x].key = c##x; \
00349 alert_dialog[A_B##x].dp = (char *)b##x; \
00350 len##x = gui_strlen(b##x); \
00351 b[buttons++] = A_B##x; \
00352 } \
00353 else { \
00354 alert_dialog[A_B##x].flags |= D_HIDDEN; \
00355 len##x = 0; \
00356 } \
00357 }
00358
00359 usetc(tmp+usetc(tmp, ' '), 0);
00360
00361 avg_w = text_length(font, tmp);
00362 avg_h = text_height(font);
00363
00364 alert_dialog[A_S1].dp = alert_dialog[A_S2].dp = alert_dialog[A_S3].dp =
00365 alert_dialog[A_B1].dp = alert_dialog[A_B2].dp = empty_string;
00366
00367 if (s1) {
00368 alert_dialog[A_S1].dp = (char *)s1;
00369 maxlen = text_length(font, s1);
00370 }
00371
00372 if (s2) {
00373 alert_dialog[A_S2].dp = (char *)s2;
00374 len1 = text_length(font, s2);
00375 if (len1 > maxlen)
00376 maxlen = len1;
00377 }
00378
00379 if (s3) {
00380 alert_dialog[A_S3].dp = (char *)s3;
00381 len1 = text_length(font, s3);
00382 if (len1 > maxlen)
00383 maxlen = len1;
00384 }
00385
00386 SORT_OUT_BUTTON(1);
00387 SORT_OUT_BUTTON(2);
00388 SORT_OUT_BUTTON(3);
00389
00390 len1 = MAX(len1, MAX(len2, len3)) + avg_w*3;
00391 if (len1*buttons > maxlen)
00392 maxlen = len1*buttons;
00393
00394 maxlen += avg_w*4;
00395 alert_dialog[0].w = maxlen;
00396 alert_dialog[A_S1].x = alert_dialog[A_S2].x = alert_dialog[A_S3].x =
00397 alert_dialog[0].x + maxlen/2;
00398
00399 alert_dialog[A_B1].w = alert_dialog[A_B2].w = alert_dialog[A_B3].w = len1;
00400
00401 alert_dialog[A_B1].x = alert_dialog[A_B2].x = alert_dialog[A_B3].x =
00402 alert_dialog[0].x + maxlen/2 - len1/2;
00403
00404 if (buttons == 3) {
00405 alert_dialog[b[0]].x = alert_dialog[0].x + maxlen/2 - len1*3/2 - avg_w;
00406 alert_dialog[b[2]].x = alert_dialog[0].x + maxlen/2 + len1/2 + avg_w;
00407 }
00408 else if (buttons == 2) {
00409 alert_dialog[b[0]].x = alert_dialog[0].x + maxlen/2 - len1 - avg_w;
00410 alert_dialog[b[1]].x = alert_dialog[0].x + maxlen/2 + avg_w;
00411 }
00412
00413 alert_dialog[0].h = avg_h*8;
00414 alert_dialog[A_S1].y = alert_dialog[0].y + avg_h;
00415 alert_dialog[A_S2].y = alert_dialog[0].y + avg_h*2;
00416 alert_dialog[A_S3].y = alert_dialog[0].y + avg_h*3;
00417 alert_dialog[A_S1].h = alert_dialog[A_S2].h = alert_dialog[A_S3].h = avg_h;
00418 alert_dialog[A_B1].y = alert_dialog[A_B2].y = alert_dialog[A_B3].y = alert_dialog[0].y + avg_h*5;
00419 alert_dialog[A_B1].h = alert_dialog[A_B2].h = alert_dialog[A_B3].h = avg_h*2;
00420
00421 centre_dialog(alert_dialog);
00422 set_dialog_color(alert_dialog, gui_fg_color, gui_bg_color);
00423 for (c = 0; alert_dialog[c].proc; c++)
00424 if (alert_dialog[c].proc == _gui_ctext_proc)
00425 alert_dialog[c].bg = -1;
00426
00427 clear_keybuf();
00428
00429 do {
00430 } while (gui_mouse_b());
00431
00432 c = algl_popup_dialog(alert_dialog, A_B1);
00433
00434 if (c == A_B1)
00435 return 1;
00436 else if (c == A_B2)
00437 return 2;
00438 else
00439 return 3;
00440 }
00441
00442
00443
00453 int algl_alert(AL_CONST char *s1, AL_CONST char *s2, AL_CONST char *s3, AL_CONST char *b1, AL_CONST char *b2, int c1, int c2)
00454 {
00455 int ret;
00456
00457 AGL_LOG(2, "allegro_gl_alert\n");
00458
00459 ret = algl_alert3(s1, s2, s3, b1, b2, NULL, c1, c2, 0);
00460
00461 if (ret > 2)
00462 ret = 2;
00463
00464 return ret;
00465 }
00466
00467
00468
00481 int d_algl_viewport_proc(int msg, DIALOG *d, int c)
00482 {
00483 int ret = D_O_K;
00484 typedef int (*_callback)(BITMAP*, int, int);
00485 _callback callback = (_callback) d->dp;
00486 BITMAP *viewport = create_sub_bitmap(screen, d->x, d->y, d->w, d->h);
00487
00488 AGL_LOG(3, "d_algl_viewport_proc\n");
00489
00490
00491 allegro_gl_unset_allegro_mode();
00492
00493 if (msg == MSG_DRAW) {
00494
00495 clear_to_color(viewport, d->bg);
00496 }
00497
00498
00499 glPushAttrib(GL_SCISSOR_BIT | GL_VIEWPORT_BIT);
00500
00501
00502 glViewport(d->x, SCREEN_H - d->y - d->h, d->w, d->h);
00503 glScissor(d->x, SCREEN_H - d->y - d->h, d->w, d->h);
00504 glEnable(GL_SCISSOR_TEST);
00505
00506
00507 if (msg == MSG_DRAW) {
00508 glClear(GL_DEPTH_BUFFER_BIT);
00509 }
00510
00511
00512 if (callback)
00513 ret = callback(viewport, msg, c);
00514
00515
00516 glPopAttrib();
00517 allegro_gl_set_allegro_mode();
00518 destroy_bitmap(viewport);
00519
00520 return ret;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 int allegro_gl_set_mouse_sprite(BITMAP *sprite, int xfocus, int yfocus)
00530 {
00531 BITMAP *bmp = NULL;
00532 GLint old_texture;
00533
00534 AGL_LOG(2, "allegro_gl_set_mouse_sprite\n");
00535
00536 glGetIntegerv(GL_TEXTURE_2D_BINDING, &old_texture);
00537
00538 bmp = create_bitmap_ex(bitmap_color_depth(sprite),
00539 __allegro_gl_make_power_of_2(sprite->w),
00540 __allegro_gl_make_power_of_2(sprite->h));
00541
00542 if (allegro_gl_mouse.texture) {
00543 glDeleteTextures(1, &allegro_gl_mouse.texture);
00544 allegro_gl_mouse.texture = 0;
00545 }
00546
00547 clear_to_color(bmp, bitmap_mask_color(sprite));
00548 blit(sprite, bmp, 0, 0, 0, 0, sprite->w, sprite->h);
00549 #ifdef DEBUGMODE
00550 save_bmp("mcursor.bmp",bmp,NULL);
00551 #endif
00552
00553 allegro_gl_mouse.texture = allegro_gl_make_texture_ex(AGL_TEXTURE_RESCALE
00554 | AGL_TEXTURE_MASKED | AGL_TEXTURE_FLIP, bmp, -1);
00555 if (!allegro_gl_mouse.texture) {
00556 destroy_bitmap(bmp);
00557 return -1;
00558 }
00559
00560 glBindTexture(GL_TEXTURE_2D, allegro_gl_mouse.texture);
00561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00562 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00563
00564 if (allegro_gl_extensions_GL.SGIS_texture_edge_clamp) {
00565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00566 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00567 }
00568 else {
00569 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00571 }
00572
00573 glBindTexture(GL_TEXTURE_2D, old_texture);
00574
00575 allegro_gl_mouse.width = bmp->w;
00576 allegro_gl_mouse.height = bmp->h;
00577 allegro_gl_mouse.xfocus = xfocus;
00578 allegro_gl_mouse.yfocus = yfocus;
00579
00580 destroy_bitmap(bmp);
00581 return 0;
00582 }
00583
00584
00585
00586 int allegro_gl_show_mouse(BITMAP* bmp, int x, int y)
00587 {
00588 AGL_LOG(3, "allegro_gl_show_mouse\n");
00589 allegro_gl_mouse.hidden = FALSE;
00590 return 0;
00591 }
00592
00593
00594
00595 void allegro_gl_hide_mouse(void)
00596 {
00597 AGL_LOG(3, "allegro_gl_hide_mouse\n");
00598 allegro_gl_mouse.hidden = TRUE;
00599 }
00600
00601
00602
00603 void allegro_gl_move_mouse(int x, int y)
00604 {
00605 AGL_LOG(3, "allegro_gl_move_mouse\n");
00606
00607
00608
00609 }
00610