ユーザ用ツール

サイト用ツール


x88000

文書の過去の版を表示しています。


X88000

概要

Project X88000において開発・配布されているPC-8801エミュレータ。 ソースコードはPDSとして公開されており自由に改変できる。

Linux対応版とWindows版とがあり、Linux版は音声のサポートがない。

HAL研PCG-8800にPCGおよび音源まで含めて対応している。

高性能な反面、設定可能な項目は少なく、As Isで利用する場合は問題ないが、キーバインドを変更したい、あるいは、イメージファイルの拡張子の対応を増やしたいといったような場合には、ソースに手を入れて再構築する必要がある。

開発が止まって久しいので、Linux版はさておき、Windows版はある程度手を入れないとビルドすらままならない。

改造

ビルド可能にする(Windows版)

Windows版はDirectX7をターゲットに作成されており、Visual Studio 2019 Communityなどではコンパイルすらできない。 とはいえ、いくつかのポイントを修正すればビルド可能であり、現在でも手を入れたバージョンで遊ぶことが可能である。

よくわからないが、Debugフラグで構築したところ、Windows DefencerにTrojan.Script/Wacatac.B!mlと判定され、駆除された。 Releaseフラグで構築すると特に何も言われないので、誤検出ではないかと思うが、不安な方は使わないほうがいいだろう。

修正箇所

  • StdHeader.h:112~117の一連のtypedefを無効化する。
  • コンパイルエラー(LPDWORDに変換できない)を起こすuint32_t宣言の変数をすべてDWORD宣言に変更する。
  • ライブラリdinput.libおよびdinput.dllはそれぞれdinput8.libおよびdinput8.dllに置き換える。

以上を修正するとバイナリを得ることができる。

カーソルキーの機能を変える(Windows版)

X88000はエミュレータとしての完成度が高いものの、キーバインドを含め、設定可能な項目が非常に少ない。 ノートPCで遊ぶ場合など、テンキーがない環境では、カーソルキーにテンキーの2,4,6,8あるいは1,2,3,5などを割り当てて、快適にゲームを楽しみたいのだが、これができない。

なので、キー入力処理に手を入れて、カーソルキーの処理を変更する。 なお、ゲームによって、2,4,6,8または1,2,3,5で上下左右の割り当てになっているので、メニューから切り替えられるようにしておく。

リソース(メニュー)の作成

リソースエディターで、メニューを追加する。 IDR_MAINMENU(日本語)およびIDR_MAINMENU_E(英語)の二つがあるので、両方に追加する。 X88000カーソルキーメニュー

それぞれのIDシンボルは以下のようにする。

  • IDM_CURSORKEYS_CURSOR
  • IDM_CURSORKEYS_2468
  • IDM_CURSORKEYS_1235

処理タイプフラグの追加

キー処理はX88Frameの中で行われているので、フラグを、X88Frame.cppおよびX88Frame.hに追加していく。

X88Frame.hの93行目からフラグの宣言を追加。

91:    // keyboard state table
92:    static uint8_t m_abtKeyboardState[256];
93:#if 1
94:    // cursor key mapping
95:    static uint8_t m_cursorMode;
96:#endif

X88Frame.cppの122行目からフラグのインスタンスを定義する。

118:// keyboard state table
119:
120:uint8_t CX88Frame::m_abtKeyboardState[256];
121:
122:#if 1
123:// cursor keys
124:uint8_t CX88Frame::m_cursorMode = 0;
125:#endif

メニュー処理の実装

X88Frame.cppCX88Frame::WndProc()処理内に追加(汚い)

		case IDM_VERSION:
			OnHelpMenuCommand(LOWORD(wParam));
			break;
