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 "input.h"
2
 
20 pmbaty 3
#include "brender/brender.h"
1 pmbaty 4
#include "errors.h"
5
#include "globvars.h"
6
#include "grafdata.h"
7
#include "graphics.h"
8
#include "harness/hooks.h"
9
#include "harness/trace.h"
10
#include "pd/sys.h"
11
#include "utility.h"
12
#include <stdlib.h>
13
 
14
int gEdge_trigger_mode;
15
tU32 gLast_poll_keys;
16
int gInsert_mode;
17
int gGo_ahead_keys[3] = { 51, 52, 106 }; // enter, return, space
18
tJoy_array gJoy_array;
19
tKey_array gKey_array;
20
int gKey_poll_counter;
21
tRolling_letter* gRolling_letters;
22
int gCurrent_cursor;
23
int gCurrent_position;
24
int gLetter_x_coords[15];
25
int gVisible_length;
26
int gLetter_y_coords[15];
27
int gThe_key;
28
tU32 gLast_key_down_time;
29
int gThe_length;
30
tU32 gLast_roll;
31
int gLast_key_down;
32
int gKey_mapping[67];
33
char gCurrent_typing[110];
34
 
35
#define NBR_ROLLING_LETTERS 500
36
 
37
// IDA: void __usercall SetJoystickArrays(int *pKeys@<EAX>, int pMark@<EDX>)
38
void SetJoystickArrays(int* pKeys, int pMark) {
39
    //int i; // Pierre-Marie Baty -- unused variable
40
    //tS32 joyX; // Pierre-Marie Baty -- unused variable
41
    //tS32 joyY; // Pierre-Marie Baty -- unused variable
42
    //static tS32 old_joy1X; // Pierre-Marie Baty -- unused variable
43
    //static tS32 old_joy1Y; // Pierre-Marie Baty -- unused variable
44
    //static tS32 old_joy2X; // Pierre-Marie Baty -- unused variable
45
    //static tS32 old_joy2Y; // Pierre-Marie Baty -- unused variable
46
}
47
 
48
// IDA: void __cdecl PollKeys()
49
void PollKeys(void) {
50
 
51
    gKey_poll_counter++;
52
    PDSetKeyArray(gKey_array, gKey_poll_counter);
53
    SetJoystickArrays(gKey_array, gKey_poll_counter);
54
    gLast_poll_keys = PDGetTotalTime();
55
}
56
 
57
// IDA: void __cdecl CyclePollKeys()
58
void CyclePollKeys(void) {
59
    int i;
60
    for (i = 0; i < COUNT_OF(gKey_array); i++) {
61
        if (gKey_array[i] > gKey_poll_counter) {
62
            gKey_array[i] = 0;
63
            if (i > 115) {
64
                gJoy_array[i - 115] = -1; // yes this is a little weird I know...
65
            }
66
        }
67
    }
68
    gKey_poll_counter = 0;
69
}
70
 
71
// IDA: void __cdecl ResetPollKeys()
72
void ResetPollKeys(void) {
73
    int i;
74
    for (i = 0; i < COUNT_OF(gKey_array); i++) {
75
        gKey_array[i] = 0;
76
    }
77
    for (i = 0; i < COUNT_OF(gJoy_array); i++) {
78
        gJoy_array[i] = -1;
79
    }
80
}
81
 
82
// IDA: void __cdecl CheckKeysForMouldiness()
83
void CheckKeysForMouldiness(void) {
84
    LOG_TRACE9("()");
85
 
86
    if (PDGetTotalTime() - gLast_poll_keys > 500) {
87
        ResetPollKeys();
88
        CyclePollKeys();
89
        PollKeys();
90
    }
91
}
92
 
93
// IDA: int __cdecl EitherMouseButtonDown()
94
int EitherMouseButtonDown(void) {
95
    int but_1;
96
    int but_2;
97
 
98
    PDMouseButtons(&but_1, &but_2);
99
    return but_1 || but_2;
100
}
101
 
102
// IDA: tKey_down_result __usercall PDKeyDown2@<EAX>(int pKey_index@<EAX>)
103
tKey_down_result PDKeyDown2(int pKey_index) {
104
    tU32 the_time;
105
 
106
    CheckKeysForMouldiness();
107
    if (!gEdge_trigger_mode) {
108
        return gKey_array[pKey_index];
109
    }
110
    the_time = PDGetTotalTime();
111
    if (gKey_array[pKey_index]) {
112
        if (gLast_key_down == pKey_index) {
113
            if (the_time - gLast_key_down_time < 300) {
114
                return tKey_down_still;
115
            } else {
116
                gLast_key_down_time = the_time;
117
                return tKey_down_repeat;
118
            }
119
        } else {
120
            gLast_key_down_time = the_time;
121
            gLast_key_down = pKey_index;
122
            return tKey_down_yes;
123
        }
124
    }
125
    if (gLast_key_down == pKey_index) {
126
        gLast_key_down_time = 0;
127
        gLast_key_down = -1;
128
    }
129
    return tKey_down_no;
130
}
131
 
