CDefHandler.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  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. add = 4 - FullWidth%4;
  265. /*if (add==4)
  266. add=0;*/ //moved to defcompression dependent block
  267. #if SDL_BYTEORDER == SDL_BIG_ENDIAN
  268. int rmask = 0xff000000;
  269. int gmask = 0x00ff0000;
  270. int bmask = 0x0000ff00;
  271. int amask = 0x000000ff;
  272. #else
  273. int rmask = 0x000000ff;
  274. int gmask = 0x0000ff00;
  275. int bmask = 0x00ff0000;
  276. int amask = 0xff000000;
  277. #endif
  278. ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, 0, 0, 0, 0);
  279. //int tempee2 = readNormalNr(0,4,((unsigned char *)tempee.c_str()));
  280. int BaseOffsetor = BaseOffset = i;
  281. for(int i=0; i<256; ++i)
  282. {
  283. SDL_Color pr;
  284. pr.r = palette[i].R;
  285. pr.g = palette[i].G;
  286. pr.b = palette[i].B;
  287. pr.unused = palette[i].F;
  288. (*(ret->format->palette->colors+i))=pr;
  289. }
  290. for (int i=0;i<800;i++)
  291. fbuffer[i]=0;
  292. if (defType2==0)
  293. {
  294. if (add==4)
  295. add=0;
  296. if (TopMargin>0)
  297. {
  298. for (int i=0;i<TopMargin;i++)
  299. {
  300. for (int j=0;j<FullWidth+add;j++)
  301. FTemp+=fbuffer[j];
  302. }
  303. }
  304. for (int i=0;i<SpriteHeight;i++)
  305. {
  306. if (LeftMargin>0)
  307. {
  308. for (int j=0;j<LeftMargin;j++)
  309. FTemp+=fbuffer[j];
  310. }
  311. for (int j=0; j<SpriteWidth;j++)
  312. FTemp+=FDef[BaseOffset++];
  313. if (RightMargin>0)
  314. {
  315. for (int j=0;j<add;j++)
  316. FTemp+=fbuffer[j];
  317. }
  318. }
  319. if (BottomMargin>0)
  320. {
  321. for (int i=0;i<BottomMargin;i++)
  322. {
  323. for (int j=0;j<FullWidth+add;j++)
  324. FTemp+=fbuffer[j];
  325. }
  326. }
  327. }
  328. if (defType2==1)
  329. {
  330. if (add==4)
  331. add=0; ////////was 3
  332. if (TopMargin>0)
  333. {
  334. for (int i=0;i<TopMargin;i++)
  335. {
  336. for (int j=0;j<FullWidth+add;j++)
  337. FTemp+=fbuffer[j];
  338. }
  339. }
  340. RLEntries = new int[SpriteHeight];
  341. for (int i=0;i<SpriteHeight;i++)
  342. {
  343. RLEntries[i]=readNormalNr(BaseOffset,4,FDef);BaseOffset+=4;
  344. }
  345. for (int i=0;i<SpriteHeight;i++)
  346. {
  347. BaseOffset=BaseOffsetor+RLEntries[i];
  348. if (LeftMargin>0)
  349. {
  350. for (int j=0;j<LeftMargin;j++)
  351. FTemp+=fbuffer[j];
  352. }
  353. TotalRowLength=0;
  354. do
  355. {
  356. SegmentType=FDef[BaseOffset++];
  357. SegmentLength=FDef[BaseOffset++];
  358. if (SegmentType==0xFF)
  359. {
  360. for (int k=0;k<=SegmentLength;k++)
  361. {
  362. FTemp+=FDef[BaseOffset+k];
  363. if ((TotalRowLength+k+1)>=SpriteWidth)
  364. break;
  365. }
  366. BaseOffset+=SegmentLength+1;////
  367. TotalRowLength+=SegmentLength+1;
  368. }
  369. else
  370. {
  371. for (int k=0;k<SegmentLength+1;k++)
  372. {
  373. FTemp+=fbuffer[k];//
  374. //FTemp+='\0';
  375. }
  376. TotalRowLength+=SegmentLength+1;
  377. }
  378. }while(TotalRowLength<SpriteWidth);
  379. RowAdd=SpriteWidth-TotalRowLength;
  380. if (RightMargin>0)
  381. {
  382. for (int j=0;j<RightMargin;j++)
  383. FTemp+=fbuffer[j];
  384. }
  385. if (add>0)
  386. {
  387. for (int j=0;j<add+RowAdd;j++)
  388. FTemp+=fbuffer[j];
  389. }
  390. }
  391. delete RLEntries;
  392. if (BottomMargin>0)
  393. {
  394. for (int i=0;i<BottomMargin;i++)
  395. {
  396. for (int j=0;j<FullWidth+add;j++)
  397. FTemp+=fbuffer[j];
  398. }
  399. }
  400. }
  401. if (defType2==3)
  402. {
  403. if (add==4)
  404. add=0;
  405. if (TopMargin>0)
  406. {
  407. for (int i=0;i<TopMargin;i++)
  408. {
  409. for (int j=0;j<FullWidth+add;j++)
  410. FTemp+=fbuffer[j];
  411. }
  412. }
  413. RWEntries = new unsigned int[SpriteHeight];
  414. for (int i=0;i<SpriteHeight;i++)
  415. {
  416. BaseOffset=BaseOffsetor+i*2*(SpriteWidth/32);
  417. RWEntries[i] = readNormalNr(BaseOffset,2,FDef);
  418. }
  419. for (int i=0;i<SpriteHeight;i++)
  420. {
  421. BaseOffset = BaseOffsetor+RWEntries[i];
  422. if (LeftMargin>0)
  423. {
  424. for (int j=0;j<LeftMargin;j++)
  425. FTemp+=fbuffer[j];
  426. }
  427. TotalRowLength=0;
  428. do
  429. {
  430. SegmentType=FDef[BaseOffset++];
  431. expand(SegmentType,BL,BR);
  432. if (BL==0) //transparent
  433. {
  434. for (int k=0;k<100;k++)
  435. fbuffer[k]='\0';
  436. for (int k=0;k<BR+1;k++)
  437. {
  438. FTemp+=fbuffer[k];
  439. }
  440. TotalRowLength=TotalRowLength+BR+1;
  441. }
  442. if (BL==1) //shadow
  443. {
  444. for (int k=0;k<100;k++)
  445. fbuffer[k]='\1';
  446. for (int k=0;k<BR+1;k++)
  447. {
  448. FTemp+=fbuffer[k];
  449. }
  450. TotalRowLength=TotalRowLength+BR+1;
  451. }
  452. if (BL==2) //shadow
  453. {
  454. for (int k=0;k<100;k++)
  455. fbuffer[k]='\2';
  456. for (int k=0;k<BR+1;k++)
  457. {
  458. FTemp+=fbuffer[k];
  459. }
  460. TotalRowLength=TotalRowLength+BR+1;
  461. }
  462. if (BL==3) //shadow
  463. {
  464. for (int k=0;k<100;k++)
  465. fbuffer[k]='\3';
  466. for (int k=0;k<BR+1;k++)
  467. {
  468. FTemp+=fbuffer[k];
  469. }
  470. TotalRowLength=TotalRowLength+BR+1;
  471. }
  472. if (BL==4) //shadow
  473. {
  474. for (int k=0;k<100;k++)
  475. fbuffer[k]='\4';
  476. for (int k=0;k<BR+1;k++)
  477. {
  478. FTemp+=fbuffer[k];
  479. }
  480. TotalRowLength=TotalRowLength+BR+1;
  481. }
  482. if (BL==5) //team colour?
  483. {
  484. for (int k=0;k<100;k++)
  485. fbuffer[k]='\5';
  486. for (int k=0;k<BR+1;k++)
  487. {
  488. FTemp+=fbuffer[k];
  489. }
  490. TotalRowLength=TotalRowLength+BR+1;
  491. }
  492. if (BL==7) //opaque
  493. {
  494. for (int k=0;k<BR+1;k++)
  495. {
  496. FTemp+=FDef[BaseOffset++];
  497. }
  498. TotalRowLength=TotalRowLength+BR+1;
  499. }
  500. }while(TotalRowLength<SpriteWidth);
  501. if (RightMargin>0)
  502. {
  503. for (int j=0;j<RightMargin;j++)
  504. FTemp+=fbuffer[j];
  505. }
  506. if (add>0)
  507. {
  508. for (int j=0;j<add+RowAdd;j++)
  509. FTemp+=fbuffer[j];
  510. }
  511. }
  512. delete RWEntries;
  513. if (BottomMargin>0)
  514. {
  515. for (int i=0;i<BottomMargin;i++)
  516. {
  517. for (int j=0;j<FullWidth+add;j++)
  518. FTemp+=fbuffer[j];
  519. }
  520. }
  521. }
  522. for (int i=0; i<FullHeight; ++i)
  523. {
  524. for (int j=0;j<FullWidth+add;j++)
  525. {
  526. *((char*)ret->pixels + ret->format->BytesPerPixel * (i*(fullWidth+add) + j)) = FTemp[i*(FullWidth+add)+j];
  527. }
  528. }
  529. SDL_Color ttcol = ret->format->palette->colors[0];
  530. Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
  531. SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
  532. return ret;
  533. };
  534. CDefEssential * CDefHandler::essentialize()
  535. {
  536. CDefEssential * ret = new CDefEssential;
  537. ret->ourImages = ourImages;
  538. return ret;
  539. }