13
13
14
14
#include "emulator.h"
15
15
16
- #define DEBUG_JOYPAD_BUTTONS 0
16
+ #define DEBUG_SYSTEM_INPUT 0
17
17
18
18
#if 0
19
19
#define LOG (...) printf(__VA_ARGS__)
25
25
26
26
typedef struct {
27
27
Ticks ticks ;
28
- u16 buttons ;
29
- u8 padding [6 ];
28
+ u32 input ;
29
+ u8 padding [4 ];
30
30
} JoypadState ;
31
31
32
32
typedef struct JoypadChunk {
@@ -43,7 +43,7 @@ typedef struct {
43
43
44
44
typedef struct {
45
45
JoypadChunk sentinel ;
46
- JoypadButtons last_buttons ;
46
+ SystemInput last_input ;
47
47
} JoypadBuffer ;
48
48
49
49
typedef struct {
@@ -55,8 +55,7 @@ typedef struct {
55
55
56
56
typedef struct {
57
57
u32 latch ;
58
- u8 buttons [2 ];
59
- u8 padding [2 ];
58
+ u32 input ;
60
59
} JoypadMovieFrame ;
61
60
62
61
typedef struct {
@@ -70,7 +69,7 @@ typedef struct {
70
69
JoypadMovieBuffer * movie_buffer ;
71
70
u32 current_frame , current_frame_latch ;
72
71
u32 current_total_latch , max_latches ;
73
- JoypadButtons last_buttons ;
72
+ SystemInput last_input ;
74
73
} JoypadMoviePlayback ;
75
74
76
75
typedef struct Joypad {
@@ -84,16 +83,16 @@ typedef struct Joypad {
84
83
JoypadMoviePlayback movie_playback ;
85
84
} Joypad ;
86
85
87
- static void joypad_append (JoypadBuffer * , JoypadButtons * , Ticks );
88
- static u16 joypad_pack_buttons ( JoypadButtons * );
89
- static JoypadButtons joypad_unpack_buttons ( u16 packed );
86
+ static void joypad_append (JoypadBuffer * , SystemInput * , Ticks );
87
+ static u32 joypad_pack_input ( SystemInput * );
88
+ static SystemInput joypad_unpack_input ( u32 packed );
90
89
static JoypadStateIter joypad_get_next_state (JoypadStateIter );
91
90
static JoypadStateIter joypad_find_state (JoypadBuffer * , Ticks );
92
91
93
92
static JoypadBuffer * joypad_buffer_new (void ) {
94
93
JoypadBuffer * buffer = xcalloc (1 , sizeof (JoypadBuffer ));
95
94
buffer -> sentinel .next = buffer -> sentinel .prev = & buffer -> sentinel ;
96
- joypad_append (buffer , & buffer -> last_buttons , 0 );
95
+ joypad_append (buffer , & buffer -> last_input , 0 );
97
96
return buffer ;
98
97
}
99
98
@@ -137,56 +136,66 @@ static JoypadState* alloc_joypad_state(JoypadBuffer* buffer) {
137
136
return & tail -> data [tail -> size ++ ];
138
137
}
139
138
140
- static void joypad_append (JoypadBuffer * buffer , JoypadButtons * buttons ,
139
+ static void joypad_append (JoypadBuffer * buffer , SystemInput * input ,
141
140
Ticks ticks ) {
142
141
JoypadState * state = alloc_joypad_state (buffer );
143
142
state -> ticks = ticks ;
144
- state -> buttons = joypad_pack_buttons ( buttons );
145
- buffer -> last_buttons = * buttons ;
143
+ state -> input = joypad_pack_input ( input );
144
+ buffer -> last_input = * input ;
146
145
}
147
146
148
- static bool buttons_are_equal ( JoypadButtons * lhs , JoypadButtons * rhs ) {
147
+ static bool joypad_input_is_equal ( JoypadInput * lhs , JoypadInput * rhs ) {
149
148
return lhs -> down == rhs -> down && lhs -> up == rhs -> up &&
150
149
lhs -> left == rhs -> left && lhs -> right == rhs -> right &&
151
150
lhs -> start == rhs -> start && lhs -> select == rhs -> select &&
152
- lhs -> B == rhs -> B && lhs -> A == rhs -> A && lhs -> reset == rhs -> reset ;
151
+ lhs -> B == rhs -> B && lhs -> A == rhs -> A ;
153
152
}
154
153
155
- static void print_joypad_buttons (Ticks ticks , JoypadButtons buttons ) {
156
- printf ("joyp: %" PRIu64 " %c%c%c%c %c%c%c%c%s\n" , ticks ,
157
- buttons .down ? 'D' : '_' , buttons .up ? 'U' : '_' ,
158
- buttons .left ? 'L' : '_' , buttons .right ? 'R' : '_' ,
159
- buttons .start ? 'S' : '_' , buttons .select ? 's' : '_' ,
160
- buttons .B ? 'B' : '_' , buttons .A ? 'A' : '_' ,
161
- buttons .reset ? " [R]" : "" );
154
+ static bool system_input_is_equal (SystemInput * lhs , SystemInput * rhs ) {
155
+ return joypad_input_is_equal (& lhs -> joyp [0 ], & rhs -> joyp [0 ]) &&
156
+ joypad_input_is_equal (& lhs -> joyp [1 ], & rhs -> joyp [1 ]) &&
157
+ lhs -> reset == rhs -> reset ;
162
158
}
163
159
164
- void joypad_append_if_new (Joypad * joypad , JoypadButtons * buttons , Ticks ticks ) {
165
- if (!buttons_are_equal (buttons , & joypad -> buffer -> last_buttons )) {
166
- joypad_append (joypad -> buffer , buttons , ticks );
167
- #if DEBUG_JOYPAD_BUTTONS
168
- print_joypad_buttons (ticks , * buttons );
160
+ static void print_input (Ticks ticks , SystemInput input ) {
161
+ printf ("joyp: %" PRIu64 " 0:%c%c%c%c %c%c%c%c 1:%c%c%c%c %c%c%c%c%s\n" , ticks ,
162
+ input .joyp [0 ].down ? 'D' : '_' , input .joyp [0 ].up ? 'U' : '_' ,
163
+ input .joyp [0 ].left ? 'L' : '_' , input .joyp [0 ].right ? 'R' : '_' ,
164
+ input .joyp [0 ].start ? 'S' : '_' , input .joyp [0 ].select ? 's' : '_' ,
165
+ input .joyp [0 ].B ? 'B' : '_' , input .joyp [0 ].A ? 'A' : '_' ,
166
+ input .joyp [1 ].down ? 'D' : '_' , input .joyp [1 ].up ? 'U' : '_' ,
167
+ input .joyp [1 ].left ? 'L' : '_' , input .joyp [1 ].right ? 'R' : '_' ,
168
+ input .joyp [1 ].start ? 'S' : '_' , input .joyp [1 ].select ? 's' : '_' ,
169
+ input .joyp [1 ].B ? 'B' : '_' , input .joyp [1 ].A ? 'A' : '_' ,
170
+ input .reset ? " [R]" : "" );
171
+ }
172
+
173
+ void joypad_append_if_new (Joypad * joypad , SystemInput * input , Ticks ticks ) {
174
+ if (!system_input_is_equal (input , & joypad -> buffer -> last_input )) {
175
+ joypad_append (joypad -> buffer , input , ticks );
176
+ #if DEBUG_SYSTEM_INPUT
177
+ print_input (ticks , * input );
169
178
#endif
170
179
}
171
180
}
172
181
173
182
void joypad_append_reset (Joypad * joypad , bool set , Ticks ticks ) {
174
- JoypadButtons buttons = joypad -> buffer -> last_buttons ;
175
- buttons .reset = set ;
176
- joypad_append_if_new (joypad , & buttons , ticks );
183
+ SystemInput input = joypad -> buffer -> last_input ;
184
+ input .reset = set ;
185
+ joypad_append_if_new (joypad , & input , ticks );
177
186
}
178
187
179
188
Ticks joypad_get_next_reset_change (Joypad * joypad ) {
180
189
if (joypad && joypad -> mode == JOYPAD_MODE_PLAYBACK ) {
181
190
Ticks ticks = emulator_get_ticks (joypad -> playback .e );
182
191
JoypadStateIter current = joypad_find_state (joypad -> playback .buffer , ticks );
183
192
bool is_reset = current .state != NULL &&
184
- joypad_unpack_buttons (current .state -> buttons ).reset ;
193
+ joypad_unpack_input (current .state -> input ).reset ;
185
194
if (current .state != NULL ) {
186
195
JoypadStateIter iter = joypad_get_next_state (current );
187
196
while (iter .state != NULL ) {
188
- JoypadButtons buttons = joypad_unpack_buttons (iter .state -> buttons );
189
- if (buttons .reset != is_reset ) {
197
+ SystemInput input = joypad_unpack_input (iter .state -> input );
198
+ if (input .reset != is_reset ) {
190
199
return iter .state -> ticks ;
191
200
}
192
201
iter = joypad_get_next_state (iter );
@@ -257,7 +266,7 @@ static void joypad_truncate_to(JoypadBuffer *buffer, JoypadStateIter iter) {
257
266
}
258
267
iter .chunk -> next = sentinel ;
259
268
sentinel -> prev = iter .chunk ;
260
- buffer -> last_buttons = joypad_unpack_buttons (iter .state -> buttons );
269
+ buffer -> last_input = joypad_unpack_input (iter .state -> input );
261
270
}
262
271
263
272
static JoypadStateIter joypad_get_next_state (JoypadStateIter iter ) {
@@ -272,24 +281,38 @@ static JoypadStateIter joypad_get_next_state(JoypadStateIter iter) {
272
281
return iter ;
273
282
}
274
283
275
- static u16 joypad_pack_buttons (JoypadButtons * buttons ) {
276
- return (buttons -> reset << 8 ) | (buttons -> down << 7 ) | (buttons -> up << 6 ) |
277
- (buttons -> left << 5 ) | (buttons -> right << 4 ) | (buttons -> start << 3 ) |
278
- (buttons -> select << 2 ) | (buttons -> B << 1 ) | (buttons -> A << 0 );
284
+ static u32 joypad_pack_input (SystemInput * input ) {
285
+ return (input -> reset << 16 ) | (input -> joyp [1 ].down << 15 ) |
286
+ (input -> joyp [1 ].up << 14 ) | (input -> joyp [1 ].left << 13 ) |
287
+ (input -> joyp [1 ].right << 12 ) | (input -> joyp [1 ].start << 11 ) |
288
+ (input -> joyp [1 ].select << 10 ) | (input -> joyp [1 ].B << 9 ) |
289
+ (input -> joyp [1 ].A << 8 ) | (input -> joyp [0 ].down << 7 ) |
290
+ (input -> joyp [0 ].up << 6 ) | (input -> joyp [0 ].left << 5 ) |
291
+ (input -> joyp [0 ].right << 4 ) | (input -> joyp [0 ].start << 3 ) |
292
+ (input -> joyp [0 ].select << 2 ) | (input -> joyp [0 ].B << 1 ) |
293
+ (input -> joyp [0 ].A << 0 );
279
294
}
280
295
281
- static JoypadButtons joypad_unpack_buttons (u16 packed ) {
282
- JoypadButtons buttons ;
283
- buttons .A = packed & 1 ;
284
- buttons .B = (packed >> 1 ) & 1 ;
285
- buttons .select = (packed >> 2 ) & 1 ;
286
- buttons .start = (packed >> 3 ) & 1 ;
287
- buttons .right = (packed >> 4 ) & 1 ;
288
- buttons .left = (packed >> 5 ) & 1 ;
289
- buttons .up = (packed >> 6 ) & 1 ;
290
- buttons .down = (packed >> 7 ) & 1 ;
291
- buttons .reset = (packed >> 8 ) & 1 ;
292
- return buttons ;
296
+ static SystemInput joypad_unpack_input (u32 packed ) {
297
+ SystemInput input ;
298
+ input .joyp [0 ].A = packed & 1 ;
299
+ input .joyp [0 ].B = (packed >> 1 ) & 1 ;
300
+ input .joyp [0 ].select = (packed >> 2 ) & 1 ;
301
+ input .joyp [0 ].start = (packed >> 3 ) & 1 ;
302
+ input .joyp [0 ].right = (packed >> 4 ) & 1 ;
303
+ input .joyp [0 ].left = (packed >> 5 ) & 1 ;
304
+ input .joyp [0 ].up = (packed >> 6 ) & 1 ;
305
+ input .joyp [0 ].down = (packed >> 7 ) & 1 ;
306
+ input .joyp [1 ].A = (packed >> 8 ) & 1 ;
307
+ input .joyp [1 ].B = (packed >> 9 ) & 1 ;
308
+ input .joyp [1 ].select = (packed >> 10 ) & 1 ;
309
+ input .joyp [1 ].start = (packed >> 11 ) & 1 ;
310
+ input .joyp [1 ].right = (packed >> 12 ) & 1 ;
311
+ input .joyp [1 ].left = (packed >> 13 ) & 1 ;
312
+ input .joyp [1 ].up = (packed >> 14 ) & 1 ;
313
+ input .joyp [1 ].down = (packed >> 15 ) & 1 ;
314
+ input .reset = (packed >> 16 ) & 1 ;
315
+ return input ;
293
316
}
294
317
295
318
JoypadStats joypad_get_stats (Joypad * joypad ) {
@@ -361,8 +384,7 @@ static Result joypad_read(const FileData *file_data,
361
384
ON_ERROR_RETURN ;
362
385
}
363
386
364
- static void joypad_playback_callback (struct JoypadButtons * joyp ,
365
- void * user_data ,
387
+ static void joypad_playback_callback (struct SystemInput * input , void * user_data ,
366
388
bool strobe ) {
367
389
bool changed = false;
368
390
JoypadPlayback * playback = user_data ;
@@ -382,17 +404,16 @@ static void joypad_playback_callback(struct JoypadButtons* joyp,
382
404
changed = true;
383
405
}
384
406
385
- #if DEBUG_JOYPAD_BUTTONS
407
+ #if DEBUG_SYSTEM_INPUT
386
408
if (changed ) {
387
- print_joypad_buttons (
388
- playback -> current .state -> ticks ,
389
- joypad_unpack_buttons (playback -> current .state -> buttons ));
409
+ print_input (playback -> current .state -> ticks ,
410
+ joypad_unpack_input (playback -> current .state -> input ));
390
411
}
391
412
#else
392
413
(void )changed ;
393
414
#endif
394
415
395
- * joyp = joypad_unpack_buttons (playback -> current .state -> buttons );
416
+ * input = joypad_unpack_input (playback -> current .state -> input );
396
417
}
397
418
398
419
static void init_joypad_playback_state (Emulator * e , JoypadPlayback * playback ,
@@ -435,10 +456,6 @@ static Result joypad_read_movie(const FileData *file_data,
435
456
size_t j ;
436
457
CHECK_MSG (frame -> latch != 0 , "Expected latch to be non-zero at index %zu\n" ,
437
458
i );
438
- for (j = 0 ; j < ARRAY_SIZE (frame -> padding ); ++ j ) {
439
- CHECK_MSG (frame -> padding [j ] == 0 , "Expected padding to be zero, got %u\n" ,
440
- frame -> padding [j ]);
441
- }
442
459
total_latches += frame -> latch ;
443
460
}
444
461
@@ -463,12 +480,11 @@ static void init_joypad_movie_playback_state(JoypadMoviePlayback *playback,
463
480
playback -> current_frame_latch = 0 ;
464
481
playback -> current_total_latch = 0 ;
465
482
playback -> max_latches = 0 ;
466
- memset (& playback -> last_buttons , 0 , sizeof (JoypadButtons ));
483
+ memset (& playback -> last_input , 0 , sizeof (SystemInput ));
467
484
}
468
485
469
- static void joypad_movie_playback_callback (struct JoypadButtons * joyp ,
470
- void * user_data ,
471
- bool strobe ) {
486
+ static void joypad_movie_playback_callback (struct SystemInput * input ,
487
+ void * user_data , bool strobe ) {
472
488
JoypadMoviePlayback * playback = user_data ;
473
489
474
490
Ticks ticks = emulator_get_ticks (playback -> e );
@@ -482,7 +498,7 @@ static void joypad_movie_playback_callback(struct JoypadButtons *joyp,
482
498
#undef GET_TICKS
483
499
#undef CMP_LT
484
500
485
- u8 last_buttons = 0 ;
501
+ u32 last_input = 0 ;
486
502
size_t total_latch_index = lower_bound - begin ;
487
503
u32 total_latches = 0 ;
488
504
for (size_t i = 0 ; i < playback -> movie_buffer -> frame_count - 1 ; ++ i ) {
@@ -492,11 +508,11 @@ static void joypad_movie_playback_callback(struct JoypadButtons *joyp,
492
508
playback -> current_frame = i ;
493
509
playback -> current_frame_latch = total_latch_index - total_latches ;
494
510
playback -> current_total_latch = total_latch_index ;
495
- playback -> last_buttons = joypad_unpack_buttons ( last_buttons );
511
+ playback -> last_input = joypad_unpack_input ( last_input );
496
512
break ;
497
513
}
498
514
total_latches += frame -> latch ;
499
- last_buttons = frame -> buttons [ 0 ] ;
515
+ last_input = frame -> input ;
500
516
}
501
517
502
518
LOG (" *** Resync %" PRIu64 ". New frame=%u, latch=%u total=%u\n" , ticks ,
@@ -520,23 +536,32 @@ static void joypad_movie_playback_callback(struct JoypadButtons *joyp,
520
536
}
521
537
if (++ playback -> current_frame_latch >= frame -> latch ) {
522
538
assert (playback -> current_frame_latch <= frame -> latch );
523
- playback -> last_buttons = joypad_unpack_buttons (frame -> buttons [ 0 ] );
539
+ playback -> last_input = joypad_unpack_input (frame -> input );
524
540
++ playback -> current_frame ;
525
541
playback -> current_frame_latch = 0 ;
526
- LOG ("buttons=%c%c%c%c%c%c%c%c\n" , playback -> last_buttons .down ? 'D' : '_' ,
527
- playback -> last_buttons .up ? 'U' : '_' ,
528
- playback -> last_buttons .left ? 'L' : '_' ,
529
- playback -> last_buttons .right ? 'R' : '_' ,
530
- playback -> last_buttons .start ? 'T' : '_' ,
531
- playback -> last_buttons .select ? 'E' : '_' ,
532
- playback -> last_buttons .B ? 'B' : '_' ,
533
- playback -> last_buttons .A ? 'A' : '_' );
542
+ LOG ("0:%c%c%c%c%c%c%c%c 1:%c%c%c%c%c%c%c%c\n" ,
543
+ playback -> last_input .joyp [0 ].down ? 'D' : '_' ,
544
+ playback -> last_input .joyp [0 ].up ? 'U' : '_' ,
545
+ playback -> last_input .joyp [0 ].left ? 'L' : '_' ,
546
+ playback -> last_input .joyp [0 ].right ? 'R' : '_' ,
547
+ playback -> last_input .joyp [0 ].start ? 'T' : '_' ,
548
+ playback -> last_input .joyp [0 ].select ? 'E' : '_' ,
549
+ playback -> last_input .joyp [0 ].B ? 'B' : '_' ,
550
+ playback -> last_input .joyp [0 ].A ? 'A' : '_' ,
551
+ playback -> last_input .joyp [1 ].down ? 'D' : '_' ,
552
+ playback -> last_input .joyp [1 ].up ? 'U' : '_' ,
553
+ playback -> last_input .joyp [1 ].left ? 'L' : '_' ,
554
+ playback -> last_input .joyp [1 ].right ? 'R' : '_' ,
555
+ playback -> last_input .joyp [1 ].start ? 'T' : '_' ,
556
+ playback -> last_input .joyp [1 ].select ? 'E' : '_' ,
557
+ playback -> last_input .joyp [1 ].B ? 'B' : '_' ,
558
+ playback -> last_input .joyp [1 ].A ? 'A' : '_' );
534
559
} else {
535
560
LOG ("\n" );
536
561
}
537
562
}
538
563
539
- * joyp = playback -> last_buttons ;
564
+ * input = playback -> last_input ;
540
565
}
541
566
542
567
Result joypad_new_for_movie (Emulator * e , FileData * file_data , Joypad * * out ) {
@@ -573,8 +598,8 @@ void joypad_truncate_to_current(Joypad* joypad) {
573
598
if (joypad -> mode == JOYPAD_MODE_USER ) {
574
599
joypad_truncate_to (joypad -> buffer , joypad -> playback .current );
575
600
/* Append the current joypad state. */
576
- JoypadButtons buttons ;
577
- joypad -> callback (& buttons , joypad -> callback_user_data , false);
601
+ SystemInput input ;
602
+ joypad -> callback (& input , joypad -> callback_user_data , false);
578
603
}
579
604
}
580
605
0 commit comments