mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-04-02 10:42:14 -04:00
byuu says: Changelog: - GBA: SOUND_CTL_H is readable, fixes sound effects in Mario&Luigi Superstar Saga [Cydrak] (note: game is still unplayable due to other bugs) - phoenix/Windows: workaround for Win32 API ListView bug, fixes slot loading behavior - ruby: added udev driver for Linux with rumble support, and added rumble support to existing RawInput driver for XInput and DirectInput - ethos: added new "Rumble" mapping to GBA input assignment, use it to tell higan which controller to rumble (clear it to disable rumble) - GBA: Game Boy Player rumble is now fully emulated - core: added new normalized raw-color palette mode for Display Emulation shaders The way rumble was added to ethos was somewhat hackish. The support doesn't really exist in nall. I need to redesign the entire input system, but that's not a change I want to make so close to a release.
89 lines
2.3 KiB
C++
89 lines
2.3 KiB
C++
#include <gba/gba.hpp>
|
|
|
|
namespace GameBoyAdvance {
|
|
|
|
//Game Boy Player emulation
|
|
|
|
#include "serialization.cpp"
|
|
Player player;
|
|
|
|
void Player::power() {
|
|
status.enable = false;
|
|
status.rumble = false;
|
|
|
|
status.logoDetected = false;
|
|
status.logoCounter = 0;
|
|
|
|
status.packet = 0;
|
|
status.send = 0;
|
|
status.recv = 0;
|
|
}
|
|
|
|
void Player::frame() {
|
|
uint32 hash = crc32_calculate((const uint8*)ppu.output, 240 * 160 * sizeof(uint32));
|
|
status.logoDetected = (hash == 0x7776eb55);
|
|
|
|
if(status.logoDetected) {
|
|
status.enable = true;
|
|
status.logoCounter = (status.logoCounter + 1) % 3;
|
|
status.packet = 0;
|
|
}
|
|
|
|
if(status.enable == false) return;
|
|
|
|
if(cpu.regs.joybus.settings == 0x0000 && cpu.regs.serial.control == 0x5088) {
|
|
status.packet = (status.packet + 1) % 17;
|
|
switch(status.packet) {
|
|
case 0: status.send = 0x0000494e; break;
|
|
case 1: status.send = 0xb6b1494e; break;
|
|
case 2: status.send = 0xb6b1494e; break;
|
|
case 3: status.send = 0xb6b1544e; break;
|
|
case 4: status.send = 0xabb1544e; break;
|
|
case 5: status.send = 0xabb14e45; break;
|
|
case 6: status.send = 0xb1ba4e45; break;
|
|
case 7: status.send = 0xb1ba4f44; break;
|
|
case 8: status.send = 0xb0bb4f44; break;
|
|
case 9: status.send = 0xb0bb8002; break;
|
|
case 10: status.send = 0x10000010; break;
|
|
case 11: status.send = 0x20000013; break;
|
|
case 12: status.send = 0x30000003; break;
|
|
case 13: status.send = 0x30000003; break;
|
|
case 14: status.send = 0x30000003; break;
|
|
case 15: status.send = 0x30000003; break;
|
|
case 16: status.send = 0x30000003; break;
|
|
}
|
|
cpu.regs.irq.flag.serial = true;
|
|
}
|
|
}
|
|
|
|
optional<uint16> Player::keyinput() {
|
|
if(status.logoDetected == false) return false;
|
|
|
|
switch(status.logoCounter) {
|
|
case 0: return {true, 0x03ff};
|
|
case 1: return {true, 0x03ff};
|
|
case 2: return {true, 0x030f};
|
|
}
|
|
unreachable;
|
|
}
|
|
|
|
optional<uint32> Player::read() {
|
|
if(status.enable == false) return false;
|
|
|
|
return {true, status.send};
|
|
}
|
|
|
|
void Player::write(uint8 byte, uint2 addr) {
|
|
if(status.enable == false) return;
|
|
|
|
unsigned shift = addr << 3;
|
|
status.recv &= ~(255 << shift);
|
|
status.recv |= byte << shift;
|
|
|
|
if(addr == 3 && status.packet == 15) {
|
|
status.rumble = (status.recv & 0xff) == 0x26; //on = 0x26, off = 0x04
|
|
interface->inputRumble(0, 0, 10, status.rumble);
|
|
}
|
|
}
|
|
|
|
}
|