Stop message skip on unseen text

This makes System3-sdl2 stop message skip when it sees text that has not
been read by the player. Seen / unseen flags are stored in MSGSKIP.DAT
file in the save folder.
This commit is contained in:
kichikuou
2020-12-24 17:12:47 +09:00
parent 3a2d345521
commit c2ff6de675
12 changed files with 146 additions and 15 deletions
+1
View File
@@ -93,6 +93,7 @@ target_sources(system3 PRIVATE
sys/ags_window.cpp
sys/dri.cpp
sys/mako_midi.cpp
sys/msgskip.cpp
sys/nact.cpp
sys/nact_crc32.cpp
sys/nact_input.cpp
+4
View File
@@ -47,6 +47,10 @@ void NACT::output_console(const char *format, ...)
#endif
}
void NACT::set_skip_menu_state(bool enabled, bool checked)
{
}
bool NACT::handle_platform_event(const SDL_Event& e)
{
if (e.type == SDL_FINGERDOWN && SDL_GetNumTouchFingers(e.tfinger.touchId) == 3) {
+4
View File
@@ -42,6 +42,10 @@ void NACT::output_console(const char *format, ...)
#endif
}
void NACT::set_skip_menu_state(bool enabled, bool checked)
{
}
bool NACT::handle_platform_event(const SDL_Event& e)
{
return false;
+4
View File
@@ -24,6 +24,10 @@ void NACT::output_console(const char *format, ...)
#endif
}
void NACT::set_skip_menu_state(bool enabled, bool checked)
{
}
bool NACT::handle_platform_event(const SDL_Event& e)
{
return false;
+81
View File
@@ -0,0 +1,81 @@
#include "msgskip.h"
#include "nact.h"
#include "fileio.h"
namespace {
// Parameters for Bloom filter that can contain 47,543 items with 0.5% false
// positive rate.
const int BLOOM_FILTER_SIZE = 1 << 19; // 64KiB
const int BLOOM_FILTER_HASHES = 8;
const char MSGSKIP_FILENAME[] = "MSGSKIP.DAT";
// Knuth's multiplicative hash.
inline uint32 hash(uint32 x, int s) {
return (x * 2654435761ULL) >> s;
}
} // namespace
MsgSkip::MsgSkip(NACT* nact)
: nact(nact),
bloom(new uint8[BLOOM_FILTER_SIZE / 8]),
skip_enabled(false),
menu_enabled(true)
{
memset(bloom, 0, BLOOM_FILTER_SIZE / 8);
FILEIO fio;
if (fio.Fopen(MSGSKIP_FILENAME, FILEIO_READ_BINARY | FILEIO_SAVEDATA)) {
uint32 size = fio.Fgetw();
size |= fio.Fgetw() << 16;
if (size == BLOOM_FILTER_SIZE)
fio.Fread(bloom, BLOOM_FILTER_SIZE / 8, 1);
fio.Fclose();
}
}
MsgSkip::~MsgSkip()
{
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();
}
delete[] bloom;
}
void MsgSkip::enable_skip(bool enable) {
if (skip_enabled != enable) {
skip_enabled = enable;
nact->set_skip_menu_state(menu_enabled, skip_enabled);
}
}
void MsgSkip::on_message(int page, int addr)
{
if (!bloom)
return;
uint32 h1 = hash(page, 5);
uint32 h2 = hash(addr, 11);
uint8 unseen = 0;
for (int i = 0; i < BLOOM_FILTER_HASHES; i++) {
uint32 h = (h1 + i * h2) % BLOOM_FILTER_SIZE;
uint8 bit = 1 << (h & 7);
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);
}
} else {
if (!menu_enabled) {
menu_enabled = true;
nact->set_skip_menu_state(menu_enabled, skip_enabled);
}
}
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef _MSGSKIP_H_
#define _MSGSKIP_H_
#include "common.h"
class NACT;
class MsgSkip {
public:
MsgSkip(NACT* nact);
~MsgSkip();
void enable_skip(bool enable);
bool is_skip_enabled() const { return skip_enabled; }
void on_message(int page, int addr);
private:
NACT* nact;
uint8* bloom;
bool skip_enabled;
bool menu_enabled;
};
#endif
+7 -8
View File
@@ -8,6 +8,7 @@
#include "nact.h"
#include "ags.h"
#include "mako.h"
#include "msgskip.h"
#include "dri.h"
#include "../fileio.h"
#include "crc32.h"
@@ -67,7 +68,6 @@ NACT::NACT(int sys_ver, uint32 crc32_a, uint32 crc32_b, const char* font_file, c
seed = SDL_GetTicks(); // 乱数の種
text_wait_time = 100; // メッセージ表示のウェイト
text_wait_enb = false;
text_skip_enb = false;
mouse_sence = 16; // マウス移動感知
menu_window = text_window = 1;
@@ -86,6 +86,7 @@ NACT::NACT(int sys_ver, uint32 crc32_a, uint32 crc32_b, const char* font_file, c
// 各種クラス生成
ags = new AGS(this, font_file);
mako = new MAKO(this, mako_config);
msgskip = new MsgSkip(this);
#ifdef USE_JOY
// 入力初期化
@@ -101,13 +102,9 @@ NACT::NACT(int sys_ver, uint32 crc32_a, uint32 crc32_b, const char* font_file, c
NACT::~NACT()
{
// 各種クラス開放
if(ags) {
delete ags;
}
if(mako) {
delete mako;
}
delete ags;
delete mako;
delete msgskip;
// シナリオ開放
if(scenario_data) {
@@ -318,6 +315,8 @@ void NACT::message()
text_refresh = false;
}
}
if (!ags->draw_menu)
msgskip->on_message(scenario_page, scenario_addr);
// TODO: Convert hankaku to zenkaku
output_console(buf);
+3 -1
View File
@@ -83,6 +83,7 @@ constexpr char SJIS_NEXT_PAGE [] = "\x8E\x9F\x82\xCC\x83\x79\x81\x5B\x83\x57"; /
class AGS;
class MAKO;
class MAKOConfig;
class MsgSkip;
class NACT
{
@@ -94,6 +95,7 @@ public:
protected:
AGS* ags;
MAKO* mako;
MsgSkip* msgskip;
// コマンドパーサ
void execute();
@@ -251,8 +253,8 @@ public:
static const int get_sys_ver(uint32 crc32_a, uint32 crc32_b);
const char* get_title();
void text_wait();
void set_skip_menu_state(bool enabled, bool checked);
bool text_skip_enb; // メッセージスキップ
bool text_wait_enb; // テキスト表示のウェイト有効/無効
int sys_ver;
uint32 crc32_a; // ADISK
+2 -1
View File
@@ -14,6 +14,7 @@
#include "nact.h"
#include "ags.h"
#include "mako.h"
#include "msgskip.h"
#include "crc32.h"
#include "../fileio.h"
@@ -784,7 +785,7 @@ void NACT_Sys1::cmd_a()
{
output_console("A\n");
if(!text_skip_enb) {
if(!msgskip->is_skip_enabled()) {
// Pushマークの表示
if(show_push) {
ags->draw_push(text_window);
+2 -1
View File
@@ -9,6 +9,7 @@
#include "nact.h"
#include "ags.h"
#include "mako.h"
#include "msgskip.h"
#include "crc32.h"
#include "../fileio.h"
@@ -748,7 +749,7 @@ void NACT_Sys2::cmd_a()
{
output_console("A\n");
if(!text_skip_enb) {
if(!msgskip->is_skip_enabled()) {
// Pushマークの表示
if(show_push) {
ags->draw_push(text_window);
+2 -1
View File
@@ -9,6 +9,7 @@
#include "nact.h"
#include "ags.h"
#include "mako.h"
#include "msgskip.h"
#include "crc32.h"
#include "../fileio.h"
#include "texthook.h"
@@ -373,7 +374,7 @@ void NACT_Sys3::cmd_a()
output_console("A\n");
if(!text_skip_enb) {
if(!msgskip->is_skip_enabled()) {
// Pushマークの表示
if(show_push) {
ags->draw_push(text_window);
+12 -3
View File
@@ -4,6 +4,7 @@
#include "SDL_syswm.h"
#include "ags.h"
#include "mako.h"
#include "msgskip.h"
#include "../res3/resource.h"
extern SDL_Window* g_window;
@@ -130,6 +131,16 @@ void NACT::output_console(const char *format, ...)
#endif
}
void NACT::set_skip_menu_state(bool enabled, bool checked)
{
HWND hwnd = get_hwnd(g_window);
HMENU hmenu = GetMenu(hwnd);
EnableMenuItem(hmenu, ID_TEXT_SKIP, enabled ? MF_ENABLED : MF_GRAYED);
CheckMenuItem(hmenu, ID_TEXT_SKIP, MF_BYCOMMAND |
checked ? MFS_CHECKED : MFS_UNCHECKED);
DrawMenuBar(hwnd);
}
bool NACT::handle_platform_event(const SDL_Event& e)
{
if (e.type != SDL_SYSWMEVENT)
@@ -163,9 +174,7 @@ bool NACT::handle_platform_event(const SDL_Event& e)
mako->select_sound(BGM_CD);
break;
case ID_TEXT_SKIP:
text_skip_enb = !text_skip_enb;
CheckMenuItem(GetMenu(get_hwnd(g_window)), ID_TEXT_SKIP, MF_BYCOMMAND |
text_skip_enb ? MFS_CHECKED : MFS_UNCHECKED);
msgskip->enable_skip(!msgskip->is_skip_enabled());
break;
case ID_TEXT_WAIT:
text_wait_enb = !text_wait_enb;