Subversion Repositories Games.Carmageddon

Rev

Rev 11 | Rev 20 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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