Skip to content

Commit 43bb9b6

Browse files
committed
fix: add missing commit fixing menu input for msx
1 parent 43cb328 commit 43bb9b6

File tree

2 files changed

+108
-35
lines changed

2 files changed

+108
-35
lines changed
Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,59 @@
11
#pragma once
22

3+
#include <cstdint>
4+
35
struct GamepadState {
4-
int a : 1;
5-
int b : 1;
6-
int x : 1;
7-
int y : 1;
8-
int select : 1;
9-
int start : 1;
10-
int up : 1;
11-
int down : 1;
12-
int left : 1;
13-
int right : 1;
6+
enum class Button {
7+
ANY = -1,
8+
A = 0,
9+
B = 1,
10+
X = 2,
11+
Y = 3,
12+
SELECT = 4,
13+
START = 5,
14+
UP = 6,
15+
DOWN = 7,
16+
LEFT = 8,
17+
RIGHT = 9
18+
};
19+
20+
union {
21+
struct {
22+
int a : 1;
23+
int b : 1;
24+
int x : 1;
25+
int y : 1;
26+
int select : 1;
27+
int start : 1;
28+
int up : 1;
29+
int down : 1;
30+
int left : 1;
31+
int right : 1;
32+
};
33+
uint16_t buttons{0};
34+
};
35+
36+
bool is_pressed(Button button) const {
37+
switch (button) {
38+
case Button::ANY: return buttons != 0;
39+
case Button::A: return a;
40+
case Button::B: return b;
41+
case Button::X: return x;
42+
case Button::Y: return y;
43+
case Button::SELECT: return select;
44+
case Button::START: return start;
45+
case Button::UP: return up;
46+
case Button::DOWN: return down;
47+
case Button::LEFT: return left;
48+
case Button::RIGHT: return right;
49+
default: return false;
50+
}
51+
}
1452

15-
bool operator==(const GamepadState& other) const = default;
53+
bool operator==(const GamepadState& other) const {
54+
return buttons == other.buttons;
55+
}
56+
bool operator!=(const GamepadState& other) const {
57+
return !(*this == other);
58+
}
1659
};

components/msx/src/msx.cpp

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ static uint8_t currentAudioBuffer = 0;
2424
static uint16_t* audio_buffer = nullptr;
2525
static std::atomic<bool> frame_complete = false;
2626

27+
static bool unlock = false;
28+
2729
static int JoyState, LastKey, InMenu, InKeyboard;
2830
static int KeyboardCol, KeyboardRow, KeyboardKey;
2931
static int64_t KeyboardDebounce = 0;
@@ -90,6 +92,22 @@ static const char *BiosFiles[] = {
9092
// "KANJI.ROM",
9193
};
9294

95+
bool wait_for_key(GamepadState::Button key, bool state, int timeout_ms) {
96+
static auto& box = BoxEmu::get();
97+
auto buttons = box.gamepad_state();
98+
auto start = esp_timer_get_time();
99+
auto timeout = start + (timeout_ms * 1000);
100+
using namespace std::chrono_literals;
101+
while (buttons.is_pressed(key) != state) {
102+
if (esp_timer_get_time() > timeout) {
103+
return false;
104+
}
105+
std::this_thread::sleep_for(10ms);
106+
buttons = box.gamepad_state();
107+
}
108+
return true;
109+
}
110+
93111
int ProcessEvents(int Wait)
94112
{
95113
for (int i = 0; i < 16; ++i)
@@ -99,12 +117,18 @@ int ProcessEvents(int Wait)
99117
static auto& box = BoxEmu::get();
100118
auto state = box.gamepad_state();
101119

120+
// update unlock based on x button
121+
static bool last_x = false;
122+
if (state.x && !last_x) {
123+
unlock = !unlock;
124+
}
125+
last_x = state.x;
126+
102127
if (state.select)
103128
{
104129
InKeyboard = !InKeyboard;
105-
// TODO: what do we do with this?
106-
//
107-
// rg_input_wait_for_key(RG_KEY_ANY, false, 500);
130+
// wait no more than 500ms for the user to release the key
131+
wait_for_key(GamepadState::Button::SELECT, false, 500);
108132
}
109133
else if (state.start)
110134
{
@@ -117,13 +141,14 @@ int ProcessEvents(int Wait)
117141
if (InMenu == 2)
118142
{
119143
InMenu = 1;
120-
// TODO: mute audio
121-
// rg_audio_set_mute(true);
144+
// mute audio
145+
bool is_muted = box.is_muted();
146+
box.mute(true);
122147
MenuMSX();
123-
// TODO: unmute audio
124-
// rg_audio_set_mute(false);
125-
// TODO: figure out what to do with this
126-
// rg_input_wait_for_key(RG_KEY_ANY, false, 500);
148+
// unmute audio
149+
box.mute(is_muted);
150+
// wait at least 500ms for the user to release the key
151+
wait_for_key(GamepadState::Button::START, false, 500);
127152
InMenu = 0;
128153
}
129154
else if (InMenu)
@@ -169,8 +194,8 @@ int ProcessEvents(int Wait)
169194
}
170195
else if (state.b)
171196
{
172-
// TODO: figure out what to do with this
173-
// rg_input_wait_for_key(RG_KEY_ANY, false, 500);
197+
// wait at least 500ms for the user to release the key
198+
wait_for_key(GamepadState::Button::B, false, 500);
174199
InKeyboard = false;
175200
}
176201
}
@@ -331,12 +356,15 @@ unsigned int GetKey(void)
331356

