mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-09-22 22:58:12 +03:00
Scenario: Refactor address handling
This commit is contained in:
+3
-11
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user