mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-08 14:58:13 +03:00
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:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user