Compare commits

...
Author SHA1 Message Date
Hat Kid 85039fe2d6 jak3: fix all-types file order (#3316)
In #3300, `per_object` in `ObjectFileDB::ir2_analyze_all_types()` was
changed to an `unordered_map`, which messed with the object file order
in `all-types`. This fixes the issue by going through each object file
in order and then looking up the type info from the map instead of
iterating through the map.

This also removes the method IDs from the old method comments and adds a
stub for the `new` method if there is an old method comment for it, in
order to stay consistent with the rest of the method list.
2024-01-18 14:57:10 +01:00
Hat Kid b06d63ba83 custom levels: sort actors by aid and check for duplicates (#3315)
When giving entities custom actor IDs in your level JSON, it is possible
to break entity lookups by actor ID if the actors are not sorted by ID
because `entity-by-aid` expects them to be in order.

This sorts the actor list by ID before generating the level file and
also checks for any duplicates.
2024-01-18 10:29:30 +01:00
ManDude 13f1aa1785 [jak2] fully implement PLAYER set-param for VAG streams + fix regression (#3314)
At last...
2024-01-18 01:59:04 +00:00
ManDude ba7b0397b1 [pckernel] fix settings not being applied if file isn't found (#3313) 2024-01-17 15:43:53 +00:00
water111 4f537d4a71 [jak3] Set up ckernel (#3308)
This sets up the C Kernel for Jak 3, and makes it possible to build and
load code built with `goalc --jak3`.

There's not too much interesting here, other than they switched to a
system where symbol IDs (unique numbers less than 2^14) are generated at
compile time, and those get included in the object file itself.

This is kind of annoying, since it means all tools that produce a GOAL
object file need to work together to assign unique symbol IDs. And since
the symbol IDs can't conflict, and are only a number between 0 and 2^14,
you can't just hash and hope for no collisions.

We work around this by ignoring the IDs and re-assigning our own. I
think this is very similar to what the C Kernel did on early builds of
Jak 3 which supported loading old format level files, which didn't have
the IDs included.

As far as I can tell, this shouldn't cause any problems. It defeats all
of their fancy tricks to save memory by not storing the symbol string,
but we don't care.
2024-01-16 19:24:02 -05:00
James AldridgeandJamesAldridge ed6639ee60 fix zydis alignment issue during build for intel macs (#3312)
Fix zydis alignment issues when building on Intel macOS builds was
discussed with zydis devs https://github.com/zyantific/zydis/issues/474

Verified locally that I can run open goal with the change.

Co-authored-by: JamesAldridge <[email protected]>
2024-01-16 19:01:55 -05:00
ManDude 1dba36c614 fix jak3 jp strings (#3311) 2024-01-16 11:09:17 +00:00
Tyler Wilding 4101d5d80e tests: add jak3 typeconsistency test and ensure offline tests are working (#3310) 2024-01-16 00:15:33 -05:00
jabermonyandTyler Wilding 07427799a6 Jak3 Build Environment (#3098)
This sets out the bones of a Jak 3 build, many things are stubbed out,
guessed, or copied from Jak 2 but it should at least be good enough to:
run `task set-game-jak3`
launch the repl
run builds from the repl

build outputs themselves are untested but the build itself runs without
errors

---------

Co-authored-by: Tyler Wilding <[email protected]>
2024-01-15 20:37:16 -05:00
Tyler Wilding 637b043293 deps: update zydis to latest commit (#3306)
Updates Zydis to it's latest commit, this should fix building the
project on intel macs with a more recent version of macOS. This likely
needs some sanity checks that the debugger stuff still works as
expected.
2024-01-15 16:56:14 -05:00
ManDude 46db6a36da [pckernel] use pc-get-resolution to fetch initial fullscreen resolution (#3307)
This is the more correct way of doing what that code is trying to do.
Fixes #3296

Also fixed some type inconsistencies with related code, probably wasn't
causing issues though.

May also fix the "black screen on startup" issues people keep having,
but that would simply be a nice bonus and isn't the aim of this PR.
2024-01-15 18:53:49 +00:00
Hat Kid 619f39d3b7 custom levels: enum lump support (#3305)
This adds support for using enums in lumps using the new lump types
`enum-int32` and `enum-uint32`. Also adds these other new lump types:

- `water-height` (takes 3 meter floats, an enum and another optional
meter float)
- `eco-info` (takes an enum and an int)
- `vector3m` (3 meter floats + `w` set to 1.0)
2024-01-15 12:46:42 +01:00
Matt Dallmeyer 2071c98b55 Fix cases of string formatting with non string literals (#3304)
The logger used in `goalc` tries to print an already-formatted string
`message` using `fmt::print(message);` Usually this doesn't cause
problems, but if you try to print, for example, an exception that has
special characters (notably `{`) it will try to do another round of
formatting/replacements, despite not having any args to replace with,
which ends up throwing another exception. This is why errors when
parsing custom level JSON cause the REPL to exit.

I've hopefully identified all the various instances of this across the
codebase
2024-01-14 12:02:08 +00:00
ManDude 7a8aa71204 [jak2] implement statistics tracker (#3288)
Currently only tracks enemy kills, and how they were killed. There is
currently no menu for this, but I've already added most of the text for
it. Also did a bunch of misc decompilation fixes and renamed some
methods.

Fixes #3277 
Fixes #3278
2024-01-11 22:49:41 +00:00
Tyler Wilding a80cff9a4c game: Fix issues related to remapping with SDL axii's (ie. triggers) (#3294)
This was just not implemented end to end. There are still two notable
issues, one that I can live with, one I need to narrow down eventually:
1. Rebinding confirm buttons with trigger (ie. X) behaviour is not 100%
as it should be. I fixed it enough that I can live with it but it's
still not proper. The difficulty is that unlike a button it will
re-trigger the pressed state on the journey back to neutral (aka
unpressed).
2. If you change the bind for the confirm button, then reset your
bindings, the next confirm input is eaten. This is unrelated to these
changes but I briefly looked into it and was unable to find the root
cause.
2024-01-09 16:50:58 -05:00
Tyler Wilding 4cccaf2645 d/j3: all-types: guess at associated process for non-virtual states and fix some issues along the way (#3300)
This will make a best effort attempt at guessing which process a
non-virtual state belongs to:
![Screenshot 2024-01-08
195309](https://github.com/open-goal/jak-project/assets/13153231/69132f10-823d-4df5-b2d6-662d4dd754a0)

I also noticed some issues while working on this, mainly around how
virtual states were being output. They were being duplicated, for
example:
![Screenshot 2024-01-08
184733](https://github.com/open-goal/jak-project/assets/13153231/1edb0f1a-3ac7-46cb-96cd-cf93d42fb01f)
or
![Screenshot 2024-01-08
193730](https://github.com/open-goal/jak-project/assets/13153231/45673653-4000-45bb-af00-9baa6e2a70ae)

I think I've fixed that, but @Hat-Kid I defer to you to see if i've done
something terrible.
![Screenshot 2024-01-08
194513](https://github.com/open-goal/jak-project/assets/13153231/75543d2e-69da-4bbd-b143-2f824b9d8dde)
2024-01-09 16:50:05 -05:00
Matt Dallmeyer 9d680a0aba Support extracting collision to obj for jak2/3 formats (#3292)
![image](https://github.com/open-goal/jak-project/assets/2515356/b4d43254-4fc4-4f66-92d1-0d61e471b90e)

![image](https://github.com/open-goal/jak-project/assets/2515356/d2fa9fb8-5f51-43c5-8e0e-b51b64499b72)
2024-01-05 09:36:09 +01:00
dependabot[bot] b0713641e7 build(deps): bump actions/download-artifact from 3 to 4 (#3283)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 3 to 4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<h2>What's Changed</h2>
<p>The release of upload-artifact@v4 and download-artifact@v4 are major
changes to the backend architecture of Artifacts. They have numerous
performance and behavioral improvements.</p>
<p>For more information, see the <a
href="https://github.com/actions/toolkit/tree/main/packages/artifact"><code>@​actions/artifact</code></a>
documentation.</p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/bflad"><code>@​bflad</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/194">actions/download-artifact#194</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v3...v4.0.0">https://github.com/actions/download-artifact/compare/v3...v4.0.0</a></p>
<h2>v3.0.2</h2>
<ul>
<li>Bump <code>@actions/artifact</code> to v1.1.1 - <a
href="https://redirect.github.com/actions/download-artifact/pull/195">actions/download-artifact#195</a></li>
<li>Fixed a bug in Node16 where if an HTTP download finished too quickly
(&lt;1ms, e.g. when it's mocked) we attempt to delete a temp file that
has not been created yet <a
href="hhttps://redirect.github.com/actions/toolkit/pull/1278">actions/toolkit#1278</a></li>
</ul>
<h2>v3.0.1</h2>
<ul>
<li><a
href="https://redirect.github.com/actions/download-artifact/pull/178">Bump
<code>@​actions/core</code> to 1.10.0</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/download-artifact/commit/f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110"><code>f44cd7b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/259">#259</a>
from actions/robherley/glob-downloads</li>
<li><a
href="https://github.com/actions/download-artifact/commit/3181fe853d2c9a606cd326853bf4c5b8ced5df02"><code>3181fe8</code></a>
add some migration docs</li>
<li><a
href="https://github.com/actions/download-artifact/commit/aaaac7b403f278b6b7eebdca69ca1658616f1c57"><code>aaaac7b</code></a>
licensed cache</li>
<li><a
href="https://github.com/actions/download-artifact/commit/7c9182f0e18dadedfbca3189ab7a22a416aa6714"><code>7c9182f</code></a>
update readme</li>
<li><a
href="https://github.com/actions/download-artifact/commit/b94e7015566b40b2de5eeeda514f239968da2dd7"><code>b94e701</code></a>
licensed cache</li>
<li><a
href="https://github.com/actions/download-artifact/commit/0b55470e40ab7435f445813ebc18b1107ecf7e32"><code>0b55470</code></a>
add test case for globbed downloads to same directory</li>
<li><a
href="https://github.com/actions/download-artifact/commit/0b51c2ef9042b581aded9711127e4a6d5f71c550"><code>0b51c2e</code></a>
update prettier/eslint versions</li>
<li><a
href="https://github.com/actions/download-artifact/commit/c4c6db724f9510b2b3cff5ebcc417c87a2b2fa97"><code>c4c6db7</code></a>
support globbing artifact list &amp; merging download directory</li>
<li><a
href="https://github.com/actions/download-artifact/commit/1bd0606e08fcaa4c28afc1fc7d45830ab5482dac"><code>1bd0606</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/252">#252</a>
from stchr/patch-1</li>
<li><a
href="https://github.com/actions/download-artifact/commit/eff4d42b1f6ff704c7a0f37152ed8793673560ef"><code>eff4d42</code></a>
fix default for run-id</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/download-artifact/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-04 01:32:49 -05:00
dependabot[bot] aa68b80da2 build(deps): bump actions/upload-artifact from 3 to 4 (#3284)
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 3 to 4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<h2>What's Changed</h2>
<p>The release of upload-artifact@v4 and download-artifact@v4 are major
changes to the backend architecture of Artifacts. They have numerous
performance and behavioral improvements.</p>
<p>For more information, see the <a
href="https://github.com/actions/toolkit/tree/main/packages/artifact"><code>@​actions/artifact</code></a>
documentation.</p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/vmjoseph"><code>@​vmjoseph</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/464">actions/upload-artifact#464</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v3...v4.0.0">https://github.com/actions/upload-artifact/compare/v3...v4.0.0</a></p>
<h2>v3.1.3</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(github): remove trailing whitespaces by <a
href="https://github.com/ljmf00"><code>@​ljmf00</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/313">actions/upload-artifact#313</a></li>
<li>Bump <code>@​actions/artifact</code> version to v1.1.2 by <a
href="https://github.com/bethanyj28"><code>@​bethanyj28</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/436">actions/upload-artifact#436</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v3...v3.1.3">https://github.com/actions/upload-artifact/compare/v3...v3.1.3</a></p>
<h2>v3.1.2</h2>
<ul>
<li>Update all <code>@actions/*</code> NPM packages to their latest
versions- <a
href="https://redirect.github.com/actions/upload-artifact/issues/374">#374</a></li>
<li>Update all dev dependencies to their most recent versions - <a
href="https://redirect.github.com/actions/upload-artifact/issues/375">#375</a></li>
</ul>
<h2>v3.1.1</h2>
<ul>
<li>Update actions/core package to latest version to remove
<code>set-output</code> deprecation warning <a
href="https://redirect.github.com/actions/upload-artifact/issues/351">#351</a></li>
</ul>
<h2>v3.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump <code>@​actions/artifact</code> to v1.1.0 (<a
href="https://redirect.github.com/actions/upload-artifact/pull/327">actions/upload-artifact#327</a>)
<ul>
<li>Adds checksum headers on artifact upload (<a
href="https://redirect.github.com/actions/toolkit/pull/1095">actions/toolkit#1095</a>)
(<a
href="https://redirect.github.com/actions/toolkit/pull/1063">actions/toolkit#1063</a>)</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/upload-artifact/commit/c7d193f32edcb7bfad88892161225aeda64e9392"><code>c7d193f</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/466">#466</a>
from actions/v4-beta</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/13131bb095770b4070a7477c3cd2d96e1c16d9f4"><code>13131bb</code></a>
licensed cache</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/4a6c273b9834f66a1d05c170dc3f80f9cdb9def1"><code>4a6c273</code></a>
Merge branch 'main' into v4-beta</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/f391bb91a3d3118aeca171c365bb319ece276b37"><code>f391bb9</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/465">#465</a>
from actions/robherley/v4-documentation</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/9653d03c4b74c32144e02dae644fea70e079d4b3"><code>9653d03</code></a>
Apply suggestions from code review</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/875b63076402f25ef9d52c294c86ba4f97810575"><code>875b630</code></a>
add limitations section</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/ecb21463e93740a6be75c3116242169bfdbcb15a"><code>ecb2146</code></a>
add compression example</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/5e7604f84a055838f64ed68bb9904751523081ae"><code>5e7604f</code></a>
trim some repeated info</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/d6437d07581fe318a364512e6cf6b1dca6b4f92c"><code>d6437d0</code></a>
naming</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/1b561557037b4957d7d184e9aac02bec86c771eb"><code>1b56155</code></a>
s/v4-beta/v4/g</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/upload-artifact/compare/v3...v4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-04 01:32:40 -05:00
Ziemas 6901e80e7f j2-overlord: Clean up some VAG functions (#3287)
Some cleanup of vag related functions in overlord.
2024-01-02 16:30:56 +00:00
EvelynTSMG 12118e57cb Impr: Make mesh extract compatible with gLTF 2.0 (and Blender 4.0) (#3268)
:3
2024-01-01 16:30:48 -05:00
ManDude 349919f788 [jak2] implement pc cheats in menu (#3275)
Adds the opengoal cheats to the secrets menu. Only cheats that are fully
functional and unlockable are there right now, which is eight cheats.

This update will reset most Jak 2 settings.

Also fixes #3274 .
2023-12-28 11:14:10 +00:00
ManDude a01d78c7d4 [jak2] fix shadow origin using wrong joint (#3271)
Copypasta. Fixes #3269
2023-12-22 16:52:53 +00:00
Tyler Wilding 708c15788b g/j2: switch to OpenGOAL speedrun.com leaderboards (#3265)
Boards that have no runs yet look kinda awkward but i'd rather just wait
until those fill out (won't take long) rather than add another string to
be translated.
2023-12-19 19:06:55 -05:00
Tyler Wilding 6cfb89a78a g/j2: fix interleaving of local and external highscores (#3264)
Local scores weren't going above external scores even if they were
higher, a few test cases:

![Screenshot 2023-12-19
182412](https://github.com/open-goal/jak-project/assets/13153231/bf3c700d-0f23-441e-b537-88794532523b)
![Screenshot 2023-12-19
182446](https://github.com/open-goal/jak-project/assets/13153231/18d5d6eb-54b1-466e-8302-ca629677344f)
![Screenshot 2023-12-19
182442](https://github.com/open-goal/jak-project/assets/13153231/7de763a5-3587-416f-8755-1868049b92ed)
![Screenshot 2023-12-19
182421](https://github.com/open-goal/jak-project/assets/13153231/d44c1b5b-5f4f-4151-a1f0-e28d7612ed9d)
2023-12-19 18:58:25 -05:00
Tyler Wilding 99da5da441 g/j2: save window-size to pc-settings when it's changed (#3263)
Fixes #3262
2023-12-19 18:56:49 -05:00
RoyalForgottenandTyler Wilding c7af284c6b French subtitle_lines_fr-FR.json (#3259)
French subtitles complete + fixed some wrong texts

---------

Co-authored-by: Tyler Wilding <[email protected]>
2023-12-19 18:55:51 -05:00
Matt Dallmeyer 3e568cb95d Disable save_texture_pngs by default [jak1] (#3256) 2023-12-18 18:25:51 -05:00
tripp 4b9c1dde70 add ms to loader output (#3261) 2023-12-18 18:17:27 -05:00
OpenGOAL BotandOpenGOALBot 35daebcce7 CI: Periodic Controller Database Update (#3255)
Updating Controller Database

Co-authored-by: OpenGOALBot <[email protected]>
2023-12-18 18:17:10 -05:00
ManDude 897e9c588b fix weird potential initialization bug with the music log (#3258) 2023-12-12 23:34:14 +00:00
water111 f17427bc26 [jak2] Fix unicode issue with GAME.CGO load (#3254)
Fix for https://github.com/open-goal/jak-project/issues/3244
2023-12-09 18:11:24 -05:00
Ziemas 168afa0e2e 989snd: sound bank loading overhaul (#3185) 2023-12-07 20:22:54 -05:00
Hat Kid 9b6f16f561 jak2: 90 fps menu option (#3245)
Closes #3223
2023-12-03 21:32:21 +01:00
ManDude 1808596679 save & load game territory setting (#3243) 2023-12-03 18:19:38 +00:00
ManDude 94b984326f [jak2] add game territory menu option (#3242) 2023-12-03 16:16:05 +00:00
ManDude 2795d3aa67 [jak2] fix health bar color fading (#3241)
Fixes #3237
2023-12-03 09:42:01 +00:00
ManDude be6a6dead4 [jak2] fix use-after-free bug in nav enemies (#3240)
Fixes #3153
2023-12-03 09:24:34 +00:00
ManDude 974f5931de [jak2] add resolutions menu (#3238) 2023-12-03 08:11:18 +00:00
Brent Hickey e119a66788 [jak2] Support STICK_DEADZONE (#3239)
fixes #3235
2023-12-03 08:11:10 +00:00
SuperSamusandMartino Fontana 37069e2f8e [jak2] Fix "Select controller" (#3191)
Co-authored-by: Martino Fontana <[email protected]>
2023-12-02 15:20:26 -05:00
Hat KidandTyler Wilding dfa6622544 jak2: add vehicle hijack lines PC cheat (#3205)
Co-authored-by: Tyler Wilding <[email protected]>
2023-12-02 15:17:54 -05:00
Luminar Light a3af37989b Allow replacing all instances of a texture with one texture (#3234)
There are art groups that are present in multiple levels, and that means
that also their textures are present in multiple levels. With texture
replacement, currently we need to make replacements for all instances if
we want it replaced everywhere, but this is not ideal, especially when
you make changes to your replacement texture and now you have to put it
in each folder again.

I added a way to replace all instances of a texture, by letting
texture-replacer people put their replacements into an '_all' folder. I
set up the logic in such a way that if you have a replacement for the
texture in its corresponding folder, it will take priority over a
replacement that you placed into the '_all' folder.

I personally found this very useful for replacing guard textures. The
guards appear in a lot of levels. But ideally you want them to look the
same everywhere. And that is why I looked into this and made a PR.

Oh and I changed what is printed in the 'Replacing ' part because it was
printing the path to our replacement, which didn't look nicely when
several textures got replaced by the same replacement from the '_all'
folder. So now it will print the original texture's page and name, I
think this information is more useful anyway.
2023-12-02 12:17:47 -05:00
water111 a01182315b [jak2] Support per-proto shrub visibility (#3228)
Fixes the issue reported in
https://github.com/open-goal/jak-project/issues/3168,
https://github.com/open-goal/jak-project/issues/3189,
https://github.com/open-goal/jak-project/issues/3166,
https://github.com/open-goal/jak-project/issues/3152,
https://github.com/open-goal/jak-project/issues/3224 where a small part
of the pipes in the `strip-grenade` mission appear, but shouldn't.
2023-12-02 12:16:14 -05:00
ManDude e38fe70ac4 [jak2] split language and text language (#3233) 2023-11-29 23:28:53 +00:00
ManDude 956645bdb9 [jak2] adjust progress generic item sizes + add scrolling effect (#3231)
Makes most of the options larger to reduce the amount of dead space and
adds a smooth scrolling effect instead of having "pages".


![imagem](https://github.com/open-goal/jak-project/assets/7569514/fc483dea-226c-44ff-96e0-680e89a6df81)

Button remap menu has no scrolling. Fixes #2984
2023-11-29 18:27:02 +00:00
981 changed files with 124576 additions and 29226 deletions

No files matched your search

+1 -1
View File
@@ -63,7 +63,7 @@ jobs:
python ./scripts/docs/append-file-docs.py
- name: Upload Docs Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: opengoal-docs
if-no-files-found: error
+1 -1
View File
@@ -71,7 +71,7 @@ jobs:
strip ./build/lsp/lsp
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: ${{ inputs.uploadArtifacts }}
with:
name: opengoal-linux-${{ inputs.cachePrefix }}
+1 -1
View File
@@ -55,7 +55,7 @@ jobs:
run: ./test.sh
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: opengoal-macos-${{ inputs.cachePrefix }}
if-no-files-found: error
+1 -1
View File
@@ -64,7 +64,7 @@ jobs:
strip ./build/lsp/lsp
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: ${{ inputs.uploadArtifacts }}
with:
name: opengoal-macos-${{ inputs.cachePrefix }}
+1 -1
View File
@@ -51,7 +51,7 @@ jobs:
- name: Prepare Artifact Folder
run: mkdir -p ./ci-artifacts/final
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
name: Download all Artifacts
with:
path: ./ci-artifacts/
+1 -1
View File
@@ -71,7 +71,7 @@ jobs:
run: ./build/bin/goalc-test.exe --gtest_color=yes --gtest_brief=0 --gtest_filter="-*MANUAL_TEST*"
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: ${{ inputs.uploadArtifacts }}
with:
name: opengoal-windows-${{ inputs.cachePrefix }}
-1
View File
@@ -1 +0,0 @@
endOfLine: "auto"
+11
View File
@@ -0,0 +1,11 @@
{
"endOfLine": "auto",
"overrides": [
{
"files": ["**/*.jsonc"],
"options": {
"parser": "json"
}
}
]
}
+25
View File
@@ -68,6 +68,18 @@
"jak2"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "offline-test.exe (bin\\offline-test.exe)",
"name": "Tests - Offline Tests - Jak 3",
"args": [
"--iso_data_path",
"${workspaceRoot}/iso_data/jak3",
"--game",
"jak3"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
@@ -218,6 +230,19 @@
"--config-override \"{\\\"decompile_code\\\": false, \\\"levels_extract\\\": true, \\\"allowed_objects\\\": []}\""
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "decompiler.exe (bin\\decompiler.exe)",
"name": "Decompiler - Jak 3",
"args": [
"${workspaceRoot}/decompiler/config/jak3/jak3_config.jsonc",
"${workspaceRoot}/iso_data",
"${workspaceRoot}/decompiler_out",
"--version",
"ntsc_v1"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
+1 -1
View File
@@ -5,7 +5,7 @@
"comments": true,
"strings": true
},
"editor.wordBasedSuggestions": true,
"editor.wordBasedSuggestions": "matchingDocuments",
"editor.snippetSuggestions": "top"
},
"python.formatting.provider": "black",
+10 -14
View File
@@ -74,16 +74,6 @@ tasks:
msg: "Couldn't locate compiler executable in '{{.GOALC_BIN_RELEASE_DIR}}/goalc'"
cmds:
- "{{.GOALC_BIN_RELEASE_DIR}}/goalc --user-auto --game {{.GAME}}"
format:
desc: "Format code"
cmds:
- cmd: python ./scripts/cpp/format-includes.py
- cmd: python ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i
# npm install -g prettier
- cmd: npx prettier --write ./decompiler/config/jak1/**/*.jsonc
ignore_error: true
- cmd: npx prettier --write ./decompiler/config/jak2/**/*.jsonc
ignore_error: true
format-json:
desc: "Format code"
cmds:
@@ -92,6 +82,15 @@ tasks:
ignore_error: true
- cmd: npx prettier --write ./decompiler/config/jak2/**/*.jsonc
ignore_error: true
- cmd: npx prettier --write ./decompiler/config/jak3/**/*.jsonc
ignore_error: true
format:
desc: "Format code"
cmds:
- cmd: python ./scripts/cpp/format-includes.py
- cmd: python ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i
- task: format-json
# DECOMPILING
decomp:
cmds:
@@ -166,9 +165,6 @@ tasks:
ignore_error: true
- python ./scripts/update_decomp_reference.py ./failures ./test/decompiler/reference/ --game {{.GAME}}
- task: offline-test-file
type-test-jak1:
cmds:
- cmd: '{{.GOALCTEST_BIN_RELEASE_DIR}}/goalc-test --gtest_brief=0 --gtest_filter="*Jak1TypeConsistency*" --gtest_break_on_failure'
type-test:
cmds:
- cmd: '{{.GOALCTEST_BIN_RELEASE_DIR}}/goalc-test --gtest_brief=0 --gtest_filter="*Jak2TypeConsistency*" --gtest_break_on_failure'
- cmd: '{{.GOALCTEST_BIN_RELEASE_DIR}}/goalc-test --gtest_brief=0 --gtest_filter="*{{.TYPE_CONSISTENCY_TEST_FILTER}}*" --gtest_break_on_failure'
+4
View File
@@ -42,6 +42,7 @@ void ShrubDraw::serialize(Serializer& ser) {
ser.from_ptr(&num_triangles);
ser.from_ptr(&first_index_index);
ser.from_ptr(&num_indices);
ser.from_ptr(&proto_idx);
}
void InstancedStripDraw::serialize(Serializer& ser) {
@@ -416,6 +417,9 @@ void ShrubTree::serialize(Serializer& ser) {
for (auto& draw : static_draws) {
draw.serialize(ser);
}
ser.from_ptr(&has_per_proto_visibility_toggle);
ser.from_string_vector(&proto_names);
}
void BVH::serialize(Serializer& ser) {
+7 -1
View File
@@ -18,7 +18,7 @@ namespace tfrag3 {
// - if changing any large things (vertices, vis, bvh, colors, textures) update get_memory_usage
// - if adding a new category to the memory usage, update extract_level to print it.
constexpr int TFRAG3_VERSION = 38;
constexpr int TFRAG3_VERSION = 39;
enum MemoryUsageCategory {
TEXTURE,
@@ -219,6 +219,8 @@ struct ShrubDraw {
// for debug counting.
u32 num_triangles = 0;
u16 proto_idx = 0;
void serialize(Serializer& ser);
};
@@ -430,6 +432,10 @@ struct ShrubTree {
std::vector<ShrubGpuVertex> vertices; // mesh vertices
} unpacked;
// jak 2 and later can toggle on and off visibility per proto by name
bool has_per_proto_visibility_toggle = false;
std::vector<std::string> proto_names;
void serialize(Serializer& ser);
void memory_usage(MemoryUsageTracker* tracker) const;
void unpack();
+1 -1
View File
@@ -191,7 +191,7 @@ bool can_node_be_inlined(const FormatterTreeNode& curr_node, int cursor_pos) {
}
std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
std::vector<std::string> output = {},
std::vector<std::string> /*output*/ = {},
int cursor_pos = 0) {
using namespace formatter_rules;
if (!curr_node.token && curr_node.refs.empty()) {
+1 -1
View File
@@ -9,7 +9,7 @@ namespace config {
FormFormattingConfig new_flow_rule(int start_index) {
FormFormattingConfig cfg;
cfg.hang_forms = false;
cfg.inline_until_index = [start_index](const std::vector<std::string>& curr_lines) {
cfg.inline_until_index = [start_index](const std::vector<std::string>& /*curr_lines*/) {
return start_index;
};
return cfg;
+2 -2
View File
@@ -21,8 +21,8 @@ struct FormFormattingConfig {
bool combine_first_two_lines =
false; // NOTE - basically hang, but will probably stick around after hang is gone, may be
// redundant (inline_until_index!)
std::function<std::optional<int>(const std::vector<std::string>& curr_lines)> inline_until_index =
[](std::vector<std::string> curr_lines) { return std::nullopt; };
std::function<std::optional<int>(const std::vector<std::string>& /*curr_lines*/)>
inline_until_index = [](std::vector<std::string> /*curr_lines*/) { return std::nullopt; };
bool has_constant_pairs = false;
bool prevent_inlining = false; // TODO - duplicate of below
std::function<bool(FormFormattingConfig, int num_refs)> should_prevent_inlining =
+1 -7
View File
@@ -62,15 +62,9 @@ constexpr int LEVEL_MAX = 6;
constexpr int LEVEL_TOTAL = LEVEL_MAX + 1;
} // namespace jak2
// TODO copypaste from jak 2 for now
namespace jak3 {
// for now, we don't have the ability to extend the size of the symbol table
constexpr s32 GOAL_MAX_SYMBOLS = 0x4000;
constexpr s32 SYM_TABLE_MEM_SIZE = 0x30000;
// from the "off-by-one" symbol pointer
constexpr int SYM_TO_STRING_OFFSET = 0xff37;
constexpr int SYM_TO_HASH_OFFSET = 0x1fe6f;
// amount of levels in level heap
constexpr int LEVEL_MAX = 10;
// total amount of levels, including ones outside level heap (default-level)
@@ -84,7 +78,7 @@ constexpr s32 max_symbols(GameVersion version) {
case GameVersion::Jak2:
return jak2::GOAL_MAX_SYMBOLS;
case GameVersion::Jak3:
return jak2::GOAL_MAX_SYMBOLS;
return jak3::GOAL_MAX_SYMBOLS;
}
}
+1 -1
View File
@@ -1888,7 +1888,7 @@ Object Interpreter::eval_format(const Object& form,
fmt::format_args(args2.data(), static_cast<unsigned>(args2.size())));
if (truthy(dest)) {
lg::print(formatted.c_str());
lg::print("{}", formatted.c_str());
}
return StringObject::make_new(formatted);
+7 -2
View File
@@ -238,9 +238,14 @@ Object Reader::read_from_string(const std::string& str,
* Read a file
*/
Object Reader::read_from_file(const std::vector<std::string>& file_path, bool check_encoding) {
std::string joined_path = fmt::format("{}", fmt::join(file_path, "/"));
std::string file_descriptor = fmt::format("{}", fmt::join(file_path, "/"));
const auto joined_file_path = file_util::get_file_path(file_path);
auto textFrag = std::make_shared<FileText>(file_util::get_file_path(file_path), joined_path);
if (!fs::exists(joined_file_path)) {
throw std::runtime_error(fmt::format("Cannot read {}, file doesn't exist", joined_file_path));
}
auto textFrag = std::make_shared<FileText>(joined_file_path, file_descriptor);
db.insert(textFrag);
auto result = internal_read(textFrag, check_encoding);
+3 -3
View File
@@ -85,9 +85,9 @@ std::pair<int, int> SourceText::get_containing_line(int offset) {
/*!
* Read text from a file.
*/
FileText::FileText(const std::string& filename, const std::string& description_name)
: m_filename(filename), m_desc_name(description_name) {
m_text = file_util::read_text_file(m_filename);
FileText::FileText(const std::string& file_path, const std::string& description_name)
: m_filepath(file_path), m_desc_name(description_name) {
m_text = file_util::read_text_file(m_filepath);
build_offsets();
}
+2 -2
View File
@@ -80,13 +80,13 @@ class ProgramString : public SourceText {
*/
class FileText : public SourceText {
public:
FileText(const std::string& filename, const std::string& description_name);
FileText(const std::string& file_path, const std::string& description_name);
std::string get_description() { return m_desc_name; }
~FileText() = default;
private:
std::string m_filename;
std::string m_filepath;
std::string m_desc_name;
};
+15
View File
@@ -54,6 +54,21 @@ struct LinkHeaderV4 {
uint32_t code_size; // length of object data before link data starts
};
struct LinkHeaderV5Core {
uint32_t length_to_get_to_code; // 4 length.. of link data?
uint16_t version; // 8
uint16_t unknown; // 10
uint32_t length_to_get_to_link; // 12
uint32_t link_length; // 16
uint8_t n_segments; // 20
char name[59]; // 21 (really??)
};
struct LinkHeaderV5 {
uint32_t type_tag; // 0 always 0?
LinkHeaderV5Core core;
};
// when a u32/s32 symbol link contains this value, (s7 + <val>) should be a 4-byte aligned address,
// not including the 1 byte symbol offset. (no effect in jak 1).
constexpr u32 LINK_SYM_NO_OFFSET_FLAG = 0xbadbeef;
+1 -1
View File
@@ -106,7 +106,7 @@ void log_print(const char* message) {
}
if (gLogger.stdout_log_level < lg::level::off_unless_die) {
fmt::print(message);
fmt::print("{}", message);
fflush(stdout);
fflush(stderr);
}
@@ -373,7 +373,7 @@ bool GameSubtitleDB::write_subtitle_db_to_files(const GameVersion game_version)
file_util::write_text_file(dump_path, lines_file.dump(2));
}
} catch (std::exception& ex) {
lg::error(ex.what());
lg::error("{}", ex.what());
return false;
}
return true;
+174
View File
@@ -150,6 +150,180 @@ constexpr int FIX_FIXED_SYM_END_OFFSET = 0xec;
} // namespace jak2_symbols
namespace jak3_symbols {
constexpr int FIX_SYM_EMPTY_CAR = -0x8;
constexpr int S7_OFF_FIX_SYM_EMPTY_PAIR = -0x6 - 1;
constexpr int FIX_SYM_EMPTY_CDR = -0x4;
constexpr int FIX_SYM_FALSE = 0x0; // GOAL boolean #f (note that this is equal to the $s7 register)
constexpr int FIX_SYM_TRUE = 0x4; // GOAL boolean #t
constexpr int FIX_SYM_FUNCTION_TYPE = 0x8;
constexpr int FIX_SYM_BASIC = 0xc;
constexpr int FIX_SYM_STRING_TYPE = 0x10;
constexpr int FIX_SYM_SYMBOL_TYPE = 0x14;
constexpr int FIX_SYM_TYPE_TYPE = 0x18;
constexpr int FIX_SYM_OBJECT_TYPE = 0x1c;
constexpr int FIX_SYM_LINK_BLOCK = 0x20;
constexpr int FIX_SYM_INTEGER = 0x24;
constexpr int FIX_SYM_SINTEGER = 0x28;
constexpr int FIX_SYM_UINTEGER = 0x2c;
constexpr int FIX_SYM_BINTEGER = 0x30;
constexpr int FIX_SYM_INT8 = 0x34;
constexpr int FIX_SYM_INT16 = 0x38;
constexpr int FIX_SYM_INT32 = 0x3c;
constexpr int FIX_SYM_INT64 = 0x40;
constexpr int FIX_SYM_INT128 = 0x44;
constexpr int FIX_SYM_UINT8 = 0x48;
constexpr int FIX_SYM_UINT16 = 0x4c;
constexpr int FIX_SYM_UINT32 = 0x50;
constexpr int FIX_SYM_UINT64 = 0x54;
constexpr int FIX_SYM_UINT128 = 0x58;
constexpr int FIX_SYM_FLOAT = 0x5c;
constexpr int FIX_SYM_PROCESS_TREE = 0x60;
constexpr int FIX_SYM_PROCESS_TYPE = 0x64;
constexpr int FIX_SYM_THREAD = 0x68;
constexpr int FIX_SYM_STRUCTURE = 0x6c;
constexpr int FIX_SYM_PAIR_TYPE = 0x70;
constexpr int FIX_SYM_POINTER = 0x74;
constexpr int FIX_SYM_NUMBER = 0x78;
constexpr int FIX_SYM_ARRAY = 0x7c;
constexpr int FIX_SYM_VU_FUNCTION = 0x80;
constexpr int FIX_SYM_CONNECTABLE = 0x84;
constexpr int FIX_SYM_STACK_FRAME = 0x88;
constexpr int FIX_SYM_FILE_STREAM = 0x8c;
constexpr int FIX_SYM_HEAP = 0x90;
constexpr int FIX_SYM_NOTHING_FUNC = 0x94;
constexpr int FIX_SYM_DELETE_BASIC = 0x98;
constexpr int FIX_SYM_STATIC = 0x9c;
constexpr int FIX_SYM_GLOBAL_HEAP = 0xa0;
constexpr int FIX_SYM_DEBUG = 0xa4;
constexpr int FIX_SYM_LOADING_LEVEL = 0xa8;
constexpr int FIX_SYM_LOADING_PACKAGE = 0xac;
constexpr int FIX_SYM_PROCESS_LEVEL_HEAP = 0xb0;
constexpr int FIX_SYM_STACK = 0xb4;
constexpr int FIX_SYM_SCRATCH = 0xb8;
constexpr int FIX_SYM_SCRATCH_TOP = 0xbc;
constexpr int FIX_SYM_ZERO_FUNC = 0xc0;
constexpr int FIX_SYM_ASIZE_OF_BASIC_FUNC = 0xc4;
constexpr int FIX_SYM_COPY_BASIC_FUNC = 0xc8; // bugged name
constexpr int FIX_SYM_LEVEL = 0xcc;
constexpr int FIX_SYM_ART_GROUP = 0xd0;
constexpr int FIX_SYM_TEXTURE_PAGE_DIR = 0xd4;
constexpr int FIX_SYM_TEXTURE_PAGE = 0xd8;
constexpr int FIX_SYM_SOUND = 0xdc;
constexpr int FIX_SYM_DGO = 0xe0;
constexpr int FIX_SYM_TOP_LEVEL = 0xe4;
constexpr int FIX_SYM_QUOTE = 0xe8;
constexpr int FIX_SYM_LISTENER_LINK_BLOCK = 0xec;
constexpr int FIX_SYM_LISTENER_FUNCTION = 0xf0;
constexpr int FIX_SYM_STACK_TOP = 0xf4;
constexpr int FIX_SYM_STACK_BASE = 0xf8;
constexpr int FIX_SYM_STACK_SIZE = 0xfc;
constexpr int FIX_SYM_KERNEL_FUNCTION = 0x100;
constexpr int FIX_SYM_KERNEL_PACKAGES = 0x104;
constexpr int FIX_SYM_KERNEL_BOOT_MESSAGE = 0x108;
constexpr int FIX_SYM_KERNEL_BOOT_MODE = 0x10c;
constexpr int FIX_SYM_KERNEL_BOOT_LEVEL = 0x110;
constexpr int FIX_SYM_KERNEL_BOOT_ART_GROUP = 0x114;
constexpr int FIX_SYM_KERNEL_DEBUG = 0x118;
constexpr int FIX_SYM_KERNEL_VERSION = 0x11c;
constexpr int FIX_SYM_KERNEL_DISPATCHER = 0x120;
constexpr int FIX_SYM_SYNC_DISPATCHER = 0x124;
constexpr int FIX_SYM_PRINT_COLLUMN = 0x128;
constexpr int FIX_SYM_DEBUG_SEGMENT = 300;
constexpr int FIX_SYM_ENABLE_METHOD_SET = 0x130;
constexpr int FIX_SYM_SQL_RESULT = 0x134;
constexpr int FIX_SYM_COLLAPSE_QUOTE = 0x138;
constexpr int FIX_SYM_LEVEL_TYPE_LIST = 0x13C;
constexpr int FIX_SYM_DECI_COUNT = 0x140;
constexpr int FIX_SYM_USER = 0x144;
constexpr int FIX_SYM_VIDEO_MODE = 0x148;
constexpr int FIX_SYM_BOOT_VIDEO_MODE = 0x14C;
constexpr int FIX_SYM_BOOT = 0x150;
constexpr int FIX_SYM_DEMO = 0x154;
constexpr int FIX_SYM_DEMO_SHARED = 0x158;
constexpr int FIX_SYM_PREVIEW = 0x15C;
constexpr int FIX_SYM_KIOSK = 0x160;
constexpr int FIX_SYM_PLAY_BOOT = 0x164;
constexpr int FIX_SYM_SIN = 0x168;
constexpr int FIX_SYM_COS = 0x16C;
constexpr int FIX_SYM_PUT_DISPLAY_ENV = 0x170;
constexpr int FIX_SYM_SYNCV = 0x174;
constexpr int FIX_SYM_SYNC_PATH = 0x178;
constexpr int FIX_SYM_RESET_PATH = 0x17C;
constexpr int FIX_SYM_RESET_GRAPH = 0x180;
constexpr int FIX_SYM_DMA_SYNC = 0x184;
constexpr int FIX_SYM_GS_PUT_IMR = 0x188;
constexpr int FIX_SYM_GS_GET_IMR = 0x18C;
constexpr int FIX_SYM_GS_STORE_IMAGE = 400;
constexpr int FIX_SYM_FLUSH_CACHE = 0x194;
constexpr int FIX_SYM_CPAD_OPEN = 0x198;
constexpr int FIX_SYM_CPAD_GET_DATA = 0x19C;
constexpr int FIX_SYM_MOUSE_GET_DATA = 0x1A0;
constexpr int FIX_SYM_KEYBD_GET_DATA = 0x1A4;
constexpr int FIX_SYM_INSTALL_HANDLER = 0x1A8;
constexpr int FIX_SYM_INSTALL_DEBUG_HANDLER = 0x1AC;
constexpr int FIX_SYM_FILE_STREAM_OPEN = 0x1B0;
constexpr int FIX_SYM_FILE_STREAM_CLOSE = 0x1B4;
constexpr int FIX_SYM_FILE_STREAM_LENGTH = 0x1B8;
constexpr int FIX_SYM_FILE_STREAM_SEEK = 0x1BC;
constexpr int FIX_SYM_FILE_STREAM_READ = 0x1C0;
constexpr int FIX_SYM_FILE_STREAM_WRITE = 0x1C4;
constexpr int FIX_SYM_SCF_GET_LANGUAGE = 0x1C8;
constexpr int FIX_SYM_SCF_GET_TIME = 0x1CC;
constexpr int FIX_SYM_SCF_GET_ASPECT = 0x1D0;
constexpr int FIX_SYM_SCF_GET_VOLUME = 0x1D4;
constexpr int FIX_SYM_SCF_GET_TERRITORY = 0x1D8;
constexpr int FIX_SYM_SCF_GET_TIMEOUT = 0x1DC;
constexpr int FIX_SYM_SCF_GET_INACTIVE_TIMEOUT = 0x1E0;
constexpr int FIX_SYM_DMA_TO_IOP = 0x1E4;
constexpr int FIX_SYM_KERNEL_SHUTDOWN = 0x1E8;
constexpr int FIX_SYM_AYBABTU = 0x1EC;
constexpr int FIX_SYM_STRING_TO_SYMBOL = 0x1F0;
constexpr int FIX_SYM_SYMBOL_TO_STRING = 500;
constexpr int FIX_SYM_PRINT = 0x1F8;
constexpr int FIX_SYM_INSPECT = 0x1FC;
constexpr int FIX_SYM_LOAD = 0x200;
constexpr int FIX_SYM_LOADB = 0x204;
constexpr int FIX_SYM_LOADO = 0x208;
constexpr int FIX_SYM_UNLOAD = 0x20C;
constexpr int FIX_SYM_FORMAT = 0x210;
constexpr int FIX_SYM_MALLOC = 0x214;
constexpr int FIX_SYM_KMALLOC = 0x218;
constexpr int FIX_SYM_KMEMOPEN = 0x21C;
constexpr int FIX_SYM_KMEMCLOSE = 0x220;
constexpr int FIX_SYM_NEW_DYNAMIC_STRUCTURE = 0x224;
constexpr int FIX_SYM_METHOD_SET = 0x228;
constexpr int FIX_SYM_LINK = 0x22C;
constexpr int FIX_SYM_LINK_BUSY = 0x230;
constexpr int FIX_SYM_LINK_RESET = 0x234;
constexpr int FIX_SYM_LINK_BEGIN = 0x238;
constexpr int FIX_SYM_LINK_RESUME = 0x23C;
constexpr int FIX_SYM_DGO_LOAD = 0x240;
constexpr int FIX_SYM_SQL_QUERY = 0x244;
constexpr int FIX_SYM_MC_RUN = 0x248;
constexpr int FIX_SYM_MC_FORMAT = 0x24C;
constexpr int FIX_SYM_MC_UNFORMAT = 0x250;
constexpr int FIX_SYM_MC_CREATE_FILE = 0x254;
constexpr int FIX_SYM_MC_SAVE = 600;
constexpr int FIX_SYM_MC_LOAD = 0x25C;
constexpr int FIX_SYM_MC_CHECK_RESULT = 0x260;
constexpr int FIX_SYM_MC_GET_SLOT_INFO = 0x264;
constexpr int FIX_SYM_MC_MAKEFILE = 0x268;
constexpr int FIX_SYM_KSET_LANGUAGE = 0x26C;
constexpr int FIX_SYM_RPC_CALL = 0x270;
constexpr int FIX_SYM_RPC_BUSY = 0x274;
constexpr int FIX_SYM_TEST_LOAD_DGO_C = 0x278;
constexpr int FIX_SYM_SYMLINK2 = 0x27c;
constexpr int FIX_SYM_SYMLINK3 = 0x280;
constexpr int FIX_SYM_ULTIMATE_MEMCPY = 0x284;
constexpr int FIX_SYM_PLAY = 0x288;
constexpr int FIX_SYM_SYMBOL_STRING = 0x28c;
constexpr int FIX_SYM_KERNEL_SYMBOL_WARNINGS = 0x290;
constexpr int FIX_SYM_NETWORK_BOOTSTRAP = 0x294;
} // namespace jak3_symbols
constexpr int false_symbol_offset() {
return jak1_symbols::FIX_SYM_FALSE;
}
+2 -2
View File
@@ -16,12 +16,12 @@ void private_assert_failed(const char* expr,
if (!msg || msg[0] == '\0') {
std::string log = fmt::format("Assertion failed: '{}'\n\tSource: {}:{}\n\tFunction: {}\n", expr,
file, line, function);
lg::die(log);
lg::die("{}", log);
} else {
std::string log =
fmt::format("Assertion failed: '{}'\n\tMessage: {}\n\tSource: {}:{}\n\tFunction: {}\n",
expr, msg, file, line, function);
lg::die(log);
lg::die("{}", log);
}
abort();
}
+10 -7
View File
@@ -12,30 +12,33 @@
#include "common/common_types.h"
#include "common/util/Assert.h"
#include "third-party/span.hpp"
class BinaryReader {
public:
explicit BinaryReader(const std::vector<uint8_t>& _buffer) : m_buffer(_buffer) {}
explicit BinaryReader(nonstd::span<const uint8_t> _span) : m_span(_span) {}
template <typename T>
T read() {
ASSERT(m_seek + sizeof(T) <= m_buffer.size());
ASSERT(m_seek + sizeof(T) <= m_span.size());
T obj;
memcpy(&obj, m_buffer.data() + m_seek, sizeof(T));
memcpy(&obj, m_span.data() + m_seek, sizeof(T));
m_seek += sizeof(T);
return obj;
}
void ffwd(int amount) {
m_seek += amount;
ASSERT(m_seek <= m_buffer.size());
ASSERT(m_seek <= m_span.size());
}
uint32_t bytes_left() const { return m_buffer.size() - m_seek; }
uint8_t* here() { return m_buffer.data() + m_seek; }
uint32_t bytes_left() const { return m_span.size() - m_seek; }
const uint8_t* here() { return m_span.data() + m_seek; }
BinaryReader at(u32 pos) { return BinaryReader(m_span.subspan(pos)); }
uint32_t get_seek() const { return m_seek; }
void set_seek(u32 seek) { m_seek = seek; }
private:
std::vector<u8> m_buffer;
nonstd::span<const u8> m_span;
uint32_t m_seek = 0;
};
+3
View File
@@ -636,6 +636,9 @@ std::vector<fs::path> find_files_in_dir(const fs::path& dir, const std::regex& p
std::vector<fs::path> find_files_recursively(const fs::path& base_dir, const std::regex& pattern) {
std::vector<fs::path> files = {};
if (!fs::exists(base_dir)) {
return files;
}
for (auto& p : fs::recursive_directory_iterator(base_dir)) {
if (p.is_regular_file()) {
if (std::regex_match(p.path().filename().string(), pattern)) {
+1 -1
View File
@@ -21,7 +21,7 @@ void assert_string_empty_after(const char* str, int size) {
}
}
std::string get_object_file_name(const std::string& original_name, u8* data, int size) {
std::string get_object_file_name(const std::string& original_name, const u8* data, int size) {
const std::string art_group_text_strings[] = {
fmt::format("/src/next/data/art-group{}/", versions::jak1::ART_FILE_VERSION),
fmt::format("/src/jak2/final/art-group{}/", versions::jak2::ART_FILE_VERSION),
+1 -1
View File
@@ -6,4 +6,4 @@
#include "common/versions/versions.h"
void assert_string_empty_after(const char* str, int size);
std::string get_object_file_name(const std::string& original_name, u8* data, int size);
std::string get_object_file_name(const std::string& original_name, const u8* data, int size);
+9 -2
View File
@@ -11,13 +11,15 @@ GameVersion game_name_to_version(const std::string& name) {
return GameVersion::Jak1;
} else if (name == "jak2") {
return GameVersion::Jak2;
} else if (name == "jak3") {
return GameVersion::Jak3;
} else {
ASSERT_MSG(false, fmt::format("invalid game name: {}", name));
}
}
bool valid_game_version(const std::string& name) {
return name == "jak1" || name == "jak2";
return name == "jak1" || name == "jak2" || name == "jak3";
}
std::string version_to_game_name(GameVersion v) {
@@ -26,6 +28,8 @@ std::string version_to_game_name(GameVersion v) {
return "jak1";
case GameVersion::Jak2:
return "jak2";
case GameVersion::Jak3:
return "jak3";
default:
ASSERT_MSG(false, fmt::format("no game_name for version: {} found", fmt::underlying(v)));
}
@@ -37,13 +41,16 @@ std::string version_to_game_name_external(GameVersion v) {
return "Jak 1";
case GameVersion::Jak2:
return "Jak 2";
case GameVersion::Jak3:
return "Jak 3";
default:
ASSERT_MSG(false, fmt::format("no game_name for version: {} found", fmt::underlying(v)));
}
}
std::vector<std::string> valid_game_version_names() {
return {game_version_names[GameVersion::Jak1], game_version_names[GameVersion::Jak2]};
return {game_version_names[GameVersion::Jak1], game_version_names[GameVersion::Jak2],
game_version_names[GameVersion::Jak3]};
}
std::string build_revision() {
+1
View File
@@ -34,6 +34,7 @@ constexpr u32 TX_PAGE_VERSION = 8;
namespace jak3 {
constexpr u32 ART_FILE_VERSION = 8;
constexpr u32 LEVEL_FILE_VERSION = 36;
constexpr u32 DGO_FILE_VERSION = 1;
constexpr u32 TX_PAGE_VERSION = 8;
} // namespace jak3
+24 -10
View File
@@ -20,16 +20,30 @@
// this makes collision 2x slower and bigger, so only use if really needed
"double_sided_collide": false,
// available res-lump tag data types:
// int32, float, meters, vector, vector4m (meters)
// available res-lump tag types:
// value types: int32, uint32, enum-int32, enum-uint32, float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°)
// vector types: vector (normal floats), vector4m (meters), vector3m (meters with w set to 1.0), vector-vol (normal floats with w in meters), movie-pos (meters with w in degrees)
// special types: eco-info, water-height
//
// examples:
//
// adds a float tag 'spring-height' with value of 200 meters (1 meter = 4096.0 units):
// "spring-height": ["meters", 200.0]
//
// adds a vector tag 'movie-pos':
// "movie-pos": ["vector", [4096000.0, -176128.0, 1353973.76, 1.0]]
// adds a degrees tag 'rotoffset':
// "rotoffset": ["degrees", -45.0]
//
// adds a movie-pos tag:
// "movie-pos": ["movie-pos", [100.22, -25.3, 99.5, 180.0]]
//
// adds an enum tag 'options':
// "options": ["enum-int32", "(fact-options large)"]
//
// adds a water-height tag:
// "water-height": ["water-height", 25.0, 0.5, 2.0, "(water-flags wt08 wt03 wt01)"]
//
// adds an eco-info tag:
// "eco-info": ["eco-info", "(pickup-type health)", 2]
// The base actor id for your custom level. If you have multiple levels this should be unique!
"base_id": 100,
@@ -65,7 +79,7 @@
"lump": {
"name": "test-ambient",
"type": "'hint",
"text-id": ["int32", 557], // text id for the "POWER CELL" text
"text-id": ["enum-uint32", "(text-id fuel-cell)"], // text id for the "POWER CELL" text
"play-mode": "'notice"
}
}
@@ -75,7 +89,7 @@
{
"trans": [-21.6238, 20.0496, 17.1191], // translation
"etype": "fuel-cell", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-21.6238, 19.3496, 17.1191, 10], // bounding sphere
"lump": {
@@ -86,20 +100,20 @@
{
"trans": [-15.2818, 15.2461, 17.1360], // translation
"etype": "crate", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
"lump": {
"name": "test-crate",
"crate-type": "'steel",
"eco-info": ["int32", 5, 10]
"eco-info": ["eco-info", "(pickup-type money)", 10]
}
},
{
"trans": [-5.4630, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
"lump": {
@@ -109,7 +123,7 @@
// {
// "trans": [-7.41, 3.5, 28.42], // translation
// "etype": "plat", // actor type
// "game_task": 0, // associated game task (for powercells, etc)
// "game_task": "(game-task none)", // associated game task (for powercells, etc)
// "quat": [0, 0, 0, 1], // quaternion
// "bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere
// "lump": {
+22 -9
View File
@@ -20,24 +20,37 @@
// this makes collision 2x slower and bigger, so only use if really needed
"double_sided_collide": false,
// available res-lump tag data types:
// int32, float, meters, vector, vector4m (meters)
// available res-lump tag types:
// value types: int32, uint32, enum-int32, enum-uint32, float, meters (1 meter = 4096.0 units), degrees (65536.0 = 360°)
// vector types: vector (normal floats), vector4m (meters), vector3m (meters with w set to 1.0), vector-vol (normal floats with w in meters), movie-pos (meters with w in degrees)
// special types: eco-info, water-height
//
// examples:
//
// adds a float tag 'spring-height' with value of 200 meters (1 meter = 4096.0 units):
// "spring-height": ["meters", 200.0]
//
// adds a vector tag 'movie-pos':
// "movie-pos": ["vector", [4096000.0, -176128.0, 1353973.76, 1.0]]
// adds a degrees tag 'rotoffset':
// "rotoffset": ["degrees", -45.0]
//
// adds a movie-pos tag:
// "movie-pos": ["movie-pos", [100.22, -25.3, 99.5, 180.0]]
//
// adds an enum tag 'options':
// "options": ["enum-int32", "(fact-options large)"]
//
// adds a water-height tag:
// "water-height": ["water-height", 25.0, 0.5, 2.0, "(water-flags can-swim can-wade)"]
//
// adds an eco-info tag:
// "eco-info": ["eco-info", "(pickup-type health)", 2]
// The base actor id for your custom level. If you have multiple levels, this should be unique!
"base_id": 100,
// All art groups you want to use in your custom level. Will add their models and corresponding textures to the FR3 file.
// Removed so that the release builds don't have to double-decompile the game
//"art_groups": ["prsn-torture-ag"],
"art_groups": [],
// "art_groups": ["prsn-torture-ag"],
// Any textures you want to include in your custom level.
// This is mainly useful for textures which are not in the common level files and have no art group associated with them.
@@ -55,14 +68,14 @@
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
"lump": {
"name": "test-crate",
"eco-info": ["int32", 18, 2]
"eco-info": ["eco-info", "(pickup-type health)", 2]
}
},
{
"trans": [-5.4630, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"kill_mask": 0,
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-5.4630, 17.4553, 1.6169, 10], // bounding sphere
@@ -74,7 +87,7 @@
{
"trans": [-7.41, 13.5, 28.42], // translation
"etype": "prsn-torture", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-7.41, 13.5, 28.42, 10], // bounding sphere
"lump": {
+2 -2
View File
@@ -191,7 +191,7 @@ TP_Type SimpleExpression::get_type(const TypeState& input,
return TP_Type::make_from_ts("float");
}
// new for jak 2:
if (env.version == GameVersion::Jak2 && in_type.is_integer_constant() &&
if (env.version >= GameVersion::Jak2 && in_type.is_integer_constant() &&
(s64)((s32)in_type.get_integer_constant()) == (s64)in_type.get_integer_constant()) {
return TP_Type::make_from_ts("float");
}
@@ -406,7 +406,7 @@ TP_Type SimpleExpression::get_type_int2(const TypeState& input,
}
if (m_kind == Kind::RIGHT_SHIFT_ARITH) {
if (env.version == GameVersion::Jak2 && arg0_type.typespec().base_type() == "float") {
if (env.version >= GameVersion::Jak2 && arg0_type.typespec().base_type() == "float") {
return TP_Type::make_from_ts(TypeSpec("float"));
}
return TP_Type::make_from_ts(TypeSpec("int"));
+1 -1
View File
@@ -170,7 +170,7 @@ FormElement* handle_get_property_struct(const std::vector<Form*>& forms,
const Env& env) {
return handle_get_property_data_or_structure(
forms, pool, env, ResLumpMacroElement::Kind::STRUCT,
env.version == GameVersion::Jak2 ? "(the-as structure #f)" : "#f", TypeSpec("structure"));
env.version >= GameVersion::Jak2 ? "(the-as structure #f)" : "#f", TypeSpec("structure"));
}
FormElement* handle_get_property_value(const std::vector<Form*>& forms,
+4 -4
View File
@@ -3141,11 +3141,11 @@ goos::Object DefskelgroupElement::to_form_internal(const Env& env) const {
}
if (m_static_info.shadow_joint_index != 0) {
forms.push_back(pretty_print::to_symbol(
fmt::format(":shadow-joint-index {}", m_static_info.origin_joint_index)));
fmt::format(":shadow-joint-index {}", m_static_info.shadow_joint_index)));
}
if (m_static_info.light_index != 0) {
forms.push_back(pretty_print::to_symbol(
fmt::format(":light-index {}", m_static_info.origin_joint_index)));
forms.push_back(
pretty_print::to_symbol(fmt::format(":light-index {}", m_static_info.light_index)));
}
}
@@ -3255,7 +3255,7 @@ goos::Object DefpartgroupElement::to_form_internal(const Env& env) const {
if (offset) {
// jak2 has switched this field to a signed 16 bit number
if (env.version == GameVersion::Jak2) {
if (env.version >= GameVersion::Jak2) {
result += fmt::format(" :offset {}", (s16)offset);
} else {
result += fmt::format(" :offset {}", offset);
+5 -5
View File
@@ -122,7 +122,7 @@ Form* try_cast_simplify(Form* in,
return in;
}
if (env.version == GameVersion::Jak2) {
if (env.version >= GameVersion::Jak2) {
if (new_type == TypeSpec("float")) {
auto ic = get_goal_integer_constant(in, env);
if (ic) {
@@ -138,7 +138,7 @@ Form* try_cast_simplify(Form* in,
if (new_type == TypeSpec("meters")) {
auto fc = get_goal_float_constant(in);
if (!fc && env.version == GameVersion::Jak2) {
if (!fc && env.version >= GameVersion::Jak2) {
auto ic = get_goal_integer_constant(in, env);
if (ic) {
ASSERT((s64)*ic == (s64)(s32)*ic);
@@ -2853,7 +2853,7 @@ bool try_to_rewrite_vector_inline_ctor(const Env& env,
token_matchers = {DerefTokenMatcher::string("quad")};
}
if (env.version == GameVersion::Jak2) {
if (env.version >= GameVersion::Jak2) {
token_matchers = {DerefTokenMatcher::string("quad")};
}
@@ -3376,7 +3376,7 @@ void FunctionCallElement::update_from_stack(const Env& env,
argset = argset.substr(1);
auto argsym = arg_forms.at(1)->to_string(env);
// convert the float param
if (env.version == GameVersion::Jak2) {
if (env.version >= GameVersion::Jak2) {
static const std::unordered_set<std::string> use_degrees_settings = {
"matrix-blend-max-angle",
"fov",
@@ -4081,7 +4081,7 @@ void DerefElement::update_from_stack(const Env& env,
}
auto as_simple_expr = m_base->try_as_element<SimpleExpressionElement>();
if (env.version == GameVersion::Jak2 && as_simple_expr && as_simple_expr->expr().is_identity() &&
if (env.version >= GameVersion::Jak2 && as_simple_expr && as_simple_expr->expr().is_identity() &&
as_simple_expr->expr().get_arg(0).is_sym_val() &&
as_simple_expr->expr().get_arg(0).get_str() == "*game-info*" && m_tokens.size() >= 2 &&
m_tokens.at(0).is_field_name("sub-task-list") && m_tokens.at(1).is_int()) {
@@ -263,7 +263,7 @@ static void link_v2_or_v4(LinkedObjectFile& f,
const uint8_t* code_end =
&data.at(code_offset + code_size - 1) + 1; // get the pointer to one past the end.
if (version == GameVersion::Jak2) {
if (version >= GameVersion::Jak2) {
while (((code_end - code_start) % 4)) {
code_end++;
}
@@ -472,7 +472,7 @@ static void link_v5(LinkedObjectFile& f,
for (int i = 0; i < n_segs; i++) {
segment_data_offsets[i] = header->length_to_get_to_code + seg_info_array[i].data;
segment_link_offsets[i] = header->length_to_get_to_link + seg_info_array[i].relocs;
ASSERT(seg_info_array[i].magic == 1);
ASSERT(seg_info_array[i].magic == 1); // if set, always use symlink2.
}
// check that the data region is filled
@@ -689,7 +689,7 @@ static void link_v3(LinkedObjectFile& f,
segment_size++;
}
if (game_version == GameVersion::Jak2) {
if (game_version >= GameVersion::Jak2) {
while (segment_size % 4) {
segment_size++;
}
+2 -1
View File
@@ -222,13 +222,14 @@ class ObjectFileDB {
void ir2_setup_labels(const Config& config, ObjectFileData& data);
void ir2_run_mips2c(const Config& config, ObjectFileData& data);
struct PerObjectAllTypeInfo {
std::string object_name;
std::unordered_set<std::string> already_seen_symbols;
// type-name : { method id : state name }
std::unordered_map<std::string, std::unordered_map<int, std::string>> state_methods;
// symbol-name : type-name
std::unordered_map<std::string, std::string> symbol_types;
// state-name : type-name
std::unordered_map<std::string, std::string> non_virtual_state_guesses;
struct TypeInfo {
bool from_inspect_method = false; // does this come from an inspect method?
+80 -19
View File
@@ -10,6 +10,7 @@
#include "common/log/log.h"
#include "common/util/FileUtil.h"
#include "common/util/Timer.h"
#include "common/util/string_util.h"
#include "decompiler/IR2/Form.h"
#include "decompiler/analysis/analyze_inspect_method.h"
@@ -319,7 +320,11 @@ void ObjectFileDB::ir2_top_level_pass(const Config& config) {
void ObjectFileDB::ir2_analyze_all_types(const fs::path& output_file,
const std::optional<std::string>& previous_game_types,
const std::unordered_set<std::string>& bad_types) {
std::vector<PerObjectAllTypeInfo> per_object;
auto is_code_file = [](ObjectFileData& data) {
return (data.obj_version == 3 ||
(data.obj_version == 5 && data.linked_data.has_any_functions()));
};
std::unordered_map<std::string, PerObjectAllTypeInfo> per_object;
DecompilerTypeSystem previous_game_ts(GameVersion::Jak2); // version here doesn't matter.
if (previous_game_types) {
@@ -328,16 +333,66 @@ void ObjectFileDB::ir2_analyze_all_types(const fs::path& output_file,
TypeInspectorCache ti_cache;
// Do a first pass to initialize all types and symbols
for_each_obj([&](ObjectFileData& data) {
if (data.obj_version == 3 || (data.obj_version == 5 && data.linked_data.has_any_functions())) {
auto& object_result = per_object.emplace_back();
object_result.object_name = data.to_unique_name();
if (is_code_file(data)) {
per_object[data.to_unique_name()] = PerObjectAllTypeInfo();
// Go through the top-level segment first to identify the type names associated with each
// symbol def
for_each_function_in_seg_in_obj(TOP_LEVEL_SEGMENT, data, [&](Function& f) {
inspect_top_level_for_metadata(f, data.linked_data, dts, previous_game_ts, object_result);
inspect_top_level_for_metadata(f, data.linked_data, dts, previous_game_ts,
per_object.at(data.to_unique_name()));
});
}
});
// Guess at non-virtual state type's:
//
// Collect all type names, since the DTS doesn't know the actual type tree (all-types is empty!)
// we can't filter by what is actually a process type (with existing code).
std::unordered_map<std::string, std::vector<std::string>> all_type_names;
for (auto& [obj_name, obj_info] : per_object) {
for (const auto& type_name : obj_info.type_names_in_order) {
if (all_type_names.find(obj_name) == all_type_names.end()) {
all_type_names[obj_name] = {};
}
all_type_names[obj_name].push_back(type_name);
}
}
std::unordered_map<std::string, std::string> state_to_type_map;
for (auto& [obj_name, obj_info] : per_object) {
for (const auto& [sym_name, sym_type] : obj_info.symbol_types) {
if (sym_type == "state") {
int longest_match_length = 0;
std::string longest_match = "";
std::string longest_match_object_name = "";
// Make a best effort guess by finding the longest prefix match
for (const auto& [obj_name, type_names] : all_type_names) {
for (const auto& type_name : type_names) {
if (str_util::starts_with(sym_name, type_name) &&
(int)type_name.length() > longest_match_length) {
longest_match_length = type_name.length();
longest_match = type_name;
longest_match_object_name = obj_name;
}
}
}
if (longest_match != "") {
if (per_object.find(longest_match_object_name) != per_object.end()) {
per_object.at(longest_match_object_name).non_virtual_state_guesses[sym_name] =
longest_match;
obj_info.already_seen_symbols.insert(sym_name);
}
}
}
}
}
// Then another to actually setup the definitions
for_each_obj([&](ObjectFileData& data) {
if (is_code_file(data)) {
auto& object_result = per_object.at(data.to_unique_name());
// Handle the top level last, which is fine as all symbol_defs are always written after
// typedefs
@@ -368,21 +423,27 @@ void ObjectFileDB::ir2_analyze_all_types(const fs::path& output_file,
}
});
// Output result
std::string result;
result += ";; All Types\n\n";
for (auto& obj : per_object) {
result += fmt::format(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
result += fmt::format(";; {:30s} ;;\n", obj.object_name);
result += fmt::format(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n");
for (const auto& type_name : obj.type_names_in_order) {
auto& info = obj.type_info.at(type_name);
result += info.type_definition;
for_each_obj([&](ObjectFileData& data) {
if (is_code_file(data)) {
auto& obj = per_object.at(data.to_unique_name());
result += fmt::format(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
result += fmt::format(";; {:30s} ;;\n", data.name_in_dgo);
result += fmt::format(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n");
for (const auto& type_name : obj.type_names_in_order) {
auto& info = obj.type_info.at(type_name);
result += info.type_definition;
result += "\n";
}
result += obj.symbol_defs;
result += "\n";
}
result += obj.symbol_defs;
result += "\n";
}
});
file_util::write_text_file(output_file, result);
}
@@ -594,8 +655,8 @@ void ObjectFileDB::ir2_type_analysis_pass(int seg, const Config& config, ObjectF
}
constexpr bool kForceNewTypes = false;
if (config.game_version == GameVersion::Jak2 || kForceNewTypes) {
// use new types for jak 2 always
if (config.game_version != GameVersion::Jak1 || kForceNewTypes) {
// use new types for jak 2/3 always
types2::Input in;
types2::Output out;
in.func = &func;
@@ -749,7 +810,7 @@ void ObjectFileDB::ir2_insert_lets(int seg, ObjectFileData& data) {
"Error while inserting lets: {}. Make sure that the return type is not "
"none if something is actually returned.",
e.what());
lg::warn(err);
lg::warn("{}", err);
func.warnings.error(err);
}
}
+81 -59
View File
@@ -1427,10 +1427,15 @@ std::string inspect_inspect_method(Function& inspect_method,
object_file_meta);
}
std::string old_method_string(const MethodInfo& info) {
std::string old_method_string(const MethodInfo& info, const bool omit_comment = false) {
if (info.type.arg_count() > 0) {
if (info.type.base_type() == "function" || info.type.base_type() == "state") {
std::string result = fmt::format(" ;; ({} (", info.name);
std::string result;
if (omit_comment) {
result = fmt::format(" ({} (", info.name);
} else {
result = fmt::format(" ;; ({} (", info.name);
}
bool add = false;
for (int i = 0; i < (int)info.type.arg_count() - 1; i++) {
result += info.type.get_arg(i).print();
@@ -1445,11 +1450,14 @@ std::string old_method_string(const MethodInfo& info) {
if (info.type.base_type() == "state") {
result += " :state";
}
result += fmt::format(" {})", info.id);
result += ")";
return result;
}
}
if (omit_comment) {
return fmt::format(" ({} {}) weird method", info.name, info.type.print());
}
return fmt::format(" ;; ({} {}) weird method", info.name, info.type.print());
}
@@ -1637,81 +1645,75 @@ std::string TypeInspectorResult::print_as_deftype(
result.append("\n ");
}
std::string state_methods_list;
std::unordered_map<int, std::string> method_states = {};
if (object_file_meta.state_methods.count(type_name) != 0) {
method_states = object_file_meta.state_methods.at(type_name);
for (const auto& [method_id, state_name] : method_states) {
MethodInfo info;
state_methods_list += fmt::format(" {} ;; {}", state_name, method_id);
if (old_game_type && old_game_type->get_my_method(method_id, &info)) {
state_methods_list += ", old:" + old_method_string(info, true);
}
state_methods_list += "\n";
}
}
std::string methods_list;
if (type_method_count > 9) {
std::string methods_list;
std::string state_methods_list;
MethodInfo old_new_method;
if (old_game_type && old_game_type->get_my_new_method(&old_new_method)) {
methods_list.append(" ");
methods_list.append(" (new (symbol type) _type_) ;; 0");
methods_list.append(old_method_string(old_new_method));
methods_list.push_back('\n');
}
bool done_with_state_methods = false;
for (int i = parent_method_count; i < type_method_count; i++) {
bool print_as_state_method = false;
if (method_states.count(i) != 0) {
if (!done_with_state_methods) {
print_as_state_method = true;
state_methods_list.append(fmt::format(" {}", method_states.at(i)));
} else {
methods_list.append(
fmt::format(" ({} () _type_ :state) ;; {}", method_states.at(i), i));
}
} else {
done_with_state_methods = true;
methods_list.append(fmt::format(" ({}-method-{} () none) ;; {}", type_name, i, i));
// If it's a state-method (virtual state) skip it
if (method_states.find(i) != method_states.end()) {
continue;
}
methods_list.append(fmt::format(" ({}-method-{} () none) ;; {}", type_name, i, i));
if (old_game_type) {
MethodInfo info;
if (old_game_type->get_my_method(i, &info)) {
if (print_as_state_method) {
state_methods_list += old_method_string(info);
} else {
methods_list += old_method_string(info);
}
methods_list += old_method_string(info);
}
}
if (print_as_state_method) {
state_methods_list.push_back('\n');
} else {
methods_list.push_back('\n');
}
}
if (!state_methods_list.empty()) {
result.append("(:state-methods\n");
result.append(state_methods_list);
result.append(" )\n ");
}
if (!methods_list.empty()) {
result.append("(:methods");
result.append(methods_list);
result.append(" )\n ");
methods_list.push_back('\n');
}
}
// Print out (normal) states if we have em
// - Could probably assume the process name comes first and associate it with the right type
// but that may or may not be risky so, edit the types yourself...
if (method_states.size() > 0) {
result.append("(:states\n ");
for (const auto& [id, name] : method_states) {
result.append(name);
// Append old symbol def if we have it
auto it = previous_game_ts.symbol_types.find(name);
// non-virtual states
std::string non_virtual_states_list;
for (const auto& [state_name, guessed_type_name] : object_file_meta.non_virtual_state_guesses) {
if (type_name == guessed_type_name) {
std::string line;
line += fmt::format(" {}", state_name);
auto it = previous_game_ts.symbol_types.find(state_name);
if (it != previous_game_ts.symbol_types.end()) {
result.append(fmt::format(" ;; {}", it->second.print()));
line += fmt::format(" ;; associated process guessed by decompiler, old: {}",
it->second.print());
}
// Add symbol name to `already_seen_symbols`
object_file_meta.already_seen_symbols.insert(name);
result.append("\n ");
non_virtual_states_list.append(line + "\n");
}
result.append(")\n ");
}
// methods and virtual states
if (!methods_list.empty()) {
result.append("(:methods\n");
result.append(methods_list);
result.append(" )\n ");
}
if (!state_methods_list.empty()) {
result.append("(:state-methods\n");
result.append(state_methods_list);
result.append(" )\n ");
}
// non-virtual states
if (!non_virtual_states_list.empty()) {
result.append("(:states\n");
result.append(non_virtual_states_list);
result.append(" )\n ");
}
result.append(")\n");
@@ -1800,7 +1802,8 @@ void inspect_top_level_for_metadata(Function& top_level,
const auto& aop = top_level.ir2.atomic_ops->ops.at(i);
const std::string as_str = aop.get()->to_string(top_level.ir2.env);
// Keep track of the last seen label so we can easily reference it if a later operation uses it
// Keep track of the last seen label so we can easily reference it if a later operation uses
// it
auto label_match = get_regex_match(as_str, std::regex("\\(set!\\s[^\\s]*\\s(L.*)\\)"));
if (!label_match.empty()) {
last_seen_label = label_match;
@@ -1843,7 +1846,24 @@ void inspect_top_level_for_metadata(Function& top_level,
if (state_name.empty()) {
continue;
}
objectFile.state_methods[type_match][method_id] = state_name;
// Ensure there are no labels between now and when the `method-set!` is actually called
bool was_another_label = false;
for (int j = i; j < (int)top_level.ir2.atomic_ops->ops.size(); j++) {
const auto& temp_aop = top_level.ir2.atomic_ops->ops.at(j);
const std::string temp_as_str = temp_aop.get()->to_string(top_level.ir2.env);
if (temp_as_str.find("call!") != std::string::npos) {
break;
}
auto temp_label_match =
get_regex_match(temp_as_str, std::regex("\\(set!\\s[^\\s]*\\s(L.*)\\)"));
if (!temp_label_match.empty()) {
was_another_label = true;
break;
}
}
if (!was_another_label) {
objectFile.state_methods[type_match][method_id] = state_name;
}
}
}
@@ -1858,7 +1878,8 @@ void inspect_top_level_for_metadata(Function& top_level,
}
// lwu t9, 16(v1) ;; [ 21] (set! t9-0 (l.wu (+ v1-10 16)))
// ;; [v1: <the etype type> ] -> [t9: (function symbol type int type)
// ;; [v1: <the etype type> ] -> [t9: (function symbol type int
// type)
const auto& aop_1 = top_level.ir2.atomic_ops->ops.at(i + 1);
if (!is_set_reg_to_load(aop_1.get(), Register(Reg::GPR, Reg::T9), 16)) {
continue;
@@ -1935,8 +1956,9 @@ std::string inspect_top_level_symbol_defines(Function& top_level,
if (as_store && as_store->addr().kind() == SimpleExpression::Kind::IDENTITY &&
as_store->addr().get_arg(0).is_sym_val()) {
auto& sym_name = as_store->addr().get_arg(0).get_str();
if (object_file_meta.already_seen_symbols.find(sym_name) ==
object_file_meta.already_seen_symbols.end()) {
const auto sym_already_seen = object_file_meta.already_seen_symbols.find(sym_name) !=
object_file_meta.already_seen_symbols.end();
if (!sym_already_seen) {
object_file_meta.already_seen_symbols.insert(sym_name);
if (dts.ts.partially_defined_type_exists(sym_name)) {
continue;
+1 -1
View File
@@ -172,7 +172,7 @@ bool convert_to_expressions(
"statement.",
f.name());
f.warnings.warning(warn);
lg::warn(warn);
lg::warn("{}", warn);
}
}
+1 -1
View File
@@ -87,7 +87,7 @@ bool rewrite_inline_asm_instructions(Form* top_level_form,
} catch (std::exception& e) {
std::string warning =
fmt::format("ASM instruction re-writing failed in {}: {}", f.name(), e.what());
lg::warn(warning);
lg::warn("{}", warning);
f.warnings.error(";; {}", warning);
return false;
}
+2 -2
View File
@@ -13,7 +13,7 @@
(z float :offset 64)
(w float :offset 96))
:method-count-assert 9
:size-assert #x10
:size-assert #x10
:flag-assert #x900000010
)
@@ -23608,7 +23608,7 @@
(define-extern nav-enemy-turn-to-face-point (function vector float none :behavior nav-enemy))
(define-extern nav-enemy-execute-jump (function none :behavior nav-enemy))
(define-extern nav-enemy-jump-land-anim (function none :behavior nav-enemy)) ;; TODO
(define-extern nav-enemy-rnd-float-range (function float float float :behavior nav-enemy))
(define-extern nav-enemy-rnd-float-range (function float float float))
(define-extern nav-enemy-common-post (function none :behavior nav-enemy)) ;; TODO not confirmed
(define-extern nav-enemy-execute-custom-jump (function int float float none :behavior nav-enemy))
(define-extern nav-enemy-initialize-custom-jump (function vector symbol float float float none :behavior nav-enemy))
+1 -1
View File
@@ -108,7 +108,7 @@
// these can be displayed in game, but makes the .fr3 files slightly larger
"extract_collision": true,
// save game textures as .png files.
"save_texture_pngs": true,
"save_texture_pngs": false,
////////////////////////////
// PATCHING OPTIONS
+157 -90
View File
@@ -7381,6 +7381,14 @@
(progress-cheats-board-tricks #x1260)
(progress-cheats-weather-bad #x1261)
(progress-cheats-weather-good #x1262)
(progress-cheats-hijack-lines #x1263)
(progress-cheats-locked #x1264)
(progress-cheats-turbo-board-unlock #x1265)
(progress-cheats-health-bars-unlock #x1266)
(progress-cheats-vehicle-health-bars-unlock #x1267)
(progress-cheats-statistics-unlock #x1268)
(progress-cheats-suck-in-all-unlock #x1269)
(progress-cheats-fast-travel-unlock #x126a)
(progress-camera-options #x1280)
(progress-camera-options-first-horz #x1281)
(progress-camera-options-first-vert #x1282)
@@ -7415,6 +7423,47 @@
(progress-shadows #x12a0)
(progress-shadows-normal #x12a1)
(progress-shadows-extended #x12a2)
(progress-error-no-resolutions #x12a3)
(progress-territory-auto #x12a4)
(progress-kill-stats #x12a5)
(progress-other-stats #x12a6)
(progress-ks-total-killed #x12a7)
(progress-ks-killed-by-jak #x12a8)
(progress-ks-killed-by-darkjak #x12a9)
(progress-ks-killed-by-daxter #x12aa)
(progress-ks-killed-by-others #x12ab)
(progress-ks-source-gun-yellow #x12ac)
(progress-ks-source-gun-red #x12ad)
(progress-ks-source-gun-blue #x12ae)
(progress-ks-source-gun-dark #x12af)
(progress-ks-source-board #x12b0)
(progress-ks-source-board-trick #x12b1)
(progress-ks-source-mech #x12b2)
(progress-ks-source-mech-bonk #x12b3)
(progress-ks-source-turret #x12b4)
(progress-ks-source-punch #x12b5)
(progress-ks-source-flop #x12b6)
(progress-ks-source-uppercut #x12b7)
(progress-ks-source-spin #x12b8)
(progress-ks-source-roll #x12b9)
(progress-ks-source-darkjak-punch #x12ba)
(progress-ks-source-darkjak-flop #x12bb)
(progress-ks-source-darkjak-uppercut #x12bc)
(progress-ks-source-darkjak-spin #x12bd)
(progress-ks-source-darkjak-roll #x12be)
(progress-ks-source-darkjak-bomb0 #x12bf)
(progress-ks-source-darkjak-bomb1 #x12c0)
(progress-ks-source-indax-punch #x12c1)
(progress-ks-source-indax-spin #x12c2)
(progress-ks-source-guard #x12c3)
(progress-ks-source-sig #x12c4)
(progress-ks-source-ashelin #x12c5)
(progress-ks-source-jinx #x12c6)
(progress-ks-source-grim #x12c7)
(progress-ks-source-mog #x12c8)
(progress-ks-source-metalhead #x12c9)
(progress-ks-source-other-bot #x12ca)
(progress-ks-source-other-enemy #x12cb)
(progress-input-options-auto-hide-cursor #x1300)
(progress-menu-reassign-binds #x1301)
(progress-reassign-binds-controller #x1302)
@@ -7437,6 +7486,7 @@
(progress-highscores-local-time #x1313)
(progress-fps-disclaimer-warning #x1314)
(progress-fps-disclaimer #x1315)
(progress-highscores-local-score #x1316)
(trick-board-none #x1320)
(trick-board-spin #x1321)
(trick-board-boost #x1322)
@@ -15775,6 +15825,24 @@
(test 22) ;; hi 64
)
;; +++game-h:knocked-type
(defenum knocked-type
:type uint8
(knocked-type-0 0)
(knocked-type-1 1)
(knocked-type-2 2)
(knocked-type-3 3)
(knocked-type-4 4) ;; what the heck is this! (its on gator, and cant trigger it for the life of me)
(knocked-type-5 5)
(knocked-type-6 6)
(knocked-type-7 7)
(knocked-type-8 8)
(knocked-type-9 9)
(knocked-type-10 10)
)
;; ---game-h:knocked-type
(declare-type touching-shapes-entry structure)
(deftype attack-info (structure)
@@ -15800,7 +15868,7 @@
(penetrate-using penetrate :offset-assert 136)
(damage float :offset-assert 144)
(shield-damage float :offset-assert 148)
(knock uint8 :offset-assert 152)
(knock knocked-type :offset-assert 152)
(test symbol :offset-assert 156)
)
:method-count-assert 12
@@ -24877,7 +24945,7 @@
(define-extern shadow-add-single-tris function)
(define-extern shadow-add-double-tris function)
(define-extern shadow-add-double-edges function)
(define-extern debug-draw-settings (function matrix none))
(define-extern debug-draw-settings (function shadow-settings symbol))
(define-extern shadow-execute (function shadow-dma-packet pointer pointer))
(define-extern shadow-vu0-upload (function none))
(define-extern shadow-execute-all (function dma-buffer none))
@@ -27728,7 +27796,7 @@
(define-extern dist-info-valid? (function collide-los-dist-info symbol)) ;;
(define-extern dist-info-append (function collide-los-dist-info vector none)) ;;
(define-extern dist-info-print (function collide-los-dist-info string object)) ;;
(define-extern los-cw-ccw (function (inline-array collide-cache-tri) vector vector float collide-los-result vector float symbol)) ;;
(define-extern los-cw-ccw (function (inline-array collide-cache-tri) vector vector float collide-los-result vector float symbol :behavior camera-slave)) ;;
(define-extern cam-los-spline-collide (function vector vector pat-surface float)) ;;
(define-extern cam-los-setup-lateral (function collide-los-result vector vector symbol :behavior camera-slave)) ;;
(define-extern cam-los-collide (function vector vector collide-los-result pat-surface symbol :behavior camera-slave)) ;;
@@ -32801,42 +32869,42 @@
(defenum enemy-flag
:type int64
:bitfield #t
(lock-focus 0)
(death-start 1)
(enable-on-active 2)
(checking-water 3)
(check-water 4)
(spawn-gem 5)
(chase-startup 6)
(attackable-backup 7)
(look-at-focus 8)
(use-notice-distance 9)
(enable-on-notice 10)
(look-at-move-dest 11)
(notice 12)
(auto-reset-penetrate 13)
(jump-check-blocked 14)
(drawn-mirrored 15)
(multi-focus 16)
(alert 17)
(victory 18)
(dangerous-backup 19)
(actor-pause-backup 20)
(trackable 21)
(called-dying 22)
(check-water-backup 23)
(no-initial-move-to-ground 24)
(cam-attack-mode 25)
(trackable-backup 26)
(enable-on-hostile 27)
(directed-ready 28)
(use-trigger 29)
(directed 30)
(dislike-combo 31)
(recover-applied-velocity 32)
(vulnerable-backup 33)
(vulnerable 34)
(recover 35)
(look-at-focus 0)
(look-at-move-dest 1)
(vulnerable 2)
(vulnerable-backup 3)
(dangerous-backup 4)
(notice 5)
(alert 6)
(auto-reset-penetrate 7)
(victory 8)
(cam-attack-mode 9)
(use-notice-distance 10)
(attackable-backup 11)
(actor-pause-backup 12)
(enable-on-notice 13)
(enable-on-active 14)
(enable-on-hostile 15)
(dislike-combo 16)
(directed 17)
(directed-ready 18)
(chase-startup 19)
(lock-focus 20)
(multi-focus 21)
(use-trigger 22)
(trackable 23)
(trackable-backup 24)
(spawn-gem 25)
(check-water 26)
(check-water-backup 27)
(checking-water 28)
(recover 29)
(recover-applied-velocity 30)
(drawn-mirrored 31)
(called-dying 32)
(no-initial-move-to-ground 33)
(jump-check-blocked 34)
(death-start 35)
(enemy-flag36 36)
(enemy-flag37 37)
(enemy-flag38 38)
@@ -32975,8 +33043,21 @@
:flag-assert #x900000018
)
(defenum enemy-jump-flags
:bitfield #t
:type uint8
(enjflag-0)
(enjflag-1)
(enjflag-2)
(enjflag-3)
(enjflag-4)
(enjflag-5)
(enjflag-6)
(enjflag-7)
)
(deftype enemy-jump-info (structure)
((flags uint8 :offset-assert 0)
((flags enemy-jump-flags :offset-assert 0)
(anim-speed float :offset-assert 4)
(hang-time time-frame :offset-assert 8)
(start-pos vector :inline :offset-assert 16)
@@ -33000,27 +33081,13 @@
:flag-assert #x90000002c
)
;; +++enemy-h:knocked-type
(defenum knocked-type
:type uint8
(knocked-type-0 0)
(knocked-type-1 1)
(knocked-type-2 2)
(knocked-type-3 3)
(knocked-type-4 4) ;; what the heck is this! (its on gator, and cant trigger it for the life of me)
(knocked-type-5 5)
(knocked-type-6 6)
(knocked-type-7 7)
)
;; ---enemy-h:knocked-type
(deftype enemy-attack-info (structure)
((attack-id uint32 :offset-assert 0)
(knocked-type knocked-type :offset-assert 4)
(blue-juggle-count uint8 :offset-assert 5)
(attacker-handle handle :offset-assert 8)
(attack-time time-frame :offset-assert 16)
(penetrate-using uint64 :offset-assert 24)
(penetrate-using penetrate :offset-assert 24)
(attacker-pos vector :inline :offset-assert 32)
(attack-direction vector :inline :offset-assert 48)
)
@@ -33114,7 +33181,7 @@
"TODO"
(_type_ process-focusable) symbol) ;; 53
(enemy-method-54 (_type_) enemy-flag) ;; 54
(track-target!
(common-post
"Does a lot of various things relating to interacting with the target
- tracks when the enemy was last drawn
- looks at the target and handles attacking
@@ -33139,8 +33206,8 @@
(enemy-method-61 (_type_ int) int :behavior enemy) ;; 61
(enemy-method-62 (_type_) none) ;; 62
(enemy-method-63 (_type_ process-focusable enemy-aware) symbol) ;; 63
(enemy-method-64 (_type_) none) ;; 64
(enemy-method-65 (_type_) none) ;; 65
(go-dormant (_type_) object) ;; 64
(go-dormant-aware (_type_) object) ;; 65
(go-ambush (_type_) object) ;; 66
(go-stare (_type_) object) ;; 67
(go-stare2 (_type_) object) ;; 68
@@ -33159,8 +33226,8 @@
(_type_ process int symbol event-message-block) object) ;; 74
(enemy-method-75 (_type_ process event-message-block) object) ;; 75
(enemy-method-76 (_type_ process event-message-block) symbol) ;; 76
(enemy-method-77 (_type_ (pointer float)) symbol) ;; 77
(enemy-method-78 (_type_ (pointer float)) symbol) ;; 78
(enemy-method-77 (_type_ enemy-knocked-info) symbol) ;; 77
(enemy-method-78 (_type_ enemy-knocked-info) symbol) ;; 78
(enemy-method-79 (_type_ int enemy-knocked-info) symbol) ;; 79
(enemy-method-80 (_type_ enemy-knocked-info) symbol) ;; 80
(enemy-method-81 (_type_) symbol) ;; 81
@@ -33174,10 +33241,7 @@
(enemy-method-89 (_type_ enemy-jump-info) symbol) ;; 89
(enemy-method-90 (_type_ int enemy-jump-info) symbol) ;; 90
(enemy-method-91 (_type_ int enemy-jump-info) none) ;; 91
(enemy-method-92
"TODO - nav-poly is a guess
@abstract"
(_type_ int nav-poly) none) ;; 92
(enemy-method-92 "@abstract" (_type_ int enemy-jump-info) none) ;; 92
(enemy-method-93 (_type_) none) ;; 93
(enemy-method-94 (_type_ vector float) symbol) ;; 94
(enemy-method-95 (_type_ vector float) symbol) ;; 95
@@ -33197,11 +33261,11 @@
(enemy-method-103 (_type_) collide-spec) ;; 103
(enemy-method-104 (_type_ process touching-shapes-entry uint) symbol :behavior process) ;; 104
(enemy-method-105 (_type_ process) enemy-flag) ;; 105
(enemy-method-106 (_type_ process object int attack-info) none :behavior enemy) ;; 106
(set-incoming-attack-info (_type_ process object penetrate attack-info) none :behavior enemy) ;; 106
(get-enemy-target
"@returns the [[process-focusable]] that the enemy is currently focusing on, or [[#f]] otherwise"
(_type_) process-focusable) ;; 107
(enemy-method-108 (_type_ enemy event-message-block) int) ;; 108
(enemy-method-108 (_type_ process-drawable event-message-block) int) ;; 108
(look-at-target!
"Logic for looking at the target that is locked on, sets some flags and adjusts the neck to look at the target if available
@param flag Reacts to [[enemy-flag::death-start]] and [[enemy-flag::enable-on-active]], see implementation for details"
@@ -33224,33 +33288,32 @@
"Common method called to initialize the enemy, typically sets up default field values and calls ancillary helper methods"
(_type_) none) ;; 115
(go-idle (_type_) none) ;; 116
(get-rand-float
(rnd-float
"@returns the result of calling [[rand-vu]]"
(_type_) float) ;; 117
(get-rand-float-range
(rnd-float-range
"@param low The lower bound of the range (inclusive)
@param high The upper bound of the range (exclusive)
@returns A random float in the specified range"
(_type_ float float) float) ;; 118
(get-rand-int
(rnd-int-count
"@param high The upper bound of the range (exclusive)
@returns a random integer in the range 0 to `high`
@see [[rand-vu]]"
(_type_ int) int) ;; 119
(enemy-method-120 "TODO" (_type_ int int) int) ;; 120
(get-rand-int-range
(rnd-bit "TODO" (_type_ int int) int) ;; 120
(rnd-int-range
"@param low The lower bound of the range (inclusive)
@param high The upper bound of the range (exclusive)
@returns A random integer in the specified range"
(_type_ int int) int) ;; 121
(rng-hit?
"TODO - not the best name
@param chance The value to compare ([[>=]]) with the result from [[rand-vu]].
(rnd-percent?
"@param chance The value to compare ([[>=]]) with the result from [[rand-vu]].
@returns If `chance` is greater than the random draw"
(_type_ float) symbol) ;; 122
(enemy-method-123 "TODO" (_type_ float) symbol) ;; 123
(rnd-go-idle? "TODO" (_type_ float) symbol) ;; 123
(enemy-method-124 "TODO" (_type_) collide-spec) ;; 124
(enemy-method-125 (_type_ collide-query collide-spec float float float) pat-surface) ;; 125
(ground-pat-set! (_type_ collide-query collide-spec float float float) pat-surface) ;; 125
(enemy-above-ground?
"@returns if the enemy is above the ground or not
@see [[above-ground?]]"
@@ -33259,12 +33322,12 @@
(enemy-method-128 (_type_ vector move-above-ground-params) none) ;; 128
(enemy-method-129 (_type_) none) ;; 129
(enemy-method-130 (_type_ float) symbol) ;; 130
(enemy-method-131 (_type_ int) uint) ;; 131
(dispose!
(penetrate-using->knocked (_type_ penetrate) knocked-type) ;; 131
(dying
"Cleans-up the enemy and any associated resources. Potentially spawns skull gems"
(_type_) none) ;; 132
(enemy-method-133 (_type_) symbol) ;; 133
(enemy-method-134 (_type_ process attack-info) process-focusable) ;; 134
(get-attacker (_type_ process attack-info) process-focusable) ;; 134
(enemy-method-135 (_type_ int) sound-id) ;; 135
(enemy-method-136 (_type_) enemy-flag) ;; 136
)
@@ -34814,7 +34877,7 @@
(unknown-byte-n1k2n3 int8 :offset 636)
(unknown-byte-m2j342 int8 :offset 637)
(unknown-byte-1ji2n3 int8 :offset 638)
(unknown-byte-n123n int8 :offset 639)
(unknown-byte-n123n uint8 :offset 639)
(state-timeout2 uint64 :offset-assert 640)
(next-warn-time time-frame :offset-assert 648)
(dest vector :inline :offset-assert 656)
@@ -38515,7 +38578,7 @@
charge
)
(:methods
(rhino-method-182 (_type_ process event-message-block) symbol) ;; 182
(hit-stomach? (_type_ process event-message-block) symbol) ;; 182
)
)
@@ -39415,7 +39478,7 @@
(hit-by-enemy-count uint16 :offset-assert 698)
(hit-by-player-count uint16 :offset-assert 700)
(notice-enemy-dist float :offset-assert 704)
(channel uint8 :offset-assert 708)
(channel gui-channel :offset-assert 708)
(focus-mode int8 :offset-assert 709)
(nav-mesh-index int8 :offset-assert 710)
(delay-too-far-check int8 :offset-assert 711)
@@ -39478,13 +39541,13 @@
(play-speech (_type_ int) none) ;; 206
(play-death-sound "Play one of our death sounds." (_type_ string) none) ;; 207
(bot-method-208 (_type_) symbol) ;; 208
(channel-active? "Is the given [[gui-channel]] active?" (_type_ uint) symbol) ;; 209
(channel-active? "Is the given [[gui-channel]] active?" (_type_ gui-channel) symbol) ;; 209
(init! "Set defaults for various fields." (_type_) none) ;; 210
(clear-speech-flags! "Clear the `playing` flag for all of our speeches." (_type_) none) ;; 211
(reset-warn-time! (_type_) none) ;; 212
(go-to-waypoint! "Start moving to the given [[bot-waypoint]]." (_type_ int symbol) object) ;; 213
(bot-method-214 (_type_) symbol) ;; 214
(skip-waypoint (_type_) none) ;; 215
(skip-waypoint (_type_) object) ;; 215
(bot-method-216 (_type_) none) ;; 216
(speech-ended? "Is the given speech active?" (_type_ int) symbol) ;; 217
(speech-playing? "Is the given speech playing?" (_type_ int) symbol) ;; 218
@@ -43427,7 +43490,7 @@
(define-extern set-countdown-to-roar (function none :behavior metalkor))
(define-extern metalkor-go-next-stage (function none :behavior metalkor))
(define-extern metalkor-setup-hit-anim (function attack-info process-drawable art-element art-element float none :behavior metalkor))
(define-extern metalkor-get-gem-tracker (function process-focusable none :behavior metalkor))
(define-extern metalkor-get-gem-tracker (function process-focusable gem-tracker :behavior metalkor))
(define-extern metalkor-handler (function process int symbol event-message-block object :behavior metalkor))
(define-extern metalkor-start-egg (function symbol :behavior metalkor))
(define-extern metalkor-check-egg (function symbol :behavior metalkor))
@@ -50579,13 +50642,15 @@
(
(ai-hook (function vehicle-guard none) :offset-assert 880)
(turret turret-control :inline :offset-assert 888)
(target-flags turret-flag :offset-assert 968)
(target-flags traffic-target-flag :offset-assert 968)
(target-in-sight-time time-frame :offset-assert 976)
(minimap connection-minimap :offset-assert 984)
(vehicle-guard-pad-k1jn23k1 uint32 :offset-assert 988)
(traffic-target-status traffic-target-status :offset-assert 992)
(pursuit-target handle :offset-assert 1000)
(vehicle-guard-pad-1kjh2nb3k1 uint32 16 :offset-assert 1008)
(vehicle-guard-pad-0jkfdjslf uint32 4 :offset-assert 1008)
(vehicle-guard-vector0341413 vector :inline :offset-assert 1024)
(vehicle-guard-pad-1kjh2nb3k1 uint32 8 :offset-assert 1040)
(lod2 symbol :offset-assert 1072)
)
:method-count-assert 159
@@ -50616,7 +50681,7 @@
(define-extern vehicle-draw-beam (function sparticle-launcher vector vector object symbol none))
(define-extern vehicle-draw-laser-spot (function vector vector symbol none))
(define-extern vehicle-draw-laser (function vector vector none))
(define-extern vehicle-guard-choose-branch (function vehicle-controller vehicle nav-branch))
(define-extern vehicle-guard-choose-branch (function vehicle-controller vehicle-guard nav-branch))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; transport ;;
@@ -52949,7 +53014,9 @@
(deftype mechblock (process-drawable)
((root collide-shape-moving :override)
(origin vector :inline :offset-assert 208)
(drop-point vector :inline :offset 256)
(unknown-quat quaternion :inline :offset-assert 224)
(unknown-vector vector :inline :offset-assert 240)
(drop-point vector :inline :offset-assert 256)
(allow-drag? symbol :offset-assert 272)
(reset-on-land? symbol :offset-assert 276)
(hit-something? symbol :offset-assert 280)
@@ -53473,4 +53540,4 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-extern *default-envmap-shader* adgif-shader)
(define-extern *generic-envmap-texture* texture)
(define-extern *generic-envmap-texture* texture)
@@ -654,7 +654,7 @@
"collectables": [[69, "(function part-tracker vector)"]],
"mech-states": [[50, "(function none :behavior target)"]],
"target-mech": [
[7, "(function none :behavior target)"],
[7, "(function none :behavior manipy)"],
[8, "(function none :behavior mech)"],
[9, "(function none :behavior manipy)"],
[18, "(function surface object surface int none :behavior target)"],
@@ -1227,8 +1227,8 @@
"castle-baron": [[7, "(function collectable none)"]],
"metalkor-extras": [[65, "(function vector :behavior metalkor-shot)"]],
"metalkor-setup": [
[1, "(function gem-tracker none)"],
[2, "(function gem-tracker none)"]
[1, "(function gem-tracker symbol)"],
[2, "(function gem-tracker symbol)"]
],
"meet-brutter": [
[0, "(function none :behavior task-manager)"],
@@ -4309,7 +4309,8 @@
"(method 74 enemy)": [
[50, "s3", "process-drawable"],
[94, "v1", "attack-info"],
[[111, 205], "s2", "attack-info"],
[[111, 137], "s2", "attack-info"],
[204, "s2", "attack-info"],
[554, "a0", "vector"]
],
"(method 56 enemy)": [[[0, 6], "v1", "attack-info"]],
@@ -4537,7 +4538,7 @@
],
"(method 23 joint-exploder)": [[26, "v1", "process-drawable"]],
"(method 28 joint-exploder)": [[[0, 250], "s5", "joint-exploder-list"]],
"joint-exploder-joint-callback": [[3, "s4", "joint-exploder"]],
"joint-exploder-joint-callback": [[[3, 25], "s4", "joint-exploder"]],
"(event idle fort-trap-door)": [[4, "v1", "attack-info"]],
"(code idle hide-light)": [[10, "v1", "art-joint-anim"]],
"(event impact turret-shot)": [[11, "s4", "process-drawable"]],
@@ -4968,10 +4969,6 @@
],
"(enter target-mech-carry-hit-ground)": [[3, "v0", "sound-rpc-set-param"]],
"(event target-mech-grab)": [[24, "a0", "process"]],
"(anon-function 7 target-mech)": [
[32, "a0", "joint-mod-ik"],
[26, "a0", "(array joint-mod-ik)"]
],
"(enter target-mech-hit-ground)": [[3, "v0", "sound-rpc-set-param"]],
"(exit target-mech-carry-drag)": [
[11, "v0", "sound-rpc-set-param"],
@@ -7064,7 +7061,7 @@
],
"(method 9 city-level-info)": [[387, "v1", "nav-segment"]],
"(method 67 traffic-engine)": [
[[137, 183], "s0", "crimson-guard"],
[[137, 185], "s0", "crimson-guard"],
[[44, 86], "a3", "vehicle"]
],
"set-eye-draw-flag": [[20, "s5", "eye-control"]],
@@ -10155,5 +10152,8 @@
"race-birth-func-texture-position-word": [
[10, "v1", "(array int32)"],
[1, "v1", "(array int32)"]
]
],
"(method 206 hal)": [[32, "a2", "bot"]],
"(method 209 hal)": [[32, "v1", "bot"]],
"(method 220 hal)": [[29, "v1", "bot"]]
}
+25 -1
View File
@@ -4228,7 +4228,9 @@
"vars": {
"v1-3": "shadow-settings",
"a3-0": "shadow-geo",
"t0-0": "dist"
"t0-0": "dist",
"a3-2": ["shadow-pack1", "shadow-dma-packet"],
"t2-11": ["shadow-pack2", "shadow-dma-packet"]
}
},
"progress-selected": {
@@ -4637,5 +4639,27 @@
"vars": {
"t1-3": ["imp-sound", "sound-name"]
}
},
"(method 9 menu-secret-option)": {
"vars": {
"s5-1": "hero?",
"s3-0": "min-item",
"s2-0": "max-item",
"s5-2": "scroll-sound?",
"v1-74": "item",
"a0-54": "flag",
"a1-9": "on-off?"
}
},
"(method 10 menu-unlocked-menu-option)": {
"vars": {
"s5-0": "secrets",
"f30-0": "alpha"
}
},
"joint-exploder-joint-callback": {
"vars": {
"s4-0": ["exploder", "joint-exploder"]
}
}
}
File diff suppressed because it is too large. Load diff
+10 -1
View File
@@ -80,7 +80,7 @@
////////////////////////////
// CONFIG FILES
////////////////////////////
"type_casts_file": "decompiler/config/jak3/ntsc_v1/type_casts.jsonc",
"anonymous_function_types_file": "decompiler/config/jak3/ntsc_v1/anonymous_function_types.jsonc",
"var_names_file": "decompiler/config/jak3/ntsc_v1/var_names.jsonc",
@@ -125,5 +125,14 @@
"apply_patches": true,
// what to patch an object to and what the patch file is
"object_patches": {
},
"version_overrides": {
"ntsc_v1": {},
"pal": {
"game_name": "jak3_pal",
"expected_elf_name": "SCES_524.60",
"is_pal": true,
"object_patches": {}
}
}
}
@@ -1 +1 @@
{}
{}
+10 -2
View File
@@ -126,6 +126,7 @@
// will be less picky about types related to pairs.
"pair_functions_by_name": [
"ref",
"ref&",
"(method 4 pair)",
"last",
"member",
@@ -755,14 +756,21 @@
"generic-warp-dest",
"generic-warp-envmap-dest",
"generic-no-light-proc"
],
"mips2c_jump_table_functions": {},
// there are some missing textures. I don't know what the game actually does here.
// the format for entries is [level, tpage, index]
"missing_textures": [["lfac", 0, 0], ["ltow", 0, 0], ["lcit", 0, 0], ["pow", 0, 0], ["wasintro", 0, 0], ["lfacctyb", 0, 0], ["intpfall", 0, 0]],
"missing_textures": [
["lfac", 0, 0],
["ltow", 0, 0],
["lcit", 0, 0],
["pow", 0, 0],
["wasintro", 0, 0],
["lfacctyb", 0, 0],
["intpfall", 0, 0]
],
// some object files have garbage pad data at the end which makes the decompiler
// assume they must be different files, such as the art group for orb-cache-top.
+2 -2
View File
@@ -7,7 +7,7 @@
// most objects are part of CGO/DGO files (both go in dgo_names). This includes levels and the engine
// the DGOs will be processed in this order. Usually it's best to have KERNEL, ENGINE, then the levels when
// you want to run on the entire game.
"dgo_names":[
"dgo_names": [
//"CGO/ART.CGO",
"CGO/KERNEL.CGO",
// "CGO/ENGINE.CGO",
@@ -285,7 +285,7 @@
"DGO/LCTYPROT.DGO",
"DGO/DESHOVER.DGO",
"DGO/DESBOSS2.DGO"
],
],
// some objects are part of STR files (streaming data).
"str_file_names": [],
@@ -1 +1 @@
{}
{}
@@ -1 +1 @@
{}
{}
@@ -1 +1,37 @@
{}
{
"(method 2 array)": [
[23, "gp", "(array int32)"],
[43, "gp", "(array uint32)"],
[63, "gp", "(array int64)"],
[83, "gp", "(array uint64)"],
[102, "gp", "(array int8)"],
[121, "gp", "(array uint8)"],
[141, "gp", "(array int16)"],
[161, "gp", "(array uint16)"],
[186, "gp", "(array uint128)"],
[204, "gp", "(array int32)"],
[223, "gp", "(array float)"],
[232, "gp", "(array float)"],
[249, "gp", "(array basic)"],
[258, "gp", "(array basic)"]
],
"(method 3 array)": [
[51, "gp", "(array int32)"],
[69, "gp", "(array uint32)"],
[87, "gp", "(array int64)"],
[105, "gp", "(array uint64)"],
[122, "gp", "(array int8)"],
[139, "gp", "(array int8)"],
[157, "gp", "(array int16)"],
[175, "gp", "(array uint16)"],
[198, "gp", "(array uint128)"],
[214, "gp", "(array int32)"],
[233, "gp", "(array float)"],
[250, "gp", "(array basic)"]
],
"(method 0 cpu-thread)": [[[0, 35], "v0", "cpu-thread"]],
"(method 0 process)": [
// [11, "a0", "int"],
// [[12, 45], "v0", "process"]
]
}
@@ -1 +1 @@
{}
{}
+15 -12
View File
@@ -133,20 +133,23 @@ void TextureDB::replace_textures(const fs::path& path) {
fs::path base_path(path);
for (auto& tex : textures) {
fs::path full_path = base_path / tpage_names.at(tex.second.page) / (tex.second.name + ".png");
if (fs::exists(full_path)) {
lg::info("Replacing {}", full_path.string().c_str());
int w, h;
auto data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4); // rgba channels
if (!data) {
lg::warn("failed to load PNG file: {}", full_path.string().c_str());
if (!fs::exists(full_path)) {
full_path = base_path / "_all" / (tex.second.name + ".png");
if (!fs::exists(full_path))
continue;
}
tex.second.rgba_bytes.resize(w * h);
memcpy(tex.second.rgba_bytes.data(), data, w * h * 4);
tex.second.w = w;
tex.second.h = h;
stbi_image_free(data);
}
lg::info("Replacing {}", tpage_names.at(tex.second.page) + "/" + (tex.second.name));
int w, h;
auto data = stbi_load(full_path.string().c_str(), &w, &h, 0, 4); // rgba channels
if (!data) {
lg::warn("failed to load PNG file: {}", full_path.string().c_str());
continue;
}
tex.second.rgba_bytes.resize(w * h);
memcpy(tex.second.rgba_bytes.data(), data, w * h * 4);
tex.second.w = w;
tex.second.h = h;
stbi_image_free(data);
}
}
@@ -1,5 +1,6 @@
#include "extract_collide_frags.h"
#include "common/log/log.h"
#include "common/util/FileUtil.h"
namespace decompiler {
@@ -230,6 +231,7 @@ void set_vertices_for_tri(tfrag3::CollisionMesh::Vertex* out, const math::Vector
void extract_collide_frags(const level_tools::DrawableTreeCollideFragment* tree,
const std::vector<const level_tools::DrawableTreeInstanceTie*>& ties,
const Config& config,
const std::string& debug_name,
tfrag3::Level& out,
bool dump_level) {
@@ -260,8 +262,8 @@ void extract_collide_frags(const level_tools::DrawableTreeCollideFragment* tree,
if (dump_level) {
auto debug_out = debug_dump_to_obj(all_frags);
auto file_path =
file_util::get_file_path({"debug_out", fmt::format("collide-{}.obj", debug_name)});
auto file_path = file_util::get_file_path(
{fmt::format("debug_out/{}", config.game_name), fmt::format("collide-{}.obj", debug_name)});
file_util::create_dir_if_needed_for_file(file_path);
file_util::write_text_file(file_path, debug_out);
}
@@ -408,10 +410,40 @@ void handle_collide_fragment(const TypedRef& collide_fragment,
}
}
std::string debug_dump_to_obj(const std::vector<tfrag3::CollisionMesh::Vertex>& verts_in) {
std::vector<math::Vector4f> verts;
std::vector<math::Vector<u32, 3>> faces;
for (auto& v : verts_in) {
verts.emplace_back(v.x / 4096.0, v.y / 4096.0, v.z / 4096.0, 1.0);
u32 v_len = verts.size();
if (v_len % 3 == 0) {
// add face from last 3 vertices
faces.emplace_back(v_len - 2, v_len - 1, v_len);
}
}
std::string result;
for (auto& vert : verts) {
result += fmt::format("v {} {} {}\n", vert.x(), vert.y(), vert.z());
}
for (auto& face : faces) {
result += fmt::format("f {}/{} {}/{} {}/{}\n", face.x(), face.x(), face.y(), face.y(), face.z(),
face.z());
}
return result;
}
void extract_collide_frags(const level_tools::CollideHash& chash,
const std::vector<const level_tools::DrawableTreeInstanceTie*>& ties,
const Config& config,
const std::string& debug_name,
const decompiler::DecompilerTypeSystem& dts,
tfrag3::Level& out) {
tfrag3::Level& out,
bool dump_level) {
// We need to find all collide-hash-fragments, but we can't just scan through the entire file.
// for collide-hash-fragments, we need to figure out which TIEs they belong to, to apply the
// instance transformation matrix.
@@ -474,5 +506,15 @@ void extract_collide_frags(const level_tools::CollideHash& chash,
}
}
}
if (dump_level) {
// out.collision.vertices every 3 vertices make a face, so it duplicates vertices in many cases
// for now debug_dump_to_obj isn't smart and doesn't hash these to save space or anything
auto debug_out = debug_dump_to_obj(out.collision.vertices);
auto file_path = file_util::get_file_path(
{fmt::format("debug_out/{}", config.game_name), fmt::format("collide-{}.obj", debug_name)});
file_util::create_dir_if_needed_for_file(file_path);
file_util::write_text_file(file_path, debug_out);
}
}
} // namespace decompiler
@@ -8,13 +8,17 @@ namespace decompiler {
void extract_collide_frags(const level_tools::DrawableTreeCollideFragment* tree,
const std::vector<const level_tools::DrawableTreeInstanceTie*>& ties,
const Config& config,
const std::string& debug_name,
tfrag3::Level& out,
bool dump_level);
void extract_collide_frags(const level_tools::CollideHash& chash,
const std::vector<const level_tools::DrawableTreeInstanceTie*>& ties,
const Config& config,
const std::string& debug_name,
const decompiler::DecompilerTypeSystem& dts,
tfrag3::Level& out);
tfrag3::Level& out,
bool dump_level);
} // namespace decompiler
} // namespace decompiler
+7 -5
View File
@@ -159,9 +159,10 @@ std::vector<level_tools::TextureRemap> extract_tex_remap(const ObjectFileDB& db,
level_tools::BspHeader extract_bsp_from_level(const ObjectFileDB& db,
const TextureDB& tex_db,
const std::string& dgo_name,
const DecompileHacks& hacks,
const Config& config,
bool extract_collision,
tfrag3::Level& level_data) {
auto hacks = config.hacks;
auto bsp_rec = get_bsp_file(db.obj_files_by_dgo.at(dgo_name), dgo_name);
if (!bsp_rec) {
lg::warn("Skipping extract for {} because the BSP file was not found", dgo_name);
@@ -236,8 +237,8 @@ level_tools::BspHeader extract_bsp_from_level(const ObjectFileDB& db,
ASSERT(as_collide_frags);
ASSERT(!got_collide);
got_collide = true;
extract_collide_frags(as_collide_frags, all_ties, fmt::format("{}-{}-collide", dgo_name, i++),
level_data, false);
extract_collide_frags(as_collide_frags, all_ties, config,
fmt::format("{}-{}-collide", dgo_name, i++), level_data, false);
} else {
lg::print(" unsupported tree {}\n", draw_tree->my_type());
}
@@ -245,7 +246,8 @@ level_tools::BspHeader extract_bsp_from_level(const ObjectFileDB& db,
if (bsp_header.collide_hash.num_items) {
ASSERT(!got_collide);
extract_collide_frags(bsp_header.collide_hash, all_ties, db.dts, level_data);
extract_collide_frags(bsp_header.collide_hash, all_ties, config,
fmt::format("{}-{}-collide", dgo_name, i++), db.dts, level_data, false);
}
level_data.level_name = level_name;
@@ -348,7 +350,7 @@ void extract_from_level(const ObjectFileDB& db,
// the bsp header file data
auto bsp_header =
extract_bsp_from_level(db, tex_db, dgo_name, config.hacks, extract_collision, level_data);
extract_bsp_from_level(db, tex_db, dgo_name, config, extract_collision, level_data);
extract_art_groups_from_level(db, tex_db, bsp_header.texture_remap_table, dgo_name, level_data,
art_group_data);
+14 -2
View File
@@ -424,7 +424,8 @@ void make_draws(tfrag3::Level& lev,
std::vector<std::vector<u32>> indices_regrouped_by_draw;
std::unordered_map<u32, std::vector<u32>> static_draws_by_tex;
size_t global_vert_counter = 0;
for (auto& proto : protos) {
for (u32 proto_idx = 0; proto_idx < protos.size(); proto_idx++) {
auto& proto = protos[proto_idx];
// packed_vert_indices[frag][draw] = {start, end}
std::vector<std::vector<std::pair<int, int>>> packed_vert_indices;
@@ -509,7 +510,9 @@ void make_draws(tfrag3::Level& lev,
std::vector<u32>* verts_to_add_to = nullptr;
if (existing_draws_in_tex != static_draws_by_tex.end()) {
for (auto idx : existing_draws_in_tex->second) {
if (tree_out.static_draws.at(idx).mode == mode) {
auto& candidate_draw_out = tree_out.static_draws.at(idx);
if (candidate_draw_out.mode == mode && (!tree_out.has_per_proto_visibility_toggle ||
candidate_draw_out.proto_idx == proto_idx)) {
draw_to_add_to = &tree_out.static_draws[idx];
verts_to_add_to = &indices_regrouped_by_draw[idx];
}
@@ -523,6 +526,9 @@ void make_draws(tfrag3::Level& lev,
draw_to_add_to = &tree_out.static_draws.back();
draw_to_add_to->mode = mode;
draw_to_add_to->tree_tex_id = idx_in_lev_data;
if (tree_out.has_per_proto_visibility_toggle) {
draw_to_add_to->proto_idx = proto_idx;
}
verts_to_add_to = &indices_regrouped_by_draw.emplace_back();
}
@@ -573,10 +579,16 @@ void extract_shrub(const shrub_types::DrawableTreeInstanceShrub* tree,
bool dump_level,
GameVersion version) {
auto& tree_out = out.shrub_trees.emplace_back();
if (version > GameVersion::Jak1) {
tree_out.has_per_proto_visibility_toggle = true;
}
auto& protos = tree->info.prototype_inline_array_shrub;
std::vector<ShrubProtoInfo> proto_info;
for (auto& proto : protos.data) {
proto_info.push_back(extract_proto(proto, tex_db, map, version));
tree_out.proto_names.push_back(proto.name);
}
for (auto& arr : tree->discovered_arrays) {
+1 -1
View File
@@ -1368,7 +1368,7 @@ void types2_for_add(types2::Type& type_out,
}
}
if (env.version == GameVersion::Jak2 && tc(dts, TypeSpec("symbol"), arg1_type) &&
if (env.version >= GameVersion::Jak2 && tc(dts, TypeSpec("symbol"), arg1_type) &&
is_int_or_uint(dts, arg0_type)) {
if (arg0_type.is_integer_constant(jak2::SYM_TO_STRING_OFFSET)) {
// symbol -> GOAL String
+23
View File
@@ -115,6 +115,29 @@ void DecompilerTypeSystem::parse_type_defs(const std::vector<std::string>& file_
});
}
void DecompilerTypeSystem::parse_enum_defs(const std::vector<std::string>& file_path) {
auto read = m_reader.read_from_file(file_path);
auto& data = cdr(read);
for_each_in_list(data, [&](goos::Object& o) {
try {
if (car(o).as_symbol() == "defenum") {
auto symbol_metadata = DefinitionMetadata();
parse_defenum(cdr(o), &ts, &symbol_metadata);
symbol_metadata.definition_info = m_reader.db.get_short_info_for(o);
auto* rest = &cdr(o);
const auto& enum_name = car(*rest).as_symbol();
symbol_metadata_map[enum_name.name_ptr] = symbol_metadata;
// so far, enums are never runtime types so there's no symbol for them.
}
} catch (std::exception& e) {
auto info = m_reader.db.get_info_for(o);
lg::error("{} when parsing decompiler type file:{}", e.what(), info);
throw;
}
});
}
TypeSpec DecompilerTypeSystem::parse_type_spec(const std::string& str) const {
auto read = m_reader.read_from_string(str);
auto data = cdr(read);
+1
View File
@@ -56,6 +56,7 @@ class DecompilerTypeSystem {
const TypeSpec& type_spec,
const DefinitionMetadata& symbol_metadata);
void parse_type_defs(const std::vector<std::string>& file_path);
void parse_enum_defs(const std::vector<std::string>& file_path);
TypeSpec parse_type_spec(const std::string& str) const;
void add_type_flags(const std::string& name, u64 flags);
void add_type_parent(const std::string& child, const std::string& parent);
+3 -1
View File
@@ -13,7 +13,9 @@ namespace decompiler {
bool allowable_base_type_for_symbol_to_string(const TypeSpec& ts);
constexpr PerGameVersion<int> SYMBOL_TO_STRING_MEM_OFFSET_DECOMP = {
8167 * 8, jak2::SYM_TO_STRING_OFFSET, jak3::SYM_TO_STRING_OFFSET};
8167 * 8, jak2::SYM_TO_STRING_OFFSET,
-99999, // not supported this way!
};
constexpr PerGameVersion<int> OFFSET_OF_NEXT_STATE_STORE = {72, 64, 68};
} // namespace decompiler
+13 -2
View File
@@ -121,6 +121,19 @@ set(RUNTIME_SOURCE
kernel/jak2/kprint.cpp
kernel/jak2/kscheme.cpp
kernel/jak2/ksound.cpp
kernel/jak3/fileio.cpp
kernel/jak3/kboot.cpp
kernel/jak3/kdgo.cpp
kernel/jak3/kdsnetm.cpp
kernel/jak3/klink.cpp
kernel/jak3/klisten.cpp
kernel/jak3/kmachine.cpp
kernel/jak3/kmalloc.cpp
kernel/jak3/kmemcard.cpp
kernel/jak3/kprint.cpp
kernel/jak3/kscheme.cpp
kernel/jak3/ksocket.cpp
kernel/jak3/ksound.cpp
mips2c/jak1_functions/bones.cpp
mips2c/jak1_functions/collide_cache.cpp
mips2c/jak1_functions/collide_edge_grab.cpp
@@ -234,8 +247,6 @@ set(RUNTIME_SOURCE
system/IOP_Kernel.cpp
system/iop_thread.cpp
system/SystemThread.cpp
system/vm/dmac.cpp
system/vm/vm.cpp
tools/filter_menu/filter_menu.cpp
tools/subtitle_editor/subtitle_editor_db.cpp
tools/subtitle_editor/subtitle_editor_repl_client.cpp
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,243 @@
{
"cutscenes": {},
"other": {}
"other": {
"erol002": {
"lines": [
{
"frame_end": 100,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "errol"
},
{
"frame_end": 162,
"frame_start": 101,
"merge": false,
"offscreen": true,
"speaker": "errol"
},
{
"frame_end": 277,
"frame_start": 163,
"merge": false,
"offscreen": true,
"speaker": "errol"
},
{
"frame_end": 348,
"frame_start": 278,
"merge": false,
"offscreen": true,
"speaker": "errol"
},
{
"frame_end": 425,
"frame_start": 349,
"merge": false,
"offscreen": true,
"speaker": "errol"
},
{
"frame_end": 588,
"frame_start": 426,
"merge": false,
"offscreen": true,
"speaker": "errol"
},
{
"frame_end": 815,
"frame_start": 589,
"merge": false,
"offscreen": true,
"speaker": "errol"
}
]
},
"jakfall": {
"lines": [
{
"frame_end": 93,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "jak"
}
]
},
"mtn-plat-buried-rocks-a": {
"lines": [
{
"frame_end": 168,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"mtn-step-plat-rocks-a": {
"lines": [
{
"frame_end": 88,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"mtn-step-plat-rocks-b": {
"lines": [
{
"frame_end": 92,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"mtn-step-plat-rocks-c": {
"lines": [
{
"frame_end": 80,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"sam001": {
"lines": [
{
"frame_end": 120,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "youngsamos"
},
{
"frame_end": 273,
"frame_start": 121,
"merge": false,
"offscreen": true,
"speaker": "youngsamos"
},
{
"frame_end": 423,
"frame_start": 274,
"merge": false,
"offscreen": true,
"speaker": "youngsamos"
},
{
"frame_end": 479,
"frame_start": 424,
"merge": false,
"offscreen": true,
"speaker": "youngsamos"
}
]
},
"sigc001": {
"lines": [
{
"frame_end": 140,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "sig"
}
]
},
"sigc073": {
"lines": [
{
"frame_end": 52,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "sig"
},
{
"frame_end": 151,
"frame_start": 53,
"merge": false,
"offscreen": true,
"speaker": "sig"
}
]
},
"tombplta": {
"lines": [
{
"frame_end": 129,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"tombpltb": {
"lines": [
{
"frame_end": 350,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"wtrdrain": {
"lines": [
{
"frame_end": 163,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"wtrfill": {
"lines": [
{
"frame_end": 165,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "none"
}
]
},
"ys002": {
"lines": [
{
"frame_end": 55,
"frame_start": 0,
"merge": false,
"offscreen": true,
"speaker": "youngsamos"
},
{
"frame_end": 93,
"frame_start": 56,
"merge": false,
"offscreen": true,
"speaker": "samos"
},
{
"frame_end": 153,
"frame_start": 94,
"merge": false,
"offscreen": true,
"speaker": "samos"
}
]
}
}
}
@@ -92,7 +92,7 @@
"1251": "Enemy Health Bars",
"1252": "Vehicle Health Bars",
"1253": "Vehicle Invulnerability",
"1254": "Statistics Page",
"1254": "Statistics",
"1255": "Automatically Grab Collectables",
"1256": "Music Player",
"1257": "No Textures Mode",
@@ -107,6 +107,14 @@
"1260": "JET-Board Trick Display",
"1261": "Bad Weather",
"1262": "Nice Weather",
"1263": "Vehicle Hijack Voice Lines",
"1264": "Locked",
"1265": "Hit all 3 valves and find Mar's Statue in \"~S\" in under ~D seconds",
"1266": "Reduce Haven City's population count by ~D",
"1267": "Reduce Haven City's vehicle count by ~D",
"1268": "Hunt every species of Metal Head",
"1269": "Use the JET-Board to break open containers",
"126a": "Transport the Rift Rider while leaving Samos and Young Samos unscathed",
"1280": "Camera Options",
"1281": "Left/Right (1st Person)",
"1282": "Up/Down (1st Person)",
@@ -142,6 +150,40 @@
"12a0": "Object Shadows",
"12a1": "Normal",
"12a2": "Extended",
"12a3": "No valid resolutions found.",
"12a4": "Automatic",
"12a5": "Bestiary",
"12a6": "Other Statistics",
"12a7": "Total Killed",
"12a8": "Killed by Jak",
"12a9": "Killed by Dark Jak",
"12aa": "Killed by Daxter",
"12ab": "Killed by Others",
"12ac": "Blaster",
"12ad": "Scatter Gun",
"12ae": "Vulcan Fury",
"12af": "Peacemaker",
"12b0": "JET-Board",
"12b1": "JET-Board Trick",
"12b2": "Titan Suit Punch",
"12b3": "Titan Suit Body",
"12b4": "Gunpod",
"12b5": "Punch",
"12b6": "Flop",
"12b7": "Uppercut",
"12b8": "Spin",
"12b9": "Roll",
"12bf": "Dark Bomb",
"12c0": "Dark Blast",
"12c3": "Krimzon Guard",
"12c4": "Sig",
"12c5": "Ashelin",
"12c6": "Jinx",
"12c7": "Grim",
"12c8": "Mog",
"12c9": "Metal Heads",
"12ca": "Other Friends",
"12cb": "Other Enemies",
"1300": "Auto Hide Cursor",
"1301": "Reassign Binds",
"1302": "Controller Binds",
@@ -164,6 +206,7 @@
"1313": "Local Time",
"1314": "Warning!",
"1315": "This setting is highly experimental. When not played at 60 frames per second, visual and gameplay issues may arise as a result.",
"1316": "Local Score",
"1320": "None",
"1321": "Spin",
"1322": "Boost",
@@ -1,6 +1,6 @@
{
"1a3": "Veuillez ne pas retirer ou insérer de périphériques, éteindre votre système ou arreter le jeu",
"1b5": "Lorsque cette icône est à l'écran, ne retirez pas ou n'insérez aucun périphérique, n'éteignez pas votre système et n'arretez pas le jeu",
"1a3": "Sauvegarde en cours. Veuillez à ne retirer ou n'insérer aucun périphérique, ni éteindre votre système ou arrêter le jeu.",
"1b5": "Lorsque cette icône est à l'écran, ne retirez ou n'insérez aucun périphérique, ni éteindre votre système ou arrêter le jeu.",
"1100": "Pas dans une mission",
"1101": "Jouer une mission bonus",
"1102": "Pulvérisator (Entrainement)",
@@ -10,84 +10,84 @@
"1106": "Le jeu d'Onin",
"1107": "Chasse-taupe",
"1200": "Mode d'affichage",
"1201": "Fenetré",
"1201": "Fenêtré",
"1202": "Plein écran",
"1203": "Sans bordures",
"1204": "Auto",
"1203": "Sans bordure",
"1204": "Adapté à la fenêtre",
"1205": "Personnalisé",
"1206": "4x3",
"1207": "16x9",
"1207": "16x9 (4x3 zoomé en vertical)",
"1208": "Choisissez le rapport entre la largeur/hauteur",
"1209": "Appuyer sur <PAD_X> pour confirmer et quitter.",
"120a": "Appuyer <PAD_CIRCLE> pour confirmer et quitter.",
"1209": "Appuyer sur <PAD_X> pour confirmer.",
"120a": "Appuyer <PAD_CIRCLE> pour confirmer.",
"120b": "Le ratio ne doit pas être inférieur à 4x3!",
"120c": "Lecteur de musique",
"120c": "Musiques",
"120d": "Synchronisation Verticale",
"120e": "Langue du texte",
"120f": "Secrets OpenGoal",
"1210": "Largeur",
"1211": "Hauteur",
"1212": "??????????",
"1213": "Lecture en cours...",
"1214": "No Track",
"1215": "Défaut",
"1216": "Morph Gun",
"1217": "Jet Board",
"1218": "Titan Suit",
"1219": "Dark Jak",
"121a": "Vehicule",
"1212": "Non débloqué",
"1213": "Lecture en cours :",
"1214": "Pas de musique",
"1215": "Normal",
"1216": "Avec une arme",
"1217": "Sur le Jet Board",
"1218": "Dans la Titanocombi",
"1219": "En Dark Jak",
"121a": "Dans un Véhicule",
"121b": "Danger",
"121c": "Sans",
"121c": "Non",
"121d": "Faible",
"121e": "Moyen",
"121f": "Élevé",
"1220": "Exploration d'Abriville",
"1220": "Abriville",
"1221": "Course-poursuite",
"1222": "Chasse-taupes (Alt)",
"1223": "Le tombeau de Mar",
"1222": "Inutilisé (Jak 3)",
"1223": "Araignée géante",
"1224": "Le défi d'Onin",
"1225": "Métal Kor",
"1225": "Praxis / Métal Kor",
"1226": "Combat contre Krew",
"1227": "Combat contre le Baron",
"1228": "Bouncing Boulders",
"1229": "Eco explosive",
"1227": "Praxis au tombeau",
"1228": "Éboulement",
"1229": "Bombes plasmites",
"122a": "Tank de la forteresse",
"122b": "Station de pompage",
"122c": "Protéger Sig",
"122d": "Mine à ciel ouvert",
"122e": "Forêt d'Abriville",
"122f": "Dragons de la foret",
"122e": "Abriforêt",
"122f": "Abriforêt 2 / Crédits",
"1230": "La forteresse",
"1231": "Fuite",
"1232": "Temple de la montagne",
"1233": "Chasse-taupe",
"1234": "Palais du baron Praxis",
"1231": "La forteresse 2",
"1232": "Temple montagne",
"1233": "Rhinocéros",
"1234": "Palais",
"1235": "Usine d'armes",
"1236": "Course d'arène",
"1236": "Les courses",
"1237": "Ville morte",
"1238": "Taille de la fenetre",
"1239": "Sélectionnez la taille de la fenetre",
"1238": "Taille de la fenêtre",
"1239": "Sélectionnez une taille",
"123a": "Résolution du jeu",
"123b": "Sélectionnez la résolution du jeu",
"123c": "Niveau des détails (arrière-plan)",
"123d": "Niveau des détails (premier plan)",
"123c": "Niveau des textures",
"123d": "Distance d'affichage des unités",
"123f": "Nom de l'orateur",
"1240": "Jamais",
"1241": "Hors écran",
"1242": "Toujours",
"1243": "Game Territory",
"1244": "America (SCEA)",
"1243": "Territoire de jeu",
"1244": "Amérique (SCEA)",
"1245": "Europe (SCEE)",
"1246": "Japan (SCEI)",
"1247": "Korea (SCEK)",
"1248": "MSAA",
"1246": "Japon (SCEI)",
"1247": "Corée (SCEK)",
"1248": "Anti-Aliasing",
"1249": "~DX",
"124a": "Options de la LED du contrôleur",
"124b": "Afficher l'état du joueur",
"124c": "Afficher le niveau de santé",
"124d": "Désactiver la sauvegarde automatique",
"124e": "Sauvegarde automatique désactivée",
"124f": "Etes-vous sûr de vouloir désactiver la sauvegarde automatique?",
"124f": "Êtes-vous sûr de vouloir désactiver la sauvegarde automatique ?",
"1250": "Turbo Jet Board dans Abriville",
"1251": "Barres de santé des ennemis",
"1252": "Barres de santé des véhicules",
@@ -104,24 +104,24 @@
"125d": "Suivi des orbes",
"125e": "Heure réelle de la journée",
"125f": "Ruines d'Abriville",
"1260": "Afficher les figures de Jet Board",
"1260": "Afficher les figures du Jet Board",
"1261": "Mauvais temps",
"1262": "Beau temps",
"1280": "Options de caméra",
"1281": "Gauche/Droite (1ere Personne)",
"1282": "Haut/Bas (1ere Personne)",
"1283": "Gauche/Droite (3eme Personne)",
"1284": "Haut/Bas (3eme Personne)",
"1281": "Horizontal (1ère Personne)",
"1282": "Vertical (1ère Personne)",
"1283": "Horizontal (3ème Personne)",
"1284": "Vertical (3ème Personne)",
"1285": "Réinitialiser les paramètres par défaut",
"1286": "Normale",
"1287": "Inversée",
"1288": "Élimination des particules",
"1289": "Discord Rich-Presence",
"128a": "Défaut",
"1289": "Rich Presence sur Discord",
"128a": "Par défaut",
"128b": "Bas",
"128c": "Haut",
"128d": "Crédits",
"128e": "Fréquence d'images",
"128e": "Fréquence d'images (FPS)",
"128f": "Autres",
"1290": "Mode speedrun",
"1291": "Options d'entrée",
@@ -129,7 +129,7 @@
"1293": "Options de la manette",
"1294": "Sélectionnez la manette",
"1295": "Zone morte",
"1296": "Ignorer si la fenetre est en arrière-plan",
"1296": "Pause en arrière-plan",
"1297": "Utiliser la LED pour la santé",
"1298": "Utiliser la LED pour d'autres états",
"1299": "Activer le clavier",
@@ -139,9 +139,9 @@
"129d": "Sensibilité horizontale",
"129e": "Sensibilité verticale",
"129f": "Déplacements du personnage",
"12a0": "Object Shadows",
"12a0": "Ombres des objets",
"12a1": "Normal",
"12a2": "Extended",
"12a2": "Élevées",
"1300": "Masquer automatiquement le curseur",
"1301": "Configuration des touches",
"1302": "Affectation des boutons de la manette",
@@ -164,8 +164,8 @@
"1313": "Heure locale",
"1314": "Attention !",
"1315": "Ce paramètre est expérimental. Si le jeu n'est pas joué à 60 images par seconde, des problèmes visuels et de gameplay peuvent survenir.",
"1320": "None",
"1321": "Spin",
"1320": "Rien",
"1321": "Tourbillon",
"1322": "Boost",
"1323": "Flip",
"1324": "Rail Grind",
@@ -183,11 +183,11 @@
"1330": "Dark Bomb",
"1331": "Dark Blast",
"1332": "Dark Giant",
"1333": "PS2 Options",
"1333": "Options PS2",
"1334": "Actor Culling",
"1335": "Force Environment Mapping",
"1336": "Fast Progress Menu",
"1336": "Menu de pause rapide",
"1337": "PS2 LOD Distance",
"1338": "Off",
"1339": "Display"
"1339": "Écran"
}
+57
View File
@@ -0,0 +1,57 @@
;; "project file" for subtitles make tool.
(subtitle-v2
(file-json
:language-id 0
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 1
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_fr-FR.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_fr-FR.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 2
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_de-DE.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_de-DE.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 3
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_es-ES.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_es-ES.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 4
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_it-IT.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_it-IT.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 5
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_jp-JP.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_jp-JP.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 6
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_ko-KR.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_ko-KR.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json")
(file-json
:language-id 7
:text-version "jak2"
:lines "game/assets/jak2/subtitle/subtitle_lines_en-GB.json"
:meta "game/assets/jak2/subtitle/subtitle_meta_en-GB.json"
:lines-base "game/assets/jak2/subtitle/subtitle_lines_en-US.json"
:meta-base "game/assets/jak2/subtitle/subtitle_meta_en-US.json"))
+18
View File
@@ -0,0 +1,18 @@
;; "project file" for text make tool.
;; it's very simple... a list of (action args...)
;; There are two actions:
;; - file-json (A path to a json file)
;; - args: (language_id text_version group_name '(filename list))
;; - file (A path to a GOAL data file)
;; - the same arguments are provided within the file itself
(text
;; NOTE : we compile using the fixed v2 encoding because it's what we use.
(file "$DECOMP/assets/game_text.txt") ;; this is the decompiler-generated file!
;; add custom files down here
(file-json 0 jak2 "common" '("game/assets/jak3/text/game_custom_text_en-US.json"))
(file-json 5 jak2 "common" '("game/assets/jak3/text/game_custom_text_ja-JP.json"))
(file-json 7 jak2 "common" '("game/assets/jak3/text/game_custom_text_en-GB.json"))
)
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,5 @@
{
"cutscenes": {},
"other": {},
"speakers": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,4 @@
{
"cutscenes": {},
"other": {}
}
@@ -0,0 +1,2 @@
{
}
@@ -0,0 +1,2 @@
{
}
@@ -0,0 +1,2 @@
{
}
+2
View File
@@ -559,6 +559,7 @@
030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows,
030000009b2800006300000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
030000009b2800006100000000000000,Raphnet N64 Adapter,+rightx:b9,+righty:b7,-rightx:b8,-righty:b6,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,lefttrigger:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b3,platform:Windows,
030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows,
030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows,
030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows,
@@ -1408,6 +1409,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00000901000011010000,PDP PS3 Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
030000006f0e00002f01000011010000,PDP Wired PS3 Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
03000000ad1b000004f9000000010000,PDP Xbox 360 Versus Fighting,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+15 -2
View File
@@ -8,8 +8,7 @@
#include "common/common_types.h"
#include "common/versions/versions.h"
// TODO: jak 3 stub
constexpr PerGameVersion<int> DGO_RPC_ID(0xdeb4, 0xfab3, 0x0);
constexpr PerGameVersion<int> DGO_RPC_ID(0xdeb4, 0xfab3, 0xfab3);
constexpr int DGO_RPC_CHANNEL = 3;
constexpr int DGO_RPC_LOAD_FNO = 0;
constexpr int DGO_RPC_LOAD_NEXT_FNO = 1;
@@ -28,3 +27,17 @@ struct RPC_Dgo_Cmd {
uint32_t buffer_heap_top;
char name[16];
};
namespace jak3 {
struct RPC_Dgo_Cmd {
uint16_t rsvd;
uint16_t result;
uint32_t buffer1;
uint32_t buffer2;
uint32_t buffer_heap_top;
char name[16];
uint16_t cgo_id;
uint8_t pad[30];
};
static_assert(sizeof(RPC_Dgo_Cmd) == 0x40);
} // namespace jak3
+1 -1
View File
@@ -13,11 +13,11 @@ enum class Language {
Japanese = 5,
UK_English = 6,
// uk english?
Portuguese = 9
};
struct GameLaunchOptions {
GameVersion game_version = GameVersion::Jak1;
bool disable_display = false;
bool disable_debug_vm = true;
int server_port = DECI2_PORT;
};
+1 -2
View File
@@ -7,6 +7,5 @@
#include "common/versions/versions.h"
// TODO: jak 3 stub
constexpr PerGameVersion<int> LOADER_RPC_ID(0xdeb2, 0xfab1, 0x0);
constexpr PerGameVersion<int> LOADER_RPC_ID(0xdeb2, 0xfab1, 0xfab1);
constexpr int LOADER_RPC_CHANNEL = 1;
+1 -2
View File
@@ -7,6 +7,5 @@
*/
#include "common/versions/versions.h"
// TODO: jak 3 stub
constexpr PerGameVersion<int> PLAY_RPC_ID(0xdeb6, 0xfab5, 0x0);
constexpr PerGameVersion<int> PLAY_RPC_ID(0xdeb6, 0xfab5, 0xfab5);
constexpr int PLAY_RPC_CHANNEL = 5;
+1 -2
View File
@@ -7,6 +7,5 @@
*/
#include "common/versions/versions.h"
// TODO: jak 3 stub
constexpr PerGameVersion<int> PLAYER_RPC_ID(0xdeb1, 0xfab0, 0x0);
constexpr PerGameVersion<int> PLAYER_RPC_ID(0xdeb1, 0xfab0, 0xfab0);
constexpr int PLAYER_RPC_CHANNEL = 0;
Loaded 100 of 981 files, more files were not shown because too many files have changed in this diff. Show more