jak-project - このプロジェクトは、Jak 1(NTSC、「ブラックラベル」バージョン)をPCに移植することです。このゲームの98%以上は、NaughtyDogによって開発されたカスタムLisp言語であるGOALで書かれています。

(Reviving the language that brought us the Jak & Daxter Series)

Created at: 2020-08-23 07:55:21
Language: Common Lisp
License: ISC

ドキュメントバッジ Linux ウィンドウズ Codacyバッジ Codacyバッジ 不和 PR

目次

プロジェクトの説明

このプロジェクトは、Jak 1(NTSC、「ブラックラベル」バージョン)をPCに移植することです。このゲームの98%以上は、NaughtyDogによって開発されたカスタムLisp言語であるGOALで書かれています。私たちの戦略は次のとおりです。

  • 元のゲームコードを人間が読めるGOALコードに逆コンパイルします
  • GOAL用に独自のコンパイラを開発し、x86-64用にゲームコードを再コンパイルします
  • ゲームアセットを簡単に表示または変更できる形式に抽出するツールを作成する
  • ゲームアセットをポートが使用する形式に再パックするためのツールを作成します。

私たちの目的は次のとおりです。

  • ポートをx86-64の「ネイティブアプリケーション」にして、高性能にします。エミュレート、解釈、またはトランスパイルされるべきではありません。
  • GOALコンパイラのパフォーマンスは、最適化されていないCとほぼ同じである必要があります。
  • オリジナルのゲームと開発から可能な限り一致するようにしてください。たとえば、元のGOALコンパイラは、ゲームの実行中にコードのライブ変更をサポートしていたため、ゲームの移植だけに必要なわけではありませんが、同じことを行います。
  • 変更をサポートします。他のすべてを壊すことなく、コードを編集できるはずです。

x86-64ではLinuxとWindowsの両方をサポートしています。

ご不明な点がございましたら、こちらをクリックしてよくある質問をお読みください。

開発について話し合うDiscordサーバーがあります:https ://discord.gg/VZbXMHXzWv

現在のステータス

これまでのところ、元のゲームからの推定合計50万行のうち、約40万行のGOALコードを逆コンパイルしました。ゲームの世界とフォアグラウンドのほとんどをレンダリングする、動作するOpenGLレンダラーがあります。レベルは完全にプレイ可能で、100%完了してゲームを終了できます!

レンダラーのスクリーンショットは次のとおりです。

YouTubeプレイリスト: https ://www.youtube.com/playlist?list = PLWx9T30aAT50cLnCTY1SAbt2TtWQzKfXX

逆コンパイルを支援するために、GOALコードを処理してゲームアセットを解凍できる逆コンパイラを構築しました。逆コンパイラーが成功するまで、元のコードに型キャストがあったと思われる関数の型と場所を手動で指定します。次に、コメントを追加してフォーマットを調整することにより、逆コンパイルされたコードの出力をクリーンアップし、に保存し

goal_src
ます。私たちの逆コンパイラーは、元のGOALコンパイラーの出力を処理するために特別に設計されています。その結果、正しいキャストが与えられると、コンパイラーに直接フィードでき、完全に機能するコードが生成されることがよくあります。これは単体テストの一部としてテストされており、これまでに300,000行(460ファイル)以上が合格しています。

ゲームからアセットを保存することはありません。ゲームのコピーを持参し、デコンパイラーを使用してアセットを抽出する必要があります。

次は何ですか

  • バグテスト!ゲームは最初から最後まで100%勝つことができますが、いくつかのことが正しく機能しない可能性があります。
  • 逆コンパイラを改善し、GOALコードの逆コンパイルをクリーンアップします。私たちは常にGOAL言語の新しい機能とマクロを見つけています。
  • より複雑なレンダラーを調査して書き直します。

はじめに-Linux

Ubuntu(20.04)

パッケージと初期化リポジトリをインストールします。

sudo apt install gcc make cmake build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev python
sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin

コンパイル:

cmake -B build && cmake --build build -j 8

テストを実行します。

./test.sh

注:コンパイルとリンクは、よりも大幅に高速であり

clang
、より高速なコードを生成し、より優れた警告メッセージが表示されることがわかりました。これらをインストールするには:
lld
gcc

sudo apt install lld clang

そして

cmake
(新しいビルドディレクトリで)実行します:

cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..

アーチ

パッケージと初期化リポジトリをインストールします。

sudo pacman -S gcc make cmake base-devel g++ nasm python
yay -S taskfile-git

コンパイル:

cmake -B build && cmake --build build -j 8

テストを実行します。

./test.sh

はじめに-Windows

必要なソフトウェア

C++開発には主にWindows上のVisualStudioを使用します。ここから最新のコミュニティエディションをダウンロードします

