Subversion Repositories Games.Carmageddon

Rev

Rev 20 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
#include "controls.h"
2
 
20 pmbaty 3
#include "brender/brender.h"
1 pmbaty 4
#include "brucetrk.h"
5
#include "car.h"
6
#include "constants.h"
7
#include "crush.h"
8
#include "depth.h"
9
#include "displays.h"
10
#include "finteray.h"
11
#include "flicplay.h"
12
#include "globvars.h"
13
#include "globvrkm.h"
14
#include "globvrpb.h"
15
#include "grafdata.h"
16
#include "graphics.h"
17
#include "harness/trace.h"
18
#include "init.h"
19
#include "input.h"
20
#include "loadsave.h"
21
#include "mainloop.h"
22
#include "netgame.h"
23
#include "network.h"
24
#include "opponent.h"
25
#include "pd/sys.h"
26
#include "pedestrn.h"
27
#include "piping.h"
28
#include "powerup.h"
29
#include "pratcam.h"
30
#include "raycast.h"
31
#include "replay.h"
32
#include "s3/s3.h"
33
#include "sound.h"
34
#include "spark.h"
35
#include "structur.h"
36
#include "utility.h"
37
#include "world.h"
38
#include <stdlib.h>
39
 
40
tToggle_element gToggle_array[] = {
41
    { KEYMAP_MIRROR, -2, 1, 1, 0, ToggleMirror },
42
    { KEYMAP_MAP, -2, 1, 1, 0, ToggleMap },
43
    { KEYMAP_PRATCAM, -2, 1, 1, 0, TogglePratcam },
44
    { KEYMAP_RECOVERY, -2, 1, 1, 0, SetRecovery },
45
    { KEYMAP_CTRL_ABORT_RACE, 7, 1, 1, 0, AbortRace },
46
    { KEYMAP_COCKPIT, -2, 1, 1, 0, ToggleCockpit },
47
    { KEYMAP_LOOK_LEFT, -2, 1, 1, 0, LookLeft },
48
    { KEYMAP_LOOK_FORWARD, -2, 1, 1, 0, LookForward },
49
    { KEYMAP_LOOK_RIGHT, -2, 1, 1, 0, LookRight },
50
    { KEYMAP_SOUND, -2, 0, 1, 0, ToggleSoundEnable },
51
    { KEYMAP_SHIFT_DUMPSCREEN, KEYMAP_SHIFT_ANY, 0, 1, 0, PrintScreen },
52
    { KEYMAP_CTRL_DRAW_SOME_TEXT, KEYMAP_CONTROL_ANY, 1, 1, 0, DrawSomeText }, // commented out in original executable
53
    { KEYMAP_CTRL_FLY, KEYMAP_CONTROL_ANY, 1, 1, 0, ToggleFlying },
54
    { KEYMAP_PEDESTRIANS, -2, 1, 1, 0, TogglePedestrians },
55
    { KEYMAP_F4, -2, 0, 0, 0, F4Key },
56
    { KEYMAP_F5, -2, 1, 0, 0, F5Key },
57
    { KEYMAP_F6, -2, 1, 0, 0, F6Key },
58
    { KEYMAP_F7, -2, 1, 0, 0, F7Key },
59
    { KEYMAP_F8, -2, 1, 0, 0, F8Key },
60
    { KEYMAP_F10, -2, 1, 0, 0, F10Key },
61
    { KEYMAP_F11, -2, 1, 0, 0, F11Key },
62
    { KEYMAP_F12, -2, 1, 0, 0, F12Key },
63
    { KEYMAP_EDITMODE_0, -2, 1, 0, 0, NumberKey0 },
64
    { KEYMAP_EDITMODE_1, -2, 1, 0, 0, NumberKey1 },
65
    { KEYMAP_EDITMODE_2, -2, 1, 0, 0, NumberKey2 },
66
    { KEYMAP_EDITMODE_3, -2, 1, 0, 0, NumberKey3 },
67
    { KEYMAP_EDITMODE_4, -2, 1, 0, 0, NumberKey4 },
68
    { KEYMAP_EDITMODE_5, -2, 1, 0, 0, NumberKey5 },
69
    { KEYMAP_EDITMODE_6, -2, 1, 0, 0, NumberKey6 },
70
    { KEYMAP_EDITMODE_7, -2, 1, 0, 0, NumberKey7 },
71
    { KEYMAP_EDITMODE_8, -2, 1, 0, 0, NumberKey8 },
72
    { KEYMAP_EDITMODE_9, -2, 1, 0, 0, NumberKey9 },
73
    { KEYMAP_SCREEN_SMALLER, -2, 1, 0, 0, ScreenSmaller },
74
    { KEYMAP_SCREEN_LARGER, -2, 1, 0, 0, ScreenLarger },
75
    { KEYMAP_BUY_ARMOUR, -2, 1, 0, 0, BuyArmour },
76
    { KEYMAP_BUY_POWER, -2, 1, 0, 0, BuyPower },
77
    { KEYMAP_BUY_OFFENSE, -2, 1, 0, 0, BuyOffense },
78
    { KEYMAP_VIEW_NETPLAYER, -2, 1, 0, 0, ViewNetPlayer },
79
    { KEYMAP_SEND_MESSAGE, -2, 1, 0, 0, UserSendMessage },
80
    { KEYMAP_ARROW, -2, 1, 1, 0, ToggleArrow }, // commented out in original executable
81
    { KEYMAP_INFO, -2, 1, 1, 0, ToggleInfo },
82
    { KEYMAP_INFO, KEYMAP_SHIFT_ANY, 1, 1, 0, ToggleInfo },
83
    { KEYMAP_INFO, KEYMAP_CONTROL_ANY, 1, 1, 0, ToggleInfo }
84
};
85
int gRepair_last_time;
86
int gHad_auto_recover;
87
tU32 gLast_repair_time;
88
tEdit_mode gWhich_edit_mode = eEdit_mode_options;
89
char* gEdit_mode_names[10] = {
90
    "Cheat",
91
    "Accessories",
92
    "Special Volumes",
93
    "Pedestrians",
94
    "Opponents",
95
    "Prat-cam",
96
    "Depth effects",
97
    "Damage",
98
    "Bonnet",
99
    "Options",
100
};
101
 
