1 /***************************************************************************
2
3 inptport.c
4
5 Input ports handling
6
7 TODO: remove the 1 analog device per port limitation
8 support for inputports producing interrupts
9 support for extra "real" hardware (PC throttle's, spinners etc)
10
11 ***************************************************************************/
12
13 #include "driver.h"
14 #include <math.h>
15
16 #ifdef MAME_NET
17 #include "network.h"
18
19 static unsigned short input_port_defaults[MAX_INPUT_PORTS];
20 static int default_player;
21 static int analog_player_port[MAX_INPUT_PORTS];
22 #endif /* MAME_NET */
23
24 /* Use the MRU code for 4way joysticks */
25 #define MRU_JOYSTICK
26
27 /* header identifying the version of the game.cfg file */
28 /* mame 0.36b11 */
29 #define MAMECFGSTRING_V5 "MAMECFG\5"
30 #define MAMEDEFSTRING_V5 "MAMEDEF\4"
31
32 /* mame 0.36b12 with multi key/joy extension */
33 #define MAMECFGSTRING_V6 "MAMECFG\6"
34 #define MAMEDEFSTRING_V6 "MAMEDEF\5"
35
36 /* mame 0.36b13 with and/or/not combination */
37 #define MAMECFGSTRING_V7 "MAMECFG\7"
38 #define MAMEDEFSTRING_V7 "MAMEDEF\6"
39
40 /* mame 0.36b16 with key/joy merge */
41 #define MAMECFGSTRING_V8 "MAMECFG\x8"
42 #define MAMEDEFSTRING_V8 "MAMEDEF\7"
43
44 extern void *record;
45 extern void *playback;
46
47 extern unsigned int dispensed_tickets;
48 extern unsigned int coins[COIN_COUNTERS];
49 extern unsigned int lastcoin[COIN_COUNTERS];
50 extern unsigned int coinlockedout[COIN_COUNTERS];
51
52 static unsigned short input_port_value[MAX_INPUT_PORTS];
53 static unsigned short input_vblank[MAX_INPUT_PORTS];
54
55 /* Assuming a maxium of one analog input device per port BW 101297 */
56 static struct InputPort *input_analog[MAX_INPUT_PORTS];
57 static int input_analog_current_value[MAX_INPUT_PORTS],input_analog_previous_value[MAX_INPUT_PORTS];
58 static int input_analog_init[MAX_INPUT_PORTS];
59
60 static int mouse_delta_x[OSD_MAX_JOY_ANALOG], mouse_delta_y[OSD_MAX_JOY_ANALOG];
61 static int analog_current_x[OSD_MAX_JOY_ANALOG], analog_current_y[OSD_MAX_JOY_ANALOG];
62 static int analog_previous_x[OSD_MAX_JOY_ANALOG], analog_previous_y[OSD_MAX_JOY_ANALOG];
63
64 #ifdef ENABLE_AUTOFIRE
65 int seq_pressed_with_autofire(struct InputPort *in, InputSeq *code);
66 #endif
67
68
69 /***************************************************************************
70
71 Configuration load/save
72
73 ***************************************************************************/
74
75 /* this must match the enum in inptport.h */
76 char ipdn_defaultstrings[][MAX_DEFSTR_LEN] =
77 {
78 "Off",
79 "On",
80 "No",
81 "Yes",
82 "Lives",
83 "Bonus Life",
84 "Difficulty",
85 "Demo Sounds",
86 "Coinage",
87 "Coin A",
88 "Coin B",
89 "9 Coins/1 Credit",
90 "8 Coins/1 Credit",
91 "7 Coins/1 Credit",
92 "6 Coins/1 Credit",
93 "5 Coins/1 Credit",
94 "4 Coins/1 Credit",
95 "3 Coins/1 Credit",
96 "8 Coins/3 Credits",
97 "4 Coins/2 Credits",
98 "2 Coins/1 Credit",
99 "5 Coins/3 Credits",
100 "3 Coins/2 Credits",
101 "4 Coins/3 Credits",
102 "4 Coins/4 Credits",
103 "3 Coins/3 Credits",
104 "2 Coins/2 Credits",
105 "1 Coin/1 Credit",
106 "4 Coins/5 Credits",
107 "3 Coins/4 Credits",
108 "2 Coins/3 Credits",
109 "4 Coins/7 Credits",
110 "2 Coins/4 Credits",
111 "1 Coin/2 Credits",
112 "2 Coins/5 Credits",
113 "2 Coins/6 Credits",
114 "1 Coin/3 Credits",
115 "2 Coins/7 Credits",
116 "2 Coins/8 Credits",
117 "1 Coin/4 Credits",
118 "1 Coin/5 Credits",
119 "1 Coin/6 Credits",
120 "1 Coin/7 Credits",
121 "1 Coin/8 Credits",
122 "1 Coin/9 Credits",
123 "Free Play",
124 "Cabinet",
125 "Upright",
126 "Cocktail",
127 "Flip Screen",
128 "Service Mode",
129 "Unused",
130 "Unknown"
131 };
132
133 struct ipd inputport_defaults[] =
134 {
135 { IPT_UI_CONFIGURE, "Config Menu", SEQ_DEF_1(KEYCODE_TAB) },
136 { IPT_UI_ON_SCREEN_DISPLAY, "On Screen Display", SEQ_DEF_1(KEYCODE_TILDE) },
137 { IPT_UI_PAUSE, "Pause", SEQ_DEF_1(KEYCODE_P) },
138 { IPT_UI_RESET_MACHINE, "Reset Game", SEQ_DEF_1(KEYCODE_F3) },
139 { IPT_UI_SHOW_GFX, "Show Gfx", SEQ_DEF_1(KEYCODE_F4) },
140 { IPT_UI_FRAMESKIP_DEC, "Frameskip Dec", SEQ_DEF_1(KEYCODE_F8) },
141 { IPT_UI_FRAMESKIP_INC, "Frameskip Inc", SEQ_DEF_1(KEYCODE_F9) },
142 { IPT_UI_THROTTLE, "Throttle", SEQ_DEF_1(KEYCODE_F10) },
143 { IPT_UI_SHOW_FPS, "Show FPS", SEQ_DEF_5(KEYCODE_F11, CODE_NOT, KEYCODE_LCONTROL, CODE_NOT, KEYCODE_LSHIFT) },
144 { IPT_UI_SHOW_PROFILER, "Show Profiler", SEQ_DEF_2(KEYCODE_F11, KEYCODE_LSHIFT) },
145 #ifdef MESS
146 { IPT_UI_TOGGLE_UI, "UI Toggle", SEQ_DEF_1(KEYCODE_SCRLOCK) },
147 #endif
148 { IPT_UI_SNAPSHOT, "Save Snapshot", SEQ_DEF_1(KEYCODE_F12) },
149 { IPT_UI_TOGGLE_CHEAT, "Toggle Cheat", SEQ_DEF_1(KEYCODE_F5) },
150 { IPT_UI_UP, "UI Up", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
151 { IPT_UI_DOWN, "UI Down", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
152 { IPT_UI_LEFT, "UI Left", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
153 { IPT_UI_RIGHT, "UI Right", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
154 { IPT_UI_SELECT, "UI Select", SEQ_DEF_3(KEYCODE_ENTER, CODE_OR, JOYCODE_1_BUTTON1) },
155 { IPT_UI_CANCEL, "UI Cancel", SEQ_DEF_1(KEYCODE_ESC) },
156 { IPT_UI_PAN_UP, "Pan Up", SEQ_DEF_3(KEYCODE_PGUP, CODE_NOT, KEYCODE_LSHIFT) },
157 { IPT_UI_PAN_DOWN, "Pan Down", SEQ_DEF_3(KEYCODE_PGDN, CODE_NOT, KEYCODE_LSHIFT) },
158 { IPT_UI_PAN_LEFT, "Pan Left", SEQ_DEF_2(KEYCODE_PGUP, KEYCODE_LSHIFT) },
159 { IPT_UI_PAN_RIGHT, "Pan Right", SEQ_DEF_2(KEYCODE_PGDN, KEYCODE_LSHIFT) },
160 { IPT_START1, "1 Player Start", SEQ_DEF_1(KEYCODE_1) },
161 { IPT_START2, "2 Players Start", SEQ_DEF_1(KEYCODE_2) },
162 { IPT_START3, "3 Players Start", SEQ_DEF_1(KEYCODE_3) },
163 { IPT_START4, "4 Players Start", SEQ_DEF_1(KEYCODE_4) },
164 { IPT_COIN1, "Coin 1", SEQ_DEF_1(KEYCODE_5) },
165 { IPT_COIN2, "Coin 2", SEQ_DEF_1(KEYCODE_6) },
166 { IPT_COIN3, "Coin 3", SEQ_DEF_1(KEYCODE_7) },
167 { IPT_COIN4, "Coin 4", SEQ_DEF_1(KEYCODE_8) },
168 { IPT_SERVICE1, "Service 1", SEQ_DEF_1(KEYCODE_9) },
169 { IPT_SERVICE2, "Service 2", SEQ_DEF_1(KEYCODE_0) },
170 { IPT_SERVICE3, "Service 3", SEQ_DEF_1(KEYCODE_MINUS) },
171 { IPT_SERVICE4, "Service 4", SEQ_DEF_1(KEYCODE_EQUALS) },
172 #ifndef MESS
173 { IPT_TILT, "Tilt", SEQ_DEF_1(KEYCODE_T) },
174 #else
175 { IPT_TILT, "Tilt", SEQ_DEF_0 },
176 #endif
177
178 { IPT_JOYSTICK_UP | IPF_PLAYER1, "P1 Up", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
179 { IPT_JOYSTICK_DOWN | IPF_PLAYER1, "P1 Down", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
180 { IPT_JOYSTICK_LEFT | IPF_PLAYER1, "P1 Left", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
181 { IPT_JOYSTICK_RIGHT | IPF_PLAYER1, "P1 Right", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
182 { IPT_BUTTON1 | IPF_PLAYER1, "P1 Button 1", SEQ_DEF_3(KEYCODE_LCONTROL, CODE_OR, JOYCODE_1_BUTTON1) },
183 { IPT_BUTTON2 | IPF_PLAYER1, "P1 Button 2", SEQ_DEF_3(KEYCODE_LALT, CODE_OR, JOYCODE_1_BUTTON2) },
184 { IPT_BUTTON3 | IPF_PLAYER1, "P1 Button 3", SEQ_DEF_3(KEYCODE_SPACE, CODE_OR, JOYCODE_1_BUTTON3) },
185 { IPT_BUTTON4 | IPF_PLAYER1, "P1 Button 4", SEQ_DEF_3(KEYCODE_LSHIFT, CODE_OR, JOYCODE_1_BUTTON4) },
186 { IPT_BUTTON5 | IPF_PLAYER1, "P1 Button 5", SEQ_DEF_3(KEYCODE_Z, CODE_OR, JOYCODE_1_BUTTON5) },
187 { IPT_BUTTON6 | IPF_PLAYER1, "P1 Button 6", SEQ_DEF_3(KEYCODE_X, CODE_OR, JOYCODE_1_BUTTON6) },
188 { IPT_BUTTON7 | IPF_PLAYER1, "P1 Button 7", SEQ_DEF_1(KEYCODE_C) },
189 { IPT_BUTTON8 | IPF_PLAYER1, "P1 Button 8", SEQ_DEF_1(KEYCODE_V) },
190 { IPT_BUTTON9 | IPF_PLAYER1, "P1 Button 9", SEQ_DEF_1(KEYCODE_B) },
191 { IPT_BUTTON10 | IPF_PLAYER1, "P1 Button 10", SEQ_DEF_1(KEYCODE_N) },
192 { IPT_JOYSTICKRIGHT_UP | IPF_PLAYER1, "P1 Right/Up", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_1_BUTTON4) },
193 { IPT_JOYSTICKRIGHT_DOWN | IPF_PLAYER1, "P1 Right/Down", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_1_BUTTON2) },
194 { IPT_JOYSTICKRIGHT_LEFT | IPF_PLAYER1, "P1 Right/Left", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_1_BUTTON3) },
195 { IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER1, "P1 Right/Right", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_1_BUTTON1) },
196 { IPT_JOYSTICKLEFT_UP | IPF_PLAYER1, "P1 Left/Up", SEQ_DEF_3(KEYCODE_E, CODE_OR, JOYCODE_1_UP) },
197 { IPT_JOYSTICKLEFT_DOWN | IPF_PLAYER1, "P1 Left/Down", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_1_DOWN) },
198 { IPT_JOYSTICKLEFT_LEFT | IPF_PLAYER1, "P1 Left/Left", SEQ_DEF_3(KEYCODE_S, CODE_OR, JOYCODE_1_LEFT) },
199 { IPT_JOYSTICKLEFT_RIGHT | IPF_PLAYER1, "P1 Left/Right", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_1_RIGHT) },
200
201 { IPT_JOYSTICK_UP | IPF_PLAYER2, "P2 Up", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
202 { IPT_JOYSTICK_DOWN | IPF_PLAYER2, "P2 Down", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
203 { IPT_JOYSTICK_LEFT | IPF_PLAYER2, "P2 Left", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
204 { IPT_JOYSTICK_RIGHT | IPF_PLAYER2, "P2 Right", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
205 { IPT_BUTTON1 | IPF_PLAYER2, "P2 Button 1", SEQ_DEF_3(KEYCODE_A, CODE_OR, JOYCODE_2_BUTTON1) },
206 { IPT_BUTTON2 | IPF_PLAYER2, "P2 Button 2", SEQ_DEF_3(KEYCODE_S, CODE_OR, JOYCODE_2_BUTTON2) },
207 { IPT_BUTTON3 | IPF_PLAYER2, "P2 Button 3", SEQ_DEF_3(KEYCODE_Q, CODE_OR, JOYCODE_2_BUTTON3) },
208 { IPT_BUTTON4 | IPF_PLAYER2, "P2 Button 4", SEQ_DEF_3(KEYCODE_W, CODE_OR, JOYCODE_2_BUTTON4) },
209 { IPT_BUTTON5 | IPF_PLAYER2, "P2 Button 5", SEQ_DEF_1(JOYCODE_2_BUTTON5) },
210 { IPT_BUTTON6 | IPF_PLAYER2, "P2 Button 6", SEQ_DEF_1(JOYCODE_2_BUTTON6) },
211 { IPT_BUTTON7 | IPF_PLAYER2, "P2 Button 7", SEQ_DEF_0 },
212 { IPT_BUTTON8 | IPF_PLAYER2, "P2 Button 8", SEQ_DEF_0 },
213 { IPT_BUTTON9 | IPF_PLAYER2, "P2 Button 9", SEQ_DEF_0 },
214 { IPT_BUTTON10 | IPF_PLAYER2, "P2 Button 10", SEQ_DEF_0 },
215 { IPT_JOYSTICKRIGHT_UP | IPF_PLAYER2, "P2 Right/Up", SEQ_DEF_0 },
216 { IPT_JOYSTICKRIGHT_DOWN | IPF_PLAYER2, "P2 Right/Down", SEQ_DEF_0 },
217 { IPT_JOYSTICKRIGHT_LEFT | IPF_PLAYER2, "P2 Right/Left", SEQ_DEF_0 },
218 { IPT_JOYSTICKRIGHT_RIGHT | IPF_PLAYER2, "P2 Right/Right", SEQ_DEF_0 },
219 { IPT_JOYSTICKLEFT_UP | IPF_PLAYER2, "P2 Left/Up", SEQ_DEF_0 },
220 { IPT_JOYSTICKLEFT_DOWN | IPF_PLAYER2, "P2 Left/Down", SEQ_DEF_0 },
221 { IPT_JOYSTICKLEFT_LEFT | IPF_PLAYER2, "P2 Left/Left", SEQ_DEF_0 },
222 { IPT_JOYSTICKLEFT_RIGHT | IPF_PLAYER2, "P2 Left/Right", SEQ_DEF_0 },
223
224 { IPT_JOYSTICK_UP | IPF_PLAYER3, "P3 Up", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
225 { IPT_JOYSTICK_DOWN | IPF_PLAYER3, "P3 Down", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
226 { IPT_JOYSTICK_LEFT | IPF_PLAYER3, "P3 Left", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
227 { IPT_JOYSTICK_RIGHT | IPF_PLAYER3, "P3 Right", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
228 { IPT_BUTTON1 | IPF_PLAYER3, "P3 Button 1", SEQ_DEF_3(KEYCODE_RCONTROL, CODE_OR, JOYCODE_3_BUTTON1) },
229 { IPT_BUTTON2 | IPF_PLAYER3, "P3 Button 2", SEQ_DEF_3(KEYCODE_RSHIFT, CODE_OR, JOYCODE_3_BUTTON2) },
230 { IPT_BUTTON3 | IPF_PLAYER3, "P3 Button 3", SEQ_DEF_3(KEYCODE_ENTER, CODE_OR, JOYCODE_3_BUTTON3) },
231 { IPT_BUTTON4 | IPF_PLAYER3, "P3 Button 4", SEQ_DEF_1(JOYCODE_3_BUTTON4) },
232
233 { IPT_JOYSTICK_UP | IPF_PLAYER4, "P4 Up", SEQ_DEF_1(JOYCODE_4_UP) },
234 { IPT_JOYSTICK_DOWN | IPF_PLAYER4, "P4 Down", SEQ_DEF_1(JOYCODE_4_DOWN) },
235 { IPT_JOYSTICK_LEFT | IPF_PLAYER4, "P4 Left", SEQ_DEF_1(JOYCODE_4_LEFT) },
236 { IPT_JOYSTICK_RIGHT | IPF_PLAYER4, "P4 Right", SEQ_DEF_1(JOYCODE_4_RIGHT) },
237 { IPT_BUTTON1 | IPF_PLAYER4, "P4 Button 1", SEQ_DEF_1(JOYCODE_4_BUTTON1) },
238 { IPT_BUTTON2 | IPF_PLAYER4, "P4 Button 2", SEQ_DEF_1(JOYCODE_4_BUTTON2) },
239 { IPT_BUTTON3 | IPF_PLAYER4, "P4 Button 3", SEQ_DEF_1(JOYCODE_4_BUTTON3) },
240 { IPT_BUTTON4 | IPF_PLAYER4, "P4 Button 4", SEQ_DEF_1(JOYCODE_4_BUTTON4) },
241
242 { IPT_PEDAL | IPF_PLAYER1, "Pedal 1", SEQ_DEF_3(KEYCODE_LCONTROL, CODE_OR, JOYCODE_1_BUTTON1) },
243 { (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER1, "P1 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
244 { IPT_PEDAL | IPF_PLAYER2, "Pedal 2", SEQ_DEF_3(KEYCODE_A, CODE_OR, JOYCODE_2_BUTTON1) },
245 { (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER2, "P2 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
246 { IPT_PEDAL | IPF_PLAYER3, "Pedal 3", SEQ_DEF_3(KEYCODE_RCONTROL, CODE_OR, JOYCODE_3_BUTTON1) },
247 { (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER3, "P3 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
248 { IPT_PEDAL | IPF_PLAYER4, "Pedal 4", SEQ_DEF_1(JOYCODE_4_BUTTON1) },
249 { (IPT_PEDAL+IPT_EXTENSION) | IPF_PLAYER4, "P4 Auto Release <Y/N>", SEQ_DEF_1(KEYCODE_Y) },
250
251 { IPT_PADDLE | IPF_PLAYER1, "Paddle", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
252 { (IPT_PADDLE | IPF_PLAYER1)+IPT_EXTENSION, "Paddle", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
253 { IPT_PADDLE | IPF_PLAYER2, "Paddle 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
254 { (IPT_PADDLE | IPF_PLAYER2)+IPT_EXTENSION, "Paddle 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
255 { IPT_PADDLE | IPF_PLAYER3, "Paddle 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
256 { (IPT_PADDLE | IPF_PLAYER3)+IPT_EXTENSION, "Paddle 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
257 { IPT_PADDLE | IPF_PLAYER4, "Paddle 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
258 { (IPT_PADDLE | IPF_PLAYER4)+IPT_EXTENSION, "Paddle 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },
259 { IPT_PADDLE_V | IPF_PLAYER1, "Paddle V", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
260 { (IPT_PADDLE_V | IPF_PLAYER1)+IPT_EXTENSION, "Paddle V", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
261 { IPT_PADDLE_V | IPF_PLAYER2, "Paddle V 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
262 { (IPT_PADDLE_V | IPF_PLAYER2)+IPT_EXTENSION, "Paddle V 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
263 { IPT_PADDLE_V | IPF_PLAYER3, "Paddle V 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
264 { (IPT_PADDLE_V | IPF_PLAYER3)+IPT_EXTENSION, "Paddle V 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
265 { IPT_PADDLE_V | IPF_PLAYER4, "Paddle V 4", SEQ_DEF_1(JOYCODE_4_UP) },
266 { (IPT_PADDLE_V | IPF_PLAYER4)+IPT_EXTENSION, "Paddle V 4", SEQ_DEF_1(JOYCODE_4_DOWN) },
267 { IPT_DIAL | IPF_PLAYER1, "Dial", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
268 { (IPT_DIAL | IPF_PLAYER1)+IPT_EXTENSION, "Dial", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
269 { IPT_DIAL | IPF_PLAYER2, "Dial 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
270 { (IPT_DIAL | IPF_PLAYER2)+IPT_EXTENSION, "Dial 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
271 { IPT_DIAL | IPF_PLAYER3, "Dial 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
272 { (IPT_DIAL | IPF_PLAYER3)+IPT_EXTENSION, "Dial 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
273 { IPT_DIAL | IPF_PLAYER4, "Dial 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
274 { (IPT_DIAL | IPF_PLAYER4)+IPT_EXTENSION, "Dial 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },
275 { IPT_DIAL_V | IPF_PLAYER1, "Dial V", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
276 { (IPT_DIAL_V | IPF_PLAYER1)+IPT_EXTENSION, "Dial V", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
277 { IPT_DIAL_V | IPF_PLAYER2, "Dial V 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
278 { (IPT_DIAL_V | IPF_PLAYER2)+IPT_EXTENSION, "Dial V 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
279 { IPT_DIAL_V | IPF_PLAYER3, "Dial V 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
280 { (IPT_DIAL_V | IPF_PLAYER3)+IPT_EXTENSION, "Dial V 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
281 { IPT_DIAL_V | IPF_PLAYER4, "Dial V 4", SEQ_DEF_1(JOYCODE_4_UP) },
282 { (IPT_DIAL_V | IPF_PLAYER4)+IPT_EXTENSION, "Dial V 4", SEQ_DEF_1(JOYCODE_4_DOWN) },
283
284 { IPT_TRACKBALL_X | IPF_PLAYER1, "Track X", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
285 { (IPT_TRACKBALL_X | IPF_PLAYER1)+IPT_EXTENSION, "Track X", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
286 { IPT_TRACKBALL_X | IPF_PLAYER2, "Track X 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
287 { (IPT_TRACKBALL_X | IPF_PLAYER2)+IPT_EXTENSION, "Track X 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
288 { IPT_TRACKBALL_X | IPF_PLAYER3, "Track X 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
289 { (IPT_TRACKBALL_X | IPF_PLAYER3)+IPT_EXTENSION, "Track X 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
290 { IPT_TRACKBALL_X | IPF_PLAYER4, "Track X 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
291 { (IPT_TRACKBALL_X | IPF_PLAYER4)+IPT_EXTENSION, "Track X 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },
292
293 { IPT_TRACKBALL_Y | IPF_PLAYER1, "Track Y", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
294 { (IPT_TRACKBALL_Y | IPF_PLAYER1)+IPT_EXTENSION, "Track Y", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
295 { IPT_TRACKBALL_Y | IPF_PLAYER2, "Track Y 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
296 { (IPT_TRACKBALL_Y | IPF_PLAYER2)+IPT_EXTENSION, "Track Y 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
297 { IPT_TRACKBALL_Y | IPF_PLAYER3, "Track Y 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
298 { (IPT_TRACKBALL_Y | IPF_PLAYER3)+IPT_EXTENSION, "Track Y 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
299 { IPT_TRACKBALL_Y | IPF_PLAYER4, "Track Y 4", SEQ_DEF_1(JOYCODE_4_UP) },
300 { (IPT_TRACKBALL_Y | IPF_PLAYER4)+IPT_EXTENSION, "Track Y 4", SEQ_DEF_1(JOYCODE_4_DOWN) },
301
302 { IPT_AD_STICK_X | IPF_PLAYER1, "AD Stick X", SEQ_DEF_3(KEYCODE_LEFT, CODE_OR, JOYCODE_1_LEFT) },
303 { (IPT_AD_STICK_X | IPF_PLAYER1)+IPT_EXTENSION, "AD Stick X", SEQ_DEF_3(KEYCODE_RIGHT, CODE_OR, JOYCODE_1_RIGHT) },
304 { IPT_AD_STICK_X | IPF_PLAYER2, "AD Stick X 2", SEQ_DEF_3(KEYCODE_D, CODE_OR, JOYCODE_2_LEFT) },
305 { (IPT_AD_STICK_X | IPF_PLAYER2)+IPT_EXTENSION, "AD Stick X 2", SEQ_DEF_3(KEYCODE_G, CODE_OR, JOYCODE_2_RIGHT) },
306 { IPT_AD_STICK_X | IPF_PLAYER3, "AD Stick X 3", SEQ_DEF_3(KEYCODE_J, CODE_OR, JOYCODE_3_LEFT) },
307 { (IPT_AD_STICK_X | IPF_PLAYER3)+IPT_EXTENSION, "AD Stick X 3", SEQ_DEF_3(KEYCODE_L, CODE_OR, JOYCODE_3_RIGHT) },
308 { IPT_AD_STICK_X | IPF_PLAYER4, "AD Stick X 4", SEQ_DEF_1(JOYCODE_4_LEFT) },
309 { (IPT_AD_STICK_X | IPF_PLAYER4)+IPT_EXTENSION, "AD Stick X 4", SEQ_DEF_1(JOYCODE_4_RIGHT) },
310
311 { IPT_AD_STICK_Y | IPF_PLAYER1, "AD Stick Y", SEQ_DEF_3(KEYCODE_UP, CODE_OR, JOYCODE_1_UP) },
312 { (IPT_AD_STICK_Y | IPF_PLAYER1)+IPT_EXTENSION, "AD Stick Y", SEQ_DEF_3(KEYCODE_DOWN, CODE_OR, JOYCODE_1_DOWN) },
313 { IPT_AD_STICK_Y | IPF_PLAYER2, "AD Stick Y 2", SEQ_DEF_3(KEYCODE_R, CODE_OR, JOYCODE_2_UP) },
314 { (IPT_AD_STICK_Y | IPF_PLAYER2)+IPT_EXTENSION, "AD Stick Y 2", SEQ_DEF_3(KEYCODE_F, CODE_OR, JOYCODE_2_DOWN) },
315 { IPT_AD_STICK_Y | IPF_PLAYER3, "AD Stick Y 3", SEQ_DEF_3(KEYCODE_I, CODE_OR, JOYCODE_3_UP) },
316 { (IPT_AD_STICK_Y | IPF_PLAYER3)+IPT_EXTENSION, "AD Stick Y 3", SEQ_DEF_3(KEYCODE_K, CODE_OR, JOYCODE_3_DOWN) },
317 { IPT_AD_STICK_Y | IPF_PLAYER4, "AD Stick Y 4", SEQ_DEF_1(JOYCODE_4_UP) },
318 { (IPT_AD_STICK_Y | IPF_PLAYER4)+IPT_EXTENSION, "AD Stick Y 4", SEQ_DEF_1(JOYCODE_4_DOWN) },
319
320 { IPT_UNKNOWN, "UNKNOWN", SEQ_DEF_0 },
321 { IPT_END, 0, SEQ_DEF_0 } /* returned when there is no match */
322 };
323
324 struct ipd inputport_defaults_backup[sizeof(inputport_defaults)/sizeof(struct ipd)];
325
326 /***************************************************************************/
327 /* Generic IO */
328
readint(void * f,UINT32 * num)329 static int readint(void *f,UINT32 *num)
330 {
331 unsigned i;
332
333 *num = 0;
334 for (i = 0;i < sizeof(UINT32);i++)
335 {
336 unsigned char c;
337
338
339 *num <<= 8;
340 if (osd_fread(f,&c,1) != 1)
341 return -1;
342 *num |= c;
343 }
344
345 return 0;
346 }
347
writeint(void * f,UINT32 num)348 static void writeint(void *f,UINT32 num)
349 {
350 unsigned i;
351
352 for (i = 0;i < sizeof(UINT32);i++)
353 {
354 unsigned char c;
355
356
357 c = (num >> 8 * (sizeof(UINT32)-1)) & 0xff;
358 osd_fwrite(f,&c,1);
359 num <<= 8;
360 }
361 }
362
readword(void * f,UINT16 * num)363 static int readword(void *f,UINT16 *num)
364 {
365 unsigned i;
366 int res;
367
368 res = 0;
369 for (i = 0;i < sizeof(UINT16);i++)
370 {
371 unsigned char c;
372
373
374 res <<= 8;
375 if (osd_fread(f,&c,1) != 1)
376 return -1;
377 res |= c;
378 }
379
380 *num = res;
381 return 0;
382 }
383
writeword(void * f,UINT16 num)384 static void writeword(void *f,UINT16 num)
385 {
386 unsigned i;
387
388 for (i = 0;i < sizeof(UINT16);i++)
389 {
390 unsigned char c;
391
392
393 c = (num >> 8 * (sizeof(UINT16)-1)) & 0xff;
394 osd_fwrite(f,&c,1);
395 num <<= 8;
396 }
397 }
398
399 #ifndef NOLEGACY
400 #include "legacy.h"
401 #endif
402
seq_read_ver_8(void * f,InputSeq * seq)403 static int seq_read_ver_8(void* f, InputSeq* seq)
404 {
405 int j,len;
406 UINT32 i;
407 UINT16 w;
408
409 if (readword(f,&w) != 0)
410 return -1;
411
412 len = w;
413 seq_set_0(seq);
414 for(j=0;j<len;++j)
415 {
416 if (readint(f,&i) != 0)
417 return -1;
418 (*seq)[j] = savecode_to_code(i);
419 }
420
421 return 0;
422 }
423
seq_read(void * f,InputSeq * seq,int ver)424 static int seq_read(void* f, InputSeq* seq, int ver)
425 {
426 #ifdef NOLEGACY
427 if (ver==8)
428 return seq_read_ver_8(f,seq);
429 #else
430 switch (ver) {
431 case 5 : return seq_read_ver_5(f,seq);
432 case 6 : return seq_read_ver_6(f,seq);
433 case 7 : return seq_read_ver_7(f,seq);
434 case 8 : return seq_read_ver_8(f,seq);
435 }
436 #endif
437 return -1;
438 }
439
seq_write(void * f,InputSeq * seq)440 static void seq_write(void* f, InputSeq* seq)
441 {
442 int j,len;
443 for(len=0;len<SEQ_MAX;++len)
444 if ((*seq)[len] == CODE_NONE)
445 break;
446 writeword(f,len);
447 for(j=0;j<len;++j)
448 writeint(f, code_to_savecode( (*seq)[j] ));
449 }
450
451 /***************************************************************************/
452 /* Load */
453
load_default_keys(void)454 static void load_default_keys(void)
455 {
456 void *f;
457
458
459 osd_customize_inputport_defaults(inputport_defaults);
460 memcpy(inputport_defaults_backup,inputport_defaults,sizeof(inputport_defaults));
461
462 if ((f = osd_fopen("default",0,OSD_FILETYPE_CONFIG,0)) != 0)
463 {
464 char buf[8];
465 int version;
466
467 /* read header */
468 if (osd_fread(f,buf,8) != 8)
469 goto getout;
470
471 if (memcmp(buf,MAMEDEFSTRING_V5,8) == 0)
472 version = 5;
473 else if (memcmp(buf,MAMEDEFSTRING_V6,8) == 0)
474 version = 6;
475 else if (memcmp(buf,MAMEDEFSTRING_V7,8) == 0)
476 version = 7;
477 else if (memcmp(buf,MAMEDEFSTRING_V8,8) == 0)
478 version = 8;
479 else
480 goto getout; /* header invalid */
481
482 for (;;)
483 {
484 UINT32 type;
485 InputSeq def_seq;
486 InputSeq seq;
487 int i;
488
489 if (readint(f,&type) != 0)
490 goto getout;
491
492 if (seq_read(f,&def_seq,version)!=0)
493 goto getout;
494 if (seq_read(f,&seq,version)!=0)
495 goto getout;
496
497 i = 0;
498 while (inputport_defaults[i].type != IPT_END)
499 {
500 if (inputport_defaults[i].type == type)
501 {
502 /* load stored settings only if the default hasn't changed */
503 if (seq_cmp(&inputport_defaults[i].seq,&def_seq)==0)
504 seq_copy(&inputport_defaults[i].seq,&seq);
505 }
506
507 i++;
508 }
509 }
510
511 getout:
512 osd_fclose(f);
513 }
514 }
515
save_default_keys(void)516 static void save_default_keys(void)
517 {
518 void *f;
519
520
521 if ((f = osd_fopen("default",0,OSD_FILETYPE_CONFIG,1)) != 0)
522 {
523 int i;
524
525
526 /* write header */
527 osd_fwrite(f,MAMEDEFSTRING_V8,8);
528
529 i = 0;
530 while (inputport_defaults[i].type != IPT_END)
531 {
532 writeint(f,inputport_defaults[i].type);
533
534 seq_write(f,&inputport_defaults_backup[i].seq);
535 seq_write(f,&inputport_defaults[i].seq);
536
537 i++;
538 }
539
540 osd_fclose(f);
541 }
542 memcpy(inputport_defaults,inputport_defaults_backup,sizeof(inputport_defaults_backup));
543 }
544
input_port_read_ver_8(void * f,struct InputPort * in)545 static int input_port_read_ver_8(void *f,struct InputPort *in)
546 {
547 UINT32 i;
548 UINT16 w;
549 if (readint(f,&i) != 0)
550 return -1;
551 in->type = i;
552
553 if (readword(f,&w) != 0)
554 return -1;
555 in->mask = w;
556
557 if (readword(f,&w) != 0)
558 return -1;
559 in->default_value = w;
560
561 if (seq_read_ver_8(f,&in->seq) != 0)
562 return -1;
563
564 return 0;
565 }
566
input_port_read(void * f,struct InputPort * in,int ver)567 static int input_port_read(void *f,struct InputPort *in, int ver)
568 {
569 #ifdef NOLEGACY
570 if (ver==8)
571 return input_port_read_ver_8(f,in);
572 #else
573 switch (ver) {
574 case 5 : return input_port_read_ver_5(f,in);
575 case 6 : return input_port_read_ver_6(f,in);
576 case 7 : return input_port_read_ver_7(f,in);
577 case 8 : return input_port_read_ver_8(f,in);
578 }
579 #endif
580 return -1;
581 }
582
input_port_write(void * f,struct InputPort * in)583 static void input_port_write(void *f,struct InputPort *in)
584 {
585 writeint(f,in->type);
586 writeword(f,in->mask);
587 writeword(f,in->default_value);
588 seq_write(f,&in->seq);
589 }
590
591
load_input_port_settings(void)592 int load_input_port_settings(void)
593 {
594 void *f;
595 #ifdef MAME_NET
596 struct InputPort *in;
597 int port, player;
598 #endif /* MAME_NET */
599
600
601 load_default_keys();
602
603 if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,0)) != 0)
604 {
605 #ifndef MAME_NET
606 struct InputPort *in;
607 #endif
608 unsigned int total,savedtotal;
609 char buf[8];
610 int i;
611 int version;
612
613 in = Machine->input_ports_default;
614
615 /* calculate the size of the array */
616 total = 0;
617 while (in->type != IPT_END)
618 {
619 total++;
620 in++;
621 }
622
623 /* read header */
624 if (osd_fread(f,buf,8) != 8)
625 goto getout;
626
627 if (memcmp(buf,MAMECFGSTRING_V5,8) == 0)
628 version = 5;
629 else if (memcmp(buf,MAMECFGSTRING_V6,8) == 0)
630 version = 6;
631 else if (memcmp(buf,MAMECFGSTRING_V7,8) == 0)
632 version = 7;
633 else if (memcmp(buf,MAMECFGSTRING_V8,8) == 0)
634 version = 8;
635 else
636 goto getout; /* header invalid */
637
638 /* read array size */
639 if (readint(f,&savedtotal) != 0)
640 goto getout;
641 if (total != savedtotal)
642 goto getout; /* different size */
643
644 /* read the original settings and compare them with the ones defined in the driver */
645 in = Machine->input_ports_default;
646 while (in->type != IPT_END)
647 {
648 struct InputPort saved;
649
650 if (input_port_read(f,&saved,version) != 0)
651 goto getout;
652
653 if (in->mask != saved.mask ||
654 in->default_value != saved.default_value ||
655 in->type != saved.type ||
656 seq_cmp(&in->seq,&saved.seq) !=0 )
657 goto getout; /* the default values are different */
658
659 in++;
660 }
661
662 /* read the current settings */
663 in = Machine->input_ports;
664 while (in->type != IPT_END)
665 {
666 if (input_port_read(f,in,version) != 0)
667 goto getout;
668 in++;
669 }
670
671 /* Clear the coin & ticket counters/flags - LBO 042898 */
672 for (i = 0; i < COIN_COUNTERS; i ++)
673 coins[i] = lastcoin[i] = coinlockedout[i] = 0;
674 dispensed_tickets = 0;
675
676 /* read in the coin/ticket counters */
677 for (i = 0; i < COIN_COUNTERS; i ++)
678 {
679 if (readint(f,&coins[i]) != 0)
680 goto getout;
681 }
682 if (readint(f,&dispensed_tickets) != 0)
683 goto getout;
684
685 mixer_read_config(f);
686
687 getout:
688 osd_fclose(f);
689 }
690
691 /* All analog ports need initialization */
692 {
693 int i;
694 for (i = 0; i < MAX_INPUT_PORTS; i++)
695 input_analog_init[i] = 1;
696 }
697 #ifdef MAME_NET
698 /* Find out what port is used by what player and swap regular inputs */
699 in = Machine->input_ports;
700
701 // if (in->type == IPT_END) return; /* nothing to do */
702
703 /* make sure the InputPort definition is correct */
704 // if (in->type != IPT_PORT)
705 // {
706 // logerror("Error in InputPort definition: expecting PORT_START\n");
707 // return;
708 // }
709 // else in++;
710 in++;
711
712 /* scan all the input ports */
713 port = 0;
714 while (in->type != IPT_END && port < MAX_INPUT_PORTS)
715 {
716 /* now check the input bits. */
717 while (in->type != IPT_END && in->type != IPT_PORT)
718 {
719 if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING && /* skip dipswitch definitions */
720 (in->type & ~IPF_MASK) != IPT_EXTENSION && /* skip analog extension fields */
721 (in->type & IPF_UNUSED) == 0 && /* skip unused bits */
722 !(!options.cheat && (in->type & IPF_CHEAT)) && /* skip cheats if cheats disabled */
723 (in->type & ~IPF_MASK) != IPT_VBLANK && /* skip vblank stuff */
724 ((in->type & ~IPF_MASK) >= IPT_COIN1 && /* skip if coin input and it's locked out */
725 (in->type & ~IPF_MASK) <= IPT_COIN4 &&
726 coinlockedout[(in->type & ~IPF_MASK) - IPT_COIN1]))
727 {
728 player = 0;
729 if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
730 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
731 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
732
733 if (((in->type & ~IPF_MASK) > IPT_ANALOG_START)
734 && ((in->type & ~IPF_MASK) < IPT_ANALOG_END))
735 {
736 analog_player_port[port] = player;
737 }
738 if (((in->type & ~IPF_MASK) == IPT_BUTTON1) ||
739 ((in->type & ~IPF_MASK) == IPT_BUTTON2) ||
740 ((in->type & ~IPF_MASK) == IPT_BUTTON3) ||
741 ((in->type & ~IPF_MASK) == IPT_BUTTON4) ||
742 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_UP) ||
743 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_DOWN) ||
744 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_LEFT) ||
745 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_RIGHT) ||
746 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_UP) ||
747 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_DOWN) ||
748 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_LEFT) ||
749 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_RIGHT) ||
750 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_UP) ||
751 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_DOWN) ||
752 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_LEFT) ||
753 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_RIGHT) ||
754 ((in->type & ~IPF_MASK) == IPT_PADDLE) ||
755 ((in->type & ~IPF_MASK) == IPT_DIAL) ||
756 ((in->type & ~IPF_MASK) == IPT_TRACKBALL_X) ||
757 ((in->type & ~IPF_MASK) == IPT_TRACKBALL_Y) ||
758 ((in->type & ~IPF_MASK) == IPT_AD_STICK_X) ||
759 ((in->type & ~IPF_MASK) == IPT_AD_STICK_Y))
760 {
761 switch (default_player)
762 {
763 case 0:
764 /* do nothing */
765 break;
766 case 1:
767 if (player == 0)
768 {
769 in->type &= ~IPF_PLAYER1;
770 in->type |= IPF_PLAYER2;
771 }
772 else if (player == 1)
773 {
774 in->type &= ~IPF_PLAYER2;
775 in->type |= IPF_PLAYER1;
776 }
777 break;
778 case 2:
779 if (player == 0)
780 {
781 in->type &= ~IPF_PLAYER1;
782 in->type |= IPF_PLAYER3;
783 }
784 else if (player == 2)
785 {
786 in->type &= ~IPF_PLAYER3;
787 in->type |= IPF_PLAYER1;
788 }
789 break;
790 case 3:
791 if (player == 0)
792 {
793 in->type &= ~IPF_PLAYER1;
794 in->type |= IPF_PLAYER4;
795 }
796 else if (player == 3)
797 {
798 in->type &= ~IPF_PLAYER4;
799 in->type |= IPF_PLAYER1;
800 }
801 break;
802 }
803 }
804 }
805 in++;
806 }
807 port++;
808 if (in->type == IPT_PORT) in++;
809 }
810
811 /* TODO: at this point the games should initialize peers to same as server */
812
813 #endif /* MAME_NET */
814
815 update_input_ports();
816
817 /* if we didn't find a saved config, return 0 so the main core knows that it */
818 /* is the first time the game is run and it should diplay the disclaimer. */
819 if (f) return 1;
820 else return 0;
821 }
822
823 /***************************************************************************/
824 /* Save */
825
save_input_port_settings(void)826 void save_input_port_settings(void)
827 {
828 void *f;
829 #ifdef MAME_NET
830 struct InputPort *in;
831 int port, player;
832
833 /* Swap input port definitions back to defaults */
834 in = Machine->input_ports;
835
836 if (in->type == IPT_END) return; /* nothing to do */
837
838 /* make sure the InputPort definition is correct */
839 if (in->type != IPT_PORT)
840 {
841 logerror("Error in InputPort definition: expecting PORT_START\n");
842 return;
843 }
844 else in++;
845
846 /* scan all the input ports */
847 port = 0;
848 while (in->type != IPT_END && port < MAX_INPUT_PORTS)
849 {
850 /* now check the input bits. */
851 while (in->type != IPT_END && in->type != IPT_PORT)
852 {
853 if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING && /* skip dipswitch definitions */
854 (in->type & ~IPF_MASK) != IPT_EXTENSION && /* skip analog extension fields */
855 (in->type & IPF_UNUSED) == 0 && /* skip unused bits */
856 !(!options.cheat && (in->type & IPF_CHEAT)) && /* skip cheats if cheats disabled */
857 (in->type & ~IPF_MASK) != IPT_VBLANK && /* skip vblank stuff */
858 ((in->type & ~IPF_MASK) >= IPT_COIN1 && /* skip if coin input and it's locked out */
859 (in->type & ~IPF_MASK) <= IPT_COIN4 &&
860 coinlockedout[(in->type & ~IPF_MASK) - IPT_COIN1]))
861 {
862 player = 0;
863 if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
864 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
865 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
866
867 if (((in->type & ~IPF_MASK) == IPT_BUTTON1) ||
868 ((in->type & ~IPF_MASK) == IPT_BUTTON2) ||
869 ((in->type & ~IPF_MASK) == IPT_BUTTON3) ||
870 ((in->type & ~IPF_MASK) == IPT_BUTTON4) ||
871 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_UP) ||
872 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_DOWN) ||
873 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_LEFT) ||
874 ((in->type & ~IPF_MASK) == IPT_JOYSTICK_RIGHT) ||
875 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_UP) ||
876 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_DOWN) ||
877 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_LEFT) ||
878 ((in->type & ~IPF_MASK) == IPT_JOYSTICKRIGHT_RIGHT) ||
879 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_UP) ||
880 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_DOWN) ||
881 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_LEFT) ||
882 ((in->type & ~IPF_MASK) == IPT_JOYSTICKLEFT_RIGHT) ||
883 ((in->type & ~IPF_MASK) == IPT_PADDLE) ||
884 ((in->type & ~IPF_MASK) == IPT_DIAL) ||
885 ((in->type & ~IPF_MASK) == IPT_TRACKBALL_X) ||
886 ((in->type & ~IPF_MASK) == IPT_TRACKBALL_Y) ||
887 ((in->type & ~IPF_MASK) == IPT_AD_STICK_X) ||
888 ((in->type & ~IPF_MASK) == IPT_AD_STICK_Y))
889 {
890 switch (default_player)
891 {
892 case 0:
893 /* do nothing */
894 analog_player_port[port] = player;
895 break;
896 case 1:
897 if (player == 0)
898 {
899 in->type &= ~IPF_PLAYER1;
900 in->type |= IPF_PLAYER2;
901 analog_player_port[port] = 1;
902 }
903 else if (player == 1)
904 {
905 in->type &= ~IPF_PLAYER2;
906 in->type |= IPF_PLAYER1;
907 analog_player_port[port] = 0;
908 }
909 break;
910 case 2:
911 if (player == 0)
912 {
913 in->type &= ~IPF_PLAYER1;
914 in->type |= IPF_PLAYER3;
915 analog_player_port[port] = 2;
916 }
917 else if (player == 2)
918 {
919 in->type &= ~IPF_PLAYER3;
920 in->type |= IPF_PLAYER1;
921 analog_player_port[port] = 0;
922 }
923 break;
924 case 3:
925 if (player == 0)
926 {
927 in->type &= ~IPF_PLAYER1;
928 in->type |= IPF_PLAYER4;
929 analog_player_port[port] = 3;
930 }
931 else if (player == 3)
932 {
933 in->type &= ~IPF_PLAYER4;
934 in->type |= IPF_PLAYER1;
935 analog_player_port[port] = 0;
936 }
937 break;
938 }
939 }
940 }
941 in++;
942 }
943 port++;
944 if (in->type == IPT_PORT) in++;
945 }
946 #endif /* MAME_NET */
947
948 save_default_keys();
949
950 if ((f = osd_fopen(Machine->gamedrv->name,0,OSD_FILETYPE_CONFIG,1)) != 0)
951 {
952 #ifndef MAME_NET
953 struct InputPort *in;
954 #endif /* MAME_NET */
955 int total;
956 int i;
957
958
959 in = Machine->input_ports_default;
960
961 /* calculate the size of the array */
962 total = 0;
963 while (in->type != IPT_END)
964 {
965 total++;
966 in++;
967 }
968
969 /* write header */
970 osd_fwrite(f,MAMECFGSTRING_V8,8);
971 /* write array size */
972 writeint(f,total);
973 /* write the original settings as defined in the driver */
974 in = Machine->input_ports_default;
975 while (in->type != IPT_END)
976 {
977 input_port_write(f,in);
978 in++;
979 }
980 /* write the current settings */
981 in = Machine->input_ports;
982 while (in->type != IPT_END)
983 {
984 input_port_write(f,in);
985 in++;
986 }
987
988 /* write out the coin/ticket counters for this machine - LBO 042898 */
989 for (i = 0; i < COIN_COUNTERS; i ++)
990 writeint(f,coins[i]);
991 writeint(f,dispensed_tickets);
992
993 mixer_write_config(f);
994
995 osd_fclose(f);
996 }
997 }
998
999
1000
1001 /* Note that the following 3 routines have slightly different meanings with analog ports */
input_port_name(const struct InputPort * in)1002 const char *input_port_name(const struct InputPort *in)
1003 {
1004 int i;
1005 unsigned type;
1006
1007 if (in->name != IP_NAME_DEFAULT) return in->name;
1008
1009 i = 0;
1010
1011 if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
1012 type = (in-1)->type & (~IPF_MASK | IPF_PLAYERMASK);
1013 else
1014 type = in->type & (~IPF_MASK | IPF_PLAYERMASK);
1015
1016 while (inputport_defaults[i].type != IPT_END &&
1017 inputport_defaults[i].type != type)
1018 i++;
1019
1020 if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
1021 return inputport_defaults[i+1].name;
1022 else
1023 return inputport_defaults[i].name;
1024 }
1025
input_port_type_seq(int type)1026 InputSeq* input_port_type_seq(int type)
1027 {
1028 unsigned i;
1029
1030 i = 0;
1031
1032 while (inputport_defaults[i].type != IPT_END &&
1033 inputport_defaults[i].type != type)
1034 i++;
1035
1036 return &inputport_defaults[i].seq;
1037 }
1038
input_port_seq(const struct InputPort * in)1039 InputSeq* input_port_seq(const struct InputPort *in)
1040 {
1041 int i,type;
1042
1043 static InputSeq ip_none = SEQ_DEF_1(CODE_NONE);
1044
1045 while (seq_get_1((InputSeq*)&in->seq) == CODE_PREVIOUS) in--;
1046
1047 if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
1048 {
1049 type = (in-1)->type & (~IPF_MASK | IPF_PLAYERMASK);
1050 /* if port is disabled, or cheat with cheats disabled, return no key */
1051 if (((in-1)->type & IPF_UNUSED) || (!options.cheat && ((in-1)->type & IPF_CHEAT)))
1052 return &ip_none;
1053 }
1054 else
1055 {
1056 type = in->type & (~IPF_MASK | IPF_PLAYERMASK);
1057 /* if port is disabled, or cheat with cheats disabled, return no key */
1058 if ((in->type & IPF_UNUSED) || (!options.cheat && (in->type & IPF_CHEAT)))
1059 return &ip_none;
1060 }
1061
1062 if (seq_get_1((InputSeq*)&in->seq) != CODE_DEFAULT)
1063 return (InputSeq*)&in->seq;
1064
1065 i = 0;
1066
1067 while (inputport_defaults[i].type != IPT_END &&
1068 inputport_defaults[i].type != type)
1069 i++;
1070
1071 if ((in->type & ~IPF_MASK) == IPT_EXTENSION)
1072 return &inputport_defaults[i+1].seq;
1073 else
1074 return &inputport_defaults[i].seq;
1075 }
1076
1077
1078 extern int analog_read[4];
1079
update_analog_port(int port)1080 void update_analog_port(int port)
1081 {
1082 struct InputPort *in;
1083 int current, delta, type, sensitivity, min, max, default_value;
1084 int axis, is_stick, check_bounds;
1085 InputSeq* incseq;
1086 InputSeq* decseq;
1087 int keydelta;
1088 int player;
1089
1090 /* get input definition */
1091 in = input_analog[port];
1092
1093 switch (in->type & IPF_PLAYERMASK)
1094 {
1095 case IPF_PLAYER2: player = 1; break;
1096 case IPF_PLAYER3: player = 2; break;
1097 case IPF_PLAYER4: player = 3; break;
1098 case IPF_PLAYER1: default: player = 0; break;
1099 }
1100
1101 /* if we're not cheating and this is a cheat-only port, bail */
1102 if (!options.cheat && (in->type & IPF_CHEAT)) return;
1103 type=(in->type & ~IPF_MASK);
1104
1105 decseq = input_port_seq(in);
1106 incseq = input_port_seq(in+1);
1107
1108 keydelta = IP_GET_DELTA(in);
1109
1110 if(analog_read[player])keydelta=0;
1111
1112 switch (type)
1113 {
1114 case IPT_PADDLE:
1115 axis = X_AXIS; is_stick = 0; check_bounds = 1; break;
1116 case IPT_PADDLE_V:
1117 axis = Y_AXIS; is_stick = 0; check_bounds = 1; break;
1118 case IPT_DIAL:
1119 axis = X_AXIS; is_stick = 0; check_bounds = 0; break;
1120 case IPT_DIAL_V:
1121 axis = Y_AXIS; is_stick = 0; check_bounds = 0; break;
1122 case IPT_TRACKBALL_X:
1123 axis = X_AXIS; is_stick = 0; check_bounds = 0; break;
1124 case IPT_TRACKBALL_Y:
1125 axis = Y_AXIS; is_stick = 0; check_bounds = 0; break;
1126 case IPT_AD_STICK_X:
1127 axis = X_AXIS; is_stick = 1; check_bounds = 1; break;
1128 case IPT_AD_STICK_Y:
1129 axis = Y_AXIS; is_stick = 1; check_bounds = 1; break;
1130 case IPT_PEDAL:
1131 axis = Y_AXIS; is_stick = 0; check_bounds = 1; break;
1132 default:
1133 /* Use some defaults to prevent crash */
1134 axis = X_AXIS; is_stick = 0; check_bounds = 0;
1135 logerror("Oops, polling non analog device in update_analog_port()????\n");
1136 }
1137
1138
1139 sensitivity = IP_GET_SENSITIVITY(in);
1140
1141 //if(analog_read[player])sensitivity=(sensitivity/4);
1142
1143 min = IP_GET_MIN(in);
1144 max = IP_GET_MAX(in);
1145 default_value = in->default_value * 100 / sensitivity;
1146 /* extremes can be either signed or unsigned */
1147 if (min > max)
1148 {
1149 if (in->mask > 0xff) min = min - 0x10000;
1150 else min = min - 0x100;
1151 }
1152
1153 input_analog_previous_value[port] = input_analog_current_value[port];
1154
1155 /* if IPF_CENTER go back to the default position */
1156 /* sticks are handled later... */
1157 if ((in->type & IPF_CENTER) && (!is_stick))
1158 input_analog_current_value[port] = in->default_value * 100 / sensitivity;
1159
1160 current = input_analog_current_value[port];
1161
1162 delta = 0;
1163
1164 if (!is_stick)
1165 {
1166 if (axis == X_AXIS)
1167 delta = mouse_delta_x[player];
1168 else
1169 delta = mouse_delta_y[player];
1170 }
1171
1172 if (seq_pressed(decseq)) delta -= keydelta;
1173
1174 if (type != IPT_PEDAL)
1175 {
1176 if (seq_pressed(incseq)) delta += keydelta;
1177 }
1178 else
1179 {
1180 /* is this cheesy or what? */
1181 if (!delta && seq_get_1(incseq) == KEYCODE_Y) delta += keydelta;
1182 delta = -delta;
1183 }
1184
1185 if (in->type & IPF_REVERSE) delta = -delta;
1186
1187 if (is_stick)
1188 {
1189 int _new, prev;
1190
1191 /* center stick */
1192 if ((delta == 0) && (in->type & IPF_CENTER))
1193 {
1194 if (current > default_value)
1195 delta = -100 / sensitivity;
1196 if (current < default_value)
1197 delta = 100 / sensitivity;
1198 }
1199
1200 /* An analog joystick which is not at zero position (or has just */
1201 /* moved there) takes precedence over all other computations */
1202 /* analog_x/y holds values from -128 to 128 (yes, 128, not 127) */
1203
1204 if (axis == X_AXIS)
1205 {
1206 _new = analog_current_x[player];
1207 prev = analog_previous_x[player];
1208 }
1209 else
1210 {
1211 _new = analog_current_y[player];
1212 prev = analog_previous_y[player];
1213 }
1214
1215 if ((_new != 0) || (_new-prev != 0))
1216 {
1217 delta=0;
1218
1219 if (in->type & IPF_REVERSE)
1220 {
1221 _new = -_new;
1222 prev = -prev;
1223 }
1224
1225 /* apply sensitivity using a logarithmic scale */
1226 if (in->mask > 0xff)
1227 {
1228 if (_new > 0)
1229 {
1230 current = (pow(_new / 32768.0, 100.0 / sensitivity) * (max-in->default_value)
1231 + in->default_value) * 100 / sensitivity;
1232 }
1233 else
1234 {
1235 current = (pow(-_new / 32768.0, 100.0 / sensitivity) * (min-in->default_value)
1236 + in->default_value) * 100 / sensitivity;
1237 }
1238 }
1239 else
1240 {
1241 if (_new > 0)
1242 {
1243 current = (pow(_new / 128.0, 100.0 / sensitivity) * (max-in->default_value)
1244 + in->default_value) * 100 / sensitivity;
1245 }
1246 else
1247 {
1248 current = (pow(-_new / 128.0, 100.0 / sensitivity) * (min-in->default_value)
1249 + in->default_value) * 100 / sensitivity;
1250 }
1251 }
1252 }
1253 }
1254
1255 current += delta;
1256
1257 if (check_bounds)
1258 {
1259 if ((current * sensitivity + 50) / 100 < min)
1260 current = (min * 100 + sensitivity/2) / sensitivity;
1261 if ((current * sensitivity + 50) / 100 > max)
1262 current = (max * 100 + sensitivity/2) / sensitivity;
1263 }
1264
1265 input_analog_current_value[port] = current;
1266 //printf("input_analog_current_value %d %d %d %d ",port,current,sensitivity,keydelta);
1267 }
1268
scale_analog_port(int port)1269 static void scale_analog_port(int port)
1270 {
1271 struct InputPort *in;
1272 int delta,current,sensitivity;
1273
1274 profiler_mark(PROFILER_INPUT);
1275 in = input_analog[port];
1276 sensitivity = IP_GET_SENSITIVITY(in);
1277
1278 delta = cpu_scalebyfcount(input_analog_current_value[port] - input_analog_previous_value[port]);
1279
1280 current = input_analog_previous_value[port] + delta;
1281
1282 input_port_value[port] &= ~in->mask;
1283 input_port_value[port] |= ((current * sensitivity + 50) / 100) & in->mask;
1284
1285 if (playback)
1286 readword(playback,&input_port_value[port]);
1287 if (record)
1288 writeword(record,input_port_value[port]);
1289 #ifdef MAME_NET
1290 if ( net_active() && (default_player != NET_SPECTATOR) )
1291 net_analog_sync((unsigned char *) input_port_value, port, analog_player_port, default_player);
1292 #endif /* MAME_NET */
1293 profiler_mark(PROFILER_END);
1294 }
1295
1296
update_input_ports(void)1297 void update_input_ports(void)
1298 {
1299 int port,ib;
1300 struct InputPort *in;
1301 #define MAX_INPUT_BITS 1024
1302 static int impulsecount[MAX_INPUT_BITS];
1303 static int waspressed[MAX_INPUT_BITS];
1304 #define MAX_JOYSTICKS 3
1305 #define MAX_PLAYERS 4
1306 #ifdef MRU_JOYSTICK
1307 static int update_serial_number = 1;
1308 static int joyserial[MAX_JOYSTICKS*MAX_PLAYERS][4];
1309 #else
1310 int joystick[MAX_JOYSTICKS*MAX_PLAYERS][4];
1311 #endif
1312
1313 #ifdef MAME_NET
1314 int player;
1315 #endif /* MAME_NET */
1316
1317
1318 profiler_mark(PROFILER_INPUT);
1319
1320 /* clear all the values before proceeding */
1321 for (port = 0;port < MAX_INPUT_PORTS;port++)
1322 {
1323 input_port_value[port] = 0;
1324 input_vblank[port] = 0;
1325 input_analog[port] = 0;
1326 }
1327
1328 #ifndef MRU_JOYSTICK
1329 for (i = 0;i < 4*MAX_JOYSTICKS*MAX_PLAYERS;i++)
1330 joystick[i/4][i%4] = 0;
1331 #endif
1332
1333 in = Machine->input_ports;
1334
1335 if (in->type == IPT_END) return; /* nothing to do */
1336
1337 /* make sure the InputPort definition is correct */
1338 if (in->type != IPT_PORT)
1339 {
1340 logerror("Error in InputPort definition: expecting PORT_START\n");
1341 return;
1342 }
1343 else in++;
1344
1345 #ifdef MRU_JOYSTICK
1346 /* scan all the joystick ports */
1347 port = 0;
1348 while (in->type != IPT_END && port < MAX_INPUT_PORTS)
1349 {
1350 while (in->type != IPT_END && in->type != IPT_PORT)
1351 {
1352 if ((in->type & ~IPF_MASK) >= IPT_JOYSTICK_UP &&
1353 (in->type & ~IPF_MASK) <= IPT_JOYSTICKLEFT_RIGHT)
1354 {
1355 InputSeq* seq;
1356
1357 seq = input_port_seq(in);
1358
1359 if (seq_get_1(seq) != 0 && seq_get_1(seq) != CODE_NONE)
1360 {
1361 int joynum,joydir,player;
1362
1363 player = 0;
1364 if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2)
1365 player = 1;
1366 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3)
1367 player = 2;
1368 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4)
1369 player = 3;
1370
1371 joynum = player * MAX_JOYSTICKS +
1372 ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) / 4;
1373 joydir = ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) % 4;
1374
1375 #ifdef ENABLE_AUTOFIRE
1376 if (seq_pressed_with_autofire(in, seq))
1377 #else
1378 if (seq_pressed(seq))
1379 #endif
1380 {
1381 if (joyserial[joynum][joydir] == 0)
1382 joyserial[joynum][joydir] = update_serial_number;
1383 }
1384 else
1385 joyserial[joynum][joydir] = 0;
1386 }
1387 }
1388 in++;
1389 }
1390
1391 port++;
1392 if (in->type == IPT_PORT) in++;
1393 }
1394 update_serial_number += 1;
1395
1396 in = Machine->input_ports;
1397
1398 /* already made sure the InputPort definition is correct */
1399 in++;
1400 #endif
1401
1402
1403 /* scan all the input ports */
1404 port = 0;
1405 ib = 0;
1406 while (in->type != IPT_END && port < MAX_INPUT_PORTS)
1407 {
1408 struct InputPort *start;
1409
1410
1411 /* first of all, scan the whole input port definition and build the */
1412 /* default value. I must do it before checking for input because otherwise */
1413 /* multiple keys associated with the same input bit wouldn't work (the bit */
1414 /* would be reset to its default value by the second entry, regardless if */
1415 /* the key associated with the first entry was pressed) */
1416 start = in;
1417 while (in->type != IPT_END && in->type != IPT_PORT)
1418 {
1419 if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING && /* skip dipswitch definitions */
1420 (in->type & ~IPF_MASK) != IPT_EXTENSION) /* skip analog extension fields */
1421 {
1422 input_port_value[port] =
1423 (input_port_value[port] & ~in->mask) | (in->default_value & in->mask);
1424 #ifdef MAME_NET
1425 if ( net_active() )
1426 input_port_defaults[port] = input_port_value[port];
1427 #endif /* MAME_NET */
1428 }
1429
1430 in++;
1431 }
1432
1433 /* now get back to the beginning of the input port and check the input bits. */
1434 for (in = start;
1435 in->type != IPT_END && in->type != IPT_PORT;
1436 in++, ib++)
1437 {
1438 #ifdef MAME_NET
1439 player = 0;
1440 if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
1441 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
1442 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
1443 #endif /* MAME_NET */
1444 if ((in->type & ~IPF_MASK) != IPT_DIPSWITCH_SETTING && /* skip dipswitch definitions */
1445 (in->type & ~IPF_MASK) != IPT_EXTENSION) /* skip analog extension fields */
1446 {
1447 if ((in->type & ~IPF_MASK) == IPT_VBLANK)
1448 {
1449 input_vblank[port] ^= in->mask;
1450 input_port_value[port] ^= in->mask;
1451 if (Machine->drv->vblank_duration == 0)
1452 logerror("Warning: you are using IPT_VBLANK with vblank_duration = 0. You need to increase vblank_duration for IPT_VBLANK to work.\n");
1453 }
1454 /* If it's an analog control, handle it appropriately */
1455 else if (((in->type & ~IPF_MASK) > IPT_ANALOG_START)
1456 && ((in->type & ~IPF_MASK) < IPT_ANALOG_END )) /* LBO 120897 */
1457 {
1458 input_analog[port]=in;
1459 /* reset the analog port on first access */
1460 if (input_analog_init[port])
1461 {
1462 input_analog_init[port] = 0;
1463 input_analog_current_value[port] = input_analog_previous_value[port]
1464 = in->default_value * 100 / IP_GET_SENSITIVITY(in);
1465 }
1466 }
1467 else
1468 {
1469 InputSeq* seq;
1470
1471 seq = input_port_seq(in);
1472
1473 #ifdef ENABLE_AUTOFIRE
1474 if (seq_pressed_with_autofire(in, seq))
1475 #else
1476 if (seq_pressed(seq))
1477 #endif
1478 {
1479 /* skip if coin input and it's locked out */
1480 if ((in->type & ~IPF_MASK) >= IPT_COIN1 &&
1481 (in->type & ~IPF_MASK) <= IPT_COIN4 &&
1482 coinlockedout[(in->type & ~IPF_MASK) - IPT_COIN1])
1483 {
1484 continue;
1485 }
1486
1487 /* if IPF_RESET set, reset the first CPU */
1488 if ((in->type & IPF_RESETCPU) && waspressed[ib] == 0)
1489 cpu_set_reset_line(0,PULSE_LINE);
1490
1491 if (in->type & IPF_IMPULSE)
1492 {
1493 if (IP_GET_IMPULSE(in) == 0)
1494 logerror("error in input port definition: IPF_IMPULSE with length = 0\n");
1495 if (waspressed[ib] == 0)
1496 impulsecount[ib] = IP_GET_IMPULSE(in);
1497 /* the input bit will be toggled later */
1498 }
1499 else if (in->type & IPF_TOGGLE)
1500 {
1501 if (waspressed[ib] == 0)
1502 {
1503 in->default_value ^= in->mask;
1504 input_port_value[port] ^= in->mask;
1505 }
1506 }
1507 else if ((in->type & ~IPF_MASK) >= IPT_JOYSTICK_UP &&
1508 (in->type & ~IPF_MASK) <= IPT_JOYSTICKLEFT_RIGHT)
1509 {
1510 #ifndef MAME_NET
1511 int joynum,joydir,mask,player;
1512
1513
1514 player = 0;
1515 if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER2) player = 1;
1516 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER3) player = 2;
1517 else if ((in->type & IPF_PLAYERMASK) == IPF_PLAYER4) player = 3;
1518 #else
1519 int joynum,joydir,mask;
1520 #endif /* !MAME_NET */
1521 joynum = player * MAX_JOYSTICKS +
1522 ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) / 4;
1523 joydir = ((in->type & ~IPF_MASK) - IPT_JOYSTICK_UP) % 4;
1524
1525 mask = in->mask;
1526
1527 #ifndef MRU_JOYSTICK
1528 /* avoid movement in two opposite directions */
1529 if (joystick[joynum][joydir ^ 1] != 0)
1530 mask = 0;
1531 else if (in->type & IPF_4WAY)
1532 {
1533 int dir;
1534
1535
1536 /* avoid diagonal movements */
1537 for (dir = 0;dir < 4;dir++)
1538 {
1539 if (joystick[joynum][dir] != 0)
1540 mask = 0;
1541 }
1542 }
1543
1544 joystick[joynum][joydir] = 1;
1545 #else
1546 /* avoid movement in two opposite directions */
1547 if (joyserial[joynum][joydir ^ 1] != 0)
1548 mask = 0;
1549 else if (in->type & IPF_4WAY)
1550 {
1551 int mru_dir = joydir;
1552 int mru_serial = 0;
1553 int dir;
1554
1555
1556 /* avoid diagonal movements, use mru button */
1557 for (dir = 0;dir < 4;dir++)
1558 {
1559 if (joyserial[joynum][dir] > mru_serial)
1560 {
1561 mru_serial = joyserial[joynum][dir];
1562 mru_dir = dir;
1563 }
1564 }
1565
1566 if (mru_dir != joydir)
1567 mask = 0;
1568 }
1569 #endif
1570
1571 input_port_value[port] ^= mask;
1572 }
1573 else
1574 input_port_value[port] ^= in->mask;
1575
1576 waspressed[ib] = 1;
1577 }
1578 else
1579 waspressed[ib] = 0;
1580
1581 if ((in->type & IPF_IMPULSE) && impulsecount[ib] > 0)
1582 {
1583 impulsecount[ib]--;
1584 waspressed[ib] = 1;
1585 input_port_value[port] ^= in->mask;
1586 }
1587 }
1588 }
1589 }
1590
1591 port++;
1592 if (in->type == IPT_PORT) in++;
1593 }
1594
1595 if (playback)
1596 {
1597 int i;
1598
1599 for (i = 0; i < MAX_INPUT_PORTS; i ++)
1600 readword(playback,&input_port_value[i]);
1601 }
1602 if (record)
1603 {
1604 int i;
1605
1606 for (i = 0; i < MAX_INPUT_PORTS; i ++)
1607 writeword(record,input_port_value[i]);
1608 }
1609 #ifdef MAME_NET
1610 if ( net_active() && (default_player != NET_SPECTATOR) )
1611 net_input_sync((unsigned char *) input_port_value, (unsigned char *) input_port_defaults, MAX_INPUT_PORTS);
1612 #endif /* MAME_NET */
1613
1614 profiler_mark(PROFILER_END);
1615 }
1616
1617
1618
1619 /* used the the CPU interface to notify that VBlank has ended, so we can update */
1620 /* IPT_VBLANK input ports. */
inputport_vblank_end(void)1621 void inputport_vblank_end(void)
1622 {
1623 int port;
1624 int i;
1625
1626
1627 profiler_mark(PROFILER_INPUT);
1628 for (port = 0;port < MAX_INPUT_PORTS;port++)
1629 {
1630 if (input_vblank[port])
1631 {
1632 input_port_value[port] ^= input_vblank[port];
1633 input_vblank[port] = 0;
1634 }
1635 }
1636
1637 /* poll all the analog joysticks */
1638 osd_poll_joysticks();
1639
1640 /* update the analog devices */
1641 for (i = 0;i < OSD_MAX_JOY_ANALOG;i++)
1642 {
1643 /* update the analog joystick position */
1644 analog_previous_x[i] = analog_current_x[i];
1645 analog_previous_y[i] = analog_current_y[i];
1646 osd_analogjoy_read (i, &(analog_current_x[i]), &(analog_current_y[i]));
1647
1648 /* update mouse/trackball position */
1649 osd_trak_read (i, &mouse_delta_x[i], &mouse_delta_y[i]);
1650 }
1651
1652 for (i = 0;i < MAX_INPUT_PORTS;i++)
1653 {
1654 struct InputPort *in;
1655
1656 in=input_analog[i];
1657 if (in)
1658 {
1659 update_analog_port(i);
1660 }
1661 }
1662 profiler_mark(PROFILER_END);
1663 }
1664
1665
1666
readinputport(int port)1667 int readinputport(int port)
1668 {
1669 struct InputPort *in;
1670
1671 /* Update analog ports on demand */
1672 in=input_analog[port];
1673 if (in)
1674 {
1675 scale_analog_port(port);
1676 }
1677
1678 return input_port_value[port];
1679 }
1680
READ_HANDLER(input_port_0_r)1681 READ_HANDLER( input_port_0_r ) { return readinputport(0); }
READ_HANDLER(input_port_1_r)1682 READ_HANDLER( input_port_1_r ) { return readinputport(1); }
READ_HANDLER(input_port_2_r)1683 READ_HANDLER( input_port_2_r ) { return readinputport(2); }
READ_HANDLER(input_port_3_r)1684 READ_HANDLER( input_port_3_r ) { return readinputport(3); }
READ_HANDLER(input_port_4_r)1685 READ_HANDLER( input_port_4_r ) { return readinputport(4); }
READ_HANDLER(input_port_5_r)1686 READ_HANDLER( input_port_5_r ) { return readinputport(5); }
READ_HANDLER(input_port_6_r)1687 READ_HANDLER( input_port_6_r ) { return readinputport(6); }
READ_HANDLER(input_port_7_r)1688 READ_HANDLER( input_port_7_r ) { return readinputport(7); }
READ_HANDLER(input_port_8_r)1689 READ_HANDLER( input_port_8_r ) { return readinputport(8); }
READ_HANDLER(input_port_9_r)1690 READ_HANDLER( input_port_9_r ) { return readinputport(9); }
READ_HANDLER(input_port_10_r)1691 READ_HANDLER( input_port_10_r ) { return readinputport(10); }
READ_HANDLER(input_port_11_r)1692 READ_HANDLER( input_port_11_r ) { return readinputport(11); }
READ_HANDLER(input_port_12_r)1693 READ_HANDLER( input_port_12_r ) { return readinputport(12); }
READ_HANDLER(input_port_13_r)1694 READ_HANDLER( input_port_13_r ) { return readinputport(13); }
READ_HANDLER(input_port_14_r)1695 READ_HANDLER( input_port_14_r ) { return readinputport(14); }
READ_HANDLER(input_port_15_r)1696 READ_HANDLER( input_port_15_r ) { return readinputport(15); }
READ_HANDLER(input_port_16_r)1697 READ_HANDLER( input_port_16_r ) { return readinputport(16); }
READ_HANDLER(input_port_17_r)1698 READ_HANDLER( input_port_17_r ) { return readinputport(17); }
READ_HANDLER(input_port_18_r)1699 READ_HANDLER( input_port_18_r ) { return readinputport(18); }
READ_HANDLER(input_port_19_r)1700 READ_HANDLER( input_port_19_r ) { return readinputport(19); }
1701
1702
1703 #ifdef MAME_NET
set_default_player_controls(int player)1704 void set_default_player_controls(int player)
1705 {
1706 if (player == NET_SPECTATOR)
1707 default_player = NET_SPECTATOR;
1708 else
1709 default_player = player - 1;
1710 }
1711 #endif /* MAME_NET */
1712
1713 /***************************************************************************/
1714 /* InputPort conversion */
1715
input_port_count(const struct InputPortTiny * src)1716 static unsigned input_port_count(const struct InputPortTiny *src)
1717 {
1718 unsigned total;
1719
1720 total = 0;
1721 while (src->type != IPT_END)
1722 {
1723 int type = src->type & ~IPF_MASK;
1724 if (type > IPT_ANALOG_START && type < IPT_ANALOG_END)
1725 total += 2;
1726 else if (type != IPT_EXTENSION)
1727 ++total;
1728 ++src;
1729 }
1730
1731 ++total; /* for IPT_END */
1732
1733 return total;
1734 }
1735
input_port_allocate(const struct InputPortTiny * src)1736 struct InputPort* input_port_allocate(const struct InputPortTiny *src)
1737 {
1738 struct InputPort* dst;
1739 struct InputPort* base;
1740 unsigned total;
1741
1742 total = input_port_count(src);
1743
1744 base = (struct InputPort*)malloc(total * sizeof(struct InputPort));
1745 dst = base;
1746
1747 while (src->type != IPT_END)
1748 {
1749 int type = src->type & ~IPF_MASK;
1750 const struct InputPortTiny *ext;
1751 const struct InputPortTiny *src_end;
1752 InputCode seq_default;
1753
1754 if (type > IPT_ANALOG_START && type < IPT_ANALOG_END)
1755 src_end = src + 2;
1756 else
1757 src_end = src + 1;
1758
1759 switch (type)
1760 {
1761 case IPT_END :
1762 case IPT_PORT :
1763 case IPT_DIPSWITCH_NAME :
1764 case IPT_DIPSWITCH_SETTING :
1765 seq_default = CODE_NONE;
1766 break;
1767 default:
1768 seq_default = CODE_DEFAULT;
1769 }
1770
1771 ext = src_end;
1772 while (src != src_end)
1773 {
1774 dst->type = src->type;
1775 dst->mask = src->mask;
1776 dst->default_value = src->default_value;
1777 dst->name = src->name;
1778
1779 if (ext->type == IPT_EXTENSION)
1780 {
1781 InputCode or1 = IP_GET_CODE_OR1(ext);
1782 InputCode or2 = IP_GET_CODE_OR2(ext);
1783
1784 if (or1 < __code_max)
1785 {
1786 if (or2 < __code_max)
1787 seq_set_3(&dst->seq, or1, CODE_OR, or2);
1788 else
1789 seq_set_1(&dst->seq, or1);
1790 } else {
1791 if (or1 == CODE_NONE)
1792 seq_set_1(&dst->seq, or2);
1793 else
1794 seq_set_1(&dst->seq, or1);
1795 }
1796
1797 ++ext;
1798 } else {
1799 seq_set_1(&dst->seq,seq_default);
1800 }
1801
1802 ++src;
1803 ++dst;
1804 }
1805
1806 src = ext;
1807 }
1808
1809 dst->type = IPT_END;
1810
1811 return base;
1812 }
1813
input_port_free(struct InputPort * dst)1814 void input_port_free(struct InputPort* dst)
1815 {
1816 free(dst);
1817 }
1818
1819 /*
1820 * added for autofire
1821 */
1822 #ifdef ENABLE_AUTOFIRE
1823
1824 extern void ui_displaymenu(struct osd_bitmap *bitmap, const char **items, const char **subitems, char *flag, int selected, int arrowize_subitem);
1825 extern int need_to_clear_bitmap; /* used to tell updatescreen() to clear the bitmap */
1826
1827 #define MAX_AUTOFIRE_BUTTON 6
1828
1829 static int af_ipt_button[] = {
1830 IPT_BUTTON1,IPT_BUTTON2,IPT_BUTTON3,IPT_BUTTON4,
1831 IPT_BUTTON5,IPT_BUTTON6,IPT_BUTTON7,IPT_BUTTON8
1832 };
1833
1834 InputSeq af_fire_on = { KEYCODE_INSERT, CODE_NONE };
1835 InputSeq af_fire_off= { KEYCODE_DEL, CODE_NONE };
1836
1837 static char af_autofire[MAX_AUTOFIRE_BUTTON];
1838 static char af_noautofire[MAX_AUTOFIRE_BUTTON];
1839 static char af_autopressed[MAX_AUTOFIRE_BUTTON];
1840 //static int af_record_first_insert = 1;
1841
autofire_menu(struct osd_bitmap * bitmap,int selected)1842 int autofire_menu(struct osd_bitmap *bitmap, int selected)
1843 {
1844 const char *menu_item[100];
1845 const char *menu_subitem[100];
1846 char menu_item_sub[100][256];
1847 char menu_subitem_sub[100][256];
1848 char flag[100];
1849 int sel,sel_af_on,sel_af_off,sel_return;
1850 int total;
1851 int arrowize;
1852
1853 sel = selected - 1;
1854 arrowize = 0;
1855
1856 /* auto-fire button menu */
1857 for (total = 0; total < MAX_AUTOFIRE_BUTTON; total ++) {
1858 flag[total] = 0;
1859 sprintf(menu_item_sub[total] , "Auto-Fire on Button %d", total + 1);
1860 sprintf(menu_subitem_sub[total], "Delay %02d", af_autofire[total]);
1861 menu_item[total] = menu_item_sub[total];
1862 if (af_autofire[total] > 0)
1863 menu_subitem[total] = menu_subitem_sub[total];
1864 else
1865 menu_subitem[total] = " No";
1866
1867 if (sel == total) {
1868 if (af_autofire[sel] == 0)
1869 arrowize = 2;
1870 else if (af_autofire[sel] == 99)
1871 arrowize = 1;
1872 else
1873 arrowize = 3;
1874 }
1875 }
1876
1877 /* auto-fire on menu */
1878 sel_af_on = total;
1879 flag[total] = 0;
1880 menu_subitem[total] = code_name(af_fire_on[0]);
1881 menu_item[total ++] = "Auto-Fire On ";
1882
1883 /* auto-fire off menu */
1884 sel_af_off = total;
1885 flag[total] = 0;
1886 menu_subitem[total] = code_name(af_fire_off[0]);
1887 menu_item[total ++] = "Auto-Fire Off ";
1888
1889 /* Return to Main Menu */
1890 sel_return = total;
1891 flag[total] =0;
1892 menu_subitem[total] = "";
1893 menu_item[total ++] = "Return to Main Menu";
1894
1895 menu_item[total] = 0; /* End of array */
1896
1897 if (sel > SEL_MASK) {
1898 int ret;
1899 InputSeq seq;
1900
1901 menu_subitem[sel & SEL_MASK] = " ";
1902 ui_displaymenu(bitmap, menu_item, menu_subitem,
1903 flag, sel & SEL_MASK, 3);
1904
1905 seq_set_1(&seq, CODE_NONE);
1906 ret = seq_read_async(&seq, 0);
1907
1908 if (ret >= 0) {
1909 sel &= 0xff;
1910 schedule_full_refresh();
1911 if (seq_get_1(&seq) != CODE_NONE) {
1912 if (sel == sel_af_on)
1913 af_fire_on[0] = seq_get_1(&seq);
1914 else if (sel==sel_af_off)
1915 af_fire_off[0] = seq_get_1(&seq);
1916 }
1917 }
1918 return sel + 1;
1919 }
1920
1921 ui_displaymenu(bitmap, menu_item, menu_subitem, flag, sel, arrowize);
1922
1923 if (input_ui_pressed_repeat(IPT_UI_DOWN, 8)) {
1924 if (sel < sel_return)
1925 sel++;
1926 else
1927 sel = 0;
1928 }
1929
1930 if (input_ui_pressed_repeat(IPT_UI_UP, 8)) {
1931 if (sel > 0)
1932 sel--;
1933 else
1934 sel = sel_return;
1935 }
1936
1937 if (input_ui_pressed_repeat(IPT_UI_RIGHT, 8)) {
1938 if ((sel >= 0) && (sel < MAX_AUTOFIRE_BUTTON))
1939 if (af_autofire[sel] ++ > 98)
1940 af_autofire[sel] = 99;
1941 schedule_full_refresh();
1942 }
1943
1944 if (input_ui_pressed_repeat(IPT_UI_LEFT, 8)) {
1945 if ((sel >= 0) && (sel < MAX_AUTOFIRE_BUTTON))
1946 if (af_autofire[sel] -- < 1)
1947 af_autofire[sel] = 0;
1948 schedule_full_refresh();
1949 }
1950
1951 if (input_ui_pressed(IPT_UI_SELECT)) {
1952 if (sel == sel_return)
1953 sel = -1;
1954 else if ((sel == sel_af_on) || (sel == sel_af_off)) {
1955 seq_read_async_start();
1956 sel |= 1 << SEL_BITS; /* we'll ask for a key */
1957 /* sel |= 0x100; we'll ask for a key */
1958 schedule_full_refresh();
1959 }
1960 }
1961
1962 if (input_ui_pressed(IPT_UI_CANCEL))
1963 sel = -1;
1964
1965 if (input_ui_pressed(IPT_UI_CONFIGURE))
1966 sel = -2;
1967
1968 if (sel == -1 || sel == -2)
1969 schedule_full_refresh();
1970
1971 return sel + 1;
1972 }
1973
AfButton(int impport)1974 void AfButton(int impport)
1975 {
1976 int no;
1977 #if 0
1978 int i;
1979 char msg[100];
1980 char tmp[10];
1981 #endif
1982
1983 switch (impport) {
1984 case IPT_BUTTON1:
1985 no = 0;
1986 break;
1987 case IPT_BUTTON2:
1988 no = 1;
1989 break;
1990 case IPT_BUTTON3:
1991 no = 2;
1992 break;
1993 case IPT_BUTTON4:
1994 no = 3;
1995 break;
1996 case IPT_BUTTON5:
1997 no = 4;
1998 break;
1999 case IPT_BUTTON6:
2000 no = 5;
2001 break;
2002 case IPT_BUTTON7:
2003 no = 6;
2004 break;
2005 case IPT_BUTTON8:
2006 no = 7;
2007 break;
2008 default:
2009 return;
2010 }
2011 if (no >= MAX_AUTOFIRE_BUTTON)
2012 return;
2013
2014 if (seq_pressed(&af_fire_on))
2015 af_noautofire[no] = 0;
2016 else if (seq_pressed(&af_fire_off))
2017 af_noautofire[no] = 1;
2018 else
2019 return;
2020
2021 #if 0
2022 strcpy(msg, "Autofire ");
2023 for (i = 0; i < MAX_AUTOFIRE_BUTTON; i ++) {
2024 if (!af_noautofire[i]) {
2025 if (af_autofire[i])
2026 sprintf(tmp, "%d=%02d ", i + 1, af_autofire[i]);
2027 else
2028 sprintf(tmp, "%d=NO ", i + 1);
2029 } else
2030 sprintf(tmp, "%d=OFF ", i + 1);
2031 strcat(msg, tmp);
2032 }
2033 usrintf_showmessage(msg);
2034 #endif
2035 }
2036
seq_pressed_with_autofire(struct InputPort * in,InputSeq * code)2037 int seq_pressed_with_autofire(struct InputPort *in,InputSeq* code)
2038 {
2039 int i, impport, ret;
2040
2041 impport = in->type & ~IPF_MASK;
2042
2043 ret = seq_pressed(code);
2044 if (ret != 0) {
2045 for (i = 0; i < MAX_AUTOFIRE_BUTTON; i ++)
2046 if (impport == af_ipt_button[i]) {
2047 if (!af_noautofire[i] && (af_autofire[i] > 0)
2048 && (af_autopressed[i] >= af_autofire[i])) {
2049 ret = 0;
2050 af_autopressed[i] = 0;
2051 }
2052 else
2053 af_autopressed[i] ++;
2054 }
2055
2056 AfButton(impport);
2057 }
2058
2059 return ret;
2060 }
2061
2062 #endif
2063