2D格闘ゲームだったはずなのにナンバリングタイトルでいきなり格闘アクション + RTSというジャンル変更、ストーリーが前作からいきなり何年も先に進んだため急展開、Xbox 360専用タイトルということで賛否両論を巻き起こした2007年発売の「GUILTY GEAR 2 -OVERTURE-」
2016年4月1日になって突如としてSteam版が発売され、360専用という敷居の高さは緩和されたが、対戦ツールとしては良作という評価もあるものの流石に古いタイトルというのもあってプレイヤー人口は伸びず、またもう一つ大きな問題点としてPCゲームとしてリリースされたにもかかわらずグラフィック設定が一切ない(F11キーでフルスクリーンに切り替えられるのみ)という致命的な欠点があった。デフォルトでもある程度見栄えが良ければいいが、360版当時としても十分とは言えないグラフィックで、PC版でも720p相当の解像度と思われるボケたレンダリング解像度とソフトシャドウすらかかっていないジャギーやモアレの目立つシャドウマップが余りにも醜い。
2016年のアップデートアナウンスではグラフィック関連の設定も追加されることがアナウンスされていたが結局実装されず、既に2018年になっているのでサポートも終了してこのままと思われるので、需要は無いに等しいとは思うけどAPIフックプログラミングの練習も兼ねて画質改善Modを作ってみた。
※追記:ジオシティーズ閉鎖で古いバージョンがダウンロードできなくなったので、ついでにModを改良して更に高画質化したバージョンを上げ直す
上記の記事からダウンロード可能
これより下に記載した古いバージョンは既にダウンロードできません
名前からもわかるとおりPC版ダークソウルの高画質化 & 60fps化を参考にしている。圧縮ファイル内の「d3d9.dll」と「gg2fix.ini」を、「ggsx.exe」があるゲームフォルダと同一の場所にコピーするのみ。設定はgg2fix.iniを書き換えることで行える。
比較例
レンダリング解像度のみ上げた状態での影の解像度比較
似たようなMod作ったり、他のプログラム作成する際の自分メモ用にAPIフックプログラムの原理を説明すると、
- 対象の実行ファイルで読み出されるAPIが記述されたDLLファイルのダミーを作成。
- そのダミーDLLファイルが読みだされた(DllMain関数が実行された)際に、関数LoadLibraryでオリジナルのDLLを読み込み、GetProcAddressでアドレスを取得して別名の関数に割り当てておく。
- 基本的にダミーDLL内で記述したAPIでは、そのまま引数を別名に割り当てていたオリジナルのAPIに引き渡し、戻り値もそのまま利用するようにする。
- 何か処理が必要な場合、オリジナルのAPIに引数を渡す前に処理を行ってから引き渡す。
今回のModの場合はテクスチャ作成のAPIで特定の解像度とフォーマットだった場合に値を書き換えてオリジナルAPIに渡すように変更。
HRESULT APIENTRY hkIDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle)
{
return m_pD3Ddev->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle); return m_pD3Ddev->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle);
}
とダミーAPIではなっているところを
HRESULT APIENTRY hkIDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle)
{
if ( (Width == 1024 && Height == 1024) && (Format == D3DFMT_R32F || Format == D3DFMT_D24S8) ) {
return m_pD3Ddev->CreateTexture(4096, 4096, Levels, Usage, Format, Pool, ppTexture, pSharedHandle);
}
return m_pD3Ddev->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle); return m_pD3Ddev->CreateTexture(Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle);
}