CDefHandler.cpp 27 KB

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