1 /*************************************************************************** 2 Process Outputs. 3 4 - Only the Deluxe Moving Motor Code is ported for now. 5 - This is used by the force-feedback haptic system. 6 7 One thing to note is that this code was originally intended to drive 8 a moving hydraulic cabinet, not to be mapped to a haptic device. 9 10 Therefore, it's not perfect when used in this way, but the results 11 aren't bad :) 12 13 Copyright Chris White. 14 See license.txt for more details. 15 ***************************************************************************/ 16 17 #pragma once 18 19 #include "stdint.hpp" 20 21 struct CoinChute 22 { 23 // Coin Chute Counters 24 uint8_t counter[3]; 25 // Output bit 26 uint8_t output_bit; 27 }; 28 29 class OOutputs 30 { 31 public: 32 const static int MODE_DISABLED = 0; // Disabled 33 const static int MODE_CABINET = 1; // SmartyPi Interface / Original Cabinet 34 const static int MODE_FFEEDBACK = 2; // Force Feedback for Wheels 35 const static int MODE_RUMBLE = 3; // Simple rumble for controllers 36 37 // Hardware Motor Control: 38 // 0 = Switch off 39 // 5 = Left 40 // 8 = Centre 41 // B = Right 42 uint8_t hw_motor_control; 43 44 // Digital Outputs 45 enum 46 { 47 D_EXT_MUTE = 0x01, // bit 0 = External Amplifier Mute Control 48 D_BRAKE_LAMP = 0x02, // bit 1 = brake lamp 49 D_START_LAMP = 0x04, // bit 2 = start lamp 50 D_COIN1_SUCC = 0x08, // bit 3 = Coin successfully inserted - Chute 2 51 D_COIN2_SUCC = 0x10, // bit 4 = Coin successfully inserted - Chute 1 52 D_MOTOR = 0x20, // bit 5 = steering wheel central vibration 53 D_UNUSED = 0x40, // bit 6 = ? 54 D_SOUND = 0x80, // bit 7 = sound enable 55 }; 56 57 CoinChute chute1, chute2; 58 59 OOutputs(void); 60 ~OOutputs(void); 61 62 void init(); 63 void set_mode(int); 64 bool diag_motor(int16_t input_motor, uint8_t hw_motor_limit, uint32_t packets); 65 bool calibrate_motor(int16_t input_motor, uint8_t hw_motor_limit, uint32_t packets); 66 void tick(int16_t input_motor = 0); 67 void writeDigitalToConsole(); 68 void set_digital(uint8_t); 69 void clear_digital(uint8_t); 70 int is_set(uint8_t); 71 void coin_chute_out(CoinChute* chute, bool insert); 72 73 private: 74 int mode; 75 76 uint8_t dig_out, dig_out_old; 77 78 const static uint16_t STATE_INIT = 0; 79 const static uint16_t STATE_DELAY = 1; 80 const static uint16_t STATE_LEFT = 2; 81 const static uint16_t STATE_RIGHT = 3; 82 const static uint16_t STATE_CENTRE = 4; 83 const static uint16_t STATE_DONE = 5; 84 const static uint16_t STATE_EXIT = 6; 85 86 // Calibration Counter 87 const static int COUNTER_RESET = 300; 88 89 const static uint8_t MOTOR_OFF = 0; 90 const static uint8_t MOTOR_RIGHT = 0x5; 91 const static uint8_t MOTOR_CENTRE = 0x8; 92 const static uint8_t MOTOR_LEFT = 0xB; 93 94 95 // These are calculated during startup in the original game. 96 // Here we just hardcode them, as the motor init code isn't ported. 97 const static uint8_t CENTRE_POS = 0x80; 98 const static uint8_t LEFT_LIMIT = 0xC1; 99 const static uint8_t RIGHT_LIMIT = 0x3C; 100 101 // Motor Limit Values. Calibrated during startup. 102 int16_t limit_left; 103 int16_t limit_right; 104 105 // Motor Centre Position. (We Fudge this for Force Feedback wheel mode.) 106 int16_t motor_centre_pos; 107 108 // Difference between input_motor and input_motor_old 109 int16_t motor_x_change; 110 111 uint16_t motor_state; 112 bool motor_enabled; 113 114 // 0x11: Motor Control Value 115 int8_t motor_control; 116 // 0x12: Movement (1 = Left, -1 = Right, 0 = None) 117 int8_t motor_movement; 118 // 0x14: Is Motor Centered 119 bool is_centered; 120 // 0x16: Motor X Change Latch 121 int16_t motor_change_latch; 122 // 0x18: Speed 123 int16_t speed; 124 // 0x1A: Road Curve 125 int16_t curve; 126 // 0x1E: Increment counter to index motor table for off-road/crash 127 int16_t vibrate_counter; 128 // 0x20: Last Motor X_Change > 8. No need to adjust further. 129 bool was_small_change; 130 // 0x22: Adjusted movement value based on steering 1 131 int16_t movement_adjust1; 132 // 0x24: Adjusted movement value based on steering 2 133 int16_t movement_adjust2; 134 // 0x26: Adjusted movement value based on steering 3 135 int16_t movement_adjust3; 136 137 // Counter control for motor tests 138 int16_t counter; 139 140 // Columns for output 141 uint16_t col1, col2; 142 143 void diag_left(int16_t input_motor, uint8_t hw_motor_limit); 144 void diag_right(int16_t input_motor, uint8_t hw_motor_limit); 145 void diag_centre(int16_t input_motor, uint8_t hw_motor_limit); 146 void diag_done(); 147 148 void calibrate_left(int16_t input_motor, uint8_t hw_motor_limit); 149 void calibrate_right(int16_t input_motor, uint8_t hw_motor_limit); 150 void calibrate_centre(int16_t input_motor, uint8_t hw_motor_limit); 151 void calibrate_done(); 152 153 void do_motors(const int MODE, int16_t input_motor); 154 void car_moving(const int MODE); 155 void car_stationary(); 156 void adjust_motor(); 157 void do_motor_crash(); 158 void do_motor_offroad(); 159 void set_value(const uint8_t*, uint8_t); 160 void done(); 161 void motor_output(uint8_t cmd); 162 163 void do_vibrate_upright(); 164 void do_vibrate_mini(); 165 };