332357
unsigned int WaitKey(void)
333358
{
334-
GetKey();
335-
// TODO: figure out what to do with this
336-
// rg_input_wait_for_key(RG_KEY_ANY, false, 200);
337-
// TODO: figure out what to do with this
338-
// while (!rg_input_wait_for_key(RG_KEY_ANY, true, 100))
339-
// continue;
359+
LastKey = 0;
360+
// wait no more than 200ms for the user to release the key
361+
wait_for_key(GamepadState::Button::ANY, false, 200);
362+
// wait no more than 100ms for the user to press any key
363+
while (!wait_for_key(GamepadState::Button::ANY, true, 100)) {
364+
// wait for key
365+
continue;
366+
}
367+
340368
return GetKey();
341369
}
342370

@@ -364,18 +392,14 @@ unsigned int GetFreeAudio(void)
364392
}
365393

366394
void PlayAllSound(int uSec) {
367-
// unsigned int samples = 2 * uSec * AUDIO_SAMPLE_RATE / 1000000;
368-
// rg_queue_send(audioQueue, &samples, 100);
369395
static auto &box = BoxEmu::get();
370396
unsigned int samples = 2 * uSec * AUDIO_SAMPLE_RATE / 1'000'000;
371397
RenderAndPlayAudio(samples);
372398
}
373399

374400
unsigned int WriteAudio(sample *Data, unsigned int Length) {
375-
// rg_audio_submit((void *)Data, Length >> 1);
376401
static auto &box = BoxEmu::get();
377402
bool sound_enabled = !box.is_muted();
378-
// fmt::print("WriteAudio: Length: {}\n", Length);
379403
if (sound_enabled) {
380404
if (audio_buffer_offset + Length > AUDIO_BUFFER_LENGTH) {
381405
box.play_audio((uint8_t*)audio_buffer, audio_buffer_offset * sizeof(int16_t));
@@ -423,6 +447,9 @@ void init_msx(const std::string& rom_filename, uint8_t *romdata, size_t rom_data
423447
Buf = (HUNTEntry*)shared_malloc(sizeof(HUNTEntry) * HUNT_BUFSIZE);
424448
RPLData = (RPLState*)shared_malloc(sizeof(RPLState) * RPL_BUFSIZE);
425449

450+
// reset unlock
451+
unlock = false;
452+
426453
// now init the state
427454
displayBuffer[0] = (uint16_t*)BoxEmu::get().frame_buffer0();
428455
displayBuffer[1] = (uint16_t*)BoxEmu::get().frame_buffer1();
@@ -482,9 +509,12 @@ void IRAM_ATTR run_msx_rom() {
482509
auto elapsed = end - start;
483510
update_frame_time(elapsed);
484511

485-
// // frame rate should be 60 FPS, so 1/60th second is what we want to sleep for
486-
// static constexpr auto delay = std::chrono::duration<float>(1.0f/60.0f);
487-
// std::this_thread::sleep_until(start + delay);
512+
static constexpr uint64_t max_frame_time = 1000000 / 60;
513+
if (!unlock && elapsed < max_frame_time) {
514+
using namespace std::chrono_literals;
515+
auto sleep_time = (max_frame_time - elapsed) / 1e3;
516+
std::this_thread::sleep_for(sleep_time * 1ms);
517+
}
488518
}
489519

490520
void load_msx(std::string_view save_path) {

0 commit comments

Comments
 (0)