mirror of https://github.com/bsnes-emu/bsnes.git
Fix SGB multiplayer, improve multiplayer accuracy
This commit is contained in:
parent
eaa1c1cd4a
commit
4fcc921b46
|
@ -858,7 +858,7 @@ void GB_reset(GB_gameboy_t *gb)
|
||||||
gb->mbc_rom_bank = 1;
|
gb->mbc_rom_bank = 1;
|
||||||
gb->last_rtc_second = time(NULL);
|
gb->last_rtc_second = time(NULL);
|
||||||
gb->cgb_ram_bank = 1;
|
gb->cgb_ram_bank = 1;
|
||||||
gb->io_registers[GB_IO_JOYP] = 0xF;
|
gb->io_registers[GB_IO_JOYP] = 0xCF;
|
||||||
gb->mbc_ram_size = mbc_ram_size;
|
gb->mbc_ram_size = mbc_ram_size;
|
||||||
if (GB_is_cgb(gb)) {
|
if (GB_is_cgb(gb)) {
|
||||||
gb->ram_size = 0x1000 * 8;
|
gb->ram_size = 0x1000 * 8;
|
||||||
|
|
|
@ -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 : 0;
|
uint8_t current_player = gb->sgb? (gb->sgb->current_player & (gb->sgb->player_count - 1)) : 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) {
|
||||||
|
@ -73,7 +73,7 @@ void GB_icd_set_joyp(GB_gameboy_t *gb, uint8_t value)
|
||||||
if (previous_state & ~(gb->io_registers[GB_IO_JOYP] & 0xF)) {
|
if (previous_state & ~(gb->io_registers[GB_IO_JOYP] & 0xF)) {
|
||||||
gb->io_registers[GB_IO_IF] |= 0x10;
|
gb->io_registers[GB_IO_IF] |= 0x10;
|
||||||
}
|
}
|
||||||
|
gb->io_registers[GB_IO_JOYP] |= 0xC0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB_set_key_state(GB_gameboy_t *gb, GB_key_t index, bool pressed)
|
void GB_set_key_state(GB_gameboy_t *gb, GB_key_t index, bool pressed)
|
||||||
|
|
|
@ -746,9 +746,11 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GB_IO_JOYP:
|
case GB_IO_JOYP:
|
||||||
|
if ((gb->io_registers[GB_IO_JOYP] & 0x30) != (value & 0x30)) {
|
||||||
gb->io_registers[GB_IO_JOYP] = value & 0xF0;
|
gb->io_registers[GB_IO_JOYP] = value & 0xF0;
|
||||||
GB_sgb_write(gb, value);
|
GB_sgb_write(gb, value);
|
||||||
GB_update_joyp(gb);
|
GB_update_joyp(gb);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GB_IO_BIOS:
|
case GB_IO_BIOS:
|
||||||
|
|
13
Core/sgb.c
13
Core/sgb.c
|
@ -338,7 +338,6 @@ static void command_ready(GB_gameboy_t *gb)
|
||||||
break;
|
break;
|
||||||
case MLT_REQ:
|
case MLT_REQ:
|
||||||
gb->sgb->player_count = (uint8_t[]){1, 2, 1, 4}[gb->sgb->command[1] & 3];
|
gb->sgb->player_count = (uint8_t[]){1, 2, 1, 4}[gb->sgb->command[1] & 3];
|
||||||
gb->sgb->current_player = gb->sgb->player_count - 1;
|
|
||||||
break;
|
break;
|
||||||
case CHR_TRN:
|
case CHR_TRN:
|
||||||
gb->sgb->vram_transfer_countdown = 2;
|
gb->sgb->vram_transfer_countdown = 2;
|
||||||
|
@ -382,13 +381,16 @@ void GB_sgb_write(GB_gameboy_t *gb, uint8_t value)
|
||||||
if (gb->joyp_write_callback) {
|
if (gb->joyp_write_callback) {
|
||||||
gb->joyp_write_callback(gb, value);
|
gb->joyp_write_callback(gb, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GB_is_sgb(gb)) return;
|
if (!GB_is_sgb(gb)) return;
|
||||||
if (!GB_is_hle_sgb(gb)) {
|
if (!GB_is_hle_sgb(gb)) {
|
||||||
/* Notify via callback */
|
/* Notify via callback */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gb->sgb->disable_commands) return;
|
if (gb->sgb->disable_commands) return;
|
||||||
if (gb->sgb->command_write_index >= sizeof(gb->sgb->command) * 8) return;
|
if (gb->sgb->command_write_index >= sizeof(gb->sgb->command) * 8) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t command_size = (gb->sgb->command[0] & 7 ?: 1) * SGB_PACKET_SIZE * 8;
|
uint16_t command_size = (gb->sgb->command[0] & 7 ?: 1) * SGB_PACKET_SIZE * 8;
|
||||||
if ((gb->sgb->command[0] & 0xF1) == 0xF1) {
|
if ((gb->sgb->command[0] & 0xF1) == 0xF1) {
|
||||||
|
@ -398,10 +400,10 @@ void GB_sgb_write(GB_gameboy_t *gb, uint8_t value)
|
||||||
switch ((value >> 4) & 3) {
|
switch ((value >> 4) & 3) {
|
||||||
case 3:
|
case 3:
|
||||||
gb->sgb->ready_for_pulse = true;
|
gb->sgb->ready_for_pulse = true;
|
||||||
/* TODO: This is the logic used by BGB which *should* work for most/all games, but a proper test ROM is needed */
|
if (gb->sgb->player_count > 1 && !gb->sgb->mlt_lock) {
|
||||||
if (gb->sgb->player_count > 1 && (gb->io_registers[GB_IO_JOYP] & 0x30) == 0x10) {
|
|
||||||
gb->sgb->current_player++;
|
gb->sgb->current_player++;
|
||||||
gb->sgb->current_player &= gb->sgb->player_count - 1;
|
gb->sgb->current_player &= 3;
|
||||||
|
gb->sgb->mlt_lock = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -426,6 +428,7 @@ 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");
|
||||||
|
|
|
@ -52,6 +52,9 @@ struct GB_sgb_s {
|
||||||
|
|
||||||
/* GB Header */
|
/* GB Header */
|
||||||
uint8_t received_header[0x54];
|
uint8_t received_header[0x54];
|
||||||
|
|
||||||
|
/* Multiplayer (cont) */
|
||||||
|
bool mlt_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GB_sgb_write(GB_gameboy_t *gb, uint8_t value);
|
void GB_sgb_write(GB_gameboy_t *gb, uint8_t value);
|
||||||
|
|
Loading…
Reference in New Issue