/** * @brief Handles input to the map overlay. */ int ovr_input( SDL_Event *event ) { int mx, my; double x, y; /* We only want mouse events. */ if (event->type != SDL_MOUSEBUTTONDOWN) return 0; /* Player must not be NULL. */ if (player_isFlag(PLAYER_DESTROYED) || (player.p == NULL)) return 0; /* Player must not be dead. */ if (pilot_isFlag(player.p, PILOT_DEAD)) return 0; /* Mouse targeting only uses left and right buttons. */ if (event->button.button != SDL_BUTTON_LEFT && event->button.button != SDL_BUTTON_RIGHT) return 0; /* Translate from window to screen. */ mx = event->button.x; my = event->button.y; gl_windowToScreenPos( &mx, &my, mx, my ); /* Translate to space coords. */ x = ((double)mx - SCREEN_W/2.) * ovr_res; y = ((double)my - SCREEN_H/2.) * ovr_res; return input_clickPos( event, x, y, 1., 10. * ovr_res, 15. * ovr_res ); }
/** * @brief Handles a click event. */ static void input_clickevent( SDL_Event* event ) { unsigned int pid; int mx, my, mxr, myr, pntid, jpid; int rx, ry, rh, rw, res; int autonav; double x, y, zoom, px, py; double ang, angp, mouseang; HookParam hparam[2]; /* Generate hook. */ hparam[0].type = HOOK_PARAM_NUMBER; hparam[0].u.num = event->button.button; hparam[1].type = HOOK_PARAM_SENTINEL; hooks_runParam( "mouse", hparam ); #if !SDL_VERSION_ATLEAST(2,0,0) /* Handle zoom. */ if (event->button.button == SDL_BUTTON_WHEELUP) { input_clickZoom( 1.1 ); return; } else if (event->button.button == SDL_BUTTON_WHEELDOWN) { input_clickZoom( 0.9 ); return; } #endif /* !SDL_VERSION_ATLEAST(2,0,0) */ /* Player must not be NULL. */ if ((player.p == NULL) || player_isFlag(PLAYER_DESTROYED)) return; /* Player must not be dead. */ if (pilot_isFlag(player.p, PILOT_DEAD)) return; /* Middle mouse enables mouse flying. */ if (event->button.button == SDL_BUTTON_MIDDLE) { player_toggleMouseFly(); return; } /* Mouse targeting only uses left and right buttons. */ if (event->button.button != SDL_BUTTON_LEFT && event->button.button != SDL_BUTTON_RIGHT) return; autonav = (event->button.button == SDL_BUTTON_RIGHT) ? 1 : 0; px = player.p->solid->pos.x; py = player.p->solid->pos.y; gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y ); if ((mx <= 15 || my <= 15 ) || (my >= gl_screen.h - 15 || mx >= gl_screen.w - 15)) { /* Border targeting is handled as a special case, as it uses angles, * not coordinates. */ x = (mx - (gl_screen.w / 2.)) + px; y = (my - (gl_screen.h / 2.)) + py; mouseang = atan2(py - y, px - x); angp = pilot_getNearestAng( player.p, &pid, mouseang, 1 ); ang = system_getClosestAng( cur_system, &pntid, &jpid, x, y, mouseang ); if ((ABS(angle_diff(mouseang, angp)) > M_PI / 64) || ABS(angle_diff(mouseang, ang)) < ABS(angle_diff(mouseang, angp))) pid = PLAYER_ID; /* Pilot angle is too great, or planet/jump is closer. */ if (ABS(angle_diff(mouseang, ang)) > M_PI / 64 ) jpid = pntid = -1; /* Asset angle difference is too great. */ if (!autonav && pid != PLAYER_ID) { if (input_clickedPilot(pid)) return; } else if (pntid >= 0) { /* Planet is closest. */ if (input_clickedPlanet(pntid, autonav)) return; } else if (jpid >= 0) { /* Jump point is closest. */ if (input_clickedJump(jpid, autonav)) return; } /* Fall-through and handle as a normal click. */ } /* Radar targeting requires raw coordinates. */ mxr = event->button.x; myr = gl_screen.rh - event->button.y; gui_radarGetPos( &rx, &ry ); gui_radarGetDim( &rw, &rh ); if ((mxr > rx && mxr <= rx + rw ) && (myr > ry && myr <= ry + rh )) { /* Radar */ zoom = 1.; gui_radarGetRes( &res ); x = (mxr - (rx + rw / 2.)) * res + px; y = (myr - (ry + rh / 2.)) * res + py; if (input_clickPos( event, x, y, zoom, 10. * res, 15. * res )) return; } /* Visual (on-screen) */ gl_screenToGameCoords( &x, &y, (double)mx, (double)my ); zoom = res = 1. / cam_getZoom(); input_clickPos( event, x, y, zoom, 10. * res, 15. * res ); return; }