CDefHandler.cpp 13 KB

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