gui.c

Go to the documentation of this file.
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     /* Allegro GUI routines generally use the 2D gfx functions therefore
00062        we set default behaviour to allegro_gl_set_allegro_mode so that we
00063        can use the GUI functions "as is" */
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         /* Redraw the GUI every frame */
00072         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00073         broadcast_dialog_message (MSG_DRAW, 0);
00074 
00075         /* Draw the mouse cursor */
00076         algl_draw_mouse();
00077 
00078         /* Flip buffers */
00079         allegro_gl_flip();
00080     }
00081 
00082     show_mouse(NULL);
00083     /* restore previous projection matrices */
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     /* Allegro GUI routines generally use the 2D gfx functions therefore
00126        we set default behaviour to allegro_gl_set_allegro_mode so that we
00127        can use the GUI functions "as is" */
00128     allegro_gl_set_allegro_mode();
00129 
00130     glGetIntegerv(GL_READ_BUFFER, &read_buffer);
00131     glReadBuffer (GL_FRONT); /* TODO: don't clobber */
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         /* Redraw the GUI every frame */
00143         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00144         glRasterPos2f (0., SCREEN_H-.5); /* TODO: don't clobber */
00145         glDrawPixels (SCREEN_W, SCREEN_H, GL_RGB, GL_UNSIGNED_BYTE, backdrop);
00146         broadcast_dialog_message (MSG_DRAW, 0);
00147 
00148         /* Draw the mouse cursor */
00149         algl_draw_mouse();
00150 
00151         /* Flip buffers */
00152         allegro_gl_flip();
00153     }
00154 
00155     glRasterPos2f (0., SCREEN_H-.5); /* TODO: don't clobber */
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     /* restore previous projection matrices */
00162     allegro_gl_unset_allegro_mode();
00163 
00164     return shutdown_dialog (player);
00165 }
00166 
00167 
00168 
00169 /* User mouse drawing callback */
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     /* don't draw the mouse if it's not in our window */
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    /* (dialog proc)        (x)   (y)   (w)   (h)   (fg)  (bg)  (key) (flags)  (d1)  (d2)  (dp)  (dp2) (dp3) */
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     /* First we get back into a 3D mode */
00491     allegro_gl_unset_allegro_mode();
00492 
00493     if (msg == MSG_DRAW) {
00494         /* Draws the background */
00495         clear_to_color(viewport, d->bg);
00496     }
00497 
00498     /* Save the Viewport and Scissor states */
00499     glPushAttrib(GL_SCISSOR_BIT | GL_VIEWPORT_BIT);
00500 
00501     /* Adapt the viewport to the object size */
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     /* Clear the depth buffer for this scissor region */
00507     if (msg == MSG_DRAW) {
00508         glClear(GL_DEPTH_BUFFER_BIT);
00509     }
00510 
00511     /* Call the callback function */
00512     if (callback)
00513         ret = callback(viewport, msg, c);
00514 
00515     /* Restore the previous state */
00516     glPopAttrib();
00517     allegro_gl_set_allegro_mode();
00518     destroy_bitmap(viewport);
00519 
00520     return ret;
00521 }
00522 
00523 
00524 
00525 /*****************/
00526 /* Mouse manager */
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     /* This function is not called from the main thread, so
00607      * we must not call any OpenGL command there !!!
00608      */
00609 }
00610 

Generated on Mon Apr 3 18:20:13 2006 for AllegroGL by  doxygen 1.4.6