Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 51 additions & 12 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ uint32_t pico8_frame_start = 0;
uint32_t pico8_frame_ms = 0;

// Touch button state (when SDL_HINT_MOUSE_TOUCH_EVENTS is used).
uint8_t touch_button_state = 0;
uint8_t touch_button_state_player_0 = 0;
uint8_t touch_button_state_player_1 = 0;

// Input state: tracks how many consecutive frames each button has been held.
// Index [player][button], players 0-1, buttons 0-5.
Expand Down Expand Up @@ -1501,7 +1502,7 @@ static int pico8_btn(lua_State* L)

if (argc == 0)
{
lua_pushunsigned(L, fix32_value(pico8_ram[0x5f4c], 0));
lua_pushunsigned(L, fix32_value(pico8_ram[0x5f4c] | (pico8_ram[0x5f4d] << 8), 0));
return 1;
}

Expand Down Expand Up @@ -1542,13 +1543,16 @@ static int pico8_btnp(lua_State* L)

if (argc == 0)
{
uint8_t result = 0;
for (int b = 0; b < 6; b++)
uint16_t result = 0;
for (int p = 0; p < 2; p++)
{
uint8_t f = btn_held_frames[0][b];
if (f == 1 || (f > 15 && ((f - 15) % 4 == 0)))
for (int b = 0; b < 6; b++)
{
result |= (1 << b);
uint8_t f = btn_held_frames[p][b];
if (f == 1 || (f > 15 && ((f - 15) % 4 == 0)))
{
result |= (1 << (b + p * 8));
}
}
}
lua_pushunsigned(L, fix32_value(result, 0));
Expand Down Expand Up @@ -2727,16 +2731,48 @@ void update_input(SDL_Renderer* renderer)
state |= (1 << 5);
}
#else
if (keys[SDL_SCANCODE_Z] || keys[SDL_SCANCODE_Y] || keys[SDL_SCANCODE_C])
if (keys[SDL_SCANCODE_Z] || keys[SDL_SCANCODE_Y] || keys[SDL_SCANCODE_C] ||
keys[SDL_SCANCODE_N] || keys[SDL_SCANCODE_KP_MULTIPLY])
{
state |= (1 << 4);
}
if (keys[SDL_SCANCODE_X] || keys[SDL_SCANCODE_V])
if (keys[SDL_SCANCODE_X] || keys[SDL_SCANCODE_V] || keys[SDL_SCANCODE_M] ||
keys[SDL_SCANCODE_8])
{
state |= (1 << 5);
}
#endif
}
else
{
int num_keys = 0;
const bool* keys = SDL_GetKeyboardState(&num_keys);

if (keys[SDL_SCANCODE_S])
{
state |= (1 << 0);
}
if (keys[SDL_SCANCODE_F])
{
state |= (1 << 1);
}
if (keys[SDL_SCANCODE_E])
{
state |= (1 << 2);
}
if (keys[SDL_SCANCODE_D])
{
state |= (1 << 3);
}
if (keys[SDL_SCANCODE_LSHIFT] || keys[SDL_SCANCODE_TAB])
{
state |= (1 << 4);
}
if (keys[SDL_SCANCODE_A] || keys[SDL_SCANCODE_Q])
{
state |= (1 << 5);
}
}

// Gamepad input: first connected gamepad -> player 0, second -> player 1.
SDL_Gamepad* gp = SDL_GetGamepadFromPlayerIndex(p);
Expand Down Expand Up @@ -2768,11 +2804,14 @@ void update_input(SDL_Renderer* renderer)
}
}

// Touch button state (when SDL_HINT_MOUSE_TOUCH_EVENTS is used)
// Only applied to player 0.
// Touch button state (when SDL_HINT_MOUSE_TOUCH_EVENTS is used).
if (p == 0)
{
state |= touch_button_state;
state |= touch_button_state_player_0;
}
else
{
state |= touch_button_state_player_1;
}

pico8_ram[0x5f4c + p] = state;
Expand Down
12 changes: 6 additions & 6 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ static void update_touch_input(SDL_Renderer* renderer)
}

// Reset button state and accumulate from all active fingers.
touch_button_state = 0;
touch_button_state_player_0 = 0;

