- // window_main.cpp 
-   
- #include "../common.h" 
-   
-   
- // global variables used in this module only 
- static wchar_t folder_path[MAX_PATH]; 
-   
-   
- // prototypes of local functions 
- static bool Button_IsHovered (guibutton_t *button, int gui_x, int gui_y); 
- static bool Button_UpdateHoverState (guibutton_t *button, int gui_x, int gui_y); 
-   
-   
- LRESULT CALLBACK WindowProc_Main (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam) 
- { 
-    // this is the main message handler for the program 
-   
-    static wchar_t fen_string[128]; 
-    static char selectable_parts[14] = "PRNBQK kqbnrp"; 
-    static int prevgui_x = 0; 
-    static int prevgui_y = 0; 
-    static bool ctrl_pressed = false; 
-    static bool rbutton_pushed = false; 
-   
-    unsigned short wParam_hiword; 
-    unsigned short wParam_loword; 
-    int prev_hovered_position[2]; 
-    player_t *current_player; 
-    player_t *opposite_player; 
-    player_t *local_player; 
-    player_t *remote_player; 
-    ccreply_t *entered_ccreply; 
-    boardmove_t *current_move; 
-    float board_x; 
-    float board_y; 
-    int gui_x; 
-    int gui_y; 
-    int line; 
-    int column; 
-    int index_line; 
-    int index_column; 
-    int part_index; 
-    int part_color; 
-    int viewer_index; 
-   
-    // filter out the commonly used message values 
-    wParam_hiword = HIWORD (wParam); 
-    wParam_loword = LOWORD (wParam); 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // has the window just been fired up ? 
-    if (message == WM_CREATE) 
-    { 
-       the_scene.gui.is_entering_text = false; // we are NOT entering text yet 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // else have we clicked on the close button ? 
-    else if (message == WM_CLOSE) 
-    { 
-       if (the_board.game_state == STATE_PLAYING) 
-          DialogBox_Quit (); // if a game has started, ask for confirmation 
-       else 
-          is_dialogbox_quit_validated = true; // if game hasn't started yet, quit without question 
-   
-       return (0); // don't let Windows do the default processing on this message 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // else is the user closing its session OR the window is being destroyed ? 
-    else if ((message == WM_QUERYENDSESSION) || (message == WM_ENDSESSION) || (message == WM_DESTROY)) 
-       terminate_everything = true; // suicide (for some reason, PostQuitMessage() is unreliable !?) 
-   
-    ///////////////// 
-    // MENU EVENTS // 
-    ///////////////// 
-   
-    /////////////// 
-    // menu command 
-    else if (message == WM_COMMAND) 
-    { 
-       // game menu, new game 
-       if (wParam_loword == MENUID_GAME_NEWGAME) 
-       { 
-          if ((the_board.game_state == STATE_PLAYING) && (the_board.move_count > 1)) 
-             DialogBox_Resign (); // if a game is playing, ask to resign first 
-          else 
-             DialogBox_NewGame (); // game not started yet, show the new game dialog box 
-       } 
-   
-       // game menu, setup start position 
-       else if (wParam_loword == MENUID_GAME_SETUPPOSITION) 
-       { 
-          if ((the_board.game_state == STATE_PLAYING) && (the_board.move_count > 1)) 
-             DialogBox_Resign (); // if a game is playing, ask to resign first 
-          else 
-          { 
-             current_move = &the_board.moves[0]; // quick access to start move 
-             memset (¤t_move->slots, 0, sizeof (current_move->slots)); // erase all slots 
-   
-             the_board.game_state = STATE_SETUPPOSITION; // game not started yet, enter board setup mode 
-             the_board.reevaluate = true; // evaluate board again 
-   
-             // display the "please choose start position" phrase in the middle of the screen 
-             Scene_SetText (&the_scene.gui.central_text, 50.0f, 50.0f, -1, ALIGN_CENTER, ALIGN_CENTER, ALIGN_CENTER, centermsg_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 191), 
-                            999999.0f, true, LOCALIZE (L"SetupMode")); 
-             the_scene.gui.partspick_selectedpart = ' '; // no selected part yet 
-             the_scene.update = true; // and update the 3D scene 
-          } 
-       } 
-   
-       // game menu, load game 
-       else if (wParam_loword == MENUID_GAME_LOAD) 
-          DialogBox_Load (); // fire up the load dialog box 
-   
-       // game menu, save game 
-       else if (wParam_loword == MENUID_GAME_SAVE) 
-       { 
-          if (save_pathname[0] != 0) 
-             is_dialogbox_save_validated = true; // if the filename is known, save it directly 
-          else 
-             DialogBox_Save (); // else fire up the save dialog box 
-       } 
-   
-       // game menu, save as 
-       else if (wParam_loword == MENUID_GAME_SAVEAS) 
-          DialogBox_Save (); // fire up the save dialog box 
-   
-       // game menu, save position as 
-       else if (wParam_loword == MENUID_GAME_SAVEPOSITIONAS) 
-          DialogBox_SavePosition (); // fire up the save position dialog box 
-   
-       // game menu, resign 
-       else if (wParam_loword == MENUID_GAME_RESIGN) 
-          DialogBox_Resign (); // if a game has started, ask for confirmation 
-   
-       // game menu, statistics (stats are only available in online mode) 
-       else if (wParam_loword == MENUID_GAME_STATISTICS) 
-       { 
-          local_player = Player_FindByType (PLAYER_HUMAN); 
-          if (local_player != NULL) 
-             PlayerCard_FindOrCreate (local_player->name); // display player's own player card 
-       } 
-   
-       // game menu, options 
-       else if (wParam_loword == MENUID_GAME_OPTIONS) 
-          DialogBox_Options (); // fire up the options dialog box 
-   
-       // game menu, quit 
-       else if (wParam_loword == MENUID_GAME_QUIT) 
-       { 
-          if (the_board.game_state == STATE_PLAYING) 
-             DialogBox_Quit (); // if a game has started, ask for confirmation 
-          else 
-             is_dialogbox_quit_validated = true; // if game hasn't started yet, quit without question 
-       } 
-   
-       // chessboard menu, suggest move 
-       else if (wParam_loword == MENUID_CHESSBOARD_SUGGESTMOVE) 
-          the_board.players[current_viewer].wants_hint = true; // remember this player wants a hint 
-   
-       // chessboard menu, cancel last move 
-       else if (wParam_loword == MENUID_CHESSBOARD_CANCELLASTMOVE) 
-          the_board.players[current_viewer].wants_cancel = true; // remember this player wants to cancel his last move 
-   
-       // chessboard menu, comment move 
-       else if (wParam_loword == MENUID_CHESSBOARD_COMMENTMOVE) 
-          DialogBox_Comment (); // fire up the comment dialog box 
-   
-       // chessboard menu, go to move 
-       else if (wParam_loword == MENUID_CHESSBOARD_GOTOMOVE) 
-          DialogBox_GoToMove (); // fire up the go to move dialog box 
-   
-       // chessboard menu, swap sides 
-       else if (wParam_loword == MENUID_CHESSBOARD_SWAPSIDES) 
-          the_board.want_playerswap = true; // remember board sides are to be swapped 
-   
-       // chessboard menu, beginning of game 
-       else if (wParam_loword == MENUID_CHESSBOARD_BEGINNINGOFGAME) 
-       { 
-          the_board.viewed_move = 0; // enter view mode and go to the beginning of the game 
-          Audio_PlaySound (SOUNDTYPE_CLICK); // make a click sound 
-          the_board.reevaluate = true; // evaluate board again 
-       } 
-   
-       // chessboard menu, previous move (only if arrow is enabled) 
-       else if ((wParam_loword == MENUID_CHESSBOARD_PREVIOUSMOVE) && (the_scene.gui.larrow.state != 0)) 
-       { 
-          the_board.viewed_move--; // enter view mode and go back one move 
-          Audio_PlaySound (SOUNDTYPE_CLICK); // make a click sound 
-          the_board.reevaluate = true; // evaluate board again 
-       } 
-   
-       // chessboard menu, next move (only if arrow is enabled) 
-       else if ((wParam_loword == MENUID_CHESSBOARD_NEXTMOVE) && (the_scene.gui.rarrow.state != 0)) 
-       { 
-          the_board.viewed_move++; // enter view mode and go forward one move 
-          Audio_PlaySound (SOUNDTYPE_CLICK); // make a click sound 
-          the_board.reevaluate = true; // evaluate board again 
-       } 
-   
-       // chessboard menu, current state of game 
-       else if (wParam_loword == MENUID_CHESSBOARD_CURRENTSTATEOFGAME) 
-       { 
-          the_board.viewed_move = the_board.move_count - 1; // enter view mode and go to the current state of the game 
-          Audio_PlaySound (SOUNDTYPE_CLICK); // make a click sound 
-          the_board.reevaluate = true; // evaluate board again 
-       } 
-   
-       // chessboard menu, top view 
-       else if (wParam_loword == MENUID_CHESSBOARD_TOPVIEW) 
-       { 
-          // cycle through both players and change their view angles EXCEPT the opponent if he's human 
-          for (viewer_index = 0; viewer_index < 2; viewer_index++) 
-             if ((the_board.players[viewer_index].type == PLAYER_COMPUTER) 
-                 || (the_board.players[viewer_index].type == PLAYER_INTERNET) 
-                 || (viewer_index == current_viewer)) 
-             { 
-                the_board.players[viewer_index].view_pitch = 89.99f; 
-                the_board.players[viewer_index].view_yaw = (current_viewer == COLOR_BLACK ? 90.0f : -90.0f); 
-                the_board.players[viewer_index].view_distance = 58.0f; 
-             } 
-       } 
-   
-       // chessboard menu, default view 
-       else if (wParam_loword == MENUID_CHESSBOARD_DEFAULTVIEW) 
-       { 
-          // cycle through both players and change their view angles EXCEPT the opponent if he's human 
-          for (viewer_index = 0; viewer_index < 2; viewer_index++) 
-             if ((the_board.players[viewer_index].type == PLAYER_COMPUTER) 
-                 || (the_board.players[viewer_index].type == PLAYER_INTERNET) 
-                 || (viewer_index == current_viewer)) 
-             { 
-                the_board.players[viewer_index].view_pitch = 55.0f; 
-                the_board.players[viewer_index].view_yaw = (current_viewer == COLOR_BLACK ? 90.0f : -90.0f); 
-                the_board.players[viewer_index].view_distance = 70.0f; 
-             } 
-       } 
-   
-       // chessboard menu, reset view 
-       else if (wParam_loword == MENUID_CHESSBOARD_RESETVIEW) 
-       { 
-          // cycle through both players and change their view angles EXCEPT the opponent if he's human 
-          for (viewer_index = 0; viewer_index < 2; viewer_index++) 
-             if ((the_board.players[viewer_index].type == PLAYER_COMPUTER) 
-                 || (the_board.players[viewer_index].type == PLAYER_INTERNET) 
-                 || (viewer_index == current_viewer)) 
-             { 
-                the_board.players[viewer_index].view_pitch = the_board.players[current_viewer].custom_pitch; 
-                the_board.players[viewer_index].view_yaw = the_board.players[current_viewer].custom_yaw; 
-                the_board.players[viewer_index].view_distance = the_board.players[current_viewer].custom_distance; 
-             } 
-       } 
-   
-       // chessboard menu, zoom in 
-       else if (wParam_loword == MENUID_CHESSBOARD_ZOOMIN) 
-       { 
-          // scroll up & save this as the new custom distance 
-          the_board.players[current_viewer].view_distance = max (48.0f, the_board.players[current_viewer].view_distance - 2.0f); 
-          the_board.players[current_viewer].custom_distance = the_board.players[current_viewer].view_distance; 
-          the_scene.update = true; // update the 3D scene 
-       } 
-   
-       // chessboard menu, zoom out 
-       else if (wParam_loword == MENUID_CHESSBOARD_ZOOMOUT) 
-       { 
-          // scroll down & save this as the new custom distance 
-          the_board.players[current_viewer].view_distance = min (100.0f, the_board.players[current_viewer].view_distance + 2.0f); 
-          the_board.players[current_viewer].custom_distance = the_board.players[current_viewer].view_distance; 
-          the_scene.update = true; // update the 3D scene 
-       } 
-   
-       // chessboard menu, change appearance 
-       else if (wParam_loword == MENUID_CHESSBOARD_CHANGEAPPEARANCE) 
-          DialogBox_ChangeAppearance (); 
-   
-       // chessboard menu, display windows desktop 
-       else if (wParam_loword == MENUID_CHESSBOARD_DISPLAYWINDOWSDESKTOP) 
-          ShowWindow (hWnd, SW_MINIMIZE); 
-   
-       // internet menu, show online players 
-       else if (wParam_loword == MENUID_INTERNET_SHOWONLINEPLAYERS) 
-          Window_Opponents (); 
-   
-       // internet menu, show sought games 
-       else if (wParam_loword == MENUID_INTERNET_SHOWSOUGHTGAMES) 
-          Window_Sought (); 
-   
-       // internet menu, seek game 
-       else if (wParam_loword == MENUID_INTERNET_SEEKGAME) 
-          DialogBox_SendSeek (); 
-   
-       // internet menu, chatter channels 
-       else if (wParam_loword == MENUID_INTERNET_CHATTERCHANNELS) 
-          Window_ChatterChannels (); 
-   
-       // internet menu, enter chat text 
-       else if (wParam_loword == MENUID_INTERNET_ENTERCHATTEXT) 
-          PostMessage (hWnd, WM_CHAR, L' ', 0); // emulate a space bar hit 
-   
-       // internet menu, display player card 
-       else if (wParam_loword == MENUID_INTERNET_DISPLAYPLAYERCARD) 
-          DialogBox_PlayerInfoName (); 
-   
-       // internet menu, display your card 
-       else if (wParam_loword == MENUID_INTERNET_DISPLAYYOURCARD) 
-       { 
-          local_player = Player_FindByType (PLAYER_HUMAN); 
-          if (local_player != NULL) 
-             PlayerCard_FindOrCreate (local_player->name); // display player's own player card 
-       } 
-   
-       // internet menu, MOTD 
-       else if (wParam_loword == MENUID_INTERNET_MOTD) 
-          Window_MOTD (); 
-   
-       // help menu, help 
-       else if (wParam_loword == MENUID_HELP_HELP) 
-       { 
-          swprintf_s (folder_path, WCHAR_SIZEOF (folder_path), L"%s\\Chess Giants (%s).html", app_path, os_language); 
-          ShellExecute (NULL, L"open", folder_path, NULL, NULL, SW_MAXIMIZE); // fire up the help file 
-       } 
-   
-       // help menu, get chess games 
-       else if (wParam_loword == MENUID_HELP_GETCHESSGAMES) 
-          ShellExecute (NULL, L"open", L"http://www.chessgames.com", NULL, NULL, SW_MAXIMIZE); // fire up the browser 
-   
-       // help menu, add/modify visual themes 
-       else if (wParam_loword == MENUID_HELP_ADDMODIFYVISUALTHEMES) 
-       { 
-          swprintf_s (folder_path, WCHAR_SIZEOF (folder_path), L"%s\\themes", app_path); 
-          ShellExecute (NULL, L"open", folder_path, NULL, NULL, SW_SHOWNORMAL); // fire up Windows Explorer 
-       } 
-   
-       // help menu, add/modify translations 
-       else if (wParam_loword == MENUID_HELP_ADDMODIFYTRANSLATIONS) 
-       { 
-          swprintf_s (folder_path, WCHAR_SIZEOF (folder_path), L"%s\\data\\languages", app_path); 
-          ShellExecute (NULL, L"open", folder_path, NULL, NULL, SW_SHOWNORMAL); // fire up Windows Explorer 
-       } 
-   
-       // help menu, about 
-       else if (wParam_loword == MENUID_HELP_ABOUT) 
-          DialogBox_About (); // show the About dialog box 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    ///////////////////////////////////////////////////// 
-    // ctrl key press or release (while not in animation) 
-    else if ((message == WM_KEYDOWN) && (wParam == VK_CONTROL) && (animation_endtime + 1.0f < current_time)) 
-    { 
-       ctrl_pressed = true; // remember the ctrl key is pressed 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-    else if ((message == WM_KEYUP) && (wParam == VK_CONTROL) && (animation_endtime + 1.0f < current_time)) 
-    { 
-       ctrl_pressed = false; // remember the ctrl key is released 
-       rbutton_pushed = false; // remember button is released 
-       the_scene.update = true; // update the 3D scene 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    ////////////////// 
-    // MOUSE EVENTS // 
-    ////////////////// 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // left mouse button push 
-    else if (message == WM_LBUTTONDOWN) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       // is the ctrl key pressed (emulates a right click) ? 
-       if (ctrl_pressed) 
-       { 
-          prevgui_x = GET_X_LPARAM (lParam); // remember mouse coordinates 
-          prevgui_y = GET_Y_LPARAM (lParam); 
-   
-          // if we click something, stop moving the table immediately 
-   
-          // cycle through both players and change their view angles EXCEPT the opponent if he's human 
-          for (viewer_index = 0; viewer_index < 2; viewer_index++) 
-             if ((the_board.players[viewer_index].type == PLAYER_COMPUTER) 
-                 || (the_board.players[viewer_index].type == PLAYER_INTERNET) 
-                 || (viewer_index == current_viewer)) 
-             { 
-                the_board.players[viewer_index].view_pitch = current_pitch; 
-                the_board.players[viewer_index].view_yaw = current_yaw; 
-             } 
-   
-          rbutton_pushed = true; // remember button is clicked 
-       } 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // left mouse button release 
-    else if (message == WM_LBUTTONUP) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       // is the ctrl key pressed (emulates a right click) ? 
-       if (ctrl_pressed) 
-       { 
-          rbutton_pushed = false; // remember button is released 
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       prevgui_x = GET_X_LPARAM (lParam); // remember mouse coordinates 
-       prevgui_y = GET_Y_LPARAM (lParam); 
-   
-       // get mouse coordinates 
-       gui_x = GET_X_LPARAM (lParam); 
-       gui_y = GET_Y_LPARAM (lParam); 
-   
-       // is the left arrow displayed AND is the mouse hovering it ? 
-       if ((the_scene.gui.larrow.state != 0) && Button_IsHovered (&the_scene.gui.larrow, gui_x, gui_y)) 
-          SendMessage (hWnd, WM_COMMAND, MENUID_CHESSBOARD_PREVIOUSMOVE, NULL); // send a "previous move" event 
-   
-       // is the right arrow displayed AND is the mouse hovering it ? 
-       if ((the_scene.gui.rarrow.state != 0) && Button_IsHovered (&the_scene.gui.rarrow, gui_x, gui_y)) 
-          SendMessage (hWnd, WM_COMMAND, MENUID_CHESSBOARD_NEXTMOVE, NULL); // send a "next move" event 
-   
-       // is the chat button displayed AND is the mouse hovering it ? 
-       if ((the_scene.gui.chatbutton.state != 0) && Button_IsHovered (&the_scene.gui.chatbutton, gui_x, gui_y)) 
-       { 
-          opposite_player = Player_FindByType (PLAYER_INTERNET); // get a hand on the remote player 
-   
-          // find or create the corresponding interlocutor structure and fire it up 
-          if (opposite_player != NULL) 
-             Interlocutor_FindOrCreate (opposite_player->name); 
-       } 
-   
-       // is the games button displayed AND is the mouse hovering it ? 
-       if ((the_scene.gui.gamesbutton.state != 0) && Button_IsHovered (&the_scene.gui.gamesbutton, gui_x, gui_y)) 
-          Window_Sought (); // if so, display the sought games window 
-   
-       // is the people button displayed AND is the mouse hovering it ? 
-       if ((the_scene.gui.peoplebutton.state != 0) && Button_IsHovered (&the_scene.gui.peoplebutton, gui_x, gui_y)) 
-          Window_Opponents (); // if so, display the opponents window 
-   
-       // is the parts selection line displayed AND is the mouse anywhere near it ? 
-       if (the_scene.gui.is_partspick_displayed && Render_IsMouseInBox (gui_x, gui_y, 0.0f, 0.0f, 100.0f, 11.0f)) 
-       { 
-          // for each selectable part, if the mouse is on it, mark it as selected 
-          for (part_index = 0; part_index < 13; part_index++) 
-             if (Render_IsMouseInBox (gui_x, gui_y, part_index * (100.0f / 13.0f), 0, 100.0f / 13.0f, 11.0f)) 
-             { 
-                the_scene.gui.partspick_selectedpart = selectable_parts[part_index]; // mark it as selected 
-                Audio_PlaySound (SOUNDTYPE_CLICK); // make a click sound 
-                break; // no need to search further if one selection was found 
-             } 
-       } 
-   
-       // get current player and see if we're online 
-       current_player = Player_GetCurrent (); 
-       remote_player = Player_FindByType (PLAYER_INTERNET); 
-   
-       // if we are not allowed to select anything, don't even try 
-       if ((current_player->type != PLAYER_HUMAN) || (the_board.viewed_move != the_board.move_count - 1) 
-           || ((remote_player != NULL) && !remote_player->is_in_game)) 
-       { 
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       // it's a single click. The user clicked on a square. 
-   
-       // figure out the coordinates on table 
-       Render_MouseToFloor (gui_x, gui_y, &board_x, &board_y); 
-   
-       // translate them to board coordinates 
-       the_board.hovered_position[0] = (int) floor ((20.0f - board_y) / 5.0f); 
-       the_board.hovered_position[1] = 7 - (int) floor ((20.0f - board_x) / 5.0f); 
-       highlight_endtime = 0; // stop highlighting anything 
-   
-       // if it's outside the table, end the job 
-       if (!IS_VALID_POSITION (the_board.hovered_position)) 
-       { 
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       // we clicked a valid slot on the table 
-   
-       current_move = &the_board.moves[the_board.viewed_move]; // quick access to current move 
-   
-       /////////////////////////////////// 
-       // are we in parts placement mode ? 
-       if (the_board.game_state == STATE_SETUPPOSITION) 
-       { 
-          // quick access to line and column 
-          line = the_board.hovered_position[0]; 
-          column = the_board.hovered_position[1]; 
-   
-          // figure out the color of the part we are placing 
-          if (the_scene.gui.partspick_selectedpart == tolower (the_scene.gui.partspick_selectedpart)) 
-             part_color = COLOR_BLACK; // black color 
-          else 
-             part_color = COLOR_WHITE; // white color 
-   
-          // are we erasing a king ? if so, replace it at its default location 
-          if ((current_move->slots[line][column].part == PART_KING) && (current_move->slots[line][column].color == COLOR_BLACK) 
-              && (the_scene.gui.partspick_selectedpart != 'k')) 
-          { 
-             // is it ALREADY the king's default location ? if so, give up 
-             if ((line == 7) && (column == 4)) 
-             { 
-                Audio_PlaySound (SOUNDTYPE_ILLEGALMOVE); // play the "illegal move" sound 
-                return (DefWindowProc (hWnd, message, wParam, lParam)); // call the default window message proc 
-             } 
-   
-             Move_SetSlot (current_move, 7, 4, COLOR_BLACK, PART_KING); // replace black king 
-          } 
-          else if ((current_move->slots[line][column].part == PART_KING) && (current_move->slots[line][column].color == COLOR_WHITE) 
-                   && (the_scene.gui.partspick_selectedpart != 'K')) 
-          { 
-             // is it ALREADY the king's default location ? if so, give up 
-             if ((line == 0) && (column == 4)) 
-             { 
-                Audio_PlaySound (SOUNDTYPE_ILLEGALMOVE); // play the "illegal move" sound 
-                return (DefWindowProc (hWnd, message, wParam, lParam)); // call the default window message proc 
-             } 
-   
-             Move_SetSlot (current_move, 0, 4, COLOR_WHITE, PART_KING); // replace white king 
-          } 
-   
-          // place the selected part on the board 
-          if (tolower (the_scene.gui.partspick_selectedpart) == 'p') 
-             Move_SetSlot (current_move, line, column, part_color, PART_PAWN); // pawn 
-          else if (tolower (the_scene.gui.partspick_selectedpart) == 'r') 
-             Move_SetSlot (current_move, line, column, part_color, PART_ROOK); // rook 
-          else if (tolower (the_scene.gui.partspick_selectedpart) == 'n') 
-             Move_SetSlot (current_move, line, column, part_color, PART_KNIGHT); // knight 
-          else if (tolower (the_scene.gui.partspick_selectedpart) == 'b') 
-             Move_SetSlot (current_move, line, column, part_color, PART_BISHOP); // bishop 
-          else if (tolower (the_scene.gui.partspick_selectedpart) == 'q') 
-             Move_SetSlot (current_move, line, column, part_color, PART_QUEEN); // queen 
-          else if (tolower (the_scene.gui.partspick_selectedpart) == 'k') 
-          { 
-             // parse the board for other kings of the same color and erase them 
-             for (index_line = 0; index_line < 8; index_line++) 
-                for (index_column = 0; index_column < 8; index_column++) 
-                   if ((current_move->slots[index_line][index_column].color == part_color) 
-                       && (current_move->slots[index_line][index_column].part == PART_KING)) 
-                      memset (¤t_move->slots[index_line][index_column], 0, sizeof (boardslot_t)); // erase this slot 
-   
-             Move_SetSlot (current_move, line, column, part_color, PART_KING); // king 
-          } 
-          else 
-             Move_SetSlot (current_move, line, column, 0, PART_NONE); // no part 
-   
-          // figure out which sound to play 
-          if (the_scene.gui.partspick_selectedpart != ' ') 
-             Audio_PlaySound (SOUNDTYPE_MOVE); // play a move sound when placing a part 
-   
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-       // end of parts placement mode 
-       ////////////////////////////// 
-   
-       // does a selection NOT exist yet ? 
-       if (!IS_VALID_POSITION (the_board.selected_position)) 
-       { 
-          // is there a selectable part at this location ? 
-          if ((current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].part != PART_NONE) 
-             && (current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].color == Board_ColorToMove (&the_board))) 
-          { 
-             // mark the selected position as selected (and remember it) 
-             the_board.selected_position[0] = the_board.hovered_position[0]; 
-             the_board.selected_position[1] = the_board.hovered_position[1]; 
-          } 
-   
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       // a selection exists already 
-   
-       // is it the slot that was previously selected ? (i.e, user wants to "unselect" it) 
-       if ((the_board.hovered_position[0] == the_board.selected_position[0]) && (the_board.hovered_position[1] == the_board.selected_position[1])) 
-       { 
-          // forget the selected position 
-          the_board.selected_position[0] = -1; 
-          the_board.selected_position[1] = -1; 
-   
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       // else is it another part of the same color ? (i.e, user wants to change the part he selected) 
-       else if ((current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].part != PART_NONE) 
-                && (current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].color == Board_ColorToMove (&the_board))) 
-       { 
-          // mark the selected position as selected (and remember it) 
-          the_board.selected_position[0] = the_board.hovered_position[0]; 
-          the_board.selected_position[1] = the_board.hovered_position[1]; 
-   
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       // else is it a possible move ? 
-       else if ((current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].flags & FLAG_POSSIBLEMOVE) 
-                || (current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].flags & FLAG_TAKEABLE)) 
-       { 
-          // are we in check after the move ? (FIXME: call EP version of this func for en passant moves) 
-          if (Move_IsColorInCheckAfterTestMove (current_move, the_board.selected_position[0], the_board.selected_position[1], the_board.hovered_position[0], the_board.hovered_position[1], Board_ColorToMove (&the_board))) 
-          { 
-             Audio_PlaySound (SOUNDTYPE_ILLEGALMOVE); // play the "illegal move" sound 
-   
-             the_scene.update = true; // update the 3D scene 
-   
-             // call the default window message processing function to keep things going 
-             return (DefWindowProc (hWnd, message, wParam, lParam)); 
-          } 
-   
-          //////////////////// 
-          // movement is valid 
-   
-          // do it 
-          Board_AppendMove (&the_board, the_board.selected_position[0], the_board.selected_position[1], the_board.hovered_position[0], the_board.hovered_position[1], PART_NONE, NULL); 
-          current_move = &the_board.moves[the_board.move_count - 1]; // update current move pointer 
-   
-          // are we in internet mode ? 
-          if (remote_player != NULL) 
-             the_board.reevaluate = false; // if so, don't reevaluate the board yet, let the server do it 
-   
-          // was it a pawn being promoted ? if so, display the dialog box and wait for the reply 
-          if ((current_move->slots[the_board.hovered_position[0]][the_board.hovered_position[1]].part == PART_PAWN) 
-              && ((the_board.hovered_position[0] == 0) || (the_board.hovered_position[0] == 7))) 
-             DialogBox_PawnPromotion (); // display the pawn promotion dialog box 
-   
-          // else it was a normal move 
-          else 
-          { 
-             Board_SetSelectedAndHovered (&the_board, -1, -1, -1, -1); // forget the hovered and selected positions 
-             the_board.has_playerchanged = true; // and switch players 
-          } 
-   
-          the_scene.update = true; // update the 3D scene 
-          animation_endtime = current_time + ANIMATION_DURATION; // play animation now 
-          sound_playtime = current_time + ANIMATION_DURATION - 0.1f; // play sound near the end of animation 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-   
-       // else it's another location 
-   
-       Audio_PlaySound (SOUNDTYPE_ILLEGALMOVE); // play the "illegal move" sound 
-   
-       the_scene.update = true; // update the 3D scene 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // right mouse button push 
-    else if (message == WM_RBUTTONDOWN) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       prevgui_x = GET_X_LPARAM (lParam); // remember mouse coordinates 
-       prevgui_y = GET_Y_LPARAM (lParam); 
-   
-       // if we click something, stop moving the table immediately 
-   
-       // cycle through both players and change their view angles EXCEPT the opponent if he's human 
-       for (viewer_index = 0; viewer_index < 2; viewer_index++) 
-          if ((the_board.players[viewer_index].type == PLAYER_COMPUTER) 
-                || (the_board.players[viewer_index].type == PLAYER_INTERNET) 
-                || (viewer_index == current_viewer)) 
-          { 
-             the_board.players[viewer_index].view_pitch = current_pitch; 
-             the_board.players[viewer_index].view_yaw = current_yaw; 
-          } 
-   
-       rbutton_pushed = true; // remember button is clicked 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // right mouse button release 
-    else if (message == WM_RBUTTONUP) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       rbutton_pushed = false; // remember button is released 
-       the_scene.update = true; // update the 3D scene 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // left mouse button DOUBLE-click 
-    else if (message == WM_LBUTTONDBLCLK) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       // get mouse coordinates 
-       gui_x = GET_X_LPARAM (lParam); 
-       gui_y = GET_Y_LPARAM (lParam); 
-   
-       // are we in game and did we click the move comments area ? 
-       if ((the_board.game_state >= STATE_PLAYING) && (the_board.viewed_move > 0) && Render_IsMouseInBox (gui_x, gui_y, 10.0f, 0.0f, 80.0f, 10.0f)) 
-       { 
-          DialogBox_Comment (); // fire up the comment dialog box 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // call the default window message processing function to keep things going 
-       } 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // mouse move (while not in animation) 
-    else if (message == WM_MOUSEMOVE) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       // get mouse coordinates 
-       gui_x = GET_X_LPARAM (lParam); 
-       gui_y = GET_Y_LPARAM (lParam); 
-   
-       // handle button update status 
-       the_scene.update |= Button_UpdateHoverState (&the_scene.gui.larrow, gui_x, gui_y); 
-       the_scene.update |= Button_UpdateHoverState (&the_scene.gui.rarrow, gui_x, gui_y); 
-       the_scene.update |= Button_UpdateHoverState (&the_scene.gui.chatbutton, gui_x, gui_y); 
-       the_scene.update |= Button_UpdateHoverState (&the_scene.gui.gamesbutton, gui_x, gui_y); 
-       the_scene.update |= Button_UpdateHoverState (&the_scene.gui.peoplebutton, gui_x, gui_y); 
-   
-       // see if we're online 
-       remote_player = Player_FindByType (PLAYER_INTERNET); 
-   
-       // are we online AND do we NOT have the right to select anything ? 
-       if ((remote_player != NULL) && !remote_player->is_in_game) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default window message processing function to keep things going 
-   
-       // is the parts selection line displayed AND is the mouse anywhere in it ? 
-       if (the_scene.gui.is_partspick_displayed && Render_IsMouseInBox (gui_x, gui_y, 0.0f, 0.0f, 100.0f, 11.0f)) 
-       { 
-          // for each selectable part... 
-          for (part_index = 0; part_index < 13; part_index++) 
-          { 
-             // is the mouse hovering it ? 
-             if (Render_IsMouseInBox (gui_x, gui_y, part_index * (100.0f / 13.0f), 0, 100.0f / 13.0f, 11.0f)) 
-             { 
-                // was it NOT hovered before ? 
-                if (the_scene.gui.partspick_hoveredpart != selectable_parts[part_index]) 
-                { 
-                   the_scene.gui.partspick_hoveredpart = selectable_parts[part_index]; // mark it as hovered 
-                   the_scene.update = true; // update the scene 
-                } 
-             } 
-   
-             // else was it hovered before ? 
-             else if (the_scene.gui.partspick_hoveredpart == selectable_parts[part_index]) 
-             { 
-                the_scene.gui.partspick_hoveredpart = 0; // clear the hovered part 
-                the_scene.update = true; // update the scene 
-             } 
-          } 
-       } 
-       else 
-          the_scene.gui.partspick_hoveredpart = 0; // clear the hovered part 
-   
-       // get current and opposite players 
-       current_player = Player_GetCurrent (); 
-       opposite_player = Player_GetOpposite (); 
-   
-       // if right button was clicked, compute new pitch and yaw 
-       if (rbutton_pushed) 
-       { 
-          // cycle through both players and change their view angles EXCEPT the opponent if he's human 
-          for (viewer_index = 0; viewer_index < 2; viewer_index++) 
-             if ((the_board.players[viewer_index].type == PLAYER_COMPUTER) 
-                 || (the_board.players[viewer_index].type == PLAYER_INTERNET) 
-                 || (viewer_index == current_viewer)) 
-             { 
-                the_board.players[viewer_index].view_pitch += (gui_y - prevgui_y) * 0.3f; 
-                if (the_board.players[viewer_index].view_pitch < 10.0f) 
-                   the_board.players[viewer_index].view_pitch = 10.0f; // wrap angles around so that they 
-                if (the_board.players[viewer_index].view_pitch > 89.99f) 
-                   the_board.players[viewer_index].view_pitch = 89.99f; // stay in the [10, 89.99] bounds 
-   
-                the_board.players[viewer_index].view_yaw += (gui_x - prevgui_x) * 0.3f; 
-                the_board.players[viewer_index].view_yaw = WrapAngle (the_board.players[viewer_index].view_yaw); 
-   
-                // save these as the new custom angles 
-                the_board.players[viewer_index].custom_pitch = the_board.players[viewer_index].view_pitch; 
-                the_board.players[viewer_index].custom_yaw = the_board.players[viewer_index].view_yaw; 
-   
-                // when moving the table around, jump to ideal angles immediately 
-                current_pitch = the_board.players[viewer_index].view_pitch; 
-                current_yaw = the_board.players[viewer_index].view_yaw; 
-             } 
-   
-          the_scene.update = true; // button was clicked, update the 3D scene 
-       } 
-   
-       // else it's just the mouse wandering around ; have we the right to select something ? 
-       else if ((the_board.viewed_move == the_board.move_count - 1) && (current_player->type == PLAYER_HUMAN) && (highlight_endtime < current_time)) 
-       { 
-          // save the old positions 
-          prev_hovered_position[0] = the_board.hovered_position[0]; 
-          prev_hovered_position[1] = the_board.hovered_position[1]; 
-   
-          // figure out the coordinates on table 
-          Render_MouseToFloor (gui_x, gui_y, &board_x, &board_y); 
-   
-          // translate them to board coordinates 
-          the_board.hovered_position[0] = (int) floor ((20.0f - board_y) / 5.0f); 
-          the_board.hovered_position[1] = 7 - (int) floor ((20.0f - board_x) / 5.0f); 
-   
-          // do they differ from last time ? 
-          if ((the_board.hovered_position[0] != prev_hovered_position[0]) || (the_board.hovered_position[1] != prev_hovered_position[1])) 
-             the_scene.update = true; // if so, update scene 
-       } 
-   
-       // has the user the right to leave a command AND is there no comment yet ? 
-       if ((the_board.game_state >= STATE_PLAYING) && (the_board.viewed_move > 0) 
-           && ((the_board.moves[the_board.viewed_move].comment == NULL) || (the_board.moves[the_board.viewed_move].comment[0] == 0))) 
-       { 
-          // is the mouse above the comments zone ? if so, display a dimmed hint text 
-          if (Render_IsMouseInBox (gui_x, gui_y, 30.0f, 0.0f, 40.0f, 10.0f)) 
-          { 
-             if (!the_scene.gui.comment_text.is_displayed) 
-             { 
-                Scene_SetText (&the_scene.gui.comment_text, 50.0f, 5.0f, 40.0f, ALIGN_CENTER, ALIGN_CENTER, ALIGN_LEFT, chat_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 127), 999999.0f, false, LOCALIZE (L"DoubleClickToEnterComment")); 
-                the_scene.update = true; // and update the scene 
-             } 
-          } 
-          else 
-          { 
-             if (the_scene.gui.comment_text.is_displayed) 
-             { 
-                the_scene.gui.comment_text.is_displayed = false; // if not, erase the hint text 
-                the_scene.update = true; // and update the scene 
-             } 
-          } 
-       } 
-   
-       // remember these coordinates for next time 
-       prevgui_x = gui_x; 
-       prevgui_y = gui_y; 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // mouse scroll 
-    else if (message == WM_MOUSEWHEEL) 
-    { 
-       // are we in animation OR are mouse commands NOT allowed ? 
-       if ((animation_endtime + 1.0f >= current_time) || (command_ignoretime >= current_time)) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default message proc to keep things going 
-   
-       // see if we're online 
-       remote_player = Player_FindByType (PLAYER_INTERNET); 
-   
-       // are we online AND do we NOT have the right to select anything ? 
-       if ((remote_player != NULL) && !remote_player->is_in_game) 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); // if so, call the default window message processing function to keep things going 
-   
-       // scroll up / scroll down ? 
-       if (GET_WHEEL_DELTA_WPARAM (wParam) > 0) 
-          the_board.players[current_viewer].view_distance = max (48.0f, the_board.players[current_viewer].view_distance - 2.0f); 
-       else if (GET_WHEEL_DELTA_WPARAM (wParam) < 0) 
-          the_board.players[current_viewer].view_distance = min (100.0f, the_board.players[current_viewer].view_distance + 2.0f); 
-   
-       // save this as the new custom distance 
-       the_board.players[current_viewer].custom_distance = the_board.players[current_viewer].view_distance; 
-   
-       // when moving the table around, jump to ideal angles immediately 
-       current_distance = the_board.players[current_viewer].view_distance; 
-   
-       the_scene.update = true; // update the 3D scene 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // keyboard release 
-    else if (message == WM_CHAR) 
-    { 
-       // are we in position setup mode ? 
-       if (the_board.game_state == STATE_SETUPPOSITION) 
-       { 
-          // is it the enter key ? if so, exit setup mode and start playing 
-          if (wParam == L'\r') 
-          { 
-             current_move = &the_board.moves[the_board.viewed_move]; // quick access to current move 
-   
-             // (in)validate the castling positions 
-             if ((current_move->slots[0][0].color == COLOR_WHITE) && (current_move->slots[0][0].part == PART_ROOK) 
-                 && (current_move->slots[0][4].color == COLOR_WHITE) && (current_move->slots[0][4].part == PART_KING)) 
-                current_move->sides[COLOR_WHITE].longcastle_allowed = true; // white castling queenside allowed 
-             else 
-                current_move->sides[COLOR_WHITE].longcastle_allowed = false; // white castling queenside no longer possible 
-             if ((current_move->slots[0][7].color == COLOR_WHITE) && (current_move->slots[0][7].part == PART_ROOK) 
-                 && (current_move->slots[0][4].color == COLOR_WHITE) && (current_move->slots[0][4].part == PART_KING)) 
-                current_move->sides[COLOR_WHITE].shortcastle_allowed = true; // white castling kingside allowed 
-             else 
-                current_move->sides[COLOR_WHITE].shortcastle_allowed = false; // white castling kingside no longer possible 
-             if ((current_move->slots[7][0].color == COLOR_BLACK) && (current_move->slots[7][0].part == PART_ROOK) 
-                 && (current_move->slots[7][4].color == COLOR_BLACK) && (current_move->slots[7][4].part == PART_KING)) 
-                current_move->sides[COLOR_BLACK].longcastle_allowed = true; // white castling queenside allowed 
-             else 
-                current_move->sides[COLOR_BLACK].longcastle_allowed = false; // white castling queenside no longer possible 
-             if ((current_move->slots[7][7].color == COLOR_BLACK) && (current_move->slots[7][7].part == PART_ROOK) 
-                 && (current_move->slots[7][4].color == COLOR_BLACK) && (current_move->slots[7][4].part == PART_KING)) 
-                current_move->sides[COLOR_BLACK].shortcastle_allowed = true; // white castling kingside allowed 
-             else 
-                current_move->sides[COLOR_BLACK].shortcastle_allowed = false; // white castling kingside no longer possible 
-   
-             current_move->color = COLOR_BLACK; // so that game starts with white 
-   
-             // validate this board in Forsyth-Edwards Notation and reset it 
-             Move_DescribeInFEN (current_move); 
-             wcscpy_s (fen_string, WCHAR_SIZEOF (fen_string), current_move->fen_string); // have a copy of fen string 
-             Board_Reset (&the_board, fen_string); 
-   
-             the_board.game_state = STATE_PLAYING; // start the game now 
-             the_board.reevaluate = true; // evaluate board again 
-   
-             the_scene.gui.central_text.disappear_time = current_time + 1.0f; // fade out help text now (FIXME: ugly) 
-             the_scene.update = true; // update the 3D scene 
-   
-             // call the default window message processing function to keep things going 
-             return (DefWindowProc (hWnd, message, wParam, lParam)); 
-          } 
-       } 
-   
-       // else are we in internet mode ? 
-       else if (Player_FindByType (PLAYER_INTERNET) != NULL) 
-       { 
-          entered_ccreply = &the_scene.gui.entered_ccreply; // quick access to entered ccreply 
-          local_player = Player_FindByType (PLAYER_HUMAN); // quick access to local player 
-          if (local_player == NULL) 
-             return (DefWindowProc (hWnd, message, wParam, lParam)); // theoretically impossible condition, but better be sure 
-          if (selected_chatterchannel == NULL) 
-             return (DefWindowProc (hWnd, message, wParam, lParam)); // theoretically impossible condition, but better be sure 
-   
-          // are we NOT entering text yet ? 
-          if (!the_scene.gui.is_entering_text) 
-          { 
-             // is it the space bar ? 
-             if (wParam == L' ') 
-             { 
-                the_scene.gui.is_entering_text = true; // remember we are entering text 
-   
-                // reset the entered text buffer 
-                entered_ccreply->text = (wchar_t *) SAFE_malloc (1, sizeof (wchar_t), false); 
-                entered_ccreply->text[0] = 0; // only the null terminator will fit 
-                entered_ccreply->text_length = 0; // and set its length to zero 
-             } 
-          } 
-   
-          // else we are currently in text entering mode 
-          else 
-          { 
-             // is the typed character a printable character ? 
-             if (iswprint (wParam)) 
-             { 
-                // if so, reallocate space in the typed buffer (include null terminator) 
-                entered_ccreply->text = (wchar_t *) SAFE_realloc (entered_ccreply->text, entered_ccreply->text_length + 1, entered_ccreply->text_length + 1 + 1, sizeof (wchar_t), false); 
-                swprintf_s (&entered_ccreply->text[entered_ccreply->text_length], 1 + 1, L"%c", wParam); // append character 
-                entered_ccreply->text_length++; // buffer holds now one character more 
-             } 
-   
-             // else is the typed character a backspace AND is there text to erase ? 
-             else if ((wParam == 0x08) && (entered_ccreply->text_length > 0)) 
-             { 
-                // if so, reallocate space in the typed buffer (include null terminator) 
-                entered_ccreply->text = (wchar_t *) SAFE_realloc (entered_ccreply->text, entered_ccreply->text_length + 1, entered_ccreply->text_length + 1 - 1, sizeof (wchar_t), false); 
-                entered_ccreply->text[entered_ccreply->text_length - 1] = 0; // backspace, delete one character 
-                entered_ccreply->text_length--; // buffer holds now one character less 
-             } 
-   
-             // else is the typed character the escape key ? 
-             else if (wParam == 0x1b) 
-             { 
-                SAFE_free ((void **) &entered_ccreply->text); // reset the entered text buffer 
-                entered_ccreply->text_length = 0; // and set its length to zero 
-                the_scene.gui.is_entering_text = false; // and exit from the text entering mode 
-             } 
-   
-             // else is the typed character the enter key ? 
-             else if (wParam == 0x0d) 
-                the_scene.gui.is_entering_text = false; // enter, exit from the text entering mode (this will validate our reply) 
-   
-             // else it's an illegal character 
-             else 
-                Audio_PlaySound (SOUNDTYPE_ILLEGALMOVE); // illegal character, beep the illegal move sound 
-          } 
-   
-          the_scene.update = true; // update the 3D scene 
-   
-          // call the default window message processing function to keep things going 
-          return (DefWindowProc (hWnd, message, wParam, lParam)); 
-       } 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // mouse move outside the window 
-    else if (message == WM_NCMOUSEMOVE) 
-    { 
-       rbutton_pushed = false; // remember right button is released 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    //////////////////////////////////////////////////////////////////////////////////////////////// 
-    // window repaint 
-    else if (message == WM_PAINT) 
-    { 
-       the_scene.update = true; // update the 3D scene 
-   
-       // call the default window message processing function to keep things going 
-       return (DefWindowProc (hWnd, message, wParam, lParam)); 
-    } 
-   
-    // call the default window message processing function to keep things going 
-    return (DefWindowProc (hWnd, message, wParam, lParam)); 
- } 
-   
-   
- static bool Button_IsHovered (guibutton_t *button, int gui_x, int gui_y) 
- { 
-    // handy wrapper that returns whether a particular GUI button is hovered when the mouse is at the given coordinates 
-   
-    return (Render_IsMouseInBox (gui_x, gui_y, button->left, button->top, button->width, button->height)); 
- } 
-   
-   
- static bool Button_UpdateHoverState (guibutton_t *button, int gui_x, int gui_y) 
- { 
-    // this function updates the hover state of a GUI button, and returns TRUE if the 
-    // scene needs to be updated, FALSE otherwise. 
-   
-    // is the button displayed ? 
-    if (button->state != 0) 
-    { 
-       // is the mouse hovering it ? 
-       if (Render_IsMouseInBox (gui_x, gui_y, button->left, button->top, button->width, button->height)) 
-       { 
-          // was it NOT hovered before ? 
-          if (button->state != 2) 
-          { 
-             button->state = 2; // mark it as hovered 
-             return (true); // return TRUE so as to update the scene 
-          } 
-       } 
-   
-       // else was it hovered before ? 
-       else if (button->state == 2) 
-       { 
-          button->state = 1; // else mark it as not hovered 
-          return (true); // return TRUE so as to update the scene 
-       } 
-    } 
-   
-    return (false); // no need to update the scene 
- } 
-