102
// order is: { None, CTRL, ALT, CTRL+ALT, SHIFT, CTRL+SHIFT, ALT+SHIFT, CTRL+ALT+SHIFT }
103
tEdit_func* gEdit_funcs[10][18][8] = {
104
    { // CHEAT EDIT MODE
105
 
106
        // F5
107
        { TotalRepair, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
108
        // F6
109
        { ToggleInvulnerability, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
110
        // F7
111
        { MoreTime, NULL, NULL, NULL, MuchMoreTime, NULL, NULL, NULL },
112
        // F8
113
        { ToggleTimerFreeze, ShadowMode, NULL, NULL, ToggleShadow, NULL, NULL, NULL },
114
        // F10
115
        { IncrementLap, NULL, NULL, NULL, IncrementCheckpoint, NULL, NULL, NULL },
116
        // F11
117
        { EarnDosh, NULL, NULL, NULL, LoseDosh, NULL, NULL, NULL },
118
        // F12
119
        { ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent },
120
        // 0
121
        { GotPowerup0, GotPowerup0, GotPowerup0, GotPowerup0, GotPowerup0, GotPowerup0, GotPowerup0, GotPowerup0 },
122
        // 1
123
        { GotPowerup1, GotPowerup1, GotPowerup1, GotPowerup1, GotPowerup1, GotPowerup1, GotPowerup1, GotPowerup1 },
124
        // 2
125
        { GotPowerup2, GotPowerup2, GotPowerup2, GotPowerup2, GotPowerup2, GotPowerup2, GotPowerup2, GotPowerup2 },
126
        // 3
127
        { GotPowerup3, GotPowerup3, GotPowerup3, GotPowerup3, GotPowerup3, GotPowerup3, GotPowerup3, GotPowerup3 },
128
        // 4
129
        { GotPowerup4, GotPowerup4, GotPowerup4, GotPowerup4, GotPowerup4, GotPowerup4, GotPowerup4, GotPowerup4 },
130
        // 5
131
        { GotPowerup5, GotPowerup5, GotPowerup5, GotPowerup5, GotPowerup5, GotPowerup5, GotPowerup5, GotPowerup5 },
132
        // 6
133
        { GotPowerup6, GotPowerup6, GotPowerup6, GotPowerup6, GotPowerup6, GotPowerup6, GotPowerup6, GotPowerup6 },
134
        // 7
135
        { GotPowerup7, GotPowerup7, GotPowerup7, GotPowerup7, GotPowerup7, GotPowerup7, GotPowerup7, GotPowerup7 },
136
        // 8
137
        { GotPowerup8, GotPowerup8, GotPowerup8, GotPowerup8, GotPowerup8, GotPowerup8, GotPowerup8, GotPowerup8 },
138
        // 9
139
        { GotPowerup9, GotPowerup9, GotPowerup9, GotPowerup9, GotPowerup9, GotPowerup9, GotPowerup9, GotPowerup9 },
140
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
141
 
142
    { // ACCESSORIES EDIT MODE
143
 
144
        // F5
145
        { CycleAccRotate, NULL, NULL, NULL, CycleAccScale, NULL, NULL, NULL },
146
        // F6
147
        { IdentifyAcc, ScaleAccUp2, ScaleAccUp3, ScaleAccUp4, IdentifyAcc, ScaleAccDown2, ScaleAccDown3, ScaleAccDown4 },
148
        // F7
149
        { RotateAccL, RotateAccL2, RotateAccL3, RotateAccL4, RotateAccR, RotateAccR2, RotateAccR3, RotateAccR4 },
150
        // F8
151
        { DeleteAcc, NULL, NULL, NULL, SnapAccToVertical, NULL, NULL, NULL },
152
        // F10
153
        { MoveXAccL, MoveXAccL2, MoveXAccL3, MoveXAccL4, MoveXAccR, MoveXAccR2, MoveXAccR3, MoveXAccR4 },
154
        // F11
155
        { MoveYAccL, MoveYAccL2, MoveYAccL3, MoveYAccL4, MoveYAccR, MoveYAccR2, MoveYAccR3, MoveYAccR4 },
156
        // F12
157
        { MoveZAccL, MoveZAccL2, MoveZAccL3, MoveZAccL4, MoveZAccR, MoveZAccR2, MoveZAccR3, MoveZAccR4 },
158
        // 0
159
        { DropActor0, DropActor0, DropActor0, DropActor0, DropActor0, DropActor0, DropActor0, DropActor0 },
160
        // 1
161
        { DropActor1, DropActor1, DropActor1, DropActor1, DropActor1, DropActor1, DropActor1, DropActor1 },
162
        // 2
163
        { DropActor2, DropActor2, DropActor2, DropActor2, DropActor2, DropActor2, DropActor2, DropActor2 },
164
        // 3
165
        { DropActor3, DropActor3, DropActor3, DropActor3, DropActor3, DropActor3, DropActor3, DropActor3 },
166
        // 4
167
        { DropActor4, DropActor4, DropActor4, DropActor4, DropActor4, DropActor4, DropActor4, DropActor4 },
168
        // 5
169
        { DropActor5, DropActor5, DropActor5, DropActor5, DropActor5, DropActor5, DropActor5, DropActor5 },
170
        // 6
171
        { DropActor6, DropActor6, DropActor6, DropActor6, DropActor6, DropActor6, DropActor6, DropActor6 },
172
        // 7
173
        { DropActor7, DropActor7, DropActor7, DropActor7, DropActor7, DropActor7, DropActor7, DropActor7 },
174
        // 8
175
        { DropActor8, DropActor8, DropActor8, DropActor8, DropActor8, DropActor8, DropActor8, DropActor8 },
176
        // 9
177
        { DropActor9, DropActor9, DropActor9, DropActor9, DropActor9, DropActor9, DropActor9, DropActor9 },
178
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
179
 
180
    { // SPECVOL EDIT MODE
181
 
182
        // F5
183
        { CycleSpecVolRotate, NULL, NULL, NULL, CycleSpecVolScale, NULL, NULL, NULL },
184
        // F6
185
        { IdentifySpecVol, ScaleSpecVolUp2, ScaleSpecVolUp3, ScaleSpecVolUp4, IdentifySpecVol, ScaleSpecVolDown2, ScaleSpecVolDown3, ScaleSpecVolDown4 },
186
        // F7
187
        { RotateSpecVolL, RotateSpecVolL2, RotateSpecVolL3, RotateSpecVolL4, RotateSpecVolR, RotateSpecVolR2, RotateSpecVolR3, RotateSpecVolR4 },
188
        // F8
189
        { DeleteSpecVol, NULL, NULL, NULL, SnapSpecVolToVertical, NULL, NULL, NULL },
190
        // F10
191
        { MoveXSpecVolL, MoveXSpecVolL2, MoveXSpecVolL3, MoveXSpecVolL4, MoveXSpecVolR, MoveXSpecVolR2, MoveXSpecVolR3, MoveXSpecVolR4 },
192
        // F11
193
        { MoveYSpecVolL, MoveYSpecVolL2, MoveYSpecVolL3, MoveYSpecVolL4, MoveYSpecVolR, MoveYSpecVolR2, MoveYSpecVolR3, MoveYSpecVolR4 },
194
        // F12
195
        { MoveZSpecVolL, MoveZSpecVolL2, MoveZSpecVolL3, MoveZSpecVolL4, MoveZSpecVolR, MoveZSpecVolR2, MoveZSpecVolR3, MoveZSpecVolR4 },
196
        // 0
197
        { DropSpecVol0, DropSpecVol0, DropSpecVol0, DropSpecVol0, DropSpecVol0, DropSpecVol0, DropSpecVol0, DropSpecVol0 },
198
        // 1
199
        { DropSpecVol1, DropSpecVol1, DropSpecVol1, DropSpecVol1, DropSpecVol1, DropSpecVol1, DropSpecVol1, DropSpecVol1 },
200
        // 2
201
        { DropSpecVol2, DropSpecVol2, DropSpecVol2, DropSpecVol2, DropSpecVol2, DropSpecVol2, DropSpecVol2, DropSpecVol2 },
202
        // 3
203
        { DropSpecVol3, DropSpecVol3, DropSpecVol3, DropSpecVol3, DropSpecVol3, DropSpecVol3, DropSpecVol3, DropSpecVol3 },
204
        // 4
205
        { DropSpecVol4, DropSpecVol4, DropSpecVol4, DropSpecVol4, DropSpecVol4, DropSpecVol4, DropSpecVol4, DropSpecVol4 },
206
        // 5
207
        { DropSpecVol5, DropSpecVol5, DropSpecVol5, DropSpecVol5, DropSpecVol5, DropSpecVol5, DropSpecVol5, DropSpecVol5 },
208
        // 6
209
        { DropSpecVol6, DropSpecVol6, DropSpecVol6, DropSpecVol6, DropSpecVol6, DropSpecVol6, DropSpecVol6, DropSpecVol6 },
210
        // 7
211
        { DropSpecVol7, DropSpecVol7, DropSpecVol7, DropSpecVol7, DropSpecVol7, DropSpecVol7, DropSpecVol7, DropSpecVol7 },
212
        // 8
213
        { DropSpecVol8, DropSpecVol8, DropSpecVol8, DropSpecVol8, DropSpecVol8, DropSpecVol8, DropSpecVol8, DropSpecVol8 },
214
        // 09
215
        { DropSpecVol9, DropSpecVol9, DropSpecVol9, DropSpecVol9, DropSpecVol9, DropSpecVol9, DropSpecVol9, DropSpecVol9 },
216
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
217
 
218
    { // PEDESTRIAN EDIT MODE
219
 
220
        // F5
221
        { TogglePedDetect, NULL, NULL, NULL, DoPedReport, NULL, NULL, NULL },
222
        // F6
223
        { ShowPedPaths, NULL, NULL, NULL, ShowPedPos, NULL, NULL, NULL },
224
        // F7
225
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
226
        // F8
227
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
228
        // F10
229
        { DropPedPoint, DropPedPointAir, NULL, NULL, PullPedPoint, PullPedPointAir, NULL, NULL },
230
        // F11
231
        { DropInitPedPoint, DropInitPedPointAir, NULL, NULL, NULL, NULL, NULL, NULL },
232
        // F12
233
        { ScrubPedestrian, DeletePedPoint, NULL, NULL, DeletePedPath, NULL, NULL, NULL },
234
        // 0
235
        { NewPed0, NewPed0, NewPed0, NewPed0, NewPed0, NewPed0, NewPed0, NewPed0 },
236
        // 1
237
        { NewPed1, NewPed1, NewPed1, NewPed1, NewPed1, NewPed1, NewPed1, NewPed1 },
238
        // 2
239
        { NewPed2, NewPed2, NewPed2, NewPed2, NewPed2, NewPed2, NewPed2, NewPed2 },
240
        // 3
241
        { NewPed3, NewPed3, NewPed3, NewPed3, NewPed3, NewPed3, NewPed3, NewPed3 },
242
        // 4
243
        { NewPed4, NewPed4, NewPed4, NewPed4, NewPed4, NewPed4, NewPed4, NewPed4 },
244
        // 5
245
        { NewPed5, NewPed5, NewPed5, NewPed5, NewPed5, NewPed5, NewPed5, NewPed5 },
246
        // 6
247
        { NewPed6, NewPed6, NewPed6, NewPed6, NewPed6, NewPed6, NewPed6, NewPed6 },
248
        // 7
249
        { NewPed7, NewPed7, NewPed7, NewPed7, NewPed7, NewPed7, NewPed7, NewPed7 },
250
        // 8
251
        { NewPed8, NewPed8, NewPed8, NewPed8, NewPed8, NewPed8, NewPed8, NewPed8 },
252
        // 9
253
        { NewPed9, NewPed9, NewPed9, NewPed9, NewPed9, NewPed9, NewPed9, NewPed9 },
254
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
255
 
256
    { // OPPONENTS EDIT MODE
257
 
258
        // F5
259
        { ShowHideOppoPaths, ShowSectionInfo1, NULL, NULL, ShowNodeInfo, ShowSectionInfo2, NULL, NULL },
260
        // F6
261
        { ReverseSectionDirection, ToggleOneWayNess, NULL, NULL, CycleSectionType, NULL, NULL, NULL },
262
        // F7
263
        { DropElasticateyNode, NULL, PullOppoPoint, NULL, InsertAndElasticate, NULL, NULL, NULL },
264
        // F8
265
        { DropNodeOnNodeAndStopElasticating, DropDeadEndNode, NULL, NULL, InsertAndDontElasticate, NULL, NULL, NULL },
266
        // F10
267
        { WidenOppoPathSection, IncreaseSectionMinSpeed, IncreaseSectionMaxSpeed, NULL, NarrowOppoPathSection, DecreaseSectionMinSpeed, DecreaseSectionMaxSpeed, NULL },
268
        // F11
269
        { NULL, DeleteOppoPathNodeAndJoin, NULL, NULL, DeleteOppoPathSection, DeleteOppoPathNodeAndSections, NULL, NULL },
270
        // F12
271
        { ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent },
272
        // 0
273
        { ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent, ViewOpponent },
274
        // 1
275
        { ToggleOpponentProcessing, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
276
        // 2
277
        { CopStartPointInfo, DeleteCopStartPoint, DropCopStartPoint, NULL, CycleCopStartPointType, NULL, NULL, NULL },
278
        // 3
279
        { ToggleMellowOpponents, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
280
        // 4
281
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
282
        // 5
283
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
284
        // 6
285
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
286
        // 7
287
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
288
        // 8
289
        { AdjustDownForce, NULL, NULL, NULL, PutOpponentsInNeutral, NULL, NULL, NULL },
290
        // 9
291
        { SwapCar, FreezeMechanics, NULL, NULL, ToggleCarToCarCollisions, NULL, NULL, NULL },
292
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
293
 
294
    { // PRAT-CAM EDIT MODE
295
 
296
        // F5
297
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
298
        // F6
299
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
300
        // F7
301
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
302
        // F8
303
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
304
        // F10
305
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
306
        // F11
307
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
308
        // F12
309
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
310
        // 0
311
        { PratCam0, PratCam0, PratCam0, PratCam0, PratCam0, PratCam0, PratCam0, PratCam0 },
312
        // 1
313
        { PratCam1, PratCam1, PratCam1, PratCam1, PratCam1, PratCam1, PratCam1, PratCam1 },
314
        // 2
315
        { PratCam2, PratCam2, PratCam2, PratCam2, PratCam2, PratCam2, PratCam2, PratCam2 },
316
        // 3
317
        { PratCam3, PratCam3, PratCam3, PratCam3, PratCam3, PratCam3, PratCam3, PratCam3 },
318
        // 4
319
        { PratCam4, PratCam4, PratCam4, PratCam4, PratCam4, PratCam4, PratCam4, PratCam4 },
320
        // 5
321
        { PratCam5, PratCam5, PratCam5, PratCam5, PratCam5, PratCam5, PratCam5, PratCam5 },
322
        // 6
323
        { PratCam6, PratCam6, PratCam6, PratCam6, PratCam6, PratCam6, PratCam6, PratCam6 },
324
        // 7
325
        { PratCam7, PratCam7, PratCam7, PratCam7, PratCam7, PratCam7, PratCam7, PratCam7 },
326
        // 8
327
        { PratCam8, PratCam8, PratCam8, PratCam8, PratCam8, PratCam8, PratCam8, PratCam8 },
328
        // 9
329
        { PratCam9, PratCam9, PratCam9, PratCam9, PratCam9, PratCam9, PratCam9, PratCam9 },
330
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
331
 
332
    { // DEPTH EFFECTS EDIT MODE
333
 
334
        // F5
335
        { ToggleDepthMode, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
336
        // F6
337
        { ToggleSky, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
338
        // F7
339
        { LessDepthFactor, NULL, NULL, NULL, LessDepthFactor2, NULL, NULL, NULL },
340
        // F8
341
        { MoreDepthFactor, NULL, NULL, NULL, MoreDepthFactor2, NULL, NULL, NULL },
342
        // F10
343
        { IncreaseYon, NULL, NULL, NULL, DecreaseYon, NULL, NULL, NULL },
344
        // F11
345
        { IncreaseAngle, NULL, NULL, NULL, DecreaseAngle, NULL, NULL, NULL },
346
        // F12
347
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
348
        // 0
349
        { ToggleShadow, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
350
        // 1
351
        { ShadowMode, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
352
        // 2
353
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
354
        // 3
355
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
356
        // 4
357
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
358
        // 5
359
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
360
        // 6
361
        { SelectFaceDown, NULL, NULL, NULL, SelectFaceForward, NULL, NULL, NULL },
362
        // 7
363
        { ScaleUpX, NULL, NULL, NULL, ScaleDnX, NULL, NULL, NULL },
364
        // 8
365
        { ScaleUpY, NULL, NULL, NULL, ScaleDnY, NULL, NULL, NULL },
366
        // 9
367
        { DustRotate, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
368
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
369
 
370
    { // DAMAGE EDIT MODE
371
 
372
        // F5
373
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
374
        // F6
375
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
376
        // F7
377
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
378
        // F8
379
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
380
        // F10
381
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
382
        // F11
383
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
384
        // F12
385
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
386
        // 0
387
        { TDamageEngine, NULL, NULL, NULL, TDamageEngine, NULL, NULL, NULL },
388
        // 1
389
        { TDamageTrans, NULL, NULL, NULL, TDamageTrans, NULL, NULL, NULL },
390
        // 2
391
        { TDamageSteering, NULL, NULL, NULL, TDamageSteering, NULL, NULL, NULL },
392
        // 3
393
        { TDamageLFWheel, NULL, NULL, NULL, TDamageLFBrake, NULL, NULL, NULL },
394
        // 4
395
        { TDamageLRWheel, NULL, NULL, NULL, TDamageLRBrake, NULL, NULL, NULL },
396
        // 5
397
        { TDamageRFWheel, NULL, NULL, NULL, TDamageRFBrake, NULL, NULL, NULL },
398
        // 6
399
        { TDamageRRWheel, NULL, NULL, NULL, TDamageRRBrake, NULL, NULL, NULL },
400
        // 7
401
        { TDamageDriver, NULL, NULL, NULL, TDamageDriver, NULL, NULL, NULL },
402
        // 8
403
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
404
        // 9
405
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
406
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
407
 
408
    { // BONNET EDIT MODE
409
 
410
        // F5
411
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
412
        // F6
413
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
414
        // F7
415
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
416
        // F8
417
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
418
        // F10
419
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
420
        // F11
421
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
422
        // F12
423
        { SaveBonnet, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
424
        // 0
425
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
426
        // 1
427
        { MoveBonnetForward, NULL, NULL, NULL, MoveBonnetBackward, NULL, NULL, NULL },
428
        // 2
429
        { MoveBonnetLeft, NULL, NULL, NULL, MoveBonnetRight, NULL, NULL, NULL },
430
        // 3
431
        { MoveBonnetUp, NULL, NULL, NULL, MoveBonnetDown, NULL, NULL, NULL },
432
        // 4
433
        { TiltBonnetUpX, NULL, NULL, NULL, TiltBonnetDownX, NULL, NULL, NULL },
434
        // 5
435
        { TiltBonnetUpY, NULL, NULL, NULL, TiltBonnetDownY, NULL, NULL, NULL },
436
        // 6
437
        { TiltBonnetUpZ, NULL, NULL, NULL, TiltBonnetDownZ, NULL, NULL, NULL },
438
        // 7
439
        { ShrinkBonnetX, NULL, NULL, NULL, SwellBonnetX, NULL, NULL, NULL },
440
        // 8
441
        { ShrinkBonnetY, NULL, NULL, NULL, SwellBonnetY, NULL, NULL, NULL },
442
        // 9
443
        { ShrinkBonnetZ, NULL, NULL, NULL, SwellBonnetZ, NULL, NULL, NULL },
444
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
445
 
446
    { // OPTIONS EDIT MODE
447
 
448
        // F5
449
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
450
        // F6
451
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
452
        // F7
453
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
454
        // F8
455
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
456
        // F10
457
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
458
        // F11
459
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
460
        // F12
461
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
462
        // 0
463
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
464
        // 1
465
        { CycleCarSimplificationLevel, NULL, NULL, NULL, CycleCarTexturingLevel, NULL, NULL, NULL },
466
        // 2
467
        { ToggleShadow, NULL, NULL, NULL, ToggleSmoke, NULL, NULL, NULL },
468
        // 3
469
        { CycleWallTexturingLevel, NULL, NULL, NULL, CycleRoadTexturingLevel, NULL, NULL, NULL },
470
        // 4
471
        { ToggleSky, NULL, NULL, NULL, ToggleDepthCueing, NULL, NULL, NULL },
472
        // 5
473
        { CycleYonFactor, NULL, NULL, NULL, ToggleAccessoryRendering, NULL, NULL, NULL },
474
        // 6
475
        { DecreaseYon, NULL, NULL, NULL, IncreaseYon, NULL, NULL, NULL },
476
        // 7
477
        { CycleSoundDetailLevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
478
        // 8
479
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
480
        // 9
481
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
482
        { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
483
 
484
    }
485
};
486
 
487
tCheat gKev_keys[44] = {
488
    { .code = 0xa11ee75d, .code2 = 0xf805eddd, .action_proc = SetFlag, .num = 0x0a11ee75d },
489
    { .code = 0x564e78b9, .code2 = 0x99155115, .action_proc = SetFlag, .num = 0x0564e78b9 },
490
    { .code = 0x1f47e5e8, .code2 = 0xa715222c, .action_proc = SetFlag2, .num = 1 },
491
    { .code = 0x39d4c4c4, .code2 = 0xf0a2c5b0, .action_proc = FinishLap, .num = 0 },
492
    { .code = 0x2654216c, .code2 = 0xf8256d15, .action_proc = GetPowerup, .num = 1 },
493
    { .code = 0x4294ec89, .code2 = 0xc38ad60e, .action_proc = GetPowerup, .num = 2 },
494
    { .code = 0x2ceb2850, .code2 = 0xa0c2d27e, .action_proc = GetPowerup, .num = 3 },
495
    { .code = 0x2d5f3125, .code2 = 0x9ce8a541, .action_proc = GetPowerup, .num = 4 },
496
    { .code = 0x2169c78b, .code2 = 0x7f3c9229, .action_proc = GetPowerup, .num = 5 },
497
    { .code = 0x2203c0cb, .code2 = 0x79729be4, .action_proc = GetPowerup, .num = 6 },
498
    { .code = 0x34f4e3ec, .code2 = 0x868c534d, .action_proc = GetPowerup, .num = 7 },
499
    { .code = 0x34010316, .code2 = 0x591d1eb2, .action_proc = GetPowerup, .num = 8 },
500
    { .code = 0x214fe3bc, .code2 = 0x87285111, .action_proc = GetPowerup, .num = 9 },
501
    { .code = 0x2fabc390, .code2 = 0x0c93d9f7, .action_proc = GetPowerup, .num = 10 },
502
    { .code = 0x2902e890, .code2 = 0x40969f67, .action_proc = GetPowerup, .num = 11 },
503
    { .code = 0x2f458288, .code2 = 0x058074e2, .action_proc = GetPowerup, .num = 12 },
504
    { .code = 0x249da152, .code2 = 0x8f287346, .action_proc = GetPowerup, .num = 13 },
505
    { .code = 0x23aae08b, .code2 = 0xa668103d, .action_proc = GetPowerup, .num = 14 },
506
    { .code = 0x32130661, .code2 = 0x56f03459, .action_proc = GetPowerup, .num = 15 },
507
    { .code = 0x2734e944, .code2 = 0xfe1e4639, .action_proc = GetPowerup, .num = 16 },
508
    { .code = 0x28341139, .code2 = 0x355f6d02, .action_proc = GetPowerup, .num = 17 },
509
    { .code = 0x20508831, .code2 = 0x123d1961, .action_proc = GetPowerup, .num = 18 },
510
    { .code = 0x346b8bcb, .code2 = 0x4aba696c, .action_proc = GetPowerup, .num = 19 },
511
    { .code = 0x3fc93df0, .code2 = 0x29fa9efb, .action_proc = GetPowerup, .num = 20 },
512
    { .code = 0x2a80b09b, .code2 = 0x058516f5, .action_proc = GetPowerup, .num = 21 },
513
    { .code = 0x2f548fd1, .code2 = 0x696744da, .action_proc = GetPowerup, .num = 22 },
514
    { .code = 0x3cb74f32, .code2 = 0xb915d88d, .action_proc = GetPowerup, .num = 23 },
515
    { .code = 0x297b53ba, .code2 = 0x218d4d2d, .action_proc = GetPowerup, .num = 24 },
516
    { .code = 0x351bc37d, .code2 = 0xb2a63343, .action_proc = GetPowerup, .num = 25 },
517
    { .code = 0x2b624386, .code2 = 0x9ba6260e, .action_proc = GetPowerup, .num = 26 },
518
    { .code = 0x2ba4ae23, .code2 = 0xc163a76c, .action_proc = GetPowerup, .num = 27 },
519
    { .code = 0x2fb92dca, .code2 = 0x4ad7d54e, .action_proc = GetPowerup, .num = 32 },
520
    { .code = 0x3a42191b, .code2 = 0xeff70f4c, .action_proc = GetPowerup, .num = 35 },
521
    { .code = 0x2aca3190, .code2 = 0xd9004f25, .action_proc = GetPowerup, .num = 36 },
522
    { .code = 0x37c1f613, .code2 = 0xb7faf351, .action_proc = GetPowerup, .num = 37 },
523
    { .code = 0x2ba3f603, .code2 = 0x29f2425c, .action_proc = GetPowerup, .num = 38 },
524
    { .code = 0x416eff61, .code2 = 0x2667df4b, .action_proc = GetPowerup, .num = 39 },
525
    { .code = 0x2554125c, .code2 = 0x393ca35d, .action_proc = GetPowerup, .num = 41 },
526
    { .code = 0x3fff84d5, .code2 = 0x84a42df4, .action_proc = GetPowerup, .num = 42 },
527
    { .code = 0x37e83018, .code2 = 0xb609aee6, .action_proc = GetPowerup, .num = 43 },
528
    { .code = 0x2db03b19, .code2 = 0x924a84b7, .action_proc = GetPowerup, .num = 44 },
529
    { .code = 0x30a19fab, .code2 = 0x2b0c2782, .action_proc = GetPowerup, .num = 45 },
530
    { .code = 0x0, .code2 = 0x0, .action_proc = 0x0, .num = 0x0 }
531
};
532
int gAllow_car_flying;
533
int gEntering_message;
534
tU32 gPalette_fade_time; // was gRecover_timer
535
char* gAbuse_text[10];
536
char gString[84];
537
int gToo_late;
538
int gRecover_timer;
539
int gRecovery_voucher_count;
540
int gInstant_handbrake;
541
int gAuto_repair;
542
 
543
int _unittest_controls_lastGetPowerup = 0;
544
 
545
// IDA: void __cdecl AbortRace()
546
void AbortRace(void) {
547
    LOG_TRACE("()");
548
 
549
    if (!gRace_finished) {
550
        gAbandon_game = 1;
551
    }
552
}
553
 
554
// IDA: void __cdecl F4Key()
555
void F4Key(void) {
556
    char s[256];
557
    tEdit_mode old_edit_mode;
558
    LOG_TRACE("()");
559
 
560
    old_edit_mode = gWhich_edit_mode;
561
    if (gI_am_cheating == 0xa11ee75d || (gI_am_cheating == 0x564e78b9 && gNet_mode == eNet_mode_none)) {
562
        if (PDKeyDown(KEY_SHIFT_ANY)) {
563
            gWhich_edit_mode--;
564
            if ((int)gWhich_edit_mode < 0) {
565
                gWhich_edit_mode = COUNT_OF(gEdit_funcs) - 1;
566
            }
567
        } else {
568
            gWhich_edit_mode++;
569
            if (gWhich_edit_mode >= COUNT_OF(gEdit_funcs)) {
570
                gWhich_edit_mode = 0;
571
            }
572
        }
573
        sprintf(s, "Edit mode: %s", gEdit_mode_names[gWhich_edit_mode]);
574
        NewTextHeadupSlot2(4, 0, 2000, -4, s, 0);
575
        if (gWhich_edit_mode == eEdit_mode_spec_vol && old_edit_mode != eEdit_mode_spec_vol) {
576
            ShowSpecialVolumes();
577
        } else if (gWhich_edit_mode != eEdit_mode_spec_vol && old_edit_mode == eEdit_mode_spec_vol) {
578
            HideSpecialVolumes();
579
        }
580
    } else {
581
        gWhich_edit_mode = eEdit_mode_options;
582
    }
583
}
584
 
585
// IDA: void __usercall SetFlag(int i@<EAX>)
586
void SetFlag(int i) {
587
    LOG_TRACE("(%d)", i);
588
 
589
    if (gNet_mode == eNet_mode_none) {
21 pmbaty 590
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "You Cheat!");
1 pmbaty 591
    }
592
    gI_am_cheating = i;
593
    F4Key();
594
}
595
 
596
// IDA: void __usercall FinishLap(int i@<EAX>)
597
void FinishLap(int i) {
598
    LOG_TRACE("(%d)", i);
599
 
600
    IncrementLap();
601
}
602
 
603
// IDA: void __cdecl EnsureSpecialVolumesHidden()
604
void EnsureSpecialVolumesHidden(void) {
605
    LOG_TRACE("()");
606
 
607
    if (gWhich_edit_mode == eEdit_mode_spec_vol) {
608
        HideSpecialVolumes();
609
    }
610
}
611
 
612
// IDA: void __cdecl ShowSpecialVolumesIfRequ()
613
void ShowSpecialVolumesIfRequ(void) {
614
    LOG_TRACE("()");
615
 
616
    if (gWhich_edit_mode == eEdit_mode_spec_vol) {
617
        ShowSpecialVolumes();
618
    }
619
}
620
 
621
// IDA: void __usercall DoEditModeKey(int pIndex@<EAX>)
622
void DoEditModeKey(int pIndex) {
623
    int modifiers;
624
    LOG_TRACE("(%d)", pIndex);
625
 
626
    if (gI_am_cheating == 0xa11ee75d || (gI_am_cheating == 0x564e78b9 && gNet_mode == eNet_mode_none)) {
627
        modifiers = 0;
628
        if (PDKeyDown(KEY_SHIFT_ANY)) {
629
            modifiers |= 4;
630
        }
631
        if (PDKeyDown(KEY_ALT_ANY)) {
632
            modifiers |= 2;
633
        }
634
        if (PDKeyDown(KEY_CTRL_ANY)) {
635
            modifiers |= 1;
636
        }
637
        if (gEdit_funcs[gWhich_edit_mode][pIndex][modifiers] != NULL) {
638
            gEdit_funcs[gWhich_edit_mode][pIndex][modifiers]();
639
        }
640
    } else {
641
        gWhich_edit_mode = eEdit_mode_options;
642
    }
643
}
644
 
645
// IDA: void __cdecl F5Key()
646
void F5Key(void) {
647
    LOG_TRACE("()");
648
 
649
    DoEditModeKey(0);
650
}
651
 
652
// IDA: void __cdecl F6Key()
653
void F6Key(void) {
654
    LOG_TRACE("()");
655
 
656
    DoEditModeKey(1);
657
}
658
 
659
// IDA: void __cdecl F7Key()
660
void F7Key(void) {
661
    LOG_TRACE("()");
662
 
663
    DoEditModeKey(2);
664
}
665
 
666
// IDA: void __cdecl F8Key()
667
void F8Key(void) {
668
    LOG_TRACE("()");
669
 
670
    DoEditModeKey(3);
671
}
672
 
673
// IDA: void __cdecl F10Key()
674
void F10Key(void) {
675
    LOG_TRACE("()");
676
 
677
    DoEditModeKey(4);
678
}
679
 
680
// IDA: void __cdecl F11Key()
681
void F11Key(void) {
682
    LOG_TRACE("()");
683
 
684
    DoEditModeKey(5);
685
}
686
 
687
// IDA: void __cdecl F12Key()
688
void F12Key(void) {
689
    LOG_TRACE("()");
690
 
691
    DoEditModeKey(6);
692
}
693
 
694
// IDA: void __cdecl NumberKey0()
695
void NumberKey0(void) {
696
    LOG_TRACE("()");
697
 
698
    DoEditModeKey(7);
699
}
700
 
701
// IDA: void __cdecl NumberKey1()
702
void NumberKey1(void) {
703
    LOG_TRACE("()");
704
 
705
    DoEditModeKey(8);
706
}
707
 
708
// IDA: void __cdecl NumberKey2()
709
void NumberKey2(void) {
710
    LOG_TRACE("()");
711
 
712
    DoEditModeKey(9);
713
}
714
 
715
// IDA: void __cdecl NumberKey3()
716
void NumberKey3(void) {
717
    LOG_TRACE("()");
718
 
719
    DoEditModeKey(10);
720
}
721
 
722
// IDA: void __cdecl NumberKey4()
723
void NumberKey4(void) {
724
    LOG_TRACE("()");
725
 
726
    DoEditModeKey(11);
727
}
728
 
729
// IDA: void __cdecl NumberKey5()
730
void NumberKey5(void) {
731
    LOG_TRACE("()");
732
 
733
    DoEditModeKey(12);
734
}
735
 
736
// IDA: void __cdecl NumberKey6()
737
void NumberKey6(void) {
738
    LOG_TRACE("()");
739
 
740
    DoEditModeKey(13);
741
}
742
 
743
// IDA: void __cdecl NumberKey7()
744
void NumberKey7(void) {
745
    LOG_TRACE("()");
746
 
747
    DoEditModeKey(14);
748
}
749
 
750
// IDA: void __cdecl NumberKey8()
751
void NumberKey8(void) {
752
    LOG_TRACE("()");
753
 
754
    DoEditModeKey(15);
755
}
756
 
757
// IDA: void __cdecl NumberKey9()
758
void NumberKey9(void) {
759
    LOG_TRACE("()");
760
 
761
    DoEditModeKey(16);
762
}
763
 
764
// IDA: void __cdecl LookLeft()
765
void LookLeft(void) {
766
    LOG_TRACE("()");
767
 
768
    if (gAusterity_mode) {
21 pmbaty 769
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_NOT_ENOUGH_MEMORY));
1 pmbaty 770
    } else {
771
        PratcamEvent(27);
772
        gProgram_state.old_view = gProgram_state.which_view;
773
        if (gProgram_state.which_view == eView_left) {
774
            LookForward();
775
        } else if (gProgram_state.which_view == eView_right) {
776
            LookForward();
777
            gProgram_state.pending_view = eView_left;
778
        } else {
779
            ClearWobbles();
780
            gProgram_state.new_view = eView_left;
781
            gProgram_state.view_change_start = PDGetTotalTime();
782
            gProgram_state.pending_view = eView_undefined;
783
        }
784
    }
785
}
786
 
787
// IDA: void __cdecl LookForward()
788
void LookForward(void) {
789
    LOG_TRACE("()");
790
 
791
    if (gProgram_state.which_view == eView_right) {
792
        PratcamEvent(27);
793
    } else if (gProgram_state.which_view == eView_left) {
794
        PratcamEvent(28);
795
    }
796
    if (gProgram_state.which_view != eView_forward) {
797
        gProgram_state.old_view = gProgram_state.which_view;
798
        ClearWobbles();
799
        gProgram_state.new_view = eView_forward;
800
        gProgram_state.view_change_start = PDGetTotalTime();
801
        gProgram_state.pending_view = eView_undefined;
802
    }
803
}
804
 
805
// IDA: void __cdecl LookRight()
806
void LookRight(void) {
807
    LOG_TRACE("()");
808
 
809
    if (gAusterity_mode) {
21 pmbaty 810
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_NOT_ENOUGH_MEMORY));
1 pmbaty 811
    } else {
812
        PratcamEvent(28);
813
        gProgram_state.old_view = gProgram_state.which_view;
814
        if (gProgram_state.which_view == eView_right) {
815
            LookForward();
816
        } else if (gProgram_state.which_view == eView_left) {
817
            LookForward();
818
            gProgram_state.pending_view = eView_right;
819
        } else {
820
            ClearWobbles();
821
            gProgram_state.new_view = eView_right;
822
            gProgram_state.view_change_start = PDGetTotalTime();
823
            gProgram_state.pending_view = eView_undefined;
824
        }
825
    }
826
}
827
 
828
// IDA: void __cdecl DamageTest()
829
void DamageTest(void) {
830
    LOG_TRACE("()");
831
}
832
 
833
// IDA: void __cdecl TDamageEngine()
834
void TDamageEngine(void) {
835
    LOG_TRACE("()");
836
 
837
    DamageEngine(21);
838
}
839
 
840
// IDA: void __cdecl TDamageDriver()
841
void TDamageDriver(void) {
842
    LOG_TRACE("()");
843
 
844
    if (gProgram_state.current_car.damage_units[eDamage_driver].damage_level >= 80) {
845
        DamageUnit(&gProgram_state.current_car, eDamage_driver, 2);
846
    } else {
847
        DamageUnit(&gProgram_state.current_car, eDamage_driver, 80 - gProgram_state.current_car.damage_units[2].damage_level);
848
    }
849
}
850
 
851
// IDA: void __cdecl TDamageTrans()
852
void TDamageTrans(void) {
853
    LOG_TRACE("()");
854
 
855
    DamageTrans(21);
856
}
857
 
858
// IDA: void __cdecl TDamageSteering()
859
void TDamageSteering(void) {
860
    LOG_TRACE("()");
861
 
862
    DamageSteering(21);
863
}
864
 
865
// IDA: void __cdecl TDamageLFWheel()
866
void TDamageLFWheel(void) {
867
    LOG_TRACE("()");
868
 
869
    DamageLFWheel(21);
870
}
871
 
872
// IDA: void __cdecl TDamageLFBrake()
873
void TDamageLFBrake(void) {
874
    LOG_TRACE("()");
875
 
876
    DamageLFBrake(21);
877
}
878
 
879
// IDA: void __cdecl TDamageLRBrake()
880
void TDamageLRBrake(void) {
881
    LOG_TRACE("()");
882
 
883
    DamageLRBrake(21);
884
}
885
 
886
// IDA: void __cdecl TDamageLRWheel()
887
void TDamageLRWheel(void) {
888
    LOG_TRACE("()");
889
 
890
    DamageLRWheel(21);
891
}
892
 
893
// IDA: void __cdecl TDamageRFWheel()
894
void TDamageRFWheel(void) {
895
    LOG_TRACE("()");
896
 
897
    DamageRFWheel(21);
898
}
899
 
900
// IDA: void __cdecl TDamageRFBrake()
901
void TDamageRFBrake(void) {
902
    LOG_TRACE("()");
903
 
904
    DamageRFBrake(21);
905
}
906
 
907
// IDA: void __cdecl TDamageRRBrake()
908
void TDamageRRBrake(void) {
909
    LOG_TRACE("()");
910
 
911
    DamageRRBrake(21);
912
}
913
 
914
// IDA: void __cdecl TDamageRRWheel()
915
void TDamageRRWheel(void) {
916
    LOG_TRACE("()");
917
 
918
    DamageRRWheel(21);
919
}
920
 
921
// IDA: void __cdecl MoveBonnetForward()
922
void MoveBonnetForward(void) {
923
    LOG_TRACE("()");
924
 
925
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[2] -= .005f;
926
}
927
 
928
// IDA: void __cdecl SaveBonnet()
929
void SaveBonnet(void) {
930
    br_actor* bonny;
931
    tPath_name the_path;
932
    LOG_TRACE("()");
933
 
934
    bonny = gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor;
935
    PathCat(the_path, gApplication_path, bonny->identifier);
936
    BrActorSave(the_path, bonny);
937
}
938
 
939
// IDA: void __cdecl MoveBonnetBackward()
940
void MoveBonnetBackward(void) {
941
    LOG_TRACE("()");
942
 
943
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[2] += .005f;
944
}
945
 
946
// IDA: void __cdecl MoveBonnetLeft()
947
void MoveBonnetLeft(void) {
948
    LOG_TRACE("()");
949
 
950
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[0] -= .005f;
951
}
952
 
953
// IDA: void __cdecl ShrinkBonnetX()
954
void ShrinkBonnetX(void) {
955
    LOG_TRACE("()");
956
 
957
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[0][0] *= .98f;
958
}
959
 
960
// IDA: void __cdecl SwellBonnetX()
961
void SwellBonnetX(void) {
962
    LOG_TRACE("()");
963
 
964
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[0][0] *= 1.02f;
965
}
966
 
967
// IDA: void __cdecl ShrinkBonnetY()
968
void ShrinkBonnetY(void) {
969
    LOG_TRACE("()");
970
 
971
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[1][1] *= .98f;
972
}
973
 
974
// IDA: void __cdecl SwellBonnetY()
975
void SwellBonnetY(void) {
976
    LOG_TRACE("()");
977
 
978
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[1][1] *= 1.02f;
979
}
980
 
981
// IDA: void __cdecl ShrinkBonnetZ()
982
void ShrinkBonnetZ(void) {
983
    LOG_TRACE("()");
984
 
985
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[2][2] *= .98f;
986
}
987
 
988
// IDA: void __cdecl SwellBonnetZ()
989
void SwellBonnetZ(void) {
990
    LOG_TRACE("()");
991
 
992
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[2][2] *= 1.02f;
993
}
994
 
995
// IDA: void __cdecl MoveBonnetDown()
996
void MoveBonnetDown(void) {
997
    LOG_TRACE("()");
998
 
999
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[1] += .005f;
1000
}
1001
 
1002
// IDA: void __cdecl MoveBonnetRight()
1003
void MoveBonnetRight(void) {
1004
    LOG_TRACE("()");
1005
 
1006
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[0] += .005f;
1007
}
1008
 
1009
// IDA: void __cdecl MoveBonnetUp()
1010
void MoveBonnetUp(void) {
1011
    LOG_TRACE("()");
1012
 
1013
    gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[1] -= .005f;
1014
}
1015
 
1016
// IDA: void __cdecl TiltBonnetDownX()
1017
void TiltBonnetDownX(void) {
1018
    LOG_TRACE("()");
1019
 
1020
    BrMatrix34PreRotateX(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, BR_ANGLE_DEG(.5f));
1021
}
1022
 
1023
// IDA: void __cdecl TiltBonnetUpX()
1024
void TiltBonnetUpX(void) {
1025
    LOG_TRACE("()");
1026
 
1027
    BrMatrix34PreRotateX(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, -BR_ANGLE_DEG(.5f));
1028
}
1029
 
1030
// IDA: void __cdecl TiltBonnetDownY()
1031
void TiltBonnetDownY(void) {
1032
    LOG_TRACE("()");
1033
 
1034
    BrMatrix34PreRotateY(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, BR_ANGLE_DEG(.5f));
1035
}
1036
 
1037
// IDA: void __cdecl TiltBonnetUpY()
1038
void TiltBonnetUpY(void) {
1039
    LOG_TRACE("()");
1040
 
1041
    BrMatrix34PreRotateY(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, -BR_ANGLE_DEG(.5f));
1042
}
1043
 
1044
// IDA: void __cdecl TiltBonnetDownZ()
1045
void TiltBonnetDownZ(void) {
1046
    LOG_TRACE("()");
1047
 
1048
    BrMatrix34PreRotateZ(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, BR_ANGLE_DEG(.5f));
1049
}
1050
 
1051
// IDA: void __cdecl TiltBonnetUpZ()
1052
void TiltBonnetUpZ(void) {
1053
    LOG_TRACE("()");
1054
 
1055
    BrMatrix34PreRotateZ(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, -BR_ANGLE_DEG(.5f));
1056
}
1057
 
1058
// IDA: void __cdecl ToggleCockpit()
1059
void ToggleCockpit(void) {
1060
    //br_scalar ts; // Pierre-Marie Baty -- unused variable
1061
    LOG_TRACE("()");
1062
 
1063
    if ((&gProgram_state.current_car == gCar_to_view || gProgram_state.cockpit_on) && !gMap_mode) {
1064
        if (!gAusterity_mode || gProgram_state.cockpit_on) {
1065
            gProgram_state.cockpit_on = !gProgram_state.cockpit_on;
1066
            if (gProgram_state.cockpit_on) {
1067
                gCamera = gCamera_list[0];
1068
            } else {
1069
                gCamera = gCamera_list[1];
1070
                InitialiseExternalCamera();
1071
                PositionExternalCamera(&gProgram_state.current_car, 1);
1072
            }
1073
            AdjustRenderScreenSize();
1074
            AdjustHeadups();
1075
            MungeForwardSky();
1076
        } else {
21 pmbaty 1077
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_NOT_ENOUGH_MEMORY));
1 pmbaty 1078
        }
1079
    }
1080
}
1081
 
1082
// IDA: void __cdecl ToggleMirror()
1083
void ToggleMirror(void) {
1084
    LOG_TRACE("()");
1085
 
1086
    gProgram_state.mirror_on = !gProgram_state.mirror_on;
1087
    ReinitialiseRearviewCamera();
1088
    if (gProgram_state.mirror_on) {
21 pmbaty 1089
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -4, GetMiscString(kMiscString_MirrorOn));
1 pmbaty 1090
    } else {
21 pmbaty 1091
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -4, GetMiscString(kMiscString_MirrorOff));
1 pmbaty 1092
    }
1093
}
1094
 
1095
// IDA: void __cdecl ConcussMe()
1096
// dethrace: this is not referenced in the retail executables. Left over debug code.
1097
void ConcussMe(void) {
1098
    LOG_TRACE("()");
1099
 
1100
    SufferFromConcussion(1.f);
1101
    NewScreenWobble(IRandomPosNeg(15), IRandomPosNeg(10), IRandomBetween(10, 60));
1102
    PratcamEvent(3);
1103
}
1104
 
1105
// IDA: void __cdecl CheckHelp()
1106
void CheckHelp(void) {
1107
    LOG_TRACE("()");
20 pmbaty 1108
    NOT_IMPLEMENTED();
1 pmbaty 1109
}
1110
 
1111
// IDA: void __cdecl CheckLoadSave()
1112
void CheckLoadSave(void) {
1113
    int save_load_allowed;
1114
    //int switched_res; // Pierre-Marie Baty -- unused variable
1115
    LOG_TRACE8("()");
1116
 
1117
    save_load_allowed = !gProgram_state.saving && !gProgram_state.loading && gProgram_state.prog_status == eProg_game_ongoing && !gProgram_state.dont_save_or_load;
1118
 
1119
    if (CmdKeyDown(KEYMAP_SAVE, KEYMAP_CTRL_SAVE)) {
1120
        if (save_load_allowed) {
1121
            FadePaletteDown();
1122
            ClearEntireScreen();
1123
            if (gProgram_state.racing) {
1124
                GoingToInterfaceFromRace();
1125
            }
1126
            DoSaveGame(gProgram_state.racing == 0);
1127
            if (gProgram_state.racing) {
1128
                GoingBackToRaceFromInterface();
1129
            }
1130
        }
1131
        WaitForNoKeys();
1132
    }
1133
    if (CmdKeyDown(KEYMAP_LOAD, KEYMAP_CTRL_LOAD)) {
1134
        if (save_load_allowed && !gProgram_state.dont_load) {
1135
            FadePaletteDown();
1136
            ClearEntireScreen();
1137
            if (gProgram_state.racing) {
1138
                GoingToInterfaceFromRace();
1139
            }
1140
            if (DoLoadGame() && !gProgram_state.racing) {
1141
                gProgram_state.prog_status = eProg_game_starting;
1142
            }
1143
            if (gProgram_state.racing) {
1144
                GoingBackToRaceFromInterface();
1145
            }
1146
            PlayFlicsFromMemory();
1147
        }
1148
        WaitForNoKeys();
1149
    }
1150
}
1151
 
1152
// IDA: void __usercall CheckToggles(int pRacing@<EAX>)
1153
void CheckToggles(int pRacing) {
1154
    int i;
1155
    int new_state;
1156
 
1157
    for (i = 0; i < COUNT_OF(gToggle_array); i++) {
1158
        if ((!gToggle_array[i].in_game_only || pRacing)
1159
            && ((!gTyping && !gEntering_message) || gToggle_array[i].key2 != -2)) {
1160
            new_state = 0;
1161
            if (gToggle_array[i].key1 == -2 || KeyIsDown(gToggle_array[i].key1)) {
1162
                if (gToggle_array[i].key2 == -2 && gToggle_array[i].exact_modifiers) {
1163
                    if (!PDKeyDown(KEY_SHIFT_ANY) && !PDKeyDown(KEY_ALT_ANY) && !PDKeyDown(KEY_CTRL_ANY) && !PDKeyDown(KEY_CTRL_ANY_2)) {
1164
                        new_state = 1;
1165
                    }
1166
                } else {
1167
                    if (KeyIsDown(gToggle_array[i].key2)) {
1168
                        new_state = 1;
1169
                    }
1170
                }
1171
            }
1172
            if (gToggle_array[i].on_last_time != new_state) {
1173
                gToggle_array[i].on_last_time = new_state;
1174
                if (new_state) {
1175
                    gToggle_array[i].action_proc();
1176
                }
1177
            }
1178
        }
1179
    }
1180
}
1181
 
1182
// IDA: int __usercall CarWorldOffFallenCheckThingy@<EAX>(tCar_spec *pCar@<EAX>, int pCheck_around@<EDX>)
1183
int CarWorldOffFallenCheckThingy(tCar_spec* pCar, int pCheck_around) {
1184
    br_vector3 car_pos;
1185
    br_vector3 offset_c;
1186
    br_vector3 offset_w;
1187
    int result;
1188
    LOG_TRACE("(%p, %d)", pCar, pCheck_around);
1189
 
1190
    if (pCar->number_of_wheels_on_ground != 0) {
1191
        return 0;
1192
    }
1193
    if (pCar->driver == eDriver_local_human && gCar_flying) {
1194
        return 0;
1195
    }
1196
    if (gAction_replay_mode) {
1197
        return 0;
1198
    }
1199
    BrVector3Copy(&car_pos, &pCar->car_master_actor->t.t.translate.t);
1200
    if (FindYVerticallyBelow2(&car_pos) >= -100.f) {
1201
        return 0;
1202
    }
1203
    BrVector3Set(&offset_c, 0.f, 1.f, 0.f);
1204
    BrMatrix34ApplyV(&offset_w, &offset_c, &pCar->car_master_actor->t.t.mat);
1205
    if (FindYVerticallyBelow2(&car_pos) >= -100.f) {
1206
        // FIXME: testing twice using `FindYVerticallyBelow2' is meaningless
1207
        return 0;
1208
    }
1209
    if (!pCheck_around) {
1210
        return 1;
1211
    }
1212
    pCar->car_master_actor->t.t.translate.t.v[0] += 0.05f;
1213
    result = CarWorldOffFallenCheckThingy(pCar, 0);
1214
    pCar->car_master_actor->t.t.translate.t.v[0] -= 0.05f;
1215
    if (!result) {
1216
        return 0;
1217
    }
1218
    pCar->car_master_actor->t.t.translate.t.v[2] += 0.05f;
1219
    result = CarWorldOffFallenCheckThingy(pCar, 0);
1220
    pCar->car_master_actor->t.t.translate.t.v[2] -= 0.05f;
1221
    if (!result) {
1222
        return 0;
1223
    }
1224
    return 1;
1225
}
1226
 
1227
// IDA: int __usercall HasCarFallenOffWorld@<EAX>(tCar_spec *pCar@<EAX>)
1228
int HasCarFallenOffWorld(tCar_spec* pCar) {
1229
    LOG_TRACE("(%p)", pCar);
1230
 
1231
    return CarWorldOffFallenCheckThingy(pCar, 1);
1232
}
1233
 
1234
// IDA: void __cdecl CheckForBeingOutOfThisWorld()
1235
void CheckForBeingOutOfThisWorld(void) {
1236
    static tU32 the_time;
1237
    static tU32 sLast_check;
1238
    //int time_step; // Pierre-Marie Baty -- unused variable
1239
    LOG_TRACE("()");
1240
 
1241
    the_time = PDGetTotalTime();
1242
 
1243
    if (gRecover_timer == 0 || ((gProgram_state.current_car.frame_collision_flag || gProgram_state.current_car.number_of_wheels_on_ground) && !IsCarInTheSea())) {
1244
        gRecover_timer = 0;
1245
        if ((the_time - sLast_check) > 200) {
1246
            sLast_check = the_time;
1247
            if (HasCarFallenOffWorld(&gProgram_state.current_car)) {
1248
                gRecover_timer = 3000;
1249
            }
1250
        }
1251
        if (IsCarInTheSea()) {
1252
            if (!gRecover_timer) {
1253
                gRecover_timer = 3000;
1254
            }
1255
        }
1256
        return;
1257
    }
1258
    gRecover_timer -= gFrame_period;
1259
    if (gRecover_timer <= 0 || IsCarInTheSea() == 2) {
1260
        gRecover_timer = 0;
1261
        RecoverCar();
1262
        gHad_auto_recover = 1;
1263
    }
1264
}
1265
 
1266
// IDA: void __usercall CheckHornLocal(tCar_spec *pCar@<EAX>)
1267
void CheckHornLocal(tCar_spec* pCar) {
1268
    LOG_TRACE("(%p)", pCar);
1269
 
1270
    if (pCar->keys.horn == 1 && pCar->horn_sound_tag == 0) {
1271
        pCar->horn_sound_tag = DRS3StartSound(gEffects_outlet, 5209);
1272
    } else if (pCar->keys.horn == 0 && pCar->horn_sound_tag != 0) {
1273
        if (S3SoundStillPlaying(pCar->horn_sound_tag) != 0) {
1274
            DRS3StopSound(pCar->horn_sound_tag);
1275
            DRS3StopOutletSound(gEffects_outlet);
1276
        }
1277
        if (S3SoundStillPlaying(pCar->horn_sound_tag) == 0) {
1278
            pCar->horn_sound_tag = 0;
1279
        }
1280
    }
1281
}
1282
 
1283
// IDA: void __usercall CheckHorn3D(tCar_spec *pCar@<EAX>)
1284
void CheckHorn3D(tCar_spec* pCar) {
1285
    LOG_TRACE("(%p)", pCar);
20 pmbaty 1286
    STUB_ONCE();
1 pmbaty 1287
}
1288
 
1289
// IDA: void __cdecl CheckHorns()
1290
void CheckHorns(void) {
1291
    int i;
1292
    LOG_TRACE("()");
1293
 
1294
    if (gNet_mode != eNet_mode_none) {
1295
        for (i = 0; i < gNumber_of_net_players; i++) {
1296
            CheckHorn3D(gNet_players[i].car);
1297
        }
1298
    } else {
1299
        CheckHornLocal(&gProgram_state.current_car);
1300
    }
1301
}
1302
 
1303
// IDA: void __cdecl SetRecovery()
1304
void SetRecovery(void) {
1305
    LOG_TRACE("()");
1306
 
1307
    if (gRace_finished
1308
        || gProgram_state.current_car.knackered
1309
        || gWait_for_it
1310
        || gHad_auto_recover
1311
        || gPalette_fade_time) {
1312
        return;
1313
    }
1314
 
1315
    if (gNet_mode == eNet_mode_none) {
1316
        gRecover_car = 1;
1317
        gRecover_timer = 0;
1318
        return;
1319
    }
1320
    if (gProgram_state.current_car.time_to_recover) {
1321
        if (GetRaceTime() + 600 >= gProgram_state.current_car.time_to_recover) {
1322
            NewTextHeadupSlot2(4, 0, 2000, -4, GetMiscString(kMiscString_TOO_LATE_TO_CANCEL), 1);
1323
            gToo_late = 1;
1324
        } else {
1325
            gProgram_state.current_car.time_to_recover = 0;
1326
            NewTextHeadupSlot2(4, 0, 2000, -4, GetMiscString(kMiscString_RECOVERY_CANCELLED), 0);
1327
        }
1328
        return;
1329
    }
1330
    if (!CheckRecoverCost()) {
1331
        return;
1332
    }
1333
    if (gCurrent_net_game->type == eNet_game_type_foxy) {
1334
        if (gThis_net_player_index == gIt_or_fox) {
1335
            gProgram_state.current_car.time_to_recover = GetRaceTime() + 5000;
1336
            gRecover_timer = 0;
1337
            gToo_late = 0;
1338
            return;
1339
        }
1340
    } else {
1341
        if (gCurrent_net_game->type != eNet_game_type_tag) {
1342
            gProgram_state.current_car.time_to_recover = GetRaceTime() + 3000;
1343
            gRecover_timer = 0;
1344
            gToo_late = 0;
1345
            return;
1346
        }
1347
        if (gThis_net_player_index != gIt_or_fox) {
1348
            gProgram_state.current_car.time_to_recover = GetRaceTime() + 5000;
1349
            gRecover_timer = 0;
1350
            gToo_late = 0;
1351
            return;
1352
        }
1353
    }
1354
    gProgram_state.current_car.time_to_recover = GetRaceTime() + 1000;
1355
    gRecover_timer = 0;
1356
    gToo_late = 0;
1357
}
1358
 
1359
// IDA: void __cdecl RecoverCar()
1360
void RecoverCar(void) {
1361
    LOG_TRACE("()");
1362
 
1363
    if (gNet_mode == eNet_mode_none || !gPalette_fade_time) {
1364
        gRecover_car = 1;
1365
    }
1366
    gProgram_state.current_car.time_to_recover = 0;
1367
}
1368
 
1369
// IDA: void __cdecl CheckMapRenderMove()
1370
void CheckMapRenderMove(void) {
1371
    //int shift_down; // Pierre-Marie Baty -- unused variable
1372
    int amount;
1373
    float old_x;
1374
    float old_y;
1375
    LOG_TRACE("()");
1376
 
1377
    old_y = gMap_render_y;
1378
    old_x = gMap_render_x;
1379
    if (gMap_mode) {
1380
        amount = gFrame_period * .1f;
20 pmbaty 1381
        if (KeyIsDown(30)) {
1 pmbaty 1382
            gMap_render_y -= amount;
20 pmbaty 1383
        } else if (KeyIsDown(31)) {
1 pmbaty 1384
            gMap_render_y += amount;
1385
        }
20 pmbaty 1386
        if (KeyIsDown(32)) {
1 pmbaty 1387
            gMap_render_x -= amount;
20 pmbaty 1388
        } else if (KeyIsDown(33)) {
1 pmbaty 1389
            gMap_render_x += amount;
1390
        }
1391
        if (gMap_render_x != old_x || gMap_render_y != old_y) {
1392
            SetIntegerMapRenders();
1393
            if (gMap_render_x_i < gCurrent_graf_data->map_render_x_marg) {
1394
                if (gReal_graf_data_index == 0) {
1395
                    gMap_render_x = (gCurrent_graf_data->map_render_x_marg + 3) & ~3;
1396
                } else {
1397
                    gMap_render_x = ((gCurrent_graf_data->map_render_x_marg + 3) & ~3) / 2;
1398
                }
1399
            }
1400
            if (gMap_render_y_i < gCurrent_graf_data->map_render_y_marg) {
1401
                if (gReal_graf_data_index == 0) {
1402
                    gMap_render_y = (gCurrent_graf_data->map_render_y_marg + 1) & ~1;
1403
                } else {
1404
                    gMap_render_y = (((gCurrent_graf_data->map_render_y_marg + 1) & ~1) - 40) / 2;
1405
                }
1406
            }
1407
            if (gBack_screen->width - gCurrent_graf_data->map_render_x_marg - gMap_render_width_i < gMap_render_x_i) {
1408
                if (gReal_graf_data_index == 0) {
1409
                    gMap_render_x = (gBack_screen->width - gCurrent_graf_data->map_render_x_marg - gMap_render_width_i) & ~3;
1410
                } else {
1411
                    gMap_render_x = ((gBack_screen->width - gCurrent_graf_data->map_render_x_marg - gMap_render_width_i) & ~3) / 2;
1412
                }
1413
            }
1414
            if (gBack_screen->height - gCurrent_graf_data->map_render_y_marg - gMap_render_height_i < gMap_render_y_i) {
1415
                if (gReal_graf_data_index == 0) {
1416
                    gMap_render_y = (gBack_screen->height - gCurrent_graf_data->map_render_y_marg - gMap_render_height_i) & ~1;
1417
                } else {
1418
                    gMap_render_y = (((gBack_screen->height - gCurrent_graf_data->map_render_y_marg - gMap_render_height_i) & ~3) - 40) / 2;
1419
                }
1420
            }
1421
            SetIntegerMapRenders();
1422
            AdjustRenderScreenSize();
1423
        }
1424
    }
1425
}
1426
 
1427
// IDA: void __usercall ExplodeCar(tCar_spec *pCar@<EAX>)
1428
void ExplodeCar(tCar_spec* pCar) {
1429
    br_vector3 tv;
1430
    br_vector3 pos;
1431
    LOG_TRACE("(%p)", pCar);
1432
 
1433
    pCar->last_car_car_collision = 0;
1434
    pos.v[0] = .1449275f * pCar->cmpos.v[0];
1435
    pos.v[1] = .1449275f * pCar->cmpos.v[1];
1436
    pos.v[2] = pCar->bounds[0].min.v[2] + .3f * (pCar->bounds[0].max.v[2] - pCar->bounds[0].min.v[2]);
1437
    BrMatrix34ApplyP(&tv, &pos, &pCar->car_master_actor->t.t.mat);
1438
    CreatePuffOfSmoke(&tv, &pCar->v, 1.f, 1.f, 7, pCar);
1439
 
1440
    pos.v[2] = pCar->bounds[0].min.v[2] + .7f * (pCar->bounds[0].max.v[2] - pCar->bounds[0].min.v[2]);
1441
    BrMatrix34ApplyP(&tv, &pos, &pCar->car_master_actor->t.t.mat);
1442
    CreatePuffOfSmoke(&tv, &pCar->v, 1.f, 1.f, 7, pCar);
1443
 
1444
    DisableCar(pCar);
1445
}
1446
 
1447
// IDA: void __usercall CheckRecoveryOfCars(tU32 pEndFrameTime@<EAX>)
1448
void CheckRecoveryOfCars(tU32 pEndFrameTime) {
1449
    int i;
1450
    int time;
1451
    char s[256];
1452
    LOG_TRACE("(%d)", pEndFrameTime);
1453
 
1454
    if (gProgram_state.current_car.time_to_recover) {
1455
        if (gProgram_state.current_car.knackered) {
1456
            gProgram_state.current_car.time_to_recover = 0;
1457
        } else {
1458
            time = (gProgram_state.current_car.time_to_recover - pEndFrameTime + 1000) / 1000;
1459
            sprintf(s, "%s %d %s", GetMiscString(kMiscString_RECOVERY_IN), time, time > 1 ? GetMiscString(kMiscString_SECONDS) : GetMiscString(kMiscString_SECOND));
1460
            if (!gToo_late) {
1461
                NewTextHeadupSlot2(4, 0, 2000, -4, s, 0);
1462
            }
1463
            if (gProgram_state.current_car.time_to_recover <= pEndFrameTime) {
1464
                RecoverCar();
1465
            }
1466
        }
1467
    }
1468
    if (gNet_mode) {
1469
        for (i = 0; i < gNumber_of_net_players; i++) {
1470
            if (gThis_net_player_index != i && gNet_players[i].car->time_to_recover && gNet_players[i].car->time_to_recover <= pEndFrameTime) {
1471
                gNet_players[i].player_status = ePlayer_status_recovering;
1472
                gNet_players[i].car->message.type = 32;
1473
                gNet_players[i].car->message.time = pEndFrameTime;
1474
                ExplodeCar(gNet_players[i].car);
1475
                gNet_players[i].car->time_to_recover = 0;
1476
            }
1477
        }
1478
    }
1479
}
1480
 
1481
// IDA: void __usercall LoseSomePSPowerups(int pNumber@<EAX>)
1482
void LoseSomePSPowerups(int pNumber) {
1483
    int index;
1484
    LOG_TRACE("(%d)", pNumber);
1485
 
1486
    if (gNet_mode != eNet_mode_none && pNumber > 0) {
1487
        while (pNumber--) {
1488
            index = IRandomBetween(0, 2);
1489
            if (gProgram_state.current_car.power_up_levels[index]) {
1490
                gProgram_state.current_car.power_up_levels[index]--;
1491
            }
1492
        }
1493
    }
1494
}
1495
 
1496
// IDA: void __cdecl CheckOtherRacingKeys()
1497
void CheckOtherRacingKeys(void) {
1498
    int i;
1499
    int j;
1500
    int new_level;
1501
    int old_level;
1502
    char s[256];
1503
    tU32 cost;
1504
    br_scalar ts;
1505
    //br_vector3 tv; // Pierre-Marie Baty -- unused variable
1506
    //int flip_up_flag; // Pierre-Marie Baty -- unused variable
1507
    tCar_spec* car;
1508
    float bodywork_repair_amount;
1509
    static tU32 total_repair_cost;
1510
    static tS3_sound_tag sound_tag;
1511
    static br_scalar amount;
1512
    static int NeedToExpandBoundingBox;
1513
    static int total_difference;
1514
    static int stopped_repairing;
1515
    LOG_TRACE("()");
1516
 
1517
    car = GetCarSpec(eVehicle_self, 0);
1518
    CheckMapRenderMove();
1519
    CheckHorns();
1520
    CheckForBeingOutOfThisWorld();
1521
    if (gPalette_fade_time) {
1522
        SortOutRecover(car);
1523
    } else if (gNet_mode && NetGetPlayerStatus() == ePlayer_status_recovering) {
1524
        NetPlayerStatusChanged(ePlayer_status_racing);
1525
    }
1526
 
1527
    if ((gAuto_repair || KeyIsDown(KEYMAP_REPAIR)) && !gRace_finished && !gProgram_state.current_car.knackered && !gWait_for_it && !gEntering_message) {
1528
        if (!gAuto_repair && gRepair_last_time == 0 && GetTotalTime() - gLast_repair_time < 1200) {
1529
            gAuto_repair = 1;
1530
        }
1531
        gLast_repair_time = GetTotalTime();
1532
        gRepair_last_time = 1;
1533
        if (!NeedToExpandBoundingBox) {
1534
            if (gFree_repairs
1535
                || gNet_mode == eNet_mode_none
1536
                || gProgram_state.credits_earned - gProgram_state.credits_lost >= 1) {
1537
                bodywork_repair_amount = RepairCar(gProgram_state.current_car.car_ID, gFrame_period, &amount);
1538
                NeedToExpandBoundingBox = bodywork_repair_amount > 0;
1539
                cost = 0;
1540
                for (j = 0; j < COUNT_OF(gProgram_state.current_car.damage_units); j++) {
1541
                    old_level = gProgram_state.current_car.damage_units[j].damage_level;
1542
                    if (amount == 0.0f) {
1543
                        new_level = 0;
1544
                    } else {
1545
                        new_level = ((double)gProgram_state.current_car.damage_units[j].damage_level
1546
                            - floor(bodywork_repair_amount / amount * (double)gProgram_state.current_car.damage_units[j].damage_level));
1547
                    }
1548
                    if (new_level >= 0) {
1549
                        if (new_level < 100) {
1550
                            gProgram_state.current_car.damage_units[j].damage_level = new_level;
1551
                        } else {
1552
                            gProgram_state.current_car.damage_units[j].damage_level = 99;
1553
                        }
1554
                    } else {
1555
                        gProgram_state.current_car.damage_units[j].damage_level = 0;
1556
                    }
1557
                    gProgram_state.current_car.damage_units[j].smoke_last_level = gProgram_state.current_car.damage_units[j].damage_level;
1558
                    if (gNet_mode) {
1559
                        ts = gNet_repair_cost[gCurrent_net_game->type];
1560
                    } else {
1561
                        ts = gRepair_cost[gProgram_state.skill_level];
1562
                    }
1563
                    cost = (old_level - gProgram_state.current_car.damage_units[j].damage_level) * ts + cost;
1564
                    total_difference += old_level - new_level;
1565
                }
1566
                if (!gFree_repairs) {
1567
                    LoseSomePSPowerups(total_difference / 100);
1568
                }
1569
                total_difference %= 100;
1570
                cost = 10 * (cost / 10);
1571
                if (((!total_repair_cost && cost) || bodywork_repair_amount != 0.0f) && !sound_tag) {
1572
                    sound_tag = DRS3StartSound(gCar_outlet, 5200);
1573
                }
1574
                if (gProgram_state.current_car.num_smoke_columns) {
1575
                    StopCarSmoking(&gProgram_state.current_car);
1576
                }
1577
                if (!cost && bodywork_repair_amount == 0.0) {
1578
                    gAuto_repair = 0;
1579
                }
1580
                if (!gFree_repairs) {
1581
                    cost += SpendCredits(cost);
1582
                }
1583
                total_repair_cost += cost;
1584
                if (total_repair_cost) {
1585
                    if (gFree_repairs) {
21 pmbaty 1586
                        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_RepairingForFree));
1 pmbaty 1587
                    } else {
1588
                        sprintf(s, "%s %d", GetMiscString(kMiscString_RepairCostColon), total_repair_cost);
21 pmbaty 1589
                        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, s);
1 pmbaty 1590
                    }
1591
                }
1592
            } else {
1593
                if (!stopped_repairing) {
21 pmbaty 1594
                    NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_CANNOT_AFFORD_TO_REPAIR));
1 pmbaty 1595
                }
1596
                gAuto_repair = 0;
1597
                stopped_repairing = 1;
1598
            }
1599
        }
1600
 
1601
    } else {
1602
        gRepair_last_time = 0;
1603
        stopped_repairing = 0;
1604
        total_repair_cost = 0;
1605
        total_difference = 0;
1606
        if (sound_tag) {
1607
            for (i = 0; i < 10 && S3SoundStillPlaying(sound_tag); ++i) {
1608
                DRS3StopSound(sound_tag);
1609
            }
1610
            sound_tag = 0;
1611
        }
1612
    }
1613
    if (NeedToExpandBoundingBox) {
1614
        NeedToExpandBoundingBox = ExpandBoundingBox(&gProgram_state.current_car) == 0;
1615
    }
1616
    if (!gRecover_car || gProgram_state.current_car.knackered) {
1617
        gHad_auto_recover = 0;
1618
    } else if (CheckRecoverCost()) {
1619
        gRecover_timer = 0;
1620
        SetFlipUpCar(car);
1621
        if (gNet_mode != eNet_mode_none) {
21 pmbaty 1622
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 1500, -4, " ");
1 pmbaty 1623
        }
1624
        if (gRecovery_voucher_count != 0) {
1625
            gRecovery_voucher_count--;
1626
            sprintf(s, "%s", GetMiscString(kMiscString_RecoveringForFree));
21 pmbaty 1627
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 1500, -4, s);
1 pmbaty 1628
        } else {
1629
            if (gNet_mode) {
1630
                cost = gNet_recovery_cost[gCurrent_net_game->type];
1631
            } else {
1632
                cost = gRecovery_cost[gProgram_state.skill_level];
1633
            }
1634
            SpendCredits(cost);
1635
            if (gNet_mode) {
1636
                cost = gNet_recovery_cost[gCurrent_net_game->type];
1637
            } else {
1638
                cost = gRecovery_cost[gProgram_state.skill_level];
1639
            }
1640
            sprintf(s, "%s %d", GetMiscString(kMiscString_RecoveryCostColon), cost);
21 pmbaty 1641
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 1500, -4, s);
1 pmbaty 1642
            LoseSomePSPowerups(2);
1643
        }
1644
        CancelPendingCunningStunt();
1645
        PipeSingleSpecial(ePipe_special_fade);
1646
    }
1647
    gRecover_car = 0;
1648
}
1649
 
1650
// IDA: int __cdecl CheckRecoverCost()
1651
int CheckRecoverCost(void) {
1652
    LOG_TRACE("()");
1653
 
1654
    if (gProgram_state.current_car.knackered
1655
        || gNet_mode == eNet_mode_none
1656
        || (gProgram_state.credits_earned - gProgram_state.credits_lost) >= gNet_recovery_cost[gCurrent_net_game->type]
1657
        || gRecovery_voucher_count) {
1658
        return 1;
1659
    }
1660
    gProgram_state.credits_earned = 0;
1661
    gProgram_state.credits_lost = 0;
21 pmbaty 1662
    NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_CANNOT_AFFORD_TO_RECOVER));
1 pmbaty 1663
    DoFancyHeadup(kFancyHeadupNetworkRaceNoMoreMoney);
1664
    KnackerThisCar(&gProgram_state.current_car);
1665
    SendGameplayToHost(eNet_gameplay_suicide, 0, 0, 0, 0);
1666
    return 0;
1667
}
1668
 
1669
// IDA: void __usercall SortOutRecover(tCar_spec *pCar@<EAX>)
1670
void SortOutRecover(tCar_spec* pCar) {
1671
    int the_time;
1672
    int val;
1673
    static int old_time;
1674
    LOG_TRACE("(%p)", pCar);
1675
 
1676
    the_time = GetRaceTime() - gPalette_fade_time;
1677
    if (the_time < 0) {
1678
        gPalette_fade_time = 0;
1679
        old_time = 0;
1680
    }
1681
    if (the_time < 500) {
1682
        val = 256 - (the_time * 256) / 500;
1683
    } else {
1684
        if (old_time < 500) {
1685
            FlipUpCar(pCar);
1686
            PipeSingleSpecial(ePipe_special_fade);
1687
        }
1688
        pCar->doing_nothing_flag = 1;
1689
        val = ((the_time - 1000) * 256) / 500;
1690
        if (val >= 256) {
1691
            val = 256;
1692
            gPalette_fade_time = 0;
1693
            old_time = 0;
1694
            pCar->doing_nothing_flag = 0;
1695
        }
1696
    }
1697
    if (val <= 0) {
1698
        val = 0;
1699
    }
1700
    SetFadedPalette(val);
1701
    old_time = the_time;
1702
}
1703
 
1704
// IDA: void __usercall SetFlipUpCar(tCar_spec *pCar@<EAX>)
1705
void SetFlipUpCar(tCar_spec* pCar) {
1706
    LOG_TRACE("(%p)", pCar);
1707
 
1708
    if (gNet_mode != eNet_mode_none && pCar->driver == eDriver_local_human) {
1709
        DisableCar(pCar);
1710
        gPalette_fade_time = GetRaceTime();
1711
        NetPlayerStatusChanged(ePlayer_status_recovering);
1712
    } else {
1713
        FlipUpCar(pCar);
1714
    }
1715
}
1716
 
1717
// IDA: void __usercall FlipUpCar(tCar_spec *car@<EAX>)
1718
void FlipUpCar(tCar_spec* car) {
1719
    br_vector3 tv;
1720
    br_vector3 dir;
1721
    int new_pos;
1722
    int i;
1723
    int j;
1724
    int l;
1725
    int count;
1726
    //br_scalar dist; // Pierre-Marie Baty -- unused variable
1727
    br_material* material;
1728
    br_scalar t;
1729
    LOG_TRACE("(%p)", car);
1730
 
1731
    count = 0;
1732
    if (car->driver == eDriver_local_human && gNet_mode == eNet_mode_none) {
1733
        FadePaletteDown();
20 pmbaty 1734
        while (KeyIsDown(44)) {
1 pmbaty 1735
            ;
1736
        }
1737
    }
1738
    car->doing_nothing_flag = 0;
1739
    EnableCar(car);
1740
    new_pos = 1;
1741
    for (i = 0; i < 4; ++i) {
1742
        if (car->susp_height[i >> 1] <= car->oldd[i]) {
1743
            new_pos = 0;
1744
        }
1745
    }
1746
    do {
1747
        tv.v[0] = car->car_master_actor->t.t.mat.m[3][0] - car->last_safe_positions[0].m[3][0];
1748
        tv.v[1] = car->car_master_actor->t.t.mat.m[3][1] - car->last_safe_positions[0].m[3][1];
1749
        tv.v[2] = car->car_master_actor->t.t.mat.m[3][2] - car->last_safe_positions[0].m[3][2];
1750
        if (BrVector3LengthSquared(&tv) > 8.3015966) {
1751
            new_pos = 0;
1752
        }
1753
        BrMatrix34Copy(&car->car_master_actor->t.t.mat, &car->last_safe_positions[new_pos]);
1754
        BrMatrix34Copy(&car->oldmat, &car->last_safe_positions[new_pos]);
1755
        BrMatrix34Copy(&car->old_frame_mat, &car->oldmat);
1756
        car->oldmat.m[3][0] = car->oldmat.m[3][0] * WORLD_SCALE;
1757
        car->oldmat.m[3][1] = car->oldmat.m[3][1] * WORLD_SCALE;
1758
        car->oldmat.m[3][2] = car->oldmat.m[3][2] * WORLD_SCALE;
1759
        dir.v[0] = 0.0;
1760
        dir.v[1] = (br_scalar) 0.28985506; // Pierre-Marie Baty -- added type cast
1761
        dir.v[2] = 0.0;
1762
        FindFace(&car->car_master_actor->t.t.euler.t, &dir, &tv, &t, &material);
1763
        if (t > 1.0) {
1764
            car->car_master_actor->t.t.mat.m[3][0] += dir.v[0];
1765
            car->car_master_actor->t.t.mat.m[3][1] += dir.v[1];
1766
            car->car_master_actor->t.t.mat.m[3][2] += dir.v[2];
1767
            car->oldmat.m[3][0] = car->car_master_actor->t.t.mat.m[3][0] * WORLD_SCALE;
1768
            car->oldmat.m[3][1] = car->car_master_actor->t.t.mat.m[3][1] * WORLD_SCALE;
1769
            car->oldmat.m[3][2] = car->car_master_actor->t.t.mat.m[3][2] * WORLD_SCALE;
1770
            car->old_frame_mat.m[3][0] = car->car_master_actor->t.t.mat.m[3][0];
1771
            car->old_frame_mat.m[3][1] = car->car_master_actor->t.t.mat.m[3][1];
1772
            car->old_frame_mat.m[3][2] = car->car_master_actor->t.t.mat.m[3][2];
1773
        }
1774
        tv.v[0] = 0.0;
1775
        tv.v[1] = 0.0;
1776
        tv.v[2] = (br_scalar) -0.001; // Pierre-Marie Baty -- added type cast
1777
        BrMatrix34ApplyV(&car->v, &tv, &car->car_master_actor->t.t.mat);
1778
        car->omega.v[0] = 0.0;
1779
        car->omega.v[1] = 0.0;
1780
        car->omega.v[2] = 0.0;
1781
        car->direction.v[0] = -car->oldmat.m[2][0];
1782
        car->direction.v[1] = -car->oldmat.m[2][1];
1783
        car->direction.v[2] = -car->oldmat.m[2][2];
1784
        for (i = 0; i <= new_pos; i++) {
1785
            for (j = 0; j < 4; j++) {
1786
                BrMatrix34Copy(&car->last_safe_positions[j], &car->last_safe_positions[j + 1]);
1787
            }
1788
        }
1789
        for (l = 0; l < 10; l++) {
1790
            BrVector3Scale(&car->old_norm, &car->old_norm, 0.072463766);
1791
            BrMatrix34ApplyV(&tv, &car->old_norm, &car->car_master_actor->t.t.mat);
1792
            car->car_master_actor->t.t.mat.m[3][0] = car->car_master_actor->t.t.mat.m[3][0] + tv.v[0];
1793
            car->car_master_actor->t.t.mat.m[3][1] = car->car_master_actor->t.t.mat.m[3][1] + tv.v[1];
1794
            car->car_master_actor->t.t.mat.m[3][2] = car->car_master_actor->t.t.mat.m[3][2] + tv.v[2];
1795
            car->oldmat.m[3][0] = car->car_master_actor->t.t.mat.m[3][0] * WORLD_SCALE;
1796
            car->oldmat.m[3][1] = car->car_master_actor->t.t.mat.m[3][1] * WORLD_SCALE;
1797
            car->oldmat.m[3][2] = car->car_master_actor->t.t.mat.m[3][2] * WORLD_SCALE;
1798
            car->old_frame_mat.m[3][0] = car->car_master_actor->t.t.mat.m[3][0];
1799
            car->old_frame_mat.m[3][1] = car->car_master_actor->t.t.mat.m[3][1];
1800
            car->old_frame_mat.m[3][2] = car->car_master_actor->t.t.mat.m[3][2];
1801
            if (TestForCarInSensiblePlace(car)) {
1802
                break;
1803
            }
1804
        }
1805
        count++;
1806
    } while (l == 10 && count < 3);
1807
    car->oldmat.m[3][0] = car->car_master_actor->t.t.mat.m[3][0] * WORLD_SCALE;
1808
    car->oldmat.m[3][1] = car->car_master_actor->t.t.mat.m[3][1] * WORLD_SCALE;
1809
    car->oldmat.m[3][2] = car->car_master_actor->t.t.mat.m[3][2] * WORLD_SCALE;
1810
    car->curvature = 0.0;
1811
    for (j = 0; j < 4; ++j) {
1812
        car->oldd[j] = car->ride_height;
1813
    }
1814
    car->revs = 0.0;
1815
    car->gear = 0;
1816
    car->auto_special_volume = 0;
1817
    if (car->driver == eDriver_local_human) {
1818
        InitialiseExternalCamera();
1819
        PositionExternalCamera(car, 100u);
1820
    }
1821
}
1822
 
1823
// IDA: void __usercall GetPowerup(int pNum@<EAX>)
1824
void GetPowerup(int pNum) {
1825
    LOG_TRACE("()");
1826
 
1827
    // FIXME: remove unittest variables from dethrace
1828
    _unittest_controls_lastGetPowerup = pNum;
1829
 
1830
    GotPowerup(&gProgram_state.current_car, pNum);
1831
}
1832
 
1833
// IDA: void __usercall CheckSystemKeys(int pRacing@<EAX>)
1834
void CheckSystemKeys(int pRacing) {
1835
    tU32 start_menu_time;
1836
    //int i; // Pierre-Marie Baty -- unused variable
1837
 
1838
    start_menu_time = PDGetTotalTime();
1839
    CheckQuit();
1840
    if (!gAction_replay_mode) {
1841
        CheckLoadSave();
1842
    }
1843
    AddLostTime(PDGetTotalTime() - start_menu_time);
1844
    CheckToggles(pRacing);
1845
    if (pRacing & !gAction_replay_mode) {
1846
        CheckOtherRacingKeys();
1847
    }
1848
}
1849
 
1850
// IDA: void __cdecl CheckKevKeys()
1851
void CheckKevKeys(void) {
1852
    int i;
1853
    tU32* value;
1854
    char s[128];
1855
 
1856
    value = KevKeyService();
1857
    if (value[0] == 0) {
1858
        return;
1859
    }
1860
 
1861
    for (i = 0; gKev_keys[i].action_proc != 0; i++) {
1862
        if (gKev_keys[i].code == value[0] && gKev_keys[i].code2 == value[1]) {
1863
            break;
1864
        }
1865
    }
1866
 
1867
    if (gKev_keys[i].action_proc) {
1868
        if (gNet_mode) {
1869
            if (gKev_keys[i].num == 0xA11EE75D) {
1870
                strcpy(s, gNet_players[gThis_net_player_index].player_name);
1871
                strcat(s, " ");
1872
                strcat(s, GetMiscString(kMiscString_MANAGED_TO_CHEAT));
1873
                NetSendHeadupToEverybody(s);
1874
                gKev_keys[i].action_proc(gKev_keys[i].num);
1875
            } else {
1876
                strcpy(s, gNet_players[gThis_net_player_index].player_name);
1877
                strcat(s, " ");
1878
                strcat(s, GetMiscString(kMiscString_TRIED_TO_CHEAT));
1879
                NetSendHeadupToAllPlayers(s);
1880
            }
1881
        } else {
1882
            gKev_keys[i].action_proc(gKev_keys[i].num);
1883
        }
1884
    }
1885
}
1886
 
1887
// IDA: void __cdecl BrakeInstantly()
1888
void BrakeInstantly(void) {
1889
    int i;
1890
    LOG_TRACE("()");
1891
 
1892
    gProgram_state.current_car.revs = 0.f;
1893
    if (gProgram_state.current_car.number_of_wheels_on_ground != 0 && BrVector3LengthSquared(&gProgram_state.current_car.v) > 0.0001f) {
1894
        PratcamEvent(41);
1895
        for (i = 0; i < 5; i++) {
1896
            DRS3StartSound(gCar_outlet, 9000 + i);
1897
        }
1898
    }
1899
    BrVector3Set(&gProgram_state.current_car.v, 0.f, 0.f, 0.f);
1900
}
1901
 
1902
// IDA: void __usercall PollCarControls(tU32 pTime_difference@<EAX>)
1903
void PollCarControls(tU32 pTime_difference) {
1904
    //int decay_steering; // Pierre-Marie Baty -- unused variable
1905
    //int decay_speed; // Pierre-Marie Baty -- unused variable
1906
    //float decay_rate; // Pierre-Marie Baty -- unused variable
1907
    //tS32 joyX; // Pierre-Marie Baty -- unused variable
1908
    //tS32 joyY; // Pierre-Marie Baty -- unused variable
1909
    tCar_controls keys;
1910
    tJoystick joystick;
1911
    tCar_spec* c;
1912
    LOG_TRACE("(%d)", pTime_difference);
1913
 
1914
    c = &gProgram_state.current_car;
1915
 
1916
    memset(&keys, 0, sizeof(tCar_controls));
1917
    joystick.left = -1;
1918
    joystick.right = -1;
1919
    joystick.acc = -1;
1920
    joystick.dec = -1;
1921
    if (gEntering_message) {
1922
        memset(&c->keys, 0, sizeof(tCar_controls));
1923
        c->joystick.left = -1;
1924
        c->joystick.right = -1;
1925
        c->joystick.acc = -1;
1926
        c->joystick.dec = -1;
1927
    } else {
1928
        if (gKey_mapping[46] >= 115 || gKey_mapping[47] >= 115) {
1929
            joystick.left = gJoy_array[gKey_mapping[46] - 115];
1930
            joystick.right = gJoy_array[gKey_mapping[47] - 115];
1931
            if (joystick.left < 0 && joystick.right < 0) {
1932
                joystick.left = 0;
1933
            }
1934
        } else {
1935
            if (KeyIsDown(46)) {
1936
                keys.left = 1;
1937
            }
1938
            if (KeyIsDown(47)) {
1939
                keys.right = 1;
1940
            }
1941
        }
1942
        if (KeyIsDown(12)) {
1943
            keys.holdw = 1;
1944
        }
1945
        if (KeyIsDown(53) || gRace_finished) {
1946
            if (!gInstant_handbrake || gRace_finished) {
1947
                keys.brake = 1;
1948
            } else {
1949
                BrakeInstantly();
1950
            }
1951
        }
1952
        if (gKey_mapping[48] < 115) {
1953
            if (KeyIsDown(48) && !gRace_finished && !c->knackered && !gWait_for_it) {
1954
                keys.acc = 1;
1955
            }
1956
        } else {
1957
            joystick.acc = gJoy_array[gKey_mapping[48] - 115];
1958
            if (joystick.acc > 0xFFFF) {
1959
                joystick.acc = 0xFFFF;
1960
            }
1961
        }
1962
        if (gKey_mapping[49] < 115) {
1963
            if (KeyIsDown(49) && !gRace_finished && !c->knackered && !gWait_for_it) {
1964
                keys.dec = 1;
1965
            }
1966
        } else {
1967
            joystick.dec = gJoy_array[gKey_mapping[49] - 115];
1968
            if (joystick.dec > 0xFFFF) {
1969
                joystick.dec = 0xFFFF;
1970
            }
1971
        }
1972
        if (KeyIsDown(55) && c->gear >= 0) {
1973
            keys.change_down = 1;
1974
            c->just_changed_gear = 1;
1975
            if (keys.acc || joystick.acc > 32000) {
1976
                c->traction_control = 0;
1977
            } else if (c->gear > 1 && !c->keys.change_down) {
1978
                --c->gear;
1979
            }
1980
            if (gCountdown && !c->keys.change_down) {
1981
                JumpTheStart();
1982
            }
1983
        }
1984
        if (gCar_flying) {
1985
            if (KeyIsDown(13)) {
1986
                keys.up = 1;
1987
            }
1988
            if (KeyIsDown(11)) {
1989
                keys.down = 1;
1990
            }
1991
        }
1992
        if (KeyIsDown(58)) {
1993
            if (!gEntering_message) {
1994
                keys.horn = 1;
1995
            }
1996
        }
1997
        c->keys = keys;
1998
        c->joystick = joystick;
1999
    }
2000
}
2001
 
2002
// IDA: void __usercall PollCameraControls(tU32 pTime_difference@<EAX>)
2003
void PollCameraControls(tU32 pTime_difference) {
2004
    int flag;
2005
    int left;
2006
    int right;
2007
    int swirl_mode;
2008
    int up_and_down_mode;
2009
    int going_up;
2010
    static int last_swirl_mode = 0;
2011
    LOG_TRACE("(%d)", pTime_difference);
2012
 
2013
    flag = 0;
2014
    swirl_mode = gRace_finished && !gAction_replay_mode && (&gProgram_state.current_car == gCar_to_view || gCar_to_view->knackered);
2015
    up_and_down_mode = swirl_mode && !gCamera_has_collided;
2016
    going_up = gCamera_zoom > 1.0;
2017
    if (last_swirl_mode != swirl_mode) {
2018
        if (swirl_mode) {
2019
            SaveCameraPosition(0);
2020
        } else {
2021
            RestoreCameraPosition(0);
2022
        }
2023
        last_swirl_mode = swirl_mode;
2024
    }
2025
    if (!gMap_mode && !gProgram_state.cockpit_on && (!gAction_replay_mode || gAction_replay_camera_mode <= eAction_replay_standard)) {
2026
        if (KeyIsDown(31) || (up_and_down_mode && !going_up)) {
2027
            gCamera_zoom = (double)pTime_difference * TIME_CONV_THING / (double)(2 * swirl_mode + 1) + gCamera_zoom;
2028
            if (gCamera_zoom > 2.0f) {
2029
                gCamera_zoom = 2.0f;
2030
            }
2031
            if (up_and_down_mode && gCamera_zoom > 1.0f) {
2032
                gCamera_zoom = 1.0f;
2033
            }
2034
        }
2035
        if (KeyIsDown(30) || (up_and_down_mode && going_up)) {
2036
            gCamera_zoom = gCamera_zoom - (double)pTime_difference * TIME_CONV_THING / (double)(2 * swirl_mode + 1);
2037
            if (gCamera_zoom < 0.1) {
2038
                gCamera_zoom = (br_scalar) 0.1; // Pierre-Marie Baty -- added type cast
2039
                if (up_and_down_mode) {
2040
                    if (gCamera_zoom < 1.0f) {
2041
                        gCamera_zoom = 1.0f;
2042
                    }
2043
                }
2044
            }
2045
        }
2046
        if (swirl_mode && gProgram_state.current_car.speedo_speed < 0.001449275362318841) {
2047
            left = 1;
2048
            right = 0;
2049
        } else {
2050
            left = KeyIsDown(32);
2051
            right = KeyIsDown(33);
2052
        }
2053
 
2054
        if ((gCamera_sign ? left : right)) {
2055
            if (!gCamera_reset) {
2056
                gCamera_yaw += BrDegreeToAngle(pTime_difference * 0.05f);
2057
            }
2058
            flag = 1;
2059
        }
2060
        if ((gCamera_sign ? right : left)) {
2061
            if (!gCamera_reset) {
2062
                gCamera_yaw -= BrDegreeToAngle(pTime_difference * 0.05f);
2063
            }
2064
            if (flag) {
2065
                gCamera_yaw = 0;
2066
                gCamera_reset = 1;
2067
            }
2068
        } else if (!flag) {
2069
            gCamera_reset = 0;
2070
        }
2071
    }
2072
}
2073
 
2074
// IDA: void __usercall SetFlag2(int i@<EAX>)
2075
void SetFlag2(int i) {
2076
    LOG_TRACE("(%d)", i);
2077
 
2078
    gAllow_car_flying = 1;
2079
    ToggleFlying();
2080
    gAllow_car_flying = gCar_flying;
2081
}
2082
 
2083
// IDA: void __cdecl ToggleFlying()
2084
void ToggleFlying(void) {
2085
    LOG_TRACE("()");
2086
 
2087
    if (gAllow_car_flying && gNet_mode == eNet_mode_none) {
2088
        gCar_flying = !gCar_flying;
2089
        if (gCar_flying) {
21 pmbaty 2090
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -4, "We have lift off!!");
1 pmbaty 2091
        } else {
21 pmbaty 2092
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -4, "Back down to Earth");
1 pmbaty 2093
        }
2094
    } else {
2095
        gCar_flying = 0;
2096
    }
2097
}
2098
 