132
// IDA: int __usercall PDKeyDown@<EAX>(int pKey_index@<EAX>)
133
int PDKeyDown(int pKey_index) {
134
    tKey_down_result result;
135
 
136
    result = PDKeyDown2(pKey_index);
137
    if (!gEdge_trigger_mode || pKey_index <= 10) {
138
        return result != tKey_down_no;
139
    }
140
    return result == tKey_down_yes || result == tKey_down_repeat;
141
}
142
 
143
// IDA: int __usercall PDKeyDown3@<EAX>(int pKey_index@<EAX>)
144
int PDKeyDown3(int pKey_index) {
145
    int last_key_down_time;
146
    int last_key_down;
147
    tKey_down_result result;
148
    LOG_TRACE("(%d)", pKey_index);
149
 
150
    last_key_down = gLast_key_down;
151
    last_key_down_time = gLast_key_down_time;
152
    result = PDKeyDown2(pKey_index);
153
    gLast_key_down_time = last_key_down_time;
154
    gLast_key_down = last_key_down;
155
    return result == tKey_down_yes || result == tKey_down_repeat;
156
}
157
 
158
// IDA: int __cdecl PDAnyKeyDown()
159
int PDAnyKeyDown(void) {
160
    int i;
161
    tKey_down_result result;
162
 
163
    CheckKeysForMouldiness();
164
    for (i = COUNT_OF(gKey_array) - 1; i >= 0; --i) {
165
        if (gKey_array[i]) {
166
            if (!gEdge_trigger_mode) {
167
                return i;
168
            }
169
            result = PDKeyDown2(i);
170
            switch (result) {
171
            case tKey_down_no:
172
            case tKey_down_still:
173
                return -1;
174
            case tKey_down_yes:
175
            case tKey_down_repeat:
176
                return i;
177
            }
178
        }
179
    }
180
    if (gEdge_trigger_mode) {
181
        gLast_key_down_time = 0;
182
        gLast_key_down = -1;
183
    }
184
    return -1;
185
}
186
 
187
// IDA: int __cdecl AnyKeyDown()
188
int AnyKeyDown(void) {
189
    int the_key;
190
 
191
    the_key = PDAnyKeyDown();
192
    if ((the_key != -1 && the_key != 4) || EitherMouseButtonDown() != 0) {
193
        return 1;
194
    }
195
    return 0;
196
}
197
 
198
// IDA: tU32* __cdecl KevKeyService()
199
tU32* KevKeyService(void) {
200
    static tU32 sum = 0;
201
    static tU32 code = 0;
202
    static tU32 code2 = 0;
203
    static int last_key = -1;
204
    static int last_single_key = -1;
205
    static tU32 last_time = 0;
206
    static tU32 return_val[2];
207
    tU32 keys;
208
 
209
    keys = gKeys_pressed;
210
    // printf("key: %d, %lx, %lx\n", sizeof(long), keys, code2);
211
    return_val[0] = 0;
212
    return_val[1] = 0;
213
 
214
    if (keys < 0x6B) {
215
        last_single_key = gKeys_pressed;
216
    } else {
217
        if (keys > 0x6b00) {
218
            sum = 0;
219
            code = 0;
220
            return return_val;
221
        }
222
        if ((keys & 0xff) != last_single_key && keys >> 8 != last_single_key) {
223
            sum = 0;
224
            code = 0;
225
            return return_val;
226
        }
227
        if (keys >> 8 != last_single_key) {
228
            sum = 0;
229
            code = 0;
230
            return return_val;
231
        }
232
        if ((keys & 0xff) == last_single_key) {
233
            keys = keys >> 8;
234
        }
235
        keys = keys & 0xff;
236
    }
237
 
238
    if (keys && keys != last_key) {
239
        sum += keys;
240
        code += keys << 11;
241
        code = (code >> 17) + (code << 4);
242
        code2 = (code2 >> 29) + keys * keys + (code2 << 3);
243
        // printf("accumulate: keys=%lx, sum=%lx, code=%lx, code2=%lx\n", keys, sum, code, code2);
244
        last_time = PDGetTotalTime();
245
    } else if ((tU32) PDGetTotalTime() > (last_time + 1000)) { // Pierre-Marie Baty -- added type cast
246
        return_val[0] = ((code >> 11) + (sum << 21));
247
        return_val[1] = code2;
248
        // printf("final value: code=%lx, code2=%lx\n", return_val[0], return_val[1]);
249
        code = 0;
250
        code2 = 0;
251
        sum = 0;
252
    }
253
    last_key = keys;
254
    return return_val;
255
}
256
 
