diff --git a/src/fileio.cpp b/src/fileio.cpp index f3a8b6d..5bf5870 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -77,20 +77,15 @@ std::unique_ptr FILEIO::open(const char *file_name, int mode) return fp ? std::unique_ptr(new FILEIO(fp, mode)) : nullptr; } -void FILEIO::ag00_gets(char *dest, int length) +std::string FILEIO::gets() { - int p = 0; - - for(;;) { + std::string s; + for (;;) { int c = getc(); - if(c == 0x0d || c == EOF) { + if (c == '\r' || c == EOF) break; - } - if(c != 0x0a) { - if(p < length + 1) { - dest[p++] = c; - } - } + if(c != '\n') + s.push_back(c); } - dest[p] = '\0'; + return s; } diff --git a/src/fileio.h b/src/fileio.h index cb65368..6b4e90f 100644 --- a/src/fileio.h +++ b/src/fileio.h @@ -49,7 +49,7 @@ public: putc(w & 0xff); putc((w >> 8) & 0xff); } - void ag00_gets(char* dest, int length); + std::string gets(); }; #endif diff --git a/src/sys/nact.cpp b/src/sys/nact.cpp index e08fe78..133560e 100644 --- a/src/sys/nact.cpp +++ b/src/sys/nact.cpp @@ -34,19 +34,14 @@ NACT::NACT(const Config& config, const GameId& game_id) auto fio = FILEIO::open("AG00.DAT", FILEIO_READ_BINARY); if (fio) { int d0, d1, d2, d3; - char string[MAX_CAPTION]; - fio->ag00_gets(string, MAX_CAPTION); - if (sscanf_s(string, "%d,%d,%d,%d", &d0, &d1, &d2, &d3) != 4) + std::string line = fio->gets(); + if (sscanf_s(line.c_str(), "%d,%d,%d,%d", &d0, &d1, &d2, &d3) != 4) sys_error("AG00.DAT: parse error"); - for(int i = 0; i < d1; i++) { - // 動詞の読み込み - fio->ag00_gets(string, MAX_CAPTION); - memcpy(caption_verb[i], string, sizeof(string)); + for (int i = 0; i < d1; i++) { + caption_verb[i] = fio->gets(); } - for(int i = 0; i < d2; i++) { - // 目的語の読み込み - fio->ag00_gets(string, MAX_CAPTION); - memcpy(caption_obj[i], string, sizeof(string)); + for (int i = 0; i < d2; i++) { + caption_obj[i] = fio->gets(); } fio.reset(); } @@ -312,11 +307,11 @@ void NACT::cmd_set_menu() output_console("$"); } else { - if(!menu_index) { + if (menu_items.empty()) { ags->clear_menu_window(); ags->menu_dest_y = 0; } - menu_addr[menu_index++] = sco.getw(); + menu_items.emplace_back(sco.getw()); ags->menu_dest_x = 2; ags->menu_dest_y += 2; ags->draw_menu = true; @@ -324,7 +319,7 @@ void NACT::cmd_set_menu() if (game_id.is_gakuen()) menu_window = 2; - output_console("\n$%x,", menu_addr[menu_index - 1]); + output_console("\n$%x,", menu_items.back().addr); } } @@ -332,7 +327,7 @@ void NACT::cmd_open_menu() { output_console("\n]"); - if (!menu_index) { + if (menu_items.empty()) { sco.jump_to(sco.default_addr()); return; } @@ -343,14 +338,14 @@ void NACT::cmd_open_menu() } } - int selection = menu_select(menu_index); + int selection = menu_select(static_cast(menu_items.size())); if (terminate) return; if (selection != -1) { - sco.jump_to(menu_addr[selection]); + sco.jump_to(menu_items[selection].addr); } - menu_index = 0; + menu_items.clear(); } void NACT::cmd_set_verbobj() @@ -359,12 +354,10 @@ void NACT::cmd_set_verbobj() int obj = sco.getd(); int addr = sco.getw(); - menu_addr[menu_index] = addr; - menu_verb[menu_index] = verb; - menu_obj[menu_index++] = obj; + menu_items.emplace_back(addr, verb, obj); verb_obj = true; - output_console("\n[%x,%s,%s:", addr, caption_verb[verb], caption_obj[obj]); + output_console("\n[%x,%s,%s:", addr, caption_verb[verb].c_str(), caption_obj[obj].c_str()); } void NACT::cmd_set_verbobj2() @@ -374,14 +367,12 @@ void NACT::cmd_set_verbobj2() int obj = sco.getd(); int addr = sco.getw(); - if(condition) { - menu_addr[menu_index] = addr; - menu_verb[menu_index] = verb; - menu_obj[menu_index++] = obj; + if (condition) { + menu_items.emplace_back(addr, verb, obj); } verb_obj = true; - output_console("\n:%d,%x,%s,%s:", condition, addr, caption_verb[verb], caption_obj[obj]); + output_console("\n:%d,%x,%s,%s:", condition, addr, caption_verb[verb].c_str(), caption_obj[obj].c_str()); } void NACT::cmd_a() diff --git a/src/sys/nact.h b/src/sys/nact.h index 899a78d..73bcfe1 100644 --- a/src/sys/nact.h +++ b/src/sys/nact.h @@ -77,10 +77,8 @@ #define M_X var[57] #define M_Y var[58] -#define MAX_MENU 64 #define MAX_VERB 128 #define MAX_OBJ 256 -#define MAX_CAPTION 32 #define MAX_PCM 256 class AGS; @@ -134,7 +132,6 @@ protected: void cmd_set_verbobj(); void cmd_set_verbobj2(); virtual void cmd_open_verb() = 0; - virtual void cmd_open_obj(int verb) = 0; void cmd_a(); virtual void cmd_b() = 0; @@ -179,13 +176,16 @@ protected: bool show_push = true; // Push表示 bool clear_text = true; // メニュー後のメッセージウィンドウ消去 - int menu_index = 0; // メニュー登録のインデックス - int menu_addr[64]; // ジャンプ先のアドレス - int menu_verb[64]; // 登録された動詞 - int menu_obj[64]; // 登録された目的語 + struct MenuItem { + uint16_t addr; + uint8_t verb; + uint8_t obj; + explicit MenuItem(uint16_t addr, uint8_t verb = 0, uint8_t obj = 0) : addr(addr), verb(verb), obj(obj) {} + }; + std::vector menu_items; - char caption_verb[MAX_VERB][MAX_CAPTION]; - char caption_obj[MAX_OBJ][MAX_CAPTION]; + std::string caption_verb[MAX_VERB]; + std::string caption_obj[MAX_OBJ]; bool verb_obj = false; // 動詞-形容詞型メニューの定義中 bool set_palette = false; @@ -259,7 +259,6 @@ public: protected: void cmd_branch() override; void cmd_open_verb() override; - void cmd_open_obj(int verb) override; void cmd_b() override; void cmd_d() override; void cmd_e() override; @@ -284,6 +283,8 @@ protected: uint16 cali() override; private: + void cmd_open_obj(int verb); + // Intruder Zコマンド int paint_x; int paint_y; @@ -299,37 +300,6 @@ public: protected: void cmd_branch() override; void cmd_open_verb() override; - void cmd_open_obj(int verb) override; - void cmd_b() override; - void cmd_d() override; - void cmd_e() override; - void cmd_g() override; - void cmd_h() override; - void cmd_i() override; - void cmd_j() override; - void cmd_k() override; - void cmd_l() override; - void cmd_m() override; - void cmd_n() override; - void cmd_o() override; - void cmd_p() override; - void cmd_q() override; - void cmd_t() override; - void cmd_u() override; - void cmd_v() override; - void cmd_w() override; - void cmd_y() override; - void cmd_z() override; - uint16 cali() override; -}; - -class NACT_Sys3 final : public NACT { -public: - NACT_Sys3(const Config& config, const GameId& game_id) : NACT(config, game_id) {} -protected: - void cmd_branch() override; - void cmd_open_verb() override; - void cmd_open_obj(int verb) override; void cmd_b() override; void cmd_d() override; void cmd_e() override; @@ -353,6 +323,39 @@ protected: uint16 cali() override; private: + void cmd_open_obj(int verb); +}; + +class NACT_Sys3 final : public NACT { +public: + NACT_Sys3(const Config& config, const GameId& game_id) : NACT(config, game_id) {} +protected: + void cmd_branch() override; + void cmd_open_verb() override; + void cmd_b() override; + void cmd_d() override; + void cmd_e() override; + void cmd_g() override; + void cmd_h() override; + void cmd_i() override; + void cmd_j() override; + void cmd_k() override; + void cmd_l() override; + void cmd_m() override; + void cmd_n() override; + void cmd_o() override; + void cmd_p() override; + void cmd_q() override; + void cmd_t() override; + void cmd_u() override; + void cmd_v() override; + void cmd_w() override; + void cmd_y() override; + void cmd_z() override; + uint16 cali() override; + +private: + void cmd_open_obj(int verb); uint16 cali2(); struct K3HackInfo; diff --git a/src/sys/nact_sys1.cpp b/src/sys/nact_sys1.cpp index 385fab0..ffb137b 100644 --- a/src/sys/nact_sys1.cpp +++ b/src/sys/nact_sys1.cpp @@ -12,6 +12,7 @@ */ #include "nact.h" +#include #include "ags.h" #include "mako.h" #include "msgskip.h" @@ -222,21 +223,17 @@ void NACT_Sys1::cmd_open_verb() verb_obj = false; // 表示する動詞のチェック - int chk[MAX_VERB], page = 0, cnt = 0; - + bool chk[MAX_VERB] = {}; + int page = 0; + if (game_id.is_gakuen()) menu_window = 1; int menu_max = ags->calculate_menu_max(menu_window); - memset(chk, 0, sizeof(chk)); - for(int i = 0; i < menu_index; i++) { - chk[menu_verb[i]] = 1; - } - for(int i = 0; i < MAX_VERB; i++) { - if(chk[i]) { - cnt++; - } + for (const MenuItem& item : menu_items) { + chk[item.verb] = true; } + int cnt = std::count(chk, chk + MAX_VERB, true); top: // メニュー項目の準備 @@ -252,7 +249,7 @@ top: if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_verb[i]); + ags->draw_text(caption_verb[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } @@ -263,7 +260,7 @@ top2: if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_verb[i]); + ags->draw_text(caption_verb[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } @@ -297,7 +294,7 @@ top2: } else { cmd_open_obj(id[selection]); } - menu_index = 0; + menu_items.clear(); } void NACT_Sys1::cmd_open_obj(int verb) @@ -308,27 +305,23 @@ void NACT_Sys1::cmd_open_obj(int verb) verb_obj = false; // 表示する目的語のチェック - int chk[MAX_OBJ], addr[MAX_OBJ], page = 0, cnt = 0; - - memset(chk, 0, sizeof(chk)); - for(int i = 0; i < menu_index; i++) { - if(menu_verb[i] == verb) { - chk[menu_obj[i]] = 1; - addr[menu_obj[i]] = menu_addr[i]; - } - } - for(int i = 0; i < MAX_OBJ; i++) { - if(chk[i]) { - cnt++; + bool chk[MAX_OBJ] = {}; + int addr[MAX_OBJ], page = 0; + + for (const MenuItem& item : menu_items) { + if (item.verb == verb) { + chk[item.obj] = true; + addr[item.obj] = item.addr; } } + int cnt = std::count(chk, chk + MAX_OBJ, true); // 目的語がない場合 if(chk[0] && cnt == 1) { sco.jump_to(addr[0]); return; } // 以後、obj=0は戻るとして扱う - chk[0] = 0; + chk[0] = false; addr[0] = sco.default_addr(); top: @@ -345,7 +338,7 @@ top: if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_obj[i]); + ags->draw_text(caption_obj[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } @@ -362,7 +355,7 @@ top2: if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_obj[i]); + ags->draw_text(caption_obj[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } diff --git a/src/sys/nact_sys2.cpp b/src/sys/nact_sys2.cpp index 8d262aa..5b99251 100644 --- a/src/sys/nact_sys2.cpp +++ b/src/sys/nact_sys2.cpp @@ -255,11 +255,11 @@ void NACT_Sys2::cmd_open_verb() verb_obj = false; // 表示する動詞のチェック - int chk[MAX_VERB], page = 0; - - memset(chk, 0, sizeof(chk)); - for(int i = 0; i < menu_index; i++) { - chk[menu_verb[i]] = 1; + bool chk[MAX_VERB] = {}; + int page = 0; + + for (const MenuItem& item : menu_items) { + chk[item.verb] = true; } // メニュー項目の準備 @@ -273,7 +273,7 @@ void NACT_Sys2::cmd_open_verb() if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_verb[i]); + ags->draw_text(caption_verb[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } @@ -289,7 +289,7 @@ void NACT_Sys2::cmd_open_verb() } else { cmd_open_obj(id[selection]); } - menu_index = 0; + menu_items.clear(); } void NACT_Sys2::cmd_open_obj(int verb) @@ -298,13 +298,13 @@ void NACT_Sys2::cmd_open_obj(int verb) verb_obj = false; // 表示する目的語のチェック - int chk[MAX_OBJ], addr[MAX_OBJ], page = 0; - - memset(chk, 0, sizeof(chk)); - for(int i = 0; i < menu_index; i++) { - if(menu_verb[i] == verb) { - chk[menu_obj[i]] = 1; - addr[menu_obj[i]] = menu_addr[i]; + bool chk[MAX_OBJ] = {}; + int addr[MAX_OBJ], page = 0; + + for (const MenuItem& item : menu_items) { + if (item.verb == verb) { + chk[item.obj] = true; + addr[item.obj] = item.addr; } } // 目的語がない場合 @@ -313,7 +313,7 @@ void NACT_Sys2::cmd_open_obj(int verb) return; } // 以後、obj=0は戻るとして扱う - chk[0] = 0; + chk[0] = false; addr[0] = sco.default_addr(); // メニュー項目の準備 @@ -327,7 +327,7 @@ void NACT_Sys2::cmd_open_obj(int verb) if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_obj[i]); + ags->draw_text(caption_obj[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } diff --git a/src/sys/nact_sys3.cpp b/src/sys/nact_sys3.cpp index bde4eb1..abf75e4 100644 --- a/src/sys/nact_sys3.cpp +++ b/src/sys/nact_sys3.cpp @@ -35,11 +35,11 @@ void NACT_Sys3::cmd_open_verb() verb_obj = false; // 表示する動詞のチェック - int chk[MAX_VERB], page = 0; - - memset(chk, 0, sizeof(chk)); - for(int i = 0; i < menu_index; i++) { - chk[menu_verb[i]] = 1; + bool chk[MAX_VERB] = {}; + int page = 0; + + for (const MenuItem& item : menu_items) { + chk[item.verb] = true; } // メニュー項目の準備 @@ -53,7 +53,7 @@ void NACT_Sys3::cmd_open_verb() if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_verb[i]); + ags->draw_text(caption_verb[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; } @@ -69,7 +69,7 @@ void NACT_Sys3::cmd_open_verb() } else { cmd_open_obj(id[selection]); } - menu_index = 0; + menu_items.clear(); } void NACT_Sys3::cmd_open_obj(int verb) @@ -78,13 +78,13 @@ void NACT_Sys3::cmd_open_obj(int verb) verb_obj = false; // 表示する目的語のチェック - int chk[MAX_OBJ], addr[MAX_OBJ], page = 0; - - memset(chk, 0, sizeof(chk)); - for(int i = 0; i < menu_index; i++) { - if(menu_verb[i] == verb) { - chk[menu_obj[i]] = 1; - addr[menu_obj[i]] = menu_addr[i]; + bool chk[MAX_OBJ] = {}; + int addr[MAX_OBJ], page = 0; + + for (const MenuItem& item : menu_items) { + if (item.verb == verb) { + chk[item.obj] = true; + addr[item.obj] = item.addr; } } // 目的語がない場合 @@ -93,7 +93,7 @@ void NACT_Sys3::cmd_open_obj(int verb) return; } // 以後、obj=0は戻るとして扱う - chk[0] = 0; + chk[0] = false; addr[0] = sco.default_addr(); // メニュー項目の準備 @@ -107,7 +107,7 @@ void NACT_Sys3::cmd_open_obj(int verb) if(chk[i]) { ags->menu_dest_x = 2; ags->menu_dest_y += 2; - ags->draw_text(caption_obj[i]); + ags->draw_text(caption_obj[i].c_str()); id[index++] = i; ags->menu_dest_y += ags->menu_font_size + 2; }