「Wine for Mac OS X で Windows ゲーム」の雑なまとめ(1)

WINE

テストしたゲームも増えてきたので軽くまとめてみます。試してみたのは全て体験版またはベンチマークで、完走率は8割くらい。2D の方が簡単に動くかと思ったらそうでもありませんでした。

製品版ではアクティベーションがあり、CrossOver Mac でも上手くいかないことがあるようです。あくまで体験版での動作検証で製品版が正常に動くとは限りませんのでご注意下さい。また、システムの構成やプラグインのバージョン、バリアント等によっても上手くいかない可能性があります。

この記事は Wine を使って Mac で Windows ゲームをやるために特化したものです。Wine の基本的な設定などはアーカイブからどうぞ。

Wine でゲームやるときに大切なこと

ひとまずざっくりと。

OpenGL をまったく受け付けないゲームがある

Wine のレジストリで GDI を使用するようすると起動出来るソフトもありました。

Windows Media Player が必要なゲームがある

映像や音声に Windows Media フォーマットを利用しているゲームがあります(MHF では必須)。

Mesa と GStreamer のバリアントに気をつける

この2つはバリアントを間違っただけでゲームが動かなくなる可能性があります。Wine とは別のポートなので気づきにくいかもしれません。

Apple 謹製 X11.app でも XQuartz.app でも Wine は動く

XRandR に微妙に違いがあるようですが、動作などはほとんど同じです。これが原因で「動く」「動かない」はあまりないと思います。

動作環境

MacBook Air(Late 2010)/Mac OS X 10.6/NVIDIA GeForce 320M(256MB)

MacPorts

glxgears @8.0.0_0 (active)
glxinfo @8.0.0_0 (active)
gst-plugins-bad @0.10.23_0 (active)
gst-plugins-base @0.10.36_0+universal (active)
gst-plugins-gl @0.10.2_3 (active)
gst-plugins-good @0.10.31_0 (active)
gst-plugins-ugly @0.10.19_1 (active)
gstreamer @0.10.36_0+universal
gstreamer @0.10.36_0 (active)
mesa @8.0.1_0+iglx+python27
mesa @8.0.1_0+iglx+python27+universal
mesa @8.0.1_0+python27
mesa @8.0.1_0+python27+universal (active)
wine-devel @1.5.1_0 (active)
winetricks @20120308_0 (active)

HKEY_CURRENT_USER\Software\Wine\Direct3D

"AlwaysOffscreen"="enabled"
"DirectDrawRenderer"="opengl"
"Multisampling"="enabled"
"OffscreenRenderingMode"="fbo"
"PixelShaderMode"="enabled"
"RenderTargetLockMode"="auto"
"UseGLSL"="enabled"
"VertexShaderMode"="hardware"
"VideoMemorySize"="256"
"VideoPciDeviceID"=dword:000008a2
"VideoPciVendorID"=dword:000010de

レジストリキーの詳細は UsefulRegistryKeys - The Official Wine Wiki 参照。

MacBook Air の場合、ビデオメモリはメインメモリと共用のため VideoMemorySize はもっと増やしてもいいかもしれません。増やすと一応 dxdiag ではその数値で表記されます。

"VideoPciDeviceID" と "VideoPciVendorID" の値は必須ではありませんが、入れておくと BIO HAZARD 5 では「Direct3D HAL」として認識されました。Mac の場合は システムプロファイラ の「製造元」と「装置 ID」に記載されています。NVIDIA のベンダーコードは「10de」、デバイス ID は NVIDIA DEVELOPER ZONE Device - ID List で公開されています(Mac の場合は微妙に ID が異なるため特殊かもしれません)。

完走済みベンチマーク

いずれもシーンが切り替わる際にコマ落ちが発生するため要調整。Final Fantasy XI のみ "AlwaysOffscreen"="disabled"、"OffscreenRenderingMode"="backbuffer" を使用しないとシーン切り替え時に破綻が生じます。

  • BIO HAZARD 5 Benchmark
  • Monster Hunter Frontier Online Benchmark
  • Final Fantasy XI Benchmark