257
// IDA: int __usercall OldKeyIsDown@<EAX>(int pKey_index@<EAX>)
258
int OldKeyIsDown(int pKey_index) {
259
    int i;
260
    LOG_TRACE("(%d)", pKey_index);
261
 
262
    switch (pKey_index) {
263
    case -2:
264
        return 1;
265
    case -1:
266
        for (i = 0; i < COUNT_OF(gGo_ahead_keys); i++) {
267
            if (PDKeyDown(gGo_ahead_keys[i]) != 0) {
268
                return 1;
269
            }
270
        }
271
        return 0;
272
    default:
273
        return PDKeyDown(gKey_mapping[pKey_index]);
274
    }
275
}
276
 
277
// IDA: int __usercall KeyIsDown@<EAX>(int pKey_index@<EAX>)
278
int KeyIsDown(int pKey_index) {
279
    int i;
280
 
281
    CheckKeysForMouldiness();
282
    switch (pKey_index) {
283
    case -2:
284
        return 1;
285
    case -1:
286
        for (i = 0; i < COUNT_OF(gGo_ahead_keys); i++) {
287
            if (gKey_array[gGo_ahead_keys[i]]) {
288
                return 1;
289
            }
290
        }
291
        return 0;
292
    default:
293
        return gKey_array[gKey_mapping[pKey_index]];
294
    }
295
}
296
 
297
// IDA: void __cdecl WaitForNoKeys()
298
void WaitForNoKeys(void) {
299
    LOG_TRACE("()");
300
 
301
    while (AnyKeyDown() || EitherMouseButtonDown()) {
302
        CheckQuit();
303
    }
304
    CheckQuit();
305
}
306
 
307
// IDA: void __cdecl WaitForAKey()
308
void WaitForAKey(void) {
309
    LOG_TRACE("()");
310
 
311
    while (1) {
312
        CheckQuit();
313
        if (AnyKeyDown()) {
314
            break;
315
        }
316
        if (EitherMouseButtonDown()) {
317
            break;
318
        }
319
    }
320
    CheckQuit();
321
    WaitForNoKeys();
322
}
323
 
324
// IDA: int __usercall CmdKeyDown@<EAX>(int pFKey_ID@<EAX>, int pCmd_key_ID@<EDX>)
325
int CmdKeyDown(int pFKey_ID, int pCmd_key_ID) {
326
    return KeyIsDown(pFKey_ID) || (KeyIsDown(KEYMAP_CONTROL_ANY) && KeyIsDown(pCmd_key_ID));
327
}
328
 
329
// IDA: void __usercall GetMousePosition(int *pX_coord@<EAX>, int *pY_coord@<EDX>)
330
void GetMousePosition(int* pX_coord, int* pY_coord) {
331
    //int x_left_margin; // Pierre-Marie Baty -- unused variable
332
    //int x_right_margin; // Pierre-Marie Baty -- unused variable
333
    //int y_top_margin; // Pierre-Marie Baty -- unused variable
334
    //int y_bottom_margin; // Pierre-Marie Baty -- unused variable
335
    LOG_TRACE("(%p, %p)", pX_coord, pY_coord);
336
 
337
    PDGetMousePosition(pX_coord, pY_coord);
338
    if (*pX_coord < 0) {
339
        *pX_coord = 0;
340
    } else if (gGraf_specs[gGraf_spec_index].total_width < *pX_coord) {
341
        *pX_coord = gGraf_specs[gGraf_spec_index].total_width;
342
    }
343
    if (*pY_coord < 0) {
344
        *pY_coord = 0;
345
    } else if (gGraf_specs[gGraf_spec_index].total_height < *pY_coord) {
346
        *pY_coord = gGraf_specs[gGraf_spec_index].total_height;
347
    }
348
}
349
 
350
// IDA: void __cdecl InitRollingLetters()
351
void InitRollingLetters(void) {
352
    int i;
353
    LOG_TRACE("()");
354
 
355
    gLast_roll = 0;
356
    gCurrent_cursor = -1;
357
    gRolling_letters = BrMemAllocate(NBR_ROLLING_LETTERS * sizeof(tRolling_letter), kMem_rolling_letters);
358
    for (i = 0; i < NBR_ROLLING_LETTERS; i++) {
359
        gRolling_letters[i].number_of_letters = -1;
360
    }
361
}
362
 
