2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
19 static char rcsid[] = "$Id: controls.c,v 1.2 2001-01-31 15:17:49 bradleyb Exp $";
49 //look at keyboard, mouse, joystick, CyberMan, whatever, and set
50 //physics vars rotvel, velocity
52 fix Afterburner_charge=f1_0;
54 #define AFTERBURNER_USE_SECS 3 //use up in 3 seconds
55 #define DROP_DELTA_TIME (f1_0/15) //drop 3 per second
57 extern int Drop_afterburner_blob_flag; //ugly hack
59 extern fix Seismic_tremor_magnitude;
61 void read_flying_controls( object * obj )
63 fix forward_thrust_time;
65 Assert(FrameTime > 0); //Get MATT if hit this!
68 vm_vec_zero(&obj->mtype.phys_info.rotthrust);
69 vm_vec_zero(&obj->mtype.phys_info.thrust);
73 if ((obj->type!=OBJ_PLAYER) || (obj->id!=Player_num)) return; //references to player_ship require that this obj be the player
75 if (Guided_missile[Player_num] && Guided_missile[Player_num]->signature==Guided_missile_sig[Player_num]) {
77 vms_matrix rotmat,tempm;
80 //this is a horrible hack. guided missile stuff should not be
81 //handled in the middle of a routine that is dealing with the player
83 vm_vec_zero(&obj->mtype.phys_info.rotthrust);
85 rotangs.p = Controls.pitch_time / 2 + Seismic_tremor_magnitude/64;
86 rotangs.b = Controls.bank_time / 2 + Seismic_tremor_magnitude/16;
87 rotangs.h = Controls.heading_time / 2 + Seismic_tremor_magnitude/64;
89 vm_angles_2_matrix(&rotmat,&rotangs);
91 vm_matrix_x_matrix(&tempm,&Guided_missile[Player_num]->orient,&rotmat);
93 Guided_missile[Player_num]->orient = tempm;
95 speed = Weapon_info[Guided_missile[Player_num]->id].speed[Difficulty_level];
97 vm_vec_copy_scale(&Guided_missile[Player_num]->mtype.phys_info.velocity,&Guided_missile[Player_num]->orient.fvec,speed);
99 if (Game_mode & GM_MULTI)
100 multi_send_guided_info (Guided_missile[Player_num],0);
105 obj->mtype.phys_info.rotthrust.x = Controls.pitch_time;
106 obj->mtype.phys_info.rotthrust.y = Controls.heading_time;
107 obj->mtype.phys_info.rotthrust.z = Controls.bank_time;
110 // mprintf( (0, "Rot thrust = %.3f,%.3f,%.3f\n", f2fl(obj->mtype.phys_info.rotthrust.x),f2fl(obj->mtype.phys_info.rotthrust.y), f2fl(obj->mtype.phys_info.rotthrust.z) ));
112 forward_thrust_time = Controls.forward_thrust_time;
114 if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER)
116 if (Controls.afterburner_state) { //player has key down
117 //if (forward_thrust_time >= 0) { //..and isn't moving backward
119 fix afterburner_scale;
120 int old_count,new_count;
122 //add in value from 0..1
123 afterburner_scale = f1_0 + min(f1_0/2,Afterburner_charge) * 2;
125 forward_thrust_time = fixmul(FrameTime,afterburner_scale); //based on full thrust
127 old_count = (Afterburner_charge / (DROP_DELTA_TIME/AFTERBURNER_USE_SECS));
129 Afterburner_charge -= FrameTime/AFTERBURNER_USE_SECS;
131 if (Afterburner_charge < 0)
132 Afterburner_charge = 0;
134 new_count = (Afterburner_charge / (DROP_DELTA_TIME/AFTERBURNER_USE_SECS));
136 if (old_count != new_count)
137 Drop_afterburner_blob_flag = 1; //drop blob (after physics called)
141 fix cur_energy,charge_up;
144 charge_up = min(FrameTime/8,f1_0 - Afterburner_charge); //recharge over 8 seconds
146 cur_energy = max(Players[Player_num].energy-i2f(10),0); //don't drop below 10
148 //maybe limit charge up by energy
149 charge_up = min(charge_up,cur_energy/10);
151 Afterburner_charge += charge_up;
153 Players[Player_num].energy -= charge_up * 100 / 10; //full charge uses 10% of energy
157 // Set object's thrust vector for forward/backward
158 vm_vec_copy_scale(&obj->mtype.phys_info.thrust,&obj->orient.fvec, forward_thrust_time );
161 vm_vec_scale_add2(&obj->mtype.phys_info.thrust,&obj->orient.rvec, Controls.sideways_thrust_time );
164 vm_vec_scale_add2(&obj->mtype.phys_info.thrust,&obj->orient.uvec, Controls.vertical_thrust_time );
166 if (obj->mtype.phys_info.flags & PF_WIGGLE) {
168 fix_fastsincos(GameTime, &swiggle, NULL);
169 vm_vec_scale_add2(&obj->mtype.phys_info.velocity,&obj->orient.uvec,fixmul(swiggle,Player_ship->wiggle));
172 // As of now, obj->mtype.phys_info.thrust & obj->mtype.phys_info.rotthrust are
173 // in units of time... In other words, if thrust==FrameTime, that
174 // means that the user was holding down the Max_thrust key for the
175 // whole frame. So we just scale them up by the max, and divide by
176 // FrameTime to make them independant of framerate
178 // Prevent divide overflows on high frame rates.
179 // In a signed divide, you get an overflow if num >= div<<15
183 // Note, you must check for ft < F1_0/2, else you can get an overflow on the << 15.
184 if ((ft < F1_0/2) && (ft << 15 <= Player_ship->max_thrust)) {
185 mprintf((0, "Preventing divide overflow in controls.c for Max_thrust!\n"));
186 ft = (Player_ship->max_thrust >> 15) + 1;
189 vm_vec_scale( &obj->mtype.phys_info.thrust, fixdiv(Player_ship->max_thrust,ft) );
191 if ((ft < F1_0/2) && (ft << 15 <= Player_ship->max_rotthrust)) {
192 mprintf((0, "Preventing divide overflow in controls.c for max_rotthrust!\n"));
193 ft = (Player_ship->max_thrust >> 15) + 1;
196 vm_vec_scale( &obj->mtype.phys_info.rotthrust, fixdiv(Player_ship->max_rotthrust,ft) );