123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OMOUSECR.CPP
- //Description : Object Cursor Resource
- #include <ALL.h>
- #include <OVGA.h>
- #include <OSYS.h>
- #include <OWORLD.h>
- #include <ODB.h>
- #include <OMOUSE.h>
- #include <OMOUSECR.h>
- //---------- define constant ------------//
- #define CURSOR_DBF DIR_RES"CURSOR.RES"
- //---------- Begin of function MouseCursor::MouseCursor --------//
- MouseCursor::MouseCursor()
- {
- memset( this, 0, sizeof(MouseCursor) );
- }
- //----------- End of function MouseCursor::MouseCursor ------//
- //---------- Begin of function MouseCursor::~MouseCursor --------//
- MouseCursor::~MouseCursor()
- {
- deinit();
- }
- //----------- End of function MouseCursor::~MouseCursor ------//
- //---------- Begin of function MouseCursor::init --------//
- //
- void MouseCursor::init()
- {
- //----- open plant material bitmap resource file -------//
- String str;
- str = DIR_RES;
- str += "I_CURSOR.RES";
- res_bitmap.init_imported(str,1); // 1-read all into buffer
- //------- load database information --------//
- load_cursor_info();
- init_flag=1;
- }
- //----------- End of function MouseCursor::init ------//
- //---------- Begin of function MouseCursor::deinit --------//
- void MouseCursor::deinit()
- {
- if( init_flag )
- {
- mem_del(cursor_info_array);
- if( save_scr )
- {
- mem_del( save_scr );
- save_scr = NULL;
- }
- if( save_back_scr )
- {
- mem_del( save_back_scr );
- save_back_scr = NULL;
- }
- if( merge_buf ) // buffer for merging save screen from the front and back buffers
- {
- mem_del( merge_buf );
- merge_buf = NULL;
- }
- init_flag = 0;
- icon_ptr = NULL;
- // ###### begin Gilbert 18/8 #####//
- cur_icon = 0;
- // ###### end Gilbert 18/8 #####//
- }
- }
- //----------- End of function MouseCursor::deinit ------//
- //------- Begin of function MouseCursor::load_cursor_info -------//
- //
- void MouseCursor::load_cursor_info()
- {
- CursorRec *cursorRec;
- CursorInfo *cursorInfo;
- int i;
- long bitmapOffset;
- Database dbCursor(CURSOR_DBF, 1); // 1-read all into the buffer
- cursor_count = (short) dbCursor.rec_count();
- cursor_info_array = (CursorInfo*) mem_add( sizeof(CursorInfo)*cursor_count );
- //-------- read in PLANTBMP.DBF -------//
- memset( cursor_info_array, 0, sizeof(CursorInfo) * cursor_count );
- for( i=0 ; i<cursor_count ; i++ )
- {
- cursorRec = (CursorRec*) dbCursor.read(i+1);
- cursorInfo = cursor_info_array+i;
- memcpy( &bitmapOffset, cursorRec->bitmap_ptr, sizeof(long) );
- cursorInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
- cursorInfo->hot_spot_x = m.atoi( cursorRec->hot_spot_x, cursorRec->HOT_SPOT_LEN );
- cursorInfo->hot_spot_y = m.atoi( cursorRec->hot_spot_y, cursorRec->HOT_SPOT_LEN );
- }
- }
- //--------- End of function MouseCursor::load_cursor_info ---------//
- //--------- Begin of function MouseCursor::set_icon ------------//
- //
- // Set the bitmap of the mouse cursor
- //
- // <int> cursorId = id. of the cursor
- //
- void MouseCursor::set_icon(int cursorId)
- {
- if( !init_flag )
- return;
- //-------- hide the cursor first ----------//
- int hideAllFlag = hide_all_flag;
- if( !hideAllFlag ) // if the mouse has been hiden before, don't hide and show it
- mouse.hide();
- //------------ set cursor icon ------------//
- CursorInfo* cursorInfo = cursor_info_array+cursorId-1;
- icon_ptr = cursorInfo->bitmap_ptr;
- hot_spot_x = cursorInfo->hot_spot_x;
- hot_spot_y = cursorInfo->hot_spot_y;
- err_when( !icon_ptr );
- icon_width = *((short*)icon_ptr);
- icon_height = *((short*)icon_ptr+1);
- // ###### begin Gilbert 18/8 #####//
- cur_icon = cursorId;
- // ###### end Gilbert 18/8 #####//
- //------- allocate buffer for screen saving ------//
- 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
- 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
- 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
- //------------ redisplay cursor -----------//
- if( !hideAllFlag )
- mouse.show();
- }
- //----------- End of function MouseCursor::set_icon -------------//
- //----------- Begin of function MouseCursor::set_frame --------//
- //
- // <char> frameFlag - frame flag
- // [char] buildTrack - treat the frame as a line for building track,
- // also align the frame's position to locations.
- // (default:0)
- //
- void MouseCursor::set_frame(char frameFlag, char buildTrack)
- {
- if( frame_flag == frameFlag )
- return;
- frame_flag = frameFlag;
- frame_shown = 0;
- }
- //----------- End of function MouseCursor::set_frame -------//
- //----------- Begin of function MouseCursor::set_frame_border --------//
- void MouseCursor::set_frame_border(int borderX1, int borderY1, int borderX2, int borderY2)
- {
- frame_border_x1 = borderX1;
- frame_border_y1 = borderY1;
- frame_border_x2 = borderX2;
- frame_border_y2 = borderY2;
- }
- //----------- End of function MouseCursor::set_frame_border -------//
- //----------- Begin of function MouseCursor::process --------//
- void MouseCursor::process(int curX, int curY)
- {
- if( processing_flag || !icon_ptr) // it is being nested call by interrupt
- return; // when another instance of process is
- // being run.
- processing_flag = 1; // Prevent nested call
- //---------- store screen area ------------//
- if( cursor_shown )
- {
- // restore screen previously saved
- int save_x1, save_x2, save_y1, save_y2;
- save_x1 = max(cur_x1, 0);
- save_y1 = max(cur_y1, 0);
- save_x2 = min(cur_x2, VGA_WIDTH-1);
- save_y2 = min(cur_y2, VGA_HEIGHT-1);
- if ( save_x1 < save_x2 && save_y1 < save_y2 )
- {
- vga_front.put_bitmap_area_trans( save_x1,
- save_y1,
- save_scr,
- save_x1-cur_x1,
- save_y1-cur_y1,
- save_x2-cur_x1,
- save_y2-cur_y1 );
- }
- }
- //---- only the zoom map can be framed, limit the frame inside that area ----//
- if( frame_flag )
- {
- curX = max(curX, ZOOM_X1);
- curY = max(curY, ZOOM_Y1);
- curX = min(curX, ZOOM_X2);
- curY = min(curY, ZOOM_Y2);
- process_frame(curX, curY);
- }
- //------- update cursor postions ----------//
- cur_x1 = curX - hot_spot_x; // handle the offset of the hot site
- cur_y1 = curY - hot_spot_y;
- cur_x2 = cur_x1 + icon_width - 1;
- cur_y2 = cur_y1 + icon_height - 1;
- //------- save screen and put cursor -------//
- if( hide_all_flag || ( hide_area_flag &&
- is_touch( hide_x1, hide_y1, hide_x2, hide_y2 ) ) )
- {
- cursor_shown = 0;
- }
- else
- {
- /* Save the screen underneath the cursor
- * where it will be drawn.
- */
- int save_x1, save_x2, save_y1, save_y2;
- save_x1 = max(cur_x1, 0);
- save_y1 = max(cur_y1, 0);
- save_x2 = min(cur_x2, VGA_WIDTH-1);
- save_y2 = min(cur_y2, VGA_HEIGHT-1);
- if ( save_x1 < save_x2 && save_y1 < save_y2 ) {
- vga_front.read_bitmap( save_x1, save_y1,
- save_x2, save_y2, save_scr );
- vga_front.put_bitmap_area_trans( save_x1,
- save_y1,
- icon_ptr,
- save_x1-cur_x1,
- save_y1-cur_y1,
- save_x2-cur_x1,
- save_y2-cur_y1 );
- cursor_shown = 1;
- }
- }
- //------------------------------------------//
- processing_flag = 0; // cancel prevention of nested call
- }
- //----------- End of function MouseCursor::process -------//
- //-------- Begin of function MouseCursor::process_frame --------//
- void MouseCursor::process_frame(int curX, int curY)
- {
- //---- restore the screen area overwritten by the last frame ---//
- if( frame_shown )
- {
- vga_front.fast_put_bitmap( frame_x1, frame_y1, frame_top_save_scr );
- vga_front.fast_put_bitmap( frame_x1, frame_y2, frame_bottom_save_scr );
- vga_front.fast_put_bitmap( frame_x1, frame_y1, frame_left_save_scr );
- vga_front.fast_put_bitmap( frame_x2, frame_y1, frame_right_save_scr );
- }
- //---------- update frame position ----------//
- if( !frame_shown ) // a new frame
- {
- frame_origin_x = curX;
- frame_origin_y = curY;
- frame_x1 = curX;
- frame_y1 = curY;
- frame_x2 = curX;
- frame_y2 = curY;
- }
- else // update the postion of the existing frame
- {
- //---------- update frame position ----------//
- if( curX > frame_origin_x )
- {
- if( curY > frame_origin_y ) // stretching towards the lower right end
- {
- frame_x1 = frame_origin_x;
- frame_y1 = frame_origin_y;
- frame_x2 = curX;
- frame_y2 = curY;
- }
- else // stretching towards the upper right end
- {
- frame_x1 = frame_origin_x;
- frame_y1 = curY;
- frame_x2 = curX;
- frame_y2 = frame_origin_y;
- }
- }
- else
- {
- if( curY > frame_origin_y ) // stretching towards the lower left end
- {
- frame_x1 = curX;
- frame_y1 = frame_origin_y;
- frame_x2 = frame_origin_x;
- frame_y2 = curY;
- }
- else // stretching towards the upper left end
- {
- frame_x1 = curX;
- frame_y1 = curY;
- frame_x2 = frame_origin_x;
- frame_y2 = frame_origin_y;
- }
- }
- }
- //------- save the screen area and display the frame ------//
- disp_frame(&vga_front);
- }
- //----------- End of function MouseCursor::process_frame -------//
- //----------- Begin of function MouseCursor::disp_frame --------//
- void MouseCursor::disp_frame(VgaBuf* vgaBufPtr)
- {
- //------- save the screen area that will be overwriteen -------//
- vgaBufPtr->read_bitmap( frame_x1, frame_y1, frame_x2, frame_y1, frame_top_save_scr );
- vgaBufPtr->read_bitmap( frame_x1, frame_y2, frame_x2, frame_y2, frame_bottom_save_scr );
- vgaBufPtr->read_bitmap( frame_x1, frame_y1, frame_x1, frame_y2, frame_left_save_scr );
- vgaBufPtr->read_bitmap( frame_x2, frame_y1, frame_x2, frame_y2, frame_right_save_scr );
- //---------- draw the rectagular frame now -----------//
- vgaBufPtr->rect( frame_x1, frame_y1, frame_x2, frame_y2, 1, OWN_SELECT_FRAME_COLOR );
- //---------- set frame flag ----------//
- frame_shown = 1;
- }
- //----------- End of function MouseCursor::disp_frame -------//
- //----------- Begin of function MouseCursor::disp_back_buf --------//
- //
- // Display the mouse cursor on the back buffer.
- //
- void MouseCursor::disp_back_buf(int bltX1, int bltY1, int bltX2, int bltY2)
- {
- if( !icon_ptr )
- return;
- //-------- display frame on the back buffer ----//
- if( frame_flag )
- disp_frame(&vga_back);
- //----- display mouse cursor on the back buffer ----//
- if( is_touch(bltX1, bltY1, bltX2, bltY2) )
- {
- //--- save the front buffer area which will be overwritten ---//
- int x1 = max(cur_x1,bltX1);
- int y1 = max(cur_y1,bltY1);
- int x2 = min(cur_x2,bltX2);
- int y2 = min(cur_y2,bltY2);
- vga_back.read_bitmap( x1, y1, x2, y2, save_back_scr );
- //--- merge the save area of the back buf with the front buf's save area ---//
- // save_scr width : min(cur_x2,VGA_WIDTH-1) -max(cur_x1,0)+1;
- // save_scr height : min(cur_y2,VGA_HEIGHT-1)-max(cur_y1,0)+1;
- 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
- //--------- display the mouse cursor now -----------//
- if( cur_x1 < bltX1 || cur_x2 > bltX2 || cur_y1 < bltY1 || cur_y2 > bltY2 )
- {
- vga_back.put_bitmap_area_trans( cur_x1, cur_y1, icon_ptr,
- max(bltX1,cur_x1)-cur_x1, max(bltY1,cur_y1)-cur_y1,
- min(bltX2,cur_x2)-cur_x1, min(bltY2,cur_y2)-cur_y1 );
- }
- //---- the whole sprite is inside the view area ------//
- else
- {
- vga_back.put_bitmap_trans(cur_x1, cur_y1, icon_ptr);
- }
- cursor_shown = 1;
- }
- }
- //----------- End of function MouseCursor::disp_back_buf -------//
- //--------- Begin of function MouseCursor::is_touch ------------//
- //
- // Check if the given area touch the area defined by cur_??.
- //
- // Return : 1 or 0
- //
- int MouseCursor::is_touch(int x1, int y1, int x2, int y2)
- {
- return (( cur_y1 <= y1 && cur_y2 >= y1 ) ||
- ( y1 <= cur_y1 && y2 >= cur_y1 )) &&
- (( cur_x1 <= x1 && cur_x2 >= x1 ) ||
- ( x1 <= cur_x1 && x2 >= cur_x1 ));
- }
- //--------- End of function MouseCursor::is_touch -----------//
- // ####### begin Gilbert 18/8 ########//
- //--------- Begin of function MouseCursor::restore_icon ------------//
- void MouseCursor::restore_icon(int newCursorId)
- {
- if( newCursorId == 0)
- {
- err_here();
- // should restore to invisible cursor ?
- if( !hide_all_flag )
- mouse.hide();
- cur_icon = 0;
- icon_ptr = NULL;
- }
- else if( cur_icon == 0 || newCursorId != cur_icon )
- {
- set_icon(newCursorId);
- }
- }
- //--------- End of function MouseCursor::restore_icon ------------//
- // ####### end Gilbert 18/8 ########//
|