#if 1
		case IDM_CURSORKEYS_CURSOR:
			m_cursorMode = 0;
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_CURSOR, MFS_CHECKED);
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_2468, MFS_UNCHECKED);
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_1235, MFS_UNCHECKED);
			break;
		case IDM_CURSORKEYS_2468:
			m_cursorMode = 1;
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_CURSOR, MFS_UNCHECKED);
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_2468, MFS_CHECKED);
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_1235, MFS_UNCHECKED);
			break;
		case IDM_CURSORKEYS_1235:
			m_cursorMode = 2;
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_CURSOR, MFS_UNCHECKED);
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_2468, MFS_UNCHECKED);
			CheckMenuItem(GetMenu(hwnd), IDM_CURSORKEYS_1235, MFS_CHECKED);
			break;
#endif
		}
		break;

本来は、ラジオボタンにするべきだろうが、今時のメニューはどうするべきなのかちゃんとわかってないので、汚い処理になっている。

キー処理の変更

X8Frame.cpp CX88Frame::UpdateAllKeyMatrics()処理内に以下の変更。

		} else {
			bShift = IsKeyPressed(VK_SHIFT);
		}
#if 0
		bool bUpArrow = IsKeyPressed(VK_UP),
			bRightArrow = IsKeyPressed(VK_RIGHT);
		if (X88k().PC88().Z80Main().GetBasicMode() ==
				CPC88Z80Main::BASICMODE_N80V1)
		{
			if (IsKeyPressed(VK_DOWN)) {
				bShift = bUpArrow = true;
			}
			if (IsKeyPressed(VK_LEFT)) {
				bShift = bRightArrow = true;
			}
		}
#else
		bool bUpArrow = false, bRightArrow = false;
		if (m_cursorMode == 0||IsKeyPressed(VK_CONTROL))
		{
			bUpArrow = IsKeyPressed(VK_UP);
			bRightArrow = IsKeyPressed(VK_RIGHT);
			if (X88k().PC88().Z80Main().GetBasicMode() ==
				CPC88Z80Main::BASICMODE_N80V1)
			{
				if (IsKeyPressed(VK_DOWN)) {
					bShift = bUpArrow = true;
				}
				if (IsKeyPressed(VK_LEFT)) {
					bShift = bRightArrow = true;
				}
			}
		}
		else
		{
			if (IsKeyPressed(VK_DOWN) || IsKeyPressed(VK_LEFT) || IsKeyPressed(VK_RIGHT) || IsKeyPressed(VK_UP))
			{
				if (m_cursorMode == 1)
				{
					X88k().SetKeyMatrics(0x00, 2, IsKeyPressed(VK_DOWN));
					X88k().SetKeyMatrics(0x00, 4, IsKeyPressed(VK_LEFT));
					X88k().SetKeyMatrics(0x00, 6, IsKeyPressed(VK_RIGHT));
					X88k().SetKeyMatrics(0x01, 0, IsKeyPressed(VK_UP));
				}
				else
				{
					X88k().SetKeyMatrics(0x00, 2, IsKeyPressed(VK_DOWN));
					X88k().SetKeyMatrics(0x00, 1, IsKeyPressed(VK_LEFT));
					X88k().SetKeyMatrics(0x00, 3, IsKeyPressed(VK_RIGHT));
					X88k().SetKeyMatrics(0x00, 5, IsKeyPressed(VK_UP));
				}
				return;
			}
		}
#endif
		X88k().SetKeyMatrics(0x00, 0, IsKeyPressed(VK_NUMPAD0));
		X88k().SetKeyMatrics(0x00, 1, IsKeyPressed(VK_NUMPAD1));

#if 0で無効化しているのがもともとのカーソルキー処理。 PC-8001などは、カーソルキーが縮退1)しているので、その処理をしている。 ここで、m_cursorModeが0かコントロールキーが押されていたら、カーソルキーとして処理し、そうでなければ、テンキーの振りをするだけである。

1)
上下と左右がそれぞれ一つのキーにまとめられ、シフトキーの有無で向きを変えていた。
x88000.1610522614.txt.gz · 最終更新: 2021/01/13 16:23 by araki