Subversion Repositories Games.Carmageddon

Rev

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

Rev Author Line No. Line
1 pmbaty 1
#include "intrface.h"
20 pmbaty 2
#include "brender/brender.h"
1 pmbaty 3
#include "flicplay.h"
4
#include "globvars.h"
5
#include "grafdata.h"
6
#include "graphics.h"
7
#include "harness/trace.h"
8
#include "input.h"
9
#include "loading.h"
10
#include "main.h"
11
#include "pd/sys.h"
12
#include "sound.h"
13
#include <stdlib.h>
14
 
15
int gDisabled_choices[10];
16
int gCurrent_mode;
17
tU32 gStart_time;
18
int gCurrent_choice;
19
tInterface_spec* gSpec;
20
int gAlways_typing;
21
int gDisabled_count;
22
 
23
// IDA: void __cdecl SetAlwaysTyping()
24
void SetAlwaysTyping(void) {
25
    LOG_TRACE("()");
26
 
27
    gAlways_typing = 1;
28
}
29
 
30
// IDA: void __cdecl ClearAlwaysTyping()
31
void ClearAlwaysTyping(void) {
32
    LOG_TRACE("()");
33
 
34
    gAlways_typing = 0;
35
}
36
 
37
// IDA: int __usercall ChoiceDisabled@<EAX>(int pChoice@<EAX>)
38
int ChoiceDisabled(int pChoice) {
39
    int i;
40
    LOG_TRACE("(%d)", pChoice);
41
 
42
    for (i = 0; i < gDisabled_count; ++i) {
43
        if (gDisabled_choices[i] == pChoice) {
44
            return 1;
45
        }
46
    }
47
    return 0;
48
}
49
 
50
// IDA: void __cdecl ResetInterfaceTimeout()
51
void ResetInterfaceTimeout(void) {
52
    LOG_TRACE("()");
53
 
54
    gStart_time = PDGetTotalTime();
55
}
56
 
57
// IDA: void __usercall ChangeSelection(tInterface_spec *pSpec@<EAX>, int *pOld_selection@<EDX>, int *pNew_selection@<EBX>, int pMode@<ECX>, int pSkip_disabled)
58
void ChangeSelection(tInterface_spec* pSpec, int* pOld_selection, int* pNew_selection, int pMode, int pSkip_disabled) {
59
    //int i; // Pierre-Marie Baty -- unused variable
60
    LOG_TRACE("(%p, %p, %p, %d, %d)", pSpec, *pOld_selection, *pNew_selection, pMode, pSkip_disabled);
61
 
62
    if (ChoiceDisabled(*pNew_selection)) {
63
        if (!pSkip_disabled) {
64
            *pNew_selection = *pOld_selection;
65
        } else if (*pOld_selection < *pNew_selection) {
66
            do {
67
                *pNew_selection = *pNew_selection + 1;
68
                if (*pNew_selection < pSpec->move_up_min[pMode]) {
69
                    *pNew_selection = pSpec->move_up_max[pMode];
70
                }
71
                if (*pNew_selection > pSpec->move_up_max[pMode]) {
72
                    *pNew_selection = pSpec->move_up_min[pMode];
73
                }
74
            } while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection));
75
        } else {
76
            do {
77
                *pNew_selection = *pNew_selection - 1;
78
                if (*pNew_selection < pSpec->move_up_min[pMode]) {
79
                    *pNew_selection = pSpec->move_up_max[pMode];
80
                }
81
                if (*pNew_selection > pSpec->move_up_max[pMode]) {
82
                    *pNew_selection = pSpec->move_up_min[pMode];
83
                }
84
            } while (*pNew_selection != *pOld_selection && ChoiceDisabled(*pNew_selection));
85
        }
86
    }
87
 