WineTricks をインストールしておく

自分でエンドユーザーランタイムを拾ってきてインストールするのもありですが、レジストリを編集する時は WineTricks を使ったほうが楽です(マイナーなライブラリを探すのにも)。WineTricks の使い方はアーカイブから検索して下さい。

sudo port install winetricks

バグフィックス用のサブプレフィックスを作る

必須ではありませんが、レジストリを編集していると編集した部分が悪いのかプラグインが悪いのかよくわからなくなります。検証用にひとつ作っておいてもいいと思います。

新しいプレフィックスは Wine コマンドが実行時にプレフィックスディレクトリが存在しなければ自動的に作成されます。以下はユーザーのホームディレクトリに ".wine-beta" というプレフィックスディレクトリを作成する場合のコマンドです。コマンドは上下どちらも同じ動作です。

WINEPREFIX=$HONE/.wine-beta wine winecfg
WINEPREFIX=~/.wine-beta wine winecfg

新しいプレフィックスの作成が始まるので少し待ちます。その後、Wine Config が起動するので用が無ければそのまま終了します。以降、サブプレフィックスは WINPREFIX=~/.wine-beta で呼び出します。

以下のように新しいプレフィックスディレクトリにパスを通す方法もあります。

export WINEPREFIX=$HOME/.wine-beta
wine winecfg

プレフィックスを削除したいときはディレクトリを削除します。

rm -rf ~/.wine-beta

Mesa

「Mesa」は X11 で OpenGL を使えるようにする重要なライブラリです。Wine はデフォルトで OpenGL を使用しますが、「Mesa」のバリアントによって OpenGL が使えなくなることがあるので注意が必要かもしれません。

X11 で OpenGL が使えるか確認する

X11 で OpenGL が使えるかどうか確認するには「glxinfo」と「glxgears」を使用します。どちらも MacPorts から入手出来ます。

sudo port install glxinfo
sudo port install glxgears

上記二つをインストールしたら glxgears と叩いてみます。歯車が並んだ映像が表示されれば OpenGL が有効になっています。

以下のようなメッセージが表示された場合は OpenGL が無効です。次項の設定で直るかもしれません。

dyld: Library not loaded: /opt/local/lib/libGL.1.dylib
Referenced from: /opt/local/bin/glxgears
Reason: image not found
Trace/BPT trap

glxinfo ではグラフィックデバイスの拡張機能などを確認することが出来ます。レンダリングが出来ているかどうか確認するのであれば以下のコマンドを打ち込みます。"direct rendering: Yes" が返ればレンダリングが出来ているということになります。

glxinfo | grep direct
direct rendering: Yes

XQuartz や MacBook Air(Late 2010)の GeForce 320M が持つ OpenGL の拡張機能の確認も出来ます。Wine のレジストリで "DisabledExtensions" の項目があるのでもしかしたら何かに使えるかもしれません。

glxinfo
direct rendering: Yes
server glx vendor string: SGI
server glx version string: 1.4
server glx extensions:
    GLX_SGIX_fbconfig, GLX_SGIS_multisample, GLX_ARB_multisample, 
    GLX_EXT_visual_info, GLX_EXT_import_context
client glx vendor string: Mesa Project and SGI
client glx version string: 1.4
client glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context, 
    GLX_EXT_visual_info, GLX_EXT_visual_rating, GLX_EXT_framebuffer_sRGB, 
    GLX_MESA_copy_sub_buffer, GLX_MESA_multithread_makecurrent, 
    GLX_MESA_swap_control, GLX_OML_swap_method, GLX_OML_sync_control, 
    GLX_SGI_make_current_read, GLX_SGI_swap_control, GLX_SGI_video_sync, 
    GLX_SGIS_multisample, GLX_SGIX_fbconfig, GLX_SGIX_pbuffer, 
    GLX_SGIX_visual_select_group, GLX_EXT_texture_from_pixmap, 
    GLX_INTEL_swap_event
