Scenario: Refactor address handling

This commit is contained in:
kichikuou
2024-12-18 13:50:46 +09:00
parent f8acad01d8
commit f356d268df
6 changed files with 44 additions and 46 deletions
+3 -11
View File
@@ -117,20 +117,12 @@ void NACT::quit(int code)
EMSCRIPTEN_KEEPALIVE // Prevent inlining, because this function is listed in ASYNCIFY_ADD
void NACT::execute()
{
if (!sco.is_addr_valid()) {
sys_error("Scenario error: invalid address %d:0x%x", sco.page(), sco.addr());
return;
}
if (game_id.sys_ver == 1 && sco.page() == 0 && sco.addr() == 2) {
if (game_id.sys_ver == 1 && sco.page() == 0 && sco.current_addr() == 2) {
opening();
}
sco.skip_syseng_rev_marker();
// 1コマンド実行
sco.mark_cmd_start();
uint8 cmd = sco.getd();
uint8 cmd = sco.fetch_command();
if(set_palette && cmd != 'P') {
// パレット設定が終わった
@@ -323,7 +315,7 @@ void NACT::message(uint8 terminator)
}
}
if (!ags->draw_menu)
msgskip->on_message(sco.page(), sco.addr());
msgskip->on_message(sco.page(), sco.current_addr());
// TODO: Convert hankaku to zenkaku
output_console(buf);
+5 -6
View File
@@ -145,8 +145,7 @@ void NACT_Sys1::cmd_branch()
if(!condition) {
// 次の'}'命令までスキップする(ネストも考慮する)
for(;;) {
sco.mark_cmd_start();
uint8 cmd = sco.getd();
uint8 cmd = sco.fetch_command();
if(cmd == '!') {
int index = sco.getd();
@@ -785,7 +784,7 @@ void NACT_Sys1::cmd_q()
FPUTW(0);
FPUTW(mako->current_music);
FPUTW(0);
FPUTW(sco.addr());
FPUTW(sco.current_addr());
FPUTW(0);
for(int i = 0; i < 512; i++) {
FPUTW(var[i]);
@@ -1294,7 +1293,7 @@ uint16 NACT_Sys1::cali()
}
}
if (!ok) {
sys_error("cali: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
return (uint16)(cali[1] & 0xffff);
}
@@ -1309,10 +1308,10 @@ uint16 NACT_Sys1::cali2()
} else if(0xc0 <= dat && dat <= 0xff) {
val = ((dat & 0x3f) << 8) | sco.getd();
} else {
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
if (sco.getd() != 0x7f) {
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
return val;
}
+5 -6
View File
@@ -80,8 +80,7 @@ void NACT_Sys2::cmd_branch()
if(!condition) {
// 次の'}'命令までスキップする(ネストも考慮する)
for(;;) {
sco.mark_cmd_start();
uint8 cmd = sco.getd();
uint8 cmd = sco.fetch_command();
if(cmd == '!') {
int index = sco.getd();
@@ -870,7 +869,7 @@ void NACT_Sys2::cmd_q()
FPUTW(0);
FPUTW(mako->current_music);
FPUTW(0);
FPUTW(sco.addr());
FPUTW(sco.current_addr());
FPUTW(0);
for(int i = 0; i < 512; i++) {
FPUTW(var[i]);
@@ -1263,7 +1262,7 @@ uint16 NACT_Sys2::cali()
}
}
if (!ok) {
sys_error("cali: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
return (uint16)(cali[1] & 0xffff);
}
@@ -1278,10 +1277,10 @@ uint16 NACT_Sys2::cali2()
} else if(0xc0 <= dat && dat <= 0xff) {
val = ((dat & 0x3f) << 8) | sco.getd();
} else {
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
if (sco.getd() != 0x7f) {
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
return val;
}
+5 -5
View File
@@ -31,7 +31,7 @@ void NACT_Sys3::cmd_calc()
void NACT_Sys3::cmd_branch()
{
int condition = cali();
int t_addr = sco.addr() + 2;
int t_addr = sco.current_addr() + 2;
int f_addr = sco.getw();
// sigmarion3 最適化誤爆の対策
@@ -823,7 +823,7 @@ void NACT_Sys3::cmd_q()
FPUTW(0);
FPUTW(mako->current_music);
FPUTW(0);
FPUTW(sco.addr());
FPUTW(sco.current_addr());
FPUTW(0);
for(int i = 0; i < 512; i++) {
FPUTW(var[i]);
@@ -1428,7 +1428,7 @@ uint16 NACT_Sys3::cali()
}
}
if (!ok) {
sys_error("cali: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
return (uint16)(cali[1] & 0xffff);
}
@@ -1443,10 +1443,10 @@ uint16 NACT_Sys3::cali2()
} else if(0xc0 <= dat && dat <= 0xff) {
val = ((dat & 0x3f) << 8) | sco.getd();
} else {
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
if (sco.getd() != 0x7f) {
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.addr());
sys_error("cali2: invalid expression at %d:%04x", sco.page(), sco.cmd_addr());
}
return val;
}
+16 -5
View File
@@ -3,6 +3,19 @@
#include "common.h"
#include "encoding.h"
uint8_t Scenario::fetch_command()
{
if (addr_ < 2 || static_cast<size_t>(addr_) >= data_.size())
sys_error("Scenario error: invalid address %d:%04x", page_, addr_);
// Skip SysEng's "new style" marker
if (page_ == 0 && addr_ == 2 && data_[2] == 'R' && data_[3] == 'E' && data_[4] == 'V')
addr_ = 5;
cmd_addr_ = addr_;
return getd();
}
void Scenario::skip_syseng_string(Encoding *enc, uint8_t terminator)
{
for (uint8_t c = getd(); c != terminator; c = getd()) {
@@ -14,15 +27,13 @@ void Scenario::skip_syseng_string(Encoding *enc, uint8_t terminator)
void Scenario::get_syseng_string(char* buf, int size, Encoding *enc, uint8_t terminator)
{
int start_addr = addr_;
int i = 0;
for (uint8_t c = getd(); c != terminator; c = getd()) {
if (c != '\\')
ungetd();
int len = enc->mblen(ptr());
if (i + len >= size)
sys_error("String buffer overrun at %d:0x%x", page_, start_addr);
sys_error("String buffer overrun at %d:%04x", page_, cmd_addr_);
memcpy(&buf[i], ptr(), len);
i += len;
skip(len);
@@ -63,8 +74,8 @@ void Scenario::page_call(int target_page)
[[noreturn]] void Scenario::unknown_command(uint8_t cmd) {
if (cmd >= 0x20 && cmd < 0x7f) {
sys_error("Unknown Command: '%c' at %d:0x%d", cmd, page_, cmd_start_addr);
sys_error("Unknown Command: '%c' at %d:%04x", cmd, page_, cmd_addr_);
} else {
sys_error("Unknown Command: %02x at %d:0x%d", cmd, page_, cmd_start_addr);
sys_error("Unknown Command: %02x at %d:%04x", cmd, page_, cmd_addr_);
}
}
+10 -13
View File
@@ -14,7 +14,7 @@ public:
void page_jump(int page, int addr) {
data_ = adisk.load(page + 1);
page_ = page;
addr_ = addr;
cmd_addr_ = addr_ = addr;
}
size_t size() const { return data_.size(); }
uint8_t& operator[](int i) { return data_[i]; }
@@ -22,18 +22,16 @@ public:
int default_addr() { return data_[0] | data_[1] << 8; }
int page() const { return page_; }
int addr() const { return addr_; }
bool is_addr_valid() const {
return addr_ >= 2 && static_cast<size_t>(addr_) < data_.size();
}
// Skip SysEng's "new style" marker
void skip_syseng_rev_marker() {
if (page_ == 0 && addr_ == 2 && data_[2] == 'R' && data_[3] == 'E' && data_[4] == 'V')
addr_ = 5;
}
// start address of the current command
int cmd_addr() const { return cmd_addr_; }
// current address, possibly in the middle of a command
int current_addr() const { return addr_; }
void jump_to(int addr) { addr_ = addr; }
void jump_to(int addr) { cmd_addr_ = addr_ = addr; }
void skip(int n) { addr_ += n; }
uint8_t fetch_command();
uint8_t getd() { return data_[addr_++]; }
uint16_t getw() {
uint16_t w = data_[addr_++];
@@ -54,7 +52,6 @@ public:
void page_stack_pop() { page_stack.pop_back(); }
void page_stack_clear() { page_stack.clear(); }
void mark_cmd_start() { cmd_start_addr = addr_; }
[[noreturn]] void unknown_command(uint8_t cmd);
private:
@@ -62,7 +59,7 @@ private:
std::vector<uint8_t> data_;
int page_;
int addr_;
int cmd_start_addr;
int cmd_addr_;
std::vector<int> label_stack;
std::vector<std::pair<int, int>> page_stack;
};