88
    if (*pOld_selection != *pNew_selection) {
89
        if (*pOld_selection >= 0 && *pOld_selection < pSpec->number_of_button_flics) {
90
            if (pSpec->flicker_off_flics[*pOld_selection].flic_index >= 0) {
91
                AddToFlicQueue(pSpec->flicker_off_flics[*pOld_selection].flic_index,
92
                    pSpec->flicker_off_flics[*pOld_selection].x[gGraf_data_index],
93
                    pSpec->flicker_off_flics[*pOld_selection].y[gGraf_data_index], 0);
94
            }
95
        }
96
        if (*pNew_selection >= 0 && *pNew_selection < pSpec->number_of_button_flics) {
97
            if (pSpec->flicker_on_flics[*pNew_selection].flic_index >= 0) {
98
                AddToFlicQueue(pSpec->flicker_on_flics[*pNew_selection].flic_index,
99
                    pSpec->flicker_on_flics[*pNew_selection].x[gGraf_data_index],
100
                    pSpec->flicker_on_flics[*pNew_selection].y[gGraf_data_index], 0);
101
            }
102
        }
103
        *pOld_selection = *pNew_selection;
104
    }
105
}
106
 
107
// IDA: void __usercall RecopyAreas(tInterface_spec *pSpec@<EAX>, br_pixelmap **pCopy_areas@<EDX>)
108
void RecopyAreas(tInterface_spec* pSpec, br_pixelmap** pCopy_areas) {
109
    int i;
110
    LOG_TRACE8("(%p, %p)", pSpec, pCopy_areas);
111
 
112
    for (i = 0; i < pSpec->number_of_recopy_areas; i++) {
113
        BrPixelmapRectangleCopy(
114
            gBack_screen,
115
            pSpec->recopy_areas[i].left[gGraf_data_index],
116
            pSpec->recopy_areas[i].top[gGraf_data_index],
117
            pCopy_areas[i],
118
            0,
119
            0,
120
            pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index],
121
            pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index]);
122
    }
123
}
124
 
125
// IDA: void __usercall DisableChoice(int pChoice@<EAX>)
126
void DisableChoice(int pChoice) {
127
    int i;
128
    LOG_TRACE("(%d)", pChoice);
129
 
130
    for (i = 0; i < gDisabled_count; i++) {
131
        if (gDisabled_choices[i] == pChoice) {
132
            return;
133
        }
134
    }
135
    gDisabled_choices[gDisabled_count] = pChoice;
136
    gDisabled_count++;
137
}
138
 
139
// IDA: void __usercall EnableChoice(int pChoice@<EAX>)
140
void EnableChoice(int pChoice) {
141
    int i;
142
    LOG_TRACE("(%d)", pChoice);
143
 
144
    for (i = 0; i < gDisabled_count; i++) {
145
        if (gDisabled_choices[i] == pChoice) {
146
            memmove(&gDisabled_choices[i], &gDisabled_choices[i + 1], (gDisabled_count - i - 1) * sizeof(gDisabled_choices[0]));
147
            gDisabled_count--;
148
            break;
149
        }
150
    }
151
}
152
 