2099
// IDA: void __cdecl ToggleInvulnerability()
2100
void ToggleInvulnerability(void) {
2101
    LOG_TRACE("()");
2102
 
2103
    gProgram_state.current_car.invulnerable = !gProgram_state.current_car.invulnerable;
2104
    if (gProgram_state.current_car.invulnerable) {
21 pmbaty 2105
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_Invulnerable));
1 pmbaty 2106
    } else {
21 pmbaty 2107
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, "Vulnerability returns!");
1 pmbaty 2108
    }
2109
}
2110
 
2111
// IDA: void __cdecl MoreTime()
2112
void MoreTime(void) {
2113
    LOG_TRACE("()");
2114
 
2115
    AwardTime(30);
2116
}
2117
 
2118
// IDA: void __cdecl MuchMoreTime()
2119
void MuchMoreTime(void) {
2120
    LOG_TRACE("()");
2121
 
2122
    AwardTime(300);
2123
}
2124
 
2125
// IDA: void __cdecl ToggleTimerFreeze()
2126
void ToggleTimerFreeze(void) {
2127
    LOG_TRACE("()");
2128
 
2129
    gFreeze_timer = !gFreeze_timer;
2130
    if (gFreeze_timer) {
21 pmbaty 2131
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_TimerFrozen));
1 pmbaty 2132
    } else {
21 pmbaty 2133
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, "Timer thawed out");
1 pmbaty 2134
    }
