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