Merge pull request #310 from Daft-Freak/buttons
Button API improvements
diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c
index eaae73d..1a0ee0f 100644
--- a/32blit-stm32/Src/32blit.c
+++ b/32blit-stm32/Src/32blit.c
@@ -72,7 +72,9 @@
static void init_api_shared() {
// Reset button state, this prevents the user app immediately seeing the last button transition used to launch the game
- api.buttons = 0;
+ api.buttons.state = 0;
+ api.buttons.pressed = 0;
+ api.buttons.released = 0;
// reset shared outputs
api.vibration = 0.0f;
@@ -421,16 +423,14 @@
Rect menu_item_frame (MenuItem item, float screen_width) { return Rect (0, item * 10 + 19, screen_width, 9); }
void blit_menu_update(uint32_t time) {
- static uint32_t last_buttons = 0;
- uint32_t changed_buttons = blit::buttons ^ last_buttons;
- if(blit::buttons & changed_buttons & blit::Button::DPAD_UP) {
+ if(blit::buttons.pressed & blit::Button::DPAD_UP) {
menu_item --;
- } else if (blit::buttons & changed_buttons & blit::Button::DPAD_DOWN) {
+ } else if (blit::buttons.pressed & blit::Button::DPAD_DOWN) {
menu_item ++;
} else {
- bool button_a = blit::buttons & changed_buttons & blit::Button::A;
+ bool button_a = blit::buttons.pressed & blit::Button::A;
switch(menu_item) {
case BACKLIGHT:
if (blit::buttons & blit::Button::DPAD_LEFT) {
@@ -468,8 +468,6 @@
break;
}
}
-
- last_buttons = blit::buttons;
}
void blit_menu_render(uint32_t time) {
diff --git a/32blit/engine/api.cpp b/32blit/engine/api.cpp
index b2c44cf..3bb72d8 100644
--- a/32blit/engine/api.cpp
+++ b/32blit/engine/api.cpp
@@ -15,7 +15,7 @@
static_assert(sizeof(API) < 2048);
- uint32_t &buttons = api.buttons;
+ ButtonState &buttons = api.buttons;
float &hack_left = api.hack_left;
float &hack_right = api.hack_right;
float &vibration = api.vibration;
diff --git a/32blit/engine/api.hpp b/32blit/engine/api.hpp
index 31a380b..52f65ce 100644
--- a/32blit/engine/api.hpp
+++ b/32blit/engine/api.hpp
@@ -7,7 +7,7 @@
#include "../types/vec3.hpp"
namespace blit {
- extern uint32_t &buttons;
+ extern ButtonState &buttons;
extern float &hack_left;
extern float &hack_right;
extern float &vibration;
diff --git a/32blit/engine/api_private.hpp b/32blit/engine/api_private.hpp
index b06db14..2814e39 100644
--- a/32blit/engine/api_private.hpp
+++ b/32blit/engine/api_private.hpp
@@ -6,6 +6,7 @@
#include "engine.hpp"
#include "file.hpp"
#include "../audio/audio.hpp"
+#include "../engine/input.hpp"
#include "../graphics/jpeg.hpp"
#include "../graphics/surface.hpp"
#include "../types/vec2.hpp"
@@ -14,7 +15,7 @@
namespace blit {
#pragma pack(push, 4)
struct API {
- uint32_t buttons;
+ ButtonState buttons;
float hack_left;
float hack_right;
float vibration;
diff --git a/32blit/engine/engine.cpp b/32blit/engine/engine.cpp
index 3fd7d98..0d3bed0 100644
--- a/32blit/engine/engine.cpp
+++ b/32blit/engine/engine.cpp
@@ -68,6 +68,8 @@
while (pending_update_time >= update_rate_ms) {
update(time - pending_update_time); // create fake timestamp that would have been accurate for the update event
pending_update_time -= update_rate_ms;
+
+ api.buttons.pressed = api.buttons.released = 0;
}
last_tick_time = time;
diff --git a/32blit/engine/input.cpp b/32blit/engine/input.cpp
index a3a6519..d963d77 100644
--- a/32blit/engine/input.cpp
+++ b/32blit/engine/input.cpp
@@ -13,7 +13,7 @@
* \return `true` for pressed, `false` for released.
*/
bool pressed(uint32_t button) {
- return buttons & button;
+ return buttons.state & button;
}
}
\ No newline at end of file
diff --git a/32blit/engine/input.hpp b/32blit/engine/input.hpp
index 488f776..b82dae5 100644
--- a/32blit/engine/input.hpp
+++ b/32blit/engine/input.hpp
@@ -19,6 +19,25 @@
JOYSTICK = 1024
};
- extern bool pressed(uint32_t button);
+ struct ButtonState {
+ ButtonState &operator=(uint32_t v) {
+ uint32_t changed = state ^ v;
+ pressed |= changed & v;
+ released |= changed & state;
+
+ state = v;
+
+ return *this;
+ }
+
+ operator uint32_t() const {
+ return state;
+ }
+
+ uint32_t state;
+ uint32_t pressed, released; // state change since last update
+ };
+
+ extern bool pressed(uint32_t button);
}
diff --git a/examples/profiler-test/profiler-test.cpp b/examples/profiler-test/profiler-test.cpp
index 93af4e3..66df80e 100644
--- a/examples/profiler-test/profiler-test.cpp
+++ b/examples/profiler-test/profiler-test.cpp
@@ -83,24 +83,21 @@
void render(uint32_t time)
{
static Point ptMiddle(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
- static uint32_t lastButtons = 0;
//static ProfilerProbe *pAwayRenderProbe = g_profiler.AddProbe("AwayFromRender");
//pAwayRenderProbe->StoreElapsedUs(true);
- uint32_t changedButtons = buttons ^ lastButtons;
-
- bool button_a = buttons & changedButtons & Button::A;
- bool button_b = buttons & changedButtons & Button::B;
- bool button_x = buttons & changedButtons & Button::X;
- bool button_y = buttons & changedButtons & Button::Y;
- bool button_up = buttons & changedButtons & Button::DPAD_UP;
- bool button_down = buttons & changedButtons & Button::DPAD_DOWN;
- bool button_left = buttons & changedButtons & Button::DPAD_LEFT;
- bool button_right = buttons & changedButtons & Button::DPAD_RIGHT;
- bool button_home = buttons & changedButtons & Button::HOME;
+ bool button_a = buttons.pressed & Button::A;
+ bool button_b = buttons.pressed & Button::B;
+ bool button_x = buttons.pressed & Button::X;
+ bool button_y = buttons.pressed & Button::Y;
+ bool button_up = buttons.pressed & Button::DPAD_UP;
+ bool button_down = buttons.pressed & Button::DPAD_DOWN;
+ bool button_left = buttons.pressed & Button::DPAD_LEFT;
+ bool button_right = buttons.pressed & Button::DPAD_RIGHT;
+ bool button_home = buttons.pressed & Button::HOME;
if(button_up && (g_uRows>1))
{
@@ -158,8 +155,6 @@
g_profiler.log_probes();
}
- lastButtons = buttons;
-
g_pRenderProbe->start();
// clear screen
diff --git a/examples/scrolly-tile/scrolly-tile.cpp b/examples/scrolly-tile/scrolly-tile.cpp
index 1a08302..4fedac6 100644
--- a/examples/scrolly-tile/scrolly-tile.cpp
+++ b/examples/scrolly-tile/scrolly-tile.cpp
@@ -492,11 +492,6 @@
}
void update(uint32_t time_ms) {
- static uint16_t last_buttons = 0;
- uint16_t changed = buttons ^ last_buttons;
- uint16_t pressed = changed & buttons;
- uint16_t released = changed & ~buttons;
-
int32_t water_dist = player_position.y - (SCREEN_H - water_level);
if (water_dist < 0) {
water_dist = 0;
@@ -506,38 +501,36 @@
#endif
if (game_state == enum_state::menu) {
- if(pressed & Button::B) {
+ if(buttons.pressed & Button::B) {
new_game();
}
- else if(pressed & Button::DPAD_UP) {
+ else if(buttons.pressed & Button::DPAD_UP) {
current_random_source = RANDOM_TYPE_PRNG;
new_level();
}
- else if(pressed & Button::DPAD_DOWN) {
+ else if(buttons.pressed & Button::DPAD_DOWN) {
current_random_source = RANDOM_TYPE_HRNG;
new_level();
}
- else if(pressed & Button::DPAD_RIGHT) {
+ else if(buttons.pressed & Button::DPAD_RIGHT) {
if(current_random_source == RANDOM_TYPE_PRNG) {
current_random_seed++;
new_level();
}
}
- else if(pressed & Button::DPAD_LEFT) {
+ else if(buttons.pressed & Button::DPAD_LEFT) {
if(current_random_source == RANDOM_TYPE_PRNG) {
current_random_seed--;
new_level();
}
}
- last_buttons = buttons;
return;
}
if(game_state == enum_state::dead){
- if(pressed & Button::B) {
+ if(buttons.pressed & Button::B) {
game_state = enum_state::menu;
}
- last_buttons = buttons;
return;
}
@@ -583,7 +576,7 @@
}
if(player_jump_count){
- if(pressed & Button::A) {
+ if(buttons.pressed & Button::A) {
if(player_state == wall_left
|| player_state == wall_right
|| player_state == near_wall_left
@@ -668,8 +661,6 @@
}
for_each_tile(collide_player_ud, (void *)&tile_offset);
}
-
- last_buttons = buttons;
}
void render_summary() {
diff --git a/examples/text/text.cpp b/examples/text/text.cpp
index 7771895..80dfc33 100644
--- a/examples/text/text.cpp
+++ b/examples/text/text.cpp
@@ -3,7 +3,6 @@
using namespace blit;
bool variable_width = true;
-uint32_t prev_buttons = buttons;
TextAlign alignment = TextAlign::top_left;
std::string alignment_to_string(TextAlign alignment) {
@@ -77,7 +76,7 @@
}
void update(uint32_t time) {
- if ((prev_buttons & Button::A) && !(buttons & Button::A))
+ if (buttons.released & Button::A)
variable_width = !variable_width;
alignment = TextAlign::top_left;
@@ -95,6 +94,4 @@
else if (!(buttons & Button::DPAD_LEFT)) {
alignment = (TextAlign)(alignment | TextAlign::center_h);
}
-
- prev_buttons = buttons;
}
diff --git a/examples/voxel/voxel.cpp b/examples/voxel/voxel.cpp
index 5464c73..ced7c47 100644
--- a/examples/voxel/voxel.cpp
+++ b/examples/voxel/voxel.cpp
@@ -233,7 +233,6 @@
void update(uint32_t time_ms) {
static uint16_t tick = 0;
- static uint32_t last_buttons = 0;
tick++;
@@ -283,13 +282,11 @@
}
}
- if(!(buttons & A) && (last_buttons & A)) {
+ if(buttons.released & A) {
terrain_index++;
if(terrain_index > 4) {
terrain_index = 1;
}
load_map();
}
-
- last_buttons = buttons;
}
\ No newline at end of file
diff --git a/firmware/flash-loader/flash-loader.cpp b/firmware/flash-loader/flash-loader.cpp
index 01803af..95813b7 100644
--- a/firmware/flash-loader/flash-loader.cpp
+++ b/firmware/flash-loader/flash-loader.cpp
@@ -260,21 +260,18 @@
void FlashLoader::RenderFlashFile(uint32_t time)
{
static uint32_t lastRepeat = 0;
- static uint32_t lastButtons = 0;
if(!m_bFsInit)
FSInit();
- uint32_t changedButtons = buttons ^ lastButtons;
+ bool button_a = buttons.pressed & Button::A;
+ bool button_x = buttons.pressed & Button::X;
+ bool button_y = buttons.pressed & Button::Y;
- bool button_a = buttons & changedButtons & Button::A;
- bool button_x = buttons & changedButtons & Button::X;
- bool button_y = buttons & changedButtons & Button::Y;
+ bool button_up = buttons.pressed & Button::DPAD_UP;
+ bool button_down = buttons.pressed & Button::DPAD_DOWN;
- bool button_up = buttons & changedButtons & Button::DPAD_UP;
- bool button_down = buttons & changedButtons & Button::DPAD_DOWN;
-
- bool button_home = buttons & changedButtons & Button::HOME;
+ bool button_home = buttons.pressed & Button::HOME;
if(time - lastRepeat > 150 || button_up || button_down) {
button_up = buttons & Button::DPAD_UP;
@@ -282,8 +279,6 @@
lastRepeat = time;
}
- lastButtons = buttons;
-
screen.pen = Pen(0,0,0);
screen.rectangle(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
screen.pen = Pen(255, 255, 255);