Skip to content

Commit e3ce9de

Browse files
committedMay 14, 2023
Add player 2 input
1 parent d4940fe commit e3ce9de

File tree

11 files changed

+200
-135
lines changed

11 files changed

+200
-135
lines changed
 

‎README.md

+16-8
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,22 @@ Keys:
9292

9393
| Action | Key |
9494
| --- | --- |
95-
| DPAD-UP | <kbd>↑</kbd> |
96-
| DPAD-DOWN | <kbd>↓</kbd> |
97-
| DPAD-LEFT | <kbd>←</kbd> |
98-
| DPAD-RIGHT | <kbd>→</kbd> |
99-
| B | <kbd>Z</kbd> |
100-
| A | <kbd>X</kbd> |
101-
| START | <kbd>Enter</kbd> |
102-
| SELECT | <kbd>Tab</kbd> |
95+
| P0 DPAD-UP | <kbd>↑</kbd> |
96+
| P0 DPAD-DOWN | <kbd>↓</kbd> |
97+
| P0 DPAD-LEFT | <kbd>←</kbd> |
98+
| P0 DPAD-RIGHT | <kbd>→</kbd> |
99+
| P0 B | <kbd>Z</kbd> |
100+
| P0 A | <kbd>X</kbd> |
101+
| P0 START | <kbd>Enter</kbd> |
102+
| P0 SELECT | <kbd>Tab</kbd> |
103+
| P1 DPAD-UP | <kbd>Y</kbd> |
104+
| P1 DPAD-DOWN | <kbd>H</kbd> |
105+
| P1 DPAD-LEFT | <kbd>G</kbd> |
106+
| P1 DPAD-RIGHT | <kbd>J</kbd> |
107+
| P1 B | <kbd>K</kbd> |
108+
| P1 A | <kbd>L</kbd> |
109+
| P1 START | <kbd>O</kbd> |
110+
| P1 SELECT | <kbd>I</kbd> |
103111
| Reset | <kbd>Delete</kbd> |
104112
| Save state | <kbd>F6</kbd> |
105113
| Load state | <kbd>F9</kbd> |

‎docs/binjnes.wasm

1.48 KB
Binary file not shown.

‎docs/demo.js