2135
}
2136
 
2137
// IDA: void __cdecl EarnDosh()
2138
void EarnDosh(void) {
2139
    LOG_TRACE("()");
2140
 
2141
    EarnCredits(5000);
2142
}
2143
 
2144
// IDA: void __cdecl LoseDosh()
2145
void LoseDosh(void) {
2146
    LOG_TRACE("()");
2147
 
2148
    EarnCredits(-5000);
2149
}
2150
 
2151
// IDA: void __cdecl ToggleMap()
2152
void ToggleMap(void) {
2153
    static int old_indent;
2154
    static int was_in_cockpit;
2155
    LOG_TRACE("()");
2156
 
2157
    if (gMap_mode == 0) {
2158
        if (!gAction_replay_mode) {
2159
            if (gNet_mode != eNet_mode_none && gCurrent_net_game->type == eNet_game_type_foxy && gThis_net_player_index == gIt_or_fox) {
21 pmbaty 2160
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_THE_FOX_CANNOT_DO_THAT));
1 pmbaty 2161
            } else if (gNet_mode != eNet_mode_none && gCurrent_net_game->type == eNet_game_type_tag && gThis_net_player_index != gIt_or_fox) {
21 pmbaty 2162
                NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_ONLY_IT_CAN_DO_THAT));