GLX version: 1.4
GLX extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, GLX_EXT_import_context, 
    GLX_EXT_visual_info, GLX_MESA_multithread_makecurrent, 
    GLX_SGIS_multisample, GLX_SGIX_fbconfig
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce 320M OpenGL Engine
OpenGL version string: 2.1 NVIDIA-1.6.36
OpenGL shading language version string: 1.20
OpenGL extensions:
    GL_ARB_transpose_matrix, GL_ARB_vertex_program, GL_ARB_vertex_blend, 
    GL_ARB_window_pos, GL_ARB_shader_objects, GL_ARB_vertex_shader, 
    GL_ARB_shading_language_100, GL_EXT_multi_draw_arrays, 
    GL_EXT_clip_volume_hint, GL_EXT_rescale_normal, 
    GL_EXT_draw_range_elements, GL_EXT_fog_coord, 
    GL_EXT_gpu_program_parameters, GL_EXT_geometry_shader4, 
    GL_EXT_transform_feedback, GL_APPLE_client_storage, 
    GL_APPLE_specular_vector, GL_APPLE_transform_hint, GL_APPLE_packed_pixels, 
    GL_APPLE_fence, GL_APPLE_vertex_array_object, 
    GL_APPLE_vertex_program_evaluators, GL_APPLE_element_array, 
    GL_APPLE_flush_render, GL_APPLE_aux_depth_stencil, 
    GL_NV_texgen_reflection, GL_NV_light_max_exponent, GL_IBM_rasterpos_clip, 
    GL_SGIS_generate_mipmap, GL_ARB_imaging, GL_ARB_point_parameters, 
    GL_ARB_texture_env_crossbar, GL_ARB_texture_border_clamp, 
    GL_ARB_multitexture, GL_ARB_texture_env_add, GL_ARB_texture_cube_map, 
    GL_ARB_texture_env_dot3, GL_ARB_multisample, GL_ARB_texture_env_combine, 
    GL_ARB_texture_compression, GL_ARB_texture_mirrored_repeat, GL_ARB_shadow, 
    GL_ARB_depth_texture, GL_ARB_fragment_program, 
    GL_ARB_fragment_program_shadow, GL_ARB_fragment_shader, 
    GL_ARB_occlusion_query, GL_ARB_point_sprite, 
    GL_ARB_texture_non_power_of_two, GL_ARB_vertex_buffer_object, 
    GL_ARB_pixel_buffer_object, GL_ARB_draw_buffers, 
    GL_ARB_shader_texture_lod, GL_ARB_color_buffer_float, 
    GL_ARB_half_float_vertex, GL_ARB_texture_rg, 
    GL_ARB_texture_compression_rgtc, GL_ARB_framebuffer_object, 
    GL_EXT_compiled_vertex_array, GL_EXT_draw_buffers2, 
    GL_EXT_framebuffer_object, GL_EXT_framebuffer_blit, 
    GL_EXT_framebuffer_multisample, GL_EXT_texture_rectangle, 
    GL_ARB_texture_rectangle, GL_EXT_texture_env_add, GL_EXT_blend_color, 
    GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_texture_lod_bias, 
    GL_EXT_abgr, GL_EXT_bgra, GL_EXT_stencil_wrap, 
    GL_EXT_texture_filter_anisotropic, GL_EXT_secondary_color, 
    GL_EXT_blend_func_separate, GL_EXT_shadow_funcs, GL_EXT_stencil_two_side, 
    GL_EXT_depth_bounds_test, GL_EXT_texture_compression_s3tc, 
    GL_EXT_texture_compression_dxt1, GL_EXT_texture_sRGB, 
    GL_EXT_blend_equation_separate, GL_EXT_texture_mirror_clamp, 
    GL_EXT_packed_depth_stencil, GL_EXT_bindable_uniform, 
    GL_EXT_texture_integer, GL_EXT_gpu_shader4, GL_EXT_framebuffer_sRGB, 
    GL_EXT_provoking_vertex, GL_APPLE_flush_buffer_range, GL_APPLE_ycbcr_422, 
    GL_APPLE_rgb_422, GL_APPLE_vertex_array_range, GL_APPLE_texture_range, 
    GL_APPLE_float_pixels, GL_ATI_texture_float, GL_ARB_texture_float, 
    GL_ARB_half_float_pixel, GL_APPLE_pixel_buffer, GL_APPLE_object_purgeable, 
    GL_NV_point_sprite, GL_NV_blend_square, GL_NV_fog_distance, 
    GL_NV_depth_clamp, GL_NV_multisample_filter_hint, 
    GL_NV_fragment_program_option, GL_NV_fragment_program2, 
    GL_NV_vertex_program2_option, GL_NV_vertex_program3, 
    GL_NV_conditional_render, GL_ATI_texture_mirror_once, 
    GL_ATI_texture_env_combine3, GL_ATI_separate_stencil, 
    GL_SGIS_texture_edge_clamp, GL_SGIS_texture_lod, GL_EXT_texture_array, 
    GL_EXT_vertex_array_bgra, GL_ARB_instanced_arrays, 
    GL_ARB_depth_buffer_float, GL_EXT_packed_float, 
    GL_EXT_texture_shared_exponent