363
// IDA: void __cdecl EndRollingLetters()
364
void EndRollingLetters(void) {
365
    LOG_TRACE("()");
366
 
367
    BrMemFree(gRolling_letters);
368
}
369
 
370
// IDA: int __usercall AddRollingLetter@<EAX>(char pChar@<EAX>, int pX@<EDX>, int pY@<EBX>, tRolling_type rolling_type@<ECX>)
371
int AddRollingLetter(char pChar, int pX, int pY, tRolling_type rolling_type) {
372
    tRolling_letter* let;
373
    int i;
374
    //int number_of_letters; // Pierre-Marie Baty -- unused variable
375
    LOG_TRACE("(%d, %d, %d, %d)", pChar, pX, pY, rolling_type);
376
 
377
    let = &gRolling_letters[0];
378
    for (i = 0; i < NBR_ROLLING_LETTERS; i++) {
379
        let = &gRolling_letters[i];
380
        if (let->number_of_letters < 0) {
381
            break;
382
        }
383
    }
384
    if (i == NBR_ROLLING_LETTERS) {
385
        LOG_WARN("no rolling slot available");
386
        return -1;
387
    }
388
    let->x_coord = pX;
389
    let->y_coord = pY;
390
    let->rolling_type = rolling_type;
391
    switch (rolling_type) {
392
    case eRT_looping_random:
393
        let->number_of_letters = 9;
394
        break;
395
    case eRT_looping_single:
396
        let->number_of_letters = 2;
397
        break;
398
    default:
399
        let->number_of_letters = IRandomBetween(3, 9);
400
        break;
401
    }
402
 
403
    let->current_offset = (gCurrent_graf_data->save_slot_letter_height * let->number_of_letters);
404
    for (i = 0; i < let->number_of_letters; i++) {
405
        if (rolling_type == eRT_numeric) {
406
            /* The (tU8) cast makes sure extended ASCII is positive. */
407
            let->letters[i] = (tU8)pChar;
408
        } else {
409
            let->letters[i] = IRandomBetween('A', 'Z' + 1);
410
        }
411
    }
412
    if (rolling_type != eRT_looping_random) {
413
        /* The (tU8) cast makes sure extended ASCII is positive. */
414
        let->letters[0] = (tU8)pChar;
415
    }
416
 
417
    return 0;
418
}
419
 
420
// IDA: void __usercall AddRollingString(char *pStr@<EAX>, int pX@<EDX>, int pY@<EBX>, tRolling_type rolling_type@<ECX>)
421
void AddRollingString(char* pStr, int pX, int pY, tRolling_type rolling_type) {
422
    size_t i; // Pierre-Marie Baty -- fixed type
423
    LOG_TRACE("(\"%s\", %d, %d, %d)", pStr, pX, pY, rolling_type);
424
 
425
    for (i = 0; i < strlen(pStr); i++) {
426
        AddRollingLetter(pStr[i], pX, pY, rolling_type);
427
        pX += gCurrent_graf_data->rolling_letter_x_pitch;
428
    }
429
}
430
 
431
// IDA: void __usercall AddRollingNumber(tU32 pNumber@<EAX>, int pWidth@<EDX>, int pX@<EBX>, int pY@<ECX>)
432
void AddRollingNumber(tU32 pNumber, int pWidth, int pX, int pY) {
433
    char the_string[32];
434
    LOG_TRACE("(%d, %d, %d, %d)", pNumber, pWidth, pX, pY);
435
 
436
    sprintf(the_string, VARLZEROINT, pWidth, pNumber);
437
    AddRollingString(the_string, pX, pY, eRT_numeric);
438
}
439
 