Desktop development with C++
ワークロードが必要になります。これは、インストール中、またはVisualStudioのインストールを変更した後に選択できます
Visual Studio Installer

Windowsでは、パッケージマネージャーを使用することをお勧めします。Scoopを使用します。こちらのホームページの下部にある手順に従って入手してください。

Scoopをインストールしたら、次のコマンドを実行します。

scoop install git llvm nasm python
scoop bucket add extras
scoop install task

プロジェクトの設定と開始

選択したフォルダで次のコマンドを実行して、リポジトリのクローンを作成します。

git clone https://github.com/open-goal/jak-project.git

これにより、

jak-project
フォルダーが作成され、VisualStudioを介してCMakeプロジェクトとしてプロジェクトが開きます。

次に、プロジェクト全体をとしてビルドし

Windows Release (clang-cl)
ます。すべてビルドのホットキーとしてCtrl+Shift+Bを押すこともできます。現在
clang-cl
、WindowsではなくWindowsを使用して
msvc
いますが、同様に機能するはずです。

ゲームの構築と実行

実行中のゲームを取得するには、次の4つの手順が必要です。

  1. C ++ツールを構築します(ご使用のプラットフォームについて、上記の「はじめに」の手順に従ってください)
  2. ゲームからアセットを抽出する
  3. ゲームを構築する
  4. ゲームを実行する

アセットの抽出

最初のステップは、ISOファイルの内容を

iso_data/<game-name>
フォルダーに抽出することです。Jak 1の場合、これは
iso_data/jak1
です。

これが完了したら、

jak-project
フォルダ内のターミナルを開き、次を実行します。

task extract-jak1

ゲームを構築する

次のステップは、ゲーム自体を構築することです。これを行うには、同じターミナルで次のコマンドを実行します。

task repl

次のようなプロンプトが表示されます。

 _____             _____ _____ _____ __
|     |___ ___ ___|   __|     |  _  |  |
|  |  | . | -_|   |  |  |  |  |     |  |__
|_____|  _|___|_|_|_____|_____|__|__|_____|
      |_|
Welcome to OpenGOAL 0.8!
Run (repl-help) for help with common commands and REPL usage.
Run (lt) to connect to the local target.

g >

以下を実行してゲームをビルドします。

g > (mi)

ゲームを実行する

最後に、ゲームを実行できます。

jak-project
ディレクトリから2番目のターミナルを開き、次を実行します。

task boot-game

すべてが正しく行われた場合、ゲームは自動的に起動するはずです。

REPLをゲームに接続する

REPLをゲームに接続すると、ゲームの実行中にコードやデータを検査および変更できます。

これを行うには、成功した後のREPLで

(mi)
、次のコマンドを実行します。

g > (lt)

成功した場合、プロンプトは次のように変更されます。

gc>

たとえば、次を実行すると、Jakに関するいくつかの基本情報が出力されます。

gc> *target*

自動起動せずにゲームを実行する

起動せずにゲームを起動することもできます。これを行うには、1つの端末で次を実行します

task run-game

そして、REPLで以下を実行します(成功した後

(mi)
):

g > (lt)
[Listener] Socket connected established! (took 0 tries). Waiting for version...
Got version 0.8 OK!
[Debugger] Context: valid = true, s7 = 0x147d24, base = 0x2123000000, tid = 2438049

gc> (lg)
10836466        #xa559f2              0.0000        ("game" "kernel")

