Rev 130 | Rev 136 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 1 | pmbaty | 1 | // scene.cpp | 
        
| 2 | |||
| 3 | #include "common.h" | 
        ||
| 4 | |||
| 5 | |||
| 6 | // prototypes of local functions | 
        ||
| 7 | static void Scene_AddPart (scene_t *scene, int part_type, int part_color, float pos_x, float pos_y, float pos_z, float turn_yaw, float pitch);  | 
        ||
| 8 | static void Scene_AddTile (scene_t *scene, int tile_type, float scale, float pos_x, float pos_y, float pos_z, float turn_yaw);  | 
        ||
| 9 | |||
| 10 | |||
| 11 | // global variables used in this module only | 
        ||
| 12 | static wchar_t connected_comment[4096];  | 
        ||
| 13 | static wchar_t filename[MAX_PATH];  | 
        ||
| 14 | static float simpleshadow_sizes[] =  | 
        ||
| 15 | { | 
        ||
| 16 | 0, // #define PART_NONE 0  | 
        ||
| 17 | 2.5f, // #define PART_KING 1  | 
        ||
| 18 | 2.45f, // #define PART_QUEEN 2  | 
        ||
| 19 | 2.35f, // #define PART_BISHOP 3  | 
        ||
| 20 | 2.25f, // #define PART_KNIGHT 4  | 
        ||
| 21 | 2.15f, // #define PART_ROOK 5  | 
        ||
| 22 | 2.0f, // #define PART_PAWN 6  | 
        ||
| 23 | };  | 
        ||
| 130 | pmbaty | 24 | static bool has_endsound_played = false;  | 
        
| 1 | pmbaty | 25 | |
| 26 | |||
| 27 | void Scene_Init (scene_t *scene, board_t *board)  | 
        ||
| 28 | { | 
        ||
| 29 |    // this function initializes the scene objects array and inserts the chess table in it | 
        ||
| 30 | |||
| 31 | wchar_t format_string[4096];  | 
        ||
| 32 | |||
| 33 |    // allocate array for the board (3 objects) and zero it out | 
        ||
| 34 | scene->objects = (sceneobject_t *) SAFE_malloc (3, sizeof (sceneobject_t), true);  | 
        ||
| 35 | |||
| 36 |    // insert the table edges, the table and the board | 
        ||
| 37 | scene->objects[0].mesh_index = theme->trim_meshindex;  | 
        ||
| 38 | scene->objects[0].texture_index = theme->trim_texture;  | 
        ||
| 39 | scene->objects[0].scale = 1.0f;  | 
        ||
| 40 | scene->objects[1].mesh_index = theme->table_meshindex;  | 
        ||
| 41 | scene->objects[1].texture_index = theme->table_texture;  | 
        ||
| 42 | scene->objects[1].scale = 1.0f;  | 
        ||
| 43 | scene->objects[2].mesh_index = theme->board_meshindex;  | 
        ||
| 44 | scene->objects[2].texture_index = theme->board_texture;  | 
        ||
| 45 | scene->objects[2].scale = 1.0f;  | 
        ||
| 46 | scene->object_count = 3;  | 
        ||
| 47 | |||
| 48 |    // reset the camera position for a cool slide-in effect, but only if autorotate is enabled | 
        ||
| 49 | if (options.want_autorotateon1vs1)  | 
        ||
| 50 |    { | 
        ||
| 124 | pmbaty | 51 | current_pitch = CLOSEUP_VIEW_PITCH; // autorotate is enabled, prepare for slide-in effect  | 
        
| 1 | pmbaty | 52 | current_yaw = (Board_ColorToMove (board) == COLOR_WHITE ? 90.0f : -90.0f);  | 
        
| 124 | pmbaty | 53 | current_distance = CLOSEUP_VIEW_DISTANCE;  | 
        
| 54 | if (current_distance >= MIN_VIEW_DISTANCE)  | 
        ||
| 55 | current_distance = MIN_VIEW_DISTANCE - 1.0f; // consistency check for stupid programmers  | 
        ||
| 1 | pmbaty | 56 |    } | 
        
| 57 |    else | 
        ||
| 58 |    { | 
        ||
| 59 | current_pitch = 55.0f; // no autorotate, reset to standard view position directly  | 
        ||
| 60 | current_yaw = (Board_ColorToMove (board) == COLOR_BLACK ? 90.0f : -90.0f);  | 
        ||
| 61 | current_distance = 70.0f;  | 
        ||
| 124 | pmbaty | 62 | if (current_distance < MIN_VIEW_DISTANCE)  | 
        
| 63 | current_distance = MIN_VIEW_DISTANCE; // consistency check for stupid programmers  | 
        ||
| 1 | pmbaty | 64 |    } | 
        
| 65 | |||
| 131 | pmbaty | 66 |    // look at the center of the table immediately | 
        
| 67 | lookatpoint_x = 0;  | 
        ||
| 68 | lookatpoint_y = 0;  | 
        ||
| 69 | |||
| 21 | pmbaty | 70 |    // HACK to prevent the player to click and block the view angles while the slide-in is not finished | 
        
| 71 | command_ignoretime = current_time + 2.0f; // allow 2 seconds  | 
        ||
| 72 | |||
| 1 | pmbaty | 73 |    // build the connected comment string (we use it as a global variable) | 
        
| 74 | wcscpy_s (format_string, WCHAR_SIZEOF (format_string), LOCALIZE (L"YouAreConnectedToX"));  | 
        ||
| 75 | wcscat_s (format_string, WCHAR_SIZEOF (format_string), L"\n");  | 
        ||
| 76 | wcscat_s (format_string, WCHAR_SIZEOF (format_string), LOCALIZE (L"YouMayEitherDisplayThePlayersListOrTheSoughtGamesList"));  | 
        ||
| 77 | wcscat_s (format_string, WCHAR_SIZEOF (format_string), L"\n");  | 
        ||
| 78 | wcscat_s (format_string, WCHAR_SIZEOF (format_string), LOCALIZE (L"PleaseReferToTheInternetMenu"));  | 
        ||
| 79 | swprintf_s (connected_comment, WCHAR_SIZEOF (connected_comment), format_string, options.network.server_address);  | 
        ||
| 80 | |||
| 81 |    // completely reset the whole GUI structure so as to NULL out all pointers | 
        ||
| 82 | memset (&scene->gui, 0, sizeof (scene->gui));  | 
        ||
| 83 | |||
| 84 |    // set the buttons locations | 
        ||
| 124 | pmbaty | 85 | Scene_SetButton (&scene->gui.larrow, 0.3f, 0.5f, 3.0f, 4.0f, larrow_spriteindex, NULL);  | 
        
| 86 | Scene_SetButton (&scene->gui.rarrow, 3.3f, 0.5f, 3.0f, 4.0f, rarrow_spriteindex, NULL);  | 
        ||
| 87 | Scene_SetButton (&scene->gui.newgamebutton, 20.0f, 65.0f, 20.0f, 26.0f, newgamebutton_spriteindex, L"\n\n\n\n\n\n\n%s", LOCALIZE (L"NewGame"));  | 
        ||
| 88 | Scene_SetButton (&scene->gui.opengamebutton, 60.0f, 65.0f, 20.0f, 26.0f, opengamebutton_spriteindex, L"\n\n\n\n\n\n\n%s", LOCALIZE (L"OpenGame"));  | 
        ||
| 89 | Scene_SetButton (&scene->gui.chatbutton, 1.0f, 10.0f, 10.0f, 13.0f, chatbutton_spriteindex, NULL);  | 
        ||
| 90 | Scene_SetButton (&scene->gui.gamesbutton, 1.0f, 35.0f, 10.0f, 13.0f, gamesbutton_spriteindex, NULL);  | 
        ||
| 91 | Scene_SetButton (&scene->gui.peoplebutton, 1.0f, 60.0f, 10.0f, 13.0f, peoplebutton_spriteindex, NULL);  | 
        ||
| 1 | pmbaty | 92 | |
| 93 |    // remember to update the scene | 
        ||
| 94 | scene->update = true;  | 
        ||
| 95 | |||
| 96 | return; // finished  | 
        ||
| 97 | } | 
        ||
| 98 | |||
| 99 | |||
| 100 | void Scene_Shutdown (scene_t *scene)  | 
        ||
| 101 | { | 
        ||
| 102 |    // this function frees the memory space allocated for the 3D scene and clears its pointers | 
        ||
| 103 | |||
| 104 | int cchistory_index;  | 
        ||
| 105 | |||
| 106 |    // free GUI mallocated buffers | 
        ||
| 107 | SAFE_free ((void **) &scene->gui.arrow_text.buffer);  | 
        ||
| 108 | scene->gui.arrow_text.is_displayed = false;  | 
        ||
| 109 | SAFE_free ((void **) &scene->gui.comment_text.buffer);  | 
        ||
| 110 | scene->gui.comment_text.is_displayed = false;  | 
        ||
| 111 | SAFE_free ((void **) &scene->gui.history_text.buffer);  | 
        ||
| 112 | scene->gui.history_text.is_displayed = false;  | 
        ||
| 113 | SAFE_free ((void **) &scene->gui.clock_text.buffer);  | 
        ||
| 114 | scene->gui.clock_text.is_displayed = false;  | 
        ||
| 115 | SAFE_free ((void **) &scene->gui.turn_text.buffer);  | 
        ||
| 116 | scene->gui.turn_text.is_displayed = false;  | 
        ||
| 117 | SAFE_free ((void **) &scene->gui.central_text.buffer);  | 
        ||
| 118 | scene->gui.central_text.is_displayed = false;  | 
        ||
| 119 | |||
| 120 |    // for each entry in the CC history... | 
        ||
| 121 | for (cchistory_index = 0; cchistory_index < scene->gui.cchistory_count; cchistory_index++)  | 
        ||
| 122 | SAFE_free ((void **) &scene->gui.cchistory[cchistory_index].text); // free its text buffer  | 
        ||
| 123 | SAFE_free ((void **) &scene->gui.cchistory); // free the GUI's CC history  | 
        ||
| 124 | scene->gui.cchistory_count = 0;  | 
        ||
| 125 | |||
| 126 | SAFE_free ((void **) &scene->objects); // free the scene objects array  | 
        ||
| 127 | scene->object_count = 0;  | 
        ||
| 128 | |||
| 129 | return; // finished  | 
        ||
| 130 | } | 
        ||
| 131 | |||
| 132 | |||
| 133 | void Scene_Update (scene_t *scene, board_t *board)  | 
        ||
