CDefHandler.cpp 27 KB

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