153
// IDA: int __usercall DoInterfaceScreen@<EAX>(tInterface_spec *pSpec@<EAX>, int pOptions@<EDX>, int pCurrent_choice@<EBX>)
154
int DoInterfaceScreen(tInterface_spec* pSpec, int pOptions, int pCurrent_choice) {
155
    tProg_status entry_status; //
156
    int x_coord;               //
157
    int y_coord;               //
158
    int mouse_in_somewhere = 0;
159
    int i; //
160
    //int key2; // Pierre-Marie Baty -- unused variable
161
    //int mouse_was_started; // Pierre-Marie Baty -- unused variable
162
    int last_choice; //
163
    int escaped;     //
164
    int timed_out;   //
165
    int go_ahead;    //
166
    //int last_mode; // Pierre-Marie Baty -- unused variable
167
    int result;  //
168
    int the_key; //
169
    int the_max;
170
    int mouse_down;     //
171
    int new_mouse_down; //
172
    int last_mouse_down = 0;
173
    int defeat_mode_change; //
174
    int selection_changed;  //
175
    char the_str[256];
176
    tU32 last_press; //
177
    //tU32 last_left_press; // Pierre-Marie Baty -- unused variable
178
    //tU32 last_right_press; // Pierre-Marie Baty -- unused variable
179
    //tU32 last_up_press; // Pierre-Marie Baty -- unused variable
180
    //tU32 last_down_press; // Pierre-Marie Baty -- unused variable
181
    br_pixelmap** copy_areas;        //
182
    br_pixelmap* old_current_splash; //
183
    //void* pixels_copy; // Pierre-Marie Baty -- unused variable
184
    //void* palette_copy; // Pierre-Marie Baty -- unused variable
185
    LOG_TRACE("(%p, %d, %d)", pSpec, pOptions, pCurrent_choice);
186
 
187
#if defined(DETHRACE_FIX_BUGS)
188
    mouse_down = 0;
189
#endif
190
    entry_status = gProgram_state.prog_status;
191
    gTyping_slot = -1;
192
    EdgeTriggerModeOn();
193
    gSpec = pSpec;
194
    gDisabled_count = 0;
195
    LoadInterfaceStuff(gProgram_state.racing);
196
    gProgram_state.dont_save_or_load = pSpec->dont_save_or_load;
197
    for (i = 0; i < pSpec->number_of_button_flics; i++) {
198
        LoadFlic(pSpec->flicker_on_flics[i].flic_index);
199
        LoadFlic(pSpec->flicker_off_flics[i].flic_index);
200
        LoadFlic(pSpec->pushed_flics[i].flic_index);
201
    }
202
 
203
    InitFlicQueue();
204
    ResetInterfaceTimeout();
205
    gCurrent_choice = pCurrent_choice;
206
    gCurrent_mode = pSpec->initial_imode;
207
    StartMouseCursor();
208
    if (pSpec->font_needed) {
209
        InitRollingLetters();
210
        LoadFont(FONT_TYPEABLE);
211
    }
212
    old_current_splash = gCurrent_splash;
213
    KillSplashScreen();
214
    if (pSpec->start_proc1 != NULL) {
215
        pSpec->start_proc1();
216
    }
217
    if (!gFaded_palette && old_current_splash == NULL && !(pOptions & 2)) {
218
        DRS3StartSound(gEffects_outlet, 3006);
219
    }
220
    if (pOptions & 1) {
221
        if (pSpec->second_opening_flic > 0) {
222
            RunFlic(pSpec->second_opening_flic);
223
        }
224
    } else if (pSpec->first_opening_flic > 0) {
225
        RunFlic(pSpec->first_opening_flic);
226
    }
227
 
228
    if (pSpec->start_proc2 != NULL) {
229
        pSpec->start_proc2();
230
    }
231
 
232
    copy_areas = NULL;
233
    if (pSpec->number_of_recopy_areas != 0) {
234
        copy_areas = BrMemAllocate(sizeof(void*) * pSpec->number_of_recopy_areas, kMem_intf_copy_areas);
235
        for (i = 0; i < pSpec->number_of_recopy_areas; i++) {
236
            copy_areas[i] = BrPixelmapAllocate(BR_MEMORY_PIXELS,
237
                ((pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index]) + 3) & ~3,
238
                pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index],
239
                NULL, 0);
240
        }
241
    }
242
 
243
    last_choice = -1;
244
    ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 0);
245
    WaitForNoKeys();
246
    for (i = 0; i < pSpec->number_of_recopy_areas; i++) {
247
        BrPixelmapRectangleCopy(copy_areas[i], 0, 0, gBack_screen, pSpec->recopy_areas[i].left[gGraf_data_index], pSpec->recopy_areas[i].top[gGraf_data_index],
248
            pSpec->recopy_areas[i].right[gGraf_data_index] - pSpec->recopy_areas[i].left[gGraf_data_index],
249
            pSpec->recopy_areas[i].bottom[gGraf_data_index] - pSpec->recopy_areas[i].top[gGraf_data_index]);
250
    }
251
 
252
    timed_out = -1; /* Not sure this is right, timed_out looks like its used as a bool? */
253
    last_choice = gCurrent_choice;
254
    last_press = -1;