440
// IDA: void __cdecl RollLettersIn()
441
void RollLettersIn(void) {
442
    tU32 new_time;
443
    tU32 period;
444
    tRolling_letter* let;
445
    int i;
446
    int j;
447
    int k;
448
    int offset;
449
    int which_letter;
450
    int font_width;
451
    int letter_offset;
452
    int font_height;
453
    int the_row_bytes;
454
    tU8* char_ptr;
455
    tU8* saved_char_ptr;
456
    tU8* source_ptr;
457
    tU8 the_byte;
458
    LOG_TRACE9("()");
459
 
460
    new_time = PDGetTotalTime();
461
    if (gLast_roll) {
462
        period = new_time - gLast_roll;
463
    } else {
464
        period = 0;
465
    }
466
    font_height = gFonts[FONT_TYPEABLE].height;
467
    font_width = gFonts[FONT_TYPEABLE].width;
468
    the_row_bytes = gFonts[FONT_TYPEABLE].images->row_bytes;
469
 
470
    for (i = 0; i < NBR_ROLLING_LETTERS; i++) {
471
        let = &gRolling_letters[i];
472
        if (let->number_of_letters >= 0) {
473
            char_ptr = gBack_screen->pixels;
474
            char_ptr += let->y_coord * gBack_screen->row_bytes + let->x_coord;
475
            if (let->current_offset > 0.0f) {
476
                let->current_offset -= period * 0.18f;
477
                if (let->current_offset <= 0.0f) {
478
                    if (let->rolling_type == eRT_looping_random || let->rolling_type == eRT_looping_single) {
479
                        let->current_offset = (gCurrent_graf_data->save_slot_letter_height * let->number_of_letters) + let->current_offset;
480
                    } else {
481
                        let->current_offset = 0.0f;
482
                    }
483
                }
484
            }
485
            for (j = 0; j < gCurrent_graf_data->save_slot_height; j++) {
486
                offset = gCurrent_graf_data->save_slot_table[j] + let->current_offset;
487
                which_letter = offset / gCurrent_graf_data->save_slot_letter_height;
488
                letter_offset = offset % gCurrent_graf_data->save_slot_letter_height - (gCurrent_graf_data->save_slot_letter_height - font_height) / 2;
489
                saved_char_ptr = char_ptr;
490
                if (which_letter < let->number_of_letters && which_letter >= 0 && letter_offset >= 0 && letter_offset < font_height) {
491
 
492
                    // LOG_DEBUG("chars %d, %d, %d, %d", let->letters[0], let->letters[1], let->letters[2], let->letters[3]);
493
                    source_ptr = (tU8*)gFonts[FONT_TYPEABLE].images->pixels + (font_height * (let->letters[which_letter] - ' ') + letter_offset) * the_row_bytes;
494
                    for (k = 0; k < font_width; k++) {
495
                        the_byte = *source_ptr;
496
                        if (the_byte) {
497
                            *char_ptr = the_byte;
498
                        }
499
                        char_ptr++;
500
                        source_ptr++;
501
                    }
502
                }
503
                char_ptr = saved_char_ptr + gBack_screen->row_bytes;
504
            }
505
        }
506
    }
507
    gLast_roll = new_time;
508
}
509
 
510
// IDA: int __usercall ChangeCharTo@<EAX>(int pSlot_index@<EAX>, int pChar_index@<EDX>, char pNew_char@<EBX>)
511
int ChangeCharTo(int pSlot_index, int pChar_index, char pNew_char) {
512
    int x_coord;
513
    int y_coord;
514
    int i;
515
    //int j; // Pierre-Marie Baty -- unused variable
516
    tRolling_letter* let;
517
    tRolling_type new_type;
518
    LOG_TRACE("(%d, %d, %d)", pSlot_index, pChar_index, pNew_char);
519
 
520
    if (pChar_index >= gVisible_length || pChar_index < 0) {
521
        return -1;
522
    }
523
    y_coord = gLetter_y_coords[pSlot_index];
524
    x_coord = gCurrent_graf_data->rolling_letter_x_pitch * pChar_index + gLetter_x_coords[pSlot_index];
525
 
526
    if (pNew_char == ROLLING_LETTER_LOOP_RANDOM) {
527
        new_type = eRT_looping_random;
528
    } else if (pNew_char >= '0' && pNew_char <= '9') {
529
        new_type = eRT_numeric;
530
    } else {
531
        new_type = eRT_alpha;
532
    }
533
 
534
    for (i = 0; i < NBR_ROLLING_LETTERS; i++) {
535
        let = &gRolling_letters[i];
536
        if (let->number_of_letters >= 0 && x_coord == let->x_coord && y_coord == let->y_coord) {
537
            break;
538
        }
539
    }
540
    if (i >= NBR_ROLLING_LETTERS) {
541
        return AddRollingLetter(pNew_char, x_coord, y_coord, new_type);
542
    }
543
    if (pNew_char != ROLLING_LETTER_LOOP_RANDOM) {
544
        /* The (tU8) cast makes sure extended ASCII is positive. */
545
        let->letters[0] = (tU8)pNew_char;
546
    }
547
    if (pNew_char == ' ') {
548
        let->letters[0] = ' ';
549
    }
550
    let->rolling_type = new_type;
551
    let->current_offset = gCurrent_graf_data->save_slot_letter_height * let->number_of_letters;
552
    return i;
553
}
554
 