1 pmbaty 2163
            } else {
2164
                old_indent = gRender_indent;
2165
                gRender_indent = 0;
2166
                was_in_cockpit = gProgram_state.cockpit_on;
2167
                if (gProgram_state.cockpit_on) {
2168
                    ToggleCockpit();
2169
                }
2170
                gMap_mode = PDGetTotalTime();
2171
            }
2172
        }
2173
    } else {
2174
        gMap_mode = 0;
2175
        gRender_indent = old_indent;
2176
        if (was_in_cockpit) {
2177
            ToggleCockpit();
2178
        }
2179
    }
2180
    AdjustRenderScreenSize();
2181
}
2182
 
2183
// IDA: int __cdecl HornBlowing()
2184
int HornBlowing(void) {
2185
    LOG_TRACE("()");
2186
 
2187
    return gProgram_state.current_car.keys.horn;
2188
}
2189
 
2190
// IDA: void __cdecl ToggleArrow()
2191
void ToggleArrow(void) {
2192
    static br_actor* old_actor;
2193
    LOG_TRACE("()");
2194
 
2195
    return;
2196
 
2197
    if (gArrow_mode) {
2198
        gProgram_state.current_car.car_model_actors[gProgram_state.current_car.principal_car_actor].actor = old_actor;
2199
        BrActorRemove(gArrow_actor);
2200
        BrActorAdd(gProgram_state.current_car.car_master_actor, old_actor);
2201
        gArrow_mode = 0;
2202
        if (gInfo_on) {
2203
            ToggleInfo();
2204
        }
2205
    } else {
2206
        old_actor = gProgram_state.current_car.car_model_actors[gProgram_state.current_car.principal_car_actor].actor;
2207
        BrActorRemove(old_actor);
2208
        BrActorAdd(gProgram_state.current_car.car_master_actor, gArrow_actor);
2209
        gProgram_state.current_car.car_model_actors[gProgram_state.current_car.principal_car_actor].actor = gArrow_actor;
2210
        gArrow_mode = 1;
2211
        if (!gInfo_on) {
2212
            ToggleInfo();
2213
        }
2214
    }
2215
}
2216
 
