OHILLRES.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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 : OHILLRES.CPP
  21. //Description : Hill resource object
  22. //Onwership : Gilbert
  23. #include <OSYS.h>
  24. #include <OVGA.h>
  25. #include <OGAMESET.h>
  26. #include <OWORLD.h>
  27. #include <OHILLRES.h>
  28. #include <OCONFIG.h>
  29. #include <ALL.h>
  30. //---------- #define constant ------------//
  31. // #define HILL_DB "HILL"
  32. //------- Begin of function HillRes::HillRes -----------//
  33. HillRes::HillRes()
  34. {
  35. init_flag=0;
  36. }
  37. //--------- End of function HillRes::HillRes -----------//
  38. //---------- Begin of function HillRes::init -----------//
  39. //
  40. // This function must be called after a map is generated.
  41. //
  42. void HillRes::init()
  43. {
  44. deinit();
  45. //----- open hill material bitmap resource file -------//
  46. String str;
  47. str = DIR_RES;
  48. // str += "I_HILL.RES";
  49. str += "I_HILL";
  50. str += config.terrain_set;
  51. str += ".RES";
  52. res_bitmap.init_imported(str,1); // 1-read all into buffer
  53. //------- load database information --------//
  54. load_hill_block_info();
  55. init_flag=1;
  56. }
  57. //---------- End of function HillRes::init -----------//
  58. //---------- Begin of function HillRes::deinit -----------//
  59. void HillRes::deinit()
  60. {
  61. if( init_flag )
  62. {
  63. mem_del(first_block_index);
  64. mem_del(hill_block_info_array);
  65. init_flag=0;
  66. }
  67. }
  68. //---------- End of function HillRes::deinit -----------//
  69. //------- Begin of function HillRes::load_hill_info -------//
  70. //
  71. void HillRes::load_hill_block_info()
  72. {
  73. HillBlockRec *hillBlockRec;
  74. HillBlockInfo *hillBlockInfo;
  75. int i;
  76. long bitmapOffset;
  77. //---- read in hill count and initialize hill block info array ----//
  78. String hillDbName;
  79. hillDbName = DIR_RES;
  80. hillDbName += "HILL";
  81. hillDbName += config.terrain_set;
  82. hillDbName += ".RES";
  83. Database hillDbObj(hillDbName, 1);
  84. // Database *dbHill = game_set.open_db(HILL_DB); // only one database can be opened at a time
  85. Database *dbHill = &hillDbObj;
  86. hill_block_count = (short) dbHill->rec_count();
  87. hill_block_info_array = (HillBlockInfo*) mem_add( sizeof(HillBlockInfo)*hill_block_count );
  88. memset( hill_block_info_array, 0, sizeof(HillBlockInfo) * hill_block_count );
  89. max_pattern_id = 0;
  90. //---------- read in HILL.DBF ---------//
  91. for( i=0 ; i<hill_block_count ; i++ )
  92. {
  93. hillBlockRec = (HillBlockRec*) dbHill->read(i+1);
  94. hillBlockInfo = hill_block_info_array+i;
  95. hillBlockInfo->block_id = i + 1;
  96. hillBlockInfo->pattern_id = (char) m.atoi( hillBlockRec->pattern_id, hillBlockRec->PATTERN_ID_LEN);
  97. if( hillBlockInfo->pattern_id > max_pattern_id)
  98. max_pattern_id = hillBlockInfo->pattern_id;
  99. hillBlockInfo->sub_pattern_id = (char) m.atoi(hillBlockRec->sub_pattern_id, hillBlockRec->SUB_PATTERN_ID_LEN);
  100. hillBlockInfo->special_flag = hillBlockRec->special_flag;
  101. if( hillBlockRec->special_flag == ' ')
  102. hillBlockInfo->special_flag = 0;
  103. hillBlockInfo->layer = hillBlockRec->layer - '0';
  104. hillBlockInfo->priority = (char) m.atoi( hillBlockRec->priority, hillBlockRec->PRIORITY_LEN);
  105. hillBlockInfo->bitmap_type = hillBlockRec->bitmap_type;
  106. hillBlockInfo->offset_x = m.atoi(hillBlockRec->offset_x, hillBlockRec->OFFSET_LEN);
  107. hillBlockInfo->offset_y = m.atoi(hillBlockRec->offset_y, hillBlockRec->OFFSET_LEN);
  108. memcpy( &bitmapOffset, hillBlockRec->bitmap_ptr, sizeof(long) );
  109. hillBlockInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
  110. }
  111. //------ build index for the first block of each pattern -------//
  112. // e.g first block id of pattern 1 is 1
  113. // first block id of pattern 3 is 4
  114. // first block id of pattern 4 is 7
  115. // last block id (which is pattern 4) is 10
  116. // first_block_index is { 1, 4, 4, 7 };
  117. // such that, blocks which are pattern 1 are between [1,4)
  118. // 2 are between [4,4) i.e. not found
  119. // 3 are between [4,7)
  120. // 4 are between [7,11)
  121. // see also first_block()
  122. //
  123. first_block_index = (short *) mem_add(sizeof(short) * max_pattern_id);
  124. memset( first_block_index, 0, sizeof(short) * max_pattern_id);
  125. int patternMarked = 0;
  126. for(i = 0, hillBlockInfo = hill_block_info_array; i < hill_block_count;
  127. ++i, ++hillBlockInfo)
  128. {
  129. err_when( hillBlockInfo->pattern_id < patternMarked);
  130. while(patternMarked < hillBlockInfo->pattern_id)
  131. {
  132. first_block_index[patternMarked] = i+1;
  133. patternMarked++;
  134. }
  135. }
  136. }
  137. //--------- End of function HillRes::load_hill_info ---------//
  138. //---------- Begin of function HillRes::operator[] -----------//
  139. HillBlockInfo* HillRes::operator[](int hillBlockId)
  140. {
  141. err_if( hillBlockId<1 || hillBlockId>hill_block_count )
  142. err_now( "HillRes::operator[]" );
  143. return hill_block_info_array+(hillBlockId-1);
  144. }
  145. //------------ End of function HillRes::operator[] -----------//
  146. //---------- Begin of function HillRes::first_block -----------//
  147. short HillRes::first_block(int hillPatternId)
  148. {
  149. err_when(hillPatternId<1);
  150. if(hillPatternId>max_pattern_id)
  151. return hill_block_count+1; // return last block+1
  152. else
  153. return first_block_index[ hillPatternId-1];
  154. }
  155. //------------ End of function HillRes::first_block -----------//
  156. // ####### begin Gilbert 28/1 #######//
  157. //------------ Begin of function HillRes::locate -----------//
  158. short HillRes::locate(char patternId, char subPattern, char searchPriority, char specialFlag)
  159. {
  160. err_when(patternId < 1 || patternId > max_pattern_id);
  161. // ------- find the range which patternId may exist ------//
  162. // find the start of this pattern and next pattern
  163. short startBlockIdx = first_block(patternId);
  164. short endBlockIdx = first_block(patternId+1);
  165. for(short j = startBlockIdx; j < endBlockIdx; ++j)
  166. {
  167. HillBlockInfo *hillBlockInfo = hill_block_info_array+j-1;
  168. if( hillBlockInfo->pattern_id == patternId &&
  169. hillBlockInfo->sub_pattern_id == subPattern &&
  170. hillBlockInfo->priority == searchPriority &&
  171. hillBlockInfo->special_flag == specialFlag)
  172. {
  173. return j;
  174. }
  175. }
  176. return 0; // not found
  177. }
  178. //------------ End of function HillRes::locate -----------//
  179. //------------ Begin of function HillRes::scan -----------//
  180. short HillRes::scan(char patternId, char searchPriority, char specialFlag, char findFirst)
  181. {
  182. err_when(patternId < 1 || patternId > max_pattern_id);
  183. // ------- find the range which patternId may exist ------//
  184. // find the start of this pattern and next pattern
  185. short startBlockIdx = first_block(patternId);
  186. short endBlockIdx = first_block(patternId+1);
  187. short foundBlockId = 0;
  188. short foundCount = 0;
  189. for(short j = startBlockIdx; j < endBlockIdx; ++j)
  190. {
  191. HillBlockInfo *hillBlockInfo = hill_block_info_array+j-1;
  192. if( hillBlockInfo->pattern_id == patternId &&
  193. hillBlockInfo->priority == searchPriority &&
  194. hillBlockInfo->special_flag == specialFlag)
  195. {
  196. if( findFirst)
  197. return j;
  198. if( m.random(++foundCount) == 0)
  199. {
  200. foundBlockId = j;
  201. }
  202. }
  203. }
  204. return foundBlockId; // not found
  205. }
  206. //------------ End of function HillRes::scan -----------//
  207. // ####### end Gilbert 28/1 #######//
  208. //------- Begin of function HillInfo::draw -----------//
  209. //
  210. // Draw the current hill on the map
  211. //
  212. void HillBlockInfo::draw(int xLoc, int yLoc, int layerMask)
  213. {
  214. if(!(layerMask & layer))
  215. return;
  216. //----------- calculate absolute positions ------------//
  217. int absX1 = xLoc*ZOOM_LOC_WIDTH + offset_x;
  218. int absY1 = yLoc*ZOOM_LOC_HEIGHT + offset_y;
  219. //-------- check if the firm is within the view area --------//
  220. int x1 = absX1 - World::view_top_x;
  221. if( x1 <= -bitmap_width() || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
  222. return;
  223. int y1 = absY1 - World::view_top_y;
  224. if( y1 <= -bitmap_height() || y1 >= ZOOM_HEIGHT )
  225. return;
  226. if( bitmap_type == 'W')
  227. {
  228. vga_back.put_bitmap_32x32(x1+ZOOM_X1,y1+ZOOM_Y1, bitmap_ptr);
  229. return;
  230. }
  231. //------- decide which approach to use for displaying -----//
  232. int x2 = absX1 + bitmap_width() - 1 - World::view_top_x;
  233. int y2 = absY1 + bitmap_height()- 1 - World::view_top_y;
  234. //---- only portion of the sprite is inside the view area ------//
  235. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  236. {
  237. vga_back.put_bitmap_area_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  238. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1 );
  239. }
  240. //---- the whole sprite is inside the view area ------//
  241. else
  242. {
  243. vga_back.put_bitmap_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr );
  244. }
  245. }
  246. //--------- End of function HillBlockInfo::draw -----------//
  247. //------- Begin of function HillBlockInfo::draw_at -----------//
  248. //
  249. // Draw the hill on the zoom map, given the exact pixel position to put
  250. // the bitmap.
  251. //
  252. // <int> absX1, absY1 - the absolute base (center-bottom) coordination
  253. // of the building.
  254. //
  255. // Draw the current plant on the map
  256. //
  257. void HillBlockInfo::draw_at(int absX1, int absY1, int layerMask)
  258. {
  259. if(!(layerMask & layer))
  260. return;
  261. //-------- check if the firm is within the view area --------//
  262. absX1 += offset_x;
  263. absY1 += offset_y;
  264. int x1 = absX1 - World::view_top_x;
  265. if( x1 <= -bitmap_width() || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
  266. return;
  267. int y1 = absY1 - World::view_top_y;
  268. if( y1 <= -bitmap_height() || y1 >= ZOOM_HEIGHT )
  269. return;
  270. if( bitmap_type == 'W')
  271. {
  272. vga_back.put_bitmap_32x32(x1+ZOOM_X1,y1+ZOOM_Y1, bitmap_ptr);
  273. return;
  274. }
  275. //------- decide which approach to use for displaying -----//
  276. int x2 = absX1 + bitmap_width() - 1 - World::view_top_x;
  277. int y2 = absY1 + bitmap_height()- 1 - World::view_top_y;
  278. //---- only portion of the sprite is inside the view area ------//
  279. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  280. {
  281. vga_back.put_bitmap_area_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  282. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1 );
  283. }
  284. //---- the whole sprite is inside the view area ------//
  285. else
  286. {
  287. vga_back.put_bitmap_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr );
  288. }
  289. }
  290. //--------- End of function HillBlockInfo::draw_at -----------//