555
// IDA: void __usercall ChangeTextTo(int pXcoord@<EAX>, int pYcoord@<EDX>, char *pNew_str@<EBX>, char *pOld_str@<ECX>)
556
void ChangeTextTo(int pXcoord, int pYcoord, char* pNew_str, char* pOld_str) {
557
    int x_coord;
558
    int i;
559
    int len;
560
    int len2;
561
    int j;
562
    tRolling_letter* let;
563
    tRolling_type new_type;
564
    char new_char;
565
    LOG_TRACE("(%d, %d, \"%s\", \"%s\")", pXcoord, pYcoord, pNew_str, pOld_str);
566
 
567
    len = strlen(pOld_str);
568
    len2 = strlen(pNew_str);
569
#if defined(DETHRACE_FIX_BUGS)
570
    new_type = eRT_looping_random;
571
#endif
572
 
573
    for (i = 0; i < len; i++) {
574
        if (i < len2) {
575
            new_char = pNew_str[i];
576
        } else {
577
            new_char = ' ';
578
        }
579
        if (new_char == ROLLING_LETTER_LOOP_RANDOM) {
580
            new_type = eRT_looping_random;
581
        } else if (new_char >= '0' && new_char <= '9') {
582
            new_type = eRT_numeric;
583
        } else {
584
            new_type = eRT_alpha;
585
        }
586
        x_coord = gCurrent_graf_data->rolling_letter_x_pitch * i + pXcoord;
587
        for (j = 0, let = gRolling_letters; j < NBR_ROLLING_LETTERS; j++, let++) {
588
            if (let->number_of_letters >= 0 && let->x_coord == x_coord && let->y_coord == pYcoord) {
589
                if (new_char != ROLLING_LETTER_LOOP_RANDOM) {
590
                    let->letters[0] = new_char;
591
                }
592
                if (new_char == ' ') {
593
                    let->letters[0] = ' ';
594
                }
595
                let->current_offset = let->number_of_letters * gCurrent_graf_data->save_slot_letter_height;
596
                let->rolling_type = new_type;
597
            }
598
        }
599
    }
600
    for (i = len; i < len2; i++) {
601
        AddRollingLetter(pNew_str[i], gCurrent_graf_data->rolling_letter_x_pitch * i + pXcoord, pYcoord, new_type);
602
    }
603
}
604
 
605
// IDA: void __usercall SetRollingCursor(int pSlot_index@<EAX>)
606
void SetRollingCursor(int pSlot_index) {
607
    LOG_TRACE("(%d)", pSlot_index);
608
 
609
    gCurrent_cursor = ChangeCharTo(pSlot_index, gCurrent_position, ROLLING_LETTER_LOOP_RANDOM);
610
}
611
 
612
// IDA: void __usercall BlankSlot(int pIndex@<EAX>, int pName_length@<EDX>, int pVisible_length@<EBX>)
613
void BlankSlot(int pIndex, int pName_length, int pVisible_length) {
614
    int i;
615
    LOG_TRACE("(%d, %d, %d)", pIndex, pName_length, pVisible_length);
616
 
617
    gVisible_length = pVisible_length;
618
    for (i = 0; i < pName_length; i++) {
619
        ChangeCharTo(pIndex, i, ' ');
620
    }
621
}
622
 
623
// IDA: void __usercall DoRLBackspace(int pSlot_index@<EAX>)
624
void DoRLBackspace(int pSlot_index) {
625
    int i;
626
    int new_len;
627
    LOG_TRACE("(%d)", pSlot_index);
628
 
629
    if (gCurrent_position != 0) {
630
        if (strlen(gCurrent_typing) == gCurrent_position) {
631
            new_len = strlen(gCurrent_typing);
632
        } else {
633
            new_len = strlen(gCurrent_typing) - 1;
634
        }
635
        ChangeCharTo(pSlot_index, new_len, ' ');
636
        new_len = strlen(gCurrent_typing) - 1;
637
        for (i = gCurrent_position - 1; i < new_len; i++) {
638
            ChangeCharTo(pSlot_index, i, gCurrent_typing[i]);
639
            gCurrent_typing[i] = gCurrent_typing[i + 1];
640
        }
641
        gCurrent_typing[new_len] = 0;
642
        gCurrent_position = gCurrent_position - 1;
643
        SetRollingCursor(pSlot_index);
644
    }
645
}
646
 
647
// IDA: void __usercall DoRLDelete(int pSlot_index@<EAX>)
648
void DoRLDelete(int pSlot_index) {
649
    int i;
650
    int new_len;
651
    LOG_TRACE("(%d)", pSlot_index);
652
 
653
    if (gCurrent_position <= ((int)strlen(gCurrent_typing) - 1)) {
654
        new_len = strlen(gCurrent_typing) - 1;
655
        ChangeCharTo(pSlot_index, new_len, ' ');
656
        for (i = gCurrent_position; i < new_len; i++) {
657
            gCurrent_typing[i] = gCurrent_typing[i + 1];
658
            ChangeCharTo(pSlot_index, i, gCurrent_typing[i]);
659
        }
660
        gCurrent_typing[new_len] = '\0';
661
        SetRollingCursor(pSlot_index);
662
    }
663
}
664
 