Mesa は「+Phython27+universal」バリアントを使う

port variants mesa で確認すると Mesa のデフォルトのバリアントは「+python27」だけになっています。

mesa has the variants:
	   iglx: Install a libGL that uses your X11 server's indirect GLX path for rendering (the
			 default is off which allows libGL to accelerate rendering using OpenGL.framework)
	   python26: Use python 2.6
		 * conflicts with python27
	[+]python27: Use python 2.7
		 * conflicts with python26
	   universal: Build for multiple architectures

しかし、「+python27」だけのバリアントでは OpenGL が使えませんでした。全ての組み合わせを試したところ、「+python27+universal」バリアントでなくてはいけないようです。

DxDiag で DirectDraw と Direct3D のテスト

wine dxdiag で DirectDraw と Direct3D のテストが出来ます。Direct3D は全画面モードになるので仮想デスクトップをエミュレートしておいた方がいいかもしれません。

wine explorer /desktop=name,1024x768 dxdiag

GStreamer

2D ゲームで一番厄介な部分だと思います。ゲーム内のムービーシーンで発生し、エラーが永遠に続いてそれ以上先へ進めなくなります。

fixme:gstreamer:watch_bus decodebin21515: MPEG-1 System Stream demuxer プラグインはこのストリームを再生するのに必要ですが、インストールされていません
fixme:gstreamer:GST_Connect Gstreamer could not find any streams
fixme:gstreamer:unknown_type Could not find a filter for caps: video/mpeg, systemstream=(boolean)true, mpegversion=(int)1
fixme:gstreamer:watch_bus decodebin21516: GStreamerはプラグインを見つけることができません

解決策として「GStreamer をユニバーサルバリアントで使用しない」ようにします。Wine のインストールログで確認したところ Gstreamer は「gstreamer+universal」でインストールされてしまうようです。

sudo port install wine-devel
--->  Computing dependencies for wine-devel
--->  Dependencies to be installed: gst-plugins-base gstreamer libxml2 libxml2 mesa
--->  Activating libxml2 @2.7.8_0+universal
--->  Activating gstreamer @0.10.36_0+universal
--->  Activating gst-plugins-base @0.10.36_0+universal
--->  Activating mesa @8.0.1_0+python27+universal

port installed で確認して「gstreamer+universal」になっているようであればユニバーサルバイナリ無しに変更します。バリアントの変更だけなら deactivateacticate をではなく install で済みます(deactivate だと依存関係の問題があるので面倒です)。