+24-8
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ let data = {
9494
{name: 'P0 A', options:[key('KeyX'), gpbutton(0), gpbutton(1)]},
9595
{name: 'P0 START', options:[key('Enter'), gpbutton(10), null]},
9696
{name: 'P0 SELECT', options:[key('Tab'), gpbutton(9), null]},
97+
{name: 'P1 DPAD UP', options:[key('KeyY'), null, null]},
98+
{name: 'P1 DPAD DOWN', options:[key('KeyH'), null, null]},
99+
{name: 'P1 DPAD LEFT', options:[key('KeyG'), null, null]},
100+
{name: 'P1 DPAD RIGHT', options:[key('KeyJ'), null, null]},
101+
{name: 'P1 B', options:[key('KeyK'), null, null]},
102+
{name: 'P1 A', options:[key('KeyL'), null, null]},
103+
{name: 'P1 START', options:[key('KeyO'), null, null]},
104+
{name: 'P1 SELECT', options:[key('KeyI'), null, null]},
97105
{name: 'Rewind', options:[key('Backspace'), gpbutton(7), null]},
98106
{name: 'Pause', options:[key('Space'), null, null]},
99107
],
@@ -646,14 +654,22 @@ class Emulator {
646654

647655
bindKeys() {
648656
this.keyFuncs = [ // Order matches input.list
649-
this.module._set_joyp_up.bind(null, this.e),
650-
this.module._set_joyp_down.bind(null, this.e),
651-
this.module._set_joyp_left.bind(null, this.e),
652-
this.module._set_joyp_right.bind(null, this.e),
653-
this.module._set_joyp_B.bind(null, this.e),
654-
this.module._set_joyp_A.bind(null, this.e),
655-
this.module._set_joyp_start.bind(null, this.e),
656-
this.module._set_joyp_select.bind(null, this.e),
657+
this.module._set_joyp_up.bind(null, this.e, 0),
658+
this.module._set_joyp_down.bind(null, this.e, 0),
659+
this.module._set_joyp_left.bind(null, this.e, 0),
660+
this.module._set_joyp_right.bind(null, this.e, 0),
661+
this.module._set_joyp_B.bind(null, this.e, 0),
662+
this.module._set_joyp_A.bind(null, this.e, 0),
663+
this.module._set_joyp_start.bind(null, this.e, 0),
664+
this.module._set_joyp_select.bind(null, this.e, 0),
665+
this.module._set_joyp_up.bind(null, this.e, 1),
666+
this.module._set_joyp_down.bind(null, this.e, 1),
667+
this.module._set_joyp_left.bind(null, this.e, 1),
668+
this.module._set_joyp_right.bind(null, this.e, 1),
669+
this.module._set_joyp_B.bind(null, this.e, 1),
670+
this.module._set_joyp_A.bind(null, this.e, 1),
671+
this.module._set_joyp_start.bind(null, this.e, 1),
672+
this.module._set_joyp_select.bind(null, this.e, 1),
657673
this.keyRewind.bind(this),
658674
this.keyPause.bind(this),
659675
];

‎docs/simple.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,14 @@ class Emulator {
205205

206206
bindKeys() {
207207
this.keyFuncs = {
208-
'ArrowDown': this.module._set_joyp_down.bind(null, this.e),
209-
'ArrowLeft': this.module._set_joyp_left.bind(null, this.e),
210-
'ArrowRight': this.module._set_joyp_right.bind(null, this.e),
211-
'ArrowUp': this.module._set_joyp_up.bind(null, this.e),
212-
'KeyZ': this.module._set_joyp_B.bind(null, this.e),
213-
'KeyX': this.module._set_joyp_A.bind(null, this.e),
214-
'Enter': this.module._set_joyp_start.bind(null, this.e),
215-
'Tab': this.module._set_joyp_select.bind(null, this.e),
208+
'ArrowDown': this.module._set_joyp_down.bind(null, this.e, 0),
209+
'ArrowLeft': this.module._set_joyp_left.bind(null, this.e, 0),
210+
'ArrowRight': this.module._set_joyp_right.bind(null, this.e, 0),
211+
'ArrowUp': this.module._set_joyp_up.bind(null, this.e, 0),
212+
'KeyZ': this.module._set_joyp_B.bind(null, this.e, 0),
213+
'KeyX': this.module._set_joyp_A.bind(null, this.e, 0),
214+
'Enter': this.module._set_joyp_start.bind(null, this.e, 0),
215+
'Tab': this.module._set_joyp_select.bind(null, this.e, 0),
216216
'Space': this.keyPause.bind(this),
217217
};
218218
this.boundKeyDown = this.keyDown.bind(this);

‎src/binjnes.c

+19-10
Original file line numberDiff line numberDiff line change
@@ -402,18 +402,27 @@ static void init_audio(void) {
402402
});
403403
}
404404

405-
static void joypad_callback(JoypadButtons *joyp, void *user_data, bool strobe) {
406-
joyp->up = s_key_state[SAPP_KEYCODE_UP];
407-
joyp->down = s_key_state[SAPP_KEYCODE_DOWN];
408-
joyp->left = s_key_state[SAPP_KEYCODE_LEFT];
409-
joyp->right = s_key_state[SAPP_KEYCODE_RIGHT];
410-
joyp->B = s_key_state[SAPP_KEYCODE_Z];
411-
joyp->A = s_key_state[SAPP_KEYCODE_X];
412-
joyp->start = s_key_state[SAPP_KEYCODE_ENTER];
413-
joyp->select = s_key_state[SAPP_KEYCODE_TAB];
405+
static void joypad_callback(SystemInput* input, void *user_data, bool strobe) {
406+
input->joyp[0].up = s_key_state[SAPP_KEYCODE_UP];
407+
input->joyp[0].down = s_key_state[SAPP_KEYCODE_DOWN];
408+
input->joyp[0].left = s_key_state[SAPP_KEYCODE_LEFT];
409+
input->joyp[0].right = s_key_state[SAPP_KEYCODE_RIGHT];
410+
input->joyp[0].B = s_key_state[SAPP_KEYCODE_Z];
411+
input->joyp[0].A = s_key_state[SAPP_KEYCODE_X];
412+
input->joyp[0].start = s_key_state[SAPP_KEYCODE_ENTER];
413+
input->joyp[0].select = s_key_state[SAPP_KEYCODE_TAB];
414+
415+
input->joyp[1].up = s_key_state[SAPP_KEYCODE_Y];
416+
input->joyp[1].down = s_key_state[SAPP_KEYCODE_H];
417+
input->joyp[1].left = s_key_state[SAPP_KEYCODE_G];
418+
input->joyp[1].right = s_key_state[SAPP_KEYCODE_J];
419+
input->joyp[1].B = s_key_state[SAPP_KEYCODE_K];
420+
input->joyp[1].A = s_key_state[SAPP_KEYCODE_L];
421+
input->joyp[1].start = s_key_state[SAPP_KEYCODE_O];
422+
input->joyp[1].select = s_key_state[SAPP_KEYCODE_I];
414423

415424
Ticks ticks = emulator_get_ticks(e);
416-
joypad_append_if_new(s_joypad, joyp, ticks);
425+
joypad_append_if_new(s_joypad, input, ticks);
417426
}
418427

419428
static void init_emulator(void) {

‎src/common.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,15 @@ typedef struct FileData {
102102
size_t size;
103103
} FileData;
104104

105-
typedef struct JoypadButtons {
105+
typedef struct JoypadInput {
106106
bool down, up, left, right;
107107
bool start, select, B, A;
108+
} JoypadInput;
109+
110+
typedef struct SystemInput {
111+
JoypadInput joyp[2];
108112
bool reset;
109-
} JoypadButtons;
113+
} SystemInput;
110114

111115
const char* replace_extension(const char* filename, const char* extension);
112116
Result file_read(const char* filename, FileData* out);

‎src/emscripten/wrapper.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ typedef struct {
2424
static Emulator* e;
2525

2626
static EmulatorInit s_init;
27-
static JoypadButtons s_buttons;
27+
static SystemInput s_input;
2828

2929
Emulator* emulator_new_simple(void* rom_data, size_t rom_size,
3030
int audio_frequency, int audio_frames) {
@@ -55,12 +55,12 @@ f64 rewind_get_oldest_ticks_f64(RewindBuffer* buf) {
5555
return (f64)rewind_get_oldest_ticks(buf);
5656
}
5757

58-
static void default_joypad_callback(JoypadButtons *joyp, void *user_data,
58+
static void default_joypad_callback(SystemInput *input, void *user_data,
5959
bool strobe) {
6060
Joypad* joypad = user_data;
61-
*joyp = s_buttons;
61+
*input = s_input;
6262
Ticks ticks = emulator_get_ticks(e);
63-
joypad_append_if_new(joypad, joyp, ticks);
63+
joypad_append_if_new(joypad, input, ticks);
6464
}
6565

6666
Joypad* joypad_new_simple(Emulator *e) {
@@ -70,8 +70,10 @@ Joypad* joypad_new_simple(Emulator *e) {
7070
return result;
7171
}
7272

73-
#define DEFINE_JOYP_SET(name) \
74-
void set_joyp_##name(Emulator* e, bool set) { s_buttons.name = set; }
73+
#define DEFINE_JOYP_SET(name) \
74+
void set_joyp_##name(Emulator* e, int player, bool set) { \
75+
s_input.joyp[player].name = set; \
76+
}
7577

7678
DEFINE_JOYP_SET(up)
7779
DEFINE_JOYP_SET(down)

‎src/emulator.c

+10-9
Original file line numberDiff line numberDiff line change
@@ -1033,21 +1033,22 @@ static inline void inc_ppu_addr(P* p) {
10331033
}
10341034
}
10351035

1036-
static inline void read_joyp(E *e, bool write, u8 val) {
1036+
static inline void read_joyp(E* e, bool write, u8 val) {
10371037
if (write || e->s.j.S) {
10381038
if (e->joypad_info.callback) {
10391039
bool strobe = write && val == 1;
10401040
e->s.c.read_input = true;
1041-
JoypadButtons btns[2];
1042-
ZERO_MEMORY(btns);
1043-
e->joypad_info.callback(btns, e->joypad_info.user_data, strobe);
1041+
SystemInput input;
1042+
ZERO_MEMORY(input);
1043+
e->joypad_info.callback(&input, e->joypad_info.user_data, strobe);
10441044
for (int i = 0; i < 2; ++i) {
1045-
e->s.j.joyp[i] = (btns[i].right << 7) | (btns[i].left << 6) |
1046-
(btns[i].down << 5) | (btns[i].up << 4) |
1047-
(btns[i].start << 3) | (btns[i].select << 2) |
1048-
(btns[i].B << 1) | (btns[i].A << 0);
1045+
e->s.j.joyp[i] = (input.joyp[i].right << 7) |
1046+
(input.joyp[i].left << 6) | (input.joyp[i].down << 5) |
1047+
(input.joyp[i].up << 4) | (input.joyp[i].start << 3) |
1048+
(input.joyp[i].select << 2) | (input.joyp[i].B << 1) |
1049+
(input.joyp[i].A << 0);
10491050
if (e->s.j.joyp[i]) {
1050-
print_byte(0x4016+i, e->s.j.joyp[i], 5, "RLDUTEBA");
1051+
print_byte(0x4016 + i, e->s.j.joyp[i], 5, "RLDUTEBA");
10511052
}
10521053
}
10531054
} else {

‎src/emulator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extern "C" {
2424
#define MAX_CHRRAM_SIZE 0x8000
2525
#define CHRRAM1K_MASK ((MAX_CHRRAM_SIZE >> 10) - 1)
2626

27-
typedef void (*JoypadCallback)(struct JoypadButtons joyp[2], void *user_data,
27+
typedef void (*JoypadCallback)(struct SystemInput *input, void *user_data,
2828
bool strobe);
2929

3030
typedef struct JoypadCallbackInfo {

‎src/joypad.c

+106-81
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#include "emulator.h"
1515

16-
#define DEBUG_JOYPAD_BUTTONS 0
16+
#define DEBUG_SYSTEM_INPUT 0
1717

1818
#if 0
1919
#define LOG(...) printf(__VA_ARGS__)
@@ -25,8 +25,8 @@
2525

2626
typedef struct {
2727
Ticks ticks;
28-
u16 buttons;
29-
u8 padding[6];
28+
u32 input;
29+
u8 padding[4];
3030
} JoypadState;
3131

3232
typedef struct JoypadChunk {
@@ -43,7 +43,7 @@ typedef struct {
4343

4444
typedef struct {
4545
JoypadChunk sentinel;
46-
JoypadButtons last_buttons;
46+
SystemInput last_input;
4747
} JoypadBuffer;
4848

4949
typedef struct {
@@ -55,8 +55,7 @@ typedef struct {
5555

5656
typedef struct {
5757
u32 latch;
58-
u8 buttons[2];
59-
u8 padding[2];
58+
u32 input;
6059
} JoypadMovieFrame;
6160

6261
typedef struct {
@@ -70,7 +69,7 @@ typedef struct {
7069
JoypadMovieBuffer* movie_buffer;
7170
u32 current_frame, current_frame_latch;
7271
u32 current_total_latch, max_latches;
73-
JoypadButtons last_buttons;
72+
SystemInput last_input;
7473
} JoypadMoviePlayback;
7574

7675
typedef struct Joypad {
@@ -84,16 +83,16 @@ typedef struct Joypad {
8483
JoypadMoviePlayback movie_playback;
8584
} Joypad;
8685

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);
9089
static JoypadStateIter joypad_get_next_state(JoypadStateIter);
9190
static JoypadStateIter joypad_find_state(JoypadBuffer *, Ticks);
9291

9392
static JoypadBuffer* joypad_buffer_new(void) {
9493
JoypadBuffer* buffer = xcalloc(1, sizeof(JoypadBuffer));
9594
buffer->sentinel.next = buffer->sentinel.prev = &buffer->sentinel;
96-
joypad_append(buffer, &buffer->last_buttons, 0);
95+
joypad_append(buffer, &buffer->last_input, 0);
9796
return buffer;
9897
}
9998

@@ -137,56 +136,66 @@ static JoypadState* alloc_joypad_state(JoypadBuffer* buffer) {
137136
return &tail->data[tail->size++];
138137
}
139138

140-
static void joypad_append(JoypadBuffer * buffer, JoypadButtons * buttons,
139+
static void joypad_append(JoypadBuffer* buffer, SystemInput* input,
141140
Ticks ticks) {
142141
JoypadState* state = alloc_joypad_state(buffer);
143142
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;
146145
}
147146

148-
static bool buttons_are_equal(JoypadButtons* lhs, JoypadButtons* rhs) {
147+
static bool joypad_input_is_equal(JoypadInput* lhs, JoypadInput* rhs) {
149148
return lhs->down == rhs->down && lhs->up == rhs->up &&
150149
lhs->left == rhs->left && lhs->right == rhs->right &&
151150
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;
153152
}
154153

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;
162158
}
163159

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);
169178
#endif
170179
}
171180
}
172181

173182
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);
177186
}
178187

179188
Ticks joypad_get_next_reset_change(Joypad *joypad) {
180189
if (joypad && joypad->mode == JOYPAD_MODE_PLAYBACK) {
181190
Ticks ticks = emulator_get_ticks(joypad->playback.e);
182191
JoypadStateIter current = joypad_find_state(joypad->playback.buffer, ticks);
183192
bool is_reset = current.state != NULL &&
184-
joypad_unpack_buttons(current.state->buttons).reset;
193+
joypad_unpack_input(current.state->input).reset;
185194
if (current.state != NULL) {
186195
JoypadStateIter iter = joypad_get_next_state(current);
187196
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) {
190199
return iter.state->ticks;
191200
}
192201
iter = joypad_get_next_state(iter);
@@ -257,7 +266,7 @@ static void joypad_truncate_to(JoypadBuffer *buffer, JoypadStateIter iter) {
257266
}
258267
iter.chunk->next = sentinel;
259268
sentinel->prev = iter.chunk;
260-
buffer->last_buttons = joypad_unpack_buttons(iter.state->buttons);
269+
buffer->last_input = joypad_unpack_input(iter.state->input);
261270
}
262271

263272
static JoypadStateIter joypad_get_next_state(JoypadStateIter iter) {
@@ -272,24 +281,38 @@ static JoypadStateIter joypad_get_next_state(JoypadStateIter iter) {
272281
return iter;
273282
}
274283

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);
279294
}
280295

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;
293316
}
294317

295318
JoypadStats joypad_get_stats(Joypad* joypad) {
@@ -361,8 +384,7 @@ static Result joypad_read(const FileData *file_data,
361384
ON_ERROR_RETURN;
362385
}
363386

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,
366388
bool strobe) {
367389
bool changed = false;
368390
JoypadPlayback* playback = user_data;
@@ -382,17 +404,16 @@ static void joypad_playback_callback(struct JoypadButtons* joyp,
382404
changed = true;
383405
}
384406

385-
#if DEBUG_JOYPAD_BUTTONS
407+
#if DEBUG_SYSTEM_INPUT
386408
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));
390411
}
391412
#else
392413
(void)changed;
393414
#endif
394415

395-
*joyp = joypad_unpack_buttons(playback->current.state->buttons);
416+
*input = joypad_unpack_input(playback->current.state->input);
396417
}
397418

398419
static void init_joypad_playback_state(Emulator *e, JoypadPlayback *playback,
@@ -435,10 +456,6 @@ static Result joypad_read_movie(const FileData *file_data,
435456
size_t j;
436457
CHECK_MSG(frame->latch != 0, "Expected latch to be non-zero at index %zu\n",
437458
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-
}
442459
total_latches += frame->latch;
443460
}
444461

@@ -463,12 +480,11 @@ static void init_joypad_movie_playback_state(JoypadMoviePlayback *playback,
463480
playback->current_frame_latch = 0;
464481
playback->current_total_latch = 0;
465482
playback->max_latches = 0;
466-
memset(&playback->last_buttons, 0, sizeof(JoypadButtons));
483+
memset(&playback->last_input, 0, sizeof(SystemInput));
467484
}
468485

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) {
472488
JoypadMoviePlayback* playback = user_data;
473489

474490
Ticks ticks = emulator_get_ticks(playback->e);
@@ -482,7 +498,7 @@ static void joypad_movie_playback_callback(struct JoypadButtons *joyp,
482498
#undef GET_TICKS
483499
#undef CMP_LT
484500

485-
u8 last_buttons = 0;
501+
u32 last_input = 0;
486502
size_t total_latch_index = lower_bound - begin;
487503
u32 total_latches = 0;
488504
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,
492508
playback->current_frame = i;
493509
playback->current_frame_latch = total_latch_index - total_latches;
494510
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);
496512
break;
497513
}
498514
total_latches += frame->latch;
499-
last_buttons = frame->buttons[0];
515+
last_input = frame->input;
500516
}
501517

502518
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,
520536
}
521537
if (++playback->current_frame_latch >= frame->latch) {
522538
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);
524540
++playback->current_frame;
525541
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' : '_');
534559
} else {
535560
LOG("\n");
536561
}
537562
}
538563

539-
*joyp = playback->last_buttons;
564+
*input = playback->last_input;
540565
}
541566

542567
Result joypad_new_for_movie(Emulator *e, FileData *file_data, Joypad **out) {
@@ -573,8 +598,8 @@ void joypad_truncate_to_current(Joypad* joypad) {
573598
if (joypad->mode == JOYPAD_MODE_USER) {
574599
joypad_truncate_to(joypad->buffer, joypad->playback.current);
575600
/* 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);
578603
}
579604
}
580605

‎src/joypad.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extern "C" {
1414
#endif
1515

1616
struct Emulator;
17-
typedef void (*JoypadCallback)(struct JoypadButtons joyp[2], void *user_data,
17+
typedef void (*JoypadCallback)(struct SystemInput *input, void *user_data,
1818
bool strobe);
1919

2020
typedef struct Joypad Joypad;
@@ -37,7 +37,7 @@ Result joypad_new_for_playback(struct Emulator *, FileData *,
3737
Result joypad_new_for_movie(struct Emulator *, FileData *, struct Joypad **out);
3838
void joypad_delete(struct Joypad*);
3939

40-
void joypad_append_if_new(struct Joypad *, JoypadButtons *, Ticks);
40+
void joypad_append_if_new(struct Joypad *, SystemInput *, Ticks);
4141
void joypad_append_reset(struct Joypad *, bool set, Ticks);
4242
Ticks joypad_get_next_reset_change(struct Joypad *);
4343
void joypad_begin_rewind_playback(struct Joypad *);

0 commit comments

Comments
 (0)
Please sign in to comment.