DLLInterfaceEditor.cpp (21888B)
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 <string> 17 #include <stdio.h> 18 19 #include "function.h" 20 #include "externs.h" 21 #include "DLLInterface.h" 22 #include "Gadget.h" 23 #include "defines.h" // VOC_COUNT, VOX_COUNT 24 #include "SidebarGlyphx.h" 25 #include "mixfile.h" 26 #include "ccini.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); 38 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points); 39 40 int LoadScenario(); 41 42 extern int DLL_Startup(const char * command_line); 43 44 char EditorMapINIBuffer[SHAPE_BUFFER_SIZE]; 45 bool EditorMapInitialized = false; 46 47 const static int EDITOR_COMMMAND_SUCCESS = 0; 48 const static int EDITOR_COMMMAND_FAILURE = 1; 49 50 const char* CD1Path = "\\RED_ALERT\\CD1\\"; 51 const char* CD2Path = "\\RED_ALERT\\COUNTERSTRIKE\\"; 52 const char* CD3Path = "\\RED_ALERT\\AFTERMATH\\"; 53 54 char RedAlertINI[_MAX_PATH]; 55 56 /************************************************************************************************** 57 * CNC_Editor_Startup 58 * Initializes the system to allow map loading for the editor 59 **************************************************************************************************/ 60 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Startup() 61 { 62 /* 63 BlackPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 64 GamePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 65 OriginalPalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 66 WhitePalette = new(MEM_CLEAR | MEM_REAL) unsigned char[768]; 67 memset(WhitePalette, 63, 768); 68 69 70 Set_Palette(GamePalette); 71 72 TheaterData = 0; 73 TheaterIcons = 0; 74 LowTheaterData = 0; 75 */ 76 77 RunningFromEditor = true; 78 79 return EDITOR_COMMMAND_FAILURE; 80 } 81 82 /************************************************************************************************** 83 * CNC_Editor_Cleanup 84 * Cleans up systems initialized by the editor 85 **************************************************************************************************/ 86 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Cleanup() 87 { 88 /* 89 if (BlackPalette) 90 { 91 delete[] BlackPalette; 92 } 93 94 if (GamePalette) 95 { 96 delete[] GamePalette; 97 } 98 99 if (OriginalPalette) 100 { 101 delete[] OriginalPalette; 102 } 103 if (WhitePalette) 104 { 105 delete[] WhitePalette; 106 } 107 */ 108 109 return EDITOR_COMMMAND_SUCCESS; 110 } 111 /************************************************************************************************** 112 * CNC_Editor_Load_Mix_Files 113 * Loads all the Mix files for Tiberian Dawn 114 **************************************************************************************************/ 115 void CNC_Editor_Load_Mix_Files() 116 { 117 const char* MixFileNames[] = 118 { 119 "MAIN.MIX", 120 "REDALERT.MIX", 121 "EXPAND2.MIX", 122 "EXPAND.MIX", 123 "HIRES1.MIX", 124 //"LORES1.MIX" 125 126 "GENERAL.MIX", 127 128 "LOCAL.MIX", 129 "HIRES.MIX", 130 "NCHIRES.MIX", 131 "CONQUER.MIX", 132 133 "RUSSIAN.MIX", 134 "ALLIES.MIX", 135 136 "SNOW.MIX", 137 "TEMPERAT.MIX", 138 "INTERIOR.MIX", 139 }; 140 141 int count = sizeof(MixFileNames) / sizeof(MixFileNames[0]); 142 143 for (int i = count - 1; i >= 0; --i) 144 { 145 MFCD::Free(MixFileNames[i]); 146 } 147 148 for (int i = 0; i < count; ++i) 149 { 150 MFCD* file = new MFCD(MixFileNames[i], &FastKey); 151 file->Cache(); 152 153 } 154 155 } 156 157 /************************************************************************************************** 158 * CNC_Editor_Setup_Content_Directory 159 * Sets up where the system should load map data from. 160 * 161 * cncdata_directory: path of the base CNC data directory 162 * CD1: if true, consider this disc 1, otherwise consider this disc 2. 163 **************************************************************************************************/ 164 void CNC_Editor_Setup_Content_Directory(char* cncdata_directory, int CD, char (&content_directory)[_MAX_PATH]) 165 { 166 167 switch (CD) 168 { 169 default: 170 case 1: 171 sprintf(content_directory, "%s%s", cncdata_directory, CD1Path); 172 break; 173 case 2: 174 sprintf(content_directory, "%s%s", cncdata_directory, CD2Path); 175 break; 176 case 3: 177 sprintf(content_directory, "%s%s", cncdata_directory, CD3Path); 178 break; 179 } 180 181 //Setup red alert path 182 sprintf(RedAlertINI, "%sREDALERT.INI",content_directory); 183 184 if (strlen(content_directory) != 0) { 185 CCFileClass::Clear_Search_Drives(); 186 CCFileClass::Reset_Raw_Path(); 187 char *dll_dir = strdup(content_directory); 188 CCFileClass::Set_Search_Drives(dll_dir); 189 free(dll_dir); 190 } 191 } 192 193 /************************************************************************************************** 194 * CNC_Editor_Load_Map 195 * Loads the map with the given parameters. 196 * 197 * cncdata_directory: path of the base CNC data directory 198 * faction: the name of the faction we are loading the map for 199 * scenario_index: int scenario index 200 * east_west: 201 * variant: 202 * 203 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 204 **************************************************************************************************/ 205 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map( 206 char* cncdata_directory, 207 char* house_name, 208 int scenario_index, 209 char* east_west, 210 char* variant) 211 { 212 213 CNC_Editor_Clear_Map(); 214 215 ScenarioPlayerType scen_player; 216 int CD = 1; 217 if (stricmp(house_name, "SPAIN") == 0) { 218 scen_player = SCEN_PLAYER_SPAIN; 219 Whom = HOUSE_GOOD; 220 221 if (scenario_index >= 40) 222 { 223 CD = 3; 224 } 225 else if (scenario_index >= 15) 226 { 227 CD = 2; 228 } 229 } 230 231 if (stricmp(house_name, "GREECE") == 0 || stricmp(house_name, "ALLY") == 0) { 232 scen_player = SCEN_PLAYER_GREECE; 233 Whom = HOUSE_GOOD; 234 235 if (scenario_index >= 40) 236 { 237 CD = 3; 238 } 239 else if (scenario_index >= 15) 240 { 241 CD = 2; 242 } 243 } 244 245 if (stricmp(house_name, "USSR") == 0) { 246 scen_player = SCEN_PLAYER_USSR; 247 Whom = HOUSE_BAD; 248 249 if (scenario_index >= 40) 250 { 251 CD = 3; 252 } 253 else if (scenario_index >= 15) 254 { 255 CD = 2; 256 } 257 } 258 259 if (stricmp(house_name, "MULTI") == 0) 260 { 261 scen_player = SCEN_PLAYER_MPLAYER; 262 Whom = HOUSE_MULTI1; 263 264 if (scenario_index >= 25) 265 { 266 CD = 3; 267 } 268 269 } 270 271 if (stricmp(house_name, "JAPAN") == 0) 272 { 273 scen_player = SCEN_PLAYER_JP; 274 Whom = HOUSE_JP; 275 } 276 277 char content_directory[_MAX_PATH]; 278 279 CNC_Editor_Setup_Content_Directory(cncdata_directory, CD, content_directory); 280 281 char command_line[_MAX_PATH]; 282 sprintf(command_line, "-CD%s", content_directory); 283 284 DLL_Startup(command_line); 285 286 Scen.Scenario = scenario_index; 287 ScenarioDirType scen_dir; 288 BuildLevel = 7; 289 290 if (stricmp(east_west, "w") == 0) 291 { 292 scen_dir = SCEN_DIR_WEST; 293 } 294 else 295 { 296 scen_dir = SCEN_DIR_EAST; 297 } 298 299 ScenarioVarType variant_enum; 300 301 if (stricmp(variant, "b") == 0) 302 { 303 variant_enum = SCEN_VAR_B; 304 } 305 else if (stricmp(variant, "c") == 0) 306 { 307 variant_enum = SCEN_VAR_C; 308 } 309 else if (stricmp(variant, "d") == 0) 310 { 311 variant_enum = SCEN_VAR_D; 312 } 313 else 314 { 315 variant_enum = SCEN_VAR_A; 316 } 317 318 Scen.Set_Scenario_Name(Scen.Scenario, scen_player, scen_dir, (ScenarioVarType)variant_enum); 319 320 return LoadScenario(); 321 } 322 323 /************************************************************************************************** 324 * CNC_Editor_Load_Map_By_Scenario_Name 325 * Loads the map with the given parameters. 326 * 327 * cncdata_directory: path of the base CNC data directory 328 * scenario_name: name of the scnario to load 329 * 330 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 331 **************************************************************************************************/ 332 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Load_Map_By_Scenario_Name( 333 char* cncdata_directory, 334 char* scenario_name) 335 { 336 int CD = 3; // Always use the aftermath cd 337 if (strnlen(scenario_name, _MAX_PATH) >= 3 && (scenario_name[2] == 'a' || scenario_name[2] == 'A')) 338 { 339 // Ant missions are CD 2 340 CD = 2; 341 } 342 343 CNC_Editor_Clear_Map(); 344 345 char content_directory[_MAX_PATH]; 346 347 CNC_Editor_Setup_Content_Directory(cncdata_directory, CD, content_directory); 348 349 char command_line[_MAX_PATH]; 350 sprintf(command_line, "-CD%s", content_directory); 351 352 DLL_Startup(command_line); 353 354 snprintf(Scen.ScenarioName, _MAX_FNAME + _MAX_EXT, "%s.ini", scenario_name); 355 356 return LoadScenario(); 357 } 358 359 int LoadScenario() 360 { 361 CCFileClass file(Scen.ScenarioName); 362 363 if (!file.Is_Available()) 364 { 365 return(EDITOR_COMMMAND_FAILURE); 366 } 367 368 369 CCINIClass ini; 370 int result = ini.Load(file,true); 371 if (result == 0) 372 { 373 return(EDITOR_COMMMAND_FAILURE); 374 } 375 376 if (result == 2) 377 { 378 // if (Session.Type == GAME_NORMAL || Session.ScenarioIsOfficial) { 379 /* 380 ** Make a special exception so that multiplayer maps from 1 through 381 ** 24 will not care if the message digest is in error. All other 382 ** maps will abort the scenario load. 383 */ 384 if (Scen.ScenarioName[2] != 'M' || Scen.Scenario >= 25) 385 { 386 return(EDITOR_COMMMAND_FAILURE); 387 } 388 } 389 390 const char * const BASIC = "Basic"; 391 NewINIFormat = ini.Get_Int(BASIC, "NewINIFormat", 0); 392 393 Map.One_Time(); 394 Map.Read_INI(ini); 395 396 EditorMapInitialized = true; 397 398 return EDITOR_COMMMAND_SUCCESS; 399 } 400 401 /************************************************************************************************** 402 * CNC_Editor_Clear_Map 403 * Deletes the data for the currently loaded map. 404 * 405 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 406 **************************************************************************************************/ 407 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Clear_Map() 408 { 409 if (EditorMapInitialized) 410 { 411 Map.Init_Clear(); 412 EditorMapInitialized = false; 413 414 return EDITOR_COMMMAND_SUCCESS; 415 } 416 else 417 { 418 return EDITOR_COMMMAND_FAILURE; 419 } 420 421 return EDITOR_COMMMAND_FAILURE; 422 } 423 424 /************************************************************************************************** 425 * CNC_Editor_Get_Map_Stats 426 * Gets the stats for the currently loaded map 427 * 428 * map_width: out parameter storing the width of the map 429 * map_height: out parameter storing the height of the map 430 * theater: out paramter storing the theater of the map 431 * 432 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 433 **************************************************************************************************/ 434 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Map_Stats(int& map_width, int& map_height, int& theater) 435 { 436 if (EditorMapInitialized) 437 { 438 map_width = Map.MapCellWidth + 1; 439 map_height = Map.MapCellHeight + 1; 440 theater = Scen.Theater; 441 return EDITOR_COMMMAND_SUCCESS; 442 } 443 444 map_width = -1; 445 map_height = -1; 446 theater = -1; 447 return EDITOR_COMMMAND_FAILURE; 448 } 449 450 /************************************************************************************************** 451 * CNC_Editor_Get_Cell_Data_By_Index 452 * Get the data from the given cell. 453 * 454 * cell_index: The index of the desired cell. 455 * cell_name: out buffer to be filled with the name of the given cell. 456 * cell_name_size: the size of the cell name buffer. 457 * 458 * 459 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 460 **************************************************************************************************/ 461 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) 462 { 463 CELL index = (CELL)cell_index; 464 465 CellClass * cellptr = &Map[index]; 466 467 cell_name[0] = 0; 468 int icon = 0; 469 void *image_data = 0; 470 471 char template_name[10]; 472 if (cellptr->Get_Template_Info(template_name, icon, image_data)) 473 { 474 snprintf(cell_name, cell_name_size, "%s-%04d", template_name, icon); 475 476 template_type = cellptr->TType; 477 template_icon_index = icon; 478 479 //TemplateTypeClass::As_Reference(ptr->TType). 480 481 return EDITOR_COMMMAND_SUCCESS; 482 } 483 484 return EDITOR_COMMMAND_FAILURE; 485 } 486 487 /************************************************************************************************** 488 * CNC_Editor_Get_Cell_Data 489 * Get the data from the given cell. 490 * 491 * x,y: The corrdinates of the desired cell. 492 * cell_name: out buffer to be filled with the name of the given cell. 493 * cell_name_size: the size of the cell name buffer. 494 * 495 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 496 **************************************************************************************************/ 497 498 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) 499 { 500 if (!EditorMapInitialized) 501 { 502 return EDITOR_COMMMAND_FAILURE; 503 } 504 505 506 int map_cell_x = Map.MapCellX; 507 int map_cell_y = Map.MapCellY; 508 int map_cell_width = Map.MapCellWidth; 509 int map_cell_height = Map.MapCellHeight; 510 511 if (map_cell_x > 0) { 512 map_cell_x--; 513 map_cell_width++; 514 } 515 516 if (map_cell_width < MAP_MAX_CELL_WIDTH) { 517 map_cell_width++; 518 } 519 520 if (map_cell_y > 0) { 521 map_cell_y--; 522 map_cell_height++; 523 } 524 525 if (map_cell_height < MAP_MAX_CELL_HEIGHT) { 526 map_cell_height++; 527 } 528 529 CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); 530 531 return CNC_Editor_Get_Cell_Data_By_Index((int)cell, cell_name, cell_name_size, template_type, template_icon_index); 532 } 533 534 /************************************************************************************************** 535 * CNC_Editor_Get_Cell_Texture_Buffer 536 * 537 * x,y: 538 * out_width, out_height: dimensions of the outputed texture array 539 * out_texture_array: output array of unsigned chars storing the color data for the requested object, 540 * every 3 chars is a set of RGB values 541 **************************************************************************************************/ 542 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) 543 { 544 545 int map_cell_x = Map.MapCellX; 546 int map_cell_y = Map.MapCellY; 547 int map_cell_width = Map.MapCellWidth; 548 int map_cell_height = Map.MapCellHeight; 549 550 if (map_cell_x > 0) { 551 map_cell_x--; 552 map_cell_width++; 553 } 554 555 if (map_cell_width < MAP_MAX_CELL_WIDTH) { 556 map_cell_width++; 557 } 558 559 if (map_cell_y > 0) { 560 map_cell_y--; 561 map_cell_height++; 562 } 563 564 if (map_cell_height < MAP_MAX_CELL_HEIGHT) { 565 map_cell_height++; 566 } 567 568 CELL cell = XY_Cell(map_cell_x + x, map_cell_y + y); 569 CellClass * cellptr = &Map[cell]; 570 571 char cell_name[_MAX_PATH]; 572 573 int icon = 0; 574 void *image_data = 0; 575 if (cellptr->Get_Template_Info(cell_name, icon, image_data)) 576 { 577 GraphicBufferClass temp_gbuffer(24, 24); 578 GraphicViewPortClass temp_viewport(&temp_gbuffer, 0, 0, 24, 24); 579 580 WindowList[WINDOW_CUSTOM][WINDOWX] = 0; 581 WindowList[WINDOW_CUSTOM][WINDOWY] = 0; 582 WindowList[WINDOW_CUSTOM][WINDOWWIDTH] = 24; 583 WindowList[WINDOW_CUSTOM][WINDOWHEIGHT] = 24; 584 585 temp_viewport.Draw_Stamp(image_data, icon, 0, 0, NULL, WINDOW_CUSTOM); 586 587 out_width = temp_viewport.Get_Width(); 588 out_height = temp_viewport.Get_Height(); 589 590 const int COLOR_SIZE = 3; 591 592 SAFEARRAYBOUND Bound; 593 Bound.lLbound = 0; 594 Bound.cElements = out_width * out_height * COLOR_SIZE; 595 596 out_texture_array = SafeArrayCreate(VT_UI1, 1, &Bound); 597 598 unsigned char* out_buffer; 599 600 HRESULT hr = SafeArrayAccessData(out_texture_array, (void **)&out_buffer); 601 if (SUCCEEDED(hr)) 602 { 603 GraphicBufferClass* Graphic_Buffer = temp_viewport.Get_Graphic_Buffer(); 604 605 int VP_Scan_Line = temp_viewport.Get_Width() + temp_viewport.Get_XAdd(); 606 607 char * start_ptr; 608 start_ptr = (char *)Graphic_Buffer->Get_Buffer(); 609 start_ptr += ((temp_viewport.Get_YPos() * VP_Scan_Line) + temp_viewport.Get_XPos()); 610 611 for (int y = 0; y < out_height; ++y) 612 { 613 unsigned char* scanline_ptr = (unsigned char*)start_ptr + y * VP_Scan_Line; 614 unsigned char* out_buffer_y_ptr = out_buffer + (y * out_width * COLOR_SIZE); 615 for (int x = 0; x < out_width; ++x) 616 { 617 unsigned char* pallete_index_ptr = scanline_ptr + x; 618 unsigned char* out_buffer_ptr = out_buffer_y_ptr + (x * COLOR_SIZE); 619 620 int palette_index = (*pallete_index_ptr); 621 out_buffer_ptr[0] = ((unsigned char)GamePalette[palette_index].Red_Component()); 622 out_buffer_ptr[1] = ((unsigned char)GamePalette[palette_index].Green_Component()); 623 out_buffer_ptr[2] = ((unsigned char)GamePalette[palette_index].Blue_Component()); 624 } 625 } 626 627 SafeArrayUnaccessData(out_texture_array); 628 629 return EDITOR_COMMMAND_SUCCESS; 630 } 631 } 632 633 return EDITOR_COMMMAND_FAILURE; 634 } 635 636 /************************************************************************************************** 637 * CNC_Editor_Get_Template_Data 638 * Get the data from the given tile template type. 639 * 640 * template_type_index: The index of the template type to use. should come from the Get_Cell_Data function. 641 * template_positions: Out buffer to be filled with the list of positions of the tiles as offsets from the origin of the template. 642 * This data is store is an X, Y, X, Y, X, Y format. 643 * 644 * returns EDITOR_COMMMAND_SUCCESS on success, all other values are failure 645 **************************************************************************************************/ 646 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Template_Data(int template_type_index, SAFEARRAY*& template_points) 647 { 648 if (template_type_index >= TEMPLATE_COUNT || template_type_index == TEMPLATE_NONE) 649 { 650 return EDITOR_COMMMAND_FAILURE; 651 } 652 653 const TemplateTypeClass& template_type = TemplateTypeClass::As_Reference((TemplateType)template_type_index); 654 if (template_type.Get_Image_Data() == nullptr) 655 { 656 return EDITOR_COMMMAND_FAILURE; 657 } 658 659 660 short const * occupy_list = template_type.Occupy_List(); 661 662 short const * counter = occupy_list; 663 while (counter && *counter != REFRESH_EOL) 664 { 665 counter++; 666 } 667 668 int occupy_list_size = counter - occupy_list; 669 670 671 SAFEARRAYBOUND bounds; 672 bounds.lLbound = 0; 673 bounds.cElements = occupy_list_size * 2; 674 template_points = SafeArrayCreate(VT_I4, 1, &bounds); 675 676 int *pData; 677 HRESULT hr = SafeArrayAccessData(template_points, (void **)&pData); 678 if (SUCCEEDED(hr)) 679 { 680 for (int i = 0; i < occupy_list_size; i++) 681 { 682 CELL cell = occupy_list[i]; 683 684 int x = Cell_X(cell); 685 int y = Cell_Y(cell); 686 687 pData[i * 2] = x; 688 pData[i * 2 + 1] = y; 689 } 690 691 SafeArrayUnaccessData(template_points); 692 693 return EDITOR_COMMMAND_SUCCESS; 694 } 695 696 return EDITOR_COMMMAND_FAILURE; 697 } 698 699 extern "C" __declspec(dllexport) int __cdecl CNC_Editor_Get_Scenario_Names(char* cncdata_directory) 700 { 701 char content_directory[_MAX_PATH]; 702 703 CNC_Editor_Setup_Content_Directory(cncdata_directory,false, content_directory); 704 705 char command_line[_MAX_PATH]; 706 sprintf(command_line, "-CD%s", content_directory); 707 DLL_Startup(command_line); 708 709 char team_ids[] = 710 { 711 'a', 712 'b', 713 'c', 714 'd', 715 'e', 716 'f', 717 'g', 718 'h', 719 'i', 720 'j', 721 'k', 722 'l', 723 'm', 724 'n', 725 'o', 726 'p', 727 'q', 728 'r', 729 's', 730 't', 731 'u', 732 'v', 733 'w', 734 'x', 735 'y', 736 'z', 737 }; 738 /* 739 { 740 'g', 741 'a', 742 'u', 743 'm' 744 }; 745 */ 746 const int team_count = sizeof(team_ids) / sizeof(char); 747 748 char direction_ids[] = 749 { 750 'e', 751 'w', 752 }; 753 const int direction_count = sizeof(direction_ids) / sizeof(char); 754 755 char variant_ids[] = 756 { 757 'a', 758 'b', 759 'c', 760 'd', 761 'e', 762 'f', 763 'g', 764 'h', 765 'i', 766 'j', 767 'k', 768 'l', 769 'm', 770 'n', 771 'o', 772 'p', 773 'q', 774 'r', 775 's', 776 't', 777 'u', 778 'v', 779 'w', 780 'x', 781 'y', 782 'z', 783 }; 784 /* 785 { 786 'a', 787 'b', 788 'c', 789 'd' 790 }; 791 */ 792 const int variant_count = sizeof(variant_ids) / sizeof(char); 793 794 const int min_scenario_index = 1; 795 const int max_scenario_index = 99; 796 797 char scenario_name[_MAX_FNAME + _MAX_EXT]; 798 char file_name[_MAX_FNAME + _MAX_EXT]; 799 800 FILE * names_file = fopen("d:\\RA_Disk2.txt", "w+"); 801 802 for (int team_index = 0; team_index < team_count; team_index++) 803 { 804 for (int scenario_index = min_scenario_index; scenario_index <= max_scenario_index; ++scenario_index) 805 { 806 for (int direction_index = 0; direction_index < direction_count; direction_index++) 807 { 808 for (int variant_index = 0; variant_index < variant_count; variant_index++) 809 { 810 sprintf(scenario_name, "sc%c%.2d%c%c", 811 team_ids[team_index], 812 scenario_index, 813 direction_ids[direction_index], 814 variant_ids[variant_index]); 815 816 sprintf(file_name, "%s.INI", scenario_name); 817 CCFileClass file(file_name); 818 if (file.Is_Available()) 819 { 820 fprintf(names_file, "%s\n", scenario_name); 821 } 822 } 823 } 824 } 825 } 826 827 fclose(names_file); 828 829 return EDITOR_COMMMAND_SUCCESS; 830 }