2217
// IDA: int __cdecl GetRecoverVoucherCount()
2218
int GetRecoverVoucherCount(void) {
2219
    LOG_TRACE("()");
2220
 
2221
    return gRecovery_voucher_count;
2222
}
2223
 
2224
// IDA: void __usercall AddVouchers(int pCount@<EAX>)
2225
void AddVouchers(int pCount) {
2226
    LOG_TRACE("(%d)", pCount);
2227
 
2228
    gRecovery_voucher_count += pCount;
2229
}
2230
 
2231
// IDA: void __cdecl ResetRecoveryVouchers()
2232
void ResetRecoveryVouchers(void) {
2233
    LOG_TRACE("()");
2234
 
2235
    gRecovery_voucher_count = 0;
2236
}
2237
 
2238
// IDA: void __cdecl CycleCarTexturingLevel()
2239
void CycleCarTexturingLevel(void) {
2240
    tCar_texturing_level new_level;
2241
    LOG_TRACE("()");
2242
 
2243
    new_level = (GetCarTexturingLevel() + 1) % eCTL_count;
2244
    SetCarTexturingLevel(new_level);
2245
    switch (new_level) {
2246
    case eCTL_none:
21 pmbaty 2247
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_NoCarTextures));
1 pmbaty 2248
        break;