sudo port install gstreamer

GStreamer のプラグインを入れてみる

GStreamer のプラグインを入れることで改善するかもしれません。現在、MacPorts からインストール出来るプラグインは以下の種類です。

  • gst-ffmpeg(上手く入らないかも)
  • gst-plugins-bad
  • gst-plugins-base
  • gst-plugins-gl
  • gst-plugins-good
  • gst-plugins-ugly

各プラグインの詳細は GStreamer の公式サイトを参照して下さい。

gstreamer.freedesktop.org/documentation/plugins.html

Wine に ffdshow をインストールしておく

普通の Windows でもあり得ますが「動画が表示されない」「音声が再生されない」といった場合は、ffdshow を入れておくことで解決出来る…かもしれません。

ffdshow tryouts | Official Website

"DirectDrawRenderer"="gdi"

OpenGL をまったく受け付けないゲームのための設定です。

レジストリエディタを起動して "HKEY_CURRENT_USER\Software\Wine\Direct3D" に「文字列(REG_SZ)」で "DirectDrawRenderer"="gdi" を追加します。レジストリエディタを終了すればレンダリングに GDI が使われるようになります。環境次第だと思いますが、MacBook Air では OpenGL の方が若干軽いかな?程度です。

レジストリの編集は WineTricks の Change settings から行うと楽です。

アプリケーション毎に Direct3D の設定を変更する

レンダリングを GDI にすることによってクラッシュを避けることが出来るアプリケーションもあることがわかりましたが、毎回レジストリエディタを起動するのは面倒ですよね。Wine では「このアプケーションでは OpenGL(または GDI)を使いたい」といった個別の設定が出来るようになっています。

"HKEY_CURRENT_USER\Software\Wine" 直下に "AppDefaults" というキーを作成し、更にその直下にアプリケーション名のキーを作成し、"Direct3D" のキーを作成します。

例えば、BIO HAZARD 5(BH5DX9.EXE)を "DirectDrawRenderer"="opengl" で動かしたい時は以下のような階層になります。

+-- HKEY_CURRENT_USER\Software\Wine
    |
    +-- AppDefauls
    |   |
    |   +-- BHD5DX9.EXE
    |       |
    |       +-- Direct3D
    |           |
    |           +-- "DirectDrawRenderer"="opengl"
    |
    +-- Debug
    |
    +-- Direct3D
    |

ライブラリオーバーライド関連

オーバーライドというのは Wine 内蔵の .dll を使用せず、ネイティブな .dll を使用させることです。DirectX 関連は当然オーバーライドしますが、数が多いので WineTricks を使って導入した方が楽です。

quartz.dll

DirectX 関連とは別に重要になるのが「quartz.dll」です。WineTricks を使えば恐らく DirectX 導入時に自動的にオーバーライドされます。「quartz.dll」のオーバーライドを忘れるとゲーム内のムービーがスルーされ、コンソールに以下のようなメッセージが出ます。

fixme:quartz:MPEGSplitter_query_accept MPEG-1 system streams not yet supported.
fixme:quartz:AMGetErrorTextW (80004005,0x33ddb0,160) stub

その他のライブラリは後日追加予定。

XRandR によるフルスクリーン動作の制御

ゲームによっては起動時にフルスクリーンを強制してくるものがあります(特に 3D 系)。Wine でデスクトップエミュレートを使用していない場合、Mac OS X のディスプレイごと X11 に持っていかれます。対処方法を知らないとアプリケーションを終了させるまで戻せません。

XRandR モードを終了する

XRandR モードから離脱する場合は Command + Option + A を押します。ゲームによっては解像度変更時に落ちます。

XRandR モードを使用しているアプリケーションを終了する

XRandR モード中でも X11 上のアプリケーションの切り替えは出来るので Command + 1Command + 2 などで Wine を動かしている xterm を呼び出して Ctrl + C で Wine を終了します。