@@ -24,6 +24,8 @@ static uint8_t currentAudioBuffer = 0;
2424static uint16_t * audio_buffer = nullptr ;
2525static std::atomic<bool > frame_complete = false ;
2626
27+ static bool unlock = false ;
28+
2729static int JoyState, LastKey, InMenu, InKeyboard;
2830static int KeyboardCol, KeyboardRow, KeyboardKey;
2931static 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+
93111int 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
332357unsigned 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
366394void 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
374400unsigned 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
490520void load_msx (std::string_view save_path) {
0 commit comments