From d3d820d7273b88d87cb0af1e8cf45b5a5132d76a Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 26 Dec 2020 09:30:21 +0900 Subject: [PATCH] emscripten: Support message skip Also add flags that control message skip behavior. --- src/emscripten/nact_emscripten.cpp | 74 +++++++++++++++++++++++++++++- src/sys/msgskip.cpp | 58 ++++++++++++++++------- src/sys/msgskip.h | 22 +++++++-- src/sys/nact.cpp | 6 ++- src/sys/nact_sys1.cpp | 10 ++-- src/sys/nact_sys2.cpp | 10 ++-- src/sys/nact_sys3.cpp | 10 ++-- src/win/nact_win.cpp | 2 +- 8 files changed, 156 insertions(+), 36 deletions(-) diff --git a/src/emscripten/nact_emscripten.cpp b/src/emscripten/nact_emscripten.cpp index aafb2bd..ea0c115 100644 --- a/src/emscripten/nact_emscripten.cpp +++ b/src/emscripten/nact_emscripten.cpp @@ -1,8 +1,21 @@ #include #include "nact.h" #include "utfsjis.h" +#include "msgskip.h" #include +namespace { + +enum CustomEventCode { + SET_MESSAGESKIP_MODE, + SET_MESSAGESKIP_FLAGS, + SYNC_MESSAGESKIP_FILE, +}; + +Uint32 custom_event_type = static_cast(-1); + +} // namespace + void NACT::text_dialog() { static char buf[256]; @@ -25,6 +38,10 @@ void NACT::text_dialog() void NACT::platform_initialize() { + if (custom_event_type == static_cast(-1)) { + custom_event_type = SDL_RegisterEvents(1); + EM_ASM({ setInterval(() => _msgskip_syncFile(), 5000); }); + } } void NACT::platform_finalize() @@ -44,9 +61,64 @@ void NACT::output_console(const char *format, ...) void NACT::set_skip_menu_state(bool enabled, bool checked) { + EM_ASM({ xsystem35.shell.setSkipButtonState($0, $1); }, enabled, checked); } bool NACT::handle_platform_event(const SDL_Event& e) { - return false; + if (e.type != custom_event_type) + return false; + switch (e.user.code) { + case SET_MESSAGESKIP_MODE: + msgskip->activate(static_cast(e.user.data1)); + break; + case SET_MESSAGESKIP_FLAGS: + msgskip->set_flags(reinterpret_cast(e.user.data1), + reinterpret_cast(e.user.data2)); + break; + case SYNC_MESSAGESKIP_FILE: + if (msgskip->write_to_file()) + EM_ASM( xsystem35.shell.syncfs(); ); + break; + } + return true; } + +extern "C" { + +EMSCRIPTEN_KEEPALIVE +void msgskip_activate(int enable) { + SDL_Event event; + memset(&event, 0, sizeof(event)); + event.type = custom_event_type; + event.user.code = SET_MESSAGESKIP_MODE; + event.user.data1 = (void*)enable; + SDL_PushEvent(&event); +} + +EMSCRIPTEN_KEEPALIVE +void msgskip_setFlags(unsigned flags, unsigned mask) { + if (!SDL_WasInit(SDL_INIT_EVENTS)) { + // Retry. + EM_ASM({ setTimeout(() => _msgskip_setFlags($0, $1), 50); }, flags, mask); + return; + } + SDL_Event event; + memset(&event, 0, sizeof(event)); + event.type = custom_event_type; + event.user.code = SET_MESSAGESKIP_FLAGS; + event.user.data1 = (void*)flags; + event.user.data2 = (void*)mask; + SDL_PushEvent(&event); +} + +EMSCRIPTEN_KEEPALIVE +void msgskip_syncFile() { + SDL_Event event; + memset(&event, 0, sizeof(event)); + event.type = custom_event_type; + event.user.code = SYNC_MESSAGESKIP_FILE; + SDL_PushEvent(&event); +} + +} // extern "C" diff --git a/src/sys/msgskip.cpp b/src/sys/msgskip.cpp index ddfdd88..9cc6208 100644 --- a/src/sys/msgskip.cpp +++ b/src/sys/msgskip.cpp @@ -21,10 +21,22 @@ inline uint32 hash(uint32 x, int s) { MsgSkip::MsgSkip(NACT* nact) : nact(nact), bloom(new uint8[BLOOM_FILTER_SIZE / 8]), - skip_enabled(false), - menu_enabled(true) + dirty(false), + flags(MSGSKIP_STOP_ON_UNSEEN | MSGSKIP_STOP_ON_MENU | MSGSKIP_STOP_ON_CLICK), + activated(false), + enabled(true) { memset(bloom, 0, BLOOM_FILTER_SIZE / 8); +} + +MsgSkip::~MsgSkip() +{ + write_to_file(); + delete[] bloom; +} + +void MsgSkip::load_from_file() +{ FILEIO fio; if (fio.Fopen(MSGSKIP_FILENAME, FILEIO_READ_BINARY | FILEIO_SAVEDATA)) { uint32 size = fio.Fgetw(); @@ -35,22 +47,26 @@ MsgSkip::MsgSkip(NACT* nact) } } -MsgSkip::~MsgSkip() +bool MsgSkip::write_to_file() { + if (!dirty) + return false; FILEIO fio; if (fio.Fopen(MSGSKIP_FILENAME, FILEIO_WRITE_BINARY | FILEIO_SAVEDATA)) { fio.Fputw(BLOOM_FILTER_SIZE & 0xffff); fio.Fputw(BLOOM_FILTER_SIZE >> 16); fio.Fwrite(bloom, BLOOM_FILTER_SIZE / 8, 1); fio.Fclose(); + dirty = false; } - delete[] bloom; + return true; } -void MsgSkip::enable_skip(bool enable) { - if (skip_enabled != enable) { - skip_enabled = enable; - nact->set_skip_menu_state(menu_enabled, skip_enabled); +void MsgSkip::activate(bool enable) +{ + if (activated != enable) { + activated = enable; + nact->set_skip_menu_state(enabled, activated); } } @@ -67,15 +83,23 @@ void MsgSkip::on_message(int page, int addr) unseen |= (bloom[h >> 3] & bit) ^ bit; bloom[h >> 3] |= bit; } - if (unseen) { - if (skip_enabled || menu_enabled) { - skip_enabled = menu_enabled = false; - nact->set_skip_menu_state(menu_enabled, skip_enabled); - } + if (unseen) + dirty = true; + + bool old_enabled = enabled; + bool old_activated = activated; + if (unseen && !(flags & MSGSKIP_SKIP_UNSEEN)) { + if (flags & MSGSKIP_STOP_ON_UNSEEN) + activated = false; + enabled = false; } else { - if (!menu_enabled) { - menu_enabled = true; - nact->set_skip_menu_state(menu_enabled, skip_enabled); - } + enabled = true; } + if (enabled != old_enabled || activated != old_activated) + nact->set_skip_menu_state(enabled, activated); +} + +void MsgSkip::set_flags(unsigned val, unsigned mask) { + flags &= ~mask; + flags |= (val & mask); } diff --git a/src/sys/msgskip.h b/src/sys/msgskip.h index d0226d7..bc31449 100644 --- a/src/sys/msgskip.h +++ b/src/sys/msgskip.h @@ -5,20 +5,34 @@ class NACT; +enum MsgSkipFlags { + MSGSKIP_SKIP_UNSEEN = 1, + MSGSKIP_STOP_ON_UNSEEN = 2, + MSGSKIP_STOP_ON_MENU = 4, + MSGSKIP_STOP_ON_CLICK = 8, +}; + class MsgSkip { public: MsgSkip(NACT* nact); ~MsgSkip(); - void enable_skip(bool enable); - bool is_skip_enabled() const { return skip_enabled; } + void activate(bool enable); + bool is_activated() const { return activated; } + bool skipping() const { return enabled && activated; } void on_message(int page, int addr); + void load_from_file(); + bool write_to_file(); + unsigned get_flags() const { return flags; } + void set_flags(unsigned flags, unsigned mask); private: NACT* nact; uint8* bloom; - bool skip_enabled; - bool menu_enabled; + bool dirty; + unsigned flags; + bool activated; + bool enabled; }; #endif diff --git a/src/sys/nact.cpp b/src/sys/nact.cpp index ac4d28f..62b07d2 100644 --- a/src/sys/nact.cpp +++ b/src/sys/nact.cpp @@ -116,8 +116,9 @@ NACT::~NACT() bool NACT::mainloop() { - int sleep_cnt = 0; + msgskip->load_from_file(); + int sleep_cnt = 0; while(!terminate) { execute(); // 512コマンド実行毎にSleep(10) @@ -356,6 +357,9 @@ void NACT::load_scenario(int page) int NACT::menu_select(int num_items) { + if (msgskip->get_flags() & MSGSKIP_STOP_ON_MENU) + msgskip->activate(false); + // メニュー表示 ags->open_menu_window(menu_window); diff --git a/src/sys/nact_sys1.cpp b/src/sys/nact_sys1.cpp index 9eb2565..0eec841 100644 --- a/src/sys/nact_sys1.cpp +++ b/src/sys/nact_sys1.cpp @@ -554,13 +554,15 @@ void NACT_Sys1::cmd_a() output_console("A\n"); - // Pushマークの表示 - if(show_push) { + if (msgskip->skipping()) { + if (msgskip->get_flags() & MSGSKIP_STOP_ON_CLICK && get_key()) + msgskip->activate(false); + } else if (show_push) { ags->draw_push(text_window); } // キーが押されて離されるまで待機 - while (!msgskip->is_skip_enabled()) { + while (!msgskip->skipping()) { if(terminate) { return; } @@ -570,7 +572,7 @@ void NACT_Sys1::cmd_a() sys_sleep(16); } sys_sleep(30); - while (!msgskip->is_skip_enabled()) { + while (!msgskip->skipping()) { if(terminate) { return; } diff --git a/src/sys/nact_sys2.cpp b/src/sys/nact_sys2.cpp index 38a59c9..b3d4794 100644 --- a/src/sys/nact_sys2.cpp +++ b/src/sys/nact_sys2.cpp @@ -518,13 +518,15 @@ void NACT_Sys2::cmd_a() output_console("A\n"); - // Pushマークの表示 - if(show_push) { + if (msgskip->skipping()) { + if (msgskip->get_flags() & MSGSKIP_STOP_ON_CLICK && get_key()) + msgskip->activate(false); + } else if (show_push) { ags->draw_push(text_window); } // キーが押されて離されるまで待機 - while (!msgskip->is_skip_enabled()) { + while (!msgskip->skipping()) { if(terminate) { return; } @@ -534,7 +536,7 @@ void NACT_Sys2::cmd_a() sys_sleep(16); } sys_sleep(30); - while (!msgskip->is_skip_enabled()) { + while (!msgskip->skipping()) { if(terminate) { return; } diff --git a/src/sys/nact_sys3.cpp b/src/sys/nact_sys3.cpp index 63c7866..c8ec971 100644 --- a/src/sys/nact_sys3.cpp +++ b/src/sys/nact_sys3.cpp @@ -286,13 +286,15 @@ void NACT_Sys3::cmd_a() output_console("A\n"); - // Pushマークの表示 - if(show_push) { + if (msgskip->skipping()) { + if (msgskip->get_flags() & MSGSKIP_STOP_ON_CLICK && get_key()) + msgskip->activate(false); + } else if (show_push) { ags->draw_push(text_window); } // キーが押されて離されるまで待機 - while (!msgskip->is_skip_enabled()) { + while (!msgskip->skipping()) { if(terminate) { return; } @@ -302,7 +304,7 @@ void NACT_Sys3::cmd_a() sys_sleep(16); } sys_sleep(30); - while (!msgskip->is_skip_enabled()) { + while (!msgskip->skipping()) { if(terminate) { return; } diff --git a/src/win/nact_win.cpp b/src/win/nact_win.cpp index a9540d7..c25daf4 100644 --- a/src/win/nact_win.cpp +++ b/src/win/nact_win.cpp @@ -174,7 +174,7 @@ bool NACT::handle_platform_event(const SDL_Event& e) mako->select_sound(BGM_CD); break; case ID_TEXT_SKIP: - msgskip->enable_skip(!msgskip->is_skip_enabled()); + msgskip->activate(!msgskip->is_activated()); break; case ID_TEXT_WAIT: text_wait_enb = !text_wait_enb;