00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024
00025 #include "SDL_mouse.h"
00026 #include "SDL_timer.h"
00027 #include "mouse.h"
00028 #include "gamewin.h"
00029 #include "fnames.h"
00030 #include "Gump.h"
00031 #include "Gump_manager.h"
00032 #include "barge.h"
00033 #include "actors.h"
00034 #include "cheat.h"
00035 #include "combat_opts.h"
00036 #include "combat.h"
00037 #include "schedule.h"
00038
00039 #ifndef _MSC_VER
00040 using std::max;
00041 #endif
00042
00043 short Mouse::short_arrows[8] = {8, 9, 10, 11, 12, 13, 14, 15};
00044 short Mouse::med_arrows[8] = {16, 17, 18, 19, 20, 21, 22, 23};
00045 short Mouse::long_arrows[8] = {24, 25, 26, 27, 28, 29, 30, 31};
00046
00047 short Mouse::short_combat_arrows[8] = {32, 33, 34, 35, 36, 37, 38, 39};
00048 short Mouse::med_combat_arrows[8] = {40, 41, 42, 43, 44, 45, 46, 47};
00049
00050 Mouse* Mouse::mouse = 0;
00051 bool Mouse::mouse_update = false;
00052
00053
00054
00055
00056
00057 Mouse::Mouse
00058 (
00059 Game_window *gw
00060 ) : gwin(gw), iwin(gwin->get_win()),backup(0),box(0,0,0,0),dirty(0,0,0,0), cur_framenum(0),cur(0),avatar_speed(100*gwin->get_std_delay()/slow_speed_factor)
00061 {
00062 SDL_GetMouseState(&mousex, &mousey);
00063 mousex /= gwin->get_fastmouse() ? 1 : iwin->get_scale();
00064 mousey /= gwin->get_fastmouse() ? 1 : iwin->get_scale();
00065 if (is_system_path_defined("<PATCH>") && U7exists(PATCH_POINTERS))
00066 pointers.load(PATCH_POINTERS);
00067 else
00068 pointers.load(POINTERS);
00069 Init();
00070 set_shape(get_short_arrow(east));
00071 }
00072
00073 Mouse::Mouse
00074 (
00075 Game_window *gw,
00076 DataSource &shapes
00077 ) : gwin(gw), iwin(gwin->get_win()),backup(0),box(0,0,0,0),dirty(0,0,0,0),cur_framenum(0),cur(0),avatar_speed(100*gwin->get_std_delay()/slow_speed_factor)
00078 {
00079 SDL_GetMouseState(&mousex, &mousey);
00080 mousex /= gwin->get_fastmouse() ? 1 : iwin->get_scale();
00081 mousey /= gwin->get_fastmouse() ? 1 : iwin->get_scale();
00082 pointers.load(&shapes);
00083 Init();
00084 set_shape0(0);
00085 }
00086
00087 void Mouse::Init()
00088 {
00089 int cnt = pointers.get_num_frames();
00090 int maxleft = 0, maxright = 0, maxabove = 0, maxbelow = 0;
00091 for (int i = 0; i < cnt; i++)
00092 {
00093 Shape_frame *frame = pointers.get_frame(i);
00094 int xleft = frame->get_xleft(), xright = frame->get_xright();
00095 int yabove = frame->get_yabove(), ybelow = frame->get_ybelow();
00096 if (xleft > maxleft)
00097 maxleft = xleft;
00098 if (xright > maxright)
00099 maxright = xright;
00100 if (yabove > maxabove)
00101 maxabove = yabove;
00102 if (ybelow > maxbelow)
00103 maxbelow = ybelow;
00104 }
00105 int maxw = maxleft + maxright, maxh = maxabove + maxbelow;
00106
00107 backup = iwin->create_buffer(maxw, maxh);
00108 box.w = maxw;
00109 box.h = maxh;
00110
00111 onscreen = 0;
00112 }
00113
00114
00115
00116
00117
00118 Mouse::~Mouse
00119 (
00120 )
00121 {
00122 delete backup;
00123 }
00124
00125
00126
00127
00128
00129 void Mouse::show
00130 (
00131 )
00132 {
00133 if (!onscreen)
00134 {
00135 onscreen = 1;
00136
00137 iwin->get(backup, box.x, box.y);
00138
00139
00140 cur->paint_rle(mousex, mousey);
00141 }
00142 }
00143
00144
00145
00146
00147
00148 void Mouse::move(int x, int y) {
00149 bool warp = false;
00150 if (x >= gwin->get_width()) {
00151 x = gwin->get_width() - 1;
00152 warp = true;
00153 }
00154 if (y >= gwin->get_height()) {
00155 y = gwin->get_height() - 1;
00156 warp = true;
00157 }
00158 if (warp)
00159 SDL_WarpMouse(x, y);
00160 #ifdef DEBUG
00161 if (onscreen)
00162 std::cerr << "Trying to move mouse while onscreen!" << std::endl;
00163 #endif
00164
00165 box.shift(x - mousex, y - mousey);
00166 dirty = dirty.add(box);
00167 mousex = x;
00168 mousey = y;
00169 }
00170
00171
00172
00173
00174
00175
00176 void Mouse::set_shape0
00177 (
00178 int framenum
00179 )
00180 {
00181 cur_framenum = framenum;
00182 cur = pointers.get_frame(framenum);
00183 while (!cur)
00184 cur = pointers.get_frame(--framenum);
00185
00186 box.x = mousex - cur->get_xleft();
00187 box.y = mousey - cur->get_yabove();
00188 dirty = dirty.add(box);
00189 }
00190
00191
00192
00193
00194
00195 void Mouse::set_location
00196 (
00197 int x, int y
00198 )
00199 {
00200 mousex = x;
00201 mousey = y;
00202 box.x = mousex - cur->get_xleft();
00203 box.y = mousey - cur->get_yabove();
00204 }
00205
00206
00207
00208
00209
00210 void Mouse::flash_shape
00211 (
00212 Mouse_shapes flash
00213 )
00214 {
00215 Mouse_shapes saveshape = get_shape();
00216 hide();
00217 set_shape(flash);
00218 show();
00219 gwin->show(1);
00220 SDL_Delay(600);
00221 hide();
00222 gwin->paint();
00223 set_shape(saveshape);
00224 gwin->set_painted();
00225 }
00226
00227
00228
00229
00230
00231
00232 void Mouse::set_speed_cursor()
00233 {
00234 Game_window *gwin = Game_window::get_instance();
00235 Gump_manager *gump_man = gwin->get_gump_man();
00236
00237 int cursor = dontchange;
00238 int ax, ay;
00239
00240
00241 if (gwin->main_actor_dont_move())
00242 cursor = hand;
00243
00244 else if (gump_man->gump_mode()) {
00245 if (gump_man->gumps_dont_pause_game())
00246 {
00247 Gump *gump = gump_man->find_gump(mousex, mousey);
00248
00249 if (gump && !gump->no_handcursor())
00250 cursor = hand;
00251 }
00252 else cursor = hand;
00253 }
00254
00255 else if (gwin->get_dragging_gump()) cursor = hand;
00256
00257 else if (cheat.in_map_editor())
00258 {
00259 switch (cheat.get_edit_mode())
00260 {
00261 case Cheat::move:
00262 cursor = hand; break;
00263 case Cheat::paint:
00264 cursor = short_combat_arrows[4]; break;
00265 case Cheat::paint_chunks:
00266 cursor = med_combat_arrows[0]; break;
00267 #if 0
00268 case Cheat::select:
00269 cursor = short_arrows[7]; break;
00270 case Cheat::hide:
00271 cursor = redx; break;
00272 #endif
00273 case Cheat::combo_pick:
00274 cursor = greenselect; break;
00275 }
00276 }
00277 else if (Combat::is_paused())
00278 cursor = short_combat_arrows[0];
00279 if (cursor == dontchange)
00280 {
00281 Barge_object *barge = gwin->get_moving_barge();
00282 if (barge)
00283 {
00284 gwin->get_shape_location(barge, ax, ay);
00285 ax -= barge->get_xtiles()*(c_tilesize/2);
00286 ay -= barge->get_ytiles()*(c_tilesize/2);
00287 }
00288 else
00289 gwin->get_shape_location(gwin->get_main_actor(), ax, ay);
00290
00291 int dy = ay - mousey, dx = mousex - ax;
00292 Direction dir = Get_direction(dy, dx);
00293 Rectangle gamewin_dims = gwin->get_win_rect();
00294 float speed_section = max( max( -static_cast<float>(dx)/ax, static_cast<float>(dx)/(gamewin_dims.w-ax)), max(static_cast<float>(dy)/ay, -static_cast<float>(dy)/(gamewin_dims.h-ay)) );
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 Actor_queue nearby;
00307 if (!cheat.in_god_mode())
00308 gwin->get_nearby_npcs( nearby );
00309
00310 bool nearby_hostile = false;
00311 for( Actor_queue::const_iterator it = nearby.begin(); it != nearby.end(); ++it ) {
00312 Actor *actor = *it;
00313
00314 if( !actor->is_dead() && actor->get_schedule() &&
00315 actor->get_alignment() >= Npc_actor::hostile &&
00316 actor->get_schedule_type() == Schedule::combat &&
00317 static_cast<Combat_schedule*>(actor->get_schedule())->
00318 has_started_battle())
00319 {
00320
00321
00322 nearby_hostile = true;
00323 break;
00324 }
00325 }
00326
00327 if( speed_section < 0.4 )
00328 {
00329 if( gwin->in_combat() )
00330 cursor = get_short_combat_arrow( dir );
00331 else
00332 cursor = get_short_arrow( dir );
00333 avatar_speed = 100*gwin->get_std_delay()/slow_speed_factor;
00334 }
00335 else if( speed_section < 0.8 || gwin->in_combat() || nearby_hostile )
00336 {
00337 if( gwin->in_combat() )
00338 cursor = get_medium_combat_arrow( dir );
00339 else
00340 cursor = get_medium_arrow( dir );
00341 if( gwin->in_combat() || nearby_hostile )
00342 avatar_speed = 100*gwin->get_std_delay()/medium_combat_speed_factor;
00343 else
00344 avatar_speed = 100*gwin->get_std_delay()/medium_speed_factor;
00345 }
00346 else
00347
00348 {
00349 cursor = get_long_arrow( dir );
00350 avatar_speed = 100*gwin->get_std_delay()/fast_speed_factor;
00351 }
00352 }
00353
00354 if (cursor != dontchange)
00355 set_shape(cursor);
00356 }