CDefHandler.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. #include "stdafx.h"
  2. #include "CDefHandler.h"
  3. #include "SDL_image.h"
  4. #include <sstream>
  5. long long pow(long long a, int b)
  6. {
  7. if (!b) return 1;
  8. long c = a;
  9. while (--b)
  10. a*=c;
  11. return a;
  12. }
  13. void BMPHeader::print(std::ostream & out)
  14. {
  15. CDefHandler::print(out,fullSize,4);
  16. CDefHandler::print(out,_h1,4);
  17. CDefHandler::print(out,_c1,4);
  18. CDefHandler::print(out,_c2,4);
  19. CDefHandler::print(out,x,4);
  20. CDefHandler::print(out,y,4);
  21. CDefHandler::print(out,_c3,2);
  22. CDefHandler::print(out,_c4,2);
  23. CDefHandler::print(out,_h2,4);
  24. CDefHandler::print(out,_h3,4);
  25. CDefHandler::print(out,dataSize1,4);
  26. CDefHandler::print(out,dataSize2,4);
  27. for (int i=0;i<8;i++)
  28. out << _c5[i];
  29. out.flush();
  30. }
  31. void CDefHandler::openDef(std::string name)
  32. {
  33. int i,j, totalInBlock;
  34. char Buffer[13];
  35. defName=name;
  36. int andame;
  37. std::ifstream * is = new std::ifstream();
  38. is -> open(name.c_str(),std::ios::binary);
  39. is->seekg(0,std::ios::end); // na koniec
  40. andame = is->tellg(); // read length
  41. is->seekg(0,std::ios::beg); // wracamy na poczatek
  42. FDef = new unsigned char[andame]; // allocate memory
  43. is->read((char*)FDef, andame); // read map file to buffer
  44. is->close();
  45. delete is;
  46. i = 0;
  47. DEFType = readNormalNr(i,4); i+=4;
  48. fullWidth = readNormalNr(i,4); i+=4;
  49. fullHeight = readNormalNr(i,4); i+=4;
  50. i=0xc;
  51. totalBlocks = readNormalNr(i,4); i+=4;
  52. i=0x10;
  53. for (int it=0;it<256;it++)
  54. {
  55. palette[it].R = FDef[i++];
  56. palette[it].G = FDef[i++];
  57. palette[it].B = FDef[i++];
  58. palette[it].F = 0;
  59. }
  60. i=0x310;
  61. totalEntries=0;
  62. for (int z=0; z<totalBlocks; z++)
  63. {
  64. i+=4;
  65. totalInBlock = readNormalNr(i,4); i+=4;
  66. for (j=SEntries.size(); j<totalEntries+totalInBlock; j++)
  67. SEntries.push_back(SEntry());
  68. i+=8;
  69. for (j=0; j<totalInBlock; j++)
  70. {
  71. for (int k=0;k<13;k++) Buffer[k]=FDef[i+k];
  72. i+=13;
  73. SEntries[totalEntries+j].name=Buffer;
  74. }
  75. for (j=0; j<totalInBlock; j++)
  76. {
  77. SEntries[totalEntries+j].offset = readNormalNr(i,4);
  78. i+=4;
  79. }
  80. //totalEntries+=totalInBlock;
  81. for(int hh=0; hh<totalInBlock; ++hh)
  82. {
  83. SEntries[totalEntries].group = z;
  84. ++totalEntries;
  85. }
  86. }
  87. for(j=0; j<SEntries.size(); ++j)
  88. {
  89. SEntries[j].name = SEntries[j].name.substr(0, SEntries[j].name.find('.')+4);
  90. }
  91. for(int i=0; i<SEntries.size(); ++i)
  92. {
  93. Cimage nimg;
  94. nimg.bitmap = getSprite(i);
  95. nimg.imName = SEntries[i].name;
  96. nimg.groupNumber = SEntries[i].group;
  97. ourImages.push_back(nimg);
  98. }
  99. }
  100. void CDefHandler::openFromMemory(unsigned char *table, int size, std::string name)
  101. {
  102. int i,j, totalInBlock;
  103. char Buffer[13];
  104. defName=name;
  105. /*int andame;
  106. std::ifstream * is = new std::ifstream();
  107. is -> open(name.c_str(),std::ios::binary);
  108. is->seekg(0,std::ios::end); // na koniec
  109. andame = is->tellg(); // read length
  110. is->seekg(0,std::ios::beg); // wracamy na poczatek
  111. FDef = new unsigned char[andame]; // allocate memory
  112. is->read((char*)FDef, andame); // read map file to buffer
  113. is->close();
  114. delete is;*/
  115. //FDef = new unsigned char[size]; // allocate memory
  116. while (!(FDef = (unsigned char *)malloc((sizeof(unsigned char))*size)));
  117. for (int i=0;i<size;i++)
  118. FDef[i]=table[i];
  119. int andame = size;
  120. i = 0;
  121. DEFType = readNormalNr(i,4); i+=4;
  122. fullWidth = readNormalNr(i,4); i+=4;
  123. fullHeight = readNormalNr(i,4); i+=4;
  124. i=0xc;
  125. totalBlocks = readNormalNr(i,4); i+=4;
  126. i=0x10;
  127. for (int it=0;it<256;it++)
  128. {
  129. palette[it].R = FDef[i++];
  130. palette[it].G = FDef[i++];
  131. palette[it].B = FDef[i++];
  132. palette[it].F = 0;
  133. }
  134. i=0x310;
  135. totalEntries=0;
  136. for (int z=0; z<totalBlocks; z++)
  137. {
  138. i+=4;
  139. totalInBlock = readNormalNr(i,4); i+=4;
  140. for (j=SEntries.size(); j<totalEntries+totalInBlock; j++)
  141. SEntries.push_back(SEntry());
  142. i+=8;
  143. for (j=0; j<totalInBlock; j++)
  144. {
  145. for (int k=0;k<13;k++) Buffer[k]=FDef[i+k];
  146. i+=13;
  147. SEntries[totalEntries+j].name=Buffer;
  148. }
  149. for (j=0; j<totalInBlock; j++)
  150. {
  151. SEntries[totalEntries+j].offset = readNormalNr(i,4);
  152. i+=4;
  153. }
  154. //totalEntries+=totalInBlock;
  155. for(int hh=0; hh<totalInBlock; ++hh)
  156. {
  157. SEntries[totalEntries].group = z;
  158. ++totalEntries;
  159. }
  160. }
  161. for(j=0; j<SEntries.size(); ++j)
  162. {
  163. SEntries[j].name = SEntries[j].name.substr(0, SEntries[j].name.find('.')+4);
  164. }
  165. for(int i=0; i<SEntries.size(); ++i)
  166. {
  167. Cimage nimg;
  168. nimg.bitmap = getSprite(i);
  169. nimg.imName = SEntries[i].name;
  170. nimg.groupNumber = SEntries[i].group;
  171. ourImages.push_back(nimg);
  172. }
  173. }
  174. unsigned char * CDefHandler::writeNormalNr (int nr, int bytCon)
  175. {
  176. //int tralalalatoniedziala = 2*9+100-4*bytCon;
  177. //unsigned char * ret = new unsigned char[bytCon];
  178. unsigned char * ret = NULL;
  179. for(int jj=0; jj<100; ++jj)
  180. {
  181. ret = (unsigned char*)calloc(1, bytCon);
  182. if(ret!=NULL)
  183. break;
  184. }
  185. long long amp = pow((float)256,bytCon-1);
  186. for (int i=bytCon-1; i>=0;i--)
  187. {
  188. int test2 = nr/(amp);
  189. ret[i]=test2;
  190. nr -= (nr/(amp))*amp;
  191. amp/=256;
  192. }
  193. return ret;
  194. }
  195. void CDefHandler::expand(unsigned char N,unsigned char & BL, unsigned char & BR)
  196. {
  197. BL = (N & 0xE0) >> 5;
  198. BR = N & 0x1F;
  199. }
  200. int CDefHandler::readNormalNr (int pos, int bytCon, unsigned char * str, bool cyclic)
  201. {
  202. int ret=0;
  203. int amp=1;
  204. if (str)
  205. {
  206. for (int i=0; i<bytCon; i++)
  207. {
  208. ret+=str[pos+i]*amp;
  209. amp*=256;
  210. }
  211. }
  212. else
  213. {
  214. for (int i=0; i<bytCon; i++)
  215. {
  216. ret+=FDef[pos+i]*amp;
  217. amp*=256;
  218. }
  219. }
  220. if(cyclic && bytCon<4 && ret>=amp/2)
  221. {
  222. ret = ret-amp;
  223. }
  224. return ret;
  225. }
  226. void CDefHandler::print (std::ostream & stream, int nr, int bytcon)
  227. {
  228. unsigned char * temp = writeNormalNr(nr,bytcon);
  229. for (int i=0;i<bytcon;i++)
  230. stream << char(temp[i]);
  231. free(temp);
  232. }
  233. SDL_Surface * CDefHandler::getSprite (int SIndex) //procedure GetSprite(SIndex: LongInt; var SOut: PStream);
  234. {
  235. SDL_Surface * ret;
  236. long BaseOffset,
  237. SpriteWidth, SpriteHeight, //format sprite'a
  238. LeftMargin, RightMargin, TopMargin,BottomMargin, //Отступы от края полного изображения
  239. i, add, FullHeight,FullWidth,
  240. TotalRowLength, // dlugosc przeczytanego segmentu
  241. NextSpriteOffset, RowAdd;
  242. std::ifstream Fdef;
  243. unsigned char SegmentType, SegmentLength, BL, BR;
  244. unsigned char * TempDef; //memory
  245. std::string FTemp;
  246. BaseOffset=SEntries[SIndex].offset;//Запоминаем начальное смещение спрайта
  247. i=BaseOffset+4;
  248. int defType2 = readNormalNr(i,4,FDef);i+=4;
  249. FullWidth = readNormalNr(i,4,FDef);i+=4;
  250. FullHeight = readNormalNr(i,4,FDef);i+=4;
  251. SpriteWidth = readNormalNr(i,4,FDef);i+=4;
  252. SpriteHeight = readNormalNr(i,4,FDef);i+=4;
  253. LeftMargin = readNormalNr(i,4,FDef);i+=4;
  254. TopMargin = readNormalNr(i,4,FDef);i+=4;
  255. RightMargin = FullWidth - SpriteWidth - LeftMargin;
  256. BottomMargin = FullHeight - SpriteHeight - TopMargin;
  257. BMPHeader tb;
  258. tb.x = FullWidth;
  259. tb.y = FullHeight;
  260. tb.dataSize2 = tb.dataSize1 = tb.x*tb.y;
  261. tb.fullSize = tb.dataSize1+436;
  262. tb._h3=tb.fullSize-36;
  263. add = (int)(4*(((float)1) - ((int)(((int)((float)FullWidth/(float)4))-((float)FullWidth/(float)4)))));
  264. /*if (add==4)
  265. add=0;*/ //moved to defcompression dependent block
  266. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  267. int rmask = 0xff000000;
  268. int gmask = 0x00ff0000;
  269. int bmask = 0x0000ff00;
  270. int amask = 0x000000ff;
  271. #else
  272. int rmask = 0x000000ff;
  273. int gmask = 0x0000ff00;
  274. int bmask = 0x00ff0000;
  275. int amask = 0xff000000;
  276. #endif
  277. ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, rmask, gmask, bmask, amask);
  278. //int tempee2 = readNormalNr(0,4,((unsigned char *)tempee.c_str()));
  279. int BaseOffsetor = BaseOffset = i;
  280. for(int i=0; i<256; ++i)
  281. {
  282. SDL_Color pr;
  283. pr.r = palette[i].R;
  284. pr.g = palette[i].G;
  285. pr.b = palette[i].B;
  286. pr.unused = palette[i].F;
  287. (*(ret->format->palette->colors+i))=pr;
  288. }
  289. for (int i=0;i<800;i++)
  290. fbuffer[i]=0;
  291. if (defType2==0)
  292. {
  293. if (add==4)
  294. add=0;
  295. if (TopMargin>0)
  296. {
  297. for (int i=0;i<TopMargin;i++)
  298. {
  299. for (int j=0;j<FullWidth+add;j++)
  300. FTemp+=fbuffer[j];
  301. }
  302. }
  303. for (int i=0;i<SpriteHeight;i++)
  304. {
  305. if (LeftMargin>0)
  306. {
  307. for (int j=0;j<LeftMargin;j++)
  308. FTemp+=fbuffer[j];
  309. }
  310. for (int j=0; j<SpriteWidth;j++)
  311. FTemp+=FDef[BaseOffset++];
  312. if (RightMargin>0)
  313. {
  314. for (int j=0;j<add;j++)
  315. FTemp+=fbuffer[j];
  316. }
  317. }
  318. if (BottomMargin>0)
  319. {
  320. for (int i=0;i<BottomMargin;i++)
  321. {
  322. for (int j=0;j<FullWidth+add;j++)
  323. FTemp+=fbuffer[j];
  324. }
  325. }
  326. }
  327. if (defType2==1)
  328. {
  329. if (add==4)
  330. add=2;
  331. if (TopMargin>0)
  332. {
  333. for (int i=0;i<TopMargin;i++)
  334. {
  335. for (int j=0;j<FullWidth+add;j++)
  336. FTemp+=fbuffer[j];
  337. }
  338. }
  339. RLEntries = new int[SpriteHeight];
  340. for (int i=0;i<SpriteHeight;i++)
  341. {
  342. RLEntries[i]=readNormalNr(BaseOffset,4,FDef);BaseOffset+=4;
  343. }
  344. for (int i=0;i<SpriteHeight;i++)
  345. {
  346. BaseOffset=BaseOffsetor+RLEntries[i];
  347. if (LeftMargin>0)
  348. {
  349. for (int j=0;j<LeftMargin;j++)
  350. FTemp+=fbuffer[j];
  351. }
  352. TotalRowLength=0;
  353. do
  354. {
  355. SegmentType=FDef[BaseOffset++];
  356. SegmentLength=FDef[BaseOffset++];
  357. if (SegmentType==0xFF)
  358. {
  359. for (int k=0;k<=SegmentLength;k++)
  360. {
  361. FTemp+=FDef[BaseOffset+k];
  362. if ((TotalRowLength+k+1)>=SpriteWidth)
  363. break;
  364. }
  365. TotalRowLength+=SegmentLength+1;
  366. }
  367. else
  368. {
  369. for (int k=0;k<SegmentLength+1;k++)
  370. {
  371. //FTemp+=FDef[BaseOffset+k];//
  372. FTemp+='\0';
  373. }
  374. TotalRowLength+=SegmentLength+1;
  375. }
  376. }while(TotalRowLength<SpriteWidth);
  377. RowAdd=SpriteWidth-TotalRowLength;
  378. if (RightMargin>0)
  379. {
  380. for (int j=0;j<RightMargin;j++)
  381. FTemp+=fbuffer[j];
  382. }
  383. if (add>0)
  384. {
  385. for (int j=0;j<add+RowAdd;j++)
  386. FTemp+=fbuffer[j];
  387. }
  388. }
  389. delete RLEntries;
  390. if (BottomMargin>0)
  391. {
  392. for (int i=0;i<BottomMargin;i++)
  393. {
  394. for (int j=0;j<FullWidth+add;j++)
  395. FTemp+=fbuffer[j];
  396. }
  397. }
  398. }
  399. if (defType2==3)
  400. {
  401. if (add==4)
  402. add=0;
  403. if (TopMargin>0)
  404. {
  405. for (int i=0;i<TopMargin;i++)
  406. {
  407. for (int j=0;j<FullWidth+add;j++)
  408. FTemp+=fbuffer[j];
  409. }
  410. }
  411. RWEntries = new unsigned int[SpriteHeight];
  412. for (int i=0;i<SpriteHeight;i++)
  413. {
  414. BaseOffset=BaseOffsetor+i*2*(SpriteWidth/32);
  415. RWEntries[i] = readNormalNr(BaseOffset,2,FDef);
  416. }
  417. for (int i=0;i<SpriteHeight;i++)
  418. {
  419. BaseOffset = BaseOffsetor+RWEntries[i];
  420. if (LeftMargin>0)
  421. {
  422. for (int j=0;j<LeftMargin;j++)
  423. FTemp+=fbuffer[j];
  424. }
  425. TotalRowLength=0;
  426. do
  427. {
  428. SegmentType=FDef[BaseOffset++];
  429. expand(SegmentType,BL,BR);
  430. if (BL==0) //transparent
  431. {
  432. for (int k=0;k<100;k++)
  433. fbuffer[k]='\0';
  434. for (int k=0;k<BR+1;k++)
  435. {
  436. FTemp+=fbuffer[k];
  437. }
  438. TotalRowLength=TotalRowLength+BR+1;
  439. }
  440. if (BL==1) //shadow
  441. {
  442. for (int k=0;k<100;k++)
  443. fbuffer[k]='\1';
  444. for (int k=0;k<BR+1;k++)
  445. {
  446. FTemp+=fbuffer[k];
  447. }
  448. TotalRowLength=TotalRowLength+BR+1;
  449. }
  450. if (BL==2) //shadow
  451. {
  452. for (int k=0;k<100;k++)
  453. fbuffer[k]='\2';
  454. for (int k=0;k<BR+1;k++)
  455. {
  456. FTemp+=fbuffer[k];
  457. }
  458. TotalRowLength=TotalRowLength+BR+1;
  459. }
  460. if (BL==3) //shadow
  461. {
  462. for (int k=0;k<100;k++)
  463. fbuffer[k]='\3';
  464. for (int k=0;k<BR+1;k++)
  465. {
  466. FTemp+=fbuffer[k];
  467. }
  468. TotalRowLength=TotalRowLength+BR+1;
  469. }
  470. if (BL==4) //shadow
  471. {
  472. for (int k=0;k<100;k++)
  473. fbuffer[k]='\4';
  474. for (int k=0;k<BR+1;k++)
  475. {
  476. FTemp+=fbuffer[k];
  477. }
  478. TotalRowLength=TotalRowLength+BR+1;
  479. }
  480. if (BL==5) //team colour?
  481. {
  482. for (int k=0;k<100;k++)
  483. fbuffer[k]='\5';
  484. for (int k=0;k<BR+1;k++)
  485. {
  486. FTemp+=fbuffer[k];
  487. }
  488. TotalRowLength=TotalRowLength+BR+1;
  489. }
  490. if (BL==7) //opaque
  491. {
  492. for (int k=0;k<BR+1;k++)
  493. {
  494. FTemp+=FDef[BaseOffset++];
  495. }
  496. TotalRowLength=TotalRowLength+BR+1;
  497. }
  498. }while(TotalRowLength<SpriteWidth);
  499. if (RightMargin>0)
  500. {
  501. for (int j=0;j<RightMargin;j++)
  502. FTemp+=fbuffer[j];
  503. }
  504. if (add>0)
  505. {
  506. for (int j=0;j<add+RowAdd;j++)
  507. FTemp+=fbuffer[j];
  508. }
  509. }
  510. delete RWEntries;
  511. if (BottomMargin>0)
  512. {
  513. for (int i=0;i<BottomMargin;i++)
  514. {
  515. for (int j=0;j<FullWidth+add;j++)
  516. FTemp+=fbuffer[j];
  517. }
  518. }
  519. }
  520. for (int i=0; i<FullHeight; ++i)
  521. {
  522. for (int j=0;j<FullWidth+add;j++)
  523. {
  524. *((char*)ret->pixels + ret->format->BytesPerPixel * (i*(fullWidth+add) + j)) = FTemp[i*(FullWidth+add)+j];
  525. }
  526. }
  527. return ret;
  528. };
  529. CDefEssential * CDefHandler::essentialize()
  530. {
  531. CDefEssential * ret = new CDefEssential;
  532. ret->ourImages = ourImages;
  533. return ret;
  534. }