665
// IDA: void __usercall DoRLInsert(int pSlot_index@<EAX>)
666
void DoRLInsert(int pSlot_index) {
667
    LOG_TRACE("(%d)", pSlot_index);
668
 
669
    gInsert_mode = !gInsert_mode;
670
}
671
 
672
// IDA: void __usercall DoRLCursorLeft(int pSlot_index@<EAX>)
673
void DoRLCursorLeft(int pSlot_index) {
674
    LOG_TRACE("(%d)", pSlot_index);
675
    if (gCurrent_position != 0) {
676
        if (strlen(gCurrent_typing) == gCurrent_position) {
677
            ChangeCharTo(pSlot_index, strlen(gCurrent_typing), ' ');
678
        } else {
679
            ChangeCharTo(pSlot_index, gCurrent_position, gCurrent_typing[gCurrent_position]);
680
        }
681
 
682
        gCurrent_position--;
683
        SetRollingCursor(pSlot_index);
684
    }
685
}
686
 
687
// IDA: void __usercall DoRLCursorRight(int pSlot_index@<EAX>)
688
void DoRLCursorRight(int pSlot_index) {
689
    LOG_TRACE("(%d)", pSlot_index);
690
 
691
    if (gCurrent_position < (int) strlen(gCurrent_typing)) { // Pierre-Marie Baty -- added type cast
692
        ChangeCharTo(pSlot_index, gCurrent_position, gCurrent_typing[gCurrent_position]);
693
        gCurrent_position++;
694
        SetRollingCursor(pSlot_index);
695
    }
696
}
697
 
698
// IDA: void __usercall DoRLTypeLetter(int pChar@<EAX>, int pSlot_index@<EDX>)
699
void DoRLTypeLetter(int pChar, int pSlot_index) {
700
    int i;
701
    int new_len;
702
    LOG_TRACE("(%d, %d)", pChar, pSlot_index);
703
 
704
    // v2 = pSlot_index;
705
    if (pChar >= 32) {
706
        if (gInsert_mode) {
707
            new_len = strlen(gCurrent_typing) + 1;
708
            if (new_len > 100) {
709
                new_len = 100;
710
                DoErrorInterface(kMiscString_FIXED_THAT_YOU_TWISTED_BASTARD);
711
            }
712
            for (i = new_len - 1; i > gCurrent_position; i--) {
713
                gCurrent_typing[i] = gCurrent_typing[i - 1];
714
                ChangeCharTo(pSlot_index, i, gCurrent_typing[i]);
715
            }
716
        } else if (strlen(gCurrent_typing) == gCurrent_position) {
717
            new_len = strlen(gCurrent_typing) + 1;
718
        } else {
719
            new_len = strlen(gCurrent_typing);
720
        }
721
        if (new_len > 100) {
722
            new_len = 100;
723
            DoErrorInterface(kMiscString_FIXED_THAT_YOU_TWISTED_BASTARD);
724
        }
725
 
726
        gCurrent_typing[new_len] = 0;
727
        if (new_len - 1 < gCurrent_position) {
728
            gCurrent_position = new_len - 1;
729
        }
730
        gCurrent_typing[gCurrent_position] = pChar;
731
        ChangeCharTo(pSlot_index, gCurrent_position, pChar);
732
        gCurrent_position++;
733
        SetRollingCursor(pSlot_index);
734
    }
735
}
736
 
737
// IDA: void __usercall StopTyping(int pSlot_index@<EAX>)
738
void StopTyping(int pSlot_index) {
739
    int i;
740
    LOG_TRACE("(%d)", pSlot_index);
741
 
742
    for (i = 0; i < gThe_length; i++) {
743
        if (i < ((int) strlen(gCurrent_typing) - 1)) { // Pierre-Marie Baty -- added type cast
744
            ChangeCharTo(pSlot_index, i, gCurrent_typing[i]);
745
        } else {
746
            ChangeCharTo(pSlot_index, i, ' ');
747
        }
748
    }
749
}
750
 
