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 "replay.h"
20 pmbaty 2
#include <brender/brender.h>
1 pmbaty 3
#include "car.h"
4
#include "controls.h"
5
#include "displays.h"
6
#include "globvars.h"
7
#include "globvrpb.h"
8
#include "grafdata.h"
9
#include "graphics.h"
10
#include "input.h"
11
#include "loading.h"
12
#include "main.h"
13
#include "netgame.h"
14
#include "oil.h"
15
#include "opponent.h"
16
#include "piping.h"
17
#include "s3/s3.h"
18
#include "sys.h"
19
#include "utility.h"
20
#include "world.h"
21
 
22
#include "harness/config.h"
23
#include "harness/os.h"
24
#include "harness/trace.h"
25
 
26
#include <stdio.h>
27
#include <stdlib.h>
28
 
29
char* gReplay_pixie_names[10] = {
30
    "REPLAY.PIX",
31
    "RBUTTONS.PIX",
32
    "REWSTART.PIX",
33
    "REW.PIX",
34
    "REVPLAY.PIX",
35
    "PAUSE.PIX",
36
    "PLAY.PIX",
37
    "FFWD.PIX",
38
    "FWDEND.PIX",
39
    "CAMERA.PIX",
40
};
41
int gSingle_frame_mode = 0;
42
tU32 gCam_change_time = 0;
43
int gSave_file = 0;
44
int gProgress_line_left[2] = { 70, 141 };
45
int gProgress_line_right[2] = { 279, 558 };
46
int gProgress_line_top[2] = { 178, 429 };
47
br_pixelmap* gReplay_pixies[10];
48
int gKey_down;
49
int gNo_cursor;
50
int gSave_frame_number;
51
int gCam_change_button_down;
52
tU32 gAction_replay_start_time;
53
tU32 gLast_replay_zappy_screen;
54
tS32 gStopped_time;
55
float gPending_replay_rate;
56
tU32 gAction_replay_end_time;
57
float gReplay_rate;
58
int gSave_bunch_ID;
59
int gPlay_direction;
60
int gPaused;
61
tAction_replay_camera_type gAction_replay_camera_mode;
62
 
63
// IDA: int __cdecl ReplayIsPaused()
64
int ReplayIsPaused(void) {
65
    LOG_TRACE8("()");
66
 
67
    return gReplay_rate == 0.f;
68
}
69
 
70
// IDA: float __cdecl GetReplayRate()
71
float GetReplayRate(void) {
72
    LOG_TRACE("()");
73
 
74
    return gReplay_rate;
75
}
76
 
77
// IDA: int __cdecl GetReplayDirection()
78
int GetReplayDirection(void) {
79
    LOG_TRACE("()");
80
 
81
    return gPlay_direction;
82
}
83
 
84
// IDA: void __cdecl StopSaving()
85
void StopSaving(void) {
86
    LOG_TRACE("()");
87
 
88
    gSave_file = 0;
89
    gPaused = 1;
90
}
91
 