gc> (test-play)
(play :use-vis #t :init-game #f) has been called!
0        #x0              0.0000        0

gc>

ゲームとの相互作用

グラフィックウィンドウで、ピリオドキーを使用してデバッグメニューを表示できます。コントローラーも、元のゲームと同じマッピングを使用して機能します。

私たちが書いたGOALコードのいくつかの例については、、

pc_debug
および
examples
pc
下のフォルダーを確認してください。
goal_src
エンジンによって自動的にロードされないデバッグファイルには、それらを実行する方法の説明があります。

プロジェクトのレイアウト

プロジェクトには4つの主要なコンポーネントがあります。

1つ目は

goalc
、x86-64用のGOALコンパイラです。GOALの実装はOpenGOALと呼ばれます。コンパイラのソースコードはすべて。にあり
goalc
ます。Linuxでコンパイラを実行するために、スクリプトがあります
gc.sh
。Windowsには、
gc.bat
スクリプトと
gc-no-lt.bat
スクリプトがあり、後者は実行中のターゲットに自動的に接続しようとしません。コンパイラーは、コンパイルするコマンドの入力、対話のための実行中のGOALプログラムへの接続、OpenGOALデバッガーの実行、または実行中のGOALプログラムに接続している場合は、へのREPLとして使用できるプロンプトを介して制御されます。コードをインタラクティブに実行します。コードファイルのコンパイルに加えて、コンパイラにはデータファイルをパックおよびビルドする機能があります。

プロジェクトの2番目のコンポーネントは、逆コンパイラーです。次の図に示すように、PS2ゲームのコピーを用意し、DVDのすべてのファイルをフォルダー内のゲームに対応する

iso_data
フォルダー(
jak1
Jak 1 Black Labelなど)に配置する必要があります。

次に、

decomp.sh
(Linux)または
decomp-jak1.bat
(Windows)を実行して、逆コンパイラーを実行します。デコンパイラーはアセットを
assets
フォルダーに抽出します。これらのアセットは、ポートを構築するときにコンパイラーによって使用されます。一度実行した後は、アセットの抽出をオフにすることをお勧めします。デコンパイラーは、フォルダー内の人間による検査を目的としたコードおよびその他のデータを出力し
decompiler_out
ます。このフォルダー内のものは、コンパイラーによって使用されません。

The third is the game source code, written in OpenGOAL. This is located in

goal_src
. All GOAL and GOOS code should be in this folder. Right now most of this is placeholders or incomplete, but you can take a look at
kernel/gcommon.gc
or
goal-lib.gc
to see some in-progress source code.

The final component is the "runtime", located in

game
. This is the part of the game that's written in C++. In the port, that includes:

  • GOALリンカーといくつかの低レベルのGOAL言語機能を含む「Cカーネル」。GOALには、完全にカスタムの動的にリンクされたオブジェクトファイル形式があるため、最初のGOALコードをロードするには、C++で記述されたリンカーが必要です。I / Oプロセッサ、シンボルテーブル、文字列、および型システムと通信するメモリ割り当ての一部の低レベル関数も、リンカに必要なため、Cで実装されます。また、コンパイラからの着信メッセージをリッスンし、実行中のゲームに渡します。これはまた、PS2ハードウェアを初期化し、GOALヒープを割り当て、DVDからGOALカーネルをロードし、カーネルディスパッチャー関数を実行することにより、ゲームを初期化します。これは
    game/kernel
    フォルダにあります。これはゲームにできるだけ近いものにする必要があり、すべての違いはコメントでメモする必要があります。
  • ソニーの標準ライブラリの実装。GOALコードはCライブラリ関数を呼び出すことができ、Naughty DogはいくつかのSonyライブラリ関数を使用して、ファイル、メモリカード、コントローラにアクセスし、個別のI/Oプロセッサと通信しました。ライブラリ関数はにあり
    game/sce
    ます。PCポートに固有のライブラリ機能の実装はにあります
    game/system
  • I / Oプロセッサドライバ、OVERLORD。PS2には、DVDドライブハードウェアとサウンドハードウェアに直接接続されたI / Oプロセッサ(IOP)と呼ばれる別個のCPUがありました。Naughty Dogは、DVDからのストリーミングデータを処理するIOP用のカスタムドライバーを作成しました。それは私が最初に予想したよりもはるかに複雑です。にあり
    game/overlord
    ます。Cカーネルと同様に、これを実際のゲームにできるだけ近づけるようにしています。
  • サウンドコード。Naughty Dogは、サウンドにサードパーティのライブラリを使用しました
    989SND
    。ライブラリのコードとそのインターフェイスはにあります
    game/sound
  • PC固有のグラフィックコード。ゲームウィンドウを作成してグラフィックを表示できる、機能的なOpenGLレンダラーとコンテキストがあります。ただし、ゲームで使用される特定のレンダラーはほとんど実装されています。後処理効果を除いて、ゲーム内のすべてがレンダリングされます。これはにあり
    game/graphics
    ます。この作業を行うには多くの自由が必要ですが、最終結果は実際のゲームと非常によく一致するはずです。
  • にある、何らかの方法でポートによって使用される追加のアセット
    game/assets
    。これらには、追加のテキストファイル、アイコンなどが含まれます。

ディレクトリレイアウト

  • assets
    :逆コンパイラーによって生成された抽出されたアセット(テクスチャ、翻訳されたゲームテキスト、オーディオ)。リポジトリには含まれていません。このデータは、PCポートを構築するときに使用されます。
  • build
    :C++CMakeビルドフォルダー。
  • common
    :コンパイラ、逆コンパイラ、およびゲーム間で共有される一般的なC++コード。
    • audio
      :オーディオファイルをデコードするためのツール。
    • cross_os_debug
      :OpenGOALデバッガーを実装するためのプラットフォームに依存しないライブラリ。LinuxとWindows。
    • cross_sockets
      :ソケット用のプラットフォームに依存しないライブラリ。コンパイラを実行中のゲームに接続するために使用されます。LinuxとWindows。
    • goos
      :OpenGOALのコンパイラ時マクロ言語およびパーサー。
    • type_system
      :OpenGOAL型システム。
    • texture
      :テクスチャの解凍とフォーマットの変換。
    • dma
      :PS2DMAパケットの転送を処理するためのユーティリティ。
    • util
      、、 :ファイルやタイマーなどにアクセスするため
      math
      log
      ランダムなユーティリティ関数。
  • decompiler
    :逆コンパイラのソースコード。
    • analysis
      :分析アルゴリズム。
    • config
      :逆コンパイラーおよびタイプ定義ファイルのJSON構成ファイル。
    • data
      :ゲームからアセットを抽出するユーティリティ。
    • Disasm
      :MIPS逆アセンブラ。
    • Function
      :GOAL関数を分析するためのツール。
    • gui
      :逆コンパイラーの出力を読み取るためのPythonGUIの初期のプロトタイプ。
    • IR2
      :GOAL関数および式の「中間表現」。
    • ObjectFile
      :GOALオブジェクトファイル形式を処理するためのユーティリティ。
    • scripts
      :逆コンパイルを設定するための便利なスクリプト。
    • util
      :ランダムユーティリティ。
    • VuDisasm
      :VUコードの逆アセンブラ。
  • decompiler_out
    :コンパイラによって自動的に使用されない逆コンパイラの出力。これは人間が読んで使用するためのものです。リポジトリには含まれていません。
  • docs
    :より多くのドキュメント!
  • game
    :ゲーム実行可能ファイルのソースコード。
    • common
      kernel
      : (EE)と
      overlord
      (IOP)の間で共有されるもの。
    • graphics
      :PCポートグラフィック。
    • kernel
      :Cで記述されたGOALカーネルの一部。ゲームのエントリポイントはにあり
      kboot.cpp
      ます。
    • overlord
      :DVDからデータを取得するために使用されるI/Oプロセッサドライバ。
    • sce
      :Sonyライブラリの実装。
    • system
      :ファイルI / O、スレッド、コントローラー、デバッグネットワーク接続などのPCポート固有のOSレベルのもの。
  • goal_src
    :ゲームのGOALコード。
    • build
      :GOALビルドシステムに関連する情報。
    • engine
      :ゲームエンジン。
    • kernel
      :GOALカーネル。
    • levels
      :レベル固有のコード。
    • old
      :元のゲームから未使用または削除されたファイル。
    • dgos
      :ビルドシステム内のDGOのファイルリスト。
    • examples
      :私たちが書いたGOALコードの例。
    • test
      :私たちが書いたテストコード。
    • pc_debug
      :PC固有のデバッグ用のGOALコード。また、私たちによって書かれました。
    • pc
      :PC固有の機能のGOALコード。また、私たちによって書かれました。
    • user
      :ユーザーサンドボックス。あなたによって書かれました!そして、ユーザーコードを共有したい人は誰でも。
  • goalc
    :OpenGOALコンパイラ。
    • compiler
      :OpenGOAL言語の実装。
    • data_compiler
      :データをパックするためのツール。
    • debugger
      :OpenGOALデバッガー(コンパイラーの一部)。
    • emitter
      :x86-64エミッターおよびオブジェクトファイルジェネレーター。
    • listener
      :OpenGOALリスナー。これは、コンパイラーを対話型REPL用の実行中のGOALプログラムに接続します。
    • make
      :OpenGOALビルドシステムは、コードファイルとデータファイルの両方をビルドします。
    • regalloc
      :レジスタアロケータ。
  • iso_data
  • out
    :ビルドプロセスからの出力。サブフォルダのみに
    iso
    、ゲームで使用されるアセットを含める必要があります。
    • iso
      :ゲームで使用される最終出力。
    • obj
      :コンパイラによって生成されたオブジェクトファイル。
  • resources
    :削除されます。起動するために必要ないくつかのファイルの偽のバージョンが含まれています。
  • scripts
    :ユーティリティスクリプト。Windows固有のバッチファイルは
    batch
    フォルダにあり、Unixシェルスクリプトは
    shell
    フォルダにあります。
  • test
    :単体テスト(GitHubアクションで実行)。
  • third-party
    :サードパーティのライブラリ。
    • CMakeコードカバレッジ。GitHubビルドのコードカバレッジ統計。
    • fmt
      。文字列フォーマットライブラリ。
    • googletest
      :テストフレームワーク。
    • inja
      :コンパイラテスト用のテストコードを生成するために使用されるテンプレートライブラリ。
    • lzokay
      :Jak2以降のDGOの解凍コード。
    • mman
      :Linuxでエミュレートするために使用されるWindowsライブラリ
      mmap
    • run-clang-format
      :コードのフォーマットをチェックして適用するユーティリティ。
    • run-clang-tidy
    • zydis
      :OpenGOALデバッガーで使用されるx86-64逆アセンブラ。
    • json
      :JSONライブラリ。
    • replxx
      :REPL入力に使用されます。履歴と便利な編集ショートカットをサポートします。
    • svpng
      :PNGファイルを保存します。