OMOUSECR.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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 : OMOUSECR.CPP
  21. //Description : Object Cursor Resource
  22. #include <ALL.h>
  23. #include <OVGA.h>
  24. #include <OSYS.h>
  25. #include <OWORLD.h>
  26. #include <ODB.h>
  27. #include <OMOUSE.h>
  28. #include <OMOUSECR.h>
  29. //---------- define constant ------------//
  30. #define CURSOR_DBF DIR_RES"CURSOR.RES"
  31. //---------- Begin of function MouseCursor::MouseCursor --------//
  32. MouseCursor::MouseCursor()
  33. {
  34. memset( this, 0, sizeof(MouseCursor) );
  35. }
  36. //----------- End of function MouseCursor::MouseCursor ------//
  37. //---------- Begin of function MouseCursor::~MouseCursor --------//
  38. MouseCursor::~MouseCursor()
  39. {
  40. deinit();
  41. }
  42. //----------- End of function MouseCursor::~MouseCursor ------//
  43. //---------- Begin of function MouseCursor::init --------//
  44. //
  45. void MouseCursor::init()
  46. {
  47. //----- open plant material bitmap resource file -------//
  48. String str;
  49. str = DIR_RES;
  50. str += "I_CURSOR.RES";
  51. res_bitmap.init_imported(str,1); // 1-read all into buffer
  52. //------- load database information --------//
  53. load_cursor_info();
  54. init_flag=1;
  55. }
  56. //----------- End of function MouseCursor::init ------//
  57. //---------- Begin of function MouseCursor::deinit --------//
  58. void MouseCursor::deinit()
  59. {
  60. if( init_flag )
  61. {
  62. mem_del(cursor_info_array);
  63. if( save_scr )
  64. {
  65. mem_del( save_scr );
  66. save_scr = NULL;
  67. }
  68. if( save_back_scr )
  69. {
  70. mem_del( save_back_scr );
  71. save_back_scr = NULL;
  72. }
  73. if( merge_buf ) // buffer for merging save screen from the front and back buffers
  74. {
  75. mem_del( merge_buf );
  76. merge_buf = NULL;
  77. }
  78. init_flag = 0;
  79. icon_ptr = NULL;
  80. // ###### begin Gilbert 18/8 #####//
  81. cur_icon = 0;
  82. // ###### end Gilbert 18/8 #####//
  83. }
  84. }
  85. //----------- End of function MouseCursor::deinit ------//
  86. //------- Begin of function MouseCursor::load_cursor_info -------//
  87. //
  88. void MouseCursor::load_cursor_info()
  89. {
  90. CursorRec *cursorRec;
  91. CursorInfo *cursorInfo;
  92. int i;
  93. long bitmapOffset;
  94. Database dbCursor(CURSOR_DBF, 1); // 1-read all into the buffer
  95. cursor_count = (short) dbCursor.rec_count();
  96. cursor_info_array = (CursorInfo*) mem_add( sizeof(CursorInfo)*cursor_count );
  97. //-------- read in PLANTBMP.DBF -------//
  98. memset( cursor_info_array, 0, sizeof(CursorInfo) * cursor_count );
  99. for( i=0 ; i<cursor_count ; i++ )
  100. {
  101. cursorRec = (CursorRec*) dbCursor.read(i+1);
  102. cursorInfo = cursor_info_array+i;
  103. memcpy( &bitmapOffset, cursorRec->bitmap_ptr, sizeof(long) );
  104. cursorInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
  105. cursorInfo->hot_spot_x = m.atoi( cursorRec->hot_spot_x, cursorRec->HOT_SPOT_LEN );
  106. cursorInfo->hot_spot_y = m.atoi( cursorRec->hot_spot_y, cursorRec->HOT_SPOT_LEN );
  107. }
  108. }
  109. //--------- End of function MouseCursor::load_cursor_info ---------//
  110. //--------- Begin of function MouseCursor::set_icon ------------//
  111. //
  112. // Set the bitmap of the mouse cursor
  113. //
  114. // <int> cursorId = id. of the cursor
  115. //
  116. void MouseCursor::set_icon(int cursorId)
  117. {
  118. if( !init_flag )
  119. return;
  120. //-------- hide the cursor first ----------//
  121. int hideAllFlag = hide_all_flag;
  122. if( !hideAllFlag ) // if the mouse has been hiden before, don't hide and show it
  123. mouse.hide();
  124. //------------ set cursor icon ------------//
  125. CursorInfo* cursorInfo = cursor_info_array+cursorId-1;
  126. icon_ptr = cursorInfo->bitmap_ptr;
  127. hot_spot_x = cursorInfo->hot_spot_x;
  128. hot_spot_y = cursorInfo->hot_spot_y;
  129. err_when( !icon_ptr );
  130. icon_width = *((short*)icon_ptr);
  131. icon_height = *((short*)icon_ptr+1);
  132. // ###### begin Gilbert 18/8 #####//
  133. cur_icon = cursorId;
  134. // ###### end Gilbert 18/8 #####//
  135. //------- allocate buffer for screen saving ------//
  136. save_scr = mem_resize( save_scr , icon_width*icon_height+sizeof(short)*2 ); // sizeof(short)*2 is the header for storing width and height info
  137. save_back_scr = mem_resize( save_back_scr, icon_width*icon_height+sizeof(short)*2 ); // sizeof(short)*2 is the header for storing width and height info
  138. merge_buf = mem_resize( merge_buf , icon_width*icon_height+sizeof(short)*2 ); // sizeof(short)*2 is the header for storing width and height info
  139. //------------ redisplay cursor -----------//
  140. if( !hideAllFlag )
  141. mouse.show();
  142. }
  143. //----------- End of function MouseCursor::set_icon -------------//
  144. //----------- Begin of function MouseCursor::set_frame --------//
  145. //
  146. // <char> frameFlag - frame flag
  147. // [char] buildTrack - treat the frame as a line for building track,
  148. // also align the frame's position to locations.
  149. // (default:0)
  150. //
  151. void MouseCursor::set_frame(char frameFlag, char buildTrack)
  152. {
  153. if( frame_flag == frameFlag )
  154. return;
  155. frame_flag = frameFlag;
  156. frame_shown = 0;
  157. }
  158. //----------- End of function MouseCursor::set_frame -------//
  159. //----------- Begin of function MouseCursor::set_frame_border --------//
  160. void MouseCursor::set_frame_border(int borderX1, int borderY1, int borderX2, int borderY2)
  161. {
  162. frame_border_x1 = borderX1;
  163. frame_border_y1 = borderY1;
  164. frame_border_x2 = borderX2;
  165. frame_border_y2 = borderY2;
  166. }
  167. //----------- End of function MouseCursor::set_frame_border -------//
  168. //----------- Begin of function MouseCursor::process --------//
  169. void MouseCursor::process(int curX, int curY)
  170. {
  171. if( processing_flag || !icon_ptr) // it is being nested call by interrupt
  172. return; // when another instance of process is
  173. // being run.
  174. processing_flag = 1; // Prevent nested call
  175. //---------- store screen area ------------//
  176. if( cursor_shown )
  177. {
  178. // restore screen previously saved
  179. int save_x1, save_x2, save_y1, save_y2;
  180. save_x1 = max(cur_x1, 0);
  181. save_y1 = max(cur_y1, 0);
  182. save_x2 = min(cur_x2, VGA_WIDTH-1);
  183. save_y2 = min(cur_y2, VGA_HEIGHT-1);
  184. if ( save_x1 < save_x2 && save_y1 < save_y2 )
  185. {
  186. vga_front.put_bitmap_area_trans( save_x1,
  187. save_y1,
  188. save_scr,
  189. save_x1-cur_x1,
  190. save_y1-cur_y1,
  191. save_x2-cur_x1,
  192. save_y2-cur_y1 );
  193. }
  194. }
  195. //---- only the zoom map can be framed, limit the frame inside that area ----//
  196. if( frame_flag )
  197. {
  198. curX = max(curX, ZOOM_X1);
  199. curY = max(curY, ZOOM_Y1);
  200. curX = min(curX, ZOOM_X2);
  201. curY = min(curY, ZOOM_Y2);
  202. process_frame(curX, curY);
  203. }
  204. //------- update cursor postions ----------//
  205. cur_x1 = curX - hot_spot_x; // handle the offset of the hot site
  206. cur_y1 = curY - hot_spot_y;
  207. cur_x2 = cur_x1 + icon_width - 1;
  208. cur_y2 = cur_y1 + icon_height - 1;
  209. //------- save screen and put cursor -------//
  210. if( hide_all_flag || ( hide_area_flag &&
  211. is_touch( hide_x1, hide_y1, hide_x2, hide_y2 ) ) )
  212. {
  213. cursor_shown = 0;
  214. }
  215. else
  216. {
  217. /* Save the screen underneath the cursor
  218. * where it will be drawn.
  219. */
  220. int save_x1, save_x2, save_y1, save_y2;
  221. save_x1 = max(cur_x1, 0);
  222. save_y1 = max(cur_y1, 0);
  223. save_x2 = min(cur_x2, VGA_WIDTH-1);
  224. save_y2 = min(cur_y2, VGA_HEIGHT-1);
  225. if ( save_x1 < save_x2 && save_y1 < save_y2 ) {
  226. vga_front.read_bitmap( save_x1, save_y1,
  227. save_x2, save_y2, save_scr );
  228. vga_front.put_bitmap_area_trans( save_x1,
  229. save_y1,
  230. icon_ptr,
  231. save_x1-cur_x1,
  232. save_y1-cur_y1,
  233. save_x2-cur_x1,
  234. save_y2-cur_y1 );
  235. cursor_shown = 1;
  236. }
  237. }
  238. //------------------------------------------//
  239. processing_flag = 0; // cancel prevention of nested call
  240. }
  241. //----------- End of function MouseCursor::process -------//
  242. //-------- Begin of function MouseCursor::process_frame --------//
  243. void MouseCursor::process_frame(int curX, int curY)
  244. {
  245. //---- restore the screen area overwritten by the last frame ---//
  246. if( frame_shown )
  247. {
  248. vga_front.fast_put_bitmap( frame_x1, frame_y1, frame_top_save_scr );
  249. vga_front.fast_put_bitmap( frame_x1, frame_y2, frame_bottom_save_scr );
  250. vga_front.fast_put_bitmap( frame_x1, frame_y1, frame_left_save_scr );
  251. vga_front.fast_put_bitmap( frame_x2, frame_y1, frame_right_save_scr );
  252. }
  253. //---------- update frame position ----------//
  254. if( !frame_shown ) // a new frame
  255. {
  256. frame_origin_x = curX;
  257. frame_origin_y = curY;
  258. frame_x1 = curX;
  259. frame_y1 = curY;
  260. frame_x2 = curX;
  261. frame_y2 = curY;
  262. }
  263. else // update the postion of the existing frame
  264. {
  265. //---------- update frame position ----------//
  266. if( curX > frame_origin_x )
  267. {
  268. if( curY > frame_origin_y ) // stretching towards the lower right end
  269. {
  270. frame_x1 = frame_origin_x;
  271. frame_y1 = frame_origin_y;
  272. frame_x2 = curX;
  273. frame_y2 = curY;
  274. }
  275. else // stretching towards the upper right end
  276. {
  277. frame_x1 = frame_origin_x;
  278. frame_y1 = curY;
  279. frame_x2 = curX;
  280. frame_y2 = frame_origin_y;
  281. }
  282. }
  283. else
  284. {
  285. if( curY > frame_origin_y ) // stretching towards the lower left end
  286. {
  287. frame_x1 = curX;
  288. frame_y1 = frame_origin_y;
  289. frame_x2 = frame_origin_x;
  290. frame_y2 = curY;
  291. }
  292. else // stretching towards the upper left end
  293. {
  294. frame_x1 = curX;
  295. frame_y1 = curY;
  296. frame_x2 = frame_origin_x;
  297. frame_y2 = frame_origin_y;
  298. }
  299. }
  300. }
  301. //------- save the screen area and display the frame ------//
  302. disp_frame(&vga_front);
  303. }
  304. //----------- End of function MouseCursor::process_frame -------//
  305. //----------- Begin of function MouseCursor::disp_frame --------//
  306. void MouseCursor::disp_frame(VgaBuf* vgaBufPtr)
  307. {
  308. //------- save the screen area that will be overwriteen -------//
  309. vgaBufPtr->read_bitmap( frame_x1, frame_y1, frame_x2, frame_y1, frame_top_save_scr );
  310. vgaBufPtr->read_bitmap( frame_x1, frame_y2, frame_x2, frame_y2, frame_bottom_save_scr );
  311. vgaBufPtr->read_bitmap( frame_x1, frame_y1, frame_x1, frame_y2, frame_left_save_scr );
  312. vgaBufPtr->read_bitmap( frame_x2, frame_y1, frame_x2, frame_y2, frame_right_save_scr );
  313. //---------- draw the rectagular frame now -----------//
  314. vgaBufPtr->rect( frame_x1, frame_y1, frame_x2, frame_y2, 1, OWN_SELECT_FRAME_COLOR );
  315. //---------- set frame flag ----------//
  316. frame_shown = 1;
  317. }
  318. //----------- End of function MouseCursor::disp_frame -------//
  319. //----------- Begin of function MouseCursor::disp_back_buf --------//
  320. //
  321. // Display the mouse cursor on the back buffer.
  322. //
  323. void MouseCursor::disp_back_buf(int bltX1, int bltY1, int bltX2, int bltY2)
  324. {
  325. if( !icon_ptr )
  326. return;
  327. //-------- display frame on the back buffer ----//
  328. if( frame_flag )
  329. disp_frame(&vga_back);
  330. //----- display mouse cursor on the back buffer ----//
  331. if( is_touch(bltX1, bltY1, bltX2, bltY2) )
  332. {
  333. //--- save the front buffer area which will be overwritten ---//
  334. int x1 = max(cur_x1,bltX1);
  335. int y1 = max(cur_y1,bltY1);
  336. int x2 = min(cur_x2,bltX2);
  337. int y2 = min(cur_y2,bltY2);
  338. vga_back.read_bitmap( x1, y1, x2, y2, save_back_scr );
  339. //--- merge the save area of the back buf with the front buf's save area ---//
  340. // save_scr width : min(cur_x2,VGA_WIDTH-1) -max(cur_x1,0)+1;
  341. // save_scr height : min(cur_y2,VGA_HEIGHT-1)-max(cur_y1,0)+1;
  342. IMGblt( save_scr+4, min(cur_x2,VGA_WIDTH-1) -max(cur_x1,0)+1, x1-max(cur_x1,0), y1-max(cur_y1,0), save_back_scr ); // +4 is the width & height info
  343. //--------- display the mouse cursor now -----------//
  344. if( cur_x1 < bltX1 || cur_x2 > bltX2 || cur_y1 < bltY1 || cur_y2 > bltY2 )
  345. {
  346. vga_back.put_bitmap_area_trans( cur_x1, cur_y1, icon_ptr,
  347. max(bltX1,cur_x1)-cur_x1, max(bltY1,cur_y1)-cur_y1,
  348. min(bltX2,cur_x2)-cur_x1, min(bltY2,cur_y2)-cur_y1 );
  349. }
  350. //---- the whole sprite is inside the view area ------//
  351. else
  352. {
  353. vga_back.put_bitmap_trans(cur_x1, cur_y1, icon_ptr);
  354. }
  355. cursor_shown = 1;
  356. }
  357. }
  358. //----------- End of function MouseCursor::disp_back_buf -------//
  359. //--------- Begin of function MouseCursor::is_touch ------------//
  360. //
  361. // Check if the given area touch the area defined by cur_??.
  362. //
  363. // Return : 1 or 0
  364. //
  365. int MouseCursor::is_touch(int x1, int y1, int x2, int y2)
  366. {
  367. return (( cur_y1 <= y1 && cur_y2 >= y1 ) ||
  368. ( y1 <= cur_y1 && y2 >= cur_y1 )) &&
  369. (( cur_x1 <= x1 && cur_x2 >= x1 ) ||
  370. ( x1 <= cur_x1 && x2 >= cur_x1 ));
  371. }
  372. //--------- End of function MouseCursor::is_touch -----------//
  373. // ####### begin Gilbert 18/8 ########//
  374. //--------- Begin of function MouseCursor::restore_icon ------------//
  375. void MouseCursor::restore_icon(int newCursorId)
  376. {
  377. if( newCursorId == 0)
  378. {
  379. err_here();
  380. // should restore to invisible cursor ?
  381. if( !hide_all_flag )
  382. mouse.hide();
  383. cur_icon = 0;
  384. icon_ptr = NULL;
  385. }
  386. else if( cur_icon == 0 || newCursorId != cur_icon )
  387. {
  388. set_icon(newCursorId);
  389. }
  390. }
  391. //--------- End of function MouseCursor::restore_icon ------------//
  392. // ####### end Gilbert 18/8 ########//