2249
    case eCTL_transparent:
21 pmbaty 2250
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_TransparentCarTexturesOnly));
1 pmbaty 2251
        break;
2252
    case eCTL_full:
21 pmbaty 2253
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_FullCarTextures));
1 pmbaty 2254
        break;
2255
    case eCTL_count:
2256
        break;
2257
    }
2258
}
2259
 
2260
// IDA: void __cdecl CycleWallTexturingLevel()
2261
void CycleWallTexturingLevel(void) {
2262
    tWall_texturing_level new_level;
2263
    LOG_TRACE("()");
2264
 
2265
    new_level = (GetWallTexturingLevel() + 1) % eWTL_count;
2266
    ReallySetWallTexturingLevel(new_level);
2267
    SetWallTexturingLevel(new_level);
2268
    switch (new_level) {
2269
    case eWTL_none:
21 pmbaty 2270
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_NoWallTextures));
1 pmbaty 2271
        break;
2272
    case eWTL_linear:
21 pmbaty 2273
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_LinearWallTextures));
1 pmbaty 2274
        break;
2275
    case eWTL_full:
21 pmbaty 2276
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_BestWallTextures));
1 pmbaty 2277
        break;
2278
    case eWTL_count:
2279
        break;
2280
    }
2281
}
2282
 