255
    do {
256
        if (last_choice != gCurrent_choice) {
257
            ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1);
258
        }
259
        last_choice = gCurrent_choice;
260
        PollKeys();
261
        EdgeTriggerModeOff();
262
        the_key = PDAnyKeyDown();
263
        if (the_key != -1 && the_key != KEY_CAPSLOCK) {
264
            gMouse_in_use = 0;
265
            ResetInterfaceTimeout();
266
        }
267
        EdgeTriggerModeOn();
268
        if ((gTyping_slot < 0 || gAlways_typing) && (PDKeyDown(KEY_LEFT) || PDKeyDown(KEY_KP_4) || last_press == KEY_LEFT)) {
269
            last_press = -1;
270
            if (pSpec->move_left_delta[gCurrent_mode] != 0) {
271
                gCurrent_choice += pSpec->move_left_delta[gCurrent_mode];
272
                if (gCurrent_choice < pSpec->move_left_min[gCurrent_mode]) {
273
                    gCurrent_choice = pSpec->move_left_max[gCurrent_mode];
274
                }
275
                if (gCurrent_choice > pSpec->move_left_max[gCurrent_mode]) {
276
                    gCurrent_choice = pSpec->move_left_min[gCurrent_mode];
277
                }
278
                DRS3StartSound(gEffects_outlet, 3000);
279
            }
280
            if (pSpec->move_left_proc[gCurrent_mode] != NULL) {
281
                defeat_mode_change = (pSpec->move_left_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode);
282
            } else {
283
                defeat_mode_change = 0;
284
            }
285
            if (pSpec->move_left_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) {
286
                gCurrent_mode = pSpec->move_left_new_mode[gCurrent_mode];
287
            }
288
        }
289
        if ((gTyping_slot < 0 || gAlways_typing) && (PDKeyDown(KEY_RIGHT) || PDKeyDown(KEY_KP_6) || last_press == KEY_RIGHT)) {
290
            last_press = -1;
291
            if (pSpec->move_right_delta[gCurrent_mode] != 0) {
292
                gCurrent_choice += pSpec->move_right_delta[gCurrent_mode];
293
                if (gCurrent_choice < pSpec->move_right_min[gCurrent_mode]) {
294
                    gCurrent_choice = pSpec->move_right_max[gCurrent_mode];
295
                }
296
                if (gCurrent_choice > pSpec->move_right_max[gCurrent_mode]) {
297
                    gCurrent_choice = pSpec->move_right_min[gCurrent_mode];
298
                }
299
                DRS3StartSound(gEffects_outlet, 3000);
300
            }
301
            if (pSpec->move_right_proc[gCurrent_mode] != NULL) {
302
                defeat_mode_change = (pSpec->move_right_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode);
303
            } else {
304
                defeat_mode_change = 0;
305
            }
306
            if (pSpec->move_right_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) {
307
                gCurrent_mode = pSpec->move_right_new_mode[gCurrent_mode];
308
            }
309
        }
310
        if (PDKeyDown(KEY_UP) || PDKeyDown(KEY_KP_8) || last_press == KEY_UP) {
311
            last_press = -1;
312
            if (pSpec->move_up_delta[gCurrent_mode] != 0) {
313
                gCurrent_choice += pSpec->move_up_delta[gCurrent_mode];
314
                if (gCurrent_choice < pSpec->move_up_min[gCurrent_mode]) {
315
                    gCurrent_choice = pSpec->move_up_max[gCurrent_mode];
316
                }
317
                if (gCurrent_choice > pSpec->move_up_max[gCurrent_mode]) {
318
                    gCurrent_choice = pSpec->move_up_min[gCurrent_mode];
319
                }
320
                DRS3StartSound(gEffects_outlet, 3000);
321
            }
322
            if (pSpec->move_up_proc[gCurrent_mode] != NULL) {
323
                defeat_mode_change = (pSpec->move_up_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode);
324
            } else {
325
                defeat_mode_change = 0;
326
            }
327
            if (pSpec->move_up_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) {
328
                gCurrent_mode = pSpec->move_up_new_mode[gCurrent_mode];
329
            }
330
        }