92
// IDA: void __usercall ActualActionReplayHeadups(int pSpecial_zappy_bastard@<EAX>)
93
void ActualActionReplayHeadups(int pSpecial_zappy_bastard) {
94
    tU32 the_time;
95
    int x;
96
    //tU16 played_col1; // Pierre-Marie Baty -- unused variable
97
    //tU16 played_col2; // Pierre-Marie Baty -- unused variable
98
    //tU16 to_play_col1; // Pierre-Marie Baty -- unused variable
99
    //tU16 to_play_col2; // Pierre-Marie Baty -- unused variable
100
    LOG_TRACE("(%d)", pSpecial_zappy_bastard);
101
 
102
    the_time = PDGetTotalTime();
103
    if (gSave_file || PDKeyDown(KEY_SHIFT_ANY)) {
104
        return;
105
    }
106
    if ((the_time / 400) % 2) {
107
        DRMaskedStamp(gCurrent_graf_data->action_replay_R_x,
108
            gCurrent_graf_data->action_replay_R_y,
109
            gReplay_pixies[0]);
110
    }
111
    DRMaskedStamp(gCurrent_graf_data->action_replay_controls_x,
112
        gCurrent_graf_data->action_replay_controls_y,
113
        gReplay_pixies[1]);
114
    if (pSpecial_zappy_bastard < 0) {
115
        DRMaskedStamp(gCurrent_graf_data->action_replay_rew_start_x,
116
            gCurrent_graf_data->action_replay_hilite_y,
117
            gReplay_pixies[2]);
118
    } else if (pSpecial_zappy_bastard == 0) {
119
        if (gReplay_rate < -1.f) {
120
            DRMaskedStamp(gCurrent_graf_data->action_replay_rew_x,
121
                gCurrent_graf_data->action_replay_hilite_y,
122
                gReplay_pixies[3]);
123
        } else if (gReplay_rate > 1.f) {
124
            DRMaskedStamp(gCurrent_graf_data->action_replay_ffwd_x,
125
                gCurrent_graf_data->action_replay_hilite_y,
126
                gReplay_pixies[7]);
127
        } else if (gReplay_rate == 1.f) {
128
            DRMaskedStamp(gCurrent_graf_data->action_replay_play_x,
129
                gCurrent_graf_data->action_replay_hilite_y,
130
                gReplay_pixies[6]);
131
        } else if (gReplay_rate == -1.f) {
132
            DRMaskedStamp(gCurrent_graf_data->action_replay_rev_play_x,
133
                gCurrent_graf_data->action_replay_hilite_y,
134
                gReplay_pixies[4]);
135
        } else {
136
            DRMaskedStamp(gCurrent_graf_data->action_replay_pause_x,
137
                gCurrent_graf_data->action_replay_hilite_y,
138
                gReplay_pixies[5]);
139
        }
140
    } else {
141
        DRMaskedStamp(gCurrent_graf_data->action_replay_fwd_end_x,
142
            gCurrent_graf_data->action_replay_hilite_y,
143
            gReplay_pixies[8]);
144
    }
145
 
146
    x = gProgress_line_left[gGraf_data_index] + (float)(gProgress_line_right[gGraf_data_index] - gProgress_line_left[gGraf_data_index]) * (gLast_replay_frame_time - gAction_replay_start_time) / (gAction_replay_end_time - gAction_replay_start_time);
147
    if (x > gProgress_line_left[gGraf_data_index]) {
148
        BrPixelmapLine(gBack_screen,
149
            gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index],
150
            x - 1, gProgress_line_top[gGraf_data_index],
151
            2);
152
        BrPixelmapLine(gBack_screen,
153
            gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 1,
154
            x - 1, gProgress_line_top[gGraf_data_index] + 1,
155
            4);
156
        BrPixelmapLine(gBack_screen,
157
            gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2,
158
            x - 1, gProgress_line_top[gGraf_data_index] + 2,
159
            2);
160
    }
161
    if (x < gProgress_line_right[gGraf_data_index]) {
162
        BrPixelmapLine(gBack_screen,
163
            x, gProgress_line_top[gGraf_data_index],
164
            gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index],
165
            81);
166
        BrPixelmapLine(gBack_screen,
167
            x, gProgress_line_top[gGraf_data_index] + 1,
168
            gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 1,
169
            82);
170
        BrPixelmapLine(gBack_screen,
171
            x, gProgress_line_top[gGraf_data_index] + 2,
172
            gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2,
173
            81);
174
    }
175
    BrPixelmapLine(gBack_screen,
176
        gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index],
177
        gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2,
178
        2);
179
    BrPixelmapLine(gBack_screen,
180
        gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index],
181
        gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2,
182
        81);
183
    if (gCam_change_button_down) {
184
        DRMaskedStamp(gCurrent_graf_data->action_replay_camera_x,
185
            gCurrent_graf_data->action_replay_hilite_y,
186
            gReplay_pixies[9]);
187
    }
188
    if (the_time - gCam_change_time < 2000) {
189
        TransDRPixelmapText(gBack_screen,
11 pmbaty 190
            gCurrent_graf_data->action_replay_cam_text_x - DRTextWidth(&gFonts[kFont_ORANGHED], GetMiscString(gAction_replay_camera_mode ? kMiscString_PanningCamera : kMiscString_StandardCamera)),
1 pmbaty 191
            gCurrent_graf_data->action_replay_cam_text_y,
11 pmbaty 192
            &gFonts[kFont_ORANGHED],
1 pmbaty 193
            GetMiscString(gAction_replay_camera_mode ? kMiscString_PanningCamera : kMiscString_StandardCamera),
194
            2 * gCurrent_graf_data->action_replay_cam_text_x);
195
    }
196
    TurnOnPaletteConversion();
197
    DoMouseCursor();
198
    TurnOffPaletteConversion();
199
}
200
 
201
// IDA: void __cdecl DoActionReplayPostSwap()
202
void DoActionReplayPostSwap(void) {
203
    LOG_TRACE("()");
204
 
205
    RemoveTransientBitmaps(1);
206
}
207
 
