emscripten: Support message skip

Also add flags that control message skip behavior.
This commit is contained in:
kichikuou
2020-12-29 12:09:34 +09:00
parent 46827f35ef
commit d3d820d727
8 changed files with 156 additions and 36 deletions
+73 -1
View File
@@ -1,8 +1,21 @@
#include <stdio.h>
#include "nact.h"
#include "utfsjis.h"
#include "msgskip.h"
#include <emscripten.h>
namespace {
enum CustomEventCode {
SET_MESSAGESKIP_MODE,
SET_MESSAGESKIP_FLAGS,
SYNC_MESSAGESKIP_FILE,
};
Uint32 custom_event_type = static_cast<Uint32>(-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<Uint32>(-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<bool>(e.user.data1));
break;
case SET_MESSAGESKIP_FLAGS:
msgskip->set_flags(reinterpret_cast<unsigned>(e.user.data1),
reinterpret_cast<unsigned>(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"
+41 -17
View File
@@ -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);
}
+18 -4
View File
@@ -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
+5 -1
View File
@@ -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);
+6 -4
View File
@@ -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;
}
+6 -4
View File
@@ -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;
}
+6 -4
View File
@@ -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;
}
+1 -1
View File
@@ -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;