331
        if (PDKeyDown(KEY_DOWN) || PDKeyDown(KEY_KP_2) || last_press == KEY_DOWN) {
332
            last_press = -1;
333
            if (pSpec->move_down_delta[gCurrent_mode] != 0) {
334
                gCurrent_choice += pSpec->move_down_delta[gCurrent_mode];
335
                if (gCurrent_choice < pSpec->move_down_min[gCurrent_mode]) {
336
                    gCurrent_choice = pSpec->move_down_max[gCurrent_mode];
337
                }
338
                if (gCurrent_choice > pSpec->move_down_max[gCurrent_mode]) {
339
                    gCurrent_choice = pSpec->move_down_min[gCurrent_mode];
340
                }
341
                DRS3StartSound(gEffects_outlet, 3000);
342
            }
343
            if (pSpec->move_down_proc[gCurrent_mode] != NULL) {
344
                defeat_mode_change = (pSpec->move_down_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode);
345
            } else {
346
                defeat_mode_change = 0;
347
            }
348
            if (pSpec->move_down_new_mode[gCurrent_mode] >= 0 && !defeat_mode_change) {
349
                gCurrent_mode = pSpec->move_down_new_mode[gCurrent_mode];
350
            }
351
        }
352
        if (gTyping_slot >= 0 && pSpec->typeable[gCurrent_mode] && gTyping_slot != gCurrent_choice && !gAlways_typing) {
353
            gCurrent_choice = gTyping_slot;
354
        }
355
        if (last_choice == gCurrent_choice) {
356
            selection_changed = 0;
357
        } else {
358
            ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1);
359
            selection_changed = 1;
360
        }
361
        timed_out = pSpec->time_out && ((tU32) PDGetTotalTime() >= pSpec->time_out + gStart_time); // Pierre-Marie Baty -- added type cast
362
        RemoveTransientBitmaps(1);
363
        RecopyAreas(pSpec, copy_areas);
364
        if (pSpec->font_needed) {
365
            RollLettersIn();
366
        }
367
        ServicePanelFlics(1);
368
        if (pSpec->draw_proc != NULL) {
369
            pSpec->draw_proc(gCurrent_choice, gCurrent_mode);
370
        }
371
        ProcessFlicQueue(gFrame_period);
372
        if (DoMouseCursor() || EitherMouseButtonDown()) {
373
            ResetInterfaceTimeout();
374
        }
375
        PDScreenBufferSwap(0);
376
        if (gMouse_in_use && !selection_changed) {
377
            GetMousePosition(&x_coord, &y_coord);
378
            new_mouse_down = EitherMouseButtonDown();
379
            mouse_down = new_mouse_down && !last_mouse_down;
380
            last_mouse_down = new_mouse_down;
381
 
382
            mouse_in_somewhere = 0;
383
            for (i = 0; i < pSpec->number_of_mouse_areas; i++) {
384
                if (x_coord >= pSpec->mouse_areas[i].left[gGraf_data_index]
385
                    && y_coord >= pSpec->mouse_areas[i].top[gGraf_data_index]
386
                    && x_coord <= pSpec->mouse_areas[i].right[gGraf_data_index]
387
                    && y_coord <= pSpec->mouse_areas[i].bottom[gGraf_data_index]
388
                    && (gTyping_slot < 0 || gAlways_typing || pSpec->mouse_areas[i].available_when_typing || gTyping_slot == pSpec->mouse_areas[i].new_choice)) {
389
 
390
                    if (pSpec->mouse_areas[i].new_choice >= 0 && pSpec->mouse_areas[i].new_choice != gCurrent_choice) {
391
                        gCurrent_choice = pSpec->mouse_areas[i].new_choice;
392
                        ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 0);
393
                    }
394
                    if (pSpec->mouse_areas[i].new_mode >= 0) {
395
                        gCurrent_mode = pSpec->mouse_areas[i].new_mode;
396
                    }
397
 
398
                    if (pSpec->mouse_areas[i].new_mode >= 0 || pSpec->mouse_areas[i].new_choice >= 0) {
399
                        mouse_in_somewhere = 1;
400
                    }
401
                    if (mouse_down) {
402
                        if (pSpec->mouse_areas[i].mouse_click != NULL) {
403
                            mouse_down = pSpec->mouse_areas[i].mouse_click(&gCurrent_choice, &gCurrent_mode,
404
                                x_coord - pSpec->mouse_areas[i].left[gGraf_data_index],
405
                                y_coord - pSpec->mouse_areas[i].top[gGraf_data_index]);
406
                        }
407
                    }
408
                    break;
409
                }
410
            }