208
// IDA: void __usercall DoZappyActionReplayHeadups(int pSpecial_zappy_bastard@<EAX>)
209
void DoZappyActionReplayHeadups(int pSpecial_zappy_bastard) {
210
    tU32 the_time;
211
    LOG_TRACE("(%d)", pSpecial_zappy_bastard);
212
 
213
    the_time = PDGetTotalTime();
214
    // Draw screen every 50ms (when we are going fast)
215
    if (abs(pSpecial_zappy_bastard) > 10000 && the_time - gLast_replay_zappy_screen > 50) {
216
        ActualActionReplayHeadups(pSpecial_zappy_bastard);
217
        gLast_replay_zappy_screen = the_time;
218
        PDScreenBufferSwap(0);
219
        RemoveTransientBitmaps(1);
220
    }
221
}
222
 
223
// IDA: void __cdecl DoActionReplayHeadups()
224
void DoActionReplayHeadups(void) {
225
    LOG_TRACE("()");
226
 
227
    ActualActionReplayHeadups(0);
228
}
229
 
230
// IDA: void __usercall MoveReplayBuffer(tS32 pMove_amount@<EAX>)
231
void MoveReplayBuffer(tS32 pMove_amount) {
232
    tU8* play_ptr;
233
    tU8* old_play_ptr;
234
    tU8* old_play_ptr2;
235
    int i;
236
    //int a; // Pierre-Marie Baty -- unused variable
237
    tU32 old_time;
238
    LOG_TRACE("(%d)", pMove_amount);
239
 
240
    old_play_ptr = NULL;
241
    gLast_replay_zappy_screen = 0;
242
    old_play_ptr2 = GetPipePlayPtr();
243
    play_ptr = old_play_ptr2;
244
    old_time = GetTotalTime();
245
    for (i = 0; i < abs(pMove_amount) && play_ptr != old_play_ptr; i++) {
246
        if (KeyIsDown(KEYMAP_ESCAPE)) {
247
            break;
248
        }
249
        if (SomeReplayLeft()) {
250
            PipingFrameReset();
251
        }
252
        old_play_ptr = play_ptr;
253
        if (pMove_amount >= 1) {
254
            while (!ApplyPipedSession(&play_ptr)) {
255
                DoZappyActionReplayHeadups(pMove_amount);
256
            }
257
            SetPipePlayPtr(play_ptr);
258
        } else if (pMove_amount <= -1) {
259
            while (!UndoPipedSession(&play_ptr)) {
260
                DoZappyActionReplayHeadups(pMove_amount);
261
            }
262
            SetPipePlayPtr(play_ptr);
263
        }
264
        ProcessOilSpills(gFrame_period);
265
    }
266
    if (gReplay_rate < 0.f) {
267
        CheckSound((tPipe_chunk*)old_play_ptr2, old_time, GetTotalTime());
268
    }
269
    if (old_play_ptr == play_ptr) {
270
        gReplay_rate = 0.f;
271
        gPaused = 1;
272
        StopSaving();
273
    }
274
    if (KeyIsDown(KEYMAP_ESCAPE)) {
275
        WaitForNoKeys();
276
    }
277
}
278
 
279
// IDA: void __cdecl MoveToEndOfReplay()
280
void MoveToEndOfReplay(void) {
281
    float old_replay_rate;
282
    LOG_TRACE("()");
283
 
284
    DisablePipedSounds();
285
    old_replay_rate = gReplay_rate;
286
    gReplay_rate = 100.f;
287
    MoveReplayBuffer(INT32_MAX);
288
    gReplay_rate = old_replay_rate;
289
    EnablePipedSounds();
290
}
291
 
292
// IDA: void __cdecl MoveToStartOfReplay()
293
void MoveToStartOfReplay(void) {
294
    float old_replay_rate;
295
    LOG_TRACE("()");
296
 
297
    DisablePipedSounds();
298
    old_replay_rate = gReplay_rate;
299
    gReplay_rate = -100.f;
300
    MoveReplayBuffer(-INT32_MAX);
301
    gReplay_rate = old_replay_rate;
302
    EnablePipedSounds();
303
}
304
 
305
// IDA: void __cdecl ToggleReplay()
306
void ToggleReplay(void) {
307
    LOG_TRACE("()");
308
 
309
    if (!IsActionReplayAvailable()) {
21 pmbaty 310
        NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_ACTION_REPLAY_UNAVAILABLE));
