View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002713 | FSSCP | user interface | public | 2012-09-14 11:41 | 2014-04-17 11:29 |
Reporter | z64555 | Assigned To | z64555 | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | x86_32 | OS | Microsoft Windows | OS Version | XP SP3 |
Product Version | 3.6.14 RC6 | ||||
Target Version | 3.7.1 | ||||
Summary | 0002713: Freelook Mode unavailable | ||||
Description | As per: http://www.hard-light.net/forums/index.php?topic=68362.msg1349881#msg1349881 Freelook mode is currently inactive, possibly due to a TrackIR implementation. | ||||
Steps To Reproduce | In Misc Controls of the Options menu, assign "Free look mode" to any key. Play any mission, and try to use free look mode by holding down you assigned key, and use the mouse or joystick to change the view. | ||||
Tags | No tags attached. | ||||
|
z64_slew_r9226.patch (31,103 bytes)
Index: playerman/player.h =================================================================== --- playerman/player.h (revision 9226) +++ playerman/player.h (working copy) @@ -54,11 +54,14 @@ #define PLAYER_KILLED_SELF ( PLAYER_FLAGS_KILLED_SELF_MISSILES | PLAYER_FLAGS_KILLED_SELF_SHOCKWAVE ) -#define PCM_NORMAL 0 // normal flying mode -#define PCM_WARPOUT_STAGE1 1 // speed up to 40 km/s -#define PCM_WARPOUT_STAGE2 2 // flying towards and through warp hole -#define PCM_WARPOUT_STAGE3 3 // through warp hole, waiting for it to disapper. -#define PCM_SUPERNOVA 4 // supernova. lock everything to where it is. +enum Player_control_mode +{ + PCM_NORMAL, // normal flying mode + PCM_WARPOUT_STAGE1, // speed up to 40 km/s + PCM_WARPOUT_STAGE2, // flying towards and through warp hole + PCM_WARPOUT_STAGE3, // through warp hole, waiting for it to disapper. + PCM_SUPERNOVA // supernova. lock everything to where it is. +}; // 'lua game control' settings #define LGC_NORMAL (1<<0) // normal controls @@ -343,7 +346,7 @@ //extern control_info PlayerControls; extern int Player_use_ai; -extern int view_centering; +extern bool view_is_centering; extern angles chase_slew_angles; // The viewing angles in which viewer_slew_angles will chase to. extern void player_init(); // initialization per level Index: playerman/playercontrol.cpp =================================================================== --- playerman/playercontrol.cpp (revision 9226) +++ playerman/playercontrol.cpp (working copy) @@ -58,8 +58,8 @@ physics_info Descent_physics; // used when we want to control the player like the descent ship angles chase_slew_angles; -int view_centering = 0; - +bool view_is_centering = false; +bool freelook_mode_active; // Used to determine if slew mode (a.k.a FreeLook mode) is active int toggle_glide = 0; int press_glide = 0; @@ -73,6 +73,7 @@ DCF_BOOL( show_killer_weapon, Show_killer_weapon ) #endif +void playercontrol_read_mouse(int *axis, float frame_time); void playercontrol_read_stick(int *axis, float frame_time); void player_set_padlock_state(); @@ -80,30 +81,33 @@ * @brief Slew angles chase towards a value like they're on a spring. * @details When furthest away, move fastest. Minimum speed set so that doesn't take too long. When gets close, clamps to the value. */ -void chase_angles_to_value(angles *ap, angles *bp, int scale) +void chase_angles_to_value(angles *current_angles, angles *target_angles, int scale) { float sk; angles delta; // Make sure we actually need to do all this math. - if ((ap->p == bp->p) && (ap->h == bp->h)) + if ((current_angles->p == target_angles->p) && (current_angles->h == target_angles->h)) return; sk = 1.0f - scale*flRealframetime; CLAMP(sk, 0.0f, 1.0f); - delta.p = ap->p - bp->p; - delta.h = ap->h - bp->h; + delta.p = current_angles->p - target_angles->p; + delta.h = current_angles->h - target_angles->h; - ap->p = ap->p - delta.p * (1.0f - sk); - ap->h = ap->h - delta.h * (1.0f - sk); - // If we're very close, put ourselves at goal. - if ((fl_abs(delta.p) < 0.005f) && (fl_abs(delta.h) < 0.005f)) { - ap->p = bp->p; - ap->h = bp->h; + if ((fl_abs(delta.p) < 0.005f) && (fl_abs(delta.h) < 0.005f)) + { + current_angles->p = target_angles->p; + current_angles->h = target_angles->h; } + else // Else, apply the changes + { + current_angles->p -= ( delta.p * (1.0f - sk) ); + current_angles->h -= ( delta.h * (1.0f - sk) ); + } } angles Viewer_slew_angles_delta; @@ -111,65 +115,168 @@ void view_modify(angles *ma, angles *da, float max_p, float max_h, float frame_time) { + // Digital inputs int axis[NUM_JOY_AXIS_ACTIONS]; - float t = 0; - float u = 0; + float t = 0.0f; + float u = 0.0f; + // Analog inputs + float h = 0.0f; + float p = 0.0f; vec3d trans = ZERO_VECTOR; - if ( Viewer_mode & VM_EXTERNAL) { - if (! (Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { - t = t + (check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT)); - u = u + (check_control_timef(PITCH_BACK) - check_control_timef(PITCH_FORWARD)); - } else { + if ( Viewer_mode & VM_EXTERNAL) + { + if (! (Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) + { + // Digital + // May have to look at this again later... + // YAW_LEFT -> SLEW_LEFT YAW_RIGHT -> SLEW_RIGHT + // PITCH_BACK -> SLEW_UP PITCH_FORWARD -> SLEW_DOWN + t = (check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT)); + u = (check_control_timef(PITCH_BACK) - check_control_timef(PITCH_FORWARD)); + + // Analog + if( Use_mouse_to_fly ) + { + // Use normal mouse mode for slew + playercontrol_read_mouse(axis, frame_time); + } + else + { + // Use joystick for slew + playercontrol_read_stick(axis, frame_time); + } + + h = -f2fl( axis[0] ); + p = -f2fl( axis[1] ); + } + else + { + // External camera is locked in place, nothing to do here return; } - } else if ( gTirDll_TrackIR.Enabled( ) ) { - gTirDll_TrackIR.Query(); - ma->h = -PI2*(gTirDll_TrackIR.GetYaw()); - ma->p = PI2*(gTirDll_TrackIR.GetPitch()); + } + else // We're in the cockpit + { + if ( gTirDll_TrackIR.Enabled( ) ) + { + gTirDll_TrackIR.Query(); + ma->h = -PI2*(gTirDll_TrackIR.GetYaw()); + ma->p = PI2*(gTirDll_TrackIR.GetPitch()); - trans.xyz.x = -0.4f*gTirDll_TrackIR.GetX(); - trans.xyz.y = 0.4f*gTirDll_TrackIR.GetY(); - trans.xyz.z = -gTirDll_TrackIR.GetZ(); + trans.xyz.x = -0.4f*gTirDll_TrackIR.GetX(); + trans.xyz.y = 0.4f*gTirDll_TrackIR.GetY(); + trans.xyz.z = -gTirDll_TrackIR.GetZ(); - if(trans.xyz.z < 0) - trans.xyz.z = 0.0f; + if(trans.xyz.z < 0) + { + trans.xyz.z = 0.0f; + } - vm_vec_unrotate(&leaning_position,&trans,&Eye_matrix); - } else { - // View slewing commands commented out until we can safely add more commands in the pilot code. + vm_vec_unrotate(&leaning_position,&trans,&Eye_matrix); + } + else if (freelook_mode_active) // Freelook mode is enabled. Use flight controls for slewing + { + // Digital + t = (check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT)); + u = (check_control_timef(PITCH_BACK) - check_control_timef(PITCH_FORWARD)); + + // Analog + if( Use_mouse_to_fly ) + { + // Use normal mouse mode for slew + playercontrol_read_mouse(axis, frame_time); + } + else + { + // Use joystick for slew + playercontrol_read_stick(axis, frame_time); + } + + h = -f2fl( axis[0] ); + p = -f2fl( axis[1] ); + } + else // freelook mode is disabled. Use only slew commands + { + /** Commented out until Slew commands are actually doable + t = (check_control_timef(SLEW_LEFT) - check_control_timef(SLEW_RIGHT)); + u = (check_control_timef(SLEW_UP) - check_control_timef(SLEW_DOWN)); + */ + + if( !Use_mouse_to_fly ) + { + // Mouse now controls slew when not being used as flight controler + playercontrol_read_mouse(axis,frame_time); + + h = -f2fl( axis[0] ); + p = -f2fl( axis[1] ); + } // Else, don't do any slewing + } } - if (t != 0.0f) - da->h += t; - else - da->h = 0.0f; + if(!view_is_centering) + { + // Combine Analog and Digital Stip out any floating point errors before adding veiw changes + if ((t != 0.0f) && (h != 0.0f)) + { + da->h += (t + h); + } + else if (t!= 0.0f) + { + da->h += t; + } + else if (h != 0.0f) + { + da->h = h; // Careful! playercontrol_read_mouse returns a delta, not an absolute position + } + else + { + da->h = 0.0f; + } - if (u != 0.0f) - da->p += u; - else - da->p = 0.0f; - - da->b = 0.0f; + if ((u != 0.0f) && (p != 0.0f)) + { + da->p += (u + p); + } + else if (u!= 0.0f) + { + da->p += u; + } + else if (p != 0.0f) + { + da->p = p; // Careful! playercontrol_read_mouse returns a delta, not an absolute position + } + else + { + da->p = 0.0f; + } - playercontrol_read_stick(axis, frame_time); + da->b = 0.0f; // Twisting the veiw isn't very helpful, anyway - if (( Viewer_mode & VM_EXTERNAL ) && !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED)) { - // check the heading on the x and y axes - da->h -= f2fl( axis[0] ); - da->p -= f2fl( axis[1] ); - } + // Saturate readings + if (da->h > 1.0f) + { + da->h = 1.0f; + } + else if (da->h < -1.0f) + { + da->h = -1.0f; + } - if (da->h > 1.0f) - da->h = 1.0f; - else if (da->h < -1.0f) - da->h = -1.0f; + if (da->p > 1.0f) + { + da->p = 1.0f; + } + else if (da->p < -1.0f) + { + da->p = -1.0f; + } + } + else // View is centering + { + return; + } - if (da->p > 1.0f) - da->p = 1.0f; - else if (da->p < -1.0f) - da->p = -1.0f; - if ( (Game_time_compression >= F1_0) && !(Viewer_mode & VM_EXTERNAL) ) { ma->p += 2*da->p * flFrametime; @@ -186,14 +293,22 @@ } if (ma->p > max_p) + { ma->p = max_p; + } else if (ma->p < -max_p) + { ma->p = -max_p; + } if (ma->h > max_h) + { ma->h = max_h; + } else if (ma->h < -max_h) + { ma->h = -max_h; + } } void do_view_track_target(float frame_time) @@ -262,7 +377,7 @@ /** - * When PAD0 is pressed, keypad controls viewer direction slewing. + * When VIEW_SLEW is pressed, pitch and heading controls viewer direction slewing. */ void do_view_slew(float frame_time) { @@ -350,6 +465,41 @@ ci->forward_cruise_percent = oldspeed; } + +// Read the 3 axis Mouse (with sensitivy scaling). This is its own function +// so we can use it like a normal mouse in freelook mode and still use it as +// a joystick in normal flight modes. +void playercontrol_read_mouse(int *axis, float frame_time) +{ + int dx, dy, dz; + float factor; + + factor = (float) Mouse_sensitivity + 1.77f; + factor = factor * factor / frame_time / 0.6f; + + mouse_get_delta(&dx, &dy, &dz); + + if ( Invert_axis[0] ) + { + dx = -dx; + } + + if ( Invert_axis[1] ) + { + dy = -dy; + } + + if ( Invert_axis[3] ) + { + dz = -dz; + } + + axis[0] = (int) ((float) dx * factor); + axis[1] = (int) ((float) dy * factor); + axis[3] = (int) ((float) dz * factor); +} + + // Read the 4 joystick axis. This is its own function // because we only want to read it at a certain rate, // since it takes time. @@ -379,100 +529,113 @@ axis[i] = Joystick_saved_reading[i]; } - if (Use_mouse_to_fly) { - int dx, dy, dz; - float factor; + if (Use_mouse_to_fly) + { + int mouse_axis[4]; - factor = (float) Mouse_sensitivity + 1.77f; - factor = factor * factor / frame_time / 0.6f; - - mouse_get_delta(&dx, &dy, &dz); - - if ( Invert_axis[0] ) { - dx = -dx; - } - - if ( Invert_axis[1] ) { - dy = -dy; - } - - if ( Invert_axis[3] ) { - dz = -dz; - } - - axis[0] += (int) ((float) dx * factor); - axis[1] += (int) ((float) dy * factor); - axis[3] += (int) ((float) dz * factor); + playercontrol_read_mouse(mouse_axis, frame_time); + axis[0] += mouse_axis[0]; + axis[1] += mouse_axis[1]; + axis[2] += mouse_axis[2]; } } +// z64: bit of a misnomer here +// Engine Controls: Full, 2/3, 1/3, +5%, -5% +// View Controls: External, Chase, Cockpit void read_keyboard_controls( control_info * ci, float frame_time, physics_info *pi ) { float kh=0.0f, scaled, newspeed, delta, oldspeed; - int axis[NUM_JOY_AXIS_ACTIONS], slew_active=1; + int axis[NUM_JOY_AXIS_ACTIONS]; static int afterburner_last = 0; static float analog_throttle_last = 9e9f; static int override_analog_throttle = 0; static float savedspeed = ci->forward_cruise_percent; //Backslash - int ok_to_read_ci_pitch_yaw=1; + bool ok_to_read_ci_pitch_yaw = true; int centering_speed = 7; // the scale speed in which the camera will smoothly center when the player presses Center View oldspeed = ci->forward_cruise_percent; player_control_reset_ci( ci ); - if ( Viewer_mode & VM_EXTERNAL ) { + if ( Viewer_mode & VM_EXTERNAL ) + { control_used(VIEW_EXTERNAL); - if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { - ok_to_read_ci_pitch_yaw=0; + if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) + { + ok_to_read_ci_pitch_yaw = false; } do_view_external(frame_time); do_thrust_keys(ci); - slew_active=0; - } else if ( Viewer_mode & VM_CHASE ) { + freelook_mode_active = false; + } + else if ( Viewer_mode & VM_CHASE ) + { do_view_chase(frame_time); - slew_active=0; - } else { // We're in the cockpit. - if (view_centering) { + freelook_mode_active = false; + } + else + { // We're in the cockpit. + if (view_is_centering) + { // If we're centering the view, check to see if we're actually centered and bypass any view modifications // until the view has finally been centered. - if ((Viewer_slew_angles.h == 0.0f) && (Viewer_slew_angles.p == 0.0f)) { - view_centering = 0; // if the view has been centered, allow the player to freelook again. + if ((Viewer_slew_angles.h == 0.0f) && (Viewer_slew_angles.p == 0.0f)) + { + view_is_centering = false; // if the view has been centered, allow the player to freelook again. } - slew_active = 0; - } else if ( Viewer_mode & VM_TRACK ) { // Player's vision will track current target. + freelook_mode_active = false; + } + else if ( Viewer_mode & VM_TRACK ) + { // Player's vision will track current target. do_view_track_target(frame_time); - } else { - // The Center View command check is here because - // we don't want the player centering the view in target padlock mode - if (check_control_timef(VIEW_CENTER) && !view_centering) { - view_centering = 1; - slew_active = 0; + } + else + { + // We're not centering the view currently, nor are we tracking any targets + if ( check_control_timef(VIEW_SLEW) ) + { + // Enable slewing/freelook mode + freelook_mode_active = true; + ok_to_read_ci_pitch_yaw = false; } + else if ( check_control_timef(VIEW_CENTER) || freelook_mode_active ) + { + // Start centering the view if the VIEW_CENTER control was active, or the player previously used freelook mode + view_is_centering = true; + // ok_to_read_ci_pitch_yaw = true; // This is already handled by initialization + freelook_mode_active = false; + } // Else, do nothing + } + do_view_slew(frame_time); - // Orthogonal padlock views moved here in order to get the springy chase effect when transitioning. player_set_padlock_state(); - - } } - if ( ok_to_read_ci_pitch_yaw ) { - // From keyboard... + if ( ok_to_read_ci_pitch_yaw ) + { do_thrust_keys(ci); - if ( check_control(BANK_WHEN_PRESSED) ) { + // Bank and Yaw controls (Keyboard) + if ( check_control(BANK_WHEN_PRESSED) ) + { ci->bank = check_control_timef(BANK_LEFT) + check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT) - check_control_timef(BANK_RIGHT); ci->heading = 0.0f; - } else { + } + else + { kh = (check_control_timef(YAW_RIGHT) - check_control_timef(YAW_LEFT)) / 8.0f; - if (kh == 0.0f) { + if (kh == 0.0f) + { ci->heading = 0.0f; - - } else if (kh > 0.0f) { + } + else if (kh > 0.0f) + { if (ci->heading < 0.0f) ci->heading = 0.0f; - - } else { // kh < 0 + } + else // kh < 0 + { if (ci->heading > 0.0f) ci->heading = 0.0f; } @@ -483,36 +646,51 @@ ci->heading += kh; kh = (check_control_timef(PITCH_FORWARD) - check_control_timef(PITCH_BACK)) / 8.0f; - if (kh == 0.0f) { + if (kh == 0.0f) + { ci->pitch = 0.0f; - } else if (kh > 0.0f) { + } + else if (kh > 0.0f) + { if (ci->pitch < 0.0f) + { ci->pitch = 0.0f; - - } else { // kh < 0 + } + } + else // kh < 0 + { if (ci->pitch > 0.0f) + { ci->pitch = 0.0f; + } } ci->pitch += kh; } - if ( !slew_active ) { - // If we're not in a view that slews (ie, not a cockpit view), make the viewer slew angles spring to the center. + // If we're not in a view that slews (ie, not a cockpit view), make the viewer slew angles spring to the center. + if ( !freelook_mode_active ) + { chase_slew_angles.h = 0.0f; chase_slew_angles.p = 0.0f; } chase_angles_to_value(&Viewer_slew_angles, &chase_slew_angles, centering_speed); - if (!(Game_mode & GM_DEAD)) { - if ( button_info_query(&Player->bi, ONE_THIRD_THROTTLE) ) { + if (!(Game_mode & GM_DEAD)) + { + // Engine Controls + if ( button_info_query(&Player->bi, ONE_THIRD_THROTTLE) ) + { control_used(ONE_THIRD_THROTTLE); player_clear_speed_matching(); - if ( Player->ci.forward_cruise_percent < 33.3f ) { + + if ( Player->ci.forward_cruise_percent < 33.3f ) + { snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_UP)], 0.0f ); - - } else if ( Player->ci.forward_cruise_percent > 33.3f ) { + } + else if ( Player->ci.forward_cruise_percent > 33.3f ) + { snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_DOWN)], 0.0f ); } @@ -520,13 +698,16 @@ override_analog_throttle = 1; } - if ( button_info_query(&Player->bi, TWO_THIRDS_THROTTLE) ) { + if ( button_info_query(&Player->bi, TWO_THIRDS_THROTTLE) ) + { control_used(TWO_THIRDS_THROTTLE); player_clear_speed_matching(); - if ( Player->ci.forward_cruise_percent < 66.6f ) { + if ( Player->ci.forward_cruise_percent < 66.6f ) + { snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_UP)], 0.0f ); - - } else if (Player->ci.forward_cruise_percent > 66.6f) { + } + else if (Player->ci.forward_cruise_percent > 66.6f) + { snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_DOWN)], 0.0f ); } @@ -534,24 +715,32 @@ override_analog_throttle = 1; } - if ( button_info_query(&Player->bi, PLUS_5_PERCENT_THROTTLE) ) { + if ( button_info_query(&Player->bi, PLUS_5_PERCENT_THROTTLE) ) + { control_used(PLUS_5_PERCENT_THROTTLE); Player->ci.forward_cruise_percent += 5.0f; if (Player->ci.forward_cruise_percent > 100.0f) + { Player->ci.forward_cruise_percent = 100.0f; + } } - if ( button_info_query(&Player->bi, MINUS_5_PERCENT_THROTTLE) ) { + if ( button_info_query(&Player->bi, MINUS_5_PERCENT_THROTTLE) ) + { control_used(MINUS_5_PERCENT_THROTTLE); Player->ci.forward_cruise_percent -= 5.0f; if (Player->ci.forward_cruise_percent < 0.0f) + { Player->ci.forward_cruise_percent = 0.0f; + } } - if ( button_info_query(&Player->bi, ZERO_THROTTLE) ) { + if ( button_info_query(&Player->bi, ZERO_THROTTLE) ) + { control_used(ZERO_THROTTLE); player_clear_speed_matching(); - if ( ci->forward_cruise_percent > 0.0f && Player_obj->phys_info.fspeed > 0.5) { + if ( ci->forward_cruise_percent > 0.0f && Player_obj->phys_info.fspeed > 0.5) + { snd_play( &Snds[ship_get_sound(Player_obj, SND_ZERO_THROTTLE)], 0.0f ); } @@ -559,10 +748,12 @@ override_analog_throttle = 1; } - if ( button_info_query(&Player->bi, MAX_THROTTLE) ) { + if ( button_info_query(&Player->bi, MAX_THROTTLE) ) + { control_used(MAX_THROTTLE); player_clear_speed_matching(); - if ( ci->forward_cruise_percent < 100.0f ) { + if ( ci->forward_cruise_percent < 100.0f ) + { snd_play( &Snds[ship_get_sound(Player_obj, SND_FULL_THROTTLE)], 0.0f ); } @@ -571,23 +762,28 @@ } // AL 12-29-97: If afterburner key is down, player should have full forward thrust (even if afterburners run out) - if ( check_control(AFTERBURNER) ) { + if ( check_control(AFTERBURNER) ) + { ci->forward = 1.0f; } - if ( check_control(REVERSE_THRUST) && check_control(AFTERBURNER) ) { + if ( check_control(REVERSE_THRUST) && check_control(AFTERBURNER) ) + { ci->forward = -pi->max_rear_vel * 1.0f; } - if ( Player->flags & PLAYER_FLAGS_MATCH_TARGET ) { - if ( (Player_ai->last_target == Player_ai->target_objnum) && (Player_ai->target_objnum != -1) && ( ci->forward_cruise_percent == oldspeed) ) { + if ( Player->flags & PLAYER_FLAGS_MATCH_TARGET ) + { + if ( (Player_ai->last_target == Player_ai->target_objnum) && (Player_ai->target_objnum != -1) && ( ci->forward_cruise_percent == oldspeed) ) + { float tspeed, pmax_speed; object *targeted_objp = &Objects[Player_ai->target_objnum]; tspeed = targeted_objp->phys_info.speed; //changed from fspeed. If target is reversing, sliding, or gliding we still want to keep up. -- Backslash // maybe need to get speed from docked partner - if ( tspeed < MATCH_SPEED_THRESHOLD ) { + if ( tspeed < MATCH_SPEED_THRESHOLD ) + { Assert(targeted_objp->type == OBJ_SHIP); // Goober5000 @@ -600,63 +796,92 @@ // Note, if closer than 100 units, scale down speed a bit. Prevents repeated collisions. -- MK, 12/17/97 float dist = vm_vec_dist(&Player_obj->pos, &targeted_objp->pos); - if (dist < 100.0f) { + if (dist < 100.0f) + { tspeed = tspeed * (0.5f + dist/200.0f); } //SUSHI: If gliding, don't do anything for speed matching if (!( (Objects[Player->objnum].phys_info.flags & PF_GLIDING) || (Objects[Player->objnum].phys_info.flags & PF_FORCE_GLIDE) )) { pmax_speed = Ships[Player_obj->instance].current_max_speed; - if (pmax_speed > 0.0f) { + if (pmax_speed > 0.0f) + { ci->forward_cruise_percent = (tspeed / pmax_speed) * 100.0f; - } else { + } + else + { ci->forward_cruise_percent = 0.0f; } + override_analog_throttle = 1; } - } else + } + else + { Player->flags &= ~PLAYER_FLAGS_MATCH_TARGET; + } } // code to read joystick axis for pitch/heading. Code to read joystick buttons // for bank. - if ( !(Game_mode & GM_DEAD) ) { + if ( !(Game_mode & GM_DEAD) ) // Redundant check is redundant + { playercontrol_read_stick(axis, frame_time); - } else { + } + else + { axis[0] = axis[1] = axis[2] = axis[3] = axis[4] = 0; } - if (Axis_map_to[JOY_HEADING_AXIS] >= 0) { - // check the heading on the x axis - if ( check_control(BANK_WHEN_PRESSED) ) { - delta = f2fl( axis[JOY_HEADING_AXIS] ); - if ( (delta > 0.05f) || (delta < -0.05f) ) { - ci->bank -= delta; + if (ok_to_read_ci_pitch_yaw) + { + if (Axis_map_to[JOY_HEADING_AXIS] >= 0) + { + // Check the heading axis and apply it to either heading or bank angles + if ( check_control(BANK_WHEN_PRESSED) ) + { + delta = f2fl( axis[JOY_HEADING_AXIS] ); + if ( (delta > 0.05f) || (delta < -0.05f) ) + { + ci->bank -= delta; + } } - } else { - ci->heading += f2fl( axis[JOY_HEADING_AXIS] ); + else + { + ci->heading += f2fl( axis[JOY_HEADING_AXIS] ); + } } - } - // check the pitch on the y axis - if (Axis_map_to[JOY_PITCH_AXIS] >= 0) { - ci->pitch -= f2fl( axis[JOY_PITCH_AXIS] ); + // Check the pitch axis + if (Axis_map_to[JOY_PITCH_AXIS] >= 0) + { + ci->pitch -= f2fl( axis[JOY_PITCH_AXIS] ); + } } + else // We're in slew mode, so stop rotating the player craft before the pilot becomes billious + { + ci->pitch = 0.0f; + ci->heading = 0.0f; + } - if (Axis_map_to[JOY_BANK_AXIS] >= 0) { + // Check the bank axis + if (Axis_map_to[JOY_BANK_AXIS] >= 0) + { ci->bank -= f2fl( axis[JOY_BANK_AXIS] ) * 1.5f; } - // axis 2 is for throttle - if (Axis_map_to[JOY_ABS_THROTTLE_AXIS] >= 0) { + // Check the absolut throttle axis + if (Axis_map_to[JOY_ABS_THROTTLE_AXIS] >= 0) + { scaled = (float) axis[JOY_ABS_THROTTLE_AXIS] * 1.2f / (float) F1_0 - 0.1f; // convert to -0.1 - 1.1 range oldspeed = ci->forward_cruise_percent; newspeed = (1.0f - scaled) * 100.0f; delta = analog_throttle_last - newspeed; - if (!override_analog_throttle || (delta < -1.5f) || (delta > 1.5f)) { + if (!override_analog_throttle || (delta < -1.5f) || (delta > 1.5f)) + { ci->forward_cruise_percent = newspeed; analog_throttle_last = newspeed; override_analog_throttle = 0; @@ -664,62 +889,83 @@ } if (Axis_map_to[JOY_REL_THROTTLE_AXIS] >= 0) + { ci->forward_cruise_percent += f2fl(axis[JOY_REL_THROTTLE_AXIS]) * 100.0f * frame_time; + } + // Saturate speed to be within 0 to 100% if ( ci->forward_cruise_percent > 100.0f ) + { ci->forward_cruise_percent = 100.0f; + } + if ( ci->forward_cruise_percent < 0.0f ) + { ci->forward_cruise_percent = 0.0f; + } // set up the firing stuff. Read into control info ala Descent so that weapons will be // created during the object simulation phase, and not immediately as was happening before. //keyboard: fire the current primary weapon - if (check_control(FIRE_PRIMARY)) { + if (check_control(FIRE_PRIMARY)) + { ci->fire_primary_count++; } // for debugging, check to see if the debug key is down -- if so, make fire the debug laser instead #ifndef NDEBUG - if ( keyd_pressed[KEY_DEBUG_KEY] ) { + if ( keyd_pressed[KEY_DEBUG_KEY] ) + { ci->fire_debug_count = ci->fire_primary_count; ci->fire_primary_count = 0; } #endif // keyboard: fire the current secondary weapon - if (check_control(FIRE_SECONDARY)) { + if (check_control(FIRE_SECONDARY)) + { ci->fire_secondary_count++; // if we're a multiplayer client, set our accum bits now - if( MULTIPLAYER_CLIENT && (Net_player != NULL)){ + if( MULTIPLAYER_CLIENT && (Net_player != NULL)) + { Net_player->s_info.accum_buttons |= OOC_FIRE_SECONDARY; } } // keyboard: launch countermeasures, but not if AI controlling Player - if (button_info_query(&Player->bi, LAUNCH_COUNTERMEASURE) && !Player_use_ai) { + if (button_info_query(&Player->bi, LAUNCH_COUNTERMEASURE) && !Player_use_ai) + { control_used(LAUNCH_COUNTERMEASURE); ci->fire_countermeasure_count++; hud_gauge_popup_start(HUD_CMEASURE_GAUGE); } // see if the afterburner has been started (keyboard + joystick) - if (check_control(AFTERBURNER) && !Player_use_ai) { - if (!afterburner_last) { + if (check_control(AFTERBURNER) && !Player_use_ai) + { + if (!afterburner_last) + { Assert(Player_ship); - if ( !(Ship_info[Player_ship->ship_info_index].flags & SIF_AFTERBURNER) ) { + if ( !(Ship_info[Player_ship->ship_info_index].flags & SIF_AFTERBURNER) ) + { gamesnd_play_error_beep(); - } else { + } + else + { ci->afterburner_start = 1; } } afterburner_last = 1; - - } else { + } + else + { if (afterburner_last) + { ci->afterburner_stop = 1; + } afterburner_last = 0; } @@ -727,17 +973,22 @@ // new gliding systems combining code by Backslash, Turey, Kazan, and WMCoolmon // Check for toggle button pressed. - if ( button_info_query(&Player->bi, TOGGLE_GLIDING) ) { + if ( button_info_query(&Player->bi, TOGGLE_GLIDING) ) + { control_used(TOGGLE_GLIDING); - if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) { + + if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) + { toggle_glide = !toggle_glide; } } // This logic is a bit tricky. It checks to see if the glide_when_pressed button is in a different state // than press_glide. Since it sets press_glide equal to glide_when_pressed inside of this if statement, // this only evaluates to true when the state of the button is different than it was last time. - if ( check_control(GLIDE_WHEN_PRESSED) != press_glide ) { - if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) { + if ( check_control(GLIDE_WHEN_PRESSED) != press_glide ) + { + if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) + { // This only works if check_control returns only 1 or 0. Shouldn't be a problem, // but this comment's here just in case it is. press_glide = !press_glide; @@ -745,63 +996,81 @@ } // if the player is warping out, cancel gliding - if (Player_ship->flags & SF_DEPART_WARP) { + if (Player_ship->flags & SF_DEPART_WARP) + { toggle_glide = 0; press_glide = 0; } // Do we want to be gliding? - if ( toggle_glide || press_glide ) { + if ( toggle_glide || press_glide ) + { // Probably don't need to do this check, but just in case... - if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) { + if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) + { // Only bother doing this if we need to. - if ( toggle_glide && press_glide ) { + if ( toggle_glide && press_glide ) + { // Overkill -- if gliding is toggled on and glide_when_pressed is pressed, turn glide off - if ( object_get_gliding(Player_obj) && !object_glide_forced(Player_obj) ) { + if ( object_get_gliding(Player_obj) && !object_glide_forced(Player_obj) ) + { object_set_gliding(Player_obj, false); ci->forward_cruise_percent = savedspeed; press_glide = !press_glide; snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_UP)], 0.0f ); } - } else if ( !object_get_gliding(Player_obj) ) { + } + else if ( !object_get_gliding(Player_obj) ) + { object_set_gliding(Player_obj, true); savedspeed = ci->forward_cruise_percent; ci->forward_cruise_percent = 0.0f; override_analog_throttle = 1; - if (Ship_info[Player_ship->ship_info_index].glide_start_snd > 0) { + if (Ship_info[Player_ship->ship_info_index].glide_start_snd > 0) + { //If a custom glide start sound was specified, play it snd_play( &Snds[Ship_info[Player_ship->ship_info_index].glide_start_snd], 0.0f ); - } else { + } + else + { //If glide_start_snd wasn't set (probably == 0), use the default throttle down sound snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_DOWN)], 0.0f ); } } } - } else { + } + else + { // Probably don't need to do the second half of this check, but just in case... - if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) { + if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) + { // Only bother doing this if we need to. - if ( object_get_gliding(Player_obj) && !object_glide_forced(Player_obj) ) { + if ( object_get_gliding(Player_obj) && !object_glide_forced(Player_obj) ) + { object_set_gliding(Player_obj, false); ci->forward_cruise_percent = savedspeed; - if (Ship_info[Player_ship->ship_info_index].glide_end_snd > 0) { + if (Ship_info[Player_ship->ship_info_index].glide_end_snd > 0) + { //If a custom glide end sound was specified, play it snd_play( &Snds[Ship_info[Player_ship->ship_info_index].glide_end_snd], 0.0f ); - } else { + } + else + { //If glide_end_snd wasn't set (probably == 0), use the default throttle up sound snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_UP)], 0.0f ); } } } } - } - if ( (Viewer_mode & VM_EXTERNAL) ) { - if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { - ci->heading=0.0f; - ci->pitch=0.0f; - ci->bank=0.0f; + if ( (Viewer_mode & VM_EXTERNAL) ) + { + if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) + { + ci->heading = 0.0f; + ci->pitch = 0.0f; + ci->bank = 0.0f; } } } |
|
Attached a patch that enables freelook mode again. When the Freelook mode key is held down, the flight controls move the player's around the cockpit, and the craft stops turning (just like in retail FS2). Currently, Slew commands are belayed until 3.7 rolls around. I also wanted to use the mouse to control slew when it wasn't being used as a flight controller, but apparently there's more work involved... |
|
The patch looks okay but why are you putting all the curly braces on their own line even on lines you haven't even changed? |
|
Discussed this over IRC, but I'm Posting this for records... I wasn't aware that the tab style should not have been messed with if that's all that was being modified for a particular block. (Although this should've been apparent to me to begin with.) New patch posted, this time with less bracket warring and with some more clarification on the axes that the mouse maps to... with an added bonus of some Doxygen documentation. Mouse still doesn't control slew when "Use_mouse_to_fly" is false, but I guess that has to wait for another day. :( |
|
z64_slew_r9256.patch (26,397 bytes)
Index: controlconfig/controlsconfig.cpp =================================================================== --- controlconfig/controlsconfig.cpp (revision 9256) +++ controlconfig/controlsconfig.cpp (working copy) @@ -2212,43 +2212,43 @@ // joy_get_scaled_reading will return a value represents the joystick pos from -1 to +1 (fixed point) *h = 0; - if (Axis_map_to[0] >= 0) { + if (Axis_map_to[JOY_HEADING_AXIS] >= 0) { *h = joy_get_scaled_reading(axes_values[Axis_map_to[0]], Axis_map_to[0]); } *p = 0; - if (Axis_map_to[1] >= 0) { + if (Axis_map_to[JOY_PITCH_AXIS] >= 0) { *p = joy_get_scaled_reading(axes_values[Axis_map_to[1]], Axis_map_to[1]); } *b = 0; - if (Axis_map_to[2] >= 0) { + if (Axis_map_to[JOY_BANK_AXIS] >= 0) { *b = joy_get_scaled_reading(axes_values[Axis_map_to[2]], Axis_map_to[2]); } *ta = 0; - if (Axis_map_to[3] >= 0) { + if (Axis_map_to[JOY_ABS_THROTTLE_AXIS] >= 0) { *ta = joy_get_unscaled_reading(axes_values[Axis_map_to[3]], Axis_map_to[3]); } *tr = 0; - if (Axis_map_to[4] >= 0) { + if (Axis_map_to[JOY_REL_THROTTLE_AXIS] >= 0) { *tr = joy_get_scaled_reading(axes_values[Axis_map_to[4]], Axis_map_to[4]); } - if (Invert_axis[0]) { + if (Invert_axis[JOY_HEADING_AXIS]) { *h = -(*h); } - if (Invert_axis[1]) { + if (Invert_axis[JOY_PITCH_AXIS]) { *p = -(*p); } - if (Invert_axis[2]) { + if (Invert_axis[JOY_BANK_AXIS]) { *b = -(*b); } - if (Invert_axis[3]) { + if (Invert_axis[JOY_ABS_THROTTLE_AXIS]) { *ta = F1_0 - *ta; } - if (Invert_axis[4]) { + if (Invert_axis[JOY_REL_THROTTLE_AXIS]) { *tr = -(*tr); } Index: playerman/player.h =================================================================== --- playerman/player.h (revision 9256) +++ playerman/player.h (working copy) @@ -54,11 +54,14 @@ #define PLAYER_KILLED_SELF ( PLAYER_FLAGS_KILLED_SELF_MISSILES | PLAYER_FLAGS_KILLED_SELF_SHOCKWAVE ) -#define PCM_NORMAL 0 // normal flying mode -#define PCM_WARPOUT_STAGE1 1 // speed up to 40 km/s -#define PCM_WARPOUT_STAGE2 2 // flying towards and through warp hole -#define PCM_WARPOUT_STAGE3 3 // through warp hole, waiting for it to disapper. -#define PCM_SUPERNOVA 4 // supernova. lock everything to where it is. +enum Player_control_mode +{ + PCM_NORMAL, // normal flying mode + PCM_WARPOUT_STAGE1, // speed up to 40 km/s + PCM_WARPOUT_STAGE2, // flying towards and through warp hole + PCM_WARPOUT_STAGE3, // through warp hole, waiting for it to disapper. + PCM_SUPERNOVA // supernova. lock everything to where it is. +}; // 'lua game control' settings #define LGC_NORMAL (1<<0) // normal controls @@ -343,7 +346,7 @@ //extern control_info PlayerControls; extern int Player_use_ai; -extern int view_centering; +extern bool view_is_centering; extern angles chase_slew_angles; // The viewing angles in which viewer_slew_angles will chase to. extern void player_init(); // initialization per level Index: playerman/playercontrol.cpp =================================================================== --- playerman/playercontrol.cpp (revision 9256) +++ playerman/playercontrol.cpp (working copy) @@ -34,6 +34,7 @@ #include "network/multiutil.h" #include "network/multi_obj.h" #include "parse/parselo.h" +#include "controlconfig/controlsconfig.h" #ifndef NDEBUG #include "io/key.h" @@ -58,8 +59,8 @@ physics_info Descent_physics; // used when we want to control the player like the descent ship angles chase_slew_angles; -int view_centering = 0; - +bool view_is_centering = false; +bool freelook_mode_active; // Used to determine if slew mode (a.k.a FreeLook mode) is active int toggle_glide = 0; int press_glide = 0; @@ -73,6 +74,7 @@ DCF_BOOL( show_killer_weapon, Show_killer_weapon ) #endif +void playercontrol_read_mouse(int *axis, float frame_time); void playercontrol_read_stick(int *axis, float frame_time); void player_set_padlock_state(); @@ -80,104 +82,180 @@ * @brief Slew angles chase towards a value like they're on a spring. * @details When furthest away, move fastest. Minimum speed set so that doesn't take too long. When gets close, clamps to the value. */ -void chase_angles_to_value(angles *ap, angles *bp, int scale) +void chase_angles_to_value(angles *current_angles, angles *target_angles, int scale) { float sk; angles delta; // Make sure we actually need to do all this math. - if ((ap->p == bp->p) && (ap->h == bp->h)) + if ((current_angles->p == target_angles->p) && (current_angles->h == target_angles->h)) return; sk = 1.0f - scale*flRealframetime; CLAMP(sk, 0.0f, 1.0f); - delta.p = ap->p - bp->p; - delta.h = ap->h - bp->h; + delta.p = current_angles->p - target_angles->p; + delta.h = current_angles->h - target_angles->h; - ap->p = ap->p - delta.p * (1.0f - sk); - ap->h = ap->h - delta.h * (1.0f - sk); - // If we're very close, put ourselves at goal. if ((fl_abs(delta.p) < 0.005f) && (fl_abs(delta.h) < 0.005f)) { - ap->p = bp->p; - ap->h = bp->h; + current_angles->p = target_angles->p; + current_angles->h = target_angles->h; + } else { + // Else, apply the changes + current_angles->p -= ( delta.p * (1.0f - sk) ); + current_angles->h -= ( delta.h * (1.0f - sk) ); } } angles Viewer_slew_angles_delta; angles Viewer_external_angles_delta; +/** + * @brief Modifies the camera veiw angles according to its current view mode. (External, External Locked, + * TrackIR, Freelook, Normal, and Centering) + * @param[in,out] ma The camera veiw angles to modify (magnitude is saturated to be within max_p and max_h). + * @param[out] da The delta angles applied to ma (magnitude is saturated to 1 radian). + * @param[in] max_p The maximum pitch magnitude ma may have (radians). + * @param[in] max_h The maximum heading magnitude ma may have (radians). + * @param[in] frame_time The frame time at which this function is called. + */ void view_modify(angles *ma, angles *da, float max_p, float max_h, float frame_time) { + // Digital inputs + float t = 0.0f; + float u = 0.0f; + // Analog inputs int axis[NUM_JOY_AXIS_ACTIONS]; - float t = 0; - float u = 0; + float h = 0.0f; + float p = 0.0f; vec3d trans = ZERO_VECTOR; - if ( Viewer_mode & VM_EXTERNAL) { - if (! (Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { - t = t + (check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT)); - u = u + (check_control_timef(PITCH_BACK) - check_control_timef(PITCH_FORWARD)); + if ( Viewer_mode & VM_EXTERNAL ) { + if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { + // Digital + // May have to look at this again later... + // YAW_LEFT -> SLEW_LEFT YAW_RIGHT -> SLEW_RIGHT + // PITCH_BACK -> SLEW_UP PITCH_FORWARD -> SLEW_DOWN + t = (check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT)); + u = (check_control_timef(PITCH_BACK) - check_control_timef(PITCH_FORWARD)); + + // Analog + if( Use_mouse_to_fly ) { + // Use normal mouse mode for slew + playercontrol_read_mouse(axis, frame_time); + } else { + // Use joystick for slew + playercontrol_read_stick(axis, frame_time); + } + + h = -f2fl(axis[JOY_HEADING_AXIS]); + p = -f2fl(axis[JOY_PITCH_AXIS]); } else { + // External camera is locked in place, nothing to do here return; } - } else if ( gTirDll_TrackIR.Enabled( ) ) { - gTirDll_TrackIR.Query(); - ma->h = -PI2*(gTirDll_TrackIR.GetYaw()); - ma->p = PI2*(gTirDll_TrackIR.GetPitch()); + } else { + // We're in the cockpit + if ( gTirDll_TrackIR.Enabled() ) { + gTirDll_TrackIR.Query(); + ma->h = -PI2*(gTirDll_TrackIR.GetYaw()); + ma->p = PI2*(gTirDll_TrackIR.GetPitch()); - trans.xyz.x = -0.4f*gTirDll_TrackIR.GetX(); - trans.xyz.y = 0.4f*gTirDll_TrackIR.GetY(); - trans.xyz.z = -gTirDll_TrackIR.GetZ(); + trans.xyz.x = -0.4f*gTirDll_TrackIR.GetX(); + trans.xyz.y = 0.4f*gTirDll_TrackIR.GetY(); + trans.xyz.z = -gTirDll_TrackIR.GetZ(); - if(trans.xyz.z < 0) - trans.xyz.z = 0.0f; + if(trans.xyz.z < 0) { + trans.xyz.z = 0.0f; + } - vm_vec_unrotate(&leaning_position,&trans,&Eye_matrix); - } else { - // View slewing commands commented out until we can safely add more commands in the pilot code. + vm_vec_unrotate(&leaning_position,&trans,&Eye_matrix); + } else if ( freelook_mode_active ) { + // Freelook mode is enabled. Use flight controls for slewing + // Digital + t = (check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT)); + u = (check_control_timef(PITCH_BACK) - check_control_timef(PITCH_FORWARD)); + + // Analog + if( Use_mouse_to_fly ) { + // Use normal mouse mode for slew + playercontrol_read_mouse(axis, frame_time); + } else { + // Use joystick for slew + playercontrol_read_stick(axis, frame_time); + } + + h = -f2fl(axis[JOY_HEADING_AXIS]); + p = -f2fl(axis[JOY_PITCH_AXIS]); + } else { + // freelook mode is disabled. Use only slew commands + /** These have been commented out until Slew commands are actually doable + t = (check_control_timef(SLEW_LEFT) - check_control_timef(SLEW_RIGHT)); + u = (check_control_timef(SLEW_UP) - check_control_timef(SLEW_DOWN)); + */ + + if( !Use_mouse_to_fly ) { + // Mouse now controls slew when not being used as flight controler + playercontrol_read_mouse(axis,frame_time); + + h = -f2fl( axis[JOY_HEADING_AXIS] ); + p = -f2fl( axis[JOY_PITCH_AXIS] ); + } + // Else, don't do any slewing + } } - if (t != 0.0f) - da->h += t; - else - da->h = 0.0f; + if( !view_is_centering ) { + // Combine Analog and Digital slew commands + // Strip out any floating point errors before adding veiw changes + if ( (t != 0.0f) && (h != 0.0f) ) { + da->h += (t + h); + } else if (t!= 0.0f) { + da->h += t; + } else if (h != 0.0f) { + // Careful! playercontrol_read_mouse returns a delta, not an absolute position + da->h = h; + } else { + da->h = 0.0f; + } - if (u != 0.0f) - da->p += u; - else - da->p = 0.0f; - - da->b = 0.0f; + if ( (u != 0.0f) && (p != 0.0f) ) { + da->p += (u + p); + } else if ( u!= 0.0f ) { + da->p += u; + } else if ( p != 0.0f ) { + // Careful! playercontrol_read_mouse returns a delta, not an absolute position + da->p = p; + } else { + da->p = 0.0f; + } - playercontrol_read_stick(axis, frame_time); + da->b = 0.0f; // Twisting the veiw isn't very helpful, anyway - if (( Viewer_mode & VM_EXTERNAL ) && !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED)) { - // check the heading on the x and y axes - da->h -= f2fl( axis[0] ); - da->p -= f2fl( axis[1] ); - } + // Saturate delta angles + if ( da->h > 1.0f ) { + da->h = 1.0f; + } else if ( da->h < -1.0f ) { + da->h = -1.0f; + } - if (da->h > 1.0f) - da->h = 1.0f; - else if (da->h < -1.0f) - da->h = -1.0f; + if ( da->p > 1.0f ) { + da->p = 1.0f; + } else if (da->p < -1.0f) { + da->p = -1.0f; + } + } else { + // View is centering, so ignore any and all slew commands until veiw has been centered + return; + } - if (da->p > 1.0f) - da->p = 1.0f; - else if (da->p < -1.0f) - da->p = -1.0f; - - if ( (Game_time_compression >= F1_0) && !(Viewer_mode & VM_EXTERNAL) ) - { + if ( (Game_time_compression >= F1_0) && !(Viewer_mode & VM_EXTERNAL) ) { ma->p += 2*da->p * flFrametime; ma->b += 2*da->b * flFrametime; ma->h += 2*da->h * flFrametime; - } - else - { + } else { //If time compression is less than normal, still move camera at same speed //This gives a cool matrix effect ma->p += da->p * flRealframetime; @@ -185,15 +263,17 @@ ma->h += da->h * flRealframetime; } - if (ma->p > max_p) + if (ma->p > max_p) { ma->p = max_p; - else if (ma->p < -max_p) + } else if (ma->p < -max_p) { ma->p = -max_p; + } - if (ma->h > max_h) + if (ma->h > max_h) { ma->h = max_h; - else if (ma->h < -max_h) + } else if (ma->h < -max_h) { ma->h = -max_h; + } } void do_view_track_target(float frame_time) @@ -262,7 +342,9 @@ /** - * When PAD0 is pressed, keypad controls viewer direction slewing. + * @brief When VIEW_SLEW is pressed, pitch and heading controls viewer direction slewing. + * @details Prevents the player's "head" from swiveling unrealistacally far with a max_p of Pi/2 and a max_h of2/3 Pi. + * @param[in] frame_time The frame time at which this function is called */ void do_view_slew(float frame_time) { @@ -350,16 +432,56 @@ ci->forward_cruise_percent = oldspeed; } -// Read the 4 joystick axis. This is its own function -// because we only want to read it at a certain rate, -// since it takes time. +/** + * @brief Reads the 3 axis Mouse with sensitivy scaling. (Third axis doesn't actually work...) + * @details This is its own function so we can use the mouse in freelook mode as well as use it as a flight controller in (normal mode). + * @param[out] axis The axis array to store the scaled mouse position. + * @param[in] frame_time The frame time at which this function is called. + */ +void playercontrol_read_mouse(int *axis, float frame_time) +{ + int dx, dy, dz; + float factor; + + factor = (float) Mouse_sensitivity + 1.77f; + factor = factor * factor / frame_time / 0.6f; + + mouse_get_delta(&dx, &dy, &dz); + + if ( Invert_axis[JOY_HEADING_AXIS] ) + { + dx = -dx; + } + + if ( Invert_axis[JOY_PITCH_AXIS] ) + { + dy = -dy; + } + + if ( Invert_axis[JOY_ABS_THROTTLE_AXIS] ) + { + dz = -dz; + } + + axis[JOY_X_AXIS] = (int) ((float) dx * factor); + axis[JOY_Y_AXIS] = (int) ((float) dy * factor); + axis[JOY_RX_AXIS] = (int) ((float) dz * factor); +} + static int Joystick_saved_reading[JOY_NUM_AXES]; static int Joystick_last_reading = -1; +/** + * @brief Reads the joystick axes. + * @details This is its own function because we only want to read it at a certain rate, since it takes time. + * @param[out] axis The axis array to store the scaled joystick position. (Must have a size of NUM_JOY_AXIS_ACTIONS) + * @param[in] frame_time The frame time at which this function is called. + */ void playercontrol_read_stick(int *axis, float frame_time) { int i; + int mouse_axis[NUM_JOY_AXIS_ACTIONS]; #ifndef NDEBUG // Make sure things get reset properly between missions. @@ -375,46 +497,31 @@ Joystick_last_reading = timestamp( 1000/10 ); // Read 10x per second, like we did in Descent. } - for (i=0; i<NUM_JOY_AXIS_ACTIONS; i++) { + for ( i=0; i<NUM_JOY_AXIS_ACTIONS; i++ ) { axis[i] = Joystick_saved_reading[i]; } - if (Use_mouse_to_fly) { - int dx, dy, dz; - float factor; + if ( Use_mouse_to_fly ) { + playercontrol_read_mouse(mouse_axis, frame_time); - factor = (float) Mouse_sensitivity + 1.77f; - factor = factor * factor / frame_time / 0.6f; - - mouse_get_delta(&dx, &dy, &dz); - - if ( Invert_axis[0] ) { - dx = -dx; - } - - if ( Invert_axis[1] ) { - dy = -dy; - } - - if ( Invert_axis[3] ) { - dz = -dz; - } - - axis[0] += (int) ((float) dx * factor); - axis[1] += (int) ((float) dy * factor); - axis[3] += (int) ((float) dz * factor); + axis[JOY_HEADING_AXIS] += mouse_axis[JOY_X_AXIS]; + axis[JOY_PITCH_AXIS] += mouse_axis[JOY_Y_AXIS]; + axis[JOY_ABS_THROTTLE_AXIS] += mouse_axis[JOY_RX_AXIS]; } } +/** + * @brief Reads the player craft controls, including the keyboard, joystick, and mouse controls + */ void read_keyboard_controls( control_info * ci, float frame_time, physics_info *pi ) { float kh=0.0f, scaled, newspeed, delta, oldspeed; - int axis[NUM_JOY_AXIS_ACTIONS], slew_active=1; + int axis[NUM_JOY_AXIS_ACTIONS]; static int afterburner_last = 0; static float analog_throttle_last = 9e9f; static int override_analog_throttle = 0; static float savedspeed = ci->forward_cruise_percent; //Backslash - int ok_to_read_ci_pitch_yaw=1; + bool ok_to_read_ci_pitch_yaw = true; int centering_speed = 7; // the scale speed in which the camera will smoothly center when the player presses Center View oldspeed = ci->forward_cruise_percent; @@ -423,48 +530,59 @@ if ( Viewer_mode & VM_EXTERNAL ) { control_used(VIEW_EXTERNAL); if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { - ok_to_read_ci_pitch_yaw=0; + ok_to_read_ci_pitch_yaw = false; } - do_view_external(frame_time); do_thrust_keys(ci); - slew_active=0; + freelook_mode_active = false; + } else if ( Viewer_mode & VM_CHASE ) { do_view_chase(frame_time); - slew_active=0; - } else { // We're in the cockpit. - if (view_centering) { + freelook_mode_active = false; + + } else { + // We're in the cockpit. + if ( view_is_centering ) { // If we're centering the view, check to see if we're actually centered and bypass any view modifications // until the view has finally been centered. - if ((Viewer_slew_angles.h == 0.0f) && (Viewer_slew_angles.p == 0.0f)) { - view_centering = 0; // if the view has been centered, allow the player to freelook again. + if ( (Viewer_slew_angles.h == 0.0f) && (Viewer_slew_angles.p == 0.0f) ) { + view_is_centering = false; // if the view has been centered, allow the player to freelook again. } - slew_active = 0; - } else if ( Viewer_mode & VM_TRACK ) { // Player's vision will track current target. + freelook_mode_active = false; + + } else if ( Viewer_mode & VM_TRACK ) { + // Player's vision will track current target. do_view_track_target(frame_time); + } else { - // The Center View command check is here because - // we don't want the player centering the view in target padlock mode - if (check_control_timef(VIEW_CENTER) && !view_centering) { - view_centering = 1; - slew_active = 0; - } - do_view_slew(frame_time); + // We're not centering the view currently, nor are we tracking any targets + if ( check_control_timef(VIEW_SLEW) ) { + // Enable slewing/freelook mode + freelook_mode_active = true; + ok_to_read_ci_pitch_yaw = false; - // Orthogonal padlock views moved here in order to get the springy chase effect when transitioning. - player_set_padlock_state(); - + } else if ( check_control_timef(VIEW_CENTER) || freelook_mode_active ) { + // Start centering the view if the VIEW_CENTER control was active, or the player previously used freelook mode + view_is_centering = true; + // ok_to_read_ci_pitch_yaw = true; // This is already handled by initialization + freelook_mode_active = false; + } // Else, do nothing } + do_view_slew(frame_time); + // Orthogonal padlock views moved here in order to get the springy chase effect when transitioning. + player_set_padlock_state(); } - + if ( ok_to_read_ci_pitch_yaw ) { - // From keyboard... do_thrust_keys(ci); + // Bank and Yaw controls (Keyboard) if ( check_control(BANK_WHEN_PRESSED) ) { ci->bank = check_control_timef(BANK_LEFT) + check_control_timef(YAW_LEFT) - check_control_timef(YAW_RIGHT) - check_control_timef(BANK_RIGHT); ci->heading = 0.0f; + } else { kh = (check_control_timef(YAW_RIGHT) - check_control_timef(YAW_LEFT)) / 8.0f; + if (kh == 0.0f) { ci->heading = 0.0f; @@ -472,33 +590,36 @@ if (ci->heading < 0.0f) ci->heading = 0.0f; - } else { // kh < 0 - if (ci->heading > 0.0f) + } else { + // kh < 0 + if (ci->heading > 0.0f) { ci->heading = 0.0f; + } } - ci->bank = check_control_timef(BANK_LEFT) - check_control_timef(BANK_RIGHT); } - ci->heading += kh; + kh = (check_control_timef(PITCH_FORWARD) - check_control_timef(PITCH_BACK)) / 8.0f; - kh = (check_control_timef(PITCH_FORWARD) - check_control_timef(PITCH_BACK)) / 8.0f; if (kh == 0.0f) { ci->pitch = 0.0f; + } else if (kh > 0.0f) { - if (ci->pitch < 0.0f) + if (ci->pitch < 0.0f) { ci->pitch = 0.0f; + } - } else { // kh < 0 - if (ci->pitch > 0.0f) + } else { + // kh < 0 + if (ci->pitch > 0.0f) { ci->pitch = 0.0f; + } } - ci->pitch += kh; } - if ( !slew_active ) { - // If we're not in a view that slews (ie, not a cockpit view), make the viewer slew angles spring to the center. + // If we're not in a view that slews (ie, not a cockpit view), make the viewer slew angles spring to the center. + if ( !freelook_mode_active ) { chase_slew_angles.h = 0.0f; chase_slew_angles.p = 0.0f; } @@ -506,9 +627,11 @@ chase_angles_to_value(&Viewer_slew_angles, &chase_slew_angles, centering_speed); if (!(Game_mode & GM_DEAD)) { + // Engine Controls if ( button_info_query(&Player->bi, ONE_THIRD_THROTTLE) ) { control_used(ONE_THIRD_THROTTLE); player_clear_speed_matching(); + if ( Player->ci.forward_cruise_percent < 33.3f ) { snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_UP)], 0.0f ); @@ -523,6 +646,7 @@ if ( button_info_query(&Player->bi, TWO_THIRDS_THROTTLE) ) { control_used(TWO_THIRDS_THROTTLE); player_clear_speed_matching(); + if ( Player->ci.forward_cruise_percent < 66.6f ) { snd_play( &Snds[ship_get_sound(Player_obj, SND_THROTTLE_UP)], 0.0f ); @@ -537,15 +661,17 @@ if ( button_info_query(&Player->bi, PLUS_5_PERCENT_THROTTLE) ) { control_used(PLUS_5_PERCENT_THROTTLE); Player->ci.forward_cruise_percent += 5.0f; - if (Player->ci.forward_cruise_percent > 100.0f) + if (Player->ci.forward_cruise_percent > 100.0f) { Player->ci.forward_cruise_percent = 100.0f; + } } if ( button_info_query(&Player->bi, MINUS_5_PERCENT_THROTTLE) ) { control_used(MINUS_5_PERCENT_THROTTLE); Player->ci.forward_cruise_percent -= 5.0f; - if (Player->ci.forward_cruise_percent < 0.0f) + if (Player->ci.forward_cruise_percent < 0.0f) { Player->ci.forward_cruise_percent = 0.0f; + } } if ( button_info_query(&Player->bi, ZERO_THROTTLE) ) { @@ -591,8 +717,7 @@ Assert(targeted_objp->type == OBJ_SHIP); // Goober5000 - if (object_is_docked(targeted_objp)) - { + if (object_is_docked(targeted_objp)) { tspeed = dock_calc_docked_speed(targeted_objp); //changed from fspeed } } @@ -614,41 +739,49 @@ } override_analog_throttle = 1; } - - } else + } else { Player->flags &= ~PLAYER_FLAGS_MATCH_TARGET; + } } // code to read joystick axis for pitch/heading. Code to read joystick buttons // for bank. - if ( !(Game_mode & GM_DEAD) ) { + // Double check that the player didn't die during read_keyboard_controls... + if ( !(Game_mode & GM_DEAD) ) { playercontrol_read_stick(axis, frame_time); } else { axis[0] = axis[1] = axis[2] = axis[3] = axis[4] = 0; } - if (Axis_map_to[JOY_HEADING_AXIS] >= 0) { - // check the heading on the x axis - if ( check_control(BANK_WHEN_PRESSED) ) { - delta = f2fl( axis[JOY_HEADING_AXIS] ); - if ( (delta > 0.05f) || (delta < -0.05f) ) { - ci->bank -= delta; + if (ok_to_read_ci_pitch_yaw) { + if (Axis_map_to[JOY_HEADING_AXIS] >= 0) { + // Check the heading axis and apply it to either heading or bank angles + if ( check_control(BANK_WHEN_PRESSED) ) { + delta = f2fl( axis[JOY_HEADING_AXIS] ); + if ( (delta > 0.05f) || (delta < -0.05f) ) { + ci->bank -= delta; + } + } else { + ci->heading += f2fl( axis[JOY_HEADING_AXIS] ); } - } else { - ci->heading += f2fl( axis[JOY_HEADING_AXIS] ); } - } - // check the pitch on the y axis - if (Axis_map_to[JOY_PITCH_AXIS] >= 0) { - ci->pitch -= f2fl( axis[JOY_PITCH_AXIS] ); + // Check the pitch axis + if (Axis_map_to[JOY_PITCH_AXIS] >= 0) { + ci->pitch -= f2fl( axis[JOY_PITCH_AXIS] ); + } + } else { + // We're in slew mode, so stop rotating the player craft before the pilot becomes billious + ci->pitch = 0.0f; + ci->heading = 0.0f; } + // Check the bank axis if (Axis_map_to[JOY_BANK_AXIS] >= 0) { ci->bank -= f2fl( axis[JOY_BANK_AXIS] ) * 1.5f; } - // axis 2 is for throttle + // Check the absolute throttle axis if (Axis_map_to[JOY_ABS_THROTTLE_AXIS] >= 0) { scaled = (float) axis[JOY_ABS_THROTTLE_AXIS] * 1.2f / (float) F1_0 - 0.1f; // convert to -0.1 - 1.1 range oldspeed = ci->forward_cruise_percent; @@ -663,13 +796,19 @@ } } - if (Axis_map_to[JOY_REL_THROTTLE_AXIS] >= 0) + // Check the relative throttle axis + if (Axis_map_to[JOY_REL_THROTTLE_AXIS] >= 0) { ci->forward_cruise_percent += f2fl(axis[JOY_REL_THROTTLE_AXIS]) * 100.0f * frame_time; + } - if ( ci->forward_cruise_percent > 100.0f ) + // Saturate speed to be within 0 to 100% + if ( ci->forward_cruise_percent > 100.0f ) { ci->forward_cruise_percent = 100.0f; - if ( ci->forward_cruise_percent < 0.0f ) + } + + if ( ci->forward_cruise_percent < 0.0f ) { ci->forward_cruise_percent = 0.0f; + } // set up the firing stuff. Read into control info ala Descent so that weapons will be // created during the object simulation phase, and not immediately as was happening before. @@ -688,11 +827,11 @@ #endif // keyboard: fire the current secondary weapon - if (check_control(FIRE_SECONDARY)) { + if (check_control(FIRE_SECONDARY)){ ci->fire_secondary_count++; // if we're a multiplayer client, set our accum bits now - if( MULTIPLAYER_CLIENT && (Net_player != NULL)){ + if( MULTIPLAYER_CLIENT && (Net_player != NULL)) { Net_player->s_info.accum_buttons |= OOC_FIRE_SECONDARY; } } @@ -718,9 +857,9 @@ afterburner_last = 1; } else { - if (afterburner_last) + if (afterburner_last) { ci->afterburner_stop = 1; - + } afterburner_last = 0; } @@ -729,6 +868,7 @@ // Check for toggle button pressed. if ( button_info_query(&Player->bi, TOGGLE_GLIDING) ) { control_used(TOGGLE_GLIDING); + if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) { toggle_glide = !toggle_glide; } @@ -779,7 +919,7 @@ } } else { // Probably don't need to do the second half of this check, but just in case... - if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ) { + if ( Player_obj != NULL && Ship_info[Player_ship->ship_info_index].can_glide ){ // Only bother doing this if we need to. if ( object_get_gliding(Player_obj) && !object_glide_forced(Player_obj) ) { object_set_gliding(Player_obj, false); @@ -794,14 +934,13 @@ } } } - } if ( (Viewer_mode & VM_EXTERNAL) ) { if ( !(Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED) ) { - ci->heading=0.0f; - ci->pitch=0.0f; - ci->bank=0.0f; + ci->heading = 0.0f; + ci->pitch = 0.0f; + ci->bank = 0.0f; } } } |
|
I'm going to go ahead and pend this for full 3.7.0 so that way the options that are 'planned for' don't get forgotten and can be better integrated into this fix. If it hasn't been working up until now, one more release isn't going to make a difference, but having it in, in a more "feature complete" fashion, just makes more sense to me. |
|
Fix committed to antipodes@10566. |
fs2open: antipodes r10566 2014-04-17 06:37 Ported: N/A Details Diff |
Fixes 2713 - "Freelook Mode Unavailable." Freelook has been re-enabled with a minimal amount of changes. Efforts to add in slew control keys as well as the ability to map the mouse to a slew axis have resulted into a much larger project than previously expected. As such, these changes will be postponed until fully complete. |
Affected Issues 0002713 |
|
mod - /branches/antipodes/code/playerman/playercontrol.cpp | Diff File |
Date Modified | Username | Field | Change |
---|---|---|---|
2012-09-14 11:41 | z64555 | New Issue | |
2012-09-19 01:45 | Swifty | Assigned To | => Swifty |
2012-09-19 01:45 | Swifty | Status | new => assigned |
2012-09-26 02:27 | z64555 | File Added: z64_slew_r9226.patch | |
2012-09-26 02:29 | z64555 | Note Added: 0013978 | |
2012-09-26 04:47 | Echelon9 | Status | assigned => code review |
2012-09-26 09:53 | Swifty | Note Added: 0013979 | |
2012-10-11 11:23 | z64555 | Note Added: 0013980 | |
2012-10-11 11:23 | z64555 | File Added: z64_slew_r9256.patch | |
2012-10-11 11:25 | z64555 | Note Edited: 0013980 | |
2012-12-09 04:18 | Zacam | Note Added: 0014374 | |
2012-12-09 04:18 | Zacam | Resolution | open => suspended |
2012-12-09 04:18 | Zacam | Target Version | => 3.7.0 |
2012-12-09 04:19 | Zacam | Status | code review => confirmed |
2013-11-27 03:22 | z64555 | Assigned To | Swifty => z64555 |
2013-11-27 03:22 | z64555 | Status | confirmed => assigned |
2013-11-27 03:30 | z64555 | Resolution | suspended => open |
2013-11-27 03:30 | z64555 | Target Version | 3.7.0 => 3.7.1 |
2014-04-17 11:29 | z64555 | Changeset attached | => fs2open antipodes r10566 |
2014-04-17 11:29 | z64555 | Note Added: 0015701 | |
2014-04-17 11:29 | z64555 | Status | assigned => resolved |
2014-04-17 11:29 | z64555 | Resolution | open => fixed |