2283
// IDA: void __cdecl CycleRoadTexturingLevel()
2284
void CycleRoadTexturingLevel(void) {
2285
    tRoad_texturing_level new_level;
2286
    LOG_TRACE("()");
2287
 
2288
    new_level = (GetRoadTexturingLevel() + 1) % 3;
2289
    ReallySetRoadTexturingLevel(new_level);
2290
    SetRoadTexturingLevel(new_level);
2291
    if (new_level == eRTL_none) {
21 pmbaty 2292
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_NoRoadTextures));
1 pmbaty 2293
    } else if (new_level == eRTL_full) {
21 pmbaty 2294
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_RoadTextures));
1 pmbaty 2295
    }
2296
}
2297
 
2298
// IDA: void __cdecl CycleYonFactor()
2299
void CycleYonFactor(void) {
2300
    br_scalar new_factor;
2301
    //char factor_str[5]; // Pierre-Marie Baty -- unused variable
2302
    LOG_TRACE("()");
2303
 
2304
    new_factor = GetYonFactor() / 2.f;
2305
    if (new_factor < .1f) {
2306
        new_factor = 1.f;
2307
    }
2308
    SetYonFactor(new_factor);
2309
    if (new_factor > .75f) {
21 pmbaty 2310
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_TrackAppearsVeryQuickly));
1 pmbaty 2311
    } else if (new_factor > .375f) {
21 pmbaty 2312
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_TrackAppearsQuiteQuickly));
1 pmbaty 2313
    } else if (new_factor > .187f) {
21 pmbaty 2314
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_TrackQppearsQuiteLate));
1 pmbaty 2315
    } else {
21 pmbaty 2316
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_TrackAppearsVeryLate));
1 pmbaty 2317
    }
2318
}
2319
 
2320
// IDA: void __usercall SetSoundDetailLevel(int pLevel@<EAX>)
2321
void SetSoundDetailLevel(int pLevel) {
2322
    LOG_TRACE("(%d)", pLevel);
2323
 
2324
    gSound_detail_level = pLevel;
2325
}
2326
 
2327
// IDA: void __usercall ReallySetSoundDetailLevel(int pLevel@<EAX>)
2328
void ReallySetSoundDetailLevel(int pLevel) {
2329
    LOG_TRACE("(%d)", pLevel);
2330
 
2331
    DRS3StopAllOutletSounds();
2332
    DisposeSoundSources();
2333
    gSound_detail_level = pLevel;
2334
    InitSound();
2335
    InitSoundSources();
2336
}
2337
 
2338
// IDA: int __cdecl GetSoundDetailLevel()
2339
int GetSoundDetailLevel(void) {
2340
    LOG_TRACE("()");
2341
 
2342
    return gSound_detail_level;
2343
}
2344
 
2345
// IDA: void __cdecl CycleSoundDetailLevel()
2346
void CycleSoundDetailLevel(void) {
2347
    int new_level;
2348
    LOG_TRACE("()");
2349
 
2350
    new_level = (gSound_detail_level + 1) % 3;
2351
    ReallySetSoundDetailLevel(new_level);
2352
    SetSoundDetailLevel(new_level);
2353
    switch (new_level) {
2354
    case 0:
21 pmbaty 2355
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_FewestSounds));
1 pmbaty 2356
        break;
2357
    case 1:
21 pmbaty 2358
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_PartialSound));
1 pmbaty 2359
        break;
2360
    case 2:
21 pmbaty 2361
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_AllSounds));
1 pmbaty 2362
        break;
2363
    }
2364
}
2365
 
2366
// IDA: void __cdecl CycleCarSimplificationLevel()
2367
void CycleCarSimplificationLevel(void) {
2368
    char* src;
2369
    char* dst;
2370
    LOG_TRACE("()");
2371
 
2372
    gCar_simplification_level = (gCar_simplification_level + 1) % 5;
2373
    src = GetMiscString(kMiscString_CarSimplificationLevel_D);
2374
    dst = BrMemAllocate(strlen(src), kMem_simp_level);
2375
    sprintf(dst, src, gCar_simplification_level);
21 pmbaty 2376
    NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, dst);
1 pmbaty 2377
    BrMemFree(dst);
2378
}
2379
 
2380
// IDA: void __cdecl ToggleAccessoryRendering()
2381
void ToggleAccessoryRendering(void) {
2382
    int on;
2383
    LOG_TRACE("()");
2384
 
2385
    if (gNet_mode == eNet_mode_none) {
2386
        on = !GetAccessoryRendering();
2387
        SetAccessoryRendering(on);
2388
        if (on) {
21 pmbaty 2389
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_AccessoriesOn));
1 pmbaty 2390
        } else {
21 pmbaty 2391
            NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_AccessoriesOff));
1 pmbaty 2392
        }
2393
    } else {
21 pmbaty 2394
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_NetGamesAlwaysAccessorized));
1 pmbaty 2395
    }
2396
}
2397
 
2398
// IDA: void __cdecl ToggleSmoke()
2399
void ToggleSmoke(void) {
2400
    int on;
2401
    LOG_TRACE("()");
2402
 
2403
    on = !GetSmokeOn();
2404
    ReallySetSmokeOn(on);
2405
    SetSmokeOn(on);
2406
    if (on) {
21 pmbaty 2407
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_SmokeOn));
1 pmbaty 2408
    } else {
21 pmbaty 2409
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -4, GetMiscString(kMiscString_SmokeOff));
1 pmbaty 2410
    }
2411
}
2412
 
2413
// IDA: void __usercall DrawSomeText2(tDR_font *pFont@<EAX>)
2414
void DrawSomeText2(tDR_font* pFont) {
2415
    int y;
2416
    int i;
2417
    char* txt[15] = {
2418
        "Cops    Show all racers on map    Show peds on map",
2419
        "Random pick-up generation    Pick-up respawn",
2420
        "Open game    Closed game",
2421
        "Grid start    Random start",
2422
        "Random races    Sequential races",
2423
        "Include opponents' cars in car choices",
2424
        "Choose cars    manually    randomly    include Big APC",
2425
        "Starting credits    0    2000    5000    10000    20000",
2426
        "Driven to Destruction",
2427
        "Car Crusher",
2428
        "Carnage Accumulator",
2429
        "Checkpoint Stampede",
2430
        "Sudden Death",
2431
        "Terminal Tag",
2432
        "Fox 'n' Hounds"
2433
    };
2434
 
2435
    ClearEntireScreen();
2436
    y = 0;
2437
    for (i = 0; i < 15; i++) {
2438
        TransDRPixelmapText(gBack_screen, 0, y, pFont, txt[i], 320);
2439
        y += pFont->height + 1;
2440
    }
2441
 
2442
    PDScreenBufferSwap(0);
2443
    PrintScreen();
2444
}
2445
 
2446
// IDA: void __cdecl DrawSomeText()
2447
void DrawSomeText(void) {
11 pmbaty 2448
    DrawSomeText2(&gFonts[kFont_ORANGHED]);
2449
    DrawSomeText2(&gFonts[kFont_BLUEHEAD]);
2450
    DrawSomeText2(&gFonts[kFont_GREENHED]);
2451
    DrawSomeText2(&gFonts[kFont_MEDIUMHD]);
2452
    DrawSomeText2(&gFonts[kFont_NEWHITE]);
2453
    DrawSomeText2(&gFonts[kFont_NEWRED]);
2454
    DrawSomeText2(&gFonts[kFont_NEWBIGGR]);
1 pmbaty 2455
}
2456
 
2457
// IDA: void __cdecl SaySorryYouLittleBastard()
2458
void SaySorryYouLittleBastard(void) {
2459
    LOG_TRACE("()");
2460
    NOT_IMPLEMENTED();
2461
}
2462
 
2463
// IDA: void __cdecl UserSendMessage()
2464
void UserSendMessage(void) {
2465
    LOG_TRACE("()");
2466
 
2467
    if (gNet_mode != eNet_mode_none && gCurrent_net_game->options.enable_text_messages) {
2468
        gEntering_message = 1;
2469
    }
2470
}
2471
 
2472
// IDA: void __cdecl EnterUserMessage()
2473
void EnterUserMessage(void) {
20 pmbaty 2474
    //static int last_key; // Pierre-Marie Baty -- unused variable
2475
    //static int about_to_die; // Pierre-Marie Baty -- unused variable
2476
    //static tU32 next_time; // Pierre-Marie Baty -- unused variable
2477
    //char* the_message; // Pierre-Marie Baty -- unused variable
2478
    //char* p; // Pierre-Marie Baty -- unused variable
2479
    //int len; // Pierre-Marie Baty -- unused variable
2480
    //int the_key; // Pierre-Marie Baty -- unused variable
2481
    //int abuse_num; // Pierre-Marie Baty -- unused variable
1 pmbaty 2482
    LOG_TRACE("()");
20 pmbaty 2483
    STUB_ONCE();
1 pmbaty 2484
}
2485
 
2486
// IDA: void __cdecl DisplayUserMessage()
2487
void DisplayUserMessage(void) {
20 pmbaty 2488
    //char* the_message; // Pierre-Marie Baty -- unused variable
2489
    //int len; // Pierre-Marie Baty -- unused variable
2490
    //tDR_font* font; // Pierre-Marie Baty -- unused variable
1 pmbaty 2491
    LOG_TRACE("()");
20 pmbaty 2492
    NOT_IMPLEMENTED();
1 pmbaty 2493
}
2494
 
2495
// IDA: void __cdecl InitAbuseomatic()
2496
void InitAbuseomatic(void) {
2497
    char path[256];
2498
    char s[256];
2499
    FILE* f;
2500
    int i;
2501
    int len;
2502
    LOG_TRACE("()");
2503
 
2504
    gString[20] = '\0';
2505
    PDBuildAppPath(path);
2506
    strcat(path, "ABUSE.TXT");
2507
    for (i = 0; i < COUNT_OF(gAbuse_text); i++) {
2508
        gAbuse_text[i] = NULL;
2509
    }
2510
    f = fopen(path, "rt");
2511
    if (f == NULL) {
2512
        return;
2513
    }
2514
    for (i = 0; i < COUNT_OF(gAbuse_text); i++) {
2515
        if (fgets(s, COUNT_OF(s) - 1, f) == NULL) {
2516
            break;
2517
        }
2518
        len = strlen(s);
2519
        if (len > 63) {
2520
            s[63] = '\0';
2521
        }
2522
        len = strlen(s);
2523
        while (len != 0 && s[len - 1] < ' ') {
2524
            s[len - 1] = '\0';
2525
            len--;
2526
        }
2527
        gAbuse_text[i] = BrMemAllocate(strlen(s) + 1, kMem_abuse_text);
2528
        strcpy(gAbuse_text[i], s);
2529
    }
2530
    fclose(f);
2531
}
2532
 
2533
// IDA: void __cdecl DisposeAbuseomatic()
2534
void DisposeAbuseomatic(void) {
2535
    int i;
2536
    LOG_TRACE("()");
2537
 
2538
    for (i = 0; i < COUNT_OF(gAbuse_text); i++) {
2539
        if (gAbuse_text[i] != NULL) {
2540
            BrMemFree(gAbuse_text[i]);
2541
        }
2542
    }
2543
}