1 pmbaty 311
        return;
312
    }
313
    if (!gAction_replay_mode) {
314
        if (gMap_mode) {
315
            ToggleMap();
316
        }
317
        if (gNet_mode == eNet_mode_host) {
318
            SendGameplayToAllPlayers(eNet_gameplay_host_paused, 0, 0, 0, 0);
319
        }
320
        gReplay_rate = 1.f;
321
        gPaused = 1;
322
        gStopped_time = PDGetTotalTime();
323
        gPlay_direction = 1;
324
        gAction_replay_end_time = GetTotalTime();
325
        gLast_replay_frame_time = gAction_replay_end_time;
326
        gAction_replay_start_time = GetARStartTime();
327
        ResetPipePlayToEnd();
328
        LoadInterfaceStuff(1);
329
        StartMouseCursor();
330
        gKey_down = KEY_KP_ENTER;
331
        gPending_replay_rate = 0;
332
        gCam_change_time = PDGetTotalTime();
333
        if (!gRace_finished) {
334
            SaveCameraPosition(0);
335
        }
336
    } else {
337
        MoveToEndOfReplay();
338
        EndMouseCursor();
339
        S3SetEffects(NULL, NULL);
340
        UnlockInterfaceStuff();
341
        AddLostTime(PDGetTotalTime() - gStopped_time);
342
        if (!gRace_finished) {
343
            RestoreCameraPosition(0);
344
        }
345
        if (gNet_mode == eNet_mode_host) {
346
            SendGameplayToAllPlayers(eNet_gameplay_host_unpaused, 0, 0, 0, 0);
347
        }
348
    }
349
    gAction_replay_mode = !gAction_replay_mode;
350
    ForceRebuildActiveCarList();
351
}
352
 
353
// IDA: void __usercall ReverseSound(tS3_effect_tag pEffect_index@<EAX>, tS3_sound_tag pSound_tag@<EDX>)
354
void ReverseSound(tS3_effect_tag pEffect_index, tS3_sound_tag pSound_tag) {
355
    LOG_TRACE("(%d, %d)", pEffect_index, pSound_tag);
356
    NOT_IMPLEMENTED();
357
}
358
 
359
// IDA: int __cdecl FindUniqueFile()
360
int FindUniqueFile(void) {
361
    int index;
362
    FILE* f;
363
    tPath_name the_path;
364
    LOG_TRACE("()");
365
 
366
    for (index = 0; index < 1000; index++) {
367
        PathCat(the_path, gApplication_path, "BMPFILES");
368
        PathCat(the_path, the_path, "");
369
        sprintf(&the_path[strlen(the_path)], "%03d", index);
370
        strcat(the_path, "_0000.BMP");
371
        f = DRfopen(the_path, "rt");
372
        if (f == NULL) {
373
            return index;
374
        }
375
        fclose(f);
376
    }
377
    return 0;
378
}
379
 
