1 /* DreamChess
2 **
3 ** DreamChess is the legal property of its developers, whose names are too
4 ** numerous to list here. Please refer to the AUTHORS.txt file distributed
5 ** with this source distribution.
6 **
7 ** This program is free software: you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation, either version 3 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "ui_sdlgl.h"
22 #include "git_rev.h"
23
24 #ifdef _WIN32
25 #include <direct.h>
26 #else
27 #include <unistd.h>
28 #endif
29
30 #include "audio.h"
31 #include "dialogs.h"
32 #include "options.h"
33 #include "system_config.h"
34 #include "theme.h"
35 #include <GL/glew.h>
36 #include <SDL2/SDL_syswm.h>
37
38 static int turn_counter_start = 0;
39 static texture_t menu_title_tex;
40 static int game_in_stalemate;
41 static int white_in_check;
42 static int black_in_check;
43 static int white_in_checkmate;
44 static int black_in_checkmate;
45 static board_t board;
46 static int pgn_slot;
47 static int quit_to_menu = FALSE;
48 static int title_process_retval;
49 static int set_loading = FALSE;
50 static int dialog_promote_piece;
51 static int show_egg;
52 static int egg_req1 = FALSE;
53 static int screen_width = 640;
54 static int screen_height = 480;
55 static int screen_fs = 0;
56 static int screen_ms = 0;
57 static int reflections = 1;
58 static int mode_set_failed = 0;
59 static int engine_error_shown;
60 SDL_Window *sdl_window;
61 static GLuint screen_fb, screen_temp_fb, screen_tex, screen_color_rb, screen_temp_color_rb, screen_depth_stencil_rb;
62 static int max_samples;
63
music_callback(char * title,char * artist,char * album)64 static void music_callback(char *title, char *artist, char *album) {
65 DBG_LOG("Now playing: %s - %s", artist, title);
66 }
67
get_screen_width(void)68 int get_screen_width(void) {
69 return screen_width;
70 }
71
get_screen_height(void)72 int get_screen_height(void) {
73 return screen_height;
74 }
75
76 static int menu_state;
77 enum { MENU_STATE_FADE_IN, MENU_STATE_IN_MENU, MENU_STATE_LOAD, MENU_STATE_FADE_OUT, MENU_STATE_RETURN };
78
79 static void poll_move(void);
80
get_egg_req(void)81 int get_egg_req(void) {
82 return egg_req1;
83 }
84
set_show_egg(int set)85 void set_show_egg(int set) {
86 show_egg = set;
87 }
88
get_show_egg(void)89 int get_show_egg(void) {
90 return show_egg;
91 }
92
get_dialog_promote_piece(void)93 int get_dialog_promote_piece(void) {
94 return dialog_promote_piece;
95 }
96
set_dialog_promote_piece(int piece)97 void set_dialog_promote_piece(int piece) {
98 dialog_promote_piece = piece;
99 }
100
set_title_process_retval(int ret)101 void set_title_process_retval(int ret) {
102 title_process_retval = ret;
103 }
104
set_set_loading(int set)105 void set_set_loading(int set) {
106 set_loading = set;
107 }
108
set_quit_to_menu(int menu)109 void set_quit_to_menu(int menu) {
110 quit_to_menu = menu;
111 }
112
set_pgn_slot(int slot)113 void set_pgn_slot(int slot) {
114 pgn_slot = slot;
115 }
116
get_board(void)117 board_t *get_board(void) {
118 return &board;
119 }
120
121 config_t config;
122
get_config(void)123 config_t *get_config(void) {
124 return &config;
125 }
126
127 static int switch_to_menu = FALSE;
128 static int fading_out = FALSE;
129
set_switch_to_menu(int sw)130 void set_switch_to_menu(int sw) {
131 switch_to_menu = sw;
132 }
133
get_fading_out(void)134 int get_fading_out(void) {
135 return fading_out;
136 }
137
set_fading_out(int fade)138 void set_fading_out(int fade) {
139 fading_out = fade;
140 }
get_game_stalemate(void)141 int get_game_stalemate(void) {
142 return game_in_stalemate;
143 }
144
get_white_in_check(void)145 int get_white_in_check(void) {
146 return white_in_check;
147 }
148
get_black_in_check(void)149 int get_black_in_check(void) {
150 return black_in_check;
151 }
get_white_in_checkmate(void)152 int get_white_in_checkmate(void) {
153 return white_in_checkmate;
154 }
155
get_black_in_checkmate(void)156 int get_black_in_checkmate(void) {
157 return black_in_checkmate;
158 }
159
get_turn_counter(void)160 int get_turn_counter(void) {
161 return turn_counter_start;
162 }
163
reset_turn_counter(void)164 static void reset_turn_counter(void) {
165 turn_counter_start = SDL_GetTicks();
166 }
167
poll_event(gg_event_t * event)168 static int poll_event(gg_event_t *event) {
169 gg_event_t gg_event;
170 SDL_Event sdl_event;
171
172 audio_poll(1);
173
174 while (SDL_PollEvent(&sdl_event)) {
175
176 if (sdl_event.type == SDL_QUIT)
177 /* FIXME */
178 exit(0);
179
180 if ((sdl_event.type == SDL_KEYDOWN && sdl_event.key.keysym.mod & KMOD_ALT &&
181 sdl_event.key.keysym.sym == SDLK_RETURN) ||
182 (sdl_event.type == SDL_KEYDOWN && sdl_event.key.keysym.sym == SDLK_F11)) {
183 DBG_LOG("Toggled fullscreen");
184 toggle_fullscreen();
185 continue;
186 }
187
188 if ((sdl_event.type == SDL_KEYDOWN && sdl_event.key.keysym.mod & KMOD_CTRL &&
189 sdl_event.key.keysym.sym == SDLK_f)) {
190 DBG_LOG("Toggled fps counter");
191 toggle_show_fps();
192 continue;
193 }
194
195 gg_event = convert_event(&sdl_event);
196
197 *event = gg_event;
198 return 1;
199 }
200
201 return 0;
202 }
203
init_screen_fbo_ms(int width,int height,int ms)204 static void init_screen_fbo_ms(int width, int height, int ms) {
205 glBindFramebuffer(GL_FRAMEBUFFER, screen_fb);
206
207 glBindRenderbuffer(GL_RENDERBUFFER, screen_color_rb);
208 glRenderbufferStorageMultisample(GL_RENDERBUFFER, ms, GL_RGBA8, width, height);
209 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, screen_color_rb);
210
211 glBindRenderbuffer(GL_RENDERBUFFER, screen_depth_stencil_rb);
212 glRenderbufferStorageMultisample(GL_RENDERBUFFER, ms, GL_DEPTH24_STENCIL8, width, height);
213 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, screen_depth_stencil_rb);
214
215 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
216 DBG_ERROR("Failed to set up screen FBO with %dx multisampling", ms);
217 exit(1);
218 }
219 }
220
init_screen_temp_fbo(int width,int height)221 static void init_screen_temp_fbo(int width, int height) {
222 glBindFramebuffer(GL_FRAMEBUFFER, screen_temp_fb);
223
224 glBindRenderbuffer(GL_RENDERBUFFER, screen_temp_color_rb);
225 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
226 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, screen_temp_color_rb);
227
228 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
229 DBG_ERROR("Failed to set up temp FBO");
230 exit(1);
231 }
232 }
233
init_screen_fbo(int width,int height,int ms)234 static void init_screen_fbo(int width, int height, int ms) {
235 glGenFramebuffers(1, &screen_fb); // Our default-bound framebuffer
236 glGenRenderbuffers(1, &screen_color_rb);
237 glGenRenderbuffers(1, &screen_depth_stencil_rb);
238 init_screen_fbo_ms(width, height, ms);
239
240 glGenFramebuffers(1, &screen_temp_fb);
241 glGenRenderbuffers(1, &screen_temp_color_rb);
242 init_screen_temp_fbo(width, height);
243
244 glBindFramebuffer(GL_FRAMEBUFFER, screen_fb);
245 }
246
blit_fbo()247 void blit_fbo() {
248 int width, height;
249 SDL_GetWindowSize(sdl_window, &width, &height);
250
251 const int fbo_width = get_screen_width();
252 const int fbo_height = get_screen_height();
253
254 // Letterboxing for fullscreen
255 int start_x = 0, start_y = 0;
256 int new_width = width;
257 int new_height = height;
258
259 if (screen_fs) {
260 if (width * fbo_height > fbo_width * height) {
261 new_width = fbo_width * height / fbo_height;
262 start_x = (width - new_width) >> 1;
263 } else {
264 new_height = fbo_height * width / fbo_width;
265 start_y = (height - new_height) >> 1;
266 }
267 }
268
269 // Multisampled buffer requires a same-dimension blit to resolve
270 if (screen_ms && (new_width != fbo_width || new_height != fbo_height)) {
271 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, screen_temp_fb);
272 glBlitFramebuffer(0, 0, fbo_width, fbo_height, 0, 0, fbo_width, fbo_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
273 glBindFramebuffer(GL_READ_FRAMEBUFFER, screen_temp_fb);
274 }
275
276 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
277 glClear(GL_COLOR_BUFFER_BIT);
278 glBlitFramebuffer(0, 0, fbo_width, fbo_height, start_x, start_y, new_width + start_x, new_height + start_y,
279 GL_COLOR_BUFFER_BIT, GL_LINEAR);
280
281 SDL_GL_SwapWindow(sdl_window);
282
283 glBindFramebuffer(GL_FRAMEBUFFER, screen_fb);
284 }
285
286 /** Implements ui_driver::menu */
do_menu(int * pgn)287 static config_t *do_menu(int *pgn) {
288 title_process_retval = 2;
289
290 resize_window(screen_width, screen_height);
291 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
292 glEnable(GL_BLEND);
293 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
294 engine_error_shown = 0;
295 set_loading = FALSE;
296 draw_credits(1);
297 open_title_root_dialog();
298 if (mode_set_failed) {
299 gg_dialog_open(
300 dialog_error_create(gg_dialog_get_active(), "Error: failed to set video mode; using defaults", NULL));
301 mode_set_failed = 0;
302 }
303
304 set_fade_start(gg_system_get_ticks());
305 set_show_egg(FALSE);
306
307 DBG_LOG("Entering title menu");
308
309 while (1) {
310 const Uint8 *keystate;
311 gg_event_t event;
312
313 keystate = SDL_GetKeyboardState(NULL);
314
315 egg_req1 = FALSE;
316
317 gg_dialog_cleanup();
318
319 /* Draw the menu.. */
320 glDisable(GL_BLEND);
321 glDisable(GL_DEPTH_TEST);
322 draw_texture_fullscreen(&menu_title_tex, 1.0f);
323 glEnable(GL_BLEND);
324 glEnable(GL_DEPTH_TEST);
325 text_draw_string_right(get_gl_width() - 20, 20, g_version, 0.75f, get_col(COL_WHITE));
326
327 /*if (get_show_egg())
328 text_draw_string(560, 440, "Egg!", 1, get_col(COL_WHITE));*/
329
330 switch (menu_state) {
331 case MENU_STATE_FADE_IN:
332 while (poll_event(&event))
333 ;
334 gg_dialog_render_all();
335
336 if (!draw_fade(FADE_IN)) {
337 menu_state = MENU_STATE_IN_MENU;
338 draw_credits(1);
339 }
340 break;
341
342 case MENU_STATE_IN_MENU:
343
344 if (keystate[SDL_SCANCODE_UP])
345 egg_req1 = TRUE;
346
347 while (poll_event(&event))
348 gg_dialog_input_current(event);
349
350 if (title_process_retval == 1)
351 return NULL;
352
353 if (set_loading) {
354 gg_widget_t *widget = gg_label_create("Loading, please wait...");
355 widget = gg_dialog_create(widget, NULL, NULL, 0);
356 gg_dialog_set_style(GG_DIALOG(widget), get_menu_style());
357 gg_dialog_open(GG_DIALOG(widget));
358 menu_state = MENU_STATE_LOAD;
359 } else
360 draw_credits(0);
361
362 gg_dialog_render_all();
363 break;
364
365 case MENU_STATE_LOAD: {
366 option_t *option = config_get_option("theme");
367 struct theme_struct *theme = option->selected->data;
368
369 load_theme(theme);
370 reset_transition(TRUE);
371 }
372
373 *pgn = pgn_slot;
374 if (pgn_slot >= 0)
375 config = *get_config_save(pgn_slot);
376
377 reset_3d(config.player[WHITE] == PLAYER_ENGINE);
378
379 set_fade_start(gg_system_get_ticks());
380 gg_dialog_close();
381
382 menu_state = MENU_STATE_FADE_OUT;
383 break;
384
385 case MENU_STATE_FADE_OUT:
386 while (poll_event(&event))
387 ;
388 if ((get_show_egg() && !draw_sonic_fade(FADE_OUT)) || (!get_show_egg() && !draw_fade(FADE_OUT))) {
389 set_fade_start(gg_system_get_ticks());
390 menu_state = MENU_STATE_RETURN;
391 return &config;
392 }
393 break;
394
395 case MENU_STATE_RETURN:
396 while (poll_event(&event))
397 ;
398 gg_dialog_render_all();
399
400 if (!draw_fade(FADE_IN))
401 menu_state = MENU_STATE_IN_MENU;
402 break;
403 }
404
405 /* Draw mouse cursor.. */
406 draw_texture(get_menu_mouse_cursor(), get_mouse_x(), (479 - get_mouse_y() - 32), 32, 32, 1.0f,
407 get_col(COL_WHITE));
408
409 gl_swap();
410 }
411 }
412
free_menu_tex(void)413 static void free_menu_tex(void) {
414 glDeleteTextures(1, &menu_title_tex.id);
415 glDeleteTextures(1, &get_menu_mouse_cursor()->id);
416 glDeleteTextures(1, &get_menu_border()->id);
417 glDeleteTextures(1, &get_text_character(0)->id);
418 }
419
load_menu_tex(void)420 static void load_menu_tex(void) {
421 ch_datadir();
422 /* For the menu.. */
423 load_texture_png(&menu_title_tex, "menu_title.png", 0, 1);
424 /* New text stuff. */
425 generate_text_chars();
426
427 chdir("styles");
428 chdir("default");
429 load_border(get_menu_border(), "border.png");
430 load_texture_png(get_menu_mouse_cursor(), "mouse_cursor.png", 1, 1);
431 }
432
set_fullscreen(int fullscreen)433 static int set_fullscreen(int fullscreen) {
434 if (SDL_SetWindowFullscreen(sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) > 0) {
435 DBG_ERROR("Failed to set fullscreen to %s: %s", fullscreen ? "on" : "off", SDL_GetError());
436 return 1;
437 }
438
439 return 0;
440 }
441
resize(int width,int height,int fullscreen,int ms)442 static int resize(int width, int height, int fullscreen, int ms) {
443 DBG_LOG("Resizing video mode to %ix%i; fullscreen %s; %ix multisampling", width, height, fullscreen ? "on" : "off",
444 ms);
445
446 if (ms > max_samples)
447 return 1;
448
449 if (fullscreen != screen_fs && set_fullscreen(fullscreen))
450 return 1;
451
452 if (screen_width != width || screen_height != height || screen_fs != fullscreen) {
453 SDL_SetWindowSize(sdl_window, width, height);
454 init_screen_temp_fbo(width, height);
455 }
456
457 if (screen_ms != ms || screen_width != width || screen_height != height)
458 init_screen_fbo_ms(width, height, ms);
459
460 glBindFramebuffer(GL_FRAMEBUFFER, 0);
461 glClear(GL_COLOR_BUFFER_BIT);
462 glBindFramebuffer(GL_FRAMEBUFFER, screen_temp_fb);
463 glClear(GL_COLOR_BUFFER_BIT);
464 glBindFramebuffer(GL_FRAMEBUFFER, screen_fb);
465 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
466
467 screen_width = width;
468 screen_height = height;
469 screen_fs = fullscreen;
470 screen_ms = ms;
471 resize_window(screen_width, screen_height);
472
473 return 0;
474 }
475
476 /** Implements ui_driver::create_window. */
create_window(int width,int height,int fullscreen,int ms)477 static int create_window(int width, int height, int fullscreen, int ms) {
478 int i, err;
479
480 screen_width = width;
481 screen_height = height;
482 screen_fs = fullscreen;
483 screen_ms = ms;
484
485 int video_flags = SDL_WINDOW_OPENGL;
486
487 DBG_LOG("Setting video mode to %ix%i; fullscreen %s; %ix multisampling", width, height, fullscreen ? "on" : "off",
488 ms);
489
490 if (fullscreen)
491 video_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
492
493 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
494 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
495
496 sdl_window =
497 SDL_CreateWindow("DreamChess", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, video_flags);
498
499 if (!sdl_window) {
500 DBG_ERROR("Failed to set video mode: %ix%i; fullscreen %s; %ix multisampling: %s", width, height,
501 fullscreen ? "on" : "off", ms, SDL_GetError());
502 mode_set_failed = 1;
503 return 1;
504 }
505
506 if (!SDL_GL_CreateContext(sdl_window)) {
507 DBG_ERROR("Failed to create GL context: %s", SDL_GetError());
508 SDL_DestroyWindow(sdl_window);
509 mode_set_failed = 1;
510 return 1;
511 }
512
513 err = glewInit();
514 if (err != GLEW_OK) {
515 DBG_ERROR("Failed to initialize GLEW: %s", glewGetErrorString(err));
516 exit(1);
517 }
518
519 if (!glewIsSupported("GL_ARB_framebuffer_object")) {
520 DBG_ERROR("OpenGL extension GL_ARB_framebuffer_object not supported");
521 exit(1);
522 }
523
524 if (!glewIsSupported("GL_ARB_texture_non_power_of_two")) {
525 DBG_ERROR("OpenGL extension GL_ARB_texture_non_power_of_two not supported");
526 exit(1);
527 }
528
529 glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
530 init_fbo();
531
532 if (ms > max_samples) {
533 SDL_DestroyWindow(sdl_window);
534 mode_set_failed = 1;
535 return 1;
536 }
537
538 init_screen_fbo(width, height, ms);
539
540 init_gl();
541 load_menu_tex();
542
543 SDL_ShowCursor(SDL_DISABLE);
544
545 // SDL_WM_SetCaption( "DreamChess", NULL );
546
547 gg_system_init(get_gg_driver_sdlgl());
548 get_ingame_style()->fade_col = gg_colour(0.0f, 0.0f, 0.0f, 0.5f);
549 get_ingame_style()->hor_pad = 20;
550 get_ingame_style()->vert_pad = 10;
551
552 for (i = 0; i < 9; i++)
553 get_ingame_style()->border.image[i] = &get_border()[i];
554
555 get_menu_style()->textured = 1;
556 get_menu_style()->fade_col = gg_colour(0.0f, 0.0f, 0.0f, 0.0f);
557 get_menu_style()->hor_pad = 20;
558 get_menu_style()->vert_pad = 10;
559
560 for (i = 0; i < 9; i++)
561 get_menu_style()->border.image[i] = &get_menu_border()[i];
562
563 ch_datadir();
564 audio_init();
565
566 /* Make virtual keyboard table? */
567 populate_key_table();
568
569 update_fps_time();
570
571 /* Register music callback */
572 audio_set_music_callback(music_callback);
573
574 return 0;
575 }
576
577 /** Implements ui_driver::update. */
update(board_t * b,move_t * move)578 static void update(board_t *b, move_t *move) {
579 board = *b;
580
581 if (move != NULL)
582 start_piece_move(move->source, move->destination);
583 if (board.state == BOARD_STALEMATE) {
584 game_in_stalemate = TRUE;
585 } else
586 game_in_stalemate = FALSE;
587
588 black_in_check = FALSE;
589 white_in_check = FALSE;
590 if (board.state == BOARD_CHECK) {
591 if (IS_WHITE(board.turn))
592 white_in_check = TRUE;
593 else
594 black_in_check = TRUE;
595 }
596 black_in_checkmate = FALSE;
597 white_in_checkmate = FALSE;
598 if (board.state == BOARD_CHECKMATE) {
599 if (IS_WHITE(board.turn))
600 white_in_checkmate = TRUE;
601 else
602 black_in_checkmate = TRUE;
603 }
604
605 /* FIXME */
606 while (get_piece_moving_done() == 0)
607 poll_move();
608 }
609
610 /** Implements ui_driver::show_result. */
show_result(result_t * res)611 static void show_result(result_t *res) {
612 gg_dialog_open(dialog_victory_create(res));
613 }
614
615 /** Implements ui_driver::init. */
sdlgl_init(void)616 static void sdlgl_init(void) {
617 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE) < 0) {
618 DBG_ERROR("SDL initialization failed: %s", SDL_GetError());
619 exit(1);
620 }
621
622 ch_datadir();
623 }
624
625 /** Implements ui_driver::exit. */
sdlgl_exit(void)626 static int sdlgl_exit(void) {
627 audio_set_music_callback(NULL);
628
629 gg_system_exit();
630 free_menu_tex();
631 deinit_fbo();
632
633 SDL_Quit();
634 return 0;
635 }
636
637 /** Implements ui_driver::show_message. */
show_message(char * msg)638 static void show_message(char *msg) {
639 gg_dialog_open(dialog_message_create(msg));
640 }
641
642 /** Implements ui_driver::poll. */
poll_move(void)643 static void poll_move(void) {
644 static int source = -1, dest = -1, needprom = 0;
645 /* board_t *board = history->play->board; */
646 move_t move;
647 int input;
648
649 audio_poll(0);
650 draw_scene(&board, screen_fb, reflections);
651 gl_swap();
652
653 if (switch_to_menu == TRUE) {
654 quit_to_menu = 0;
655 switch_to_menu = FALSE;
656 fading_out = FALSE;
657 needprom = 0;
658 source = -1;
659 dest = -1;
660 unload_theme();
661 game_quit();
662 return;
663 } else if (quit_to_menu) {
664 DBG_LOG("Returning to title menu");
665 set_fading_out(TRUE);
666 reset_transition(FALSE);
667 set_fade_start(gg_system_get_ticks());
668 quit_to_menu = FALSE;
669 }
670 input = get_move();
671 /* FIXME */
672 if (!engine_error_shown && game_get_engine_error()) {
673 gg_dialog_open(dialog_engine_error_create());
674 engine_error_shown = 1;
675 return;
676 }
677
678 if (!game_want_move()) {
679 source = -1;
680 dest = -1;
681 needprom = 0;
682 }
683
684 if (source == -1) {
685 source = input;
686 /* Only allow piece of current player to be moved. */
687 if ((source >= 0) && ((PIECE(board.square[source]) == NONE) || (COLOUR(board.square[source]) != board.turn)))
688 source = -1;
689 return;
690 }
691
692 if (dest == -1) {
693 dest = input;
694 if (dest >= 0) {
695 /* Destination square must not contain piece of current player. */
696 if ((PIECE(board.square[dest]) != NONE) && (COLOUR(board.square[dest]) == board.turn)) {
697 dest = -1;
698 /* We use currently selected square as source. */
699 source = input;
700 } else
701 select_piece(-1);
702 }
703 return;
704 }
705
706 if (needprom == 1) {
707 if (dialog_promote_piece != NONE)
708 needprom = 2;
709 return;
710 }
711
712 if ((needprom == 0) && (((board.square[source] == WHITE_PAWN) && (dest >= 56)) ||
713 ((board.square[source] == BLACK_PAWN) && (dest <= 7)))) {
714 gg_dialog_open(dialog_promote_create(COLOUR(board.square[source])));
715 needprom = 1;
716 return;
717 }
718
719 move.source = source;
720 move.destination = dest;
721 if (needprom == 2)
722 move.promotion_piece = dialog_promote_piece;
723 else
724 move.promotion_piece = NONE;
725 needprom = 0;
726
727 /* start_piece_move( source, dest ); */
728
729 source = -1;
730 dest = -1;
731 game_make_move(&move, 1);
732 reset_turn_counter();
733 }
734
735 /** SDL + OpenGL driver. */
736 ui_driver_t ui_sdlgl = {"sdlgl", sdlgl_init, create_window, resize, sdlgl_exit,
737 do_menu, update, poll_move, show_message, show_result};
738