CDefHandler.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  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. notFreeImgs = false;
  20. }
  21. CDefHandler::~CDefHandler()
  22. {
  23. //if (FDef)
  24. //delete [] FDef;
  25. if (RWEntries)
  26. delete [] RWEntries;
  27. if (notFreeImgs)
  28. return;
  29. for (int i=0; i<ourImages.size(); i++)
  30. {
  31. if (ourImages[i].bitmap)
  32. {
  33. SDL_FreeSurface(ourImages[i].bitmap);
  34. ourImages[i].bitmap=NULL;
  35. }
  36. }
  37. }
  38. CDefEssential::~CDefEssential()
  39. {
  40. for(int i=0;i<ourImages.size();i++)
  41. SDL_FreeSurface(ourImages[i].bitmap);
  42. }
  43. void CDefHandler::openDef(std::string name)
  44. {
  45. int i,j, totalInBlock;
  46. char Buffer[13];
  47. BMPPalette palette[256];
  48. defName=name;
  49. int andame;
  50. std::ifstream * is = new std::ifstream();
  51. is -> open(name.c_str(),std::ios::binary);
  52. is->seekg(0,std::ios::end); // na koniec
  53. andame = is->tellg(); // read length
  54. is->seekg(0,std::ios::beg); // wracamy na poczatek
  55. unsigned char * FDef = new unsigned char[andame]; // allocate memory
  56. is->read((char*)FDef, andame); // read map file to buffer
  57. is->close();
  58. delete is;
  59. i = 0;
  60. DEFType = readNormalNr(i,4,FDef); i+=4;
  61. fullWidth = readNormalNr(i,4,FDef); i+=4;
  62. fullHeight = readNormalNr(i,4,FDef); i+=4;
  63. i=0xc;
  64. totalBlocks = readNormalNr(i,4,FDef); i+=4;
  65. i=0x10;
  66. for (int it=0;it<256;it++)
  67. {
  68. palette[it].R = FDef[i++];
  69. palette[it].G = FDef[i++];
  70. palette[it].B = FDef[i++];
  71. palette[it].F = 0;
  72. }
  73. i=0x310;
  74. totalEntries=0;
  75. for (int z=0; z<totalBlocks; z++)
  76. {
  77. i+=4;
  78. totalInBlock = readNormalNr(i,4,FDef); i+=4;
  79. for (j=SEntries.size(); j<totalEntries+totalInBlock; j++)
  80. SEntries.push_back(SEntry());
  81. i+=8;
  82. for (j=0; j<totalInBlock; j++)
  83. {
  84. for (int k=0;k<13;k++) Buffer[k]=FDef[i+k];
  85. i+=13;
  86. SEntries[totalEntries+j].name=Buffer;
  87. }
  88. for (j=0; j<totalInBlock; j++)
  89. {
  90. SEntries[totalEntries+j].offset = readNormalNr(i,4,FDef);
  91. i+=4;
  92. }
  93. //totalEntries+=totalInBlock;
  94. for(int hh=0; hh<totalInBlock; ++hh)
  95. {
  96. SEntries[totalEntries].group = z;
  97. ++totalEntries;
  98. }
  99. }
  100. for(j=0; j<SEntries.size(); ++j)
  101. {
  102. SEntries[j].name = SEntries[j].name.substr(0, SEntries[j].name.find('.')+4);
  103. }
  104. for(int i=0; i<SEntries.size(); ++i)
  105. {
  106. Cimage nimg;
  107. nimg.bitmap = getSprite(i, FDef, palette);
  108. nimg.imName = SEntries[i].name;
  109. nimg.groupNumber = SEntries[i].group;
  110. ourImages.push_back(nimg);
  111. }
  112. delete [] FDef;
  113. FDef = NULL;
  114. }
  115. void CDefHandler::openFromMemory(unsigned char *table, std::string name)
  116. {
  117. int i,j, totalInBlock;
  118. char Buffer[13];
  119. BMPPalette palette[256];
  120. defName=name;
  121. i = 0;
  122. DEFType = readNormalNr(i,4,table); i+=4;
  123. fullWidth = readNormalNr(i,4,table); i+=4;
  124. fullHeight = readNormalNr(i,4,table); i+=4;
  125. i=0xc;
  126. totalBlocks = readNormalNr(i,4,table); i+=4;
  127. i=0x10;
  128. for (int it=0;it<256;it++)
  129. {
  130. palette[it].R = table[i++];
  131. palette[it].G = table[i++];
  132. palette[it].B = table[i++];
  133. palette[it].F = 0;
  134. }
  135. i=0x310;
  136. totalEntries=0;
  137. for (int z=0; z<totalBlocks; z++)
  138. {
  139. int unknown1 = readNormalNr(i,4,table); i+=4;
  140. totalInBlock = readNormalNr(i,4,table); i+=4;
  141. for (j=SEntries.size(); j<totalEntries+totalInBlock; j++)
  142. SEntries.push_back(SEntry());
  143. int unknown2 = readNormalNr(i,4,table); i+=4;
  144. int unknown3 = readNormalNr(i,4,table); i+=4;
  145. for (j=0; j<totalInBlock; j++)
  146. {
  147. for (int k=0;k<13;k++) Buffer[k]=table[i+k];
  148. i+=13;
  149. SEntries[totalEntries+j].name=Buffer;
  150. }
  151. for (j=0; j<totalInBlock; j++)
  152. {
  153. SEntries[totalEntries+j].offset = readNormalNr(i,4,table);
  154. int unknown4 = readNormalNr(i,4,table); i+=4;
  155. }
  156. //totalEntries+=totalInBlock;
  157. for(int hh=0; hh<totalInBlock; ++hh)
  158. {
  159. SEntries[totalEntries].group = z;
  160. ++totalEntries;
  161. }
  162. }
  163. for(j=0; j<SEntries.size(); ++j)
  164. {
  165. SEntries[j].name = SEntries[j].name.substr(0, SEntries[j].name.find('.')+4);
  166. }
  167. RWEntries = new unsigned int[fullHeight];
  168. for(int i=0; i<SEntries.size(); ++i)
  169. {
  170. Cimage nimg;
  171. nimg.bitmap = getSprite(i, table, palette);
  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((long long int)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, BMPPalette * palette)
  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. for (int i=0;i<SpriteHeight;i++)
  324. {
  325. RWEntries[i]=readNormalNr(BaseOffset,4,FDef);BaseOffset+=4;
  326. }
  327. for (int i=0;i<SpriteHeight;i++)
  328. {
  329. BaseOffset=BaseOffsetor+RWEntries[i];
  330. if (LeftMargin>0)
  331. {
  332. for (int j=0;j<LeftMargin;j++)
  333. ((char*)(ret->pixels))[ftcp++]='\0';
  334. }
  335. TotalRowLength=0;
  336. do
  337. {
  338. SegmentType=FDef[BaseOffset++];
  339. SegmentLength=FDef[BaseOffset++];
  340. if (SegmentType==0xFF)
  341. {
  342. for (int k=0;k<=SegmentLength;k++)
  343. {
  344. ((char*)(ret->pixels))[ftcp++]=FDef[BaseOffset+k];
  345. if ((TotalRowLength+k+1)>=SpriteWidth)
  346. break;
  347. }
  348. BaseOffset+=SegmentLength+1;////
  349. TotalRowLength+=SegmentLength+1;
  350. }
  351. else
  352. {
  353. for (int k=0;k<SegmentLength+1;k++)
  354. {
  355. ((char*)(ret->pixels))[ftcp++]=SegmentType;//
  356. //((char*)(ret->pixels))+='\0';
  357. }
  358. TotalRowLength+=SegmentLength+1;
  359. }
  360. }while(TotalRowLength<SpriteWidth);
  361. RowAdd=SpriteWidth-TotalRowLength;
  362. if (RightMargin>0)
  363. {
  364. for (int j=0;j<RightMargin;j++)
  365. ((char*)(ret->pixels))[ftcp++]='\0';
  366. }
  367. if (add>0)
  368. {
  369. for (int j=0;j<add+RowAdd;j++)
  370. ((char*)(ret->pixels))[ftcp++]='\0';
  371. }
  372. }
  373. if (BottomMargin>0)
  374. {
  375. for (int i=0;i<BottomMargin;i++)
  376. {
  377. for (int j=0;j<FullWidth+add;j++)
  378. ((char*)(ret->pixels))[ftcp++]='\0';
  379. }
  380. }
  381. }
  382. if (defType2==2)
  383. {
  384. if (TopMargin>0)
  385. {
  386. for (int i=0;i<TopMargin;i++)
  387. {
  388. for (int j=0;j<FullWidth+add;j++)
  389. ((char*)(ret->pixels))[ftcp++]='\0';
  390. }
  391. }
  392. for (int i=0;i<SpriteHeight;i++)
  393. {
  394. BaseOffset=BaseOffsetor+i*2*(SpriteWidth/32);
  395. RWEntries[i] = readNormalNr(BaseOffset,2,FDef);
  396. }
  397. BaseOffset = BaseOffsetor+RWEntries[0];
  398. for (int i=0;i<SpriteHeight;i++)
  399. {
  400. //BaseOffset = BaseOffsetor+RWEntries[i];
  401. if (LeftMargin>0)
  402. {
  403. for (int j=0;j<LeftMargin;j++)
  404. ((char*)(ret->pixels))[ftcp++]='\0';
  405. }
  406. TotalRowLength=0;
  407. do
  408. {
  409. SegmentType=FDef[BaseOffset++];
  410. unsigned char code = SegmentType / 32;
  411. unsigned char value = (SegmentType & 31) + 1;
  412. if(code==7)
  413. {
  414. for(int h=0; h<value; ++h)
  415. {
  416. ((char*)(ret->pixels))[ftcp++]=FDef[BaseOffset++];
  417. }
  418. }
  419. else
  420. {
  421. for(int h=0; h<value; ++h)
  422. {
  423. ((char*)(ret->pixels))[ftcp++]=code;
  424. }
  425. }
  426. TotalRowLength+=value;
  427. } while(TotalRowLength<SpriteWidth);
  428. if (RightMargin>0)
  429. {
  430. for (int j=0;j<RightMargin;j++)
  431. ((char*)(ret->pixels))[ftcp++]='\0';
  432. }
  433. if (add>0)
  434. {
  435. for (int j=0;j<add+RowAdd;j++)
  436. ((char*)(ret->pixels))[ftcp++]='\0';
  437. }
  438. }
  439. if (BottomMargin>0)
  440. {
  441. for (int i=0;i<BottomMargin;i++)
  442. {
  443. for (int j=0;j<FullWidth+add;j++)
  444. ((char*)(ret->pixels))[ftcp++]='\0';
  445. }
  446. }
  447. }
  448. if (defType2==3)
  449. {
  450. if (add==4)
  451. add=0;
  452. if (TopMargin>0)
  453. {
  454. for (int i=0;i<TopMargin;i++)
  455. {
  456. for (int j=0;j<FullWidth+add;j++)
  457. ((char*)(ret->pixels))[ftcp++]='\0';
  458. }
  459. }
  460. for (int i=0;i<SpriteHeight;i++)
  461. {
  462. BaseOffset=BaseOffsetor+i*2*(SpriteWidth/32);
  463. RWEntries[i] = readNormalNr(BaseOffset,2,FDef);
  464. }
  465. for (int i=0;i<SpriteHeight;i++)
  466. {
  467. BaseOffset = BaseOffsetor+RWEntries[i];
  468. if (LeftMargin>0)
  469. {
  470. for (int j=0;j<LeftMargin;j++)
  471. ((char*)(ret->pixels))[ftcp++]='\0';
  472. }
  473. TotalRowLength=0;
  474. do
  475. {
  476. SegmentType=FDef[BaseOffset++];
  477. unsigned char code = SegmentType / 32;
  478. unsigned char value = (SegmentType & 31) + 1;
  479. if(code==7)
  480. {
  481. for(int h=0; h<value; ++h)
  482. {
  483. if(h<-LeftMargin)
  484. continue;
  485. if(h+TotalRowLength>=SpriteWidth)
  486. break;
  487. ((char*)(ret->pixels))[ftcp++]=FDef[BaseOffset++];
  488. }
  489. }
  490. else
  491. {
  492. for(int h=0; h<value; ++h)
  493. {
  494. if(h<-LeftMargin)
  495. continue;
  496. if(h+TotalRowLength>=SpriteWidth)
  497. break;
  498. ((char*)(ret->pixels))[ftcp++]=code;
  499. }
  500. }
  501. TotalRowLength+=( LeftMargin>=0 ? value : value+LeftMargin );
  502. }while(TotalRowLength<SpriteWidth);
  503. if (RightMargin>0)
  504. {
  505. for (int j=0;j<RightMargin;j++)
  506. ((char*)(ret->pixels))[ftcp++]='\0';
  507. }
  508. if (add>0)
  509. {
  510. for (int j=0;j<add+RowAdd;j++)
  511. ((char*)(ret->pixels))[ftcp++]='\0';
  512. }
  513. }
  514. if (BottomMargin>0)
  515. {
  516. for (int i=0;i<BottomMargin;i++)
  517. {
  518. for (int j=0;j<FullWidth+add;j++)
  519. ((char*)(ret->pixels))[ftcp++]='\0';
  520. }
  521. }
  522. }
  523. SDL_Color ttcol = ret->format->palette->colors[0];
  524. Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
  525. SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
  526. return ret;
  527. };
  528. CDefEssential * CDefHandler::essentialize()
  529. {
  530. CDefEssential * ret = new CDefEssential;
  531. ret->ourImages = ourImages;
  532. notFreeImgs = true;
  533. return ret;
  534. }
  535. CDefHandler * CDefHandler::giveDef(std::string defName, CLodHandler * spriteh)
  536. {
  537. if(!spriteh) spriteh=Spriteh;
  538. unsigned char * data = spriteh->giveFile(defName);
  539. if(!data)
  540. throw "bad def name!";
  541. CDefHandler * nh = new CDefHandler();
  542. nh->openFromMemory(data, defName);
  543. nh->alphaTransformed = false;
  544. delete [] data;
  545. return nh;
  546. }
  547. CDefEssential * CDefHandler::giveDefEss(std::string defName, CLodHandler * spriteh)
  548. {
  549. CDefEssential * ret;
  550. CDefHandler * temp = giveDef(defName,spriteh);
  551. ret = temp->essentialize();
  552. delete temp;
  553. return ret;
  554. }