380
// IDA: void __usercall PollActionReplayControls(tU32 pFrame_period@<EAX>)
381
void PollActionReplayControls(tU32 pFrame_period) {
382
    float old_replay_rate;
383
    int old_key_down;
384
    int x_coord;
385
    int y_coord;
386
    int i;
387
    tU32 real_time;
388
    static tU32 last_real_time = 0;
389
    static int psuedo_mouse_keys[8] = {
390
        KEY_KP_7,
391
        KEY_KP_4,
392
        KEY_COMMA,
393
        KEY_SPACE,
394
        KEY_PERIOD,
395
        KEY_KP_6,
396
        KEY_KP_9,
397
        KEY_KP_MULTIPLY,
398
    };
399
    static tRectangle mouse_areas[2][8] = {
400
        {
401
            {  63, 182,  92, 198, },
402
            {  93, 182, 118, 198, },
403
            { 119, 182, 144, 198, },
404
            { 145, 182, 166, 198, },
405
            { 167, 182, 192, 198, },
406
            { 193, 182, 218, 198, },
407
            { 219, 182, 244, 198, },
408
            { 245, 182, 272, 198, },
409
        },
410
        {
411
            { 126, 436, 184, 475, },
412
            { 186, 436, 236, 475, },
413
            { 238, 436, 288, 475, },
414
            { 290, 436, 332, 475, },
415
            { 334, 436, 384, 475, },
416
            { 386, 436, 436, 475, },
417
            { 438, 436, 488, 475, },
418
            { 490, 436, 544, 475, },
419
        },
420
    };
421
    LOG_TRACE("(%d)", pFrame_period);
422
 
423
    real_time = PDGetTotalTime();
424
    old_replay_rate = gReplay_rate;
425
    old_key_down = gKey_down == KEY_CAPSLOCK ? -1 : gKey_down;
426
    gKey_down = PDAnyKeyDown();
427
    if (KeyIsDown(KEYMAP_REPLAYMODE) && old_key_down == -1) {
428
        ToggleReplay();
429
        return;
430
    }
431
 
432
    if (gKey_down == -1) {
433
        if ((old_key_down == -1 || old_key_down == KEY_KP_4 || old_key_down == KEY_KP_6 || old_key_down == KEY_KP_MULTIPLY) && EitherMouseButtonDown()) {
434
            GetMousePosition(&x_coord, &y_coord);
435
            for (i = 0; i < COUNT_OF(mouse_areas[0]); i++) {
20 pmbaty 436
                if (mouse_areas[gGraf_data_index][i].left <= x_coord && mouse_areas[gGraf_data_index][i].top <= y_coord &&
437
                    mouse_areas[gGraf_data_index][i].right >= x_coord && mouse_areas[gGraf_data_index][i].bottom >= y_coord) {
1 pmbaty 438
                    gKey_down = psuedo_mouse_keys[i];
439
                    break;
440
                }
441
            }
442
        }
443
    } else {
444
        gMouse_in_use = 0;
445
    }
446
 
447
    if (gKey_down == KEY_KP_DIVIDE && old_key_down != KEY_KP_DIVIDE) {
448
        if (gSave_file) {
449
            StopSaving();
450
        } else {
451
            gSave_bunch_ID = FindUniqueFile();
452
            gSave_frame_number = 0;
453
            gSave_file = 1;
454
            gPlay_direction = 1;
455
            gPaused = 0;
456
        }
457
    }
458
 
459
    if (gKey_down == KEY_KP_MULTIPLY) {
460
        gCam_change_button_down = 1;
461
        if (old_key_down != KEY_KP_MULTIPLY) {
462
            gCam_change_time = PDGetTotalTime();
463
            if (gAction_replay_camera_mode == eAction_replay_action) {
464
                gAction_replay_camera_mode = eAction_replay_standard;
465
            } else {
466
                gAction_replay_camera_mode++;
467
            }
468
        }
469
    } else {
470
        gCam_change_button_down = 0;
471
    }
472
 
473
    if ((gKey_down == KEY_KP_5 || gKey_down == KEY_SPACE) && old_key_down == -1) {
474
        gPaused = !gPaused;
475
    } else if ((gKey_down == KEY_KP_0 || gKey_down == KEY_BACKSPACE) && old_key_down == -1) {
476
        gPlay_direction = -gPlay_direction;
477
        if (gPaused) {
478
            gPaused = 0;
479
        }
480
    }
481
 
482
    if (gKey_down == KEY_KP_1 && old_key_down == -1) {
483
        gReplay_rate = -1.f;
484
        gPlay_direction = -1;
485
        gSingle_frame_mode = 1;
486
    } else if (gKey_down == KEY_KP_3 && old_key_down == -1) {
487
        gReplay_rate = 1.f;
488
        gPlay_direction = 1;
489
        gSingle_frame_mode = 1;
490
    } else if (gKey_down == KEY_KP_4 || gKey_down == KEY_PAGEUP) {
491
        if (gReplay_rate > -1.2f) {
492
            gReplay_rate = -1.2f;
493
        }
494
        if (last_real_time != 0) {
495
            gReplay_rate -= 0.002f * (real_time - last_real_time);
496
        }
497
        if (gReplay_rate < -8.f) {
498
            gReplay_rate = -8.f;
499
        }
500
    } else if (gKey_down == KEY_KP_6 || gKey_down == KEY_PAGEDOWN) {
501
        if (gReplay_rate < 1.2f) {
502
            gReplay_rate = 1.2f;
503
        }
504
        if (last_real_time != 0) {
505
            gReplay_rate += 0.002f * (real_time - last_real_time);
506
        }
507
        if (gReplay_rate > 8.f) {
508
            gReplay_rate = 8.f;
509
        }
510
    } else if (gKey_down == KEY_COMMA) {
511
        gReplay_rate = -1.f;
512
        gPlay_direction = -1;
513
        gPaused = 0;
514
    } else if (gKey_down == KEY_PERIOD) {
515
        gReplay_rate = 1.f;
516
        gPlay_direction = 1;
517
        gPaused = 0;
518
    } else if (gPaused) {
519
        gReplay_rate = 0.f;
520
    } else {
521
        gReplay_rate = (float)gPlay_direction;
522
    }
523
 
524
    if ((gKey_down == KEY_KP_7 || gKey_down == KEY_HOME) && old_key_down == -1) {
525
        MoveToStartOfReplay();
526
        gReplay_rate = 1.f;
527
        MungeCarGraphics(gFrame_period);
528
        GrooveThoseDelics();
529
        gReplay_rate = 0.f;
530
        gPlay_direction = 1;
531
        gPaused = 1;
532
    } else if ((gKey_down == KEY_KP_9 || gKey_down == KEY_END) && old_key_down == -1) {
533
        MoveToEndOfReplay();
534
        gReplay_rate = -1.f;
535
        MungeCarGraphics(gFrame_period);
536
        GrooveThoseDelics();
537
        gReplay_rate = 0.f;
538
        gPlay_direction = -1;
539
        gPaused = 1;
540
    }
541
 
542
    if (gPending_replay_rate != 0.f) {
543
        gReplay_rate = gPending_replay_rate;
544
    }
545
    if (old_replay_rate * gReplay_rate >= 0.f) {
546
        gPending_replay_rate = 0.f;
547
    } else {
548
        gPending_replay_rate = gReplay_rate;
549
        gReplay_rate = 0.f;
550
    }
551
 
552
    if (old_replay_rate != 0.f) {
553
        gFrame_period = gFrame_period * gReplay_rate / old_replay_rate;
554
    }
555
    last_real_time = fabsf(gReplay_rate) >= 1.2f ? real_time : 0;
556
 
557
    if (old_replay_rate <= 0.f && gReplay_rate > 0.f) {
558
        S3SetEffects(NULL, NULL);
559
    } else if (old_replay_rate >= 0.f && gReplay_rate < 0.f) {
560
        S3SetEffects(ReverseSound, ReverseSound);
561
    }
562
}
563
 
