diff scn2k/scn2k_textimpl.cc @ 58:0aaa5bb3dde5

Moved all opcodes from scn2k_text.cc to scn2k_textimpl.cc
author Thibaut GIRKA <thib@sitedethib.com>
date Fri, 18 Dec 2009 14:25:56 +0100
parents 6d9146f56ccf
children 36d92d21300f
line wrap: on
line diff
--- a/scn2k/scn2k_textimpl.cc
+++ b/scn2k/scn2k_textimpl.cc
@@ -62,6 +62,13 @@ void Text::impl_pause(Cmd& cmd) {
 	cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため)
 }
 
+void Text::impl_PauseCursor(Cmd& cmd)
+{
+	/* なんかよくわからないけどカーソル形状変更にしとく */
+	SetCursor(cmd.args[0].value);
+	cmd.clear();
+}
+
 void Text::impl_br(Cmd& cmd) {
 	text_stream.AddReturn();
 	cur_backlog_item.DeleteTextPos();
@@ -192,7 +199,14 @@ void Text::impl_Wait(Cmd& cmd) {
 	}
 
 	if (cmd.cmd3 == 111 || cmd.cmd3 == 112 || cmd.cmd3 == 121)
-		wait_time = base_time + cmd.args[0].value; //FIXME: second argument, counter. See ReadFrame for this
+	{
+		int index;
+		if (cmd.cmd4 == 1)
+			index = 0;
+		else
+			index = cmd.args[1].value;
+		wait_time = timer_var[index].start_time + cmd.args[0].value;
+	}
 	else
 		wait_time = old_time + cmd.args[0].value;
 
@@ -213,19 +227,413 @@ void Text::impl_GetClick(Cmd& cmd) {
 	cmd.clear();
 }
 
+void Text::impl_ResetTimer(Cmd& cmd) {
+	int index;
+
+	if (cmd.cmd4 == 1)
+		index = 0;
+	else
+		index = cmd.args[0].value;
+
+	eprintf("set basetime (%d)\n",index);
+	//TODO: Handle EX timer set
+	TimerAtom& atom = timer_var[index];
+	atom.start_time = old_time;
+
+	cmd.clear();
+}
+
+void Text::impl_Timer(Cmd& cmd) {
+	int index;
+
+	if (cmd.cmd4 == 1)
+		index = 0;
+	else
+		index = cmd.args[0].value;
+
+	eprintf("get time %dth\n",index);
+	if (timer_var.find(index) == timer_var.end())
+		cmd.SetSysvar(0);
+	else
+		cmd.SetSysvar(old_time - timer_var[index].start_time);
+}
+
 void Text::impl_ReadFrame(Cmd& cmd) {
-	eprintf("get timer value[%d]\n",cmd.args[0].value);
-	if (timer_var.find(cmd.args[0].value) == timer_var.end())
+	eprintf("get timer value[%d]\n", cmd.args[0].value);
+	if (frame_var.find(cmd.args[0].value) == frame_var.end())
 		cmd.SetSysvar(0);
 	else {
-		TimerAtom& atom = timer_var[cmd.args[0].value];
+		FrameTimerAtom& atom = frame_var[cmd.args[0].value];
 		if (atom.total_time <= 0) atom.total_time = 1;
 		int cur_tm = old_time - atom.start_time;
 		if (cur_tm < 0) cur_tm = atom.total_time; // エラーなら最終時間に合わせる
 		if (cur_tm > atom.total_time) cur_tm = atom.total_time;
 		// use 'long long'(64bit) or 'double'(80bit) type, since total_time, to and from is 32 bit.
-		int v = atom.from + (long long)(atom.to-atom.from)*cur_tm/int(atom.total_time);
+		int v = atom.from + (long long)(atom.to - atom.from)*cur_tm/int(atom.total_time);
 		cmd.SetSysvar(v);
 	}
 }
 
+void Text::impl_InitFrame(Cmd& cmd) {
+	FrameTimerAtom& atom = frame_var[cmd.args[0].value];
+	atom.from = cmd.args[1].value;
+	atom.to = cmd.args[2].value;
+	atom.total_time = cmd.args[3].value;
+	atom.start_time = old_time;
+	cmd.clear();
+}
+
+void Text::impl_InitFrames(Cmd& cmd) {
+	int i, j = 0;
+	for (i = 0; i < cmd.argc; i++)
+	{
+		int cnt = cmd.args[j++].value; // £³€Ê€Î€Ç̵»ë
+		int num = cmd.args[j++].value;
+		FrameTimerAtom& atom = frame_var[num];
+		atom.from = cmd.args[j++].value;
+		atom.to = cmd.args[j++].value;
+		atom.total_time = cmd.args[j++].value;
+		atom.start_time = old_time;
+	}
+	cmd.clear();
+}
+
+void Text::impl_ReadFrames(Cmd& cmd) {
+	vector<VarInfo> args = cmd.args;
+	vector<VarInfo>::iterator it = args.begin();
+	int argc = cmd.argc;
+	int timers_active = 0;
+	int i;
+	for (i=0; i < argc; i++)
+	{
+		int cnt = (it++)->value;
+		int num = (it++)->value;
+
+		if (frame_var.find(num) == frame_var.end()) {
+			cmd.SetFlagvar(*it++, 0);
+		}
+		else
+		{
+			FrameTimerAtom& atom = frame_var[num];
+			if (atom.total_time <= 0)
+				atom.total_time = 1;
+			int cur_tm = old_time - atom.start_time;
+			if (cur_tm < 0)
+				cur_tm = atom.total_time; // ¥š¥é¡Œ€Ê€éºÇœª»þŽÖ€Ë¹ç€ï€»€ë
+			if (cur_tm > atom.total_time)
+				cur_tm = atom.total_time;
+			// use 'long long'(64bit) or 'double'(80bit) type, since total_time, to and from is 32 bit.
+			int v = atom.from + (long long)(atom.to-atom.from)*cur_tm/int(atom.total_time);
+			cmd.SetFlagvar(*it++, v);
+			if (atom.total_time != -1 && cur_tm < atom.total_time)
+				timers_active = 1;
+		}
+	}
+	cmd.SetSysvar(timers_active);
+}
+
+void Text::impl_rnd(Cmd& cmd)
+{
+	/* rand() */
+	int min, max;
+	if (cmd.args.size() == 2)
+	{
+		min = cmd.args[0].value;
+		max = cmd.args[1].value;
+	}
+	else
+	{
+		min = 0;
+		max = cmd.args[0].value;
+	}
+	if (min > max)
+	{
+		int tmp = max;
+		max = min;
+		min = tmp;
+	}
+	int r = random();
+	if (min == max)
+		r = min;
+	else
+		r = (r % (max-min)) + min;
+	cmd.SetSysvar(r);
+}
+
+void Text::impl_pcnt(Cmd& cmd)
+{
+	cmd.SetSysvar(100 * cmd.args[0].value / cmd.args[1].value);
+}
+
+void Text::impl_abs(Cmd& cmd)
+{
+	cmd.SetSysvar(abs(cmd.args[0].value));
+}
+
+void Text::impl_power(Cmd& cmd)
+{
+	//TODO
+	//cmd.SetSysvar(pow(cmd.args[0].value, cmd.args[1].value));
+}
+
+void Text::impl_min(Cmd& cmd)
+{
+	int a = cmd.args[0].value;
+	int b = cmd.args[1].value;
+	cmd.SetSysvar((a < b) ? a : b);
+}
+
+void Text::impl_max(Cmd& cmd)
+{
+	int a = cmd.args[0].value;
+	int b = cmd.args[1].value;
+	cmd.SetSysvar((a > b) ? a : b);
+}
+
+void Text::impl_index_series(Cmd& cmd)
+{
+	//TODO: This one is not fully documented in
+	// http://dev.haeleth.net/rldev/manual.html
+	// Try to figure out what's it...
+
+	/* range conversion : 比率に丸める */
+	// アルゴリズムは間違えてるような気がする
+	// 
+	if (cmd.args.size() >= 7)
+	{
+		int val = cmd.args[0].value;
+		int offset = cmd.args[1].value;
+		int r_min = cmd.args[2].value;
+		int v_min = cmd.args[3].value;
+		int v_max = cmd.args[4].value;
+		int r_max = cmd.args[5].value;
+		int mode = cmd.args[6].value;
+		// rldev : mode == 1,3 : 'acceralating curve', 2,3: 'decelerating curve'
+		// 複数の引数リスト(r_minからmodeまでのリスト)もつこともあり、その場合は
+		// "cancel out in some way" らしい
+		if (mode == 1 || mode == 3)
+			val += offset;
+		else if (mode == 2 || mode == 4)
+			val -= offset;
+if (cmd.args.size() != 7)
+	fprintf(stderr,"\n%d/%d: cmd 01-04:0320 : XXXX NOT SUPPORTED LIST : DOUBLE RANGE CONVERSION!   XXXXXXXXXXX\n",cmd.scn,cmd.pos);
+		if (val < v_min)
+			val = v_min;
+		if (val > v_max)
+			val = v_max;
+		val = (r_max-r_min)*(val-v_min)/(v_max-v_min) + r_min;
+		cmd.SetSysvar(val);
+	}
+}
+
+void Text::impl_constrain(Cmd& cmd)
+{
+	/* range 内に丸める */
+	int min = cmd.args[0].value;
+	int val = cmd.args[1].value;
+	int max = cmd.args[2].value;
+	if (min > max) {
+		max = cmd.args[0].value;
+		min = cmd.args[2].value;
+	}
+	if (val < min)
+		val = min;
+	if (val > max)
+		val = max;
+	cmd.SetSysvar(val);
+}
+
+
+void Text::impl_load(Cmd& cmd)
+{
+	// メニューからのロード
+	cmd.cmd_type = CMD_LOADREQ;
+}
+
+void Text::impl_GetWindowAttr(Cmd& cmd)
+{
+	// テキストウィンドウの色設定
+	int r, g, b, a, flag;
+
+	if (cmd.cmd3 == 2617) // 元設定を取り出す
+		config->GetOriginalParam("#WINDOW_ATTR", 5, &r, &g, &b, &a, &flag);
+	else
+		config->GetParam("#WINDOW_ATTR", 5, &r, &g, &b, &a, &flag);
+
+	if (cmd.args.size() != 5) {
+		fprintf(stderr,"cmd 01-04:%4d : invalid arg size\n", cmd.cmd3);
+	} else {
+		vector<VarInfo> args(cmd.args);
+		cmd.SetFlagvar(args[0], r);
+		cmd.SetFlagvar(args[1], g);
+		cmd.SetFlagvar(args[2], b);
+		cmd.SetFlagvar(args[3], a);
+		cmd.SetFlagvar(args[4], flag);
+	}
+}
+
+void Text::impl_SetWindowAttr(Cmd& cmd)
+{
+	int r, g, b, a, flag;
+	config->GetParam("#WINDOW_ATTR", 5, &r, &g, &b, &a, &flag);
+
+	switch(cmd.cmd3) {
+		case 2260:
+			r = cmd.args[0].value;
+			break;
+		case 2261:
+			g = cmd.args[0].value;
+			break;
+		case 2262:
+			b = cmd.args[0].value;
+			break;
+		case 2263:
+			a = cmd.args[0].value;
+			break;
+		case 2264:
+			flag = cmd.args[0].value;
+			break;
+		case 2267: 
+			r = cmd.args[0].value;
+			g = cmd.args[1].value;
+			b = cmd.args[2].value;
+			a = cmd.args[3].value;
+			flag = cmd.args[4].value;
+			break;
+	}
+	config->SetParam("#WINDOW_ATTR", 5, r, g, b, a, flag);
+	SetWindowColor(r, g, b, a, flag);
+	cmd.clear();
+}
+
+void Text::impl_GetDefConfig(Cmd& cmd)
+{
+	int v = 0;
+	switch(cmd.cmd3) {
+		case 2600:
+		case 2605:
+			config->GetOriginalParam("#INIT_MESSAGE_SPEED", 1, &v);
+			break;
+		case 2601:
+			config->GetOriginalParam("#INIT_MESSAGE_SPEED_MOD", 1, &v);
+			break;
+		case 2604:
+			config->GetOriginalParam("#MESSAGE_KEY_WAIT_USE", 1, &v);
+			break;
+		case 2606:
+			config->GetOriginalParam("#MESSAGE_KEY_WAIT_TIME", 1, &v);
+			break;
+	}
+	cmd.SetSysvar(v);
+}
+
+void Text::impl_GetConfig(Cmd& cmd)
+{
+	int v;
+	switch (cmd.cmd3)
+	{
+		case 2323:
+		case 2351:
+			config->GetParam("#INIT_MESSAGE_SPEED", 1, &v);
+			break;
+		case 2324:
+			config->GetParam("#INIT_MESSAGE_SPEED_MOD", 1, &v);
+			break;
+		case 2350:
+			config->GetParam("#MESSAGE_KEY_WAIT_USE", 1, &v);
+			break;
+		case 2352:
+			config->GetParam("#MESSAGE_KEY_WAIT_TIME", 1, &v);
+			break;
+	}
+
+	cmd.SetSysvar(v);
+}
+
+void Text::impl_SetConfig(Cmd& cmd)
+{
+	int speed, use_speed_mod, wait, use_wait_mod;
+	config->GetParam("#INIT_MESSAGE_SPEED", 1, &speed);
+	config->GetParam("#INIT_MESSAGE_SPEED_MOD", 1, &use_speed_mod);
+	config->GetParam("#MESSAGE_KEY_WAIT_USE", 1, &use_wait_mod);
+	config->GetParam("#MESSAGE_KEY_WAIT_TIME", 1, &wait);
+	switch (cmd.cmd3)
+	{
+		case 2223:
+		case 2251:
+			speed = cmd.args[0].value;
+			if (speed < 10) //FIXME: ??? 0 ???
+				speed = 10;
+			if (speed > 10000) //FIXME: ??? 255 ???
+				speed = 10000;
+			config->SetParam("#INIT_MESSAGE_SPEED", 1, speed);
+			break;
+		case 2224:
+			use_speed_mod = cmd.args[0].value;
+			config->SetParam("#INIT_MESSAGE_SPEED_MOD", 1, use_speed_mod);
+			break;
+		case 2250:
+			use_wait_mod = cmd.args[0].value;
+			config->SetParam("#MESSAGE_KEY_WAIT_USE", 1, use_wait_mod);
+			break;
+		case 2252:
+			int wait = cmd.args[0].value;
+			if (wait < 0)
+				wait = 0;
+			else if (wait > 60000)
+				wait = 60000;
+			config->SetParam("#MESSAGE_KEY_WAIT_TIME", 1, wait);
+			break;
+	}
+
+	if (use_speed_mod) // FIXME: Not the other way around?
+		SetTextSpeed(-1);
+	else
+		SetTextSpeed(speed);
+
+	if (use_wait_mod)
+		SetTextWait(wait);
+	else
+		SetTextWait(-1);
+
+	cmd.clear();
+}
+
+void Text::impl_GetName(Cmd& cmd)
+{
+	// replace_name を得る
+	int n = cmd.args[0].value;
+	if (n >= 0 && n < 26) // FIXME: Should go up to 702, but otakunoraifu is not ready for that yet
+		cmd.SetStrvar(cmd.args[1], replace_name[n]);
+	else
+		cmd.SetStrvar(cmd.args[1], "");
+}
+
+void Text::impl_SetName(Cmd& cmd)
+{
+	// replace_name を得る
+	int n = cmd.args[0].value;
+	if (n >= 0 && n < 26) // FIXME: Should go up to 702, but otakunoraifu is not ready for that yet
+		replace_name[n] = cmd.Str(cmd.args[1]);
+}
+
+void Text::impl_GetLocalName(Cmd& cmd)
+{
+	// replace_name2 を得る
+	int n = cmd.args[0].value;
+	if (n >= 0 && n < 26) // FIXME: Should go up to 702, but otakunoraifu is not ready for that yet
+		cmd.SetStrvar(cmd.args[1], replace_name2[n]);
+	else
+		cmd.SetStrvar(cmd.args[1], "");
+}
+
+void Text::impl_SetLocalName(Cmd& cmd)
+{
+	// replace_name2 の設定
+	int n = cmd.args[0].value;
+	if (n >= 0 && n < 26) // FIXME: Should go up to 702, but otakunoraifu is not ready for that yet
+		replace_name2[n] = cmd.Str(cmd.args[1]);
+
+	cmd.clear();
+}
+