97 lines
2.5 KiB
C++
97 lines
2.5 KiB
C++
// Meteor - A Nintendo Gameboy Advance emulator
|
|
// Copyright (C) 2009-2011 Philippe Daouadi
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include "ameteor/keypad.hpp"
|
|
#include "globals.hpp"
|
|
#include "ameteor.hpp"
|
|
|
|
namespace AMeteor
|
|
{
|
|
Keypad::Keypad () :
|
|
m_keyinput(IO.GetRef16(Io::KEYINPUT)),
|
|
m_keycnt(IO.GetRef16(Io::KEYCNT))
|
|
{
|
|
}
|
|
|
|
void Keypad::KeyPressed(int code)
|
|
{
|
|
if (m_keys.count(code))
|
|
m_keyinput &= ~m_keys[code];
|
|
}
|
|
|
|
void Keypad::KeyReleased(int code)
|
|
{
|
|
if (m_keys.count(code))
|
|
m_keyinput |= m_keys[code];
|
|
}
|
|
|
|
void Keypad::JoyButtonPressed (uint16_t joyid, uint16_t button)
|
|
{
|
|
uint32_t id = ((int)joyid) << 16 | button;
|
|
if (m_joys.count(id))
|
|
m_keyinput &= ~m_joys[id];
|
|
}
|
|
|
|
void Keypad::JoyButtonReleased (uint16_t joyid, uint16_t button)
|
|
{
|
|
uint32_t id = ((int)joyid) << 16 | button;
|
|
if (m_joys.count(id))
|
|
m_keyinput |= m_joys[id];
|
|
}
|
|
|
|
void Keypad::JoyMoved (uint16_t joyid, uint16_t axis, float pos)
|
|
{
|
|
uint32_t id = (((int)joyid) << 16) | ((pos < 0) << 15) | (axis & 0x7FFF);
|
|
// if pos is 0, we disable the positive and negative targets
|
|
if (pos == 0)
|
|
{
|
|
if (m_axis.count(id))
|
|
m_keyinput |= m_axis[id];
|
|
if (m_axis.count(id | (1 << 15)))
|
|
m_keyinput |= m_axis[id | (1 << 15)];
|
|
}
|
|
else
|
|
{
|
|
// we enable the corresponding button
|
|
if (m_axis.count(id))
|
|
m_keyinput &= ~((uint16_t)m_axis[id]);
|
|
// we disable the opposite button (we may have skipped 0)
|
|
if (m_axis.count(id ^ 0x8000))
|
|
m_keyinput |= m_axis[id ^ 0x8000];
|
|
}
|
|
}
|
|
|
|
void Keypad::VBlank ()
|
|
{
|
|
// if keypad IRQ are enabled
|
|
if (m_keycnt & (0x1 << 14))
|
|
// if irq condition is and
|
|
if (m_keycnt & (0x1 << 15))
|
|
{
|
|
// if condition is satisfied
|
|
if ((~m_keyinput & m_keycnt & 0x3FF) == (m_keycnt & 0x3FF))
|
|
CPU.SendInterrupt(0x1000);
|
|
}
|
|
// if irq condition is or
|
|
else
|
|
{
|
|
// if condition is satisfied
|
|
if (~m_keyinput & m_keycnt & 0x3FF)
|
|
CPU.SendInterrupt(0x1000);
|
|
}
|
|
}
|
|
}
|