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