OWALLRES.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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 : OWALLRES.CPP
  21. //Description : Wall resource object
  22. //Ownership : Gilbert
  23. #include <OSYS.h>
  24. #include <OVGA.h>
  25. #include <OFONT.h>
  26. #include <OGAMESET.h>
  27. #include <OWORLD.h>
  28. #include <ONATION.h>
  29. #include <WALLTILE.h>
  30. #include <OWALLRES.h>
  31. //---------- #define constant ------------//
  32. #define WALL_DB "WALL"
  33. //------- Begin of function WallRes::WallRes -----------//
  34. WallRes::WallRes()
  35. {
  36. init_flag=0;
  37. selected_x_loc = -1;
  38. selected_y_loc = -1;
  39. }
  40. //--------- End of function WallRes::WallRes -----------//
  41. //---------- Begin of function WallRes::init -----------//
  42. //
  43. // This function must be called after a map is generated.
  44. //
  45. void WallRes::init()
  46. {
  47. deinit();
  48. //----- open wall material bitmap resource file -------//
  49. String str;
  50. str = DIR_RES;
  51. str += "I_WALL.RES";
  52. res_bitmap.init_imported(str,1); // 1-read all into buffer
  53. //------- load database information --------//
  54. load_wall_info();
  55. init_flag=1;
  56. }
  57. //---------- End of function WallRes::init -----------//
  58. //---------- Begin of function WallRes::deinit -----------//
  59. void WallRes::deinit()
  60. {
  61. if( init_flag )
  62. {
  63. mem_del(wall_info_array);
  64. mem_del(wall_index);
  65. init_flag=0;
  66. }
  67. }
  68. //---------- End of function WallRes::deinit -----------//
  69. //------- Begin of function WallRes::load_wall_info -------//
  70. //
  71. void WallRes::load_wall_info()
  72. {
  73. WallRec *wallRec;
  74. WallInfo *wallInfo;
  75. int i;
  76. long bitmapOffset;
  77. max_wall_id = 0;
  78. //---- read in wall count and initialize wall info array ----//
  79. Database *dbWall = game_set.open_db(WALL_DB); // only one database can be opened at a time, so we read FIRM.DBF first
  80. wall_count = (short) dbWall->rec_count();
  81. wall_info_array = (WallInfo*) mem_add( sizeof(WallInfo)*wall_count );
  82. memset( wall_info_array, 0, sizeof(WallInfo) * wall_count );
  83. //---------- read in WALL.DBF ---------//
  84. for( i=0 ; i<wall_count ; i++ )
  85. {
  86. wallRec = (WallRec*) dbWall->read(i+1);
  87. wallInfo = wall_info_array+i;
  88. wallInfo->wall_id = m.atoi( wallRec->wall_id, wallRec->WALL_ID_LEN);
  89. wallInfo->flags = 0;
  90. if( wallRec->gate_flag == 'Y' || wallRec->gate_flag == 'y')
  91. wallInfo->set_gate();
  92. if( wallRec->trans_flag == 'Y' || wallRec->trans_flag == 'y')
  93. wallInfo->set_trans();
  94. wallInfo->offset_x = m.atoi( wallRec->offset_x, wallRec->OFFSET_LEN);
  95. wallInfo->offset_y = m.atoi( wallRec->offset_y, wallRec->OFFSET_LEN);
  96. wallInfo->loc_off_x = m.atoi( wallRec->loc_off_x, wallRec->LOC_OFF_LEN);
  97. wallInfo->loc_off_y = m.atoi( wallRec->loc_off_y, wallRec->LOC_OFF_LEN);
  98. wallInfo->draw_wall_id = m.atoi( wallRec->draw_wall, wallRec->WALL_ID_LEN);
  99. memcpy( &bitmapOffset, wallRec->bitmap_ptr, sizeof(long) );
  100. wallInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
  101. if( wallInfo->wall_id > max_wall_id)
  102. max_wall_id = wallInfo->wall_id;
  103. }
  104. // --------- build wall_index ---------//
  105. if( max_wall_id > 0)
  106. {
  107. wall_index = (WallInfo **) mem_add(sizeof(WallInfo *) * max_wall_id);
  108. memset( wall_index, 0, sizeof(WallInfo *) * max_wall_id);
  109. for( i=0 ; i<wall_count ; i++ )
  110. {
  111. wall_index[wall_info_array[i].wall_id -1] = &wall_info_array[i];
  112. }
  113. }
  114. else
  115. {
  116. err.run("No wall database found");
  117. }
  118. }
  119. //--------- End of function WallRes::load_wall_info ---------//
  120. //------- Begin of function WallRes::draw_selected -------//
  121. //
  122. void WallRes::draw_selected()
  123. {
  124. if( selected_x_loc < 0 )
  125. return;
  126. int x = selected_x_loc * ZOOM_LOC_WIDTH;
  127. int y = selected_y_loc * ZOOM_LOC_HEIGHT;
  128. x = x - World::view_top_x + ZOOM_X1;
  129. y = y - World::view_top_y + ZOOM_Y1;
  130. //------------ draw the square frame now ------------//
  131. if( m.is_touch( x, y, x, x, ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2 ) )
  132. {
  133. vga_back.rect( x, y, x+ZOOM_LOC_WIDTH-1, y+ZOOM_LOC_HEIGHT-1, 1, OWN_SELECT_FRAME_COLOR );
  134. }
  135. }
  136. //--------- End of function WallRes::draw_selected ---------//
  137. //------- Begin of function WallRes::disp_info -------//
  138. //
  139. void WallRes::disp_info(int refreshFlag)
  140. {
  141. if( selected_x_loc < 0 )
  142. return;
  143. if( refreshFlag == INFO_REPAINT )
  144. {
  145. font_san.d3_put( INFO_X1, INFO_Y1, INFO_X2, INFO_Y1+17, "Defense Wall" );
  146. vga_front.d3_panel_up( INFO_X1, INFO_Y1+20, INFO_X2, INFO_Y1+40, 1 );
  147. }
  148. int x=INFO_X1+3, y=INFO_Y1+23;
  149. Location* locPtr = world.get_loc( selected_x_loc, selected_y_loc );
  150. String str;
  151. str = locPtr->wall_abs_hit_point();
  152. str += " / 100";
  153. font_san.field( x, y, "Hit Points", x+80, str, INFO_X2-4, refreshFlag );
  154. }
  155. //--------- End of function WallRes::disp_info ---------//
  156. //---------- Begin of function WallRes::operator[] -----------//
  157. WallInfo* WallRes::operator[](int wallId)
  158. {
  159. err_if( wallId<1 || wallId>max_wall_id )
  160. err_now( "WallRes::operator[]" );
  161. return wall_index[wallId-1];
  162. }
  163. //------------ End of function WallRes::operator[] -----------//
  164. //------- Begin of function WallInfo::draw -----------//
  165. //
  166. // Draw the current wall on the map
  167. //
  168. void WallInfo::draw(int xLoc, int yLoc, char *remapTbl)
  169. {
  170. //----------- calculate absolute positions ------------//
  171. //-------- check if the wall is within the view area --------//
  172. int x1 = xLoc*ZOOM_LOC_WIDTH + offset_x - World::view_top_x;
  173. int x2 = x1 + bitmap_width() -1;
  174. if( x2 < 0 || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
  175. return;
  176. int y1 = yLoc*ZOOM_LOC_HEIGHT +offset_y - World::view_top_y;
  177. int y2 = y1 + bitmap_height() -1;
  178. if( y2 < 0 || y1 >= ZOOM_HEIGHT )
  179. return;
  180. //------- decide which approach to use for displaying -----//
  181. //---- only portion of the sprite is inside the view area ------//
  182. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  183. {
  184. if(is_trans())
  185. {
  186. if( remapTbl)
  187. vga_back.put_bitmap_area_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  188. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1,
  189. remapTbl);
  190. else
  191. vga_back.put_bitmap_area_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  192. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1);
  193. }
  194. else
  195. {
  196. if( remapTbl)
  197. vga_back.put_bitmap_area_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  198. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1,
  199. remapTbl);
  200. else
  201. vga_back.put_bitmap_area( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  202. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1);
  203. }
  204. }
  205. //---- the whole sprite is inside the view area ------//
  206. else
  207. {
  208. if(is_trans() )
  209. {
  210. if( remapTbl)
  211. vga_back.put_bitmap_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl);
  212. else
  213. vga_back.put_bitmap_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
  214. }
  215. else
  216. {
  217. if( remapTbl)
  218. vga_back.put_bitmap_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl );
  219. else
  220. vga_back.put_bitmap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
  221. }
  222. }
  223. }
  224. //--------- End of function WallInfo::draw -----------//
  225. //------- Begin of function WallInfo::draw_at -----------//
  226. //
  227. // Draw the wall on the zoom map, given the exact pixel position to put
  228. // the bitmap.
  229. //
  230. // <int> absBaseX, absBaseY - the absolute base (center-bottom) coordination
  231. // of the building.
  232. //
  233. // Draw the current plant on the map
  234. //
  235. void WallInfo::draw_at(int absBaseX, int absBaseY, char *remapTbl)
  236. {
  237. //-------- check if the wall is within the view area --------//
  238. int x1 = absBaseX - World::view_top_x;
  239. int x2 = x1 + bitmap_width() -1;
  240. if( x2 < 0 || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
  241. return;
  242. int y1 = absBaseY - World::view_top_y;
  243. int y2 = y1 + bitmap_height() -1;
  244. if( y2 < 0 || y1 >= ZOOM_HEIGHT )
  245. return;
  246. //------- decide which approach to use for displaying -----//
  247. //---- only portion of the sprite is inside the view area ------//
  248. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  249. {
  250. // no put_bitmap_area_remap
  251. if(is_trans())
  252. {
  253. if( remapTbl)
  254. vga_back.put_bitmap_area_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  255. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1,
  256. remapTbl);
  257. else
  258. vga_back.put_bitmap_area_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  259. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1);
  260. }
  261. else
  262. {
  263. if( remapTbl)
  264. vga_back.put_bitmap_area_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  265. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1,
  266. remapTbl);
  267. else
  268. vga_back.put_bitmap_area( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
  269. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1);
  270. }
  271. }
  272. //---- the whole sprite is inside the view area ------//
  273. else
  274. {
  275. if(is_trans() )
  276. {
  277. if( remapTbl)
  278. vga_back.put_bitmap_trans_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl);
  279. else
  280. vga_back.put_bitmap_trans( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
  281. }
  282. else
  283. {
  284. if( remapTbl)
  285. vga_back.put_bitmap_remap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, remapTbl );
  286. else
  287. vga_back.put_bitmap( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr);
  288. }
  289. }
  290. }
  291. //--------- End of function WallInfo::draw_at -----------//