CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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 }