// Get touch regions for button detection.
int touch_count = 0;
Expand Down Expand Up @@ -165,7 +165,7 @@ static void update_touch_input(SDL_Renderer* renderer)
{
if (point_in_touch_region(region_x, region_y, &regions[r]))
{
touch_button_state |= (1 << regions[r].bit);
touch_button_state_player_0 |= (1 << regions[r].bit);
}
}
}
Expand Down Expand Up @@ -1182,7 +1182,7 @@ bool handle_events(SDL_Renderer* renderer, SDL_Event* event)
{
if (point_in_touch_region(region_x, region_y, &regions[i]))
{
touch_button_state |= (1 << regions[i].bit);
touch_button_state_player_0 |= (1 << regions[i].bit);

uint8_t bit = regions[i].bit;
if (bit == 99)
Expand Down Expand Up @@ -1236,7 +1236,7 @@ bool handle_events(SDL_Renderer* renderer, SDL_Event* event)
{
if (point_in_touch_region(region_x, region_y, &regions[i]))
{
touch_button_state &= ~(1 << regions[i].bit);
touch_button_state_player_0 &= ~(1 << regions[i].bit);
}
}
}
Expand Down Expand Up @@ -1335,7 +1335,7 @@ bool handle_events(SDL_Renderer* renderer, SDL_Event* event)
{
if (point_in_touch_region(region_x, region_y, &regions[i]))
{
touch_button_state |= (1 << regions[i].bit);
touch_button_state_player_0 |= (1 << regions[i].bit);

uint8_t bit = regions[i].bit;
if (bit == 99)
Expand All @@ -1355,7 +1355,7 @@ bool handle_events(SDL_Renderer* renderer, SDL_Event* event)
// Clear touch button state when touch is released.
if (event->button.button == SDL_BUTTON_LEFT && state == STATE_EMULATOR)
{
touch_button_state = 0;
touch_button_state_player_0 = 0;
}
break;
}
Expand Down
5 changes: 3 additions & 2 deletions src/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ typedef enum state

} state_t;

// Touch button state (when SDL_HINT_MOUSE_TOUCH_EVENTS is used)
extern uint8_t touch_button_state;
// Touch button state (when SDL_HINT_MOUSE_TOUCH_EVENTS is used).
extern uint8_t touch_button_state_player_0;
extern uint8_t touch_button_state_player_1;

void handle_resize(SDL_Renderer* renderer);

Expand Down
14 changes: 14 additions & 0 deletions tests/tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,7 @@ end
function test_btn()
-- No buttons pressed: btn() bitfield == 0.
poke(0x5f4c, 0x00)
poke(0x5f4d, 0x00)
assert_equal(btn(), 0, "btn() no buttons")

-- Single button: btn(b) returns true when bit b is set.
Expand Down Expand Up @@ -1334,6 +1335,11 @@ function test_btn()
assert_true(btn(0, 1) == true, "btn(0,1) p1 pressed")
assert_true(btn(0, 0) == false, "btn(0,0) p0 not pressed")

-- No-argument btn() includes player 1 in bits 8-13.
poke(0x5f4c, 0x3f)
poke(0x5f4d, 0x3f)
assert_equal(btn(), 0x3f3f, "btn() both players")

-- Clean up.
poke(0x5f4c, 0x00)
poke(0x5f4d, 0x00)
Expand Down Expand Up @@ -1379,11 +1385,19 @@ function test_btnp()
assert_true(btnp(6) == false, "btnp(6) out of range")
assert_true(btnp(-1) == false, "btnp(-1) out of range")

for b = 0, 5 do
set_btnp_frames(b, 0)
end

-- Player 1: set frame count for p1 button 3.
set_btnp_frames(3, 1, 1)
assert_true(btnp(3, 1) == true, "btnp(3,1) p1 first press")
assert_true(btnp(3, 0) == false, "btnp(3,0) p0 not pressed")

-- No-argument btnp() includes player 1 in bits 8-13.
set_btnp_frames(3, 19, 1)
assert_equal(btnp(), 0x0800, "btnp() p1 mask")

-- Clean up.
for b = 0, 5 do
set_btnp_frames(b, 0)
Expand Down
Loading