DLLInterfaceEditor.cpp 21 KB

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