564
// IDA: void __cdecl CheckReplayTurnOn()
565
void CheckReplayTurnOn(void) {
566
    LOG_TRACE("()");
567
 
568
    if (!gAction_replay_mode) {
569
        if (!KeyIsDown(KEYMAP_REPLAYMODE) || gEntering_message) {
570
            gKey_down = -1;
571
        } else if (gKey_down == -1) {
572
            ToggleReplay();
573
        }
574
    }
575
}
576
 
577
// IDA: void __cdecl InitializeActionReplay()
578
void InitializeActionReplay(void) {
579
    int i;
580
    LOG_TRACE("()");
581
 
582
    for (i = 0; i < COUNT_OF(gReplay_pixie_names); i++) {
583
        gReplay_pixies[i] = LoadPixelmap(gReplay_pixie_names[i]);
584
    }
585
    gAction_replay_camera_mode = eAction_replay_action;
586
}
587
 
588
// IDA: void __usercall DoActionReplay(tU32 pFrame_period@<EAX>)
589
void DoActionReplay(tU32 pFrame_period) {
590
    LOG_TRACE("(%d)", pFrame_period);
591
 
592
    if (gReplay_rate != 0.f) {
593
        MoveReplayBuffer((tS32)gReplay_rate);
594
    }
595
}
596
 
597
// IDA: void __cdecl SynchronizeActionReplay()
598
void SynchronizeActionReplay(void) {
599
    FILE* f;
600
    tPath_name the_path;
601
    static tU32 gLast_synch_time;
602
    LOG_TRACE("()");
603
 
604
    while (gReplay_rate != 0.f) {
605
        if (PDGetTotalTime() - gLast_synch_time >= gFrame_period / fabsf(gReplay_rate)) {
606
            break;
607
        }
608
        ServiceGameInRace();
609
    }
610
    gLast_synch_time = PDGetTotalTime();
611
    if (gSingle_frame_mode) {
612
        gReplay_rate = 0.f;
613
        gSingle_frame_mode = 0;
614
    }
615
 
616
    if (gSave_file) {
617
        PathCat(the_path, gApplication_path, "BMPFILES");
618
        strcat(the_path, gDir_separator);
619
        sprintf(&the_path[strlen(the_path)], "%03d_%04d.BMP", gSave_bunch_ID, gSave_frame_number);
620
        f = DRfopen(the_path, "wb");
621
        if (f != NULL) {
622
            PrintScreenFile(f);
623
            fclose(f);
624
        }
625
        gSave_frame_number++;
626
    }
627
}