751
// IDA: void __usercall RevertTyping(int pSlot_index@<EAX>, char *pRevert_str@<EDX>)
752
void RevertTyping(int pSlot_index, char* pRevert_str) {
753
    int i;
754
    LOG_TRACE("(%d, \"%s\")", pSlot_index, pRevert_str);
755
 
756
    for (i = 0; i < gThe_length; i++) {
757
        ChangeCharTo(pSlot_index, i, i >= (int) strlen(pRevert_str) ? ' ' : pRevert_str[i]); // Pierre-Marie Baty -- added type cast
758
    }
759
}
760
 
761
// IDA: void __usercall StartTyping(int pSlot_index@<EAX>, char *pText@<EDX>, int pVisible_length@<EBX>)
762
void StartTyping(int pSlot_index, char* pText, int pVisible_length) {
763
    LOG_TRACE("(%d, \"%s\", %d)", pSlot_index, pText, pVisible_length);
764
 
765
    gThe_length = pVisible_length;
766
    strcpy(gCurrent_typing, pText);
767
    gVisible_length = pVisible_length;
768
    gCurrent_position = strlen(gCurrent_typing);
769
    SetRollingCursor(pSlot_index);
770
}
771
 
772
// IDA: void __usercall TypeKey(int pSlot_index@<EAX>, char pKey@<EDX>)
773
void TypeKey(int pSlot_index, char pKey) {
774
    LOG_TRACE("(%d, %d)", pSlot_index, pKey);
775
 
776
    switch (pKey) {
777
    case KEY_GRAVE:
778
        break;
779
    case KEY_BACKSPACE:
780
        DoRLBackspace(pSlot_index);
781
        break;
782
    case KEY_INSERT:
783
        DoRLInsert(pSlot_index);
784
        break;
785
    case KEY_DELETE:
786
        DoRLDelete(pSlot_index);
787
        break;
788
    case KEY_LEFT:
789
        DoRLCursorLeft(pSlot_index);
790
        break;
791
    case KEY_RIGHT:
792
        DoRLCursorRight(pSlot_index);
793
        break;
794
    default:
795
        DoRLTypeLetter(PDGetASCIIFromKey(pKey), pSlot_index);
796
        break;
797
    }
798
}
799
 
800
// IDA: void __usercall SetSlotXY(int pSlot_index@<EAX>, int pX_coord@<EDX>, int pY_coord@<EBX>)
801
void SetSlotXY(int pSlot_index, int pX_coord, int pY_coord) {
802
    LOG_TRACE("(%d, %d, %d)", pSlot_index, pX_coord, pY_coord);
803
 
804
    gLetter_x_coords[pSlot_index] = pX_coord;
805
    gLetter_y_coords[pSlot_index] = pY_coord;
806
}
807
 
808
// IDA: void __usercall GetTypedName(char *pDestn@<EAX>, int pMax_length@<EDX>)
809
void GetTypedName(char* pDestn, int pMax_length) {
810
    LOG_TRACE("(\"%s\", %d)", pDestn, pMax_length);
811
 
812
    if ((int) strlen(gCurrent_typing) <= pMax_length) { // Pierre-Marie Baty -- added type cast
813
        strcpy(pDestn, gCurrent_typing);
814
    } else {
815
        memcpy(pDestn, gCurrent_typing, pMax_length);
816
        pDestn[pMax_length] = 0;
817
    }
818
}
819
 
820
// IDA: void __usercall KillCursor(int pSlot_index@<EAX>)
821
void KillCursor(int pSlot_index) {
822
    int x_coord;
823
    int y_coord;
824
    int i;
825
    //int j; // Pierre-Marie Baty -- unused variable
826
    tRolling_letter* let;
827
    //tRolling_type new_type; // Pierre-Marie Baty -- unused variable
828
    LOG_TRACE("(%d)", pSlot_index);
829
 
830
    if (gCurrent_position < gVisible_length && gCurrent_position >= 0) {
831
        y_coord = gLetter_y_coords[pSlot_index];
832
        x_coord = gCurrent_graf_data->rolling_letter_x_pitch * gCurrent_position + gLetter_x_coords[pSlot_index];
833
        for (i = 0; i < NBR_ROLLING_LETTERS; i++) {
834
            let = &gRolling_letters[i];
835
            if (let->number_of_letters >= 0 && x_coord == let->x_coord && y_coord == let->y_coord) {
836
                gRolling_letters[i].number_of_letters = -1;
837
                break;
838
            }
839
        }
840
    }
841
}
842
 
843
// IDA: void __cdecl EdgeTriggerModeOn()
844
void EdgeTriggerModeOn(void) {
845
    gEdge_trigger_mode = 1;
846
}
847
 
848
// IDA: void __cdecl EdgeTriggerModeOff()
849
void EdgeTriggerModeOff(void) {
850
    gEdge_trigger_mode = 0;
851
}