mirror of
https://github.com/birth1mark/orbis8.git
synced 2026-10-29 01:00:32 +01:00
124 lines
3.0 KiB
C++
124 lines
3.0 KiB
C++
#include <algorithm>
|
|
|
|
#include "Input.h"
|
|
#include "hostVmShared.h"
|
|
#include "PicoRam.h"
|
|
|
|
Input::Input(PicoRam* memory):
|
|
_currentKDown(0),
|
|
_currentKHeld(0)
|
|
{
|
|
_memory = memory;
|
|
|
|
std::fill(_framesHeld, _framesHeld + 8, 0);
|
|
}
|
|
|
|
void Input::SetState(uint8_t kdown, uint8_t kheld){
|
|
_currentKDown = kdown;
|
|
_currentKHeld = kheld;
|
|
//key 6 (PAUSE MENU) only fires for one frame, even if held
|
|
if ((_currentKHeld & BITMASK(6)) && !(_currentKDown & BITMASK(6))) {
|
|
_currentKHeld = _currentKHeld & ~(BITMASK(6));
|
|
}
|
|
//memory only stores buttons 0-5, not 6 or 7
|
|
_memory->hwState.buttonStates[0] = kheld & 0x3F;
|
|
|
|
uint8_t repeatDelay = _memory->hwState.btnpRepeatDelay == 0
|
|
? 15
|
|
: _memory->hwState.btnpRepeatDelay;
|
|
|
|
if (repeatDelay == 255){
|
|
return;
|
|
}
|
|
|
|
uint8_t repeatInterval = _memory->hwState.btnpRepeatInterval == 0
|
|
? 4
|
|
: _memory->hwState.btnpRepeatDelay;
|
|
|
|
for (int i = 0; i < 7; i ++) {
|
|
bool down = BITMASK(i) & kheld;
|
|
|
|
_framesHeld[i] = down ? _framesHeld[i] + 1 : 0;
|
|
|
|
//update kdown to be true if held for 15 frames, then every 4th after that.
|
|
//from wiki:
|
|
//btnp() implements a keyboard-like repeat mechanism: if the player holds
|
|
//the button for 15 frames, it registers as on again for one frame, then
|
|
//again every four frames after that. The frame counter resets when the
|
|
//player releases the button.
|
|
|
|
bool repeatPressed =
|
|
(_framesHeld[i] == repeatDelay) ||
|
|
(_framesHeld[i] / repeatDelay >= 1 && _framesHeld[i] % repeatInterval == 0);
|
|
|
|
if (repeatPressed) {
|
|
_currentKDown = _currentKDown | BITMASK(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Input::SetMouse(int16_t mouseX, int16_t mouseY, uint8_t mouseBtnState){
|
|
_mouseX = mouseX;
|
|
_mouseY = mouseY;
|
|
_mouseBtnState = mouseBtnState;
|
|
}
|
|
|
|
void Input::SetKeyboard(bool kbDown, std::string kbKey){
|
|
_kbDown = kbDown;
|
|
_kbKey = kbKey;
|
|
}
|
|
|
|
uint8_t Input::btn(){
|
|
return _currentKHeld;
|
|
}
|
|
|
|
//todo: repetition behavior to match pico 8
|
|
uint8_t Input::btnp(){
|
|
return _currentKDown;
|
|
}
|
|
|
|
bool Input::btn(uint8_t i){
|
|
return BITMASK(i) & btn();
|
|
}
|
|
|
|
//todo: repetition behavior to match pico 8
|
|
bool Input::btnp(uint8_t i){
|
|
return BITMASK(i) & btnp();
|
|
}
|
|
|
|
bool Input::btn(uint8_t i, uint8_t p){
|
|
//no multiplayer support for now
|
|
return p == 0 ? btn(i) : 0;
|
|
}
|
|
|
|
//todo: repetition behavior to match pico 8
|
|
bool Input::btnp(uint8_t i, uint8_t p){
|
|
//no multiplayer support for now
|
|
return p == 0 ? btnp(i) : 0;
|
|
}
|
|
|
|
int16_t Input::getMouseX() {
|
|
return _mouseX;
|
|
}
|
|
|
|
int16_t Input::getMouseY() {
|
|
return _mouseY;
|
|
}
|
|
|
|
uint8_t Input::getMouseBtnState() {
|
|
return _mouseBtnState;
|
|
}
|
|
|
|
bool Input::getKeyDown() {
|
|
return _kbDown;
|
|
}
|
|
|
|
const char* Input::getKey() {
|
|
// Found this bug in Terra
|
|
// PICO-8 behavior: stat(31) appears to consume the key from the buffer
|
|
// After reading, stat(30) should return false until next key press
|
|
_kbDown = false;
|
|
return _kbKey.c_str();
|
|
}
|
|
|