| 134 | { | 
        ||
| 135 |    // this function updates the scene objects to display with what's currently on the board | 
        ||
| 136 | |||
| 137 | static bool rooksound_played = false; // hack to have two sounds when a king castles  | 
        ||
| 138 | |||
| 139 | boardslot_t *boardslot;  | 
        ||
| 140 | boardmove_t *currentmove;  | 
        ||
| 141 | player_t *local_player;  | 
        ||
| 142 | player_t *network_player;  | 
        ||
| 143 | player_t *current_player;  | 
        ||
| 24 | pmbaty | 144 | player_t *opposite_player;  | 
        
| 1 | pmbaty | 145 | wchar_t *history_text; // mallocated  | 
        
| 146 | int historytext_size;  | 
        ||
| 147 | unsigned char takenpart_type;  | 
        ||
| 148 | int movement_direction;  | 
        ||
| 149 | int line;  | 
        ||
| 150 | int column;  | 
        ||
| 151 | int pos_index;  | 
        ||
| 152 | int part_index;  | 
        ||
| 153 | int move_index;  | 
        ||
| 154 | int start_index;  | 
        ||
| 155 | int length;  | 
        ||
| 156 | int threat_line;  | 
        ||
| 157 | int threat_column;  | 
        ||
| 158 | int minutes;  | 
        ||
| 159 | int seconds;  | 
        ||
| 130 | pmbaty | 160 | bool is_sliding;  | 
        
| 25 | pmbaty | 161 | float flaticons_yaw;  | 
        
| 1 | pmbaty | 162 | float source_x;  | 
        
| 163 | float source_y;  | 
        ||
| 164 | float target_x;  | 
        ||
| 165 | float target_y;  | 
        ||
| 166 | float current_x;  | 
        ||
| 167 | float current_y;  | 
        ||
| 168 | float current_z;  | 
        ||
| 130 | pmbaty | 169 | float current_p;  | 
        
| 1 | pmbaty | 170 | int movement_diffco;  | 
        
| 171 | int movement_diffli;  | 
        ||
| 172 | float movement_maxheight;  | 
        ||
| 173 | float movement_ratio;  | 
        ||
| 174 | |||
| 24 | pmbaty | 175 |    // get the current player (we'll need it), its opponent and see if we're online | 
        
| 1 | pmbaty | 176 | current_player = Player_GetCurrent ();  | 
        
| 24 | pmbaty | 177 | opposite_player = Player_GetOpposite ();  | 
        
| 1 | pmbaty | 178 | network_player = Player_FindByType (PLAYER_INTERNET);  | 
        
| 179 | |||
| 25 | pmbaty | 180 |    // determine display yaw (for flat icons) according to camera angle | 
        
| 181 | if ((current_yaw > 45.0f) && (current_yaw <= 135.0f))  | 
        ||
| 182 | flaticons_yaw = 180.0f;  | 
        ||
| 183 | else if ((current_yaw > -45.0f) && (current_yaw <= 45.0f))  | 
        ||
| 184 | flaticons_yaw = 90.0f;  | 
        ||
| 185 | else if ((current_yaw > -135.0f) && (current_yaw <= -45.0f))  | 
        ||
| 186 | flaticons_yaw = 0.0f;  | 
        ||
| 187 |    else | 
        ||
| 188 | flaticons_yaw = -90.0f;  | 
        ||
| 189 | |||
| 24 | pmbaty | 190 |    // get the current move | 
        
| 191 | currentmove = &board->moves[board->viewed_move]; // quick access to current move  | 
        ||
| 192 | |||
| 1 | pmbaty | 193 |    // fetch the background sprite from the theme | 
        
| 194 | if (want_custombackground)  | 
        ||
| 195 | scene->background_spriteindex = custombg.sprite_index; // use the custom background if specified  | 
        ||
| 196 |    else | 
        ||
| 197 | scene->background_spriteindex = theme->bg.sprite_index; // else use the theme's supplied background  | 
        ||
| 198 | |||
| 199 |    // shrink the scene objects array to leave just the board (3 objects) | 
        ||
| 200 | scene->objects = (sceneobject_t *) SAFE_realloc (scene->objects, scene->object_count, 3, sizeof (sceneobject_t), false);  | 
        ||
| 201 | scene->object_count = 3;  | 
        ||
| 202 | |||
| 203 |    // update the board theme | 
        ||
| 204 | scene->objects[0].mesh_index = theme->trim_meshindex;  | 
        ||
| 205 | scene->objects[0].texture_index = theme->trim_texture;  | 
        ||
| 206 | scene->objects[0].material_index = theme->trim_material;  | 
        ||
| 207 | scene->objects[0].scale = 1.0f;  | 
        ||
| 208 | scene->objects[1].mesh_index = theme->table_meshindex;  | 
        ||
| 209 | scene->objects[1].texture_index = theme->table_texture;  | 
        ||
| 210 | scene->objects[1].material_index = theme->table_material;  | 
        ||
| 211 | scene->objects[1].scale = 1.0f;  | 
        ||
| 212 | scene->objects[2].mesh_index = theme->board_meshindex;  | 
        ||
| 213 | scene->objects[2].texture_index = theme->board_texture;  | 
        ||
| 214 | scene->objects[2].material_index = theme->board_material;  | 
        ||
| 215 | scene->objects[2].scale = 1.0f;  | 
        ||
| 216 | |||
| 217 |    // draw the grid numbers if we want them | 
        ||
| 218 | if (want_grid)  | 
        ||
| 219 | Scene_AddTile (scene, theme->grid_texture, 30.0f, 0.0f, 0.0f, 0.01f, 0.0f);  | 
        ||
| 220 | |||
| 221 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 24 | pmbaty | 222 |    // recompute the slot textures (only in play mode when we render the real board) | 
        
| 1 | pmbaty | 223 | |
| 224 |    // erase all the slot flags | 
        ||
| 225 | for (line = 0; line < 8; line++)  | 
        ||
| 226 | for (column = 0; column < 8; column++)  | 
        ||
| 227 | currentmove->slots[line][column].flags = FLAG_NONE; // because we will recompute them  | 
        ||
| 228 | |||
| 229 |    // cycle through all the grid again and see if either king is in check | 
        ||
| 230 | for (line = 0; line < 8; line++)  | 
        ||
| 231 | for (column = 0; column < 8; column++)  | 
        ||
| 232 |       { | 
        ||
| 233 | boardslot = ¤tmove->slots[line][column]; // quick access to grid slot  | 
        ||
| 234 | |||
| 235 | if (boardslot->part != PART_KING)  | 
        ||
| 236 | continue; // if this slot is not a king, skip it  | 
        ||
| 237 | |||
| 238 |          // is this king currently threatened ? | 
        ||
| 239 | if (Move_IsKingThreatenedAtLocation (currentmove, boardslot->color, line, column, &threat_line, &threat_column))  | 
        ||
| 240 |          { | 
        ||
| 241 | currentmove->slots[line][column].flags |= FLAG_CHECK; // mark it as threatened  | 
        ||
| 242 | currentmove->slots[threat_line][threat_column].flags |= FLAG_THREAT; // and who threatens it  | 
        ||
| 243 |          } | 
        ||
| 244 |       } | 
        ||
| 245 | |||
| 246 |    // are we in play mode ? i.e, are we rendering the last move ? | 
        ||
| 247 | if (board->viewed_move == board->move_count - 1)  | 
        ||
| 248 |    { | 
        ||
| 249 |       // mark the selected position as selected | 
        ||
| 250 | if (IS_VALID_POSITION (board->selected_position))  | 
        ||
| 251 | currentmove->slots[board->selected_position[0]][board->selected_position[1]].flags |= FLAG_SELECTED;  | 
        ||
| 252 | |||
| 253 |       // now cycle through all the grid again and see if some slots need to be coloured | 
        ||
| 254 | for (line = 0; line < 8; line++)  | 
        ||
| 255 | for (column = 0; column < 8; column++)  | 
        ||
| 256 |          { | 
        ||
| 257 | boardslot = ¤tmove->slots[line][column]; // quick access to grid slot  | 
        ||
| 258 | |||
| 259 | if (!(boardslot->flags & FLAG_SELECTED))  | 
        ||
| 260 | continue; // if this slot is not selected, skip it  | 
        ||
| 261 | |||
| 262 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 263 |             ////////////////////////////////////////// PAWN ////////////////////////////////////////// | 
        ||
| 264 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 265 |             // is it a pawn ? | 
        ||
| 266 | if (boardslot->part == PART_PAWN)  | 
        ||
| 267 |             { | 
        ||
| 268 |                // figure out movement direction | 
        ||
| 269 | if (boardslot->color == COLOR_WHITE)  | 
        ||
| 270 | movement_direction = 1;  | 
        ||
| 271 |                else | 
        ||
| 272 | movement_direction = -1;  | 
        ||
| 273 | |||
| 274 |                // if pawn has still room to move forward, it can | 
        ||
| 275 | if ((((line < 7) && (movement_direction == 1)) || ((line > 0) && (movement_direction == -1)))  | 
        ||
| 276 | && (currentmove->slots[line + movement_direction][column].part == PART_NONE))  | 
        ||
| 277 |                { | 
        ||
| 278 | currentmove->slots[line + movement_direction][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 279 | |||
| 280 |                   // if pawn is still in its initial slot, it can move twice forward | 
        ||
| 281 | if ((((line == 1) && (movement_direction == 1)) || ((line == 6) && (movement_direction == -1)))  | 
        ||
| 282 | && (currentmove->slots[line + movement_direction * 2][column].part == PART_NONE))  | 
        ||
| 283 | currentmove->slots[line + movement_direction * 2][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 284 |                } | 
        ||
| 285 | |||
| 286 |                // see if pawn can take a piece on its left | 
        ||
| 287 | if ((column > 0) && (currentmove->slots[line + movement_direction][column - 1].part != PART_NONE)  | 
        ||
| 288 | && (currentmove->slots[line + movement_direction][column - 1].color != currentmove->slots[line][column].color))  | 
        ||
| 289 | currentmove->slots[line + movement_direction][column - 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 290 | |||
| 291 |                // see if pawn can take a piece on its right | 
        ||
| 292 | if ((column < 7) && (currentmove->slots[line + movement_direction][column + 1].part != PART_NONE)  | 
        ||
| 293 | && (currentmove->slots[line + movement_direction][column + 1].color != currentmove->slots[line][column].color))  | 
        ||
| 294 | currentmove->slots[line + movement_direction][column + 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 295 | |||
| 296 |                // if previous move was a pawn rush, see if pawn can take "en passant" | 
        ||
| 297 | if ((currentmove->part == PART_PAWN)  | 
        ||
| 298 | && (currentmove->target[1] == currentmove->source[1]) // pawn moved in column  | 
        ||
| 299 | && (abs (currentmove->target[0] - currentmove->source[0]) == 2) // pawn rushed  | 
        ||
| 300 | && (currentmove->target[0] == line) // pawn is in line with us  | 
        ||
| 301 | && (abs (currentmove->target[1] - column) == 1)) // pawn is next to us  | 
        ||
| 302 | currentmove->slots[line + movement_direction][currentmove->target[1]].flags |= FLAG_TAKEABLE;  | 
        ||
| 303 |             } | 
        ||
| 304 | |||
| 305 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 306 |             ////////////////////////////////////////// ROOK ////////////////////////////////////////// | 
        ||
| 307 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 308 |             // else is it a rook ? | 
        ||
| 309 | else if (boardslot->part == PART_ROOK)  | 
        ||
| 310 |             { | 
        ||
| 311 |                // see how far rook can move upwards | 
        ||
| 312 | for (pos_index = line + 1; pos_index < 8; pos_index++)  | 
        ||
| 313 |                { | 
        ||
| 314 | if (currentmove->slots[pos_index][column].part != PART_NONE)  | 
        ||
| 315 |                   { | 
        ||
| 316 | if (currentmove->slots[pos_index][column].color != currentmove->slots[line][column].color)  | 
        ||
| 317 | currentmove->slots[pos_index][column].flags |= FLAG_TAKEABLE;  | 
        ||
| 318 | break;  | 
        ||
| 319 |                   } | 
        ||
| 320 | currentmove->slots[pos_index][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 321 |                } | 
        ||
| 322 | |||
| 323 |                // see how far rook can move downwards | 
        ||
| 324 | for (pos_index = line - 1; pos_index >= 0; pos_index--)  | 
        ||
| 325 |                { | 
        ||
| 326 | if (currentmove->slots[pos_index][column].part != PART_NONE)  | 
        ||
| 327 |                   { | 
        ||
| 328 | if (currentmove->slots[pos_index][column].color != currentmove->slots[line][column].color)  | 
        ||
| 329 | currentmove->slots[pos_index][column].flags |= FLAG_TAKEABLE;  | 
        ||
| 330 | break;  | 
        ||
| 331 |                   } | 
        ||
| 332 | currentmove->slots[pos_index][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 333 |                } | 
        ||
| 334 | |||
| 335 |                // see how far rook can move left | 
        ||
| 336 | for (pos_index = column - 1; pos_index >= 0; pos_index--)  | 
        ||
| 337 |                { | 
        ||
| 338 | if (currentmove->slots[line][pos_index].part != PART_NONE)  | 
        ||
| 339 |                   { | 
        ||
| 340 | if (currentmove->slots[line][pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 341 | currentmove->slots[line][pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 342 | break;  | 
        ||
| 343 |                   } | 
        ||
| 344 | currentmove->slots[line][pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 345 |                } | 
        ||
| 346 | |||
| 347 |                // see how far rook can move right | 
        ||
| 348 | for (pos_index = column + 1; pos_index < 8; pos_index++)  | 
        ||
| 349 |                { | 
        ||
| 350 | if (currentmove->slots[line][pos_index].part != PART_NONE)  | 
        ||
| 351 |                   { | 
        ||
| 352 | if (currentmove->slots[line][pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 353 | currentmove->slots[line][pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 354 | break;  | 
        ||
| 355 |                   } | 
        ||
| 356 | currentmove->slots[line][pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 357 |                } | 
        ||
| 358 |             } | 
        ||
| 359 | |||
| 360 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 361 |             ///////////////////////////////////////// KNIGHT ///////////////////////////////////////// | 
        ||
| 362 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 363 |             // else is it a knight ? | 
        ||
| 364 | else if (boardslot->part == PART_KNIGHT)  | 
        ||
| 365 |             { | 
        ||
| 366 |                // peek knight's NNW move | 
        ||
| 367 | if ((column > 0) && (line < 6))  | 
        ||
| 368 | if (currentmove->slots[line + 2][column - 1].part == PART_NONE)  | 
        ||
| 369 | currentmove->slots[line + 2][column - 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 370 | else if (currentmove->slots[line + 2][column - 1].color != currentmove->slots[line][column].color)  | 
        ||
| 371 | currentmove->slots[line + 2][column - 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 372 | |||
| 373 |                // peek knight's NNE move | 
        ||
| 374 | if ((column < 7) && (line < 6))  | 
        ||
| 375 | if (currentmove->slots[line + 2][column + 1].part == PART_NONE)  | 
        ||
| 376 | currentmove->slots[line + 2][column + 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 377 | else if (currentmove->slots[line + 2][column + 1].color != currentmove->slots[line][column].color)  | 
        ||
| 378 | currentmove->slots[line + 2][column + 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 379 | |||
| 380 |                // peek knight's ENE move | 
        ||
| 381 | if ((column < 6) && (line < 7))  | 
        ||
| 382 | if (currentmove->slots[line + 1][column + 2].part == PART_NONE)  | 
        ||
| 383 | currentmove->slots[line + 1][column + 2].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 384 | else if (currentmove->slots[line + 1][column + 2].color != currentmove->slots[line][column].color)  | 
        ||
| 385 | currentmove->slots[line + 1][column + 2].flags |= FLAG_TAKEABLE;  | 
        ||
| 386 | |||
| 387 |                // peek knight's ESE move | 
        ||
| 388 | if ((column < 6) && (line > 0))  | 
        ||
| 389 | if (currentmove->slots[line - 1][column + 2].part == PART_NONE)  | 
        ||
| 390 | currentmove->slots[line - 1][column + 2].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 391 | else if (currentmove->slots[line - 1][column + 2].color != currentmove->slots[line][column].color)  | 
        ||
| 392 | currentmove->slots[line - 1][column + 2].flags |= FLAG_TAKEABLE;  | 
        ||
| 393 | |||
| 394 |                // peek knight's SSW move | 
        ||
| 395 | if ((column > 0) && (line > 1))  | 
        ||
| 396 | if (currentmove->slots[line - 2][column - 1].part == PART_NONE)  | 
        ||
| 397 | currentmove->slots[line - 2][column - 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 398 | else if (currentmove->slots[line - 2][column - 1].color != currentmove->slots[line][column].color)  | 
        ||
| 399 | currentmove->slots[line - 2][column - 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 400 | |||
| 401 |                // peek knight's SSE move | 
        ||
| 402 | if ((column < 7) && (line > 1))  | 
        ||
| 403 | if (currentmove->slots[line - 2][column + 1].part == PART_NONE)  | 
        ||
| 404 | currentmove->slots[line - 2][column + 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 405 | else if (currentmove->slots[line - 2][column + 1].color != currentmove->slots[line][column].color)  | 
        ||
| 406 | currentmove->slots[line - 2][column + 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 407 | |||
| 408 |                // peek knight's WNW move | 
        ||
| 409 | if ((column > 1) && (line < 7))  | 
        ||
| 410 | if (currentmove->slots[line + 1][column - 2].part == PART_NONE)  | 
        ||
| 411 | currentmove->slots[line + 1][column - 2].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 412 | else if (currentmove->slots[line + 1][column - 2].color != currentmove->slots[line][column].color)  | 
        ||
| 413 | currentmove->slots[line + 1][column - 2].flags |= FLAG_TAKEABLE;  | 
        ||
| 414 | |||
| 415 |                // peek knight's WSW move | 
        ||
| 416 | if ((column > 1) && (line > 0))  | 
        ||
| 417 | if (currentmove->slots[line - 1][column - 2].part == PART_NONE)  | 
        ||
| 418 | currentmove->slots[line - 1][column - 2].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 419 | else if (currentmove->slots[line - 1][column - 2].color != currentmove->slots[line][column].color)  | 
        ||
| 420 | currentmove->slots[line - 1][column - 2].flags |= FLAG_TAKEABLE;  | 
        ||
| 421 |             } | 
        ||
| 422 | |||
| 423 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 424 |             ///////////////////////////////////////// BISHOP ///////////////////////////////////////// | 
        ||
| 425 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 426 |             // else is it a bishop ? | 
        ||
| 427 | else if (boardslot->part == PART_BISHOP)  | 
        ||
| 428 |             { | 
        ||
| 429 |                // see how far bishop can move NE | 
        ||
| 430 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 431 |                { | 
        ||
| 432 | if ((line + pos_index > 7) || (column + pos_index > 7))  | 
        ||
| 433 | break;  | 
        ||
| 434 | if (currentmove->slots[line + pos_index][column + pos_index].part != PART_NONE)  | 
        ||
| 435 |                   { | 
        ||
| 436 | if (currentmove->slots[line + pos_index][column + pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 437 | currentmove->slots[line + pos_index][column + pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 438 | break;  | 
        ||
| 439 |                   } | 
        ||
| 440 | currentmove->slots[line + pos_index][column + pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 441 |                } | 
        ||
| 442 | |||
| 443 |                // see how far bishop can move SE | 
        ||
| 444 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 445 |                { | 
        ||
| 446 | if ((line - pos_index < 0) || (column + pos_index > 7))  | 
        ||
| 447 | break;  | 
        ||
| 448 | if (currentmove->slots[line - pos_index][column + pos_index].part != PART_NONE)  | 
        ||
| 449 |                   { | 
        ||
| 450 | if (currentmove->slots[line - pos_index][column + pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 451 | currentmove->slots[line - pos_index][column + pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 452 | break;  | 
        ||
| 453 |                   } | 
        ||
| 454 | currentmove->slots[line - pos_index][column + pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 455 |                } | 
        ||
| 456 | |||
| 457 |                // see how far bishop can move NW | 
        ||
| 458 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 459 |                { | 
        ||
| 460 | if ((line + pos_index > 7) || (column - pos_index < 0))  | 
        ||
| 461 | break;  | 
        ||
| 462 | if (currentmove->slots[line + pos_index][column - pos_index].part != PART_NONE)  | 
        ||
| 463 |                   { | 
        ||
| 464 | if (currentmove->slots[line + pos_index][column - pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 465 | currentmove->slots[line + pos_index][column - pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 466 | break;  | 
        ||
| 467 |                   } | 
        ||
| 468 | currentmove->slots[line + pos_index][column - pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 469 |                } | 
        ||
| 470 | |||
| 471 |                // see how far bishop can move SW | 
        ||
| 472 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 473 |                { | 
        ||
| 474 | if ((line - pos_index < 0) || (column - pos_index < 0))  | 
        ||
| 475 | break;  | 
        ||
| 476 | if (currentmove->slots[line - pos_index][column - pos_index].part != PART_NONE)  | 
        ||
| 477 |                   { | 
        ||
| 478 | if (currentmove->slots[line - pos_index][column - pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 479 | currentmove->slots[line - pos_index][column - pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 480 | break;  | 
        ||
| 481 |                   } | 
        ||
| 482 | currentmove->slots[line - pos_index][column - pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 483 |                } | 
        ||
| 484 |             } | 
        ||
| 485 | |||
| 486 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 487 |             ///////////////////////////////////////// QUEEN ////////////////////////////////////////// | 
        ||
| 488 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 489 |             // else is it a queen ? | 
        ||
| 490 | else if (boardslot->part == PART_QUEEN)  | 
        ||
| 491 |             { | 
        ||
| 492 |                // see how far queen can move NE | 
        ||
| 493 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 494 |                { | 
        ||
| 495 | if ((line + pos_index > 7) || (column + pos_index > 7))  | 
        ||
| 496 | break;  | 
        ||
| 497 | if (currentmove->slots[line + pos_index][column + pos_index].part != PART_NONE)  | 
        ||
| 498 |                   { | 
        ||
| 499 | if (currentmove->slots[line + pos_index][column + pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 500 | currentmove->slots[line + pos_index][column + pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 501 | break;  | 
        ||
| 502 |                   } | 
        ||
| 503 | currentmove->slots[line + pos_index][column + pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 504 |                } | 
        ||
| 505 | |||
| 506 |                // see how far queen can move SE | 
        ||
| 507 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 508 |                { | 
        ||
| 509 | if ((line - pos_index < 0) || (column + pos_index > 7))  | 
        ||
| 510 | break;  | 
        ||
| 511 | if (currentmove->slots[line - pos_index][column + pos_index].part != PART_NONE)  | 
        ||
| 512 |                   { | 
        ||
| 513 | if (currentmove->slots[line - pos_index][column + pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 514 | currentmove->slots[line - pos_index][column + pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 515 | break;  | 
        ||
| 516 |                   } | 
        ||
| 517 | currentmove->slots[line - pos_index][column + pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 518 |                } | 
        ||
| 519 | |||
| 520 |                // see how far queen can move NW | 
        ||
| 521 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 522 |                { | 
        ||
| 523 | if ((line + pos_index > 7) || (column - pos_index < 0))  | 
        ||
| 524 | break;  | 
        ||
| 525 | if (currentmove->slots[line + pos_index][column - pos_index].part != PART_NONE)  | 
        ||
| 526 |                   { | 
        ||
| 527 | if (currentmove->slots[line + pos_index][column - pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 528 | currentmove->slots[line + pos_index][column - pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 529 | break;  | 
        ||
| 530 |                   } | 
        ||
| 531 | currentmove->slots[line + pos_index][column - pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 532 |                } | 
        ||
| 533 | |||
| 534 |                // see how far queen can move SW | 
        ||
| 535 | for (pos_index = 1; pos_index < 8; pos_index++)  | 
        ||
| 536 |                { | 
        ||
| 537 | if ((line - pos_index < 0) || (column - pos_index < 0))  | 
        ||
| 538 | break;  | 
        ||
| 539 | if (currentmove->slots[line - pos_index][column - pos_index].part != PART_NONE)  | 
        ||
| 540 |                   { | 
        ||
| 541 | if (currentmove->slots[line - pos_index][column - pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 542 | currentmove->slots[line - pos_index][column - pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 543 | break;  | 
        ||
| 544 |                   } | 
        ||
| 545 | currentmove->slots[line - pos_index][column - pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 546 |                } | 
        ||
| 547 | |||
| 548 |                // see how far queen can move upwards | 
        ||
| 549 | for (pos_index = line + 1; pos_index < 8; pos_index++)  | 
        ||
| 550 |                { | 
        ||
| 551 | if (currentmove->slots[pos_index][column].part != PART_NONE)  | 
        ||
| 552 |                   { | 
        ||
| 553 | if (currentmove->slots[pos_index][column].color != currentmove->slots[line][column].color)  | 
        ||
| 554 | currentmove->slots[pos_index][column].flags |= FLAG_TAKEABLE;  | 
        ||
| 555 | break;  | 
        ||
| 556 |                   } | 
        ||
| 557 | currentmove->slots[pos_index][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 558 |                } | 
        ||
| 559 | |||
| 560 |                // see how far queen can move downwards | 
        ||
| 561 | for (pos_index = line - 1; pos_index >= 0; pos_index--)  | 
        ||
| 562 |                { | 
        ||
| 563 | if (currentmove->slots[pos_index][column].part != PART_NONE)  | 
        ||
| 564 |                   { | 
        ||
| 565 | if (currentmove->slots[pos_index][column].color != currentmove->slots[line][column].color)  | 
        ||
| 566 | currentmove->slots[pos_index][column].flags |= FLAG_TAKEABLE;  | 
        ||
| 567 | break;  | 
        ||
| 568 |                   } | 
        ||
| 569 | currentmove->slots[pos_index][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 570 |                } | 
        ||
| 571 | |||
| 572 |                // see how far queen can move left | 
        ||
| 573 | for (pos_index = column - 1; pos_index >= 0; pos_index--)  | 
        ||
| 574 |                { | 
        ||
| 575 | if (currentmove->slots[line][pos_index].part != PART_NONE)  | 
        ||
| 576 |                   { | 
        ||
| 577 | if (currentmove->slots[line][pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 578 | currentmove->slots[line][pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 579 | break;  | 
        ||
| 580 |                   } | 
        ||
| 581 | currentmove->slots[line][pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 582 |                } | 
        ||
| 583 | |||
| 584 |                // see how far queen can move right | 
        ||
| 585 | for (pos_index = column + 1; pos_index < 8; pos_index++)  | 
        ||
| 586 |                { | 
        ||
| 587 | if (currentmove->slots[line][pos_index].part != PART_NONE)  | 
        ||
| 588 |                   { | 
        ||
| 589 | if (currentmove->slots[line][pos_index].color != currentmove->slots[line][column].color)  | 
        ||
| 590 | currentmove->slots[line][pos_index].flags |= FLAG_TAKEABLE;  | 
        ||
| 591 | break;  | 
        ||
| 592 |                   } | 
        ||
| 593 | currentmove->slots[line][pos_index].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 594 |                } | 
        ||
| 595 |             } | 
        ||
| 596 | |||
| 597 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 598 |             ////////////////////////////////////////// KING ////////////////////////////////////////// | 
        ||
| 599 |             ////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 600 |             // else is it a king ? | 
        ||
| 601 | else if (boardslot->part == PART_KING)  | 
        ||
| 602 |             { | 
        ||
| 603 |                // see if king can move NE | 
        ||
| 604 | if ((line < 7) && (column < 7))  | 
        ||
| 605 |                { | 
        ||
| 606 | if (currentmove->slots[line + 1][column + 1].part == PART_NONE)  | 
        ||
| 607 | currentmove->slots[line + 1][column + 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 608 | else if (currentmove->slots[line + 1][column + 1].color != currentmove->slots[line][column].color)  | 
        ||
| 609 | currentmove->slots[line + 1][column + 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 610 |                } | 
        ||
| 611 | |||
| 612 |                // see if king can move SE | 
        ||
| 613 | if ((line > 0) && (column < 7))  | 
        ||
| 614 |                { | 
        ||
| 615 | if (currentmove->slots[line - 1][column + 1].part == PART_NONE)  | 
        ||
| 616 | currentmove->slots[line - 1][column + 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 617 | else if (currentmove->slots[line - 1][column + 1].color != currentmove->slots[line][column].color)  | 
        ||
| 618 | currentmove->slots[line - 1][column + 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 619 |                } | 
        ||
| 620 | |||
| 621 |                // see if king can move NW | 
        ||
| 622 | if ((line < 7) && (column > 0))  | 
        ||
| 623 |                { | 
        ||
| 624 | if (currentmove->slots[line + 1][column - 1].part == PART_NONE)  | 
        ||
| 625 | currentmove->slots[line + 1][column - 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 626 | else if (currentmove->slots[line + 1][column - 1].color != currentmove->slots[line][column].color)  | 
        ||
| 627 | currentmove->slots[line + 1][column - 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 628 |                } | 
        ||
| 629 | |||
| 630 |                // see if king can move SW | 
        ||
| 631 | if ((line > 0) && (column > 0))  | 
        ||
| 632 |                { | 
        ||
| 633 | if (currentmove->slots[line - 1][column - 1].part == PART_NONE)  | 
        ||
| 634 | currentmove->slots[line - 1][column - 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 635 | else if (currentmove->slots[line - 1][column - 1].color != currentmove->slots[line][column].color)  | 
        ||
| 636 | currentmove->slots[line - 1][column - 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 637 |                } | 
        ||
| 638 | |||
| 639 |                // see if king can move upwards | 
        ||
| 640 | if (line < 7)  | 
        ||
| 641 |                { | 
        ||
| 642 | if (currentmove->slots[line + 1][column].part == PART_NONE)  | 
        ||
| 643 | currentmove->slots[line + 1][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 644 | else if (currentmove->slots[line + 1][column].color != currentmove->slots[line][column].color)  | 
        ||
| 645 | currentmove->slots[line + 1][column].flags |= FLAG_TAKEABLE;  | 
        ||
| 646 |                } | 
        ||
| 647 | |||
| 648 |                // see if king can move downwards | 
        ||
| 649 | if (line > 0)  | 
        ||
| 650 |                { | 
        ||
| 651 | if (currentmove->slots[line - 1][column].part == PART_NONE)  | 
        ||
| 652 | currentmove->slots[line - 1][column].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 653 | else if (currentmove->slots[line - 1][column].color != currentmove->slots[line][column].color)  | 
        ||
| 654 | currentmove->slots[line - 1][column].flags |= FLAG_TAKEABLE;  | 
        ||
| 655 |                } | 
        ||
| 656 | |||
| 657 |                // see if king can move right | 
        ||
| 658 | if (column < 7)  | 
        ||
| 659 |                { | 
        ||
| 660 | if (currentmove->slots[line][column + 1].part == PART_NONE)  | 
        ||
| 661 | currentmove->slots[line][column + 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 662 | else if (currentmove->slots[line][column + 1].color != currentmove->slots[line][column].color)  | 
        ||
| 663 | currentmove->slots[line][column + 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 664 |                } | 
        ||
| 665 | |||
| 666 |                // see if king can move left | 
        ||
| 667 | if (column > 0)  | 
        ||
| 668 |                { | 
        ||
| 669 | if (currentmove->slots[line][column - 1].part == PART_NONE)  | 
        ||
| 670 | currentmove->slots[line][column - 1].flags |= FLAG_POSSIBLEMOVE;  | 
        ||
| 671 | else if (currentmove->slots[line][column - 1].color != currentmove->slots[line][column].color)  | 
        ||
| 672 | currentmove->slots[line][column - 1].flags |= FLAG_TAKEABLE;  | 
        ||
| 673 |                } | 
        ||
| 674 | |||
| 675 |                // can king castle bishopside ? | 
        ||
| 676 | if (currentmove->sides[boardslot->color].shortcastle_allowed // no parts have moved yet  | 
        ||
| 677 | && (currentmove->slots[line][5].part == PART_NONE) // no other part...  | 
        ||
| 678 | && (currentmove->slots[line][6].part == PART_NONE) // ...in the way  | 
        ||
| 679 | && !Move_IsCheck (currentmove, boardslot->color) // king not currently in check  | 
        ||
| 680 | && !Move_IsKingThreatenedAtLocation (currentmove, boardslot->color, line, 5, &threat_line, &threat_column)) // king's way safe  | 
        ||
| 681 | currentmove->slots[line][column + 2].flags |= FLAG_POSSIBLEMOVE; // allow castling bishopside  | 
        ||
| 682 | |||
| 683 |                // can king castle queenside ? | 
        ||
| 684 | if (currentmove->sides[boardslot->color].longcastle_allowed // no parts have moved yet  | 
        ||
| 685 | && (currentmove->slots[line][3].part == PART_NONE) // no other part...  | 
        ||
| 686 | && (currentmove->slots[line][2].part == PART_NONE) // ...is...  | 
        ||
| 687 | && (currentmove->slots[line][1].part == PART_NONE) // ...in the way  | 
        ||
| 688 | && !Move_IsCheck (currentmove, boardslot->color) // king not currently in check  | 
        ||
| 689 | && !Move_IsKingThreatenedAtLocation (currentmove, boardslot->color, line, 3, &threat_line, &threat_column)) // king's way safe  | 
        ||
| 690 | currentmove->slots[line][column - 2].flags |= FLAG_POSSIBLEMOVE; // allow castling queenside  | 
        ||
| 691 |             } | 
        ||
| 692 |          } | 
        ||
| 693 | } // end if (play mode)  | 
        ||
| 694 | |||
| 695 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 25 | pmbaty | 696 |    // now place the parts that are off-board (taken parts) | 
        
| 1 | pmbaty | 697 | |
| 698 |    // but only if we want them displayed | 
        ||
| 699 | if (options.want_takenparts)  | 
        ||
| 700 |    { | 
        ||
| 701 |       // draw the white player's taken parts, place the part off the board (watch out for the hack...) | 
        ||
| 702 | for (part_index = 0; part_index < currentmove->sides[COLOR_WHITE].takenpart_count; part_index++)  | 
        ||
| 703 |       { | 
        ||
| 704 | takenpart_type = currentmove->sides[COLOR_WHITE].takenparts[part_index];  | 
        ||
| 25 | pmbaty | 705 | |
| 706 |          // do we want the 3D models or the flat icons ? | 
        ||
| 707 |          // we do when EITHER we don't want flat icons OR the current player is looking downstraight | 
        ||
| 708 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        ||
| 709 | Scene_AddPart (scene, takenpart_type, COLOR_BLACK, (part_index < MAX_STACKABLE_PARTS ? 23.2f : 26.8f),  | 
        ||
| 710 | (part_index % MAX_STACKABLE_PARTS == 0 ? 23.2f : scene->objects[scene->object_count - 1].y - (scene->objects[scene->object_count - 1].simpleshadow_size + simpleshadow_sizes[takenpart_type]) * 0.75f),  | 
        ||
| 711 | 0.04f, (takenpart_type == PART_PAWN ? -90.0f : 100.0f), 0.0f); // rotate pawns 90°  | 
        ||
| 712 |          else | 
        ||
| 713 | Scene_AddTile (scene, theme->flattextures[COLOR_BLACK][takenpart_type], 1.25f, (part_index < MAX_STACKABLE_PARTS ? 23.2f : 26.8f),  | 
        ||
| 714 | 20.0f - (part_index < MAX_STACKABLE_PARTS ? part_index : (part_index - MAX_STACKABLE_PARTS)) * 2.5f, 0.07f, flaticons_yaw);  | 
        ||
| 1 | pmbaty | 715 |       } | 
        
| 716 | |||
| 717 |       // now draw the black player's taken parts, place the part off the board (watch out for the hack...) | 
        ||
| 718 | for (part_index = 0; part_index < currentmove->sides[COLOR_BLACK].takenpart_count; part_index++)  | 
        ||
| 719 |       { | 
        ||
| 720 | takenpart_type = currentmove->sides[COLOR_BLACK].takenparts[part_index];  | 
        ||
| 25 | pmbaty | 721 | |
| 722 |          // do we want the 3D models or the flat icons ? | 
        ||
| 723 |          // we do when EITHER we don't want flat icons OR the current player is looking downstraight | 
        ||
| 724 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        ||
| 725 | Scene_AddPart (scene, takenpart_type, COLOR_WHITE, (part_index < MAX_STACKABLE_PARTS ? -23.2f : -26.8f),  | 
        ||
| 726 | (part_index % MAX_STACKABLE_PARTS == 0 ? -23.2f : scene->objects[scene->object_count - 1].y + (scene->objects[scene->object_count - 1].simpleshadow_size + simpleshadow_sizes[takenpart_type]) * 0.75f),  | 
        ||
| 727 | 0.04f, (takenpart_type == PART_PAWN ? -90.0f : 100.0f), 0.0f); // rotate pawns 90°  | 
        ||
| 728 |          else | 
        ||
| 729 | Scene_AddTile (scene, theme->flattextures[COLOR_WHITE][takenpart_type], 1.25f, (part_index < MAX_STACKABLE_PARTS ? -23.2f : -26.8f),  | 
        ||
| 730 | -20.0f + (part_index < MAX_STACKABLE_PARTS ? part_index : (part_index - MAX_STACKABLE_PARTS)) * 2.5f, 0.07f, flaticons_yaw);  | 
        ||
| 1 | pmbaty | 731 |       } | 
        
| 732 |    } | 
        ||
| 733 | |||
| 734 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 735 |    // now draw the textured slots | 
        ||
| 736 | |||
| 737 |    // cycle through all the board slots... | 
        ||
| 738 | for (line = 0; line < 8; line++)  | 
        ||
| 739 | for (column = 0; column < 8; column++)  | 
        ||
| 740 |       { | 
        ||
| 741 | if (currentmove->slots[line][column].flags == FLAG_NONE)  | 
        ||
| 742 | continue; // skip everything that doesn't need to be drawn  | 
        ||
| 743 | |||
| 744 |          // draw the texture we want. Only one texture is allowed, so PRIORITY MATTERS. | 
        ||
| 745 | if (currentmove->slots[line][column].flags & FLAG_SELECTED)  | 
        ||
| 746 | Scene_AddTile (scene, theme->selected_textureindex, 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.02f, 0.0f);  | 
        ||
| 747 | else if (options.want_threats && currentmove->slots[line][column].flags & FLAG_CHECK)  | 
        ||
| 748 | Scene_AddTile (scene, theme->check_textureindex, 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.02f, 0.0f);  | 
        ||
| 749 | else if (options.want_possiblemoves && currentmove->slots[line][column].flags & FLAG_POSSIBLEMOVE)  | 
        ||
| 750 | Scene_AddTile (scene, theme->possiblemove_textureindex, 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.02f, 0.0f);  | 
        ||
| 751 | else if (options.want_possiblemoves && currentmove->slots[line][column].flags & FLAG_TAKEABLE)  | 
        ||
| 752 | Scene_AddTile (scene, theme->takeable_textureindex, 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.02f, 0.0f);  | 
        ||
| 753 | else if (options.want_threats && currentmove->slots[line][column].flags & FLAG_THREAT)  | 
        ||
| 754 | Scene_AddTile (scene, theme->threat_textureindex, 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.02f, 0.0f);  | 
        ||
| 755 |       } | 
        ||
| 756 | |||
| 757 |    // is it time to draw the hovered slot and last move textures on the board slots ? | 
        ||
| 758 | if (animation_endtime < current_time)  | 
        ||
| 759 |    { | 
        ||
| 760 |       // add the hovered slot tile (only when it should not be hidden because of highlighting) | 
        ||
| 75 | pmbaty | 761 | if (!is_paused && IS_VALID_POSITION (board->hovered_position)  | 
        
| 1 | pmbaty | 762 | && ((highlight_endtime < current_time) || ((int) ((highlight_endtime - current_time) * 20.0f) % 2 == 1)))  | 
        
| 763 | Scene_AddTile (scene, theme->hovered_textureindex, 3.1f,  | 
        ||
| 764 | 17.5f - (7 - board->hovered_position[1]) * 5.0f,  | 
        ||
| 765 | 17.5f - board->hovered_position[0] * 5.0f,  | 
        ||
| 766 | 0.03f, 0.0f); // hovered tile  | 
        ||
| 767 | |||
| 768 |       // and the previous move source and target | 
        ||
| 769 | if (options.want_lastmove && (board->move_count > 1) && (board->viewed_move > 0)  | 
        ||
| 770 | && IS_VALID_POSITION (board->moves[board->viewed_move].source)  | 
        ||
| 771 | && IS_VALID_POSITION (board->moves[board->viewed_move].target))  | 
        ||
| 772 |       { | 
        ||
| 773 | Scene_AddTile (scene, theme->lastmovesource_textureindex, 2.5f,  | 
        ||
| 774 | 17.5f - (7 - board->moves[board->viewed_move].source[1]) * 5.0f,  | 
        ||
| 775 | 17.5f - board->moves[board->viewed_move].source[0] * 5.0f,  | 
        ||
| 776 | 0.04f, 0.0f); // previous move source  | 
        ||
| 777 | Scene_AddTile (scene, theme->lastmovetarget_textureindex, 2.5f,  | 
        ||
| 778 | 17.5f - (7 - board->moves[board->viewed_move].target[1]) * 5.0f,  | 
        ||
| 779 | 17.5f - board->moves[board->viewed_move].target[0] * 5.0f,  | 
        ||
| 780 | 0.04f, 0.0f); // previous move target  | 
        ||
| 781 |       } | 
        ||
| 782 |    } | 
        ||
| 783 | |||
| 784 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 24 | pmbaty | 785 |    // now draw the 3D parts that are still in play | 
        
| 1 | pmbaty | 786 | |
| 24 | pmbaty | 787 |    // cycle through all the grid and place all static parts | 
        
| 788 | for (line = 0; line < 8; line++)  | 
        ||
| 1 | pmbaty | 789 |    { | 
        
| 24 | pmbaty | 790 | for (column = 0; column < 8; column++)  | 
        
| 791 |       { | 
        ||
| 792 | boardslot = ¤tmove->slots[line][column]; // quick access to grid slot  | 
        ||
| 1 | pmbaty | 793 | |
| 24 | pmbaty | 794 |          // is there nothing on this grid slot ? | 
        
| 795 | if (boardslot->part == PART_NONE)  | 
        ||
| 796 | continue; // then don't draw anything on it  | 
        ||
| 797 | |||
| 798 |          // is this part not animated ? i.e.: | 
        ||
| 799 |          // has no movement happened yet | 
        ||
| 800 |          // OR does the movement NOT land on this slot | 
        ||
| 801 |          //    AND is it NOT the tower concerned by a castle ? | 
        ||
| 802 | if ((board->viewed_move == 0)  | 
        ||
| 803 | || (((line != currentmove->target[0]) || (column != currentmove->target[1]))  | 
        ||
| 804 | && ((towupper (currentmove->pgntext[0]) != L'O')  | 
        ||
| 805 | || (line != (currentmove->color == COLOR_WHITE ? 0 : 7)) || (column != (currentmove->target[1] == 2 ? 3 : 5)))))  | 
        ||
| 1 | pmbaty | 806 |          { | 
        
| 25 | pmbaty | 807 |             // do we want the 3D models or the flat icons ? | 
        
| 808 |             // we do when EITHER we don't want flat icons OR the player playing the current move is looking downstraight | 
        ||
| 809 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        ||
| 810 | Scene_AddPart (scene, boardslot->part, boardslot->color, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f, 0.0f, 0.0f);  | 
        ||
| 24 | pmbaty | 811 |             else | 
        
| 25 | pmbaty | 812 | Scene_AddTile (scene, theme->flattextures[boardslot->color][boardslot->part], 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.05f, flaticons_yaw);  | 
        
| 24 | pmbaty | 813 |          } | 
        
| 814 | } // end for (column = 0; column < 8; column++)  | 
        ||
| 815 | } // end for (line = 0; line < 8; line++)  | 
        ||
| 1 | pmbaty | 816 | |
| 24 | pmbaty | 817 |    // now do another pass and draw the part(s) that are currently moving | 
        
| 818 | for (line = 0; line < 8; line++)  | 
        ||
| 819 |    { | 
        ||
| 820 | for (column = 0; column < 8; column++)  | 
        ||
| 821 |       { | 
        ||
| 822 | boardslot = ¤tmove->slots[line][column]; // quick access to grid slot  | 
        ||
| 1 | pmbaty | 823 | |
| 24 | pmbaty | 824 |          // is there nothing on this grid slot ? | 
        
| 825 | if (boardslot->part == PART_NONE)  | 
        ||
| 826 | continue; // then don't draw anything on it  | 
        ||
| 827 | |||
| 828 |          // has a movement happened yet AND does it land on this slot ? | 
        ||
| 829 | if ((board->viewed_move > 0)  | 
        ||
| 830 | && (line == currentmove->target[0]) && (column == currentmove->target[1]))  | 
        ||
| 831 |          { | 
        ||
| 130 | pmbaty | 832 |             // should this part slide ? parts moving orthogonally slide instead of jumping AND only if the distance is 1 square | 
        
| 833 | is_sliding = options.want_slidinganimations  | 
        ||
| 834 | && ((currentmove->source[0] == currentmove->target[0]) || (currentmove->source[1] == currentmove->target[1]))  | 
        ||
| 835 | && (abs (currentmove->target[0] - currentmove->source[0]) < 2)  | 
        ||
| 836 | && (abs (currentmove->target[1] - currentmove->source[1]) < 2);  | 
        ||
| 837 | |||
| 24 | pmbaty | 838 |             // do we want animations AND is it still time to play the animation ? | 
        
| 839 | if (options.want_animations && (animation_endtime > current_time))  | 
        ||
| 840 |             { | 
        ||
| 841 |                // get the source and target X and Y positions | 
        ||
| 842 | source_x = 17.5f - (7 - currentmove->source[1]) * 5.0f;  | 
        ||
| 843 | source_y = 17.5f - currentmove->source[0] * 5.0f;  | 
        ||
| 844 | target_x = 17.5f - (7 - currentmove->target[1]) * 5.0f;  | 
        ||
| 845 | target_y = 17.5f - currentmove->target[0] * 5.0f;  | 
        ||
| 846 | |||
| 847 |                // compute the movement completion ratio between 0 and 1 | 
        ||
| 848 | movement_ratio = 1.0f - (animation_endtime - current_time) / ANIMATION_DURATION;  | 
        ||
| 849 | |||
| 850 |                // compute the current X an Y based on movement timing | 
        ||
| 851 | current_x = source_x + (target_x - source_x) * movement_ratio;  | 
        ||
| 852 | current_y = source_y + (target_y - source_y) * movement_ratio;  | 
        ||
| 853 | |||
| 854 |                // do we want the 3D models or the flat icons ? | 
        ||
| 855 |                // we do when EITHER we don't want flat icons OR the player playing the current move is looking downstraight | 
        ||
| 25 | pmbaty | 856 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        
| 24 | pmbaty | 857 |                { | 
        
| 130 | pmbaty | 858 |                   // should this part be sliding or jumping ? | 
        
| 859 | if (is_sliding)  | 
        ||
| 860 |                   { | 
        ||
| 861 | current_z = 0.04f; // just slide  | 
        ||
| 862 | current_p = 0.0f; // and stay vertical  | 
        ||
| 863 |                   } | 
        ||
| 864 |                   else | 
        ||
| 865 |                   { | 
        ||
| 866 |                      // height is a sine positive, max height is proportional to travelled distance | 
        ||
| 867 | movement_diffco = abs(currentmove->target[1] - currentmove->source[1]);  | 
        ||
| 868 | movement_diffli = abs(currentmove->target[0] - currentmove->source[0]);  | 
        ||
| 869 | movement_maxheight = 0.5f + (float)movement_diffco + (float)movement_diffli;  | 
        ||
| 870 | if (currentmove->part == PART_KNIGHT)  | 
        ||
| 871 | movement_maxheight *= 2.0f; // knights jump high  | 
        ||
| 872 | else if ((currentmove->part == PART_KING) && (movement_diffco == 2))  | 
        ||
| 873 | movement_maxheight *= 5.0f; // kings jump VERY high when castling too  | 
        ||
| 874 | else if (movement_maxheight > 5.0f)  | 
        ||
| 875 | movement_maxheight = 5.0f; // all other parts just hover above the ground  | 
        ||
| 876 | current_z = 0.04f + (float)sin(MATH_PI * movement_ratio) * movement_maxheight; // part height  | 
        ||
| 877 | current_p = (boardslot->color == COLOR_BLACK ? -1 : 1) * min(current_z * 3.0f, 10.0f); // part inclination  | 
        ||
| 878 |                   } | 
        ||
| 24 | pmbaty | 879 | |
| 880 |                   // make this part move realistically | 
        ||
| 130 | pmbaty | 881 | Scene_AddPart (scene, boardslot->part, boardslot->color, current_x, current_y, current_z, 0.0f, current_p);  | 
        
| 24 | pmbaty | 882 |                } | 
        
| 883 |                else | 
        ||
| 25 | pmbaty | 884 | Scene_AddTile (scene, theme->flattextures[boardslot->color][boardslot->part], 2.5f, current_x, current_y, 0.07f, flaticons_yaw);  | 
        
| 24 | pmbaty | 885 |             } | 
        
| 886 |             else | 
        ||
| 887 |             { | 
        ||
| 25 | pmbaty | 888 |                // do we want the 3D models or the flat icons ? | 
        
| 889 |                // we do when EITHER we don't want flat icons OR the current player is looking downstraight | 
        ||
| 890 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        ||
| 891 | Scene_AddPart (scene, boardslot->part, boardslot->color, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f, 0.0f, 0.0f);  | 
        ||
| 24 | pmbaty | 892 |                else | 
        
| 25 | pmbaty | 893 | Scene_AddTile (scene, theme->flattextures[boardslot->color][boardslot->part], 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.05f, flaticons_yaw);  | 
        
| 24 | pmbaty | 894 |             } | 
        
| 895 | |||
| 130 | pmbaty | 896 |             // is it time to play a "start of animation" sound ? | 
        
| 897 | if (current_time + ANIMATION_DURATION == animation_endtime)  | 
        ||
| 24 | pmbaty | 898 |             { | 
        
| 130 | pmbaty | 899 | has_endsound_played = false; // an animation just started, remember the ending sound hasn't played yet  | 
        
| 900 | if (is_sliding)  | 
        ||
| 901 | Audio_PlaySound (SOUNDTYPE_SLIDE, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f); // play the sliding move sound  | 
        ||
| 902 |             } | 
        ||
| 903 | |||
| 904 |             // is it time to play an "end of animation" sound ? | 
        ||
| 905 | else if ((animation_endtime - 0.1f < current_time) && !has_endsound_played)  | 
        ||
| 906 |             { | 
        ||
| 907 | if (!is_sliding)  | 
        ||
| 908 | Audio_PlaySound (SOUNDTYPE_MOVE, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f); // play the normal move sound (unless the part was sliding)  | 
        ||
| 909 | |||
| 910 | if (currentmove->has_captured)  | 
        ||
| 911 | Audio_PlaySound (SOUNDTYPE_PIECETAKEN, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f); // on capture, play the capture sound  | 
        ||
| 912 | |||
| 116 | pmbaty | 913 |                // is the current player in checkmate, in check, in stalemate or is it a capture ? (to play the right sound) | 
        
| 24 | pmbaty | 914 |                // read as: was the last move an opponent's move AND did it put us to check ? | 
        
| 915 | if (currentmove->is_check)  | 
        ||
| 916 |                { | 
        ||
| 917 |                   // is it a checkmate or a normal check ? (checkmate == check + stalemate) | 
        ||
| 918 | if (currentmove->is_stalemate)  | 
        ||
| 116 | pmbaty | 919 | Audio_PlaySound (board->players[currentmove->color].type == PLAYER_HUMAN ? SOUNDTYPE_VICTORY : SOUNDTYPE_DEFEAT, 0.0f, 0.0f, 0.04f); // if so, play endgame sound at the center of the board  | 
        
| 24 | pmbaty | 920 |                   else | 
        
| 116 | pmbaty | 921 | Audio_PlaySound (SOUNDTYPE_CHECK, 0.0f, 0.0f, 0.04f); // else play the check sound at the center of the board  | 
        
| 24 | pmbaty | 922 |                } | 
        
| 116 | pmbaty | 923 | else if (currentmove->is_stalemate)  | 
        
| 924 | Audio_PlaySound (SOUNDTYPE_DEFEAT, 0.0f, 0.0f, 0.04f); // on stalemate, play defeat sound at the center of the board  | 
        ||
| 24 | pmbaty | 925 | |
| 130 | pmbaty | 926 | has_endsound_played = true; // remember the "end of animation" sound has been played (this will be reset at the beginning of the next animation)  | 
        
| 24 | pmbaty | 927 |             } | 
        
| 1 | pmbaty | 928 |          } | 
        
| 929 | |||
| 24 | pmbaty | 930 |          // else has a movement happened yet AND is this movement a castle AND is this the concerned tower ? | 
        
| 931 | else if ((board->viewed_move > 0)  | 
        ||
| 932 | && (towupper (currentmove->pgntext[0]) == L'O') // either O-O-O or O-O  | 
        ||
| 933 | && (line == (currentmove->color == COLOR_WHITE ? 0 : 7)) && (column == (currentmove->target[1] == 2 ? 3 : 5)))  | 
        ||
| 934 |          { | 
        ||
| 935 |             // do we want animations AND is it still time to play the animation ? (castling rooks move faster) | 
        ||
| 936 | if (options.want_animations && (animation_endtime - (0.5f * ANIMATION_DURATION) > current_time))  | 
        ||
| 937 |             { | 
        ||
| 938 |                // get the source and target X and Y positions | 
        ||
| 939 | source_x = 17.5f - (7 - (currentmove->target[1] == 2 ? 0 : 7)) * 5.0f; // if king moves left, then rook starts on column a, else it starts on column h  | 
        ||
| 940 | source_y = 17.5f - line * 5.0f;  | 
        ||
| 941 | target_x = 17.5f - (7 - column) * 5.0f;  | 
        ||
| 942 | target_y = 17.5f - line * 5.0f;  | 
        ||
| 943 | |||
| 944 |                // compute the movement completion ratio between 0 and 1 (castling rooks move faster) | 
        ||
| 945 | movement_ratio = min (1.0f, 1.0f - (animation_endtime - (0.5f * ANIMATION_DURATION) - current_time) / (0.5f * ANIMATION_DURATION));  | 
        ||
| 946 | |||
| 947 |                // compute the current X an Y based on movement timing | 
        ||
| 948 | current_x = source_x + (target_x - source_x) * movement_ratio;  | 
        ||
| 949 | current_y = source_y + (target_y - source_y) * movement_ratio;  | 
        ||
| 950 | |||
| 951 |                // height is a sine positive, max height is proportional to travelled distance | 
        ||
| 952 | movement_maxheight = 1.0f; // castling rook will barely hover above the ground  | 
        ||
| 81 | pmbaty | 953 | current_z = 0.04f + (float) sin (MATH_PI * movement_ratio) * movement_maxheight;  | 
        
| 24 | pmbaty | 954 | |
| 955 |                // make this part move realistically - do we want the 3D models or the flat icons ? | 
        ||
| 956 |                // we do when EITHER we don't want flat icons OR the player playing the current move is looking downstraight | 
        ||
| 25 | pmbaty | 957 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        
| 24 | pmbaty | 958 | Scene_AddPart (scene, boardslot->part, boardslot->color, current_x, current_y, current_z, 0.0f, (boardslot->color == COLOR_BLACK ? -1 : 1) * min (current_z * 3.0f, 10.0f));  | 
        
| 959 |                else | 
        ||
| 25 | pmbaty | 960 | Scene_AddTile (scene, theme->flattextures[boardslot->color][boardslot->part], 2.5f, current_x, current_y, 0.09f, flaticons_yaw);  | 
        
| 24 | pmbaty | 961 | |
| 962 | if (movement_ratio < 0.9f)  | 
        ||
| 963 | rooksound_played = false; // if the rook is still moving, reset the "sound played" flag  | 
        ||
| 964 | else if (!rooksound_played)  | 
        ||
| 965 |                { | 
        ||
| 116 | pmbaty | 966 | Audio_PlaySound (SOUNDTYPE_MOVE, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f); // when the rook has landed, play a move sound  | 
        
| 24 | pmbaty | 967 | rooksound_played = true; // remember this is no longer to be done  | 
        
| 968 |                } | 
        ||
| 969 |             } | 
        ||
| 970 |             else | 
        ||
| 971 |             { | 
        ||
| 25 | pmbaty | 972 |                // do we want the 3D models or the flat icons ? | 
        
| 973 |                // we do when EITHER we don't want flat icons OR the current player is looking downstraight | 
        ||
| 974 | if (!want_flaticons || (current_pitch < MAX_PITCH_FOR_FLAT_ICONS))  | 
        ||
| 975 | Scene_AddPart (scene, boardslot->part, boardslot->color, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.04f, 0.0f, 0.0f);  | 
        ||
| 24 | pmbaty | 976 |                else | 
        
| 25 | pmbaty | 977 | Scene_AddTile (scene, theme->flattextures[boardslot->color][boardslot->part], 2.5f, 17.5f - (7 - column) * 5.0f, 17.5f - line * 5.0f, 0.05f, flaticons_yaw);  | 
        
| 24 | pmbaty | 978 |             } | 
        
| 979 |          } | 
        ||
| 980 | } // end for (column = 0; column < 8; column++)  | 
        ||
| 981 | } // end for (line = 0; line < 8; line++)  | 
        ||
| 982 | |||
| 75 | pmbaty | 983 |    //////////////////////////////////////////////////////////////////////////////////// | 
        
| 984 |    // now draw the sepia overlay if we're in history view mode or if the game is paused | 
        ||
| 1 | pmbaty | 985 | |
| 75 | pmbaty | 986 | if (options.want_sepiafilter && (is_paused || ((board->move_count > 1) && (board->viewed_move != board->move_count - 1))))  | 
        
| 1 | pmbaty | 987 | scene->overlay_spriteindex = sepia_spriteindex; // use the sepia filter  | 
        
| 988 |    else | 
        ||
| 989 | scene->overlay_spriteindex = -1; // else use natural colors  | 
        ||
| 990 | |||
| 991 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 992 |    // now draw the move comment text | 
        ||
| 993 | |||
| 994 |    // does the move we are viewing have a comment ? if so, copy it, else leave it clear. Also if we're online, display a help text | 
        ||
| 995 | if ((currentmove->comment != NULL) && (currentmove->comment[0] != 0))  | 
        ||
| 996 | Scene_SetText (&scene->gui.comment_text, 53.3f, 0.5f, 93.0f, ALIGN_CENTER, ALIGN_TOP, ALIGN_LEFT, chat_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 191), 999999.0f, false, currentmove->comment);  | 
        ||
| 997 | else if ((network_player != NULL) && network_player->is_logged_in && !network_player->is_in_game)  | 
        ||
| 998 | Scene_SetText (&scene->gui.comment_text, 53.3f, 0.5f, 93.0f, ALIGN_CENTER, ALIGN_TOP, ALIGN_LEFT, chat_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 191), 999999.0f, false, connected_comment);  | 
        ||
| 999 | else if (RGBACOLOR_ALPHA (scene->gui.comment_text.color) >= 128) // HACK: don't clear if a dimmed hint text is already here  | 
        ||
| 1000 | scene->gui.comment_text.is_displayed = false; // else clear comment text  | 
        ||
| 1001 | |||
| 1002 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 1003 |    // now draw the game clock | 
        ||
| 1004 | |||
| 1005 |    // do we want to print the game clock ? | 
        ||
| 1006 | if (options.want_clock && (board->move_count > 1) && (board->game_state == STATE_PLAYING))  | 
        ||
| 1007 |    { | 
        ||
| 1008 | network_player = Player_FindByType (PLAYER_INTERNET); // quick access to network player  | 
        ||
| 1009 | |||
| 1010 |       // are we in Internet play ? if so, count time down, else count it up | 
        ||
| 1011 | if ((network_player != NULL) && network_player->is_in_game)  | 
        ||
| 1012 | seconds = Player_GetCurrent ()->remaining_seconds - (int) (current_time - board->lastmove_time); // total seconds first  | 
        ||
| 1013 |       else | 
        ||
| 75 | pmbaty | 1014 | seconds = (int) (current_time - stoppage_time - board->lastmove_time); // total seconds first, take pauses in account  | 
        
| 1 | pmbaty | 1015 | |
| 1016 | minutes = seconds / 60; // minutes  | 
        ||
| 1017 | seconds -= 60 * minutes; // remaining seconds  | 
        ||
| 1018 | |||
| 1019 | Scene_SetText (&the_scene.gui.clock_text, 99.0f, 66.6f, -1, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_RIGHT, players_fontindex, RGBACOLOR_SETALPHA (options.clock_color, 0x7f), 999999.0f, false, L"%02d:%02d ", minutes, seconds); // note: last space is alt+255  | 
        ||
| 1020 |    } | 
        ||
| 1021 |    else | 
        ||
| 1022 | scene->gui.clock_text.is_displayed = false;  | 
        ||
| 1023 | |||
| 1024 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 1025 |    // now draw the turn text | 
        ||
| 1026 | |||
| 1027 |    // do we want to print the player's turn AND has the game not ended yet ? if so, copy it, else leave it clear | 
        ||
| 1028 | if (options.want_turn && (board->game_state == STATE_PLAYING))  | 
        ||
| 1029 |    { | 
        ||
| 1030 | if (Board_ColorToMove (board) == COLOR_BLACK)  | 
        ||
| 1031 |       { | 
        ||
| 1032 | if (the_scene.gui.turn_text.color != 0x000000C0)  | 
        ||
| 1033 | Scene_SetText (&the_scene.gui.turn_text, 99.0f, 100.0f, -1, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_RIGHT, players_fontindex, 0x000000C0, 999999.0f, true, LOCALIZE (L"BlackMoves"));  | 
        ||
| 1034 |       } | 
        ||
| 1035 |       else | 
        ||
| 1036 |       { | 
        ||
| 1037 | if (the_scene.gui.turn_text.color != 0xFFFFFF80)  | 
        ||
| 1038 | Scene_SetText (&the_scene.gui.turn_text, 99.0f, 100.0f, -1, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_RIGHT, players_fontindex, 0xFFFFFF80, 999999.0f, true, LOCALIZE (L"WhiteMoves"));  | 
        ||
| 1039 |       } | 
        ||
| 1040 |    } | 
        ||
| 1041 |    else | 
        ||
| 1042 | scene->gui.turn_text.is_displayed = false;  | 
        ||
| 1043 | |||
| 1044 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 1045 |    // now draw the game history text | 
        ||
| 1046 | |||
| 1047 |    // do we want to display the game history ? if so, display the game history text in PGN | 
        ||
| 1048 | if (options.want_history && (board->move_count > 1))  | 
        ||
| 1049 |    { | 
        ||
| 1050 |       // first off, see where we start (for long games, we don't want to display EVERYTHING... | 
        ||
| 1051 | if (board->viewed_move > 30)  | 
        ||
| 1052 | start_index = board->viewed_move - 30; // display 30 moves maximum  | 
        ||
| 1053 |       else | 
        ||
| 1054 | start_index = 1;  | 
        ||
| 1055 | |||
| 1056 |       // allocate an arbitrary length history text string buffer (assume each move can't be longer than 15 characters) | 
        ||
| 1057 | historytext_size = 15 * (1 + (board->viewed_move + 1) - start_index);  | 
        ||
| 1058 | history_text = (wchar_t *) SAFE_malloc (historytext_size, sizeof (wchar_t), false);  | 
        ||
| 1059 | history_text[0] = 0; // and reset it  | 
        ||
| 1060 | |||
| 1061 |       // now for each move we want to display... | 
        ||
| 1062 | for (move_index = start_index; move_index <= board->viewed_move; move_index++)  | 
        ||
| 1063 |       { | 
        ||
| 1064 | length = wcslen (history_text); // get current text length  | 
        ||
| 1065 | |||
| 1066 |          // every move pair, append move pair number | 
        ||
| 1067 | if (move_index % 2 == 1)  | 
        ||
| 1068 | swprintf_s (&history_text[length], historytext_size - length, L"%d. ", 1 + move_index / 2);  | 
        ||
| 1069 | |||
| 1070 |          // append move text | 
        ||
| 1071 | wcscat_s (history_text, historytext_size, board->moves[move_index].pgntext);  | 
        ||
| 1072 | wcscat_s (history_text, historytext_size, L" ");  | 
        ||
| 1073 | |||
| 1074 |          // every odd move, drop a newline | 
        ||
| 1075 | if (move_index % 2 == 0)  | 
        ||
| 1076 | wcscat_s (history_text, historytext_size, L"\n");  | 
        ||
| 1077 |       } | 
        ||
| 1078 | |||
| 1079 |       // add 50% alpha to game history color and transmit it to 3D engine | 
        ||
| 1080 | Scene_SetText (&the_scene.gui.history_text, 100.0f, 50.0f, -1, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_LEFT, chat_fontindex, RGBACOLOR_SETALPHA (options.history_color, 0x7f), 999999.0f, false, history_text);  | 
        ||
| 1081 | SAFE_free ((void **) &history_text);  | 
        ||
| 1082 |    } | 
        ||
| 1083 |    else | 
        ||
| 1084 | scene->gui.history_text.is_displayed = false; // if we don't need to display the game history, free the buffer  | 
        ||
| 1085 | |||
| 1086 |    //////////////////////////////////////////////////////////////////////////////////////////////// | 
        ||
| 1087 |    // now draw the chat area | 
        ||
| 1088 | |||
| 1089 |    // is a valid chatter channel selected ? | 
        ||
| 1090 | if ((selected_chatterchannel != NULL) && (chatterchannel_count > 0) && ((local_player = Player_FindByType (PLAYER_HUMAN)) != NULL))  | 
        ||
| 1091 |    { | 
        ||
| 1092 |       // set the chatter's name | 
        ||
| 1093 | wcscpy_s (scene->gui.entered_ccreply.nickname, WCHAR_SIZEOF (scene->gui.entered_ccreply.nickname), local_player->name);  | 
        ||
| 1094 | |||
| 1095 |       // correct or update the channel name and color | 
        ||
| 1096 | if (selected_chatterchannel->theme[0] != 0)  | 
        ||
| 1097 | wcscpy_s (scene->gui.entered_ccreply.channelname, WCHAR_SIZEOF (scene->gui.entered_ccreply.channelname), selected_chatterchannel->theme);  | 
        ||
| 1098 |       else | 
        ||
| 1099 | swprintf_s (scene->gui.entered_ccreply.channelname, WCHAR_SIZEOF (scene->gui.entered_ccreply.channelname), L"%s %d", LOCALIZE (L"ChatterChannels_ColumnChannelNumber"), selected_chatterchannel->id);  | 
        ||
| 1100 | scene->gui.entered_ccreply.color = RGBACOLOR_FULLALPHA (selected_chatterchannel->color); // full bright for entering text  | 
        ||
| 1101 |    } | 
        ||
| 1102 | |||
| 1103 |    // display parts pick line in position setup mode only | 
        ||
| 1104 | scene->gui.is_partspick_displayed = (board->game_state == STATE_SETUPPOSITION ? true : false);  | 
        ||
| 1105 | |||
| 1106 |    ////////////////////////// | 
        ||
| 1107 |    // error and notifications | 
        ||
| 1108 | |||
| 1109 |    // is the current player a computer AND are we playing a game right now | 
        ||
| 1110 |    // AND has the computer been thinking for more than 5 seconds AND is there no "thinking" text yet ? | 
        ||
| 1111 | if ((board->players[Board_ColorToMove (board)].type == PLAYER_COMPUTER) && (board->game_state == STATE_PLAYING)  | 
        ||
| 1112 | && (board->lastmove_time + 5.0f < current_time) && !scene->gui.central_text.is_displayed)  | 
        ||
| 1113 |    { | 
        ||
| 1114 | Scene_SetText (&the_scene.gui.central_text, 50.0f, 40.0f, -1, ALIGN_CENTER, ALIGN_CENTER, ALIGN_CENTER, centermsg_fontindex, RGBA_TO_RGBACOLOR (255, 255, 255, 191),  | 
        ||
| 1115 | 999999.0f, true, LOCALIZE (L"Thinking")); // if so, display the "thinking" phrase in the middle of the screen  | 
        ||
| 1116 | the_scene.gui.want_spinwheel = true; // start spinning wheel  | 
        ||
| 1117 |    } | 
        ||
| 1118 | |||
| 1119 |    // is there a network player AND is our socket gone AWOL ? | 
        ||
| 1120 | else if ((network_player != NULL) && (network_player->our_socket == INVALID_SOCKET))  | 
        ||
| 1121 |    { | 
        ||
| 1122 |       // is there nothing in the center of the screen yet ? | 
        ||
| 1123 | if (!the_scene.gui.central_text.is_displayed)  | 
        ||
| 1124 | 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),  | 
        ||
| 1125 | 999999.0f, true, LOCALIZE (L"Error_ConnectionToChessServerLost")); // display "error" in the middle of the screen  | 
        ||
| 1126 | the_scene.overlay_spriteindex = sepia_spriteindex; // display sepia filter if no connection  | 
        ||
| 1127 |    } | 
        ||
| 1128 | |||
| 75 | pmbaty | 1129 |    // is the game paused ? | 
        
| 1130 | if (is_paused)  | 
        ||
| 1131 | 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, 255),  | 
        ||
| 1132 | 1.0f, false, LOCALIZE (L"Paused")); // if so, display the "paused" phrase in the middle of the screen  | 
        ||
| 1133 | |||
| 1 | pmbaty | 1134 | return; // finished, scene is updated  | 
        
| 1135 | } | 
        ||
| 1136 | |||
| 1137 | |||
| 1138 | void Scene_AddCCReply (scene_t *scene, wchar_t *nickname, wchar_t *channelname, unsigned long color_rgbx, wchar_t *fmt, ...)  | 
        ||
| 1139 | { | 
        ||
| 1140 |    // helper function to add a CC reply on display | 
        ||
| 1141 | |||
| 1142 | static wchar_t message[4096];  | 
        ||
| 1143 |    ccreply_t re; | 
        ||
| 1144 | va_list argptr;  | 
        ||
| 1145 | |||
| 1146 |    // concatenate all the arguments in one string | 
        ||
| 1147 | va_start (argptr, fmt);  | 
        ||
| 1148 | _vsnwprintf_s (message, WCHAR_SIZEOF (message), _TRUNCATE, fmt, argptr);  | 
        ||
| 1149 | va_end (argptr);  | 
        ||
| 1150 | |||
| 1151 |    // now put the text in place | 
        ||
| 1152 | memset (&re, 0, sizeof (re)); // reset the structure we're about to fill  | 
        ||
| 1153 | |||
| 1154 | wcscpy_s (re.nickname, WCHAR_SIZEOF (re.nickname), nickname); // copy nickname  | 
        ||
| 1155 | wcscpy_s (re.channelname, WCHAR_SIZEOF (re.channelname), channelname); // copy channel name  | 
        ||
| 1156 | |||
| 1157 | re.text_length = wcslen (message); // get text length  | 
        ||
| 1158 | re.text = (wchar_t *) SAFE_malloc (re.text_length + 1, sizeof (wchar_t), false); // allocate text space (include null terminator)  | 
        ||
| 1159 | wcscpy_s (re.text, re.text_length + 1, message); // get the text  | 
        ||
| 1160 | |||
| 1161 | re.color = RGBACOLOR_SETALPHA (color_rgbx, 0xC0); // copy reply color and force a slightly transparent alpha  | 
        ||
| 1162 | re.arrival_time = current_time; // save CC reply arrival time  | 
        ||
| 1163 | |||
| 1164 |    // reallocate CC history array to hold now one reply more | 
        ||
| 1165 | the_scene.gui.cchistory = (ccreply_t *) SAFE_realloc (the_scene.gui.cchistory, the_scene.gui.cchistory_count, the_scene.gui.cchistory_count + 1, sizeof (ccreply_t), false);  | 
        ||
| 1166 | memcpy (&the_scene.gui.cchistory[the_scene.gui.cchistory_count], &re, sizeof (ccreply_t));  | 
        ||
| 1167 | the_scene.gui.cchistory_count++; // CC history holds now one reply more  | 
        ||
| 1168 | |||
| 1169 | return; // finished, announcement text is set  | 
        ||
| 1170 | } | 
        ||
| 1171 | |||
| 1172 | |||
| 1173 | void Scene_AddAnnouncement (scene_t *scene, wchar_t *fmt, ...)  | 
        ||
| 1174 | { | 
        ||
| 1175 |    // helper function to set the announcement (red) text on display | 
        ||
| 1176 | |||
| 1177 | static wchar_t message[4096];  | 
        ||
| 1178 |    ccreply_t re; | 
        ||
| 1179 | va_list argptr;  | 
        ||
| 1180 | |||
| 1181 |    // concatenate all the arguments in one string | 
        ||
| 1182 | va_start (argptr, fmt);  | 
        ||
| 1183 | _vsnwprintf_s (message, WCHAR_SIZEOF (message), _TRUNCATE, fmt, argptr);  | 
        ||
| 1184 | va_end (argptr);  | 
        ||
| 1185 | |||
| 1186 |    // now put the text in place | 
        ||
| 1187 | memset (&re, 0, sizeof (re)); // reset the structure we're about to fill  | 
        ||
| 1188 | |||
| 1189 | re.text_length = wcslen (message); // get text length  | 
        ||
| 1190 | re.text = (wchar_t *) SAFE_malloc (re.text_length + 1, sizeof (wchar_t), false); // allocate text space (include null terminator)  | 
        ||
| 1191 | wcscpy_s (re.text, re.text_length + 1, message); // get the text  | 
        ||
| 1192 | |||
| 1193 | wcscpy_s (re.channelname, WCHAR_SIZEOF (re.channelname), LOCALIZE (L"ImportantMessage"));  | 
        ||
| 1194 | re.color = RGBA_TO_RGBACOLOR (192, 0, 0, 0xE0); // fair red, a bit more opaque than normal messages  | 
        ||
| 1195 | re.arrival_time = current_time; // save announcement arrival time  | 
        ||
| 1196 | |||
| 1197 |    // reallocate CC history array to hold now one reply more | 
        ||
| 1198 | the_scene.gui.cchistory = (ccreply_t *) SAFE_realloc (the_scene.gui.cchistory, the_scene.gui.cchistory_count, the_scene.gui.cchistory_count + 1, sizeof (ccreply_t), false);  | 
        ||
| 1199 | memcpy (&the_scene.gui.cchistory[the_scene.gui.cchistory_count], &re, sizeof (ccreply_t));  | 
        ||
| 1200 | the_scene.gui.cchistory_count++; // CC history holds now one reply more  | 
        ||
| 1201 | |||
| 1202 | return; // finished, announcement text is set  | 
        ||
| 1203 | } | 
        ||
| 1204 | |||
| 1205 | |||
| 124 | pmbaty | 1206 | void Scene_SetButton (guibutton_t *button, float left, float top, float width, float height, int sprite_index, wchar_t *fmt, ...)  | 
        
| 1 | pmbaty | 1207 | { | 
        
| 1208 |    // helper function to set up a GUI button | 
        ||
| 1209 | |||
| 124 | pmbaty | 1210 | va_list argptr;  | 
        
| 1211 | |||
| 1 | pmbaty | 1212 | button->left = left;  | 
        
| 1213 | button->top = top;  | 
        ||
| 1214 | button->width = width;  | 
        ||
| 1215 | button->height = height;  | 
        ||
| 1216 | button->sprite_index = sprite_index;  | 
        ||
| 1217 | |||
| 124 | pmbaty | 1218 |    // concatenate all the arguments in one string | 
        
| 1219 | if (fmt != NULL)  | 
        ||
| 1220 |    { | 
        ||
| 1221 | va_start (argptr, fmt);  | 
        ||
| 1222 | _vsnwprintf_s (button->text, WCHAR_SIZEOF (button->text), _TRUNCATE, fmt, argptr);  | 
        ||
| 1223 | va_end (argptr);  | 
        ||
| 1224 |    } | 
        ||
| 1225 |    else | 
        ||
| 1226 | button->text[0] = 0; // (unless no text is specified for this button)  | 
        ||
| 1227 | |||
| 1 | pmbaty | 1228 | return; // finished, button is set  | 
        
| 1229 | } | 
        ||
| 1230 | |||
| 1231 | |||
| 1232 | void Scene_SetText (guitext_t *text, float xpos_percent, float ypos_percent, float maxwidth_percent, int horizontal_align, int vertical_align, int text_align, int font_index, unsigned long color_rgba, float duration, bool want_fade, wchar_t *fmt, ...)  | 
        ||
| 1233 | { | 
        ||
| 1234 |    // helper function to set some text on display | 
        ||
| 1235 | |||
| 1236 | static wchar_t message[4096];  | 
        ||
| 1237 | va_list argptr;  | 
        ||
| 1238 | int length;  | 
        ||
| 1239 | |||
| 1240 |    // concatenate all the arguments in one string | 
        ||
| 1241 | va_start (argptr, fmt);  | 
        ||
| 1242 | _vsnwprintf_s (message, WCHAR_SIZEOF (message), _TRUNCATE, fmt, argptr);  | 
        ||
| 1243 | va_end (argptr);  | 
        ||
| 1244 | |||
| 1245 | text->xpos_percent = xpos_percent; // save text's X position, in percents from left to right  | 
        ||
| 1246 | text->ypos_percent = ypos_percent; // save text's Y position, in percents from top to bottom  | 
        ||
| 1247 | text->maxwidth_percent = maxwidth_percent; // save text's max width before word wrapping  | 
        ||
| 1248 | text->horizontal_align = horizontal_align; // save text's horizontal alignment regarding the X position  | 
        ||
| 1249 | text->vertical_align = vertical_align; // save text's vertical alignment regarding the Y position  | 
        ||
| 1250 | text->text_align = text_align; // save text's horizontal alignment inside the bounding rectangle  | 
        ||
| 1251 | text->font_index = font_index; // save the index of the font with which to display this text  | 
        ||
| 1252 | text->color = color_rgba; // text's color, in RGBA  | 
        ||
| 1253 | |||
| 1254 |    // now put the text in place | 
        ||
| 1255 | length = wcslen (message) + 1; // include null terminator  | 
        ||
| 1256 | text->buffer = (wchar_t *) SAFE_realloc (text->buffer, text->buffer_size, length, sizeof (wchar_t), false);  | 
        ||
| 1257 | wcscpy_s (text->buffer, length, message); // copy message text  | 
        ||
| 1258 | text->buffer_size = length; // and save buffer length  | 
        ||
| 1259 | |||
| 1260 | text->appear_time = current_time; // save text arrival time  | 
        ||
| 1261 | text->disappear_time = current_time + duration; // make it last duration seconds  | 
        ||
| 1262 | text->want_fade = want_fade; // remember if text needs to be faded in and out  | 
        ||
| 1263 | |||
| 1264 |    // mark this text for display | 
        ||
| 1265 | text->is_displayed = true;  | 
        ||
| 1266 | |||
| 1267 | return; // finished, text is set  | 
        ||
| 1268 | } | 
        ||
| 1269 | |||
| 1270 | |||
| 1271 | static void Scene_AddPart (scene_t *scene, int part_type, int part_color, float pos_x, float pos_y, float pos_z, float turn_yaw, float pitch)  | 
        ||
| 1272 | { | 
        ||
| 1273 |    // helper function to add a specified part of the specified color to the rendered scene | 
        ||
| 1274 | |||
| 1275 | sceneobject_t *object;  | 
        ||
| 1276 | partcolor_t *partcolor;  | 
        ||
| 1277 | |||
| 1278 |    // reallocate space to hold one object more and blank it out | 
        ||
| 1279 | scene->objects = (sceneobject_t *) SAFE_realloc (scene->objects, scene->object_count, scene->object_count + 1, sizeof (sceneobject_t), true);  | 
        ||
| 1280 | |||
| 1281 | object = &scene->objects[scene->object_count]; // quick access to object  | 
        ||
| 1282 | |||
| 1283 | object->mesh_index = theme->part_meshes[part_type]; // retrieve object mesh  | 
        ||
| 1284 | object->simpleshadow_size = simpleshadow_sizes[part_type]; // retrieve simple shadow size according to part type  | 
        ||
| 1285 | object->scale = 1.0f; // scale at 1 so far  | 
        ||
| 1286 | |||
| 1287 |    // set object texture and material | 
        ||
| 1288 | partcolor = &theme->part_colors[part_color]; // quick access to part color struct  | 
        ||
| 1289 | object->texture_index = partcolor->texture;  | 
        ||
| 1290 | object->material_index = partcolor->material;  | 
        ||
| 1291 | |||
| 1292 |    // figure out object position on board | 
        ||
| 1293 | object->x = pos_x;  | 
        ||
| 1294 | object->y = pos_y;  | 
        ||
| 1295 | object->z = pos_z;  | 
        ||
| 1296 | |||
| 1297 |    // turn a color's all parts' yaw 180 degrees so as both sides face each other | 
        ||
| 1298 | if (part_color == COLOR_WHITE)  | 
        ||
| 1299 | object->yaw = 180.0f;  | 
        ||
| 1300 |    else | 
        ||
| 1301 | object->yaw = 0.0f;  | 
        ||
| 1302 | |||
| 1303 |    // and add the final turn pitch and yaw | 
        ||
| 1304 | object->pitch = pitch;  | 
        ||
| 1305 | object->yaw = WrapAngle (object->yaw + turn_yaw);  | 
        ||
| 1306 | |||
| 1307 | scene->object_count++; // array holds now one object more  | 
        ||
| 1308 | return; // finished  | 
        ||
| 1309 | } | 
        ||
| 1310 | |||
| 1311 | |||
| 1312 | static void Scene_AddTile (scene_t *scene, int texture_index, float scale, float pos_x, float pos_y, float pos_z, float turn_yaw)  | 
        ||
| 1313 | { | 
        ||
| 1314 |    // helper function to add a specified part of the specified color to the rendered scene | 
        ||
| 1315 | |||
| 1316 | sceneobject_t *object;  | 
        ||
| 1317 | |||
| 1318 |    // reallocate space to hold one object more and blank it out | 
        ||
| 1319 | scene->objects = (sceneobject_t *) SAFE_realloc (scene->objects, scene->object_count, scene->object_count + 1, sizeof (sceneobject_t), true);  | 
        ||
| 1320 | |||
| 1321 | object = &scene->objects[scene->object_count]; // quick access to object  | 
        ||
| 1322 | |||
| 1323 |    // save object data | 
        ||
| 1324 | object->mesh_index = -1; // objects that have -1 as mesh index are tiles  | 
        ||
| 1325 | object->texture_index = texture_index;  | 
        ||
| 1326 | object->material_index = -1; // objects will use the default material  | 
        ||
| 1327 | |||
| 1328 |    // figure out object position on board | 
        ||
| 1329 | object->x = pos_x;  | 
        ||
| 1330 | object->y = pos_y;  | 
        ||
| 1331 | object->z = pos_z;  | 
        ||
| 1332 | object->scale = scale;  | 
        ||
| 1333 | |||
| 1334 |    // turn tile as requested | 
        ||
| 1335 | object->yaw = turn_yaw;  | 
        ||
| 1336 | |||
| 1337 | scene->object_count++; // array holds now one object more  | 
        ||
| 1338 | |||
| 1339 | return; // finished  | 
        ||
| 1340 | } |