OROCKRES.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. // Filename : OROCKRES.CPP
  21. // Description : rock resource
  22. // Owner : Gilbert
  23. #include <OROCKRES.h>
  24. #include <OGAMESET.h>
  25. #include <OMISC.h>
  26. #include <OWORLD.h>
  27. #include <OVGABUF.h>
  28. #include <OTERRAIN.h>
  29. #include <OCONFIG.h>
  30. #include <string.h>
  31. // ---------- Define constant ------------//
  32. //#define ROCK_DB "ROCK"
  33. //#define ROCK_BLOCK_DB "ROCKBLK"
  34. //#define ROCK_BITMAP_DB "ROCKBMP"
  35. //#define ROCK_ANIM_DB "ROCKANIM"
  36. // one rock is composed of one or many rock blocks
  37. // each rock block has one or many frames
  38. // each rock has its own animation sequence
  39. // any animation sequence can change to one of the two sequences
  40. // ------------ begin of function RockRes::RockRes -----------//
  41. RockRes::RockRes()
  42. {
  43. init_flag = 0;
  44. rock_info_count = 0;
  45. rock_info_array = NULL;
  46. rock_block_count = 0;
  47. rock_block_array = NULL;
  48. rock_bitmap_count = 0;
  49. rock_bitmap_array = NULL;
  50. rock_anim_count = 0;
  51. rock_anim_array = NULL;
  52. }
  53. // ------------ end of function RockRes::RockRes -----------//
  54. // ------------ begin of function RockRes::~RockRes -----------//
  55. RockRes::~RockRes()
  56. {
  57. deinit();
  58. }
  59. // ------------ end of function RockRes::~RockRes -----------//
  60. // ------------ begin of function RockRes::init -----------//
  61. void RockRes::init()
  62. {
  63. deinit();
  64. //----- open rock bitmap resource file -------//
  65. String str;
  66. str = DIR_RES;
  67. // str += "I_ROCK.RES";
  68. str += "I_ROCK";
  69. str += config.terrain_set;
  70. str += ".RES";
  71. res_bitmap.init_imported(str,1); // 1-read all into buffer
  72. //------- load database information --------//
  73. load_info();
  74. load_bitmap_info();
  75. load_block_info();
  76. load_anim_info();
  77. //----------------------------------------//
  78. init_flag=1;
  79. }
  80. // ------------ end of function RockRes::init -----------//
  81. // ------------ begin of function RockRes::deinit -----------//
  82. void RockRes::deinit()
  83. {
  84. if(init_flag)
  85. {
  86. mem_del(rock_info_array);
  87. mem_del(rock_block_array);
  88. mem_del(rock_bitmap_array);
  89. mem_del(rock_anim_array);
  90. rock_info_count = 0;
  91. rock_block_count = 0;
  92. rock_bitmap_count = 0;
  93. rock_anim_count = 0;
  94. res_bitmap.deinit();
  95. init_flag = 0;
  96. }
  97. }
  98. // ------------ end of function RockRes::deinit -----------//
  99. // ------------ begin of function RockRes::load_info -----------//
  100. void RockRes::load_info()
  101. {
  102. RockRec *rockRec;
  103. RockInfo *rockInfo;
  104. int i;
  105. //---- read in rock count and initialize rock info array ----//
  106. String rockDbName;
  107. rockDbName = DIR_RES;
  108. rockDbName += "ROCK";
  109. rockDbName += config.terrain_set;
  110. rockDbName += ".RES";
  111. Database rockDbObj(rockDbName, 1);
  112. //Database *dbRock = game_set.open_db(ROCK_DB); // only one database can be opened at a time, so we read ROCK.DBF first
  113. Database *dbRock = &rockDbObj;
  114. rock_info_count = (short) dbRock->rec_count();
  115. rock_info_array = (RockInfo*) mem_add( sizeof(RockInfo)*rock_info_count );
  116. memset( rock_info_array, 0, sizeof(RockInfo) * rock_info_count );
  117. //---------- read in ROCK.DBF ---------//
  118. for( i=0 ; i<rock_info_count ; i++ )
  119. {
  120. rockRec = (RockRec*) dbRock->read(i+1);
  121. rockInfo = rock_info_array+i;
  122. m.rtrim_fld( rockInfo->rock_name, rockRec->rock_id, rockRec->ROCKID_LEN );
  123. rockInfo->rock_type = rockRec->rock_type;
  124. rockInfo->loc_width = m.atoi(rockRec->loc_width, rockRec->LOC_LEN);
  125. rockInfo->loc_height = m.atoi(rockRec->loc_height, rockRec->LOC_LEN);
  126. // ###### begin Gilbert 2/5 ##########//
  127. if( rockRec->terrain_1 == 0 || rockRec->terrain_1 == ' ')
  128. rockInfo->terrain_1 = 0;
  129. else
  130. rockInfo->terrain_1 = TerrainRes::terrain_code(rockRec->terrain_1);
  131. if( rockRec->terrain_2 == 0 || rockRec->terrain_2 == ' ')
  132. rockInfo->terrain_2 = 0;
  133. else
  134. rockInfo->terrain_2 = TerrainRes::terrain_code(rockRec->terrain_2);
  135. // ###### end Gilbert 2/5 ##########//
  136. rockInfo->first_anim_recno = m.atoi(rockRec->first_anim_recno, rockRec->RECNO_LEN);
  137. if(rockInfo->first_anim_recno)
  138. rockInfo->max_frame = m.atoi(rockRec->max_frame, rockRec->MAX_FRAME_LEN);
  139. else
  140. rockInfo->max_frame = 1; // unanimated, rock anim recno must be -1
  141. rockInfo->first_block_recno = 0;
  142. }
  143. }
  144. // ------------ end of function RockRes::load_info -----------//
  145. // ------------ begin of function RockRes::load_bitmap_info -----------//
  146. void RockRes::load_bitmap_info()
  147. {
  148. RockBitmapRec *rockBitmapRec;
  149. RockBitmapInfo *rockBitmapInfo;
  150. int i;
  151. //---- read in rock count and initialize rock info array ----//
  152. String rockDbName;
  153. rockDbName = DIR_RES;
  154. rockDbName += "ROCKBMP";
  155. rockDbName += config.terrain_set;
  156. rockDbName += ".RES";
  157. Database rockDbObj(rockDbName, 1);
  158. // Database *dbRock = game_set.open_db(ROCK_BITMAP_DB); // only one database can be opened at a time, so we read ROCK.DBF first
  159. Database *dbRock = &rockDbObj;
  160. rock_bitmap_count = (short) dbRock->rec_count();
  161. rock_bitmap_array = (RockBitmapInfo*) mem_add( sizeof(RockBitmapInfo)*rock_bitmap_count );
  162. memset( rock_bitmap_array, 0, sizeof(RockBitmapInfo) * rock_bitmap_count );
  163. //---------- read in ROCKBMP.DBF ---------//
  164. for( i=0 ; i<rock_bitmap_count ; i++ )
  165. {
  166. rockBitmapRec = (RockBitmapRec*) dbRock->read(i+1);
  167. rockBitmapInfo = rock_bitmap_array+i;
  168. rockBitmapInfo->loc_x = m.atoi(rockBitmapRec->loc_x, rockBitmapRec->LOC_LEN);
  169. rockBitmapInfo->loc_y = m.atoi(rockBitmapRec->loc_y, rockBitmapRec->LOC_LEN);
  170. rockBitmapInfo->frame = m.atoi(rockBitmapRec->frame, rockBitmapRec->FRAME_NO_LEN);
  171. long bitmapOffset;
  172. memcpy( &bitmapOffset, rockBitmapRec->bitmap_ptr, sizeof(long) );
  173. rockBitmapInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
  174. }
  175. }
  176. // ------------ end of function RockRes::load_bitmap_info -----------//
  177. // ------------ begin of function RockRes::load_block_info -----------//
  178. void RockRes::load_block_info()
  179. {
  180. RockBlockRec *rockBlockRec;
  181. RockBlockInfo *rockBlockInfo;
  182. int i;
  183. //---- read in rock count and initialize rock info array ----//
  184. String rockDbName;
  185. rockDbName = DIR_RES;
  186. rockDbName += "ROCKBLK";
  187. rockDbName += config.terrain_set;
  188. rockDbName += ".RES";
  189. Database rockDbObj(rockDbName, 1);
  190. // Database *dbRock = game_set.open_db(ROCK_BLOCK_DB); // only one database can be opened at a time, so we read ROCK.DBF first
  191. Database *dbRock = &rockDbObj;
  192. rock_block_count = (short) dbRock->rec_count();
  193. rock_block_array = (RockBlockInfo*) mem_add( sizeof(RockBlockInfo)*rock_block_count );
  194. memset( rock_block_array, 0, sizeof(RockBlockInfo) * rock_block_count );
  195. //---------- read in ROCKBLK.DBF ---------//
  196. for( i=0 ; i<rock_block_count ; i++ )
  197. {
  198. rockBlockRec = (RockBlockRec*) dbRock->read(i+1);
  199. rockBlockInfo = rock_block_array+i;
  200. rockBlockInfo->loc_x = m.atoi(rockBlockRec->loc_x, rockBlockRec->LOC_LEN);
  201. rockBlockInfo->loc_y = m.atoi(rockBlockRec->loc_y, rockBlockRec->LOC_LEN);
  202. rockBlockInfo->rock_recno = m.atoi(rockBlockRec->rock_recno, rockBlockRec->RECNO_LEN);
  203. rockBlockInfo->first_bitmap = m.atoi(rockBlockRec->first_bitmap, rockBlockRec->RECNO_LEN);
  204. // ------- validate rock_recno --------//
  205. err_when( rockBlockInfo->rock_recno <= 0 || rockBlockInfo->rock_recno > rock_info_count);
  206. RockInfo* rockInfo = rock_info_array+rockBlockInfo->rock_recno-1;
  207. err_when( strncmp(rockBlockRec->rock_id, rockInfo->rock_name, strlen(rockInfo->rock_name)));
  208. if(rockInfo->first_block_recno == 0)
  209. rockInfo->first_block_recno = i + 1;
  210. // ------- set block_offset in rockInfo ----------//
  211. if( rockBlockInfo->loc_x < MAX_ROCK_WIDTH &&
  212. rockBlockInfo->loc_y < MAX_ROCK_HEIGHT)
  213. {
  214. // store the rockBlockRecno (i.e. i+1) in rockInfo->block_offset
  215. // in order to find a rock block from rock recno and x offset, y offset
  216. // thus make RockRes::locate_block() faster
  217. rockInfo->block_offset[rockBlockInfo->loc_y][rockBlockInfo->loc_x] = i + 1;
  218. }
  219. #ifdef DEBUG
  220. // -------- validate loc_x and loc_y ----------//
  221. err_when( rockBlockInfo->loc_x >= rockInfo->loc_width );
  222. err_when( rockBlockInfo->loc_y >= rockInfo->loc_height );
  223. // -------- validate rockBitmapInfo -------//
  224. int blockFrame = rockInfo->max_frame;
  225. for(int f = 1; f <= blockFrame; ++f)
  226. {
  227. RockBitmapInfo *rockBitmapInfo = rock_bitmap_array + (rockBlockInfo->first_bitmap-1) + (f-1);
  228. err_when( rockBlockInfo->loc_x != rockBitmapInfo->loc_x);
  229. err_when( rockBlockInfo->loc_y != rockBitmapInfo->loc_y);
  230. err_when( f != rockBitmapInfo->frame);
  231. }
  232. #endif
  233. }
  234. }
  235. // ------------ end of function RockRes::load_block_info -----------//
  236. // ------------ begin of function RockRes::load_anim_info -----------//
  237. void RockRes::load_anim_info()
  238. {
  239. RockAnimRec *rockAnimRec;
  240. RockAnimInfo *rockAnimInfo;
  241. int i;
  242. //---- read in rock count and initialize rock info array ----//
  243. String rockDbName;
  244. rockDbName = DIR_RES;
  245. rockDbName += "ROCKANI";
  246. rockDbName += config.terrain_set;
  247. rockDbName += ".RES";
  248. Database rockDbObj(rockDbName, 1);
  249. // Database *dbRock = game_set.open_db(ROCK_ANIM_DB); // only one database can be opened at a time, so we read ROCK.DBF first
  250. Database *dbRock = &rockDbObj;
  251. rock_anim_count = (short) dbRock->rec_count();
  252. rock_anim_array = (RockAnimInfo*) mem_add( sizeof(RockAnimInfo)*rock_anim_count );
  253. memset( rock_anim_array, 0, sizeof(RockAnimInfo) * rock_anim_count );
  254. //---------- read in ROCKANIM.DBF ---------//
  255. for( i=0 ; i<rock_anim_count ; i++ )
  256. {
  257. rockAnimRec = (RockAnimRec*) dbRock->read(i+1);
  258. rockAnimInfo = rock_anim_array+i;
  259. rockAnimInfo->frame = m.atoi(rockAnimRec->frame, rockAnimRec->FRAME_NO_LEN);
  260. rockAnimInfo->delay = m.atoi(rockAnimRec->delay, rockAnimRec->DELAY_LEN);
  261. rockAnimInfo->next_frame = m.atoi(rockAnimRec->next_frame, rockAnimRec->FRAME_NO_LEN);
  262. rockAnimInfo->alt_next = m.atoi(rockAnimRec->alt_next, rockAnimRec->FRAME_NO_LEN);
  263. if( rockAnimInfo->alt_next == 0)
  264. rockAnimInfo->alt_next = rockAnimInfo->next_frame;
  265. #ifdef DEBUG
  266. char rockName[rockAnimRec->ROCKID_LEN+1];
  267. m.rtrim_fld( rockName, rockAnimRec->rock_id, rockAnimRec->ROCKID_LEN );
  268. // temporary set init_flag =1;
  269. init_flag = 1;
  270. short rockId = locate(rockName);
  271. init_flag = 0;
  272. err_when(!rockId);
  273. RockInfo *rockInfo = rock_info_array+rockId-1;
  274. // -------- validate rockAnimFrame -------//
  275. err_when( rockAnimInfo->frame <= 0 || rockAnimInfo->frame > rockInfo->max_frame);
  276. // --------- validate next_frame ---------//
  277. err_when( rockAnimInfo->next_frame <= 0 || rockAnimInfo->next_frame > rockInfo->max_frame);
  278. // --------- valudate alt_next -----------//
  279. err_when( rockAnimInfo->alt_next <= 0 || rockAnimInfo->alt_next > rockInfo->max_frame);
  280. #endif
  281. }
  282. }
  283. // ------------ end of function RockRes::load_anim_info -----------//
  284. // ------------ begin of function RockRes::get_rock_info -----------//
  285. RockInfo *RockRes::get_rock_info(short rockRecno)
  286. {
  287. err_when(rockRecno <= 0 || rockRecno > rock_info_count );
  288. return rock_info_array + rockRecno - 1;
  289. }
  290. // ------------ end of function RockRes::get_rock_info -----------//
  291. // ------------ begin of function RockRes::get_block_info -----------//
  292. RockBlockInfo *RockRes::get_block_info(short rockBlockRecno)
  293. {
  294. err_when(rockBlockRecno <= 0 || rockBlockRecno > rock_block_count);
  295. return rock_block_array + rockBlockRecno -1;
  296. }
  297. // ------------ end of function RockRes::get_block_info -----------//
  298. // ------------ begin of function RockRes::get_bitmap_info -----------//
  299. RockBitmapInfo *RockRes::get_bitmap_info(short rockBitmapRecno)
  300. {
  301. err_when( rockBitmapRecno <= 0 || rockBitmapRecno > rock_bitmap_count);
  302. return rock_bitmap_array + rockBitmapRecno - 1;
  303. }
  304. // ------------ end of function RockRes::get_bitmap_info -----------//
  305. // ------------ begin of function RockRes::get_anim_info -----------//
  306. RockAnimInfo *RockRes::get_anim_info(short rockAnimRecno )
  307. {
  308. static RockAnimInfo unanimatedInfo = { 1, 99, 1, 1, };
  309. if( rockAnimRecno == -1 ) // non-animated rock
  310. {
  311. return &unanimatedInfo;
  312. }
  313. err_when( rockAnimRecno <= 0 || rockAnimRecno > rock_anim_count );
  314. return rock_anim_array + rockAnimRecno - 1;
  315. }
  316. // ------------ end of function RockRes::get_anim_info -----------//
  317. // ------------ begin of function RockRes::get_bitmap_recno -----------//
  318. // return rockBitmapRecno
  319. short RockRes::get_bitmap_recno(short rockBlockRecno, char curFrame)
  320. {
  321. RockBlockInfo *rockBlockInfo = get_block_info(rockBlockRecno);
  322. #ifdef DEBUG
  323. // --------- validate curFrame -------------//
  324. RockInfo *rockInfo = get_rock_info(rockBlockInfo->rock_recno);
  325. err_when( curFrame <= 0 || curFrame > rockInfo->max_frame);
  326. #endif
  327. short rockBitmapRecno = rockBlockInfo->first_bitmap+curFrame-1;
  328. #ifdef DEBUG
  329. // --------- validate loc_x and loc_y ----------//
  330. RockBitmapInfo *rockBitmapInfo = get_bitmap_info(rockBitmapRecno);
  331. err_when( rockBlockInfo->loc_x != rockBitmapInfo->loc_x);
  332. err_when( rockBlockInfo->loc_y != rockBitmapInfo->loc_y);
  333. #endif
  334. return rockBitmapRecno;
  335. }
  336. // ------------ end of function RockRes::get_bitmap_recno -----------//
  337. // ------------ begin of function RockRes::choose_next -----------//
  338. // choose the next frame
  339. // <short> rockRecno rock recno
  340. // <char> curFrame the current frame no.
  341. // <long> path a random number, related to the probability of choosing alt_next
  342. // eg. choose_next(..,.., m.random(x)); prob of using alt_next is 1/x
  343. // return next frame no.
  344. char RockRes::choose_next(short rockRecno, char curFrame, long path)
  345. {
  346. // -------- validate rockRecno ---------//
  347. RockInfo *rockInfo = get_rock_info(rockRecno);
  348. // -------- validate curFrame ----------//
  349. err_when(curFrame <= 0 || curFrame > rockInfo->max_frame);
  350. RockAnimInfo *rockAnimInfo = get_anim_info(get_anim_recno(rockRecno, curFrame) );
  351. // -------- validate frame, next_frame and alt_next in rockAnimInfo -------/
  352. err_when(rockAnimInfo->frame != curFrame);
  353. err_when(get_anim_info(get_anim_recno(rockRecno, rockAnimInfo->next_frame))->frame != rockAnimInfo->next_frame);
  354. err_when(get_anim_info(get_anim_recno(rockRecno, rockAnimInfo->alt_next))->frame != rockAnimInfo->alt_next);
  355. return rockAnimInfo->choose_next(path);
  356. }
  357. // ------------ end of function RockRes::choose_next -----------//
  358. // ------------ begin of function RockRes::draw -----------//
  359. // draw the whole rock at location (xLoc, yLoc)
  360. // <short> rockRecno rock no.
  361. // <short> xLoc,yLoc where the rock is drawn
  362. // <char> curFrame frame no.
  363. void RockRes::draw(short rockRecno, short xLoc, short yLoc, char curFrame)
  364. {
  365. int yc, xc;
  366. RockInfo *rockInfo = rock_res.get_rock_info(rockRecno);
  367. short rockBlockRecno, rockBitmapRecno;
  368. for( yc = 0; yc < rockInfo->loc_height; ++yc)
  369. {
  370. for( xc = 0; xc < rockInfo->loc_width; ++xc)
  371. {
  372. if( (rockBlockRecno = locate_block(rockRecno, xc, yc)) != 0
  373. && (rockBitmapRecno = get_bitmap_recno(rockBlockRecno, curFrame)) != 0 )
  374. {
  375. get_bitmap_info(rockBitmapRecno)->draw(xLoc+xc, yLoc+yc);
  376. }
  377. }
  378. }
  379. }
  380. // ------------ end of function RockRes::draw -----------//
  381. // ------------ begin of function RockRes::draw_block -----------//
  382. // draw (offsetX, offsetY) of rockRecno at location (xLoc, yLoc)
  383. // <short> rockRecno rock no.
  384. // <short> offsetX, offsetY which cell of a rock
  385. // <short> xLoc,yLoc where the rock is drawn
  386. // <char> curFrame frame no.
  387. void RockRes::draw_block(short rockRecno, short xLoc, short yLoc,
  388. short offsetX, short offsetY, char curFrame)
  389. {
  390. RockInfo *rockInfo = rock_res.get_rock_info(rockRecno);
  391. short rockBlockRecno, rockBitmapRecno;
  392. err_when( !rockInfo );
  393. err_when( offsetX < 0 || offsetX >= rockInfo->loc_width );
  394. err_when( offsetY < 0 || offsetY >= rockInfo->loc_height );
  395. if( (rockBlockRecno = locate_block(rockRecno, offsetX, offsetY)) != 0
  396. && (rockBitmapRecno = get_bitmap_recno(rockBlockRecno, curFrame)) != 0 )
  397. {
  398. get_bitmap_info(rockBitmapRecno)->draw(xLoc, yLoc);
  399. }
  400. }
  401. // ------------ end of function RockRes::draw_block -----------//
  402. // ------------ begin of function RockRes::search -----------//
  403. //
  404. // search which rock id has the specified criteria
  405. //
  406. // <char*> rockTypes : a string of 'R', 'D', 'E', or NULL for any
  407. // <short> minWidth : minimum loc_width of RockInfo
  408. // <short> maxWidth : maximum loc_width of RockInfo
  409. // <short> minHeight : minimum loc_height of RockInfo
  410. // <short> maxHeight : maximum loc_height of RockInfo
  411. // <int> animatedFlag : 0 for non-animated (i.e. max_frame==1),
  412. // +ve for animated( max_frame > 1),
  413. // -ve for animated or non-animated (default : -1)
  414. // <int> findFirst : whether to find the first match (default : 0)
  415. //
  416. // return rock recno or 0 (for not found)
  417. //
  418. short RockRes::search(char *rockTypes, short minWidth, short maxWidth, short minHeight, short maxHeight,
  419. int animatedFlag, int findFirst, char terrainType )
  420. {
  421. // -------- search a rock by rock_type, width and height ---------//
  422. short rockRecno = 0;
  423. int findCount = 0;
  424. RockInfo *rockInfo;
  425. int i;
  426. for( i = 1, rockInfo = rock_info_array; i <= rock_info_count; ++i, ++rockInfo)
  427. {
  428. if( (!rockTypes || strchr(rockTypes,rockInfo->rock_type) )
  429. && (terrainType == 0 || rockInfo->valid_terrain(terrainType) )
  430. && rockInfo->loc_width >= minWidth && rockInfo->loc_width <= maxWidth
  431. && rockInfo->loc_height >= minHeight && rockInfo->loc_height <= maxHeight
  432. && (animatedFlag < 0 || animatedFlag == 0 && rockInfo->max_frame == 1 ||
  433. animatedFlag > 0 && rockInfo->max_frame > 1) )
  434. {
  435. ++findCount;
  436. if( findFirst )
  437. {
  438. rockRecno = i;
  439. break;
  440. }
  441. else if( m.random(findCount) == 0)
  442. {
  443. rockRecno = i;
  444. }
  445. }
  446. }
  447. return rockRecno;
  448. }
  449. // ------------ end of function RockRes::search -----------//
  450. // ------------ begin of function RockRes::locate -----------//
  451. // find a rock by name
  452. //
  453. // <char *> rockName : name of rock to find
  454. //
  455. // return rock recno or 0 (for not found)
  456. //
  457. short RockRes::locate(char *rockName)
  458. {
  459. // -------- search a rock by rock_type, width and height ---------//
  460. short rockRecno = 0;
  461. RockInfo *rockInfo;
  462. int i;
  463. for( i = 1, rockInfo = rock_info_array; i <= rock_info_count; ++i, ++rockInfo)
  464. {
  465. if( strcmp(rockName, rockInfo->rock_name) == 0 )
  466. {
  467. rockRecno = i;
  468. break;
  469. }
  470. }
  471. return rockRecno;
  472. }
  473. // ------------ end of function RockRes::locate -----------//
  474. // ------------ begin of function RockRes::locate_block -----------//
  475. // find a rock block by rock recno and x, y offset
  476. //
  477. // return rock block recno or 0 for not found
  478. short RockRes::locate_block(short rockRecno, short xLoc, short yLoc)
  479. {
  480. if( xLoc < MAX_ROCK_WIDTH && yLoc < MAX_ROCK_HEIGHT)
  481. {
  482. // if xLoc and yLoc is small enough, the block of offset x and offset y
  483. // can be found in block_offset,
  484. return get_rock_info(rockRecno)->block_offset[yLoc][xLoc];
  485. }
  486. else
  487. {
  488. // otherwise, linear search
  489. short rockBlockRecno = get_rock_info(rockRecno)->first_block_recno;
  490. RockBlockInfo *rockBlockInfo;
  491. for( rockBlockInfo = get_block_info(rockBlockRecno); rockBlockRecno <= rock_block_count
  492. && rockBlockInfo->rock_recno == rockRecno; ++rockBlockRecno, ++rockBlockInfo)
  493. {
  494. if( rockBlockInfo->loc_x == xLoc && rockBlockInfo->loc_y == yLoc)
  495. return rockBlockRecno;
  496. }
  497. return 0;
  498. }
  499. }
  500. // ------------ end of function RockRes::locate_block -----------//
  501. // ------------ begin of function RockRes::get_anim_recno -----------//
  502. // get the rockAnimRecno for a frame of a rock
  503. // <short> rockRecno rock recno
  504. // <char> curFrame the current frame no.
  505. //
  506. // return rockAnim recno
  507. //
  508. short RockRes::get_anim_recno(short rockRecno, char curFrame)
  509. {
  510. // -------- validate rockRecno ---------//
  511. RockInfo *rockInfo = get_rock_info(rockRecno);
  512. if( rockInfo->first_anim_recno )
  513. {
  514. #ifdef DEBUG
  515. // -------- validate curFrame ----------//
  516. err_when(curFrame <= 0 || curFrame > rockInfo->max_frame);
  517. RockAnimInfo *rockAnimInfo = get_anim_info(rockInfo->first_anim_recno + (curFrame-1) );
  518. // -------- validate frame, next_frame and alt_next in rockAnimInfo -------/
  519. err_when(rockAnimInfo->frame != curFrame);
  520. err_when(get_anim_info(rockInfo->first_anim_recno+rockAnimInfo->next_frame-1)->frame != rockAnimInfo->next_frame);
  521. err_when(get_anim_info(rockInfo->first_anim_recno+rockAnimInfo->alt_next-1)->frame != rockAnimInfo->alt_next);
  522. #endif
  523. return rockInfo->first_anim_recno + (curFrame-1);
  524. }
  525. else
  526. return -1; // a special recno for non-animated rock
  527. }
  528. // ------------ end of function RockRes::get_anim_recno -----------//
  529. // ------------ begin of function RockBitmapInfo::draw ---------//
  530. void RockBitmapInfo::draw(short xLoc, short yLoc)
  531. {
  532. //-------- check if the firm is within the view area --------//
  533. int x1 = xLoc * ZOOM_LOC_WIDTH - World::view_top_x;
  534. int x2 = x1 + width() -1;
  535. if( x1 >= ZOOM_WIDTH || x2 < 0)
  536. return;
  537. int y1 = yLoc * ZOOM_LOC_HEIGHT - World::view_top_y;
  538. int y2 = y1 + height() -1;
  539. if( y1 >= ZOOM_HEIGHT || y2 < 0)
  540. return;
  541. //---- only portion of the sprite is inside the view area ------//
  542. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  543. {
  544. int srcX1 = x1<0 ? -x1 : 0;
  545. int srcY1 = y1<0 ? -y1 : 0;
  546. int srcX2 = (x2>=ZOOM_WIDTH ? ZOOM_WIDTH-1-x1 : width()-1);
  547. int srcY2 = (y2>=ZOOM_HEIGHT ? ZOOM_HEIGHT-1-y1 : height()-1);
  548. // ########## begin Gilbert 7/4 ###########//
  549. vga_back.put_bitmap_area_trans( x1+ZOOM_X1, y1+ZOOM_Y1,
  550. bitmap_ptr, srcX1, srcY1, srcX2, srcY2 );
  551. // ########## end Gilbert 7/4 ###########//
  552. }
  553. //---- the whole sprite is inside the view area ------//
  554. else
  555. {
  556. // ########## begin Gilbert 7/4 ###########//
  557. vga_back.put_bitmap_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr );
  558. // ########## end Gilbert 7/4 ###########//
  559. }
  560. }
  561. // ------------ end of function RockBitmapInfo::draw ---------//