/** * @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 Provides mouse X and Y coordinates for mouse flying. */ static void input_mouseMove( SDL_Event* event ) { int mx, my; gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y ); player.mousex = mx; player.mousey = my; }
/** * @brief Provides mouse X and Y coordinates for mouse flying. */ static void input_mouseMove( SDL_Event* event ) { int mx, my; gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y ); player.mousex = (mx - (gl_screen.w / 2.)); player.mousey = (my - (gl_screen.h / 2.)); }
/** * @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; }
/** * @brief Handles a click event. */ static void input_clickevent( SDL_Event* event ) { unsigned int pid; Pilot *p; int mx, my, mxr, myr, pntid, jpid; int rx, ry, rh, rw, res; double x, y, m, r, rp, d, dp, px, py; double ang, angp, mouseang; Planet *pnt; JumpPoint *jp; HookParam hparam[2]; /* Generate hook. */ hparam[0].type = HOOK_PARAM_NUMBER; hparam[0].u.num = event->button.button; hparam[1].type = HOOK_PARAM_SENTINAL; hooks_runParam( "mouse", hparam ); /* 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; } /* Middle mouse enables mouse flying. */ if (event->button.button == SDL_BUTTON_MIDDLE) { player_toggleMouseFly(); return; } /* Mouse targetting is left only. */ if (event->button.button != SDL_BUTTON_LEFT) return; /* Player must not be NULL. */ if (player_isFlag(PLAYER_DESTROYED) || (player.p == NULL)) return; px = player.p->solid->pos.x; py = player.p->solid->pos.y; gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y ); gl_screenToGameCoords( &x, &y, (double)mx, (double)my ); if ((mx <= 15 || my <= 15 ) || (my >= gl_screen.h - 15 || mx >= gl_screen.w - 15)) { /* Border */ 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. */ } else { /* 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 */ m = 1; gui_radarGetRes( &res ); x = (mxr - (rx + rw / 2.)) * res + px; y = (myr - (ry + rh / 2.)) * res + py; } else /* Visual (on-screen) */ m = res = 1. / cam_getZoom(); dp = pilot_getNearestPos( player.p, &pid, x, y, 1 ); d = system_getClosest( cur_system, &pntid, &jpid, x, y ); rp = MAX( 1.5 * PILOT_SIZE_APROX * pilot_get(pid)->ship->gfx_space->sw / 2 * m, 10. * res); if (pntid >=0) { /* Planet is closer. */ pnt = cur_system->planets[ pntid ]; r = MAX( 1.5 * pnt->radius, 100. ); } else if (jpid >= 0) { jp = &cur_system->jumps[ jpid ]; r = MAX( 1.5 * jp->radius, 100. ); } else { r = 0.; } /* Reject pilot if it's too far or a valid asset is closer. */ if (dp > pow2(rp) || (d < pow2(r) && dp < pow2(rp) && dp > d)) pid = PLAYER_ID; if (d > pow2(r)) /* Planet or jump point is too far. */ jpid = pntid = -1; } if (pid != PLAYER_ID) { /* Apply an action if already selected. */ if (!pilot_isFlag(player.p, PILOT_DEAD) && (pid == player.p->target)) { p = pilot_get(pid); if (pilot_isDisabled(p) || pilot_isFlag(p, PILOT_BOARDABLE)) player_board(); else player_hail(); } else player_targetSet( pid ); } else if (pntid >= 0) { /* Planet is closest. */ if (pntid == player.p->nav_planet) { pnt = cur_system->planets[ pntid ]; if (planet_hasService(pnt, PLANET_SERVICE_LAND) && (!areEnemies( player.p->faction, pnt->faction ) || pnt->bribed )) player_land(); else player_hailPlanet(); } else player_targetPlanetSet( pntid ); } else if (jpid >= 0) { /* Jump point is closest. */ jp = &cur_system->jumps[ jpid ]; if (jpid == player.p->nav_hyperspace) { if (space_canHyperspace(player.p)) { if (!paused) player_autonavAbort(NULL); player_jump(); } else player_autonavStart(); } else player_targetHyperspaceSet( jpid ); } }
/** * @brief Handles input to the map overlay. */ int ovr_input( SDL_Event *event ) { unsigned int pid; Pilot *p; int mx, my; double x, y, r, rp; double d, dp; Planet *pnt; JumpPoint *jp; int pntid, jpid; /* 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; /* Selection. */ if (event->button.button == SDL_BUTTON_LEFT) { /* 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; /* Get nearest pilot and jump point/planet. */ dp = pilot_getNearestPos( player.p, &pid, x, y, 1 ); d = system_getClosest( cur_system, &pntid, &jpid, x, y ); p = pilot_get(pid); rp = MAX( 1.5 * PILOT_SIZE_APROX * p->ship->gfx_space->sw / 2, 20.*ovr_res ); if (pntid >=0) { /* Planet is closer. */ pnt = cur_system->planets[ pntid ]; r = MAX( 1.5 * pnt->radius, 20. * ovr_res ); } else if (jpid >= 0) { jp = &cur_system->jumps[ jpid ]; r = MAX( 1.5 * jp->radius, 20. * ovr_res ); } else r = 0.; /* Pilot is closest, or new jump point/planet is the same as the old. */ if ((dp < pow2(rp) && player.p->target != pid) && (dp < d || ((pntid >=0 && player.p->nav_planet == pntid) || (jpid >=0 && player.p->nav_planet == jpid)))) player_targetSet( pid ); else if ((pntid >= 0) && (d < pow2(r))) /* Planet is closest. */ player_targetPlanetSet( pntid ); else if ((jpid >= 0) && (d < pow2(r))) /* Jump point is closest. */ player_targetHyperspaceSet( jpid ); else return 0; return 1; } /* Autogo. */ else if (event->button.button == SDL_BUTTON_RIGHT) { if ((player.p == NULL) || pilot_isFlag( player.p, PILOT_MANUAL_CONTROL ) || pilot_isFlag( player.p, PILOT_HYP_PREP ) || pilot_isFlag( player.p, PILOT_HYP_BEGIN ) || pilot_isFlag( player.p, PILOT_HYPERSPACE )) return 1; /* 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; /* Go to position. */ player_autonavPos( x, y ); return 1; } return 0; }