Pass the SGB multiplayer tests

This commit is contained in:
Lior Halphon 2019-09-14 12:31:52 +03:00
parent 851dbd3ccd
commit 652e52df3d
3 changed files with 16 additions and 5 deletions

View File

@ -12,7 +12,7 @@ void GB_update_joyp(GB_gameboy_t *gb)
previous_state = gb->io_registers[GB_IO_JOYP] & 0xF; previous_state = gb->io_registers[GB_IO_JOYP] & 0xF;
key_selection = (gb->io_registers[GB_IO_JOYP] >> 4) & 3; key_selection = (gb->io_registers[GB_IO_JOYP] >> 4) & 3;
gb->io_registers[GB_IO_JOYP] &= 0xF0; gb->io_registers[GB_IO_JOYP] &= 0xF0;
uint8_t current_player = gb->sgb? (gb->sgb->current_player & (gb->sgb->player_count - 1)) : 0; uint8_t current_player = gb->sgb? (gb->sgb->current_player & (gb->sgb->player_count - 1) & 3) : 0;
switch (key_selection) { switch (key_selection) {
case 3: case 3:
if (gb->sgb && gb->sgb->player_count > 1) { if (gb->sgb && gb->sgb->player_count > 1) {

View File

@ -747,8 +747,8 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
case GB_IO_JOYP: case GB_IO_JOYP:
if ((gb->io_registers[GB_IO_JOYP] & 0x30) != (value & 0x30)) { if ((gb->io_registers[GB_IO_JOYP] & 0x30) != (value & 0x30)) {
gb->io_registers[GB_IO_JOYP] = value & 0xF0;
GB_sgb_write(gb, value); GB_sgb_write(gb, value);
gb->io_registers[GB_IO_JOYP] = value & 0xF0;
GB_update_joyp(gb); GB_update_joyp(gb);
} }
return; return;

View File

@ -337,7 +337,15 @@ static void command_ready(GB_gameboy_t *gb)
// Not supported, but used by almost all SGB games for hot patching, so let's mute the warning for this // Not supported, but used by almost all SGB games for hot patching, so let's mute the warning for this
break; break;
case MLT_REQ: case MLT_REQ:
gb->sgb->player_count = (uint8_t[]){1, 2, 1, 4}[gb->sgb->command[1] & 3]; if (gb->sgb->player_count == 1) {
gb->sgb->current_player = 0;
}
gb->sgb->player_count = (gb->sgb->command[1] & 3) + 1; /* Todo: When breaking save state comaptibility,
fix this to be 0 based. */
if (gb->sgb->player_count == 3) {
gb->sgb->current_player++;
}
gb->sgb->mlt_lock = true;
break; break;
case CHR_TRN: case CHR_TRN:
gb->sgb->vram_transfer_countdown = 2; gb->sgb->vram_transfer_countdown = 2;
@ -397,10 +405,14 @@ void GB_sgb_write(GB_gameboy_t *gb, uint8_t value)
command_size = SGB_PACKET_SIZE * 8; command_size = SGB_PACKET_SIZE * 8;
} }
if ((value & 0x20) == 0 && (gb->io_registers[GB_IO_JOYP] & 0x20) != 0) {
gb->sgb->mlt_lock ^= true;
}
switch ((value >> 4) & 3) { switch ((value >> 4) & 3) {
case 3: case 3:
gb->sgb->ready_for_pulse = true; gb->sgb->ready_for_pulse = true;
if (gb->sgb->player_count > 1 && !gb->sgb->mlt_lock) { if ((gb->sgb->player_count & 1) == 0 && !gb->sgb->mlt_lock) {
gb->sgb->current_player++; gb->sgb->current_player++;
gb->sgb->current_player &= 3; gb->sgb->current_player &= 3;
gb->sgb->mlt_lock = true; gb->sgb->mlt_lock = true;
@ -428,7 +440,6 @@ void GB_sgb_write(GB_gameboy_t *gb, uint8_t value)
} }
break; break;
case 1: // One case 1: // One
gb->sgb->mlt_lock ^= true;
if (!gb->sgb->ready_for_pulse || !gb->sgb->ready_for_write) return; if (!gb->sgb->ready_for_pulse || !gb->sgb->ready_for_write) return;
if (gb->sgb->ready_for_stop) { if (gb->sgb->ready_for_stop) {
GB_log(gb, "Corrupt SGB command.\n"); GB_log(gb, "Corrupt SGB command.\n");