DLLInterfaceEditor.cpp (21341B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 #include <stdio.h> 17 //#include <iostream> 18 //#include <fstream> 19 20 #include "function.h" 21 #include "externs.h" 22 #include "DLLInterface.h" 23 #include "Gadget.h" 24 #include "defines.h" // VOC_COUNT, VOX_COUNT 25 #include "SidebarGlyphx.h" 26 #include "TEMPLATE.H" 27 28 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup(); 29 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup(); 30 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map(char* cncdata_directory, char* house_name, int scenario_index, char* east_west, char* variant); 31 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name(char* cncdata_directory, char* scenario_name); 32 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map(); 33 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater); 34 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data_By_Index(int cell_index, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index); 35 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data(int x, int y, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index); 36 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Texture_Buffer(int x, int y, int& out_width, int& out_height, SAFEARRAY*& out_texture_array); 37 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory, int CD); 38 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points); 39 40 char EditorMapINIBuffer[SHAPE_BUFFER_SIZE]; 41 bool EditorMapInitialized = false; 42 43 const static int EDITOR_COMMMAND_SUCCESS = 0; 44 const static int EDITOR_COMMMAND_FAILURE = 1; 45 46 const static char* MixFileNames[] = 47 { 48 "GENERAL.MIX", 49 "SC-000.MIX", 50 "SC-001.MIX", 51 "DESERT.MIX", 52 "TEMPERAT.MIX", 53 "WINTER.MIX" 54 }; 55 56 extern MixFileClass *TheaterIcons; 57 extern bool Read_Movies_From_Scenario_Ini(char *root, bool fresh); 58 59 /************************************************************************************************** 60 * CNC_Editor_Startup 61 * Initializes the system to allow map loading for the editor 62 **************************************************************************************************/ 63 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup() 64 { 65 BlackPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 66 GamePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 67 OriginalPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 68 WhitePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 69 memset(WhitePalette, 63, 768); 70 71 72 Set_Palette(GamePalette); 73 74 TheaterData = 0; 75 TheaterIcons = 0; 76 LowTheaterData = 0; 77 78 return EDITOR_COMMMAND_SUCCESS; 79 } 80 81 /************************************************************************************************** 82 * CNC_Editor_Cleanup 83 * Cleans up systems initialized by the editor 84 **************************************************************************************************/ 85 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup() 86 { 87 if (BlackPalette) 88 { 89 delete[] BlackPalette; 90 } 91 92 if (GamePalette) 93 { 94 delete[] GamePalette; 95 } 96 97 if (OriginalPalette) 98 { 99 delete[] OriginalPalette; 100 } 101 if (WhitePalette) 102 { 103 delete[] WhitePalette; 104 } 105 106 return EDITOR_COMMMAND_SUCCESS; 107 } 108 /************************************************************************************************** 109 * CNC_Editor_Load_Mix_Files 110 * Loads all the Mix files for Tiberian Dawn 111 **************************************************************************************************/ 112 void CNC_Editor_Load_Mix_Files() 113 { 114 int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]); 115 116 for (int i = count - 1; i >= 0; --i) 117 { 118 MixFileClass::Free(MixFileNames[i]); 119 } 120 121 for (int i = 0; i < count; ++i) 122 { 123 new MixFileClass(MixFileNames[i]); 124 MixFileClass::Cache(MixFileNames[i]); 125 } 126 } 127 128 /************************************************************************************************** 129 * CNC_Editor_Setup_Content_Directory 130 * Sets up where the system should load map data from. 131 **************************************************************************************************/ 132 void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, char* cd_directory) 133 { 134 char content_directory[_MAX_PATH]; 135 136 sprintf(content_directory, "%s\\TIBERIAN_DAWN\\%s\\", cncdata_directory, cd_directory); 137 138 if (strlen(content_directory) != 0) { 139 CCFileClass::Clear_Search_Drives(); 140 CCFileClass::Reset_Raw_Path(); 141 char *dll_dir = strdup(content_directory); 142 CCFileClass::Set_Search_Drives(dll_dir); 143 free(dll_dir); 144 } 145 } 146 147 void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, int CD_index) 148 { 149 char cd_name[_MAX_PATH]; 150 sprintf(cd_name, "CD%i", CD_index); 151 CNC_Editor_Setup_Content_Directory(cncdata_directory, cd_name); 152 } 153 154 155 156 157 /************************************************************************************************** 158 * CNC_Editor_Load_Map 159 * Loads the map with the given parameters. 160 * 161 * cncdata_directory: path of the base CNC data directory 162 * faction: the name of the faction we are loading the map for 163 * scenario_index: int scenario index 164 * east_west: 165 * variant: 166 * 167 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 168 **************************************************************************************************/ 169 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map( 170 char* cncdata_directory, 171 char* house_name, 172 int scenario_index, 173 char* east_west, 174 char* variant) 175 { 176 CNC_Editor_Clear_Map(); 177 178 int CD = 1; 179 if (stricmp(house_name, "GDI") == 0) { 180 ScenPlayer = SCEN_PLAYER_GDI; 181 GameToPlay = GAME_NORMAL; 182 183 if (scenario_index == 30 || scenario_index == 90) { 184 CD = 5; 185 } 186 else if (scenario_index >= 60 && scenario_index <= 72) { 187 CD = 4; 188 } 189 else if (scenario_index >= 20 && scenario_index < 60) { 190 CD = 3; 191 } 192 } 193 194 if (stricmp(house_name, "NOD") == 0) { 195 ScenPlayer = SCEN_PLAYER_NOD; 196 GameToPlay = GAME_NORMAL; 197 CD = 2; 198 199 // Hack a fix for scenario 21 since the same mission number is used in Covert Ops and N64 200 if (scenario_index == 81 || scenario_index == 22) { 201 CD = 5; 202 if (scenario_index == 81) { 203 scenario_index = 21; 204 } 205 } 206 else if (scenario_index >= 60 && scenario_index <= 61) { 207 CD = 4; 208 } 209 else if (scenario_index >= 20 && scenario_index < 60) { 210 CD = 3; 211 } 212 } 213 214 if (stricmp(house_name, "MULTI") == 0) 215 { 216 ScenPlayer = SCEN_PLAYER_MPLAYER; 217 GameToPlay = GAME_GLYPHX_MULTIPLAYER; 218 } 219 220 if (stricmp(house_name, "JUR") == 0) 221 { 222 ScenPlayer = SCEN_PLAYER_JP; 223 GameToPlay = GAME_NORMAL; 224 } 225 226 switch (CD) 227 { 228 case 4: 229 CNC_Editor_Setup_Content_Directory(cncdata_directory, "CONSOLE_1"); 230 break; 231 case 5: 232 CNC_Editor_Setup_Content_Directory(cncdata_directory, "CONSOLE_2"); 233 break; 234 default: 235 CNC_Editor_Setup_Content_Directory(cncdata_directory, CD); 236 break; 237 } 238 239 CNC_Editor_Load_Mix_Files(); 240 241 Scenario = scenario_index; 242 BuildLevel = 7; 243 244 if (stricmp(east_west, "w") == 0) 245 { 246 ScenDir = SCEN_DIR_WEST; 247 } 248 else 249 { 250 ScenDir = SCEN_DIR_EAST; 251 } 252 253 ScenarioVarType variant_enum; 254 255 if (stricmp(variant, "b") == 0) 256 { 257 variant_enum = SCEN_VAR_B; 258 } 259 else if (stricmp(variant, "c") == 0) 260 { 261 variant_enum = SCEN_VAR_C; 262 } 263 else if (stricmp(variant, "d") == 0) 264 { 265 variant_enum = SCEN_VAR_D; 266 } 267 else 268 { 269 variant_enum = SCEN_VAR_A; 270 } 271 272 Set_Scenario_Name(ScenarioName, Scenario, ScenPlayer, ScenDir, variant_enum); 273 274 char fname[_MAX_FNAME + _MAX_EXT]; 275 sprintf(fname, "%s.INI", ScenarioName); 276 CCFileClass file(fname); 277 if (!file.Is_Available()) 278 { 279 return(EDITOR_COMMMAND_FAILURE); 280 } 281 else 282 { 283 memset(EditorMapINIBuffer, 0, SHAPE_BUFFER_SIZE); 284 file.Read(EditorMapINIBuffer, SHAPE_BUFFER_SIZE - 1); 285 } 286 287 Map.One_Time_Editor(); 288 Map.Read_INI(EditorMapINIBuffer); 289 if (Map.Read_Binary(ScenarioName, &ScenarioCRC)) 290 { 291 EditorMapInitialized = true; 292 return EDITOR_COMMMAND_SUCCESS; 293 } 294 else 295 { 296 return EDITOR_COMMMAND_FAILURE; 297 } 298 } 299 300 301 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name(char* cncdata_directory, char* scenario_name) 302 { 303 return EDITOR_COMMMAND_FAILURE; 304 } 305 306 /************************************************************************************************** 307 * CNC_Editor_Clear_Map 308 * Deletes the data for the currently loaded map. 309 * 310 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 311 **************************************************************************************************/ 312 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map() 313 { 314 if (EditorMapInitialized) 315 { 316 Map.Init_Clear(); 317 318 int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]); 319 for (int i = count - 1; i >= 0; --i) 320 { 321 MixFileClass::Free(MixFileNames[i]); 322 } 323 324 EditorMapInitialized = false; 325 TheaterData = nullptr; 326 TheaterIcons = nullptr; 327 328 return EDITOR_COMMMAND_SUCCESS; 329 } 330 else 331 { 332 return EDITOR_COMMMAND_FAILURE; 333 } 334 335 } 336 337 /************************************************************************************************** 338 * CNC_Editor_Get_Map_Stats 339 * Gets the stats for the currently loaded map 340 * 341 * map_width: out parameter storing the width of the map 342 * map_height: out parameter storing the height of the map 343 * theater: out paramter storing the theater of the map 344 * 345 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 346 **************************************************************************************************/ 347 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater) 348 { 349 if (EditorMapInitialized) 350 { 351 map_width = Map.MapCellWidth + 1; 352 map_height = Map.MapCellHeight + 1; 353 theater = Map.Theater; 354 return EDITOR_COMMMAND_SUCCESS; 355 } 356 357 map_width = -1; 358 map_height = -1; 359 theater = -1; 360 return EDITOR_COMMMAND_FAILURE; 361 } 362 363 /************************************************************************************************** 364 * CNC_Editor_Get_Cell_Data_By_Index 365 * Get the data from the given cell. 366 * 367 * cell_index: The index of the desired cell. 368 * cell_name: out buffer to be filled with the name of the given cell. 369 * cell_name_size: the size of the cell name buffer. 370 * 371 * 372 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 373 **************************************************************************************************/ 374 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data_By_Index(int cell_index, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index) 375 { 376 CellClass * cellptr = &Map[cell_index]; 377 378 cell_name[0] = 0; 379 int icon = 0; 380 void *image_data = 0; 381 382 char template_name[10]; 383 if (cellptr->Get_Template_Info(template_name, icon, image_data)) 384 { 385 snprintf(cell_name, cell_name_size, "%s-%04d", template_name, icon); 386 387 template_type = cellptr->TType; 388 template_icon_index = icon; 389 390 return EDITOR_COMMMAND_SUCCESS; 391 } 392 393 return EDITOR_COMMMAND_FAILURE; 394 } 395 396 /************************************************************************************************** 397 * CNC_Editor_Get_Cell_Data 398 * Get the data from the given cell. 399 * 400 * x,y: The corrdinates of the desired cell. 401 * cell_name: out buffer to be filled with the name of the given cell. 402 * cell_name_size: the size of the cell name buffer. 403 * 404 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 405 **************************************************************************************************/ 406 407 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Data(int x, int y, char* cell_name, unsigned long cell_name_size, int& template_type, int& template_icon_index) 408 { 409 if (!EditorMapInitialized) 410 { 411 return EDITOR_COMMMAND_FAILURE; 412 } 413 414 415 int map_cell_x = Map.MapCellX; 416 int map_cell_y = Map.MapCellY; 417 int map_cell_width = Map.MapCellWidth; 418 int map_cell_height = Map.MapCellHeight; 419 420 if (map_cell_x > 0) { 421 map_cell_x--; 422 map_cell_width++; 423 } 424 425 if (map_cell_width < MAP_MAX_CELL_WIDTH) { 426 map_cell_width++; 427 } 428 429 if (map_cell_y > 0) { 430 map_cell_y--; 431 map_cell_height++; 432 } 433 434 if (map_cell_height < MAP_MAX_CELL_HEIGHT) { 435 map_cell_height++; 436 } 437 438 CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); 439 440 return CNC_Editor_Get_Cell_Data_By_Index((int)cell, cell_name, cell_name_size, template_type, template_icon_index); 441 } 442 443 /************************************************************************************************** 444 * CNC_Editor_Get_Cell_Texture_Buffer 445 * 446 * x,y: 447 * out_width, out_height: dimensions of the outputed texture array 448 * out_texture_array: output array of unsigned chars storing the color data for the requested object, 449 * every 3 chars is a set of RGB values 450 **************************************************************************************************/ 451 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Cell_Texture_Buffer(int x, int y, int& out_width, int& out_height, SAFEARRAY*& out_texture_array) 452 { 453 454 int map_cell_x = Map.MapCellX; 455 int map_cell_y = Map.MapCellY; 456 int map_cell_width = Map.MapCellWidth; 457 int map_cell_height = Map.MapCellHeight; 458 459 if (map_cell_x > 0) { 460 map_cell_x--; 461 map_cell_width++; 462 } 463 464 if (map_cell_width < MAP_MAX_CELL_WIDTH) { 465 map_cell_width++; 466 } 467 468 if (map_cell_y > 0) { 469 map_cell_y--; 470 map_cell_height++; 471 } 472 473 if (map_cell_height < MAP_MAX_CELL_HEIGHT) { 474 map_cell_height++; 475 } 476 477 CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); 478 CellClass * cellptr = &Map[cell]; 479 480 char cell_name[_MAX_PATH]; 481 482 int icon = 0; 483 void *image_data = 0; 484 if (cellptr->Get_Template_Info(cell_name, icon, image_data)) 485 { 486 GraphicBufferClass temp_gbuffer(24, 24); 487 GraphicViewPortClass temp_viewport(&temp_gbuffer, 0, 0, 24, 24); 488 489 WindowList[WINDOW_CUSTOM][WINDOWX] = 0; 490 WindowList[WINDOW_CUSTOM][WINDOWY] = 0; 491 WindowList[WINDOW_CUSTOM][WINDOWWIDTH] = 24; 492 WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = 24; 493 494 temp_viewport.Draw_Stamp(image_data, icon, 0, 0, NULL, WINDOW_CUSTOM); 495 496 out_width = temp_viewport.Get_Width(); 497 out_height = temp_viewport.Get_Height(); 498 499 const int COLOR_SIZE = 3; 500 501 SAFEARRAYBOUND Bound; 502 Bound.lLbound = 0; 503 Bound.cElements = out_width * out_height * COLOR_SIZE; 504 505 out_texture_array = SafeArrayCreate(VT_UI1, 1, &Bound); 506 507 unsigned char* out_buffer; 508 509 HRESULT hr = SafeArrayAccessData(out_texture_array, (void **)&out_buffer); 510 if (SUCCEEDED(hr)) 511 { 512 GraphicBufferClass* Graphic_Buffer = temp_viewport.Get_Graphic_Buffer(); 513 514 int VP_Scan_Line = temp_viewport.Get_Width() + temp_viewport.Get_XAdd(); 515 516 char * start_ptr; 517 start_ptr = (char *)Graphic_Buffer->Get_Buffer(); 518 start_ptr += ((temp_viewport.Get_YPos() * VP_Scan_Line) + temp_viewport.Get_XPos()); 519 520 for (int y = 0; y < out_height; ++y) 521 { 522 unsigned char* scanline_ptr = (unsigned char*)start_ptr + y * VP_Scan_Line; 523 unsigned char* out_buffer_y_ptr = out_buffer + (y * out_width * COLOR_SIZE); 524 for (int x = 0; x < out_width; ++x) 525 { 526 unsigned char* pallete_index_ptr = scanline_ptr + x; 527 unsigned char* out_buffer_ptr = out_buffer_y_ptr + (x * COLOR_SIZE); 528 529 int red_palette_index = (*pallete_index_ptr) * COLOR_SIZE; 530 out_buffer_ptr[0] = GamePalette[red_palette_index] << 2; 531 out_buffer_ptr[1] = GamePalette[red_palette_index + 1] << 2; 532 out_buffer_ptr[2] = GamePalette[red_palette_index + 2] << 2; 533 } 534 } 535 536 SafeArrayUnaccessData(out_texture_array); 537 538 return EDITOR_COMMMAND_SUCCESS; 539 } 540 } 541 542 return EDITOR_COMMMAND_FAILURE; 543 } 544 545 /************************************************************************************************** 546 * CNC_Editor_Get_Template_Data 547 * Get the data from the given tile template type. 548 * 549 * template_type_index: The index of the template type to use. should come from the Get_Cell_Data function. 550 * template_points: Out buffer to be filled with the list of positions of the tiles as offsets from the origin of the template. 551 * This data is store is an X, Y, X, Y, X, Y format. 552 * 553 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 554 **************************************************************************************************/ 555 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points) 556 { 557 if (template_type_index >= TEMPLATE_COUNT || template_type_index == TEMPLATE_NONE) 558 { 559 return EDITOR_COMMMAND_FAILURE; 560 } 561 562 const TemplateTypeClass& template_type = TemplateTypeClass::As_Reference((TemplateType)template_type_index); 563 if (template_type.Get_Image_Data() == nullptr) 564 { 565 return EDITOR_COMMMAND_FAILURE; 566 } 567 568 short const * occupy_list = template_type.Occupy_List(); 569 570 short const * counter = occupy_list; 571 while (counter && *counter != REFRESH_EOL) 572 { 573 counter++; 574 } 575 576 int occupy_list_size = counter - occupy_list; 577 578 579 SAFEARRAYBOUND bounds; 580 bounds.lLbound = 0; 581 bounds.cElements = occupy_list_size * 2; 582 template_points = SafeArrayCreate(VT_I4, 1, &bounds); 583 584 int *pData; 585 HRESULT hr = SafeArrayAccessData(template_points, (void **)&pData); 586 if (SUCCEEDED(hr)) 587 { 588 for (int i = 0; i < occupy_list_size; i++) 589 { 590 CELL cell = occupy_list[i]; 591 592 int x = Cell_X(cell); 593 int y = Cell_Y(cell); 594 595 pData[i * 2] = x; 596 pData[i * 2 + 1] = y; 597 } 598 599 SafeArrayUnaccessData(template_points); 600 601 return EDITOR_COMMMAND_SUCCESS; 602 } 603 604 return EDITOR_COMMMAND_FAILURE; 605 } 606 607 608 /************************************************************************************************** 609 * CNC_Editor_Get_Scenario_Names 610 * 611 **************************************************************************************************/ 612 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory, int CD) 613 { 614 unsigned char read_buffer[SHAPE_BUFFER_SIZE]; 615 Set_Shape_Buffer(read_buffer, SHAPE_BUFFER_SIZE); 616 617 char team_ids[] = 618 { 619 'a', 620 'b', 621 'c', 622 'd', 623 'e', 624 'f', 625 'g', 626 'h', 627 'i', 628 'j', 629 'k', 630 'l', 631 'm', 632 'n', 633 'o', 634 'p', 635 'q', 636 'r', 637 's', 638 't', 639 'u', 640 'v', 641 'w', 642 'x', 643 'y', 644 'z', 645 }; 646 /* 647 { 648 'g', 649 'b', 650 'm', 651 'j' 652 }; 653 */ 654 const int team_count = sizeof(team_ids) / sizeof(char); 655 656 char direction_ids[] = 657 { 658 'e', 659 'w' 660 }; 661 const int direction_count = sizeof(direction_ids) / sizeof(char); 662 663 char variant_ids[] = 664 { 665 'a', 666 'b', 667 'c', 668 'd' 669 }; 670 671 const int variant_count = sizeof(variant_ids) / sizeof(char); 672 673 const int min_scenario_index = 1; 674 const int max_scenario_index = 99; 675 676 char scenario_name[_MAX_FNAME + _MAX_EXT]; 677 char file_name[_MAX_FNAME + _MAX_EXT]; 678 679 CNC_Editor_Setup_Content_Directory(cncdata_directory, CD); 680 CNC_Editor_Load_Mix_Files(); 681 682 char output_file_name[256]; 683 snprintf(output_file_name, 256, "d:\\TD_Disk%d_Names.txt", CD); 684 685 FILE * names_file = fopen(output_file_name, "w+"); 686 687 for (int team_index = 0; team_index < team_count; team_index++) 688 { 689 for (int scenario_index = min_scenario_index; scenario_index <= max_scenario_index; ++scenario_index) 690 { 691 for (int direction_index = 0; direction_index < direction_count; direction_index++) 692 { 693 for (int variant_index = 0; variant_index < variant_count; variant_index++) 694 { 695 sprintf(scenario_name, "sc%c%.2d%c%c", 696 team_ids[team_index], 697 scenario_index, 698 direction_ids[direction_index], 699 variant_ids[variant_index]); 700 701 sprintf(file_name, "%s.INI", scenario_name); 702 CCFileClass file(file_name); 703 if (file.Is_Available()) 704 { 705 if (Read_Movies_From_Scenario_Ini(scenario_name, false)) 706 { 707 //fprintf(names_file, "%s - \t$Intro:%s \t\t$Brief:%s \t\t$Win:%s \t\t$Lose:%s \t\t$Action:%s \t\t$Theme:%s", scenario_name, IntroMovie, BriefMovie, WinMovie, LoseMovie, ActionMovie, MovieThemeName); 708 fprintf(names_file, "------------------%s-------------- %s \n", scenario_name, MovieThemeName); 709 710 if (stricmp("x", IntroMovie) != 0) 711 { 712 fprintf(names_file, "<IntroMovieName network=\"client\">%s</IntroMovieName>\n", IntroMovie); 713 } 714 if (stricmp("x", BriefMovie) != 0) 715 { 716 fprintf(names_file, "<BriefMovieName network=\"client\">%s</BriefMovieName>\n", BriefMovie); 717 } 718 if (stricmp("x", ActionMovie) != 0) 719 { 720 fprintf(names_file, "<ActionMovieName network=\"client\">%s</ActionMovieName>\n", ActionMovie); 721 } 722 if (stricmp("x", WinMovie) != 0) 723 { 724 fprintf(names_file, "<WinMovieName network=\"client\">%s</WinMovieName>\n", WinMovie); 725 } 726 } 727 728 fprintf(names_file, "\n"); 729 } 730 731 732 733 } 734 } 735 } 736 } 737 738 fclose(names_file); 739 740 return EDITOR_COMMMAND_SUCCESS; 741 }