411
        }
412
 
413
        if (PDKeyDown(KEY_RETURN) || PDKeyDown(KEY_KP_ENTER) || (gTyping_slot < 0 && PDKeyDown(KEY_SPACE)) || (gMouse_in_use && mouse_in_somewhere && mouse_down)) {
414
            DRS3StartSound(gEffects_outlet, 3004);
415
            go_ahead = pSpec->go_ahead_allowed[gCurrent_mode];
416
            if (pSpec->go_ahead_proc[gCurrent_mode]) {
417
                go_ahead = (pSpec->go_ahead_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode);
418
            }
419
        } else {
420
            go_ahead = 0;
421
        }
422
        if (PDKeyDown(KEY_ESCAPE)) {
423
            DRS3StartSound(gEffects_outlet, 3005);
424
            escaped = pSpec->escape_allowed[gCurrent_mode];
425
            if (pSpec->escape_proc[gCurrent_mode] != NULL) {
426
                escaped = (pSpec->escape_proc[gCurrent_mode])(&gCurrent_choice, &gCurrent_mode);
427
            }
428
        } else {
429
            escaped = 0;
430
        }
431
        if (escaped && gTyping_slot >= 0 && !gAlways_typing) {
432
            pSpec->get_original_string(0, gTyping_slot, the_str, &the_max);
433
            escaped = 0;
434
            RevertTyping(gTyping_slot, the_str);
435
            gTyping = 0;
436
            gTyping_slot = -1;
437
        }
438
        if (go_ahead) {
439
            if (gCurrent_choice >= 0 && gCurrent_choice < pSpec->number_of_button_flics) {
440
                if (pSpec->pushed_flics[gCurrent_choice].flic_index >= 0) {
441
                    AddToFlicQueue(pSpec->pushed_flics[gCurrent_choice].flic_index, pSpec->pushed_flics[gCurrent_choice].x[gGraf_data_index], pSpec->pushed_flics[gCurrent_choice].y[gGraf_data_index], 1);
442
                }
443
            }
444
            if (pSpec->typeable[gCurrent_mode]) {
445
                if (gTyping_slot >= 0 || gAlways_typing) {
446
                    KillCursor(gCurrent_choice);
447
                    RecopyAreas(pSpec, copy_areas);
448
                    RollLettersIn();
449
                    PDScreenBufferSwap(0);
450
                } else {
451
                    gTyping_slot = gCurrent_choice;
452
                    pSpec->get_original_string(1, gCurrent_choice, the_str, &the_max);
453
                    StartTyping(gTyping_slot, the_str, the_max);
454
                    go_ahead = 0;
455
                    gTyping = 1;
456
                }
457
            }
458
        } else if (gTyping_slot >= 0 && !escaped) {
459
            last_press = PDAnyKeyDown();
460
            if (last_press != -1 && (!gAlways_typing || (last_press != KEY_LEFT && last_press != KEY_RIGHT && last_press != KEY_UP && last_press != KEY_DOWN))) {
461
                if (gCurrent_choice != gTyping_slot && !gAlways_typing) {
462
                    ChangeSelection(pSpec, &gCurrent_choice, &gTyping_slot, gCurrent_mode, gAlways_typing);
463
                    for (i = 0; i < 2; i++) {
464
                        if (pSpec->typeable[i]) {
465
                            gCurrent_mode = i;
466
                            break;
467
                        }
468
                    }
469
                }
470
                TypeKey(gAlways_typing ? 0 : gCurrent_choice, last_press);
471
            }
472
        }
473
        ServiceGame();
474
        if (last_choice != gCurrent_choice) {
475
            ChangeSelection(pSpec, &last_choice, &gCurrent_choice, gCurrent_mode, 1);
476
        }
477
        if (entry_status != eProg_idling && gProgram_state.prog_status == eProg_idling) {
478
            escaped = 1;
479
        }
480
    } while ((pSpec->exit_proc == NULL || !(pSpec->exit_proc)(&gCurrent_choice, &gCurrent_mode)) && !go_ahead && !timed_out && !escaped);
481
 
482
    gTyping = 0;
483
    if (pSpec->font_needed) {
484
        EndRollingLetters();
485
        DisposeFont(FONT_TYPEABLE);
486
    }
487
    if (pSpec->number_of_recopy_areas > 0) {
488
        for (i = 0; i < pSpec->number_of_recopy_areas; i++) {
489
            BrPixelmapFree(copy_areas[i]);
490
        }
491
        BrMemFree(copy_areas);
492
    }
493
 
494
    RemoveTransientBitmaps(1);
495
    FlushFlicQueue();
496
    for (i = 0; i < pSpec->number_of_button_flics; i++) {
497
        UnlockFlic(pSpec->flicker_on_flics[i].flic_index);
498
        UnlockFlic(pSpec->flicker_off_flics[i].flic_index);
499
        UnlockFlic(pSpec->pushed_flics[i].flic_index);
500
    }
501
 
502
    if (gCurrent_choice == pSpec->escape_code) {
503
        escaped = 1;
504
        go_ahead = 0;
505
    }
506
    if (escaped) {
507
        gCurrent_choice = pSpec->escape_code;
508
    }
509
    if (pSpec->done_proc != NULL) {
510
        result = (pSpec->done_proc)(gCurrent_choice, gCurrent_mode, go_ahead, escaped, timed_out);
511
    } else {
512
        result = gCurrent_choice;
513
    }
514
    if (go_ahead) {
515
        if (pSpec->end_flic_go_ahead > 0) {
11 pmbaty 516
            DRS3StartSound(gEffects_outlet, 3007);
1 pmbaty 517
            RunFlic(pSpec->end_flic_go_ahead);
518
        } else if (pSpec->end_flic_go_ahead < 0) {
519
            FadePaletteDown();
520
        }
521
    } else if (escaped) {
522
        if (pSpec->end_flic_escaped > 0) {
11 pmbaty 523
            DRS3StartSound(gEffects_outlet, 3007);
1 pmbaty 524
            RunFlic(pSpec->end_flic_escaped);
525
        } else if (pSpec->end_flic_escaped < 0) {
526
            FadePaletteDown();
527
        }
528
    } else {
529
        if (pSpec->end_flic_otherwise > 0) {
11 pmbaty 530
            DRS3StartSound(gEffects_outlet, 3007);
1 pmbaty 531
            RunFlic(pSpec->end_flic_otherwise);
532
        } else if (pSpec->end_flic_otherwise < 0) {
533
            FadePaletteDown();
534
        }
535
    }
536
 
537
    gProgram_state.dont_save_or_load = 0;
538
    EndMouseCursor();
539
    UnlockInterfaceStuff();
540
    EdgeTriggerModeOff();
541
    return result;
542
}
543
 
544
// IDA: void __usercall ChangeSelectionTo(int pNew_choice@<EAX>, int pNew_mode@<EDX>)
545
void ChangeSelectionTo(int pNew_choice, int pNew_mode) {
546
    int last_choice;
547
    LOG_TRACE("(%d, %d)", pNew_choice, pNew_mode);
548
 
549
    last_choice = gCurrent_choice;
550
    gCurrent_choice = pNew_choice;
551
    gCurrent_mode = pNew_mode;
552
    ChangeSelection(gSpec, &last_choice, &gCurrent_choice, pNew_mode, 1);
553
}