Compare commits

..
1 Commits
Author SHA1 Message Date
Tyler Wilding 836f7327db integ test commit 2024-04-20 23:38:05 -04:00
2590 changed files with 343154 additions and 1419747 deletions

No files matched your search

@@ -32,4 +32,4 @@ cp -r $SOURCE/decompiler/config $DEST/data/decompiler/
cp -r $SOURCE/goal_src $DEST/data
cp -r $SOURCE/game/assets $DEST/data/game/
cp -r $SOURCE/game/graphics/opengl_renderer/shaders $DEST/data/game/graphics/opengl_renderer
cp -r $SOURCE/custom_assets $DEST/data
cp -r $SOURCE/custom_levels $DEST/data
@@ -24,4 +24,4 @@ cp -r $SOURCE/decompiler/config $DEST/data/decompiler/
cp -r $SOURCE/goal_src $DEST/data
cp -r $SOURCE/game/assets $DEST/data/game/
cp -r $SOURCE/game/graphics/opengl_renderer/shaders $DEST/data/game/graphics/opengl_renderer
cp -r $SOURCE/custom_assets $DEST/data
cp -r $SOURCE/custom_levels $DEST/data
+1 -1
View File
@@ -33,7 +33,7 @@ jobs:
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
- name: Setup sccache
uses: hendrikmuhs/[email protected]3
uses: hendrikmuhs/[email protected]2
with:
variant: sccache
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
sudo update-alternatives --set g++ /usr/bin/g++-10
- name: Setup sccache
uses: hendrikmuhs/[email protected]3
uses: hendrikmuhs/[email protected]2
with:
variant: sccache
key: linux-ubuntu-20.04-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
run: arch -arm64 brew install cmake ninja
- name: Setup sccache
uses: hendrikmuhs/[email protected]3
uses: hendrikmuhs/[email protected]2
with:
variant: sccache
key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
run: brew install cmake nasm ninja
- name: Setup sccache
uses: hendrikmuhs/[email protected]3
uses: hendrikmuhs/[email protected]2
with:
variant: sccache
key: macos-12-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
}
- name: Setup sccache
uses: hendrikmuhs/[email protected]3
uses: hendrikmuhs/[email protected]2
with:
variant: sccache
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
}
- name: Setup sccache
uses: hendrikmuhs/[email protected]3
uses: hendrikmuhs/[email protected]2
with:
variant: sccache
key: windows-2022-${{ inputs.cachePrefix }}-${{ inputs.cmakePreset }}-${{ github.sha }}
+1 -9
View File
@@ -54,14 +54,7 @@ imgui.ini
node_modules/
# texture replacements
custom_assets/jak1/texture_replacements/*
custom_assets/jak2/texture_replacements/*
custom_assets/jak3/texture_replacements/*
# merc replacements
custom_assets/jak1/merc_replacements/*
custom_assets/jak2/merc_replacements/*
custom_assets/jak3/merc_replacements/*
texture_replacements/*
# generated cmake files
svnrev.h
@@ -83,4 +76,3 @@ __pycache__/
/TODO.md
unifont-15.0.03.ttf
*.diff
goalc-report.html
+34 -147
View File
@@ -7,58 +7,42 @@
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - Unit-Tests - Summary",
"args": [
"--gtest_brief=1"
]
"args": ["--gtest_brief=1"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - Unit-Tests - Verbose",
"args": [
"--gtest_brief=0"
]
"args": ["--gtest_brief=0"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - Draft Tests - Verbose",
"args": [
"--gtest_brief=0",
"--gtest_filter=\"*Draft*\""
]
"args": ["--gtest_brief=0", "--gtest_filter=\"*Draft*\""]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - TypeConsistency - Verbose",
"args": [
"--gtest_brief=0",
"--gtest_filter=\"*TypeConsistency*\""
]
"args": ["--gtest_brief=0", "--gtest_filter=\"*TypeConsistency*\""]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - TypeConsistency - Jak 2 - Verbose",
"args": [
"--gtest_brief=0",
"--gtest_filter=\"*Jak2TypeConsistency*\""
]
"args": ["--gtest_brief=0", "--gtest_filter=\"*Jak2TypeConsistency*\""]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - WithGameTests - Verbose",
"args": [
"--gtest_brief=0",
"--gtest_filter=\"*WithGameTests*\""
]
"args": ["--gtest_brief=0", "--gtest_filter=\"*WithGameTests*\""]
},
{
"type": "default",
@@ -129,109 +113,56 @@
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 1 - Runtime",
"args": [
"-v",
"--game",
"jak1",
"--",
"-fakeiso",
"-debug"
]
"args": ["-v", "--game", "jak1", "--", "-fakeiso", "-debug"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 1 - Runtime (boot)",
"args": [
"-v",
"--game",
"jak1",
"--",
"-boot",
"-fakeiso",
"-debug"
]
"args": ["-v", "--game", "jak1", "--", "-boot", "-fakeiso", "-debug"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 2 - Runtime (no boot)",
"args": [
"-v",
"--game",
"jak2",
"--",
"-fakeiso",
"-debug"
]
"args": ["-v", "--game", "jak2", "--", "-fakeiso", "-debug"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 2 - Runtime (boot)",
"args": [
"-v",
"--game",
"jak2",
"--",
"-boot",
"-fakeiso",
"-debug"
]
"args": ["-v", "--game", "jak2", "--", "-boot", "-fakeiso", "-debug"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 2 - Runtime (release)",
"args": [
"-v",
"--game",
"jak2",
"--",
"-boot",
"-fakeiso"
]
"args": ["-v", "--game", "jak2", "--", "-boot", "-fakeiso"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "gk.exe (bin\\gk.exe)",
"name": "Game - Jak 3 - Runtime (boot)",
"args": [
"-v",
"--game",
"jak3",
"--",
"-boot",
"-fakeiso",
"-debug"
]
"args": ["-v", "--game", "jak3", "--", "-boot", "-fakeiso", "-debug"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc.exe (bin\\goalc.exe)",
"name": "REPL - Jak 1",
"args": [
"--user-auto",
"--game",
"jak1"
]
"args": ["--user-auto", "--game", "jak1"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc.exe (bin\\goalc.exe)",
"name": "REPL - Jak 2",
"args": [
"--user-auto",
"--game",
"jak2"
]
"args": ["--user-auto", "--game", "jak2"]
},
{
"type": "default",
@@ -312,45 +243,19 @@
"ntsc_v1"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "decompiler.exe (bin\\decompiler.exe)",
"name": "Decompiler - Jak 3 - Extract",
"args": [
"${workspaceRoot}/decompiler/config/jak3/jak3_config.jsonc",
"${workspaceRoot}/iso_data",
"${workspaceRoot}/decompiler_out",
"--version",
"ntsc_v1",
"--config-override \"{\\\"decompile_code\\\": false, \\\"levels_extract\\\": true, \\\"allowed_objects\\\": []}\""
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "memory_dump_tool.exe (bin\\memory_dump_tool.exe)",
"name": "Tools - EE Memory Analyze - Jak 1",
"args": [
"\"${workspaceRoot}/eeMemory.bin\"",
"--output-path",
"\"${workspaceRoot}\"",
"--game",
"jak1"
]
"args": ["\"${workspaceRoot}/eeMemory.bin\"", "--output-path", "\"${workspaceRoot}\"", "--game", "jak1"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "memory_dump_tool.exe (bin\\memory_dump_tool.exe)",
"name": "Tools - EE Memory Analyze - Jak 2",
"args": [
"\"${workspaceRoot}/eeMemory.bin\"",
"--output-path",
"\"${workspaceRoot}\"",
"--game",
"jak2"
]
"args": ["\"${workspaceRoot}/eeMemory.bin\"", "--output-path", "\"${workspaceRoot}\"", "--game", "jak2"]
},
{
"type": "default",
@@ -367,53 +272,35 @@
"project": "CMakeLists.txt",
"projectTarget": "extractor.exe (bin\\extractor.exe)",
"name": "Tools - Extractor - Full",
"args": [
"\"E:\\ISOs\\Jak\\Jak 1.iso\""
]
"args": ["\"E:\\ISOs\\Jak\\Jak 1.iso\""]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "lsp.exe (bin\\lsp.exe)",
"name": "Tools - LSP",
"args": []
"type" : "default",
"project" : "CMakeLists.txt",
"projectTarget" : "lsp.exe (bin\\lsp.exe)",
"name" : "Tools - LSP",
"args" : []
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "type_searcher.exe (bin\\type_searcher.exe)",
"name": "Tools - Type Searcher",
"args": [
"--game",
"jak2",
"--output-path",
"./search-results.json",
"--size",
255,
"--fields",
"[{\\\"type\\\":\\\"quaternion\\\",\\\"offset\\\":48}]"
]
"type" : "default",
"project" : "CMakeLists.txt",
"projectTarget" : "type_searcher.exe (bin\\type_searcher.exe)",
"name" : "Tools - Type Searcher",
"args" : ["--game", "jak2", "--output-path", "./search-results.json", "--size", 255, "--fields", "[{\\\"type\\\":\\\"quaternion\\\",\\\"offset\\\":48}]"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "formatter.exe (bin\\formatter.exe)",
"name": "Tools - Formatter - Inplace",
"args": [
"--write",
"--file",
"C:\\Users\\xtvas\\Repositories\\opengoal\\jak-project\\goal_src\\jak1\\engine\\camera\\cam-states.gc"
]
"type" : "default",
"project" : "CMakeLists.txt",
"projectTarget" : "formatter.exe (bin\\formatter.exe)",
"name" : "Tools - Formatter - Inplace",
"args" : ["--write", "--file", "C:\\Users\\xtvas\\Repos\\opengoal\\jak-project\\decompiler_out\\jak3\\mood-h_disasm.gc"]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "goalc-test.exe (bin\\goalc-test.exe)",
"name": "Tests - Formatter",
"args": [
"--gtest_brief=0",
"--gtest_filter=\"*FormatterTests*\""
]
"args": ["--gtest_brief=0", "--gtest_filter=\"*FormatterTests*\""]
}
]
}
}
+2 -2
View File
@@ -8,10 +8,10 @@
"name": "run python script",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/scripts/gsrc/compare-compilation-outputs.py",
"program": "${workspaceFolder}/scripts/gsrc/copy-common-naming.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"args": []
"args": ["--update-names-from-refs", "--decompiler", "./out/build/Release/bin/decompiler"]
},
]
}
+1 -6
View File
@@ -101,6 +101,7 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
message(STATUS "AppleClang detected - Setting Defaults")
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} \
-march=native \
-Wall \
-Winit-self \
-ggdb \
@@ -116,12 +117,6 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
-Wsign-promo \
-fdiagnostics-color=always"
)
# pin to AVX for macOS, hopefully all macOS runners have atleast this architecture
# technically speaking, SSE4 is the cutoff for Apple Silicon so...only a matter of time!
if(NOT CMAKE_CXX_COMPILER_TARGET STREQUAL "arm64-apple-darwin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
endif()
# additional c++ flags for release mode for our projects
if(CMAKE_BUILD_TYPE MATCHES "Release")
+3 -5
View File
@@ -51,7 +51,7 @@ add_library(common
repl/config.cpp
repl/nrepl/ReplClient.cpp
repl/nrepl/ReplServer.cpp
repl/repl_wrapper.cpp
repl/util.cpp
serialization/subtitles/subtitles_v1.cpp
serialization/subtitles/subtitles_v2.cpp
serialization/subtitles/subtitles.cpp
@@ -87,11 +87,9 @@ add_library(common
util/term_util.cpp
util/Timer.cpp
util/unicode_util.cpp
util/gltf_util.cpp
versions/versions.cpp
)
versions/versions.cpp)
target_link_libraries(common fmt lzokay replxx libzstd_static tree-sitter sqlite3 libtinyfiledialogs tiny_gltf)
target_link_libraries(common fmt lzokay replxx libzstd_static tree-sitter sqlite3 libtinyfiledialogs)
if(WIN32)
target_link_libraries(common wsock32 ws2_32 windowsapp)
+2 -2
View File
@@ -5,8 +5,6 @@
#include "common/cross_sockets/XSocket.h"
#include "common/log/log.h"
#include "fmt/core.h"
// clang-format off
#ifdef _WIN32
#define NOMINMAX
@@ -15,7 +13,9 @@
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#include "common/repl/nrepl/ReplServer.h"
#include "fmt/core.h"
// clang-format on
XSocketClient::XSocketClient(int _tcp_port) {
+4 -12
View File
@@ -35,7 +35,7 @@ void XSocketServer::shutdown_server() {
close_server_socket();
}
bool XSocketServer::init_server(bool failure_may_occur) {
bool XSocketServer::init_server() {
listening_socket = open_socket(AF_INET, SOCK_STREAM, 0);
if (listening_socket < 0) {
listening_socket = -1;
@@ -76,27 +76,19 @@ bool XSocketServer::init_server(bool failure_may_occur) {
addr.sin_port = htons(tcp_port);
if (bind(listening_socket, (sockaddr*)&addr, sizeof(addr)) < 0) {
if (failure_may_occur) {
lg::debug("[XSocketServer:{}] failed to bind", tcp_port);
} else {
lg::error("[XSocketServer:{}] failed to bind", tcp_port);
}
lg::error("[XSocketServer:{}] failed to bind", tcp_port);
close_server_socket();
return false;
}
if (listen(listening_socket, 0) < 0) {
if (failure_may_occur) {
lg::debug("[XSocketServer:{}] failed to listen", tcp_port);
} else {
lg::error("[XSocketServer:{}] failed to listen", tcp_port);
}
lg::error("[XSocketServer:{}] failed to listen", tcp_port);
close_server_socket();
return false;
}
server_initialized = true;
lg::debug("[XSocketServer:{}] initialized", tcp_port);
lg::info("[XSocketServer:{}] initialized", tcp_port);
post_init();
return true;
}
+1 -1
View File
@@ -20,7 +20,7 @@ class XSocketServer {
XSocketServer(const XSocketServer&) = delete;
XSocketServer& operator=(const XSocketServer&) = delete;
bool init_server(bool failure_may_occur = false);
bool init_server();
void shutdown_server();
void close_server_socket();
+10 -54
View File
@@ -9,16 +9,10 @@
#include "third-party/sse2neon/sse2neon.h"
#endif
#include "common/log/log.h"
#include "common/util/Assert.h"
namespace tfrag3 {
void PackedTimeOfDay::serialize(Serializer& ser) {
ser.from_pod_vector(&data);
ser.from_ptr(&color_count);
}
void PackedTieVertices::serialize(Serializer& ser) {
ser.from_pod_vector(&color_indices);
ser.from_pod_vector(&matrices);
@@ -77,9 +71,10 @@ void TfragTree::serialize(Serializer& ser) {
draw.serialize(ser);
}
// ser.from_pod_vector(&vertices);
ser.from_pod_vector(&packed_vertices.vertices);
ser.from_pod_vector(&packed_vertices.cluster_origins);
colors.serialize(ser);
ser.from_pod_vector(&colors);
bvh.serialize(ser);
ser.from_ptr(&use_strips);
}
@@ -403,7 +398,7 @@ void TieTree::serialize(Serializer& ser) {
}
packed_vertices.serialize(ser);
colors.serialize(ser);
ser.from_pod_vector(&colors);
bvh.serialize(ser);
ser.from_ptr(&has_per_proto_visibility_toggle);
@@ -411,7 +406,7 @@ void TieTree::serialize(Serializer& ser) {
}
void ShrubTree::serialize(Serializer& ser) {
time_of_day_colors.serialize(ser);
ser.from_pod_vector(&time_of_day_colors);
ser.from_pod_vector(&indices);
packed_vertices.serialize(ser);
if (ser.is_saving()) {
@@ -427,30 +422,6 @@ void ShrubTree::serialize(Serializer& ser) {
ser.from_string_vector(&proto_names);
}
void HfragmentBucket::serialize(Serializer& ser) {
ser.from_pod_vector(&corners);
ser.from_ptr(&montage_table);
}
void Hfragment::serialize(Serializer& ser) {
ser.from_pod_vector(&vertices);
ser.from_pod_vector(&indices);
ser.from_pod_vector(&corners);
if (ser.is_saving()) {
ser.save<size_t>(buckets.size());
} else {
buckets.resize(ser.load<size_t>());
}
for (auto& x : buckets) {
x.serialize(ser);
}
time_of_day_colors.serialize(ser);
ser.from_ptr(&wang_tree_tex_id);
ser.from_ptr(&draw_mode);
ser.from_ptr(&occlusion_offset);
}
void BVH::serialize(Serializer& ser) {
ser.from_ptr(&first_leaf_node);
ser.from_ptr(&last_leaf_node);
@@ -492,7 +463,6 @@ void MercDraw::serialize(Serializer& ser) {
ser.from_ptr(&first_index);
ser.from_ptr(&index_count);
ser.from_ptr(&num_triangles);
ser.from_ptr(&no_strip);
}
void Blerc::serialize(Serializer& ser) {
@@ -634,8 +604,6 @@ void Level::serialize(Serializer& ser) {
tree.serialize(ser);
}
hfrag.serialize(ser);
collision.serialize(ser);
merc_data.serialize(ser);
@@ -686,7 +654,8 @@ void PackedShrubVertices::memory_usage(MemoryUsageTracker* tracker) const {
}
void ShrubTree::memory_usage(MemoryUsageTracker* tracker) const {
tracker->add(MemoryUsageCategory::SHRUB_TIME_OF_DAY, sizeof(u8) * time_of_day_colors.data.size());
tracker->add(MemoryUsageCategory::SHRUB_TIME_OF_DAY,
sizeof(TimeOfDayColor) * time_of_day_colors.size());
packed_vertices.memory_usage(tracker);
tracker->add(MemoryUsageCategory::SHRUB_DRAW, sizeof(ShrubDraw) * static_draws.size());
tracker->add(MemoryUsageCategory::SHRUB_IND, sizeof(u32) * indices.size());
@@ -714,7 +683,7 @@ void TieTree::memory_usage(MemoryUsageTracker* tracker) const {
draw.vis_groups.size() * sizeof(StripDraw::VisGroup));
}
packed_vertices.memory_usage(tracker);
tracker->add(MemoryUsageCategory::TIE_TIME_OF_DAY, sizeof(u8) * colors.data.size());
tracker->add(MemoryUsageCategory::TIE_TIME_OF_DAY, sizeof(TimeOfDayColor) * colors.size());
for (auto& draw : instanced_wind_draws) {
draw.memory_usage(tracker);
@@ -738,7 +707,7 @@ void TfragTree::memory_usage(MemoryUsageTracker* tracker) const {
draw.vis_groups.size() * sizeof(StripDraw::VisGroup));
}
packed_vertices.memory_usage(tracker);
tracker->add(MemoryUsageCategory::TFRAG_TIME_OF_DAY, sizeof(u8) * colors.data.size());
tracker->add(MemoryUsageCategory::TFRAG_TIME_OF_DAY, sizeof(TimeOfDayColor) * colors.size());
tracker->add(MemoryUsageCategory::TFRAG_BVH, sizeof(VisNode) * bvh.vis_nodes.size());
}
@@ -751,13 +720,6 @@ void IndexTexture::memory_usage(MemoryUsageTracker* tracker) const {
tracker->add(MemoryUsageCategory::SPECIAL_TEXTURE, 256 * 4); // clut
}
void Hfragment::memory_usage(tfrag3::MemoryUsageTracker* tracker) const {
tracker->add(MemoryUsageCategory::HFRAG_VERTS, vertices.size() * sizeof(HfragmentVertex));
tracker->add(MemoryUsageCategory::HFRAG_INDEX, indices.size() * sizeof(u32));
tracker->add(MemoryUsageCategory::HFRAG_TIME_OF_DAY, time_of_day_colors.data.size() * sizeof(u8));
tracker->add(MemoryUsageCategory::HFRAG_CORNERS, corners.size() * sizeof(HfragmentCorner));
}
void Level::memory_usage(MemoryUsageTracker* tracker) const {
for (const auto& texture : textures) {
texture.memory_usage(tracker);
@@ -778,7 +740,6 @@ void Level::memory_usage(MemoryUsageTracker* tracker) const {
for (const auto& tree : shrub_trees) {
tree.memory_usage(tracker);
}
hfrag.memory_usage(tracker);
collision.memory_usage(tracker);
merc_data.memory_usage(tracker);
}
@@ -822,11 +783,6 @@ void print_memory_usage(const tfrag3::Level& lev, int uncompressed_data_size) {
{"merc-mod-draw-1", mem_use.data[tfrag3::MemoryUsageCategory::MERC_MOD_DRAW_1]},
{"merc-mod-draw-2", mem_use.data[tfrag3::MemoryUsageCategory::MERC_MOD_DRAW_2]},
{"blerc", mem_use.data[tfrag3::MemoryUsageCategory::BLERC]},
{"hfrag-verts", mem_use.data[tfrag3::MemoryUsageCategory::HFRAG_VERTS]},
{"hfrag-index", mem_use.data[tfrag3::MemoryUsageCategory::HFRAG_INDEX]},
{"hfrag-time-of-day", mem_use.data[tfrag3::MemoryUsageCategory::HFRAG_TIME_OF_DAY]},
{"hfrag-corners", mem_use.data[tfrag3::MemoryUsageCategory::HFRAG_CORNERS]}
};
for (auto& known : known_categories) {
total_accounted += known.second;
@@ -839,8 +795,8 @@ void print_memory_usage(const tfrag3::Level& lev, int uncompressed_data_size) {
for (const auto& x : known_categories) {
if (x.second) {
lg::print("{:30s} : {:6d} kB {:3.1f}%\n", x.first, x.second / 1024,
100.f * (float)x.second / uncompressed_data_size);
fmt::print("{:30s} : {:6d} kB {:3.1f}%\n", x.first, x.second / 1024,
100.f * (float)x.second / uncompressed_data_size);
}
}
}
+16 -66
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 = 41;
constexpr int TFRAG3_VERSION = 39;
enum MemoryUsageCategory {
TEXTURE,
@@ -61,11 +61,6 @@ enum MemoryUsageCategory {
MERC_MOD_TABLE,
BLERC,
HFRAG_VERTS,
HFRAG_INDEX,
HFRAG_TIME_OF_DAY,
HFRAG_CORNERS,
COLLISION,
NUM_CATEGORIES
@@ -274,23 +269,18 @@ struct BVH {
void serialize(Serializer& ser);
};
// This is split into groups of 4 colors.
// The data in these groups is stored first by palette, then color, then channel.
struct PackedTimeOfDay {
std::vector<u8> data;
u32 color_count = 0;
void serialize(Serializer& ser);
// A time-of-day color. Each stores 8 colors. At a given "time of day", they are interpolated
// to find a single color which goes into a color palette.
struct TimeOfDayColor {
math::Vector<u8, 4> rgba[8];
u8 read(int color, int palette, int channel) const {
const int color_quad = color / 4;
const int color_in_quad = color % 4;
return data[color_quad * 4 * 4 * 8 + palette * 4 * 4 + color_in_quad * 4 + channel];
}
u8& read(int color, int palette, int channel) {
const int color_quad = color / 4;
const int color_in_quad = color % 4;
return data[color_quad * 4 * 4 * 8 + palette * 4 * 4 + color_in_quad * 4 + channel];
bool operator==(const TimeOfDayColor& other) const {
for (size_t i = 0; i < 8; i++) {
if (rgba[i] != other.rgba[i]) {
return false;
}
}
return true;
}
};
@@ -329,8 +319,8 @@ struct TfragTree {
TFragmentTreeKind kind; // our tfrag kind
std::vector<StripDraw> draws; // the actual topology and settings
PackedTfragVertices packed_vertices;
PackedTimeOfDay colors; // vertex colors (pre-interpolation)
BVH bvh; // the bvh for frustum culling
std::vector<TimeOfDayColor> colors; // vertex colors (pre-interpolation)
BVH bvh; // the bvh for frustum culling
bool use_strips = true;
struct {
@@ -411,7 +401,7 @@ struct TieTree {
std::array<u32, kNumTieCategories + 1> category_draw_indices;
PackedTieVertices packed_vertices;
PackedTimeOfDay colors; // vertex colors (pre-interpolation)
std::vector<TimeOfDayColor> colors; // vertex colors (pre-interpolation)
std::vector<InstancedStripDraw> instanced_wind_draws;
std::vector<TieWindInstance> wind_instance_info;
@@ -432,7 +422,7 @@ struct TieTree {
struct ShrubTree {
// todo some visibility structure
PackedTimeOfDay time_of_day_colors; // multiplier colors
std::vector<TimeOfDayColor> time_of_day_colors; // multiplier colors
PackedShrubVertices packed_vertices;
std::vector<ShrubDraw> static_draws; // the actual topology and settings
@@ -451,43 +441,6 @@ struct ShrubTree {
void unpack();
};
struct HfragmentVertex {
float height = 0;
u32 vi = 0;
u16 color_index = 0;
u8 u = 0, v = 0;
u32 pad = 0;
};
struct HfragmentCorner {
math::Vector<float, 4> bsphere;
u32 vis_id = 0;
u32 index_start = 0;
u32 index_length = 0;
u32 num_tris = 0;
};
struct HfragmentBucket {
std::vector<u32> corners;
std::array<u16, 16> montage_table;
void serialize(Serializer& ser);
};
struct Hfragment {
std::vector<HfragmentVertex> vertices;
std::vector<u32> indices;
std::vector<HfragmentCorner> corners;
std::vector<HfragmentBucket> buckets;
PackedTimeOfDay time_of_day_colors;
std::array<s32, 4> wang_tree_tex_id;
DrawMode draw_mode;
u32 occlusion_offset;
void serialize(Serializer& ser);
void memory_usage(MemoryUsageTracker* tracker) const;
};
struct CollisionMesh {
struct Vertex {
float x, y, z;
@@ -530,8 +483,6 @@ struct MercDraw {
u32 first_index;
u32 index_count;
u32 num_triangles;
// no strip hack for custom models
bool no_strip = false;
void serialize(Serializer& ser);
};
@@ -615,7 +566,6 @@ struct Level {
std::array<std::vector<TfragTree>, TFRAG_GEOS> tfrag_trees;
std::array<std::vector<TieTree>, TIE_GEOS> tie_trees;
std::vector<ShrubTree> shrub_trees;
Hfragment hfrag;
CollisionMesh collision;
MercModelGroup merc_data;
u16 version2 = TFRAG3_VERSION;
+2 -2
View File
@@ -4,7 +4,7 @@
#include "fmt/core.h"
std::string DmaTag::print() const {
std::string DmaTag::print() {
std::string result;
const char* mode_names[8] = {"refe", "cnt", "next", "ref", "refs", "call", "ret", "end"};
result += fmt::format("TAG: 0x{:08x} {:4s} qwc 0x{:04x}", addr, mode_names[(int)kind], qwc);
@@ -15,7 +15,7 @@ std::string DmaTag::print() const {
return result;
}
std::string VifCode::print() const {
std::string VifCode::print() {
std::string result;
switch (kind) {
+2 -2
View File
@@ -52,7 +52,7 @@ struct DmaTag {
bool operator!=(const DmaTag& other) const { return !((*this) == other); }
std::string print() const;
std::string print();
};
inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32 dadr) {
@@ -148,7 +148,7 @@ struct VifCode {
u16 num;
u16 immediate;
std::string print() const;
std::string print();
};
struct VifCodeStcycl {
+1
View File
@@ -12,6 +12,7 @@ Also in general I found it _really_ hard to find modern and easy to understand a
Atleast for me, it helps to understand the path code takes as it flows through the formatting process. Originally I tried to do as much at once for sake of efficiency but this just makes things incredibly hard to reason about and fix bugs. So like any problem that is complex, break it down, the formatter goes through many distinct phases chipping away at the problem:
```mermaid
%%{init: {'theme': 'dark', "flowchart" : { "curve" : "basis" } } }%%
flowchart TB
subgraph top1 [Build a Formatting Tree]
direction TB
+26 -90
View File
@@ -33,16 +33,14 @@ int hang_indentation_width(const FormatterTreeNode& curr_node) {
return 1 + hang_indentation_width(first_elt);
}
// TODO - this doesn't account for paren's width contribution!
int get_total_form_inlined_width(const FormatterTreeNode& curr_node) {
if (curr_node.token) {
return curr_node.token->length();
}
int width = 1;
for (int i = 0; i < curr_node.refs.size(); i++) {
width += get_total_form_inlined_width(curr_node.refs.at(i));
if (i != curr_node.refs.size() - 1) {
width += 1; // add the space between elements
}
for (const auto& ref : curr_node.refs) {
width += get_total_form_inlined_width(ref);
}
return width + 1;
}
@@ -51,9 +49,7 @@ int get_total_form_inlined_width(const FormatterTreeNode& curr_node) {
void apply_formatting_config(
FormatterTreeNode& curr_node,
std::optional<std::shared_ptr<formatter_rules::config::FormFormattingConfig>>
config_from_parent = {},
std::optional<std::shared_ptr<formatter_rules::config::FormFormattingConfig>>
config_merge_from_parent = {}) {
config_from_parent = {}) {
using namespace formatter_rules;
// node is empty, base-case
if (curr_node.token || curr_node.refs.empty()) {
@@ -69,13 +65,6 @@ void apply_formatting_config(
predefined_config = config::opengoal_form_config.at(form_head.value());
curr_node.formatting_config = predefined_config.value();
}
if (config_merge_from_parent) {
const auto& merge_config = *config_merge_from_parent.value();
curr_node.formatting_config.parent_mutable_extra_indent +=
merge_config.parent_mutable_extra_indent;
curr_node.formatting_config.prevent_inlining = merge_config.prevent_inlining;
}
} else if (config_from_parent) {
// TODO - doesn't merge just replaces, a bit inflexible
predefined_config = *config_from_parent.value();
@@ -115,7 +104,7 @@ void apply_formatting_config(
if (curr_node.formatting_config.has_constant_pairs) {
for (int i = 0; i < (int)curr_node.refs.size(); i++) {
auto& child_ref = curr_node.refs.at(i);
const auto& type = child_ref.metadata.node_type;
const auto type = child_ref.metadata.node_type;
if (constant_types.find(type) == constant_types.end() &&
constant_pairs::is_element_second_in_constant_pair(curr_node, child_ref, i)) {
child_ref.formatting_config.parent_mutable_extra_indent = 2;
@@ -140,16 +129,13 @@ void apply_formatting_config(
auto& ref = curr_node.refs.at(i);
if (!ref.token) {
// If the child has a pre-defined configuration at that index, we pass it along
if (predefined_config && predefined_config->index_config_override.find(i) !=
predefined_config->index_config_override.end()) {
apply_formatting_config(ref, {}, predefined_config->index_config_override.at(i));
} else if (predefined_config && predefined_config->index_configs.find(i) !=
predefined_config->index_configs.end()) {
apply_formatting_config(ref, predefined_config->index_configs.at(i), {});
if (predefined_config &&
predefined_config->index_configs.find(i) != predefined_config->index_configs.end()) {
apply_formatting_config(ref, predefined_config->index_configs.at(i));
} else if (predefined_config && predefined_config->default_index_config) {
apply_formatting_config(ref, predefined_config->default_index_config, {});
apply_formatting_config(ref, predefined_config->default_index_config);
} else {
apply_formatting_config(ref, {}, {});
apply_formatting_config(ref);
}
}
}
@@ -165,27 +151,10 @@ void apply_formatting_config(
max_columns = field.refs.size();
}
}
// if only one field has a value in the max col position, it looks weird for it to be indented
bool ignore_final_column_width = true;
int fields_with_atleast_max_col = 0;
for (const auto& field : curr_node.refs) {
if ((int)field.refs.size() == max_columns) {
fields_with_atleast_max_col++;
if (fields_with_atleast_max_col > 1) {
ignore_final_column_width = false;
break;
}
}
}
// Now find the column max widths
std::vector<int> column_max_widths = {};
for (int col = 0; col < max_columns; col++) {
column_max_widths.push_back(0);
// -2 because its the indentation before the final column that we want to skip
if (col >= curr_node.formatting_config.num_columns_to_compute_widths ||
(ignore_final_column_width && col == max_columns - 2)) {
continue;
}
for (const auto& field : curr_node.refs) {
if ((int)field.refs.size() > col) {
const auto width = get_total_form_inlined_width(field.refs.at(col));
@@ -233,10 +202,6 @@ bool form_contains_node_that_prevents_inlining(const FormatterTreeNode& curr_nod
bool can_node_be_inlined(const FormatterTreeNode& curr_node, int cursor_pos) {
using namespace formatter_rules;
if (curr_node.formatting_config.force_inline) {
// Ensure there are no comments, this still trumps this
if (form_contains_comment(curr_node)) {
return false;
}
return true;
}
// First off, we cannot inline the top level
@@ -299,15 +264,13 @@ std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
// Add new line entry
if (ref.token) {
// Cleanup block-comments
std::string val = ref.token_str();
if (ref.metadata.node_type == "block_comment") {
const auto comment_lines = comments::format_block_comment(ref.token_str());
for (const auto& line : comment_lines) {
form_lines.push_back(line);
}
} else {
form_lines.push_back(ref.token_str());
// TODO - change this sanitization to return a list of lines instead of a single new-lined
// line
val = comments::format_block_comment(ref.token_str());
}
form_lines.push_back(val);
if (!curr_node.metadata.is_top_level && i == (int)curr_node.refs.size() - 1 &&
(ref.metadata.is_comment)) {
// if there's an inline comment at the end of a form, we have to force the paren to the next
@@ -329,41 +292,26 @@ std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
if (i == (int)curr_node.refs.size() - 1 && form_lines.size() > 1 &&
(curr_node.formatting_config.hang_forms ||
curr_node.formatting_config.combine_first_two_lines)) {
form_lines.at(0) += fmt::format(" {}", str_util::ltrim(form_lines.at(1)));
form_lines.at(0) += fmt::format(" {}", form_lines.at(1));
form_lines.erase(form_lines.begin() + 1);
} else if ((i + 1) < (int)curr_node.refs.size()) {
const auto& next_ref = curr_node.refs.at(i + 1);
// combine the next inline comment or constant pair
if ((next_ref.metadata.node_type == "comment" && next_ref.metadata.is_inline) ||
(curr_node.formatting_config.has_constant_pairs &&
constant_pairs::is_element_second_in_constant_pair(curr_node, next_ref, i + 1)) ||
constant_pairs::is_element_second_in_constant_pair_new(curr_node.refs.at(i), next_ref)) {
constant_pairs::is_element_second_in_constant_pair(curr_node, next_ref, i + 1))) {
// TODO
// has issues with not consolidating first lines, this should probably just be moved to
// outside this loop for simplicity, do it later
if (next_ref.token) {
form_lines.at(form_lines.size() - 1) += fmt::format(" {}", next_ref.token_str());
form_lines.at(form_lines.size() - 1) += fmt::format(" {}", next_ref.token.value());
i++;
// We have to handle hang-consolidation here or else it will never be reached above!
if (i == (int)curr_node.refs.size() - 1 && form_lines.size() > 1 &&
(curr_node.formatting_config.hang_forms ||
curr_node.formatting_config.combine_first_two_lines)) {
form_lines.at(0) += fmt::format(" {}", form_lines.at(1));
form_lines.erase(form_lines.begin() + 1);
}
} else if (can_node_be_inlined(next_ref, cursor_pos)) {
const auto& lines = apply_formatting(next_ref, {}, cursor_pos); // TODO - cursor pos
for (const auto& line : lines) {
form_lines.at(form_lines.size() - 1) += fmt::format(" {}", line);
}
i++;
// We have to handle hang-consolidation here or else it will never be reached above!
if (i == (int)curr_node.refs.size() - 1 && form_lines.size() > 1 &&
(curr_node.formatting_config.hang_forms ||
curr_node.formatting_config.combine_first_two_lines)) {
form_lines.at(0) += fmt::format(" {}", form_lines.at(1));
form_lines.erase(form_lines.begin() + 1);
}
}
if (!curr_node.metadata.is_top_level && next_ref.metadata.node_type == "comment" &&
(i + 1) == (int)curr_node.refs.size()) {
@@ -380,9 +328,7 @@ std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
// Consolidate any lines if the configuration requires it
// TODO there is a hack here so that multi-line forms that are consolidated still line up properly
// i have to make consolidate a more first-class feature of the config
// TODO - hacky, but prevents a bad situation, clean up
if (curr_node.formatting_config.inline_until_index(form_lines) &&
!str_util::contains(form_lines.at(0), ";")) {
if (curr_node.formatting_config.inline_until_index(form_lines)) {
std::vector<std::string> new_form_lines = {};
const auto original_form_head_width = str_util::split(form_lines.at(0), '\n').at(0).length();
bool consolidating_lines = true;
@@ -428,32 +374,22 @@ std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
form_lines[form_lines.size() - 1] =
fmt::format("{}{}", form_lines[form_lines.size() - 1], form_surround_end);
}
std::string curr_form = "";
if (curr_node.formatting_config.parent_mutable_extra_indent > 0) {
curr_form += str_util::repeat(curr_node.formatting_config.parent_mutable_extra_indent, " ");
}
if (inline_form) {
// NOTE - not sure about this, if we are inlining a form, it always makes sense to eliminate
// trailing whitespace the only issue i can foresee is related to strings that span multiple
// lines.
std::vector<std::string> new_form_lines = {};
for (const auto& form_line : form_lines) {
new_form_lines.push_back(str_util::ltrim(form_line));
}
form_lines = {fmt::format("{}", fmt::join(new_form_lines, " "))};
form_lines = {fmt::format("{}", fmt::join(form_lines, " "))};
} else {
bool currently_in_block_comment = false;
for (int i = 0; i < (int)form_lines.size(); i++) {
auto& line = form_lines.at(i);
if (str_util::contains(line, "|#")) {
currently_in_block_comment = false;
}
if (i > 0 && !currently_in_block_comment) {
if (i > 0) {
auto& line = form_lines.at(i);
line = fmt::format("{}{}",
str_util::repeat(curr_node.formatting_config.indentation_width_for_index(
curr_node.formatting_config, i),
" "),
line);
}
if (str_util::contains(line, "#|") && !str_util::contains(line, "|#")) {
currently_in_block_comment = true;
}
}
}
return form_lines;
+11 -41
View File
@@ -79,18 +79,18 @@ FormatterTree::FormatterTree(const std::string& source, const TSNode& root_node)
}
const std::unordered_map<std::string, std::vector<std::string>> node_type_ignorable_contents = {
{"list_lit", {"(", ")"}}};
{"list_lit", {"(", ")"}},
{"quoting_lit", {"'"}},
{"unquoting_lit", {","}},
{"quasi_quoting_lit", {"`"}}};
// TODO make an imperative version eventually
// TODO - cleanup duplication
void FormatterTree::construct_formatter_tree_recursive(const std::string& source,
TSNode curr_node,
FormatterTreeNode& tree_node,
std::optional<std::string> node_prefix) {
if (ts_node_child_count(curr_node) == 0) {
auto new_node = FormatterTreeNode(source, curr_node);
new_node.node_prefix = node_prefix;
tree_node.refs.push_back(new_node);
tree_node.refs.push_back(FormatterTreeNode(source, curr_node));
return;
}
const std::string curr_node_type = ts_node_type(curr_node);
@@ -105,37 +105,11 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
tree_node.refs.push_back(FormatterTreeNode(source, curr_node));
return;
} else if (curr_node_type == "quoting_lit") {
if (node_prefix) {
node_prefix.value() += "'";
} else {
node_prefix = "'";
}
construct_formatter_tree_recursive(source, ts_node_child(curr_node, 1), tree_node, node_prefix);
return;
next_node_prefix = "'";
} else if (curr_node_type == "unquoting_lit") {
if (node_prefix) {
node_prefix.value() += ",";
} else {
node_prefix = ",";
}
construct_formatter_tree_recursive(source, ts_node_child(curr_node, 1), tree_node, node_prefix);
return;
next_node_prefix = ",";
} else if (curr_node_type == "quasi_quoting_lit") {
if (node_prefix) {
node_prefix.value() += "`";
} else {
node_prefix = "`";
}
construct_formatter_tree_recursive(source, ts_node_child(curr_node, 1), tree_node, node_prefix);
return;
} else if (curr_node_type == "unquote_splicing_lit") {
if (node_prefix) {
node_prefix.value() += ",@";
} else {
node_prefix = ",@";
}
construct_formatter_tree_recursive(source, ts_node_child(curr_node, 1), tree_node, node_prefix);
return;
next_node_prefix = "`";
}
std::vector<std::string> skippable_nodes = {};
if (node_type_ignorable_contents.find(curr_node_type) != node_type_ignorable_contents.end()) {
@@ -143,7 +117,6 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
}
for (size_t i = 0; i < ts_node_child_count(curr_node); i++) {
const auto child_node = ts_node_child(curr_node, i);
auto debug_child = ts_node_string(child_node);
const auto contents = get_source_code(source, child_node);
bool skip_node = false;
for (const auto& skippable_content : skippable_nodes) {
@@ -156,22 +129,19 @@ void FormatterTree::construct_formatter_tree_recursive(const std::string& source
continue;
}
if (curr_node_type == "list_lit") {
construct_formatter_tree_recursive(source, child_node, list_node, {});
construct_formatter_tree_recursive(source, child_node, list_node, next_node_prefix);
if (node_prefix) {
list_node.node_prefix = node_prefix;
}
} else {
construct_formatter_tree_recursive(source, child_node, tree_node, node_prefix);
construct_formatter_tree_recursive(source, child_node, tree_node, next_node_prefix);
// TODO - im not sure if this is correct
if (node_prefix && !tree_node.refs.empty()) {
tree_node.refs.at(tree_node.refs.size() - 1).node_prefix = node_prefix;
}
}
}
if (curr_node_type == "list_lit") {
// special case for empty lists
if (node_prefix && !list_node.node_prefix) {
list_node.node_prefix = node_prefix;
}
tree_node.refs.push_back(list_node);
}
}
+8 -69
View File
@@ -12,16 +12,12 @@ namespace formatter_rules {
// differentiate between a quoted symbol and a quoted form
const std::set<std::string> constant_types = {"kwd_lit", "num_lit", "str_lit",
"char_lit", "null_lit", "bool_lit"};
const std::set<std::string> constant_type_forms = {"meters", "seconds", "degrees"};
namespace constant_list {
bool is_constant_list(const FormatterTreeNode& node) {
if (!node.is_list() || node.refs.empty()) {
return false;
}
if (!node.refs.at(0).token) {
return true;
}
const auto& type = node.refs.at(0).metadata.node_type;
return constant_types.find(type) != constant_types.end();
}
@@ -40,28 +36,21 @@ bool should_insert_blank_line(const FormatterTreeNode& containing_node,
if (node.metadata.is_comment && node.metadata.num_blank_lines_following == 0) {
return false;
}
// If the next form is a comment and is inline, don't insert a new line
// If the next form is a comment and is inline, don't insert a comment
if ((index + 1) < (int)containing_node.refs.size() &&
containing_node.refs.at(index + 1).metadata.is_comment &&
containing_node.refs.at(index + 1).metadata.is_inline) {
return false;
}
if (node.formatting_config.elide_top_level_newline) {
if ((index + 1) < (int)containing_node.refs.size() &&
containing_node.refs.at(index + 1).metadata.is_comment) {
return true;
}
return false;
}
// TODO - only if the form doesn't fit on a single line
return true;
}
} // namespace blank_lines
namespace comments {
std::vector<std::string> format_block_comment(const std::string& comment) {
std::string format_block_comment(const std::string& comment) {
// Normalize block comments, remove any trailing or leading whitespace
// Only allow annotations on the first line, like #|@file
// Don't mess with internal indentation as the user might intend it to be a certain way.
@@ -82,22 +71,12 @@ std::vector<std::string> format_block_comment(const std::string& comment) {
// Remove trailing whitespace
comment_contents = str_util::rtrim(comment_contents);
// remove |#
if (str_util::ends_with(comment_contents, "|#")) {
comment_contents.pop_back();
comment_contents.pop_back();
}
// TODO - check suffix
comment_contents.pop_back();
comment_contents.pop_back();
comment_contents = str_util::rtrim(comment_contents);
std::vector<std::string> lines = {new_comment};
const auto contents_as_lines = str_util::split_string(comment_contents, "\n");
if (contents_as_lines.size() > 1) {
for (const auto& line : contents_as_lines) {
lines.push_back(line);
}
lines.push_back("|#");
} else {
lines.at(0) = fmt::format("{} {} |#", new_comment, str_util::trim(contents_as_lines.at(0)));
}
return lines;
new_comment += fmt::format("\n{}\n|#", comment_contents);
return new_comment;
}
} // namespace comments
@@ -122,46 +101,6 @@ bool is_element_second_in_constant_pair(const FormatterTreeNode& containing_node
return true;
}
// TODO - potentially remove the above
bool is_element_second_in_constant_pair_new(const FormatterTreeNode& prev_node,
const FormatterTreeNode& curr_node) {
if (prev_node.metadata.node_type == "kwd_lit") {
// Handle standard constant types
// TODO - pair up sym_names as well
if (constant_types.find(curr_node.metadata.node_type) != constant_types.end()) {
if (curr_node.metadata.node_type != "kwd_lit") {
// NOTE - there is ambiugity here which cannot be totally solved (i think?)
// if the element itself is also a keyword, assume this is two adjacent keywords and they
// should not be paired
return true;
}
}
// Quoted symbols
if (curr_node.metadata.node_type == "sym_name" && curr_node.node_prefix &&
(curr_node.node_prefix.value() == "'" || curr_node.node_prefix.value() == ",")) {
return true;
}
if (!curr_node.refs.empty()) {
// Constant forms special cases (ie. meters)
if (constant_type_forms.find(curr_node.refs.at(0).token_str()) != constant_type_forms.end()) {
return true;
}
// If they are just a list of symbol names (enum or simple method call)
bool all_symbols = true;
for (const auto& ref : curr_node.refs) {
if (ref.metadata.node_type != "sym_name") {
all_symbols = false;
break;
}
}
if (all_symbols) {
return true;
}
}
}
return false;
}
bool form_should_be_constant_paired(const FormatterTreeNode& node) {
// Criteria for a list to be constant paired:
// - needs to start with a non-symbol
+1 -3
View File
@@ -36,7 +36,7 @@ bool should_insert_blank_line(const FormatterTreeNode& containing_node,
//
// Reference - https://github.com/kkinnear/zprint/blob/main/doc/options/comments.md
namespace comments {
std::vector<std::string> format_block_comment(const std::string& comment);
std::string format_block_comment(const std::string& comment);
}
// Paired elements in a list will be kept in-line rather than the default new-line indentation
@@ -72,8 +72,6 @@ const static int min_pair_amount = 4;
bool is_element_second_in_constant_pair(const FormatterTreeNode& containing_node,
const FormatterTreeNode& node,
const int index);
bool is_element_second_in_constant_pair_new(const FormatterTreeNode& prev_node,
const FormatterTreeNode& curr_node);
bool form_should_be_constant_paired(const FormatterTreeNode& node);
} // namespace constant_pairs
+8 -202
View File
@@ -1,146 +1,24 @@
#include "rule_config.h"
#include "common/util/string_util.h"
namespace formatter_rules {
namespace config {
static FormFormattingConfig new_inlinable_simple_flow_rule() {
return {.config_set = true, .hang_forms = false};
}
static FormFormattingConfig new_permissive_flow_rule() {
return {.config_set = true, .hang_forms = false, .combine_first_two_lines = true};
}
static FormFormattingConfig new_flow_rule(int start_index, bool has_constant_pairs = false) {
static FormFormattingConfig new_flow_rule(int start_index) {
return {.config_set = true,
.hang_forms = false,
.inline_until_index =
[start_index](const std::vector<std::string>& /*curr_lines*/) { return start_index; },
.has_constant_pairs = has_constant_pairs};
}
static FormFormattingConfig new_function_rule(int start_index, bool has_constant_pairs = false) {
FormFormattingConfig cfg = {
.config_set = true,
.hang_forms = false,
.inline_until_index =
[start_index](const std::vector<std::string>& /*curr_lines*/) { return start_index; },
.has_constant_pairs = has_constant_pairs};
auto arg_list_config = std::make_shared<FormFormattingConfig>();
arg_list_config->force_inline = true;
arg_list_config->hang_forms = false;
cfg.index_configs.emplace(2, arg_list_config);
return cfg;
}
static FormFormattingConfig new_inlineable_flow_rule(int start_index,
bool has_constant_pairs = false) {
return {.config_set = true,
.hang_forms = false,
.inline_until_index =
[start_index](const std::vector<std::string>& curr_lines) {
int total_width = 0;
for (const auto& line : curr_lines) {
// Check for comments
// TODO - this shows how this isn't really the best strategy but it holds up
if (str_util::contains(line, ";")) {
// Can't inline, there's a comment!
return start_index;
}
total_width += line.length();
// an empty line implies a new-line was forced, this is bleeding implementation
// details, but fine for now
if (line.empty()) {
return start_index;
}
}
if (total_width <= 120) {
return (int)curr_lines.size();
}
return start_index;
},
.has_constant_pairs = has_constant_pairs};
}
static FormFormattingConfig new_defstate_rule(int start_index, bool has_constant_pairs = false) {
FormFormattingConfig cfg = {
.config_set = true,
.hang_forms = false,
.inline_until_index =
[start_index](const std::vector<std::string>& /*curr_lines*/) { return start_index; },
.has_constant_pairs = has_constant_pairs};
std::vector<int> state_handler_indexes = {4, 6, 8, 10,
12, 14}; // NOTE - not all of these have to be defined
for (const auto& index : state_handler_indexes) {
auto temp_config = std::make_shared<FormFormattingConfig>();
temp_config->prevent_inlining = true;
temp_config->parent_mutable_extra_indent = 2;
cfg.index_config_override.emplace(index, temp_config);
}
return cfg;
}
static FormFormattingConfig new_defmethod_rule(int start_index, bool has_constant_pairs = false) {
// TODO - might be nice to have a function that returns a config based on a given index, instead
// of hardcoding them!
// Right now this only works for non-`new` methods (else we may bleed into the body of a normal
// method)
auto arg_list_config = std::make_shared<FormFormattingConfig>();
arg_list_config->force_inline = true;
arg_list_config->hang_forms = false;
FormFormattingConfig cfg = {.config_set = true,
.hang_forms = false,
.inline_until_index =
[start_index](const std::vector<std::string>& curr_lines) {
if (curr_lines.size() >= 2 && curr_lines.at(1) == "new") {
// defmethod was changed to omit the type name for everything
// except the `new` method, so special case.
return start_index + 1;
}
return start_index;
},
.has_constant_pairs = has_constant_pairs};
cfg.index_configs.emplace(2, arg_list_config);
return cfg;
}
static FormFormattingConfig new_lambda_rule(int start_index, bool has_constant_pairs = false) {
FormFormattingConfig cfg = {.config_set = true,
.hang_forms = false,
.inline_until_index =
[start_index](const std::vector<std::string>& curr_lines) {
if (curr_lines.size() >= 2 && curr_lines.at(1) == ":behavior") {
// defmethod was changed to omit the type name for everything
// except the `new` method, so special case.
return start_index + 2;
}
return start_index;
},
.has_constant_pairs = has_constant_pairs};
return cfg;
}
static FormFormattingConfig new_defenum_rule() {
auto temp_list_config = std::make_shared<FormFormattingConfig>();
temp_list_config->force_inline = true;
temp_list_config->hang_forms = false;
return {
.config_set = true,
.hang_forms = false,
.inline_until_index = [](const std::vector<std::string>& /*curr_lines*/) { return 2; },
.has_constant_pairs = true,
.default_index_config = temp_list_config,
};
.inline_until_index = [start_index](const std::vector<std::string>& /*curr_lines*/) {
return start_index;
}};
}
static FormFormattingConfig new_deftype_rule(
int start_index,
int num_columns_to_compute_widths,
const std::vector<int>& inlining_preventation_indices) {
FormFormattingConfig cfg;
cfg.has_constant_pairs = true;
cfg.config_set = true;
cfg.hang_forms = false;
cfg.inline_until_index = [start_index](std::vector<std::string> curr_lines) {
@@ -161,7 +39,6 @@ static FormFormattingConfig new_deftype_rule(
temp_config->default_index_config = temp_list_config;
if (index == 3) {
temp_config->determine_column_widths_for_list_elements = true;
temp_config->num_columns_to_compute_widths = num_columns_to_compute_widths;
}
cfg.index_configs.emplace(index, temp_config);
}
@@ -197,29 +74,6 @@ static FormFormattingConfig new_binding_rule(int form_head_width) {
return cfg;
}
static FormFormattingConfig new_inline_binding_rule(int form_head_width) {
FormFormattingConfig cfg;
cfg.config_set = true;
cfg.hang_forms = false;
cfg.combine_first_two_lines = true;
auto binding_list_config = std::make_shared<FormFormattingConfig>();
binding_list_config->config_set = true;
binding_list_config->hang_forms = false;
binding_list_config->indentation_width = 1;
binding_list_config->indentation_width_for_index = [form_head_width](FormFormattingConfig /*cfg*/,
int index) {
if (index == 0) {
return 0;
}
return form_head_width;
};
binding_list_config->should_prevent_inlining = [](FormFormattingConfig /*config*/, int num_refs) {
return false;
};
cfg.index_configs.emplace(1, binding_list_config);
return cfg;
}
static FormFormattingConfig new_pair_rule(bool combine_first_two_expr) {
FormFormattingConfig cfg;
cfg.config_set = true;
@@ -234,71 +88,23 @@ static FormFormattingConfig new_pair_rule(bool combine_first_two_expr) {
return cfg;
}
static FormFormattingConfig new_top_level_inline_form(bool elide_new_line) {
return {.force_inline = true, .elide_top_level_newline = elide_new_line};
}
const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config = {
{"case", new_pair_rule(true)},
{"case-str", new_pair_rule(true)},
{"cond", new_pair_rule(false)},
{"#cond", new_pair_rule(false)},
{"in-package", new_top_level_inline_form(true)},
{"bundles", new_top_level_inline_form(true)},
{"require", new_top_level_inline_form(true)},
{"def-art-elt", new_top_level_inline_form(true)},
{"def-joint-node", new_top_level_inline_form(true)},
{"declare-file", new_top_level_inline_form(false)},
{"defenum", new_defenum_rule()},
{"defmethod", new_defmethod_rule(3)},
{"lambda", new_lambda_rule(2)},
{"deftype", new_deftype_rule(3, 1, {3, 4, 5, 6})},
{"defmethod", new_flow_rule(3)},
{"deftype", new_deftype_rule(3, {3, 4, 5, 6})},
{"defun", new_flow_rule(3)},
{"defun-recursive", new_flow_rule(4)},
{"defun-debug-recursive", new_flow_rule(4)},
{"defun-debug", new_flow_rule(3)},
{"defbehavior", new_flow_rule(4)},
{"if", new_inlineable_flow_rule(2)},
{"#if", new_inlineable_flow_rule(2)},
{"if", new_permissive_flow_rule()},
{"define", new_permissive_flow_rule()},
{"def-mips2c", new_permissive_flow_rule()},
{"defconstant", new_permissive_flow_rule()},
{"defglobalconstant", new_permissive_flow_rule()},
{"defmethod-mips2c", new_permissive_flow_rule()},
{"define-extern", new_permissive_flow_rule()},
{"declare-type", new_permissive_flow_rule()},
{"defmacro", new_function_rule(3)},
{"desfun", new_function_rule(3)},
{"defskelgroup", new_flow_rule(2, true)},
{"defpartgroup", new_flow_rule(2, true)},
{"defpart", new_flow_rule(2, true)},
{"defstate", new_defstate_rule(3, true)},
{"behavior", new_flow_rule(2)},
{"defmacro", new_flow_rule(3)},
{"dotimes", new_flow_rule(2)},
{"dolist", new_flow_rule(2)},
{"process-spawn-function", new_flow_rule(2)},
{"let", new_binding_rule(4)},
{"protect", new_binding_rule(4)},
{"let*", new_binding_rule(5)},
{"rlet", new_binding_rule(5)},
{"when", new_flow_rule(2)},
{"unless", new_flow_rule(2)},
{"with-profiler", new_flow_rule(2)},
{"with-pc", new_flow_rule(0)},
{"#unless", new_flow_rule(2)},
{"#when", new_flow_rule(2)},
{"countdown", new_flow_rule(2)},
{"until", new_flow_rule(2)},
{"loop", new_flow_rule(0)},
{"while", new_flow_rule(2)},
{"begin", new_flow_rule(0)},
{"seval", new_flow_rule(0)},
{"with-pp", new_flow_rule(0)},
{"with-gensyms", new_flow_rule(2)},
{"with-vf0", new_flow_rule(0)},
{"with-vf", new_inline_binding_rule(8)},
{"with-cnt-vif-block", new_inline_binding_rule(19)},
{"local-vars", new_inlinable_simple_flow_rule()},
{"with-dma-buffer-add-bucket", new_flow_rule(2)}};
} // namespace config
} // namespace formatter_rules
+1 -5
View File
@@ -7,6 +7,7 @@
#include <unordered_map>
#include <vector>
// TODO - some way to apply a config to all list elements (index configs with -1?)
namespace formatter_rules {
namespace config {
struct FormFormattingConfig {
@@ -32,14 +33,9 @@ struct FormFormattingConfig {
int parent_mutable_extra_indent = 0;
std::optional<std::shared_ptr<FormFormattingConfig>> default_index_config;
std::unordered_map<int, std::shared_ptr<FormFormattingConfig>> index_configs = {};
// TODO / NOTe - not fully implemented, only doing `parent_mutable_extra_indent` right now
std::unordered_map<int, std::shared_ptr<FormFormattingConfig>> index_config_override = {};
bool determine_column_widths_for_list_elements = false;
int num_columns_to_compute_widths = 0;
std::vector<int> list_element_column_widths = {};
bool elide_top_level_newline = false;
};
extern const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config;
+7 -28
View File
@@ -26,8 +26,6 @@ u64 get_current_tid() {
}
#endif
#include "common/log/log.h"
#include "common/util/compress.h"
#include "common/util/string_util.h"
// clang-format on
u64 get_current_ts() {
@@ -36,12 +34,12 @@ u64 get_current_ts() {
GlobalProfiler::GlobalProfiler() {
m_t0 = get_current_ts();
m_nodes.resize(m_max_events);
set_max_events(65536);
}
void GlobalProfiler::update_event_buffer_size(size_t new_size) {
m_max_events = new_size;
m_nodes.resize(m_max_events);
void GlobalProfiler::set_max_events(size_t event_count) {
ASSERT(!m_enabled);
m_nodes.resize(event_count);
}
void GlobalProfiler::set_waiting_for_event(const std::string& event_name) {
@@ -74,10 +72,6 @@ void GlobalProfiler::root_event() {
instant_event("ROOT");
}
size_t GlobalProfiler::get_next_idx() {
return (m_next_idx % m_nodes.size());
}
void GlobalProfiler::begin_event(const char* name) {
event(name, ProfNode::BEGIN);
}
@@ -102,10 +96,8 @@ void GlobalProfiler::set_enable(bool en) {
m_enabled = en;
}
void GlobalProfiler::dump_to_json() {
if (m_enabled) {
set_enable(false);
}
void GlobalProfiler::dump_to_json(const std::string& path) {
ASSERT(!m_enabled);
nlohmann::json json;
auto& trace_events = json["traceEvents"];
@@ -193,20 +185,7 @@ void GlobalProfiler::dump_to_json() {
t.second.highest_at_target);
}
if (m_enable_compression) {
const auto json_str = json.dump();
const auto compressed_data =
compression::compress_zstd_no_header(json_str.data(), json_str.size());
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
fmt::format("prof-{}.json.zst", str_util::current_local_timestamp_no_colons());
file_util::create_dir_if_needed_for_file(file_path);
file_util::write_binary_file(file_path, compressed_data.data(), compressed_data.size());
} else {
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
fmt::format("prof-{}.json", str_util::current_local_timestamp_no_colons());
file_util::create_dir_if_needed_for_file(file_path);
file_util::write_text_file(file_path, json.dump());
}
file_util::write_text_file(path, json.dump());
}
GlobalProfiler gprof;
+2 -8
View File
@@ -17,8 +17,7 @@ struct ProfNode {
class GlobalProfiler {
public:
GlobalProfiler();
size_t get_max_events() { return m_max_events; }
void update_event_buffer_size(size_t new_size);
void set_max_events(size_t event_count);
void set_waiting_for_event(const std::string& event_name);
void instant_event(const char* name);
void begin_event(const char* name);
@@ -26,16 +25,11 @@ class GlobalProfiler {
void end_event();
void clear();
void set_enable(bool en);
void dump_to_json();
void dump_to_json(const std::string& path);
void root_event();
bool is_enabled() { return m_enabled; }
size_t get_next_idx();
bool m_enable_compression = false;
private:
std::atomic_bool m_enabled = false;
size_t m_max_events = 65536;
u64 m_t0 = 0;
std::atomic_size_t m_next_idx = 0;
std::vector<ProfNode> m_nodes;
+1
View File
@@ -12,6 +12,7 @@
#include "Reader.h"
#include "common/log/log.h"
#include "common/repl/util.h"
#include "common/util/FileUtil.h"
#include "common/util/FontUtils.h"
+1 -1
View File
@@ -18,7 +18,7 @@
#include "common/goos/Object.h"
#include "common/goos/TextDB.h"
#include "common/repl/repl_wrapper.h"
#include "common/repl/util.h"
#include "common/util/Assert.h"
namespace goos {
+4 -4
View File
@@ -140,7 +140,7 @@ void printstd(const char* format, va_list arg_list) {
internal::log_vprintf(format, arg_list);
}
// how many extra log files for a single program should be kept
// how many extra log files for a single program should be kept?
constexpr int LOG_ROTATE_MAX = 10;
void set_file(const std::string& filename,
@@ -163,7 +163,7 @@ void set_file(const std::string& filename,
file_util::find_files_in_dir(fs::path(complete_filename).parent_path(),
std::regex(fmt::format("{}\\.(\\d\\.)?log", filename)));
for (const auto& file : old_log_files) {
lg::debug("removing {}", file.string());
lg::info("removing {}", file.string());
fs::remove(file);
}
// remove the oldest log file if there are more than LOG_ROTATE_MAX
@@ -172,9 +172,9 @@ void set_file(const std::string& filename,
// sort the names and remove them
existing_log_files = file_util::sort_filepaths(existing_log_files, true);
if (existing_log_files.size() > (LOG_ROTATE_MAX - 1)) {
lg::debug("removing {} log files", existing_log_files.size() - (LOG_ROTATE_MAX - 1));
lg::info("removing {} log files", existing_log_files.size() - (LOG_ROTATE_MAX - 1));
for (int i = 0; i < (int)existing_log_files.size() - (LOG_ROTATE_MAX - 1); i++) {
lg::debug("removing {}", existing_log_files.at(i).string());
lg::info("removing {}", existing_log_files.at(i).string());
fs::remove(existing_log_files.at(i));
}
}
-9
View File
@@ -7,21 +7,15 @@
namespace REPL {
void to_json(json& j, const Config& obj) {
j = json{
{"nreplPort", obj.nrepl_port},
{"gameVersionFolder", obj.game_version_folder},
{"numConnectToTargetAttempts", obj.target_connect_attempts},
{"asmFileSearchDirs", obj.asm_file_search_dirs},
{"keybinds", obj.keybinds},
{"perGameHistory", obj.per_game_history},
{"permissiveRedefinitions", obj.permissive_redefinitions},
};
}
void from_json(const json& j, Config& obj) {
// TODO - make a camelCase variant of json_serialize/deserialize macros
if (j.contains("nreplPort")) {
j.at("nreplPort").get_to(obj.nrepl_port);
}
if (j.contains("gameVersionFolder")) {
j.at("gameVersionFolder").get_to(obj.game_version_folder);
}
@@ -61,9 +55,6 @@ void from_json(const json& j, Config& obj) {
if (j.contains("perGameHistory")) {
j.at("perGameHistory").get_to(obj.per_game_history);
}
if (j.contains("permissiveRedefinitions")) {
j.at("permissiveRedefinitions").get_to(obj.permissive_redefinitions);
}
// if there is game specific configuration, override any values we just set
if (j.contains(version_to_game_name(obj.game_version))) {
from_json(j.at(version_to_game_name(obj.game_version)), obj);
-11
View File
@@ -26,14 +26,11 @@ struct KeyBind {
void to_json(json& j, const KeyBind& obj);
void from_json(const json& j, KeyBind& obj);
// TODO - per-game config
struct Config {
GameVersion game_version;
Config(GameVersion _game_version) : game_version(_game_version){};
// this is the default REPL configuration
int nrepl_port = 8181;
int temp_nrepl_port = -1;
std::string game_version_folder;
int target_connect_attempts = 30;
std::vector<std::string> asm_file_search_dirs = {};
@@ -48,14 +45,6 @@ struct Config {
{KeyBind::Modifier::CTRL, "B", "Displays the most recently caught backtrace", "(:di)"},
{KeyBind::Modifier::CTRL, "N", "Full build of the game", "(mi)"}};
bool per_game_history = true;
bool permissive_redefinitions = false;
int get_nrepl_port() {
if (temp_nrepl_port != -1) {
return temp_nrepl_port;
}
return nrepl_port;
}
};
void to_json(json& j, const Config& obj);
void from_json(const json& j, Config& obj);
+33 -60
View File
@@ -16,6 +16,10 @@
#include "common/log/log.h"
// clang-format on
// TODO - basically REPL to listen and inject commands into a running REPL
// - we will need a C++ side client as well which will let us communicate with the repl via for
// example, ImgUI
//
// TODO - The server also needs to eventually return the result of the evaluation
ReplServer::~ReplServer() {
@@ -27,18 +31,7 @@ ReplServer::~ReplServer() {
void ReplServer::post_init() {
// Add the listening socket to our set of sockets
lg::debug("[nREPL:{}:{}] awaiting connections", tcp_port, listening_socket);
}
void ReplServer::error_response(int socket, const std::string& error) {
std::string msg = fmt::format("[ERROR]: {}", error);
auto resp = write_to_socket(socket, msg.c_str(), msg.size());
if (resp == -1) {
lg::warn("[nREPL:{}] Client Disconnected: {}", tcp_port, address_to_string(addr),
ntohs(addr.sin_port), socket);
close_socket(socket);
client_sockets.erase(socket);
}
lg::info("[nREPL:{}:{}] awaiting connections", tcp_port, listening_socket);
}
void ReplServer::ping_response(int socket) {
@@ -59,6 +52,7 @@ std::optional<std::string> ReplServer::get_msg() {
// Add the server's main listening socket (where we accept clients from)
FD_SET(listening_socket, &read_sockets);
int max_sd = listening_socket;
for (const int& sock : client_sockets) {
if (sock > max_sd) {
@@ -70,11 +64,12 @@ std::optional<std::string> ReplServer::get_msg() {
}
// Wait for activity on _something_, with a timeout so we don't get stuck here on exit.
struct timeval timeout = {0, 100000};
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
auto activity = select(max_sd + 1, &read_sockets, NULL, NULL, &timeout);
if (activity < 0 && errno != EINTR) {
lg::error("[nREPL:{}] select error, returned: {}, errno: {}", tcp_port, activity,
strerror(errno));
if (activity < 0) { // TODO - || error!
return std::nullopt;
}
@@ -83,46 +78,44 @@ std::optional<std::string> ReplServer::get_msg() {
socklen_t addr_len = sizeof(addr);
auto new_socket = accept_socket(listening_socket, (sockaddr*)&addr, &addr_len);
if (new_socket < 0) {
if (new_socket != -1) {
lg::error("[nREPL:{}] accept error, returned: {}, errono: {}", tcp_port, new_socket,
strerror(errno));
}
// TODO - handle error
} else {
lg::info("[nREPL:{}]: New socket connection: {}:{}:{}", tcp_port, address_to_string(addr),
ntohs(addr.sin_port), new_socket);
// Say hello
ping_response(new_socket);
// Track the new socket
if ((int)client_sockets.size() < max_clients) {
client_sockets.insert(new_socket);
} else {
// Respond with NO and close the socket
lg::warn("[nREPL:{}]: Maximum clients reached. Rejecting connection.", tcp_port);
error_response(new_socket, "Maximum clients reached. Rejecting connection.");
close_socket(new_socket);
// TODO - Respond with NO
}
}
}
// Check all clients for activity
for (auto it = client_sockets.begin(); it != client_sockets.end();) {
int sock = *it;
// otherwise (and no matter what) check all the clients to see if they have sent us anything
// else its some IO operation on some other socket
//
// RACE - the first client wins
// TODO - there are ways to do this with iterators but, couldn't figure it out!
std::vector<int> sockets_to_scan(client_sockets.begin(), client_sockets.end());
for (const int& sock : sockets_to_scan) {
if (FD_ISSET(sock, &read_sockets)) {
// Attempt to read a header
// TODO - should this be in a loop?
auto req_bytes = read_from_socket(sock, header_buffer.data(), header_buffer.size());
if (req_bytes <= 0) {
if (req_bytes == 0) {
// Socket disconnected
// TODO - add a queue of messages in the REPL::Wrapper so we can print _BEFORE_ the prompt
// is output
if (req_bytes == 0) {
lg::warn("[nREPL:{}] Client Disconnected: {}", tcp_port, address_to_string(addr));
} else {
lg::warn("[nREPL:{}] Error reading from socket on {}: {}", tcp_port,
address_to_string(addr), strerror(errno));
}
lg::warn("[nREPL:{}] Client Disconnected: {}", tcp_port, address_to_string(addr),
ntohs(addr.sin_port), sock);
// Cleanup the socket and remove it from our set
close_socket(sock);
it = client_sockets.erase(it); // Erase and move to the next element
continue;
client_sockets.erase(sock);
} else {
// Otherwise, process the message
auto* header = (ReplServerHeader*)(header_buffer.data());
@@ -130,12 +123,7 @@ std::optional<std::string> ReplServer::get_msg() {
int expected_size = header->length;
int got = 0;
int tries = 0;
bool skip_to_next_socket = false;
while (got < expected_size) {
if (want_exit_callback()) {
lg::warn("[nREPL:{}] Terminating nREPL early", tcp_port);
return std::nullopt;
}
tries++;
if (tries > 100) {
break;
@@ -147,25 +135,11 @@ std::optional<std::string> ReplServer::get_msg() {
tcp_port, got, expected_size, buffer.size());
return std::nullopt;
}
auto bytes_read = read_from_socket(sock, buffer.data() + got, expected_size - got);
if (bytes_read <= 0) {
if (bytes_read == 0) {
lg::warn("[nREPL:{}] Client Disconnected: {}", tcp_port, address_to_string(addr));
} else {
lg::warn("[nREPL:{}] Error reading from socket on {}: {}", tcp_port,
address_to_string(addr), strerror(errno));
}
close_socket(sock);
it = client_sockets.erase(it); // Erase and move to the next element
skip_to_next_socket = true;
break;
auto x = read_from_socket(sock, buffer.data() + got, expected_size - got);
if (want_exit_callback()) {
return std::nullopt;
}
got += bytes_read;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
if (skip_to_next_socket) {
continue;
got += x > 0 ? x : 0;
}
switch (header->type) {
@@ -179,7 +153,6 @@ std::optional<std::string> ReplServer::get_msg() {
}
}
}
++it;
}
return std::nullopt;
}
-1
View File
@@ -27,6 +27,5 @@ class ReplServer : public XSocketServer {
fd_set read_sockets;
std::set<int> client_sockets = {};
void error_response(int socket, const std::string& error);
void ping_response(int socket);
};
@@ -1,4 +1,4 @@
#include "repl_wrapper.h"
#include "util.h"
#include "common/util/FileUtil.h"
#include "common/util/json_util.h"
@@ -8,66 +8,36 @@
#include "fmt/color.h"
#include "fmt/core.h"
#include "third-party/replxx/include/replxx.hxx"
// TODO - expand a list of hints (ie. a hint for defun to show at a glance how to write a function,
// or perhaps, show the docstring for the current function being used?)
namespace REPL {
void Wrapper::clear_screen() {
repl.clear_screen();
}
void Wrapper::print_welcome_message(const std::vector<std::string>& loaded_projects) {
std::string message;
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " ..:::::..\n");
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .:-----------:.\n");
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-----.");
message += fmt::format(fmt::emphasis::bold, " Welcome to OpenGOAL {}.{} [{}]",
versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR,
fmt::format(fg(fmt::color::gray), "{}", build_revision()));
if (!username.empty() && username != "#f" && username != "unknown") {
message += fmt::format(fg(fmt::color::light_green), " {}", username);
}
message += "!\n";
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .---.");
if (repl_config.game_version == GameVersion::Jak1) {
message += fmt::format(" [{}]: ", fmt::format(fg(fmt::color::orange), "jak1"));
} else if (repl_config.game_version == GameVersion::Jak2) {
message += fmt::format(" [{}]: ", fmt::format(fg(fmt::color::purple), "jak2"));
} else if (repl_config.game_version == GameVersion::Jak3) {
message += fmt::format(" [{}]: ", fmt::format(fg(fmt::color::gold), "jak3"));
} else {
message += fmt::format(" [{}]: ", fmt::format(fg(fmt::color::magenta), "jakx"));
}
const auto loaded_projects_str = fmt::format("{}", fmt::join(loaded_projects, ","));
message += fmt::format(fg(fmt::color::gray), "{}\n", loaded_projects_str);
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " . --- .");
message +=
fmt::format(" Project Path: {}\n",
fmt::format(fg(fmt::color::gray), file_util::get_jak_project_dir().string()));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " - :===: -");
message += " nREPL:";
if (!nrepl_alive) {
message += fmt::format(fg(fmt::color::red), "DISABLED\n");
} else {
message += fmt::format(fg(fmt::color::light_green), " Listening on {}\n",
repl_config.get_nrepl_port());
}
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " --. .--: :--. .--");
message += " Source File Search Dirs: ";
const auto search_dir_string =
fmt::format("{}", fmt::join(repl_config.asm_file_search_dirs, ","));
message += fmt::format("[{}]\n", fmt::format(fg(fmt::color::gray), search_dir_string));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .=======. =======.");
message += fmt::format(" {} or {} for basic help and usage\n",
fmt::format(fg(fmt::color::cyan), "(repl-help)"),
fmt::format(fg(fmt::color::cyan), "(repl-keybinds)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-=====-. .-=====-");
message +=
fmt::format(" {} to connect to the game\n", fmt::format(fg(fmt::color::cyan), "(lt)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===========-.");
message += fmt::format(" {} to recompile the active project.\n",
fmt::format(fg(fmt::color::cyan), "(mi)"));
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .-===-.\n");
message += fmt::format(fmt::emphasis::bold | fg(fmt::color::orange), " .\n");
fmt::print("{}", message);
void Wrapper::print_welcome_message() {
// TODO - dont print on std-out
// Welcome message / brief intro for documentation
std::string ascii;
ascii += " _____ _____ _____ _____ __ \n";
ascii += "| |___ ___ ___| __| | _ | | \n";
ascii += "| | | . | -_| | | | | | | |__ \n";
ascii += "|_____| _|___|_|_|_____|_____|__|__|_____|\n";
ascii += " |_| \n";
fmt::print(fmt::emphasis::bold | fg(fmt::color::orange), ascii);
fmt::print("Welcome to OpenGOAL {}.{}!\n", versions::GOAL_VERSION_MAJOR,
versions::GOAL_VERSION_MINOR);
fmt::print("Run {} or {} for help with common commands and REPL usage.\n",
fmt::styled("(repl-help)", fmt::emphasis::bold | fg(fmt::color::cyan)),
fmt::styled("(repl-keybinds)", fmt::emphasis::bold | fg(fmt::color::cyan)));
fmt::print("Run ");
fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(lt)");
fmt::print(" to connect to the local target.\n");
fmt::print("Run ");
fmt::print(fmt::emphasis::bold | fg(fmt::color::cyan), "(mi)");
fmt::print(" to rebuild the entire game.\n\n");
}
void Wrapper::print_to_repl(const std::string& str) {
@@ -272,24 +242,20 @@ StartupFile load_user_startup_file(const std::string& username, const GameVersio
return startup_file;
}
REPL::Config load_repl_config(const std::string& username,
const GameVersion game_version,
const int nrepl_port) {
REPL::Config load_repl_config(const std::string& username, const GameVersion game_version) {
auto repl_config_path =
file_util::get_jak_project_dir() / "goal_src" / "user" / username / "repl-config.json";
REPL::Config loaded_config(game_version);
if (file_util::file_exists(repl_config_path.string())) {
try {
REPL::Config config(game_version);
auto repl_config_data =
parse_commented_json(file_util::read_text_file(repl_config_path), "repl-config.json");
from_json(repl_config_data, loaded_config);
loaded_config.temp_nrepl_port = nrepl_port;
return loaded_config;
from_json(repl_config_data, config);
return config;
} catch (std::exception& e) {
// do nothing
REPL::Config config(game_version);
}
}
loaded_config.temp_nrepl_port = nrepl_port;
return loaded_config;
return REPL::Config(game_version);
}
} // namespace REPL
@@ -17,23 +17,18 @@ struct StartupFile {
};
class Wrapper {
replxx::Replxx repl;
public:
std::string username;
Config repl_config;
StartupFile startup_file;
bool nrepl_alive = false;
std::vector<std::string> examples{};
std::vector<std::pair<std::string, replxx::Replxx::Color>> regex_colors{};
Wrapper(GameVersion version) : repl_config(version) {}
Wrapper(const std::string& _username,
const Config& config,
const StartupFile& startup,
bool _nrepl_alive)
: username(_username),
repl_config(config),
startup_file(startup),
nrepl_alive(_nrepl_alive) {}
Wrapper(const std::string& _username, const Config& config, const StartupFile& startup)
: username(_username), repl_config(config), startup_file(startup) {}
replxx::Replxx& get_repl() { return repl; }
void init_settings();
void reload_startup_file();
@@ -41,7 +36,7 @@ class Wrapper {
// Functionality / Commands
void clear_screen();
void print_to_repl(const std::string& str);
void print_welcome_message(const std::vector<std::string>& loaded_projects);
void print_welcome_message();
void set_history_max_size(size_t len);
const char* readline(const std::string& prompt);
void add_to_history(const std::string& line);
@@ -52,14 +47,11 @@ class Wrapper {
std::pair<std::string, bool> get_current_repl_token(std::string const& context);
private:
replxx::Replxx repl;
replxx::Replxx::key_press_handler_t commit_text_action(std::string text_to_commit);
std::vector<REPL::KeyBind> keybindings = {};
};
std::string find_repl_username();
StartupFile load_user_startup_file(const std::string& username, const GameVersion game_version);
REPL::Config load_repl_config(const std::string& username,
const GameVersion game_version,
const int nrepl_port);
REPL::Config load_repl_config(const std::string& username, const GameVersion game_version);
} // namespace REPL
@@ -89,9 +89,7 @@ const std::unordered_map<std::string, u16> jak2_speaker_name_to_enum_val = {
{"citizen-male", 31},
{"citizen-female", 32},
{"oracle", 33},
{"precursor", 34},
{"metalkor-before-consite", 35},
{"metalkor-intro", 36}};
{"precursor", 34}};
GameSubtitlePackage read_json_files_v2(const GameSubtitleDefinitionFile& file_info) {
GameSubtitlePackage package;
+1 -147
View File
@@ -42,153 +42,7 @@ std::vector<std::string> jak2_slots = {
"cas-toxic-slime-scroll-dest",
};
std::vector<std::string> jak3_slots = {
"skull-gem-dest",
"jakc-arm",
"jakc-eyebrow",
"jakc-face",
"jakc-finger",
"jakc-hair",
"jakchires-arm",
"jakchires-eye",
"jakchires-eyebrow",
"jakchires-eyelid",
"jakchires-facelft",
"jakchires-facert",
"jakchires-hair",
// default-water
"bomb-gradient",
"blue-beam-dest",
"lightjak-wings",
"mushroom-dest",
// default-warp
"shield-env-rim-dest",
// templea-water
"templea-waterfall-dest",
// templea-warp
"holograph-env-rim-dest",
// hanga-sprite
"glider-ring-dest2",
"glider-ring-dest",
// foresta-water
"fora-water-dest",
"fora-waterfall-01-dest",
"fora-water-wave-01-dest",
// forestb-water
"forb-water-dest",
"forb-waterfall-01-dest",
"forb-water-wave-01-dest",
// lforplnt-pris
"mh-gem-dest",
// lmhcitya-tfrag
"mhcitya-base-goo-01-dest",
// lmhcityb-tfrag
"mhcityb-base-goo-01-dest",
// mhcitya-pris
// "mhcity-de-door-skin-01-dest",
// templec-water
"tplc-water-dest",
// sewc-water
"sewer-water-01-c-dest",
"sewer-waterfall-01-c-dest",
"sewer-waterfall-02-c-dest",
"sewer-water-wave-01-c-dest",
"sewer-water-highlight-01-c-dest",
// sewd-water
"sewer-water-01-d-dest",
"sewer-waterfall-02-d-dest",
"sewer-water-highlight-01-d-dest",
"sewer-water-wave-01-d-dest",
"sewer-water-wave-02-d-dest",
"sewer-water-still-01-d-dest",
// sewe-water
"sewer-water-01-e-dest",
"sewer-waterfall-01-e-dest",
"sewer-waterfall-02-e-dest",
"sewer-water-highlight-01-e-dest",
// sewg-water
"sewer-water-01-g-dest",
"sewer-waterfall-02-g-dest",
"sewer-water-wave-01-g-dest",
// sewh-water
"sewer-water-01-h-dest",
"sewer-waterfall-02-h-dest",
"sewer-water-wave-02-h-dest",
"sewer-watefall-froth-01-h-dest",
// sewi-water
"sewer-water-still-01-i-dest",
"sewer-waterfall-02-i-dest",
"sewer-water-wave-01-i-dest",
// sewj-water
"sewer-waterfall-02-j-dest",
"sewer-watefall-froth-01-j-dest",
// sewl-water
"sewer-waterfall-02-l-dest",
"sewer-watefall-froth-01-l-dest",
// sewm-water
"sewer-water-01-m-dest",
"sewer-waterfall-01-m-dest",
"sewer-waterfall-02-m-dest",
"sewer-water-highlight-01-m-dest",
"sewer-water-wave-01-m-dest",
"sewer-water-still-01-m-dest",
"sewer-watefall-froth-01-m-dest",
// sewn-water
"sewer-waterfall-01-n-dest",
"sewer-waterfall-02-n-dest",
// "sewer-water-highlight-01-n-dest",
"sewer-water-wave-01-n-dest",
"sewer-water-still-01-n-dest",
// hanga-water
// "des-thermal-01-dest",
// desresc-warp
"sat-shield-dest",
// security
"security-env-dest",
"security-dot-dest",
// lgunnorm-water
"kg-target-c-forcefield-01-dest",
// templex-water
"temple-waterfall-dest",
// desertd-water
"des-waterfall-dest",
// towerb-water
"tow-energy-bridge-dest",
// factoryb-water
"hemi-gradient-dest",
"hemi-gradient-flames-dest",
// factoryc-alpha
"facc-convey-dest",
"facc-convey-02-dest",
// waspal-water
"waspala-water-dest",
"waspala-waterfall-dest",
// rubblea-water
"rub-water-dest",
// rubblea2-water
"rub-water-desta2",
// rubbleb-water
"rub-water-destb",
// rubblec-water
"rub-water-destc",
// nstb-quicksand
"nstb-quicksand-dest",
// ctyslumb-water
"ctyslumb-water-dest",
"ctyslumb-fountain-fall-dest",
// ctyslumc-water
"ctyslumc-water-dest",
"ctyslumc-fountain-fall-dest",
// mined-tfrag
"mined-pillar-side-dest",
"mined-pillar-top2side-dest",
"mined-pillar-top-dest",
// volcanoa-alpha
"vola-lava-01-dest",
"vola-lava-fall-dest",
// wasstada-alpha
"wstd-lava-base-dest",
};
std::vector<std::string> jak3_slots = {};
} // namespace
-4
View File
@@ -28,12 +28,8 @@ struct MethodInfo {
std::string name;
TypeSpec type;
std::string defined_in_type;
// TODO - this might be redundant, but preventing an unknown breaking change, clean it up later
std::string type_name;
bool no_virtual = false;
// TODO - this is no longer used anymore...but was not removed from th4e struct?
bool overrides_parent = false;
// TODO - this is no longer used anymore...but was not removed from th4e struct?
bool only_overrides_docstring = false;
std::optional<std::string> docstring;
std::optional<std::string> overlay_name;
-2
View File
@@ -124,12 +124,10 @@ class TypeSpec {
ASSERT(m_arguments);
return m_arguments->at(idx);
}
TypeSpec& get_arg(int idx) {
ASSERT(m_arguments);
return m_arguments->at(idx);
}
const TypeSpec& last_arg() const {
ASSERT(m_arguments);
ASSERT(!m_arguments->empty());
+4 -9
View File
@@ -548,7 +548,6 @@ MethodInfo TypeSystem::override_method(Type* type,
existing_info.name,
existing_info.type,
type->get_name(),
type->get_name(),
existing_info.no_virtual,
false,
true,
@@ -608,7 +607,6 @@ MethodInfo TypeSystem::declare_method(Type* type,
method_name,
ts,
type->get_name(),
type->get_name(),
no_virtual,
true,
false,
@@ -647,7 +645,6 @@ MethodInfo TypeSystem::declare_method(Type* type,
method_name,
ts,
type->get_name(),
type->get_name(),
no_virtual,
false,
false,
@@ -681,8 +678,8 @@ MethodInfo TypeSystem::overlay_method(Type* type,
}
// use the existing ID.
return type->add_method({existing_info.id, method_name, ts, type->get_name(), type->get_name(),
false, true, false, docstring, std::make_optional(method_overlay_name)});
return type->add_method({existing_info.id, method_name, ts, type->get_name(), false, true, false,
docstring, std::make_optional(method_overlay_name)});
}
MethodInfo TypeSystem::define_method(const std::string& type_name,
@@ -712,10 +709,8 @@ MethodInfo TypeSystem::define_method(Type* type,
// look up the method
MethodInfo existing_info;
bool got_existing = try_lookup_method(type, method_name, &existing_info);
if (got_existing) {
// The lookup will return a parents method, but the type should be equal
// to the type in question (it's a child)
existing_info.type_name = type->get_name();
// Update the docstring
existing_info.docstring = docstring;
int bad_arg_idx = -99;
@@ -763,7 +758,7 @@ MethodInfo TypeSystem::add_new_method(Type* type,
return existing;
} else {
return type->add_new_method(
{0, "new", ts, type->get_name(), type->get_name(), false, false, false, docstring, {}});
{0, "new", ts, type->get_name(), false, false, false, docstring, {}});
}
}
+2 -4
View File
@@ -58,11 +58,10 @@ EnumType* parse_defenum(const goos::Object& defenum,
auto& enum_name_obj = car(iter);
iter = cdr(iter);
// check for docstring
std::optional<std::string> maybe_docstring;
if (iter->is_pair() && car(iter).is_string()) {
// TODO - docstring - store and use docstring if coming from the compiler
if (symbol_metadata) {
maybe_docstring = str_util::trim_newline_indents(car(iter).as_string()->data);
symbol_metadata->docstring = maybe_docstring.value();
symbol_metadata->docstring = str_util::trim_newline_indents(car(iter).as_string()->data);
}
iter = cdr(iter);
}
@@ -158,7 +157,6 @@ EnumType* parse_defenum(const goos::Object& defenum,
if (is_type("integer", base_type, ts)) {
auto parent = ts->get_type_of_type<ValueType>(base_type.base_type());
auto new_type = std::make_unique<EnumType>(parent, name, is_bitfield, entries);
new_type->m_metadata.docstring = maybe_docstring;
new_type->set_runtime_type(parent->get_runtime_name());
return dynamic_cast<EnumType*>(ts->add_type(name, std::move(new_type)));
} else {
-3
View File
@@ -36,9 +36,6 @@
#define ASSERT_NOT_REACHED_MSG(STR) \
(void)((private_assert_failed("not reached", __FILE__, __LINE__, __PRETTY_FUNCTION__, STR), 0))
#define ASSERT_EQ_IMM(EXPR, EXPECTED) \
ASSERT_MSG((EXPR) == (EXPECTED), fmt::format("result was {}, expected {}", (EXPR), (EXPECTED)))
#else
#define ASSERT(EX) ((void)0)
+8 -21
View File
@@ -185,11 +185,9 @@ std::optional<std::string> try_get_jak_project_path() {
return try_get_project_path_from_path(get_current_executable_path());
}
std::optional<fs::path> try_get_data_dir(bool skip_logs) {
std::optional<fs::path> try_get_data_dir() {
fs::path my_path = get_current_executable_path();
if (!skip_logs) {
lg::debug("Current executable directory - {}", my_path.string());
}
lg::info("Current executable directory - {}", my_path.string());
auto data_dir = my_path.parent_path() / "data";
if (fs::exists(data_dir) && fs::is_directory(data_dir)) {
return std::make_optional(data_dir);
@@ -198,7 +196,7 @@ std::optional<fs::path> try_get_data_dir(bool skip_logs) {
}
}
bool setup_project_path(std::optional<fs::path> project_path_override, bool skip_logs) {
bool setup_project_path(std::optional<fs::path> project_path_override) {
if (g_file_path_info.initialized) {
return true;
}
@@ -206,20 +204,16 @@ bool setup_project_path(std::optional<fs::path> project_path_override, bool skip
if (project_path_override) {
g_file_path_info.path_to_data_folder = fs::absolute(project_path_override.value());
g_file_path_info.initialized = true;
if (!skip_logs) {
lg::debug("Using explicitly set project path: {}",
g_file_path_info.path_to_data_folder.string());
}
lg::info("Using explicitly set project path: {}",
g_file_path_info.path_to_data_folder.string());
return true;
}
auto data_path = try_get_data_dir(skip_logs);
auto data_path = try_get_data_dir();
if (data_path) {
g_file_path_info.path_to_data_folder = *data_path;
g_file_path_info.initialized = true;
if (!skip_logs) {
lg::debug("Using data path: {}", data_path->string());
}
lg::info("Using data path: {}", data_path->string());
return true;
}
@@ -227,9 +221,7 @@ bool setup_project_path(std::optional<fs::path> project_path_override, bool skip
if (development_repo_path) {
g_file_path_info.path_to_data_folder = *development_repo_path;
g_file_path_info.initialized = true;
if (!skip_logs) {
lg::debug("Using development repo path: {}", *development_repo_path);
}
lg::info("Using development repo path: {}", *development_repo_path);
return true;
}
@@ -820,9 +812,4 @@ std::pair<int, std::string> get_majority_file_line_endings_and_count(
return {lf_count + crlf_count, "\n"};
}
bool is_dir_in_dir(const fs::path& parent, const fs::path& child) {
// Check if the parent path is a prefix of the child path
return child.has_parent_path() && child.parent_path().lexically_relative(parent) == fs::path(".");
}
} // namespace file_util
+1 -2
View File
@@ -43,7 +43,7 @@ bool create_dir_if_needed_for_file(const std::string& path);
bool create_dir_if_needed_for_file(const fs::path& path);
std::string get_current_executable_path();
std::optional<std::string> try_get_project_path_from_path(const std::string& path);
bool setup_project_path(std::optional<fs::path> project_path_override, bool skip_logs = false);
bool setup_project_path(std::optional<fs::path> project_path_override);
void override_user_config_dir(fs::path user_config_dir_override,
bool use_overridden_config_dir_for_saves);
std::string get_file_path(const std::vector<std::string>& path);
@@ -79,5 +79,4 @@ std::string make_screenshot_filepath(const GameVersion game_version, const std::
std::string get_majority_file_line_endings(const std::string& file_contents);
std::pair<int, std::string> get_majority_file_line_endings_and_count(
const std::string& file_contents);
bool is_dir_in_dir(const fs::path& parent, const fs::path& child);
} // namespace file_util
-3
View File
@@ -985,8 +985,6 @@ static std::vector<ReplaceInfo> s_replace_info_jak2 = {
{"o~Y~-26H~-4V'~Z", "ó"},
{"U~Y~-24H~-3V'~Z", "Ú"},
{"u~Y~-24H~-3V'~Z", "ú"},
{"Z~Y~-24H~-3V'~Z", "Ź"},
{"z~Y~-24H~-3V'~Z", "ź"},
// circumflex
{"A~Y~-20H~-4V^~Z", "Â"},
@@ -1017,7 +1015,6 @@ static std::vector<ReplaceInfo> s_replace_info_jak2 = {
{"a~Y~-25H~-5V¨~Z", "ä"},
{"E~Y~-20H~-5V¨~Z", "Ë"},
{"I~Y~-19H~-5V¨~Z", "Ï"},
{"i~Y~-26H~-4V¨~Z", "ï"},
{"O~Y~-26H~-8V¨~Z", "Ö"},
{"o~Y~-26H~-4V¨~Z", "ö"},
{"U~Y~-25H~-8V¨~Z", "Ü"},
-13
View File
@@ -46,17 +46,4 @@ std::vector<u8> decompress_zstd(const void* data, size_t size) {
ASSERT(decomp_size == decompressed_size);
return result;
}
std::vector<u8> compress_zstd_no_header(const void* data, size_t size) {
size_t max_compressed = ZSTD_compressBound(size);
std::vector<u8> result(max_compressed);
size_t compressed_size = ZSTD_compress(result.data(), max_compressed, data, size, 1);
if (ZSTD_isError(compressed_size)) {
ASSERT_MSG(false, fmt::format("ZSTD error: {}", ZSTD_getErrorName(compressed_size)));
}
result.resize(compressed_size);
return result;
}
} // namespace compression
+1 -2
View File
@@ -8,5 +8,4 @@ namespace compression {
// compress and decompress data with zstd
std::vector<u8> compress_zstd(const void* data, size_t size);
std::vector<u8> decompress_zstd(const void* data, size_t size);
std::vector<u8> compress_zstd_no_header(const void* data, size_t size);
} // namespace compression
} // namespace compression
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include <string>
#include "common/common_types.h"
inline u64 fnv64(const void* data, u64 len) {
u64 ret = 0xcbf29ce484222325;
const auto* ptr = (const u8*)data;
for (u64 i = 0; i < len; i++) {
ret = 1099511628211 * (((u64)*ptr) ^ ret);
ptr++;
}
return ret;
}
inline u64 fnv64(const std::string& str) {
return fnv64(str.data(), str.length());
}
-467
View File
@@ -1,467 +0,0 @@
#include "gltf_util.h"
#include "common/log/log.h"
namespace gltf_util {
/*!
* Convert a GLTF position buffer or similar to std::vector<Vec3f>
*/
std::vector<math::Vector3f> extract_vec3f(const u8* data, u32 count, u32 stride) {
std::vector<math::Vector3f> result;
result.reserve(count);
for (u32 i = 0; i < count; i++) {
memcpy(&result.emplace_back(), data, sizeof(math::Vector3f));
data += stride;
}
return result;
}
std::vector<math::Vector2f> extract_vec2f(const u8* data, u32 count, u32 stride) {
std::vector<math::Vector2f> result;
result.reserve(count);
for (u32 i = 0; i < count; i++) {
memcpy(&result.emplace_back(), data, sizeof(math::Vector2f));
data += stride;
}
return result;
}
/*!
* Convert a GLTF color buffer (float format) to u8 colors.
*/
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_float(const u8* data,
u32 count,
u32 stride) {
std::vector<math::Vector<u8, 4>> result;
result.reserve(count);
for (u32 i = 0; i < count; i++) {
math::Vector<float, 4> temp;
memcpy(&temp, data, sizeof(math::Vector<float, 4>));
data += stride;
result.emplace_back(temp.x() * 255, temp.y() * 255, temp.z() * 255, temp.w() * 255);
}
return result;
}
/*!
* Convert a GLTF color buffer (u16 format) to u8 colors.
*/
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u16(const u8* data,
u32 count,
u32 stride) {
std::vector<math::Vector<u8, 4>> result;
result.reserve(count);
for (u32 i = 0; i < count; i++) {
math::Vector<u16, 4> temp;
memcpy(&temp, data, sizeof(math::Vector<u16, 4>));
data += stride;
result.emplace_back(temp.x() >> 8, temp.y() >> 8, temp.z() >> 8, temp.w() >> 8);
}
return result;
}
/*!
* Convert a GLTF index buffer
*/
std::vector<u32> gltf_index_buffer(const tinygltf::Model& model,
int indices_idx,
u32 index_offset) {
const auto& indices_accessor = model.accessors[indices_idx];
const auto& buffer_view = model.bufferViews[indices_accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const auto data_ptr = buffer.data.data() + buffer_view.byteOffset + indices_accessor.byteOffset;
const auto stride = indices_accessor.ByteStride(buffer_view);
const auto count = indices_accessor.count;
switch (indices_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_BYTE:
return index_list_to_u32<s8>(data_ptr, count, index_offset, stride);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
return index_list_to_u32<u8>(data_ptr, count, index_offset, stride);
case TINYGLTF_COMPONENT_TYPE_SHORT:
return index_list_to_u32<s16>(data_ptr, count, index_offset, stride);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
return index_list_to_u32<u16>(data_ptr, count, index_offset, stride);
case TINYGLTF_COMPONENT_TYPE_INT:
return index_list_to_u32<s32>(data_ptr, count, index_offset, stride);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
return index_list_to_u32<u32>(data_ptr, count, index_offset, stride);
default:
ASSERT_MSG(false, "unsupported component type");
}
}
/*!
* Extract positions, colors, and normals from a mesh.
*/
ExtractedVertices gltf_vertices(const tinygltf::Model& model,
const std::map<std::string, int>& attributes,
const math::Matrix4f& w_T_local,
bool get_colors,
bool get_normals,
const std::string& debug_name) {
std::vector<tfrag3::PreloadedVertex> result;
std::vector<math::Vector<u8, 4>> vtx_colors;
{
const auto& position_attrib = attributes.find("POSITION");
ASSERT_MSG(position_attrib != attributes.end(), "Did not find position attribute.");
const auto attrib_accessor = model.accessors[position_attrib->second];
const auto& buffer_view = model.bufferViews[attrib_accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const auto data_ptr = buffer.data.data() + buffer_view.byteOffset + attrib_accessor.byteOffset;
const auto byte_stride = attrib_accessor.ByteStride(buffer_view);
const auto count = attrib_accessor.count;
ASSERT_MSG(attrib_accessor.type == TINYGLTF_TYPE_VEC3, "POSITION wasn't vec3");
ASSERT_MSG(attrib_accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT,
"POSITION wasn't float");
// for (auto& attrib : attributes) {
// lg::print("attrib: {}\n", attrib.first);
//}
auto mesh_verts = extract_vec3f(data_ptr, count, byte_stride);
result.reserve(mesh_verts.size());
for (auto& vert : mesh_verts) {
auto& new_vert = result.emplace_back();
math::Vector4f v_in(vert.x(), vert.y(), vert.z(), 1);
math::Vector4f v_w = w_T_local * v_in;
new_vert.x = v_w.x() * 4096;
new_vert.y = v_w.y() * 4096;
new_vert.z = v_w.z() * 4096;
}
}
if (get_colors) {
const auto& color_attrib = attributes.find("COLOR_0");
if (color_attrib == attributes.end()) {
lg::error("Mesh {} didn't have any colors, using white", debug_name);
for (size_t i = 0; i < result.size(); i++) {
vtx_colors.emplace_back(0x80, 0x80, 0x80, 0xff);
}
} else {
const auto attrib_accessor = model.accessors[color_attrib->second];
const auto& buffer_view = model.bufferViews[attrib_accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const auto data_ptr =
buffer.data.data() + buffer_view.byteOffset + attrib_accessor.byteOffset;
const auto byte_stride = attrib_accessor.ByteStride(buffer_view);
const auto count = attrib_accessor.count;
ASSERT_MSG(attrib_accessor.type == TINYGLTF_TYPE_VEC4, "COLOR_0 wasn't vec4");
std::vector<math::Vector<u8, 4>> colors;
switch (attrib_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_FLOAT:
colors = extract_color_from_vec4_float(data_ptr, count, byte_stride);
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
colors = extract_color_from_vec4_u16(data_ptr, count, byte_stride);
break;
default:
lg::die("Unknown component type for COLOR_0: {}", attrib_accessor.componentType);
}
vtx_colors.insert(vtx_colors.end(), colors.begin(), colors.end());
}
}
bool got_texture = false;
{
const auto& texcoord_attrib = attributes.find("TEXCOORD_0");
if (texcoord_attrib != attributes.end()) {
const auto attrib_accessor = model.accessors[texcoord_attrib->second];
const auto& buffer_view = model.bufferViews[attrib_accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const auto data_ptr =
buffer.data.data() + buffer_view.byteOffset + attrib_accessor.byteOffset;
const auto byte_stride = attrib_accessor.ByteStride(buffer_view);
const auto count = attrib_accessor.count;
ASSERT_MSG(attrib_accessor.type == TINYGLTF_TYPE_VEC2, "TEXCOORD wasn't vec2");
ASSERT_MSG(attrib_accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT,
"TEXCOORD wasn't float");
auto mesh_verts = extract_vec2f(data_ptr, count, byte_stride);
ASSERT(mesh_verts.size() == result.size());
got_texture = true;
for (size_t i = 0; i < mesh_verts.size(); i++) {
result[i].s = mesh_verts[i].x();
result[i].t = mesh_verts[i].y();
}
} else {
if (!get_normals) {
// don't warn if we're just getting collision
lg::warn("No texcoord attribute for mesh: {}", debug_name);
}
}
}
std::vector<math::Vector3f> normals;
if (get_normals) {
const auto& normal_attrib = attributes.find("NORMAL");
if (normal_attrib != attributes.end()) {
const auto attrib_accessor = model.accessors[normal_attrib->second];
const auto& buffer_view = model.bufferViews[attrib_accessor.bufferView];
const auto& buffer = model.buffers[buffer_view.buffer];
const auto data_ptr =
buffer.data.data() + buffer_view.byteOffset + attrib_accessor.byteOffset;
const auto byte_stride = attrib_accessor.ByteStride(buffer_view);
const auto count = attrib_accessor.count;
ASSERT_MSG(attrib_accessor.type == TINYGLTF_TYPE_VEC3, "NORMAL wasn't vec3");
ASSERT_MSG(attrib_accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT,
"NORMAL wasn't float");
normals = extract_vec3f(data_ptr, count, byte_stride);
for (auto& nrm : normals) {
math::Vector4f nrm4(nrm.x(), nrm.y(), nrm.z(), 0.f);
nrm = (w_T_local * nrm4).xyz();
}
ASSERT(normals.size() == result.size());
} else {
lg::error("No NORMAL attribute for mesh: {}", debug_name);
}
}
for (auto& v : result) {
v.color_index = 0;
if (!got_texture) {
v.s = 0;
v.t = 0;
}
}
// TODO: other properties
return {result, vtx_colors, normals};
}
DrawMode make_default_draw_mode() {
DrawMode mode;
mode.set_depth_write_enable(true);
mode.set_depth_test(GsTest::ZTest::GEQUAL);
mode.set_alpha_blend(DrawMode::AlphaBlend::DISABLED);
mode.set_aref(0);
mode.set_alpha_fail(GsTest::AlphaFail::KEEP);
mode.set_clamp_s_enable(false);
mode.set_clamp_t_enable(false);
mode.disable_filt(); // for checkerboard...
mode.enable_tcc(); // ?
mode.disable_at();
mode.enable_zt();
mode.disable_ab();
mode.disable_decal();
mode.enable_fog();
return mode;
}
int texture_pool_debug_checker(TexturePool* pool) {
const auto& existing = pool->textures_by_name.find("DEBUG_CHECKERBOARD");
if (existing == pool->textures_by_name.end()) {
size_t idx = pool->textures_by_idx.size();
pool->textures_by_name["DEBUG_CHECKERBOARD"] = idx;
auto& tex = pool->textures_by_idx.emplace_back();
tex.w = 16;
tex.h = 16;
tex.debug_name = "DEBUG_CHECKERBOARD";
tex.debug_tpage_name = "DEBUG";
tex.load_to_pool = false;
tex.combo_id = 0; // doesn't matter, not a pool tex
tex.data.resize(16 * 16);
u32 c0 = 0xa0303030;
u32 c1 = 0xa0e0e0e0;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
tex.data[i * 16 + j] = (((i / 4) & 1) ^ ((j / 4) & 1)) ? c1 : c0;
}
}
return idx;
} else {
return existing->second;
}
}
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex) {
const auto& existing = pool->textures_by_name.find(tex.name);
if (existing != pool->textures_by_name.end()) {
lg::info("Reusing image: {}", tex.name);
return existing->second;
} else {
lg::info("adding new texture: {}, size {} kB", tex.name, tex.width * tex.height * 4 / 1024);
}
ASSERT(tex.bits == 8);
ASSERT(tex.component == 4);
ASSERT(tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
size_t idx = pool->textures_by_idx.size();
pool->textures_by_name[tex.name] = idx;
auto& tt = pool->textures_by_idx.emplace_back();
tt.w = tex.width;
tt.h = tex.height;
tt.debug_name = tex.name;
tt.debug_tpage_name = "custom-level";
tt.load_to_pool = false;
tt.combo_id = 0; // doesn't matter, not a pool tex
tt.data.resize(tt.w * tt.h);
ASSERT(tex.image.size() >= tt.data.size());
memcpy(tt.data.data(), tex.image.data(), tt.data.size() * 4);
return idx;
}
math::Matrix4f affine_translation(const math::Vector3f& translation) {
math::Matrix4f result = math::Matrix4f::identity();
result(0, 3) = translation[0];
result(1, 3) = translation[1];
result(2, 3) = translation[2];
result(3, 3) = 1;
return result;
}
math::Matrix4f affine_scale(const math::Vector3f& scale) {
math::Matrix4f result = math::Matrix4f::zero();
result(0, 0) = scale[0];
result(1, 1) = scale[1];
result(2, 2) = scale[2];
result(3, 3) = 1;
return result;
}
math::Matrix4f affine_rot_qxyzw(const math::Vector4f& quat) {
math::Matrix4f result = math::Matrix4f::zero();
result(3, 3) = 1;
result(0, 0) = 1.0 - 2.0 * (quat.y() * quat.y() + quat.z() * quat.z());
result(0, 1) = 2.0 * (quat.x() * quat.y() - quat.z() * quat.w());
result(0, 2) = 2.0 * (quat.x() * quat.z() + quat.y() * quat.w());
result(1, 0) = 2.0 * (quat.x() * quat.y() + quat.z() * quat.w());
result(1, 1) = 1.0 - 2.0 * (quat.x() * quat.x() + quat.z() * quat.z());
result(1, 2) = 2.0 * (quat.y() * quat.z() - quat.x() * quat.w());
result(2, 0) = 2.0 * (quat.x() * quat.z() - quat.y() * quat.w());
result(2, 1) = 2.0 * (quat.y() * quat.z() + quat.x() * quat.w());
result(2, 2) = 1.0 - 2.0 * (quat.x() * quat.x() + quat.y() * quat.y());
return result;
}
math::Vector3f vector3f_from_gltf(const std::vector<double>& in) {
ASSERT(in.size() == 3);
return math::Vector3f{in[0], in[1], in[2]};
}
math::Vector4f vector4f_from_gltf(const std::vector<double>& in) {
ASSERT(in.size() == 4);
return math::Vector4f{in[0], in[1], in[2], in[3]};
}
math::Matrix4f matrix_from_node(const tinygltf::Node& node) {
if (!node.matrix.empty()) {
math::Matrix4f result;
for (int i = 0; i < 16; i++) {
result.data()[i] = node.matrix[i];
}
return result;
} else {
// from trs
math::Matrix4f t, r, s;
if (!node.translation.empty()) {
t = affine_translation(vector3f_from_gltf(node.translation));
} else {
t = math::Matrix4f::identity();
}
if (!node.rotation.empty()) {
r = affine_rot_qxyzw(vector4f_from_gltf(node.rotation));
} else {
r = math::Matrix4f::identity();
}
if (!node.scale.empty()) {
s = affine_scale(vector3f_from_gltf(node.scale));
} else {
s = math::Matrix4f::identity();
}
return t * r * s;
}
}
/*!
* Recursively walk the tree of nodes, flatten, and compute w_T_node for each.
*/
void node_find_helper(const tinygltf::Model& model,
const math::Matrix4f& w_T_parent,
int node_idx,
std::vector<NodeWithTransform>* out) {
const auto& node = model.nodes.at(node_idx);
math::Matrix4f w_T_node = w_T_parent * matrix_from_node(node);
out->push_back({node_idx, w_T_node});
for (auto& child : node.children) {
node_find_helper(model, w_T_node, child, out);
}
}
std::vector<NodeWithTransform> flatten_nodes_from_all_scenes(const tinygltf::Model& model) {
std::vector<NodeWithTransform> out;
for (auto& scene : model.scenes) {
for (auto& nidx : scene.nodes) {
math::Matrix4f identity = math::Matrix4f::identity();
node_find_helper(model, identity, nidx, &out);
}
}
return out;
}
void dedup_vertices(const std::vector<tfrag3::PreloadedVertex>& vertices_in,
std::vector<tfrag3::PreloadedVertex>& vertices_out,
std::vector<u32>& old_to_new_out) {
ASSERT(vertices_out.empty());
ASSERT(old_to_new_out.empty());
old_to_new_out.resize(vertices_in.size(), -1);
std::unordered_map<tfrag3::PreloadedVertex, u32, tfrag3::PreloadedVertex::hash> vtx_to_new;
for (size_t in_idx = 0; in_idx < vertices_in.size(); in_idx++) {
auto& vtx = vertices_in[in_idx];
const auto& lookup = vtx_to_new.find(vtx);
if (lookup == vtx_to_new.end()) {
// first time seeing this one
size_t new_idx = vertices_out.size();
vertices_out.push_back(vtx);
old_to_new_out[in_idx] = new_idx;
vtx_to_new[vtx] = new_idx;
} else {
old_to_new_out[in_idx] = lookup->second;
}
}
}
DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler) {
DrawMode mode = make_default_draw_mode();
if (sampler.magFilter == TINYGLTF_TEXTURE_FILTER_NEAREST) {
ASSERT(sampler.minFilter == TINYGLTF_TEXTURE_FILTER_NEAREST);
mode.set_filt_enable(false);
} else {
ASSERT(sampler.minFilter != TINYGLTF_TEXTURE_FILTER_NEAREST);
mode.set_filt_enable(true);
}
switch (sampler.wrapS) {
case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE:
mode.set_clamp_s_enable(true);
break;
case TINYGLTF_TEXTURE_WRAP_REPEAT:
mode.set_clamp_s_enable(false);
break;
default:
ASSERT(false);
}
switch (sampler.wrapT) {
case TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE:
mode.set_clamp_t_enable(true);
break;
case TINYGLTF_TEXTURE_WRAP_REPEAT:
mode.set_clamp_t_enable(false);
break;
default:
ASSERT(false);
}
return mode;
}
} // namespace gltf_util
-71
View File
@@ -1,71 +0,0 @@
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "common/custom_data/Tfrag3Data.h"
#include "common/math/Vector.h"
#include "third-party/tiny_gltf/tiny_gltf.h"
namespace gltf_util {
/*!
* Convert a GLTF index buffer to std::vector<u32>
*/
template <typename T>
std::vector<u32> index_list_to_u32(const u8* data, u32 num_verts, u32 offset, u32 stride) {
std::vector<u32> result;
result.reserve(num_verts);
for (u32 i = 0; i < num_verts; i++) {
T val;
memcpy(&val, data, sizeof(T));
result.push_back(offset + val);
data += stride;
}
return result;
}
std::vector<math::Vector3f> extract_vec3f(const u8* data, u32 count, u32 stride);
std::vector<math::Vector2f> extract_vec2f(const u8* data, u32 count, u32 stride);
std::vector<math::Vector<u8, 4>> extract_color_from_vec4_u16(const u8* data, u32 count, u32 stride);
std::vector<u32> gltf_index_buffer(const tinygltf::Model& model, int indices_idx, u32 index_offset);
struct ExtractedVertices {
std::vector<tfrag3::PreloadedVertex> vtx;
std::vector<math::Vector<u8, 4>> vtx_colors;
std::vector<math::Vector3f> normals;
};
ExtractedVertices gltf_vertices(const tinygltf::Model& model,
const std::map<std::string, int>& attributes,
const math::Matrix4f& w_T_local,
bool get_colors,
bool get_normals,
const std::string& debug_name);
DrawMode make_default_draw_mode();
struct TexturePool {
std::unordered_map<std::string, int> textures_by_name;
std::vector<tfrag3::Texture> textures_by_idx;
};
int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex);
int texture_pool_debug_checker(TexturePool* pool);
struct NodeWithTransform {
int node_idx;
math::Matrix4f w_T_node;
};
void dedup_vertices(const std::vector<tfrag3::PreloadedVertex>& vertices_in,
std::vector<tfrag3::PreloadedVertex>& vertices_out,
std::vector<u32>& old_to_new_out);
std::vector<NodeWithTransform> flatten_nodes_from_all_scenes(const tinygltf::Model& model);
DrawMode draw_mode_from_sampler(const tinygltf::Sampler& sampler);
} // namespace gltf_util
+3 -3
View File
@@ -27,11 +27,11 @@ Range<int> parse_json_optional_integer_range(const nlohmann::json& json);
}
template <typename T>
void json_get_optional(const nlohmann::json& j,
void json_get_optional(const nlohmann::json& json,
const std::string& key,
std::optional<T>& optionalValue) {
if (j.contains(key) && !j[key].is_null()) {
optionalValue = j[key].get<T>();
if (json.contains(key) && !json[key].is_null()) {
optionalValue = json[key].get<T>();
}
}
+8 -17
View File
@@ -3,29 +3,20 @@
#include "common/common_types.h"
#include "common/log/log.h"
#ifdef _WIN32
// clang-format off
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <psapi.h>
// clang-format on
size_t get_peak_rss() {
HANDLE hProcess = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
return pmc.PeakWorkingSetSize;
} else {
return 0;
}
}
#else
#ifdef __linux__
#include <sys/resource.h>
size_t get_peak_rss() {
rusage x;
getrusage(RUSAGE_SELF, &x);
return x.ru_maxrss * 1024;
}
#else
size_t get_peak_rss() {
return 0;
}
#endif
#ifdef _WIN32
+1
View File
@@ -3,6 +3,7 @@
#include <cstddef>
#include <string>
// Note: these are not implemented on windows and will return zero.
size_t get_peak_rss();
void setup_cpu_info();
+3
View File
@@ -7,6 +7,9 @@
// A normal Trie does not allow for duplicate keys, however this one does
// It allows for insertion and removal
//
// Note, keys assume only basic ASCII, which is _fine_ as OpenGOAL itself has this
// limitation as well.
template <typename T>
class TrieWithDuplicates {
private:
@@ -1,90 +0,0 @@
{
// The "in-game" name of the level. Should be lower case, with dashes (GOAL symbol name)
// the name of this file, and the folder this file is in must have the same name.
"long_name": "test-zone",
// The file name, should be upper case and 8 characters or less.
"iso_name": "TESTZONE",
// The nickname, should be exactly 3 characters
"nickname": "tsz", // 3 char name, all lowercase
// Background mesh file.
// Must have vertex colors. Use the blender cycles renderer, bake, diffuse, uncheck color,
// and bake to vertex colors. For now, only the first vertex color group is used, so make sure you
// only have 1.
"gltf_file": "custom_assets/jak3/levels/test-zone/test-zone2.glb",
// automatically set wall vs. ground based on angle. Useful if you don't want to assign this yourself
"automatic_wall_detection": true,
"automatic_wall_angle": 45.0,
// if your mesh has triangles with incorrect orientation, set this to make all collision mesh triangles double sided
// this makes collision 2x slower and bigger, so only use if really needed
"double_sided_collide": false,
// available res-lump tag types:
// integer types: int32, uint32, enum-int32, enum-uint32
// float types: 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: symbol, type, string, eco-info, cell-info, buzzer-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 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]
//
// adds a 'type' tag (using the "symbol" and "string" lump types works the same way):
// "spawn-types": ["type", "spyder", "juicer"]
// 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.
// "art_groups": [],
// 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.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
// "textures": [],
"actors" : [
{
"trans": [-15.2818, 15.2461, 17.1360], // translation
"etype": "crate", // actor type
"game_task": "(game-task none)", // associated game task (for powercells, etc)
"kill_mask": 0,
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-15.2818, 15.2461, 17.1360, 10], // bounding sphere
"lump": {
"name": "test-crate",
"eco-info": ["eco-info", "(pickup-type gem)", 1]
}
},
{
"trans": [-5.4630, 17.4553, 1.6169], // translation
"etype": "eco-yellow", // actor type
"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
"lump": {
"name": "test-eco"
}
}
]
}
Binary file not shown.
@@ -1,8 +0,0 @@
;; DGO definition file for Awful Village level
;; We use the convention of having a longer DGO name for levels without precomputed visibility.
;; the actual file name still needs to be 8.3
("TSZ.DGO"
("test-zone.go"
)
)
@@ -5,13 +5,13 @@ Disclaimer: custom levels are still in development and are missing most features
The first three steps are already done for "test zone", so this can be used as a starting point.
# 1: File Setup
To create a custom level, copy the layout of `custom_assets/jak1/levels/test-zone`. See `test-zone.jsonc` for information on how to name things. The `.gd` file also contains the level name.
To create a custom level, copy the layout of `custom_levels/test-zone`. See `test-zone.jsonc` for information on how to name things. The `.gd` file also contains the level name.
# 2: Modify the engine
Modify `goal_src/jak1/engine/level/level-info.gc` to add level info for each custom level. There is level info for `test-zone` at the bottom that can be used as an example.
Modify `goal_src/engine/level/level-info.gc` to add level info for each custom level. There is level info for `test-zone` at the bottom that can be used as an example.
# 3: Modify the build system
Modify `goal_src/jak1/game.gp` and add a custom level target:
Modify `goal_src/game.gp` and add a custom level target:
```lisp
(build-custom-level "test-zone")
;; the DGO file
@@ -21,7 +21,7 @@ Modify `goal_src/jak1/game.gp` and add a custom level target:
# 4: Export the GLTF file from blender.
For now, all meshes are displayed and treated as ground collision. This causes buggy collision because walls shouldn't use "floor" mode.
Blender will create a `.glb` file, which must have the name specified in the `.jsonc` file and should be located in `custom_assets/jak1/levels/your_level`
Blender will create a `.glb` file, which must have the name specified in the `.jsonc` file and should be located in `custom_level/your_level`
# 5: Rebuild the game
Any time the `.glb` file is changed, you must rebuild the game. Launch the compiler (`goalc`) and run `(mi)` to rebuild everything. It's recommended to leave the compiler open - it will remember files that haven't changed and skip rebuilding them.
File renamed without changes.
@@ -10,7 +10,7 @@
// Must have vertex colors. Use the blender cycles renderer, bake, diffuse, uncheck color,
// and bake to vertex colors. For now, only the first vertex color group is used, so make sure you
// only have 1.
"gltf_file": "custom_assets/jak1/levels/test-zone/test-zone2.glb",
"gltf_file": "custom_levels/jak1/test-zone/test-zone2.glb",
// automatically set wall vs. ground based on angle. Useful if you don't want to assign this yourself
"automatic_wall_detection": true,
@@ -55,22 +55,20 @@
// adds a 'symbol' tag (using the 'type' and 'string' lump types works the same way):
// "symbol-list": ["symbol", "sym-1", "sym-2"]
// The base actor id for your custom level. If you have multiple levels, this should be unique!
"base_id": 100,
// 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.
// Note: You will still have to add them to your level's .gd file.
// Removed so that the release builds don't have to double-decompile the game
// "art_groups": ["plat-ag"],
"art_groups": [],
// If you have any custom models in the "custom_assets/jak1/models/custom_levels" folder that you want to use in your level, add them to this list.
// Note: Like with art groups, these should also be added to your level's .gd file.
"custom_models": ["test-actor"],
// Any textures you want to include in your custom level. This is mainly useful for things such as the zoomer HUD,
// which is not in the common level files and has no art group associated with it.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
"textures": [
// Any textures you want to include in your custom level. This is mainly useful for things such as the zoomer HUD,
// which is not in the common level files and has no art group associated with it.
// To get a list of all the textures, you can extract all of the game's textures
// by setting "save_texture_pngs" to true in the decompiler config.
"textures": [
// all textures required for the zoomer HUD
// "zoomerhud",
// "zoomerhud-dial",
@@ -132,16 +130,6 @@
"lump": {
"name": "test-eco"
}
},
{
"trans": [-5.41, 3.5, 28.42], // translation
"etype": "test-actor", // actor type
"game_task": 0, // associated game task (for powercells, etc)
"quat": [0, 0, 0, 1], // quaternion
"bsphere": [-7.41, 3.5, 28.42, 10], // bounding sphere
"lump": {
"name": "test-actor"
}
}
// {
// "trans": [-7.41, 3.5, 28.42], // translation
@@ -4,8 +4,6 @@
;; the actual file name still needs to be 8.3
("TSZ.DGO"
("static-screen.o"
"test-zone-obs.o"
"plat-ag.go"
"test-actor-ag.go"
"test-zone.go"
"plat-ag.go"
))
@@ -10,7 +10,7 @@
// Must have vertex colors. Use the blender cycles renderer, bake, diffuse, uncheck color,
// and bake to vertex colors. For now, only the first vertex color group is used, so make sure you
// only have 1.
"gltf_file": "custom_assets/jak2/levels/test-zone/test-zone2.glb",
"gltf_file": "custom_levels/jak2/test-zone/test-zone2.glb",
// automatically set wall vs. ground based on angle. Useful if you don't want to assign this yourself
"automatic_wall_detection": true,
+1 -4
View File
@@ -58,7 +58,6 @@ add_library(
level_extractor/extract_actors.cpp
level_extractor/extract_collide_frags.cpp
level_extractor/extract_common.cpp
level_extractor/extract_hfrag.cpp
level_extractor/extract_joint_group.cpp
level_extractor/extract_level.cpp
level_extractor/extract_merc.cpp
@@ -68,7 +67,6 @@ add_library(
level_extractor/fr3_to_gltf.cpp
level_extractor/MercData.cpp
level_extractor/tfrag_tie_fixup.cpp
level_extractor/merc_replacement.cpp
ObjectFile/LinkedObjectFile.cpp
ObjectFile/LinkedObjectFileCreation.cpp
@@ -90,8 +88,7 @@ add_library(
VuDisasm/VuDisassembler.cpp
VuDisasm/VuInstruction.cpp
config.cpp
decompilation_process.cpp)
config.cpp)
target_link_libraries(decomp
lzokay
@@ -6586,10 +6586,6 @@ bool try_vector_reset_inline(const Env& env,
RegisterAccess orig;
store = repop_passthrough_arg(store, stack, env, &orig, &got_orig);
if (!store) {
return false;
}
// create the actual form
Form* new_thing = pool.form<GenericElement>(
GenericOperator::make_function(pool.form<ConstantTokenElement>("vector-reset!")),
-4
View File
@@ -760,10 +760,6 @@ bool Matcher::do_match(Form* input, MatchResult::Maps* maps_out, const Env* cons
break;
}
if (entries_matched == m_entry_matchers.size()) {
break;
}
if (m_entry_matchers.at(entries_matched)
.do_match(let_body->entries().at(0), maps_out, env)) {
entries_matched++;
+1 -1
View File
@@ -25,7 +25,7 @@ namespace decompiler {
*/
class LinkedObjectFile {
public:
LinkedObjectFile(GameVersion _version) : version(_version) {}
LinkedObjectFile(GameVersion version) : version(version){};
void set_segment_count(int n_segs);
void push_back_word_to_segment(uint32_t word, int segment);
int get_label_id_for(int seg, int offset);
+2 -16
View File
@@ -5,7 +5,6 @@
#include "ObjectFileDB.h"
#include "common/formatter/formatter.h"
#include "common/goos/PrettyPrinter.h"
#include "common/link_types.h"
#include "common/log/log.h"
@@ -873,22 +872,9 @@ void ObjectFileDB::ir2_write_results(const fs::path& output_dir,
auto file_name = output_dir / (obj.to_unique_name() + "_ir2.asm");
file_util::write_text_file(file_name, file_text);
auto unformatted_code = ir2_final_out(obj, imports, {});
auto final = ir2_final_out(obj, imports, {});
auto final_name = output_dir / (obj.to_unique_name() + "_disasm.gc");
if (config.format_code) {
const auto formatted_code = formatter::format_code(unformatted_code);
if (!formatted_code) {
lg::error(
"Was unable to format the decompiled result of {}, make a github issue. Writing "
"unformatted code",
obj.to_unique_name());
file_util::write_text_file(final_name, unformatted_code);
} else {
file_util::write_text_file(final_name, formatted_code.value());
}
} else {
file_util::write_text_file(final_name, unformatted_code);
}
file_util::write_text_file(final_name, final);
}
}
+6 -2
View File
@@ -54,8 +54,12 @@ void append_body_to_function_definition(goos::Object* top_form,
body_elements.insert(body_elements.end(), inline_body.begin(), inline_body.end());
// If the first element in the body is a docstring, add it first
if (body_elements.size() > 0 && body_elements.at(0).is_string()) {
initial_top_level_forms.push_back(
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
if (version > GameVersion::Jak2) {
initial_top_level_forms.push_back(
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
} else {
initial_top_level_forms.push_back(inline_body.at(0));
}
body_elements.erase(body_elements.begin());
}
+1 -6
View File
@@ -64,6 +64,7 @@ Config make_config_via_json(nlohmann::json& json) {
inputs_json.at("str_art_file_names").get<std::vector<std::string>>();
}
config.audio_dir_file_name = inputs_json.at("audio_dir_file_name").get<std::string>();
config.streamed_audio_file_names =
inputs_json.at("streamed_audio_file_names").get<std::vector<std::string>>();
@@ -95,9 +96,6 @@ Config make_config_via_json(nlohmann::json& json) {
}
config.disassemble_code = json.at("disassemble_code").get<bool>();
config.decompile_code = json.at("decompile_code").get<bool>();
if (json.contains("format_code")) {
config.format_code = json.at("format_code").get<bool>();
}
config.write_hex_near_instructions = json.at("write_hex_near_instructions").get<bool>();
config.write_scripts = json.at("write_scripts").get<bool>();
config.disassemble_data = json.at("disassemble_data").get<bool>();
@@ -320,9 +318,6 @@ Config make_config_via_json(nlohmann::json& json) {
if (json.contains("save_texture_pngs")) {
config.save_texture_pngs = json.at("save_texture_pngs").get<bool>();
}
if (json.contains("rip_streamed_audio")) {
config.rip_streamed_audio = json.at("rip_streamed_audio").get<bool>();
}
if (inputs_json.contains("animated_textures")) {
config.animated_textures =
+2 -2
View File
@@ -102,6 +102,8 @@ struct Config {
std::vector<std::string> str_file_names;
std::vector<std::string> str_texture_file_names;
std::vector<std::string> str_art_file_names;
std::string audio_dir_file_name;
std::vector<std::string> streamed_audio_file_names;
std::string obj_file_name_map_file;
@@ -109,7 +111,6 @@ struct Config {
bool disassemble_code = false;
bool decompile_code = false;
bool format_code = false;
bool write_scripts = false;
bool disassemble_data = false;
bool process_tpages = false;
@@ -173,7 +174,6 @@ struct Config {
std::vector<std::string> levels_to_extract;
bool levels_extract;
bool save_texture_pngs = false;
bool rip_streamed_audio = false;
DecompileHacks hacks;
+11 -11
View File
@@ -21102,7 +21102,7 @@
:size-assert #x94
:flag-assert #xf00300094
(:methods
(spawn-particles! (_type_) none))
(dumb-15 (_type_) none))
(:states
hud-normal
hud-coming-in
@@ -22303,20 +22303,20 @@
;; - Functions
(define-extern calculate-rotation-and-color-for-slice (function int float int int int matrix none))
(define-extern part-hud-health-01-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-health-02-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-health-03-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern calculate-rotation-and-color-for-slice (function int float int int int hud-particle none))
(define-extern part-hud-health-01-func (function basic basic hud-particle none)) ;; TODO - i figured this out on another branch...all these particle functions get called by the particle system with the same beginning types iirc
(define-extern part-hud-health-02-func (function basic basic hud-particle none))
(define-extern part-hud-health-03-func (function basic basic hud-particle none))
(define-extern fuel-cell-hud-orbit-callback (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern fuel-cell-hud-starburst-3-callback (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern fuel-cell-hud-starburst-4-callback (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern fuel-cell-hud-center-callback (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-buzzer-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-eco-timer-01-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-eco-timer-02-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-eco-timer-03-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-eco-timer-backing-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-eco-timer-func (function sparticle-system sparticle-cpuinfo matrix none))
(define-extern part-hud-buzzer-func (function basic basic hud-particle none))
(define-extern part-hud-eco-timer-01-func (function basic basic hud-particle none))
(define-extern part-hud-eco-timer-02-func (function basic basic hud-particle none))
(define-extern part-hud-eco-timer-03-func (function basic basic hud-particle none))
(define-extern part-hud-eco-timer-backing-func (function basic basic hud-particle none))
(define-extern part-hud-eco-timer-func (function basic basic hud-particle none))
(define-extern show-hud (function none))
;; - Unknowns
-7
View File
@@ -23,10 +23,6 @@
// run the first pass of the decompiler
"find_functions": true,
// will attempt to run the decompiled output through the OpenGOAL formatter
// this will be skipped in offline tests
"format_code": true,
////////////////////////////
// DATA ANALYSIS OPTIONS
////////////////////////////
@@ -122,9 +118,6 @@
// save game textures as .png files to decompiler_out/<game>/textures
"save_texture_pngs": false,
// whether or not to dump out streamed audio files to decompiler_out/<game>/audio
"rip_streamed_audio": false,
////////////////////////////
// PATCHING OPTIONS
////////////////////////////
+1 -1
View File
@@ -634,7 +634,7 @@
// 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": [["finalboss", 1419, 3]],
"missing_textures": [["finalboss-vis", 1419, 3]],
// 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.
@@ -258,6 +258,10 @@
"TEXT/6COMMON.TXT"
],
// uncomment the next line to extract audio to wave files.
//"audio_dir_file_name": "jak1/VAG",
"audio_dir_file_name": "",
"streamed_audio_file_names": [
"VAGWAD.ENG",
"VAGWAD.FRE",
@@ -228,5 +228,9 @@
"TEXT/6COMMON.TXT"
],
// uncomment the next line to extract audio to wave files.
//"audio_dir_file_name": "jak1/VAG",
"audio_dir_file_name": "",
"streamed_audio_file_names": ["VAGWAD.ENG", "VAGWAD.JAP"]
}
-14
View File
@@ -2515,7 +2515,6 @@
(iop-mem 48)
(cancel-dgo 49)
(set-stereo-mode 50) ;; sound-rpc-set-stereo-mode
(set-mirror 201)
)
(defenum sound-group
@@ -2830,17 +2829,6 @@
:flag-assert #x900000004
)
; added
(defenum sound-mirror-mode
:type uint8
(normal)
(mirrored)
)
; added for mirror mode
(deftype sound-rpc-set-mirror-mode (sound-rpc-cmd)
((mirror sound-mirror-mode)))
(deftype sound-rpc-union (structure)
((data uint32 20 :offset-assert 0)
(load-bank sound-rpc-load-bank :offset 0)
@@ -2864,7 +2852,6 @@
(shutdown sound-rpc-shutdown :offset 0)
(list-sounds sound-rpc-list-sounds :offset 0)
(unload-music sound-rpc-unload-music :offset 0)
(mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0))
)
:method-count-assert 9
:size-assert #x50
@@ -8787,7 +8774,6 @@ Unlike [[engine]], users can use [[engine-pers]] as a parent class."
(progress-graphics-ps2-lod-dist #x1337)
(progress-graphics-msaa-off #x1338)
(progress-graphics-display #x1339)
(language-name-finnish #x133a)
)
;; ---text-id-h:text-id
-3
View File
@@ -127,9 +127,6 @@
"rip_collision": false,
// save game textures as .png files to decompiler_out/<game>/textures
"save_texture_pngs": false,
// whether or not to dump out streamed audio files to decompiler_out/<game>/audio
"rip_streamed_audio": false,
////////////////////////////
// PATCHING OPTIONS
+1 -1
View File
@@ -769,7 +769,7 @@
// 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": [
["vinroom", 0, 0],
["vinroom-vis", 0, 0],
["ctyfence", 0, 0]
],
@@ -441,6 +441,10 @@
"TEXT/7COMMON.TXT"
],
// uncomment the next line to extract audio to wave files.
// "audio_dir_file_name": "jak2/VAG",
"audio_dir_file_name": "",
"streamed_audio_file_names": [
"VAGWAD.ENG",
"VAGWAD.FRE",
File diff suppressed because it is too large. Load diff
-3
View File
@@ -127,9 +127,6 @@
// save game textures as .png files to decompiler_out/<game>/textures
"save_texture_pngs": false,
// whether or not to dump out streamed audio files to decompiler_out/<game>/audio
"rip_streamed_audio": false,
////////////////////////////
// PATCHING OPTIONS
////////////////////////////
@@ -138,7 +138,7 @@
[7, "(function none)"],
[3, "(function symbol :behavior process)"]
],
"scene": [[4, "(function symbol :behavior scene-player)"]],
"scene": [[4, "(function none :behavior scene-player)"]],
"pov-camera": [
[
7,
@@ -615,390 +615,5 @@
"wvehicle": [[6, "(function collide-shape-prim none)"]],
"pilot-states": [
[15, "(function surface surface surface int object :behavior target)"]
],
"was-squad-control": [[16, "(function object object)"]],
"des-cactus": [[13, "(function collide-shape-prim none)"]],
"desertg-obs": [
[4, "(function collide-shape-prim none)"],
[7, "(function collide-shape-prim none)"]
],
"desertf-obs": [[7, "(function none)"]],
"temple-obs2": [
[43, "(function symbol)"],
[46, "(function object :behavior tpl-watcher)"]
],
"temple-scenes": [
[0, "(function none)"],
[1, "(function none)"],
[2, "(function none)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"]
],
"des-beast-2": [
[1, "(function cspace transformq none)"],
[2, "(function cspace transformq none)"],
[23, "(function projectile none)"]
],
"scorpion-gun": [
[33, "(function cspace transformq none)"],
[34, "(function cspace transformq none)"]
],
"hover-formation": [
[10, "(function form-search-info float)"],
[11, "(function int int form-search-info uint)"],
[14, "(function vector object)"],
[15, "(function int int (pointer object) int)"]
],
"robo-hover": [
[14, "(function robo-hover cspace float float vector vector int object)"]
],
"tower-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"]
],
"forest-kill-plants": [
[5, "(function engine-pers connection-pers object object symbol)"],
[7, "(function engine-pers connection-pers object object symbol)"]
],
"forest-tasks": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"],
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"],
[14, "(function none :behavior scene-player)"],
[15, "(function none :behavior scene-player)"],
[16, "(function none :behavior scene-player)"],
[17, "(function none :behavior scene-player)"],
[18, "(function none :behavior scene-player)"],
[19, "(function none :behavior scene-player)"],
[20, "(function none :behavior scene-player)"],
[21, "(function none :behavior scene-player)"]
],
"neo-wasp": [[15, "(function neo-wasp cspace transformq float float none)"]],
"for-turret": [
[1, "(function cspace transformq none)"],
[2, "(function cspace transformq none)"],
[3, "(function cspace transformq none)"],
[4, "(function cspace transformq none)"]
],
"volcano-obs": [[38, "(function cspace transformq none)"]],
"spiky-frog": [[9, "(function cspace transformq none)"]],
"volcano-scenes": [
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"]
],
"mantis": [
[8, "(function mantis vector float int vector vector)"],
[15, "(function mantis collide-shape-moving vector symbol)"]
],
"wcar-faccar": [[9, "(function handle object :behavior process)"]],
"wasstadb-obs": [[5, "(function object)"]],
"arena-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"]
],
"traffic-engine": [
[24, "(function traffic-find-segment-struct nav-segment none)"]
],
"desert-scenes": [
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"],
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"],
[14, "(function none :behavior scene-player)"],
[15, "(function none :behavior scene-player)"],
[16, "(function none :behavior scene-player)"],
[17, "(function none :behavior scene-player)"],
[18, "(function none :behavior scene-player)"],
[19, "(function none :behavior scene-player)"],
[20, "(function none :behavior scene-player)"],
[21, "(function none :behavior scene-player)"],
[22, "(function none :behavior scene-player)"],
[23, "(function none :behavior scene-player)"],
[24, "(function none :behavior scene-player)"],
[25, "(function none :behavior scene-player)"],
[26, "(function none :behavior scene-player)"],
[27, "(function none :behavior scene-player)"],
[28, "(function none :behavior scene-player)"],
[29, "(function none :behavior scene-player)"],
[30, "(function none :behavior scene-player)"],
[31, "(function none :behavior scene-player)"],
[32, "(function none :behavior scene-player)"],
[33, "(function none :behavior scene-player)"],
[34, "(function none :behavior scene-player)"],
[35, "(function none :behavior scene-player)"],
[36, "(function symbol :behavior scene-player)"]
],
"throne-scenes": [[0, "(function none :behavior scene-player)"]],
"terraformer-setup": [[38, "(function object :behavior manipy)"]],
"mined-scenes": [
[6, "(function none :behavior scene-player)"],
[7, "(function process-drawable vector none :behavior scene-player)"],
[8, "(function process-drawable vector none :behavior scene-player)"]
],
"wasteland-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"]
],
"wasdoors-scenes": [[2, "(function none :behavior scene-player)"]],
"wasdef-manager": [
[7, "(function process-tree object)"],
[8, "(function process-tree object)"],
[9, "(function process-tree object)"]
],
"des-burning-bush": [[37, "(function symbol)"]],
"mh-wasp": [
[9, "(function mh-wasp cspace float float vector vector int none)"]
],
"mh-bat": [
[1, "(function cspace transformq none)"],
[21, "(function object :behavior mh-bat)"],
[26, "(function object :behavior mh-bat)"],
[30, "(function object :behavior mh-bat)"],
[34, "(function object :behavior mh-bat)"],
[39, "(function object :behavior mh-bat)"]
],
"factoryc-obs2": [
[67, "(function (pointer joint-exploder) :behavior fac-break-floor)"]
],
"factory-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function process-drawable none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"],
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"],
[14, "(function none :behavior scene-player)"],
[15, "(function none :behavior scene-player)"]
],
"factory-boss-setup": [[37, "(function object :behavior manipy)"]],
"factory-boss-scenes": [
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"]
],
"bot": [[25, "(function gui-connection symbol :behavior bot)"]],
"oasis-defense": [
[4, "(function collide-shape-prim none)"],
[11, "(function collide-shape-prim none)"]
],
"ash-oasis-course": [
[0, "(function ashelin-oasis object)"],
[1, "(function ashelin-oasis object)"],
[2, "(function asht-wait-spot ashelin-oasis object)"],
[3, "(function ashelin-oasis symbol)"]
],
"comb-obs": [
[16, "(function collide-shape-prim none)"],
[33, "(function collide-shape-prim none)"],
[49, "(function collide-shape-prim none)"]
],
"comb-sentry": [[19, "(function collide-shape-prim none)"]],
"comb-field": [[5, "(function symbol)"]],
"comb-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"]
],
"railx-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"]
],
"title-obs": [
[20, "(function external-art-buffer int)"],
[22, "(function game-task object)"],
[26, "(function vector :behavior manipy)"],
[30, "(function object :behavior manipy)"]
],
"ff-squad-control": [
[6, "(function process-focusable traffic-object-type-info none)"],
[7, "(function process-focusable traffic-object-type-info none)"],
[8, "(function process-focusable traffic-object-type-info none)"],
[9, "(function crimson-guard traffic-object-type-info none)"]
],
"guard": [
[31, "(function crimson-guard collide-shape vector symbol)"],
[49, "(function process city-attacker-info int)"]
],
"guard-tazer": [
[7, "(function collide-shape-prim none)"],
[13, "(function collide-shape-prim none)"]
],
"roboguard-city": [
[13, "(function cspace transformq none)"],
[78, "(function roboguard-city symbol quaternion :behavior process)"]
],
"ctywide-obs": [[93, "(function symbol)"]],
"ctywide-scenes": [
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"]
],
"ctyport-obs": [[5, "(function collide-shape-prim none)"]],
"ctyport-scenes": [
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"]
],
"ctyport-attack": [[45, "(function object :behavior process)"]],
"intro-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"],
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"],
[14, "(function none :behavior scene-player)"],
[15, "(function none :behavior scene-player)"],
[16, "(function none :behavior scene-player)"],
[17, "(function none :behavior scene-player)"],
[18, "(function none :behavior scene-player)"],
[19, "(function none :behavior scene-player)"],
[20, "(function none :behavior scene-player)"],
[21, "(function none :behavior scene-player)"],
[22, "(function none :behavior scene-player)"],
[23, "(function none :behavior scene-player)"],
[24, "(function none :behavior scene-player)"],
[25, "(function none :behavior scene-player)"],
[26, "(function none :behavior scene-player)"],
[27, "(function none :behavior scene-player)"],
[28, "(function none :behavior scene-player)"],
[29, "(function none :behavior scene-player)"],
[30, "(function none :behavior scene-player)"],
[31, "(function none :behavior scene-player)"],
[32, "(function none :behavior scene-player)"],
[33, "(function none :behavior scene-player)"],
[34, "(function none :behavior scene-player)"],
[35, "(function none :behavior scene-player)"],
[36, "(function none :behavior scene-player)"],
[37, "(function none :behavior scene-player)"],
[38, "(function none :behavior scene-player)"],
[39, "(function none :behavior scene-player)"]
],
"freehq-scenes": [[0, "(function none :behavior scene-player)"]],
"hiphog-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"]
],
"rubble-attack": [[7, "(function int)"]],
"rublcst-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"],
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"]
],
"vinroom-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"]
],
"gungame-manager": [[6, "(function process symbol)"]],
"blow-tower-obs2": [
[16, "(function bt-mh-flyer cspace float float vector vector int none)"],
[117, "(function bt-roboguard symbol quaternion)"],
[124, "(function cspace transformq none)"]
],
"cty-blow-tower": [
[39, "(function collide-shape-prim none)"],
[27, "(function process symbol)"],
[46, "(function collide-shape-prim none)"],
[69, "(function process object)"]
],
"assault-enemies": [
[36, "(function assault-crimson-guard city-attacker-info int)"]
],
"assault-task": [[11, "(function symbol :behavior process)"]],
"precura-obs": [[98, "(function symbol :behavior process)"]],
"precurd-scenes": [
[0, "(function none :behavior scene-player)"],
[1, "(function none :behavior scene-player)"],
[2, "(function none :behavior scene-player)"],
[3, "(function none :behavior scene-player)"],
[4, "(function none :behavior scene-player)"],
[5, "(function none :behavior scene-player)"],
[6, "(function none :behavior scene-player)"],
[7, "(function none :behavior scene-player)"],
[8, "(function none :behavior scene-player)"],
[9, "(function none :behavior scene-player)"],
[10, "(function none :behavior scene-player)"],
[11, "(function none :behavior scene-player)"],
[12, "(function none :behavior scene-player)"],
[13, "(function none :behavior scene-player)"],
[14, "(function none :behavior scene-player)"]
]
}
+1 -25
View File
@@ -15,31 +15,7 @@
"lightjak-shield": "jakb-ag",
"freeze-screen": "collectables-ag",
"red-3-sphere": "gun-ag",
"gun-dark-3-sphere": "gun-ag",
"marauder": "marauder-male-ag",
"glider-ring": "des-glider-ring-ag",
"flut-racer": "flut-wild-ag",
"was-pre-heart": "neo-satellite-heart-ag",
"was-pre-beam": "neo-satellite-game-ring-ag",
"was-pre-bubble": "neo-satellite-ps-symbols-ag",
"maker": "dm-robot-ag",
"mh-wasp": "neo-wasp-ag",
"factory-boss": "errol-lowres-ag",
"fac-robotank-turret": "fac-robotank-ag",
"neo-sat-shield": "neo-satellite-shield-ag",
"neo-sat": "neo-satellite-ag",
"power-game-switcher": "switcher-ag",
"power-game-player": "daxter-pac-man-ag",
"power-game-glyph": "cipher-ag",
"power-game-rings": "pow-rings-ag",
"power-game-chaser": "flitter-ag",
"power-game-zapper": "grunt-head-ag",
"gungame-door": "fort-entry-gate-ag",
"bt-mh-flyer": "bt-wasp-ag",
"gunship-exploder": "kg-robot-transport-break",
"gunship-engine": "kg-robot-transport-bomb",
"protect-gunship": "kg-robot-transport",
"gunship-missile": "cty-homing-missile"
"gun-dark-3-sphere": "gun-ag"
},
// remap names for types in an entire file (higher priority)
+19 -164
View File
@@ -78,6 +78,10 @@
"blerc-execute",
"foreground-check-longest-edge-asm",
"generic-light-proc",
"shadow-add-single-edges",
"shadow-add-facing-single-tris",
"shadow-add-double-tris",
"shadow-add-double-edges",
"(method 17 collide-edge-work)",
"(method 10 collide-cache-prim)",
"(method 17 collide-cache)",
@@ -103,6 +107,11 @@
// jak 3
"(method 10 manipulator)",
"(method 46 ff-squad-control)",
"(anon-function 65 temple-obs)",
"(method 33 task-manager-nest-cocoons)",
"(method 33 rub-tower)",
"(method 261 crimson-guard)",
"(anon-function 25 volcanox-obs)",
"memcpy"
],
@@ -210,19 +219,7 @@
"borrow-city-expansion",
"add-want-level",
"level-find-borrow-slot",
"(method 18 level)",
"(method 11 tow-tentacle)",
"city-sound-expand-want-list",
"(method 12 cty-borrow-manager)",
"(method 16 cty-borrow-manager)",
"mark-permanent-holds",
"update-sound-info",
"insert-into-sound-list",
// title-obs
"(anon-function 22 title-obs)",
"cty-faction-evaluate-commands",
"traffic-manager-event-handler",
"(method 20 cty-faction-manager)"
"(method 18 level)"
],
// If format is used with the wrong number of arguments,
@@ -268,8 +265,7 @@
"~10Hfg-wa: ~8,,0m": 1,
"~140Hfg-sh: ~8,,0m": 1,
"~267Hfg-p2: ~8,,0m~%": 1,
"~30Hp2: ~8D~131Hhf: ~8D~%~1K": 2,
"Current time (~d:~d) [mission-percentage ~f~%": 2
"~30Hp2: ~8D~131Hhf: ~8D~%~1K": 2
},
"blocks_ending_in_asm_branch": {
@@ -418,51 +414,7 @@
"(method 118 vehicle)": [3, 4, 7, 8, 9, 10, 17, 26, 30, 31, 33],
"(method 25 squad-control)": [0, 4, 5, 7],
"target-pilot-post": [0, 29],
"(method 36 was-squad-control)": [0, 8, 14, 16],
"(anon-function 6 nst-tasks)": [4, 9, 10, 16, 23, 30],
"(method 33 task-manager-nest-cocoons)": [3, 7, 13, 28],
"(method 90 wvehicle)": [29, 37, 38, 44],
"(anon-function 2 artifact-race)": [40, 55, 56, 57, 65, 66],
"(anon-function 27 course-race)": [6],
"(anon-function 65 temple-obs)": [5, 6],
"(anon-function 5 target-turret)": [0, 1, 2, 3],
"dp-bipedal-consider-attacks": [15, 19],
"(anon-function 25 volcanox-obs)": [3, 5, 6],
"(method 36 task-manager-arena-fight-base)": [11],
"(method 28 hud-wasgun)": [0, 1, 2, 4],
"(method 15 hud-wasgun)": [8, 28, 29, 30, 54],
"(method 15 vehicle-controller)": [0, 3, 5, 6, 7, 10],
"(method 51 hvehicle)": [5],
"(method 159 hvehicle)": [0, 1, 10, 19, 21, 23, 26],
"(method 18 vehicle-controller)": [0, 1, 74, 75],
"glider-too-low?": [2, 19, 21],
"(method 39 task-manager-desert-glide)": [0, 3, 4, 9],
"(method 36 task-manager-desert-glide)": [20, 50, 60],
"(method 37 task-manager-desert-glide)": [11, 12, 23, 29, 31],
"(method 34 task-manager-desert-glide)": [3],
"(anon-function 20 target-flut)": [0, 38, 39],
"(anon-function 14 flut-racer)": [7, 17, 19],
"(method 28 conveyor)": [22],
"generic-merc-execute-all": [7, 15],
"check-enemy": [0, 1],
"(method 91 h-warf)": [0],
"(method 51 h-warf)": [5],
"(method 44 nav-graph)": [0, 7, 8, 26, 34],
"(method 15 city-level-info)": [0, 1, 2, 6, 7, 9, 11, 13],
"(method 10 traffic-suppressor)": [0, 1, 2, 4],
"(method 18 traffic-tracker)": [5, 6, 7, 8],
"(method 21 traffic-tracker)": [0],
"(method 9 cty-faction-manager)": [8],
"(method 46 traffic-engine)": [0, 1, 2, 4],
"(method 42 traffic-engine)": [6],
"(method 17 traffic-manager)": [7, 19, 27, 28, 29, 30, 41],
"(anon-function 10 guard-rifle)": [9],
"(method 261 crimson-guard)": [52, 64],
"(anon-function 13 metalhead-predator)": [24, 25],
"(anon-function 90 ctywide-obs)": [4],
"(anon-function 10 cty-sniper-turret)": [44],
"(method 33 rub-tower)": [9, 10],
"(method 30 gungame-manager)": [0, 4, 5, 7]
"(method 36 was-squad-control)": [0, 8, 11, 12, 14, 16]
},
// Sometimes the game might use format strings that are fetched dynamically,
@@ -496,89 +448,7 @@
[68, 1],
[101, 1],
[130, 1]
],
"(method 32 task-manager-desert-turtle-training)": [[59, 1]],
"(method 24 race-manager)": [[97, 1]],
"(method 25 race-manager)": [
[97, 1],
[126, 1]
],
"(method 15 hud-race-final-stats)": [[131, 0]],
"(method 15 hud-wasbbv-goal-time)": [[74, 0]],
"(method 32 task-manager-lightjak-training)": [[53, 0]],
"(method 18 hover-training-manager)": [[69, 0]],
"(method 37 task-manager-arena-training)": [[67, 1]],
"(method 15 hud-arena-final-stats)": [
[103, 0],
[147, 0]
],
"(method 35 task-manager-arena-fight-base)": [[53, 0]],
"(method 32 task-manager-arena-gun-training)": [[53, 0]],
"(method 26 task-manager-arena-fight-2)": [
[72, 0],
[186, 0]
],
"(method 37 task-manager-wascity-gungame)": [
[48, 0],
[78, 0],
[119, 0],
[157, 0],
[195, 0],
[227, 0],
[268, 0],
[306, 0],
[338, 0],
[379, 0],
[411, 0],
[446, 0]
],
"(method 30 was-pre-game)": [
[184, 0],
[276, 0]
],
"(method 32 task-manager-throne-gun-training)": [[53, 0]],
"(method 17 hud-spider-killed)": [[71, 0]],
"(trans idle des-burning-bush)": [
[226, 1],
[257, 0]
],
"(method 37 des-burning-bush)": [
[278, 0],
[336, 0]
],
"(method 38 des-burning-bush)": [
[109, 0],
[153, 0],
[196, 0]
],
"(method 15 freeze-time-hud)": [[108, 0]],
"(method 17 freeze-time-hud)": [[97, 0]],
"(method 15 hud-wasbbv-score)": [[61, 0]],
"(method 15 hud-wasbbv-goal)": [[64, 0]],
"(method 32 task-manager-dark-punch-training)": [[53, 0]],
"(method 32 task-manager-lightjak-training-shield)": [[53, 0]],
"(trans credits highres-viewer-manager)": [[185, 0]],
"(trans idle hirez-viewer)": [[356, 0]],
"(trans idle burning-bush)": [
[171, 1],
[202, 0]
],
"(method 33 task-manager-bbush-board)": [[86, 0]],
"(method 17 board-score-hud)": [[71, 0]],
"(method 23 gungame-manager)": [
[52, 0],
[90, 0],
[128, 0],
[164, 0],
[194, 0],
[235, 0],
[273, 0],
[305, 0],
[346, 0],
[378, 0],
[413, 0]
],
"(trans carry precur-bomb)": [[60, 0]]
]
},
"mips2c_functions_by_name": [
@@ -605,14 +475,13 @@
"draw-large-polygon",
"render-sky-quad",
"render-sky-tri",
"(method 16 sky-work)",
"(method 17 sky-work)",
"(method 18 sky-work)",
"(method 32 sky-work)",
"(method 31 sky-work)",
"(method 34 sky-work)",
"(method 33 sky-work)",
// "(method 28 sky-work)",
"(method 29 sky-work)",
"(method 30 sky-work)",
"(method 35 sky-work)",
"(method 11 collide-hash)",
"(method 12 collide-hash)",
"fill-bg-using-box-new",
@@ -708,26 +577,11 @@
"(method 21 cloth-system)",
"debug-line-clip?",
"(method 9 font-work)",
"(method 9 prim-strip)",
"live-func-curve",
"birth-func-curve",
"sparticle-motion-blur-dirt",
"foreground-draw-hud",
"shadow-execute",
"shadow-add-double-edges",
"shadow-add-single-edges",
"shadow-add-facing-single-tris",
"shadow-add-double-tris",
"shadow-xform-verts",
"shadow-calc-dual-verts",
"shadow-scissor-edges",
"shadow-scissor-top",
"shadow-init-vars",
"shadow-find-facing-single-tris",
"shadow-find-single-edges",
"shadow-find-facing-double-tris",
"shadow-find-double-edges",
"shadow-add-verts",
"shadow-add-single-tris"
"foreground-draw-hud"
],
"mips2c_jump_table_functions": {},
@@ -743,6 +597,7 @@
["lfacctyb", 0, 0],
["intpfall", 0, 0],
["lfaccity", 0, 0],
["lfacctyb-vis", 0, 0],
["ltowcity", 0, 0],
["powergd", 0, 0],
["lcitysml", 0, 0]
+259 -584
View File
@@ -28,286 +28,286 @@
"DGO/WCB.DGO",
"DGO/WCASEEM.DGO",
"DGO/WASCAST.DGO",
// arena
// // arena
"DGO/WASSTADA.DGO",
"DGO/WASSTADB.DGO",
"DGO/WASSTADC.DGO",
"DGO/ARENACST.DGO",
// desert
"DGO/DESA.DGO",
// // desert
// "DGO/DESA.DGO",
"DGO/DESB.DGO",
"DGO/DESBATTL.DGO",
"DGO/DESBCST.DGO",
"DGO/DESBOSS1.DGO",
"DGO/DESBOSS2.DGO",
"DGO/DESC.DGO",
"DGO/DESCHASE.DGO",
"DGO/DESD.DGO",
"DGO/DESE.DGO",
"DGO/DESERROL.DGO",
"DGO/DESF.DGO",
"DGO/DESG.DGO",
"DGO/DESH.DGO",
"DGO/DESHOVER.DGO",
"DGO/DESHUNT.DGO",
// "DGO/DESBATTL.DGO",
// "DGO/DESBCST.DGO",
// "DGO/DESBOSS1.DGO",
// "DGO/DESBOSS2.DGO",
// "DGO/DESC.DGO",
// "DGO/DESCHASE.DGO",
// "DGO/DESD.DGO",
// "DGO/DESE.DGO",
// "DGO/DESERROL.DGO",
// "DGO/DESF.DGO",
// "DGO/DESG.DGO",
// "DGO/DESH.DGO",
// "DGO/DESHOVER.DGO",
// "DGO/DESHUNT.DGO",
"DGO/DESINTER.DGO",
"DGO/DESJUMP.DGO",
"DGO/DESLIZ.DGO",
"DGO/DESOASIS.DGO",
"DGO/DESRACE1.DGO",
"DGO/DESRACE2.DGO",
"DGO/DESRALLY.DGO",
"DGO/DESRESC.DGO",
"DGO/DESRESCC.DGO",
"DGO/DESRESCG.DGO",
"DGO/DESTRACK.DGO",
"DGO/DESW.DGO",
// "DGO/DESJUMP.DGO",
// "DGO/DESLIZ.DGO",
// "DGO/DESOASIS.DGO",
// "DGO/DESRACE1.DGO",
// "DGO/DESRACE2.DGO",
// "DGO/DESRALLY.DGO",
// "DGO/DESRESC.DGO",
// "DGO/DESRESCC.DGO",
// "DGO/DESRESCG.DGO",
// "DGO/DESTRACK.DGO",
// "DGO/DESW.DGO",
"DGO/DST.DGO",
"DGO/OASISCST.DGO",
"DGO/WARPCAST.DGO", // air train
// nest
"DGO/NSA.DGO",
"DGO/NSB.DGO",
// temple
"DGO/TEMA.DGO",
"DGO/TEMB.DGO",
"DGO/TEMC.DGO",
"DGO/TEMD.DGO",
"DGO/TEMP.DGO",
"DGO/TEMPLEE.DGO",
"DGO/TEMX.DGO",
// hang
"DGO/HGA.DGO",
"DGO/HGB.DGO",
// volcano
"DGO/VOCA.DGO",
"DGO/VOCX.DGO",
// "DGO/OASISCST.DGO",
// "DGO/WARPCAST.DGO", // air train
// // nest
// "DGO/NSA.DGO",
// "DGO/NSB.DGO",
// // temple
// "DGO/TEMA.DGO",
// "DGO/TEMB.DGO",
// "DGO/TEMC.DGO",
// "DGO/TEMD.DGO",
// "DGO/TEMP.DGO",
// "DGO/TEMPLEE.DGO",
// "DGO/TEMX.DGO",
// // hang
// "DGO/HGA.DGO",
// "DGO/HGB.DGO",
// // volcano
// "DGO/VOCA.DGO",
// "DGO/VOCX.DGO",
// mine
"DGO/MIA.DGO",
"DGO/MIB.DGO",
"DGO/MIC.DGO",
"DGO/MINED.DGO",
"DGO/MINEE.DGO",
// city
"DGO/CWI.DGO", // ctywide
"DGO/CFA.DGO", // ctyfarm
"DGO/CFB.DGO",
"DGO/CGB.DGO", // ctygen
"DGO/CIA.DGO", // ctyind
"DGO/CIB.DGO",
"DGO/CPO.DGO", // ctyport
"DGO/CTA.DGO", // ctyslum
"DGO/CTB.DGO",
"DGO/CTC.DGO",
"DGO/CTYPEPA.DGO", // citizens
"DGO/CTYPEPB.DGO", // predator
"DGO/CTYPEPC.DGO", // empty
"DGO/CTYPESA.DGO", // guards
"DGO/CTYPESB.DGO", // metal heads
"DGO/CTYPESC.DGO", // kg
"DGO/CTYCARA.DGO", // cars
"DGO/CTYCARB.DGO", // bikes
"DGO/CTYCARC.DGO", // hellcat
"DGO/CTYCARKG.DGO", // empty
"DGO/ONINTENT.DGO",
"DGO/VIN.DGO",
"DGO/HHG.DGO", // hiphog
"DGO/GGA.DGO", // gungame
"DGO/GUNGAME1.DGO",
"DGO/GUNGAME2.DGO",
"DGO/POWERGD.DGO",
"DGO/FREEHQ.DGO",
"DGO/FREECAST.DGO",
"DGO/CITYCAST.DGO",
"DGO/GRIDCST.DGO", // city-destroy-grid-res
"DGO/SLUMBSET.DGO", // sewer-met-hum-intro
// // city
// "DGO/CWI.DGO", // ctywide
// "DGO/CFA.DGO", // ctyfarm
// "DGO/CFB.DGO",
// "DGO/CGB.DGO", // ctygen
// "DGO/CIA.DGO", // ctyind
// "DGO/CIB.DGO",
// "DGO/CPO.DGO", // ctyport
// "DGO/CTA.DGO", // ctyslum
// "DGO/CTB.DGO",
// "DGO/CTC.DGO",
// "DGO/CTYPEPA.DGO", // citizens
// "DGO/CTYPEPB.DGO", // predator
// "DGO/CTYPEPC.DGO", // empty
// "DGO/CTYPESA.DGO", // guards
// "DGO/CTYPESB.DGO", // metal heads
// "DGO/CTYPESC.DGO", // kg
// "DGO/CTYCARA.DGO", // cars
// "DGO/CTYCARB.DGO", // bikes
// "DGO/CTYCARC.DGO", // hellcat
// "DGO/CTYCARKG.DGO", // empty
// "DGO/ONINTENT.DGO",
// "DGO/VIN.DGO",
// "DGO/HHG.DGO", // hiphog
// "DGO/GGA.DGO", // gungame
// "DGO/GUNGAME1.DGO",
// "DGO/GUNGAME2.DGO",
// "DGO/POWERGD.DGO",
// "DGO/FREEHQ.DGO",
// "DGO/FREECAST.DGO",
// "DGO/CITYCAST.DGO",
// "DGO/GRIDCST.DGO", // city-destroy-grid-res
// "DGO/SLUMBSET.DGO", // sewer-met-hum-intro
// sewer
"DGO/SEA.DGO",
"DGO/SEB.DGO",
"DGO/SEC.DGO",
"DGO/SED.DGO",
"DGO/SEE.DGO",
"DGO/SEF.DGO",
"DGO/SEG.DGO",
"DGO/SEH.DGO",
"DGO/SEI.DGO",
"DGO/SEJ.DGO",
"DGO/SEK.DGO",
"DGO/SEL.DGO",
"DGO/SEM.DGO",
"DGO/SEN.DGO",
"DGO/SEO.DGO",
// mhcity
"DGO/MHCA.DGO",
"DGO/MHCB.DGO",
"DGO/MHCTYCST.DGO",
// forest
// "DGO/SEB.DGO",
// "DGO/SEC.DGO",
// "DGO/SED.DGO",
// "DGO/SEE.DGO",
// "DGO/SEF.DGO",
// "DGO/SEG.DGO",
// "DGO/SEH.DGO",
// "DGO/SEI.DGO",
// "DGO/SEJ.DGO",
// "DGO/SEK.DGO",
// "DGO/SEL.DGO",
// "DGO/SEM.DGO",
// "DGO/SEN.DGO",
// "DGO/SEO.DGO",
// // mhcity
// "DGO/MHCA.DGO",
// "DGO/MHCB.DGO",
// "DGO/MHCTYCST.DGO",
// // forest
"DGO/FRSTA.DGO",
"DGO/FRSTB.DGO",
"DGO/FRSTX.DGO",
// factory
"DGO/FACTORYA.DGO",
"DGO/FACB.DGO",
"DGO/FACC.DGO",
"DGO/FACD.DGO",
// tower
"DGO/TOWB.DGO",
"DGO/TOWERA.DGO",
"DGO/TOWERC.DGO",
"DGO/TOWERCST.DGO",
// stadium
"DGO/STA.DGO",
"DGO/STAA.DGO",
"DGO/STB.DGO",
// rubble
"DGO/RUBA.DGO",
"DGO/RUBA2.DGO",
"DGO/RUBB.DGO",
"DGO/RUBC.DGO",
"DGO/RBCT.DGO",
// comb
"DGO/COMBA.DGO",
"DGO/COMBB.DGO",
"DGO/COMBC.DGO",
"DGO/COMBD.DGO",
"DGO/COMBE.DGO",
"DGO/COMBN.DGO",
"DGO/COMBX.DGO",
"DGO/RAILA.DGO",
"DGO/RAILB.DGO",
"DGO/RAILB2.DGO",
"DGO/RAILC.DGO",
"DGO/RAILCST.DGO",
"DGO/RAILD.DGO",
"DGO/RAILE.DGO",
"DGO/RAILF.DGO",
"DGO/RAILX.DGO",
// precursor
"DGO/PRECA.DGO",
"DGO/PRECB.DGO",
"DGO/PRECC.DGO",
// // factory
// "DGO/FACTORYA.DGO",
// "DGO/FACB.DGO",
// "DGO/FACC.DGO",
// "DGO/FACD.DGO",
// // tower
// "DGO/TOWB.DGO",
// "DGO/TOWERA.DGO",
// "DGO/TOWERC.DGO",
// "DGO/TOWERCST.DGO",
// // stadium
// "DGO/STA.DGO",
// "DGO/STAA.DGO",
// "DGO/STB.DGO",
// // rubble
// "DGO/RUBA.DGO",
// "DGO/RUBA2.DGO",
// "DGO/RUBB.DGO",
// "DGO/RUBC.DGO",
// "DGO/RBCT.DGO",
// // comb
// "DGO/COMBA.DGO",
// "DGO/COMBB.DGO",
// "DGO/COMBC.DGO",
// "DGO/COMBD.DGO",
// "DGO/COMBE.DGO",
// "DGO/COMBN.DGO",
// "DGO/COMBX.DGO",
// "DGO/RAILA.DGO",
// "DGO/RAILB.DGO",
// "DGO/RAILB2.DGO",
// "DGO/RAILC.DGO",
// "DGO/RAILCST.DGO",
// "DGO/RAILD.DGO",
// "DGO/RAILE.DGO",
// "DGO/RAILF.DGO",
// "DGO/RAILX.DGO",
// // precursor
// "DGO/PRECA.DGO",
// "DGO/PRECB.DGO",
// "DGO/PRECC.DGO",
// "DGO/PRECD.DGO",
// // title/intro
"DGO/WIN.DGO", // wasintro
"DGO/TITLE.DGO",
"DGO/INTTITLE.DGO",
"DGO/INTPALRF.DGO", // intro-palace-roof
"DGO/IPF.DGO", // intro-palace-fall
"DGO/INTROCST.DGO",
// "DGO/WIN.DGO", // wasintro
// "DGO/TITLE.DGO",
// "DGO/INTTITLE.DGO",
// "DGO/INTPALRF.DGO", // intro-palace-roof
// "DGO/IPF.DGO", // intro-palace-fall
// "DGO/INTROCST.DGO",
// // outro
"DGO/OUTCAST3.DGO",
"DGO/OUTROCST.DGO",
// "DGO/OUTCAST3.DGO",
// "DGO/OUTROCST.DGO",
// // museum
"DGO/MUSEUM.DGO",
"DGO/MUSEUM2.DGO",
"DGO/MUSEUM3.DGO",
"DGO/MUSEUM3B.DGO",
"DGO/MUSEUM4.DGO",
"DGO/MUSEUM4B.DGO",
// "DGO/MUSEUM.DGO",
// "DGO/MUSEUM2.DGO",
// "DGO/MUSEUM3.DGO",
// "DGO/MUSEUM3B.DGO",
// "DGO/MUSEUM4.DGO",
// "DGO/MUSEUM4B.DGO",
// test
"DGO/HALFPIPE.DGO",
// borrow
"DGO/LASHELIN.DGO",
"DGO/LBBRING1.DGO",
"DGO/LBBRING2.DGO",
"DGO/LBBRING3.DGO",
"DGO/LBBRING4.DGO",
"DGO/LBBRING5.DGO",
"DGO/LBBRING6.DGO",
"DGO/LBBSDRP1.DGO",
"DGO/LBBSDRP2.DGO",
"DGO/LBBSDRP3.DGO",
"DGO/LBBSPID.DGO",
"DGO/LBBSPIRT.DGO",
"DGO/LBBSPRT2.DGO",
"DGO/LBBSPRT3.DGO",
"DGO/LBBTCHA1.DGO",
"DGO/LBBTCHA2.DGO",
"DGO/LBBTCHA3.DGO",
"DGO/LBIPED.DGO",
"DGO/LBLOWCST.DGO",
"DGO/LBLOWTKG.DGO",
"DGO/LBLOWTMH.DGO",
"DGO/LBOMBBOT.DGO",
"DGO/LCITYSML.DGO",
"DGO/LCTYASS.DGO",
"DGO/LCTYBLOW.DGO",
"DGO/LCTYDEST.DGO",
"DGO/LCTYHIJK.DGO",
"DGO/LCTYPALT.DGO",
"DGO/LCTYPATK.DGO",
"DGO/LCTYPROT.DGO",
"DGO/LCTYSNPR.DGO",
"DGO/LDAMKLEV.DGO",
"DGO/LDAMPECK.DGO",
"DGO/LDAMPKSM.DGO",
"DGO/LDAMSIG.DGO",
"DGO/LDAX.DGO",
"DGO/LDESGCST.DGO",
"DGO/LDMPCKGN.DGO",
"DGO/LERROL.DGO",
"DGO/LFACB.DGO",
"DGO/LFACCAR.DGO",
"DGO/LFACCITY.DGO",
"DGO/LFACO.DGO",
"DGO/LFACRM1.DGO",
"DGO/LFACRM2.DGO",
"DGO/LFACTORY.DGO",
"DGO/LFORM.DGO",
"DGO/LFORP.DGO",
"DGO/LFORRING.DGO",
"DGO/LFREEOUT.DGO",
"DGO/LGUNNORM.DGO",
"DGO/LGUNRNC.DGO",
"DGO/LJAK.DGO",
"DGO/LJAKC.DGO",
"DGO/LJAKCKLV.DGO",
"DGO/LJAKKLEV.DGO",
"DGO/LJAKNDAX.DGO",
"DGO/LJAKSIG.DGO",
"DGO/LJINX.DGO",
"DGO/LJKCDMKL.DGO",
"DGO/LJKDMPK.DGO",
"DGO/LJKDXVIN.DGO",
"DGO/LJKFEET.DGO",
"DGO/LJNDKLEV.DGO",
"DGO/LKEIRA.DGO",
"DGO/LKLEEVER.DGO",
// // borrow
// "DGO/LASHELIN.DGO",
// "DGO/LBBRING1.DGO",
// "DGO/LBBRING2.DGO",
// "DGO/LBBRING3.DGO",
// "DGO/LBBRING4.DGO",
// "DGO/LBBRING5.DGO",
// "DGO/LBBRING6.DGO",
// "DGO/LBBSDRP1.DGO",
// "DGO/LBBSDRP2.DGO",
// "DGO/LBBSDRP3.DGO",
// "DGO/LBBSPID.DGO",
// "DGO/LBBSPIRT.DGO",
// "DGO/LBBSPRT2.DGO",
// "DGO/LBBSPRT3.DGO",
// "DGO/LBBTCHA1.DGO",
// "DGO/LBBTCHA2.DGO",
// "DGO/LBBTCHA3.DGO",
// "DGO/LBIPED.DGO",
// "DGO/LBLOWCST.DGO",
// "DGO/LBLOWTKG.DGO",
// "DGO/LBLOWTMH.DGO",
// "DGO/LBOMBBOT.DGO",
// "DGO/LCITYSML.DGO",
// "DGO/LCTYASS.DGO",
// "DGO/LCTYBLOW.DGO",
// "DGO/LCTYDEST.DGO",
// "DGO/LCTYHIJK.DGO",
// "DGO/LCTYPALT.DGO",
// "DGO/LCTYPATK.DGO",
// "DGO/LCTYPROT.DGO",
// "DGO/LCTYSNPR.DGO",
// "DGO/LDAMKLEV.DGO",
// "DGO/LDAMPECK.DGO",
// "DGO/LDAMPKSM.DGO",
// "DGO/LDAMSIG.DGO",
// "DGO/LDAX.DGO",
// "DGO/LDESGCST.DGO",
// "DGO/LDMPCKGN.DGO",
// "DGO/LERROL.DGO",
// "DGO/LFACB.DGO",
// "DGO/LFACCAR.DGO",
// "DGO/LFACCITY.DGO",
// "DGO/LFACO.DGO",
// "DGO/LFACRM1.DGO",
// "DGO/LFACRM2.DGO",
// "DGO/LFACTORY.DGO",
// "DGO/LFORM.DGO",
// "DGO/LFORP.DGO",
// "DGO/LFORRING.DGO",
// "DGO/LFREEOUT.DGO",
// "DGO/LGUNNORM.DGO",
// "DGO/LGUNRNC.DGO",
// "DGO/LJAK.DGO",
// "DGO/LJAKC.DGO",
// "DGO/LJAKCKLV.DGO",
// "DGO/LJAKKLEV.DGO",
// "DGO/LJAKNDAX.DGO",
// "DGO/LJAKSIG.DGO",
// "DGO/LJINX.DGO",
// "DGO/LJKCDMKL.DGO",
// "DGO/LJKDMPK.DGO",
// "DGO/LJKDXVIN.DGO",
// "DGO/LJKFEET.DGO",
// "DGO/LJNDKLEV.DGO",
// "DGO/LKEIRA.DGO",
// "DGO/LKLEEVER.DGO",
"DGO/LMECH.DGO",
"DGO/LMHCA.DGO",
"DGO/LMHCB.DGO",
"DGO/LNSTCST.DGO",
"DGO/LNSTOA.DGO",
"DGO/LNSTOBB.DGO",
"DGO/LNSTOBC.DGO",
"DGO/LONINSIM.DGO",
"DGO/LOUTRO.DGO",
"DGO/LOUTRO2.DGO",
"DGO/LOUTRO3.DGO",
"DGO/LPATK.DGO",
"DGO/LPATKCS.DGO",
"DGO/LPRECC.DGO",
"DGO/LPRENME.DGO",
"DGO/LPTRL.DGO",
"DGO/LSAMOS.DGO",
"DGO/LSEEMWCA.DGO",
"DGO/LSIG.DGO",
"DGO/LSIGJAKC.DGO",
"DGO/LSIGKLV.DGO",
"DGO/LSNKWHLS.DGO",
"DGO/LTNFXHIP.DGO",
"DGO/LTNJXHIP.DGO",
"DGO/LTORN.DGO",
"DGO/LTORNJNX.DGO",
"DGO/LTORNSAM.DGO",
"DGO/LTOWA.DGO",
"DGO/LTOWB.DGO",
"DGO/LTOWCITY.DGO",
"DGO/LTRTWHLS.DGO",
"DGO/LVINCST.DGO",
"DGO/LWASBBV.DGO",
"DGO/LWASSIG.DGO",
"DGO/LWLANDM.DGO",
// "DGO/LMHCA.DGO",
// "DGO/LMHCB.DGO",
// "DGO/LNSTCST.DGO",
// "DGO/LNSTOA.DGO",
// "DGO/LNSTOBB.DGO",
// "DGO/LNSTOBC.DGO",
// "DGO/LONINSIM.DGO",
// "DGO/LOUTRO.DGO",
// "DGO/LOUTRO2.DGO",
// "DGO/LOUTRO3.DGO",
// "DGO/LPATK.DGO",
// "DGO/LPATKCS.DGO",
// "DGO/LPRECC.DGO",
// "DGO/LPRENME.DGO",
// "DGO/LPTRL.DGO",
// "DGO/LSAMOS.DGO",
// "DGO/LSEEMWCA.DGO",
// "DGO/LSIG.DGO",
// "DGO/LSIGJAKC.DGO",
// "DGO/LSIGKLV.DGO",
// "DGO/LSNKWHLS.DGO",
// "DGO/LTNFXHIP.DGO",
// "DGO/LTNJXHIP.DGO",
// "DGO/LTORN.DGO",
// "DGO/LTORNJNX.DGO",
// "DGO/LTORNSAM.DGO",
// "DGO/LTOWA.DGO",
// "DGO/LTOWB.DGO",
// "DGO/LTOWCITY.DGO",
// "DGO/LTRTWHLS.DGO",
// "DGO/LVINCST.DGO",
// "DGO/LWASBBV.DGO",
// "DGO/LWASSIG.DGO",
// "DGO/LWLANDM.DGO",
"DGO/LWSTDPCK.DGO"
],
@@ -333,6 +333,10 @@
"TEXT/11COMMON.TXT"
],
// uncomment the next line to extract audio to wave files.
// "audio_dir_file_name": "jak3/VAG",
"audio_dir_file_name": "",
"streamed_audio_file_names": [
"VAGWAD.ENG",
"VAGWAD.FRE",
@@ -343,335 +347,6 @@
"VAGWAD.INT"
],
"animated_textures": [
// dark jak
"jakc-arm",
"jakc-eyebrow",
"jakc-face",
"jakc-finger",
"jakc-hair",
"jakc-arm-norm",
"jakc-eyebrow-norm",
"jakc-face-norm",
"jakc-finger-norm",
"jakc-hair-norm",
"jakc-arm-dark",
"jakc-eyebrow-dark",
"jakc-face-dark",
"jakc-finger-dark",
"jakc-hair-dark",
// darkjak-highres
"jakchires-arm",
"jakchires-arm-norm",
"jakchires-arm-dark",
"jakchires-eye",
"jakchires-eye-norm",
"jakchires-eye-dark",
"jakchires-eyebrow",
"jakchires-eyebrow-norm",
"jakchires-eyebrow-dark",
"jakchires-eyelid",
"jakchires-eyelid-norm",
"jakchires-eyelid-dark",
"jakchires-facelft",
"jakchires-facelft-norm",
"jakchires-facelft-dark",
"jakchires-facert",
"jakchires-facert-norm",
"jakchires-facert-dark",
"jakchires-hair",
"jakchires-hair-norm",
"jakchires-hair-dark",
// Skull Gem
"skull-gem-dest",
"skull-gem-alpha-00",
"skull-gem-alpha-01",
"skull-gem-alpha-02",
// default-water
"bomb-gradient",
"bomb-gradient-rim",
"bomb-gradient-flames",
"lightjak-wings",
"lighjak-wings-u-src",
"lightjak-wings-v-src",
"mushroom-dest",
"mushroom-src",
// default-warp
"shield-env-rim-dest",
"common-white",
"shield-env-uscroll",
"shield-env-rim-src",
// hanga-sprite
"glider-ring-dest2",
"glider-ring-dest",
"splash-foam",
"racegate",
// templea-water
"templea-waterfall-dest",
"templea-waterfall",
// templea-warp
"holograph-env-rim-dest",
"holograph-env-noise",
"holograph-env-scan",
"holograph-env-rim",
"environment-phong-rim",
// foresta-water
"fora-water-dest",
"fora-water",
"fora-waterfall-01-dest",
"fora-waterfall-01",
"fora-water-wave-01-dest",
"fora-water-wave-01",
// forestb-water
"forb-water-dest",
"forb-water",
"forb-waterfall-01-dest",
"forb-waterfall-01",
"forb-water-wave-01-dest",
"forb-water-wave-01",
// lforplnt-pris
"mh-gem-dest",
"mh-gem",
"mh-gem-alpha-01",
"mh-gem-alpha-02",
// lmhcitya-tfrag
"mhcitya-base-goo-01-dest",
"mhcitya-base-goo-01",
// lmhcityb-tfrag
"mhcityb-base-goo-01-dest",
"mhcityb-base-goo-01",
// mhcitya-pris
// "mhcity-de-door-skin-01-dest",
// "mhcity-de-door-skin-01",
// "mhcity-de-door-skin-02"
// templec-water
"tplc-water-dest",
"tplc-water",
// sewc-water
"sewer-water-01-c-dest",
"sewer-water-01-c",
"sewer-waterfall-01-c-dest",
"sewer-waterfall-01-c",
"sewer-waterfall-02-c-dest",
"sewer-waterfall-02-c",
"sewer-water-wave-01-c-dest",
"sewer-water-wave-01-c",
"sewer-water-highlight-01-c-dest",
"sewer-water-highlight-01-c",
// sewd-water
"sewer-water-01-d-dest",
"sewer-water-01-d",
"sewer-waterfall-02-d-dest",
"sewer-waterfall-02-d",
"sewer-water-highlight-01-d-dest",
"sewer-water-highlight-01-d",
"sewer-water-wave-01-d-dest",
"sewer-water-wave-01-d",
"sewer-water-wave-02-d-dest",
"sewer-water-wave-02-d",
"sewer-water-still-01-d-dest",
"sewer-water-still-01-d",
// sewe-water
"sewer-water-01-e-dest",
"sewer-water-01-e",
"sewer-waterfall-01-e-dest",
"sewer-waterfall-01-e",
"sewer-waterfall-02-e-dest",
"sewer-waterfall-02-e",
"sewer-water-highlight-01-e-dest",
"sewer-water-highlight-01-e",
// sewg-water
"sewer-water-01-g-dest",
"sewer-water-01-g",
"sewer-waterfall-02-g-dest",
"sewer-waterfall-02-g",
"sewer-water-wave-01-g-dest",
"sewer-water-wave-01-g",
// sewh-water
"sewer-water-01-h-dest",
"sewer-water-01-h",
"sewer-waterfall-02-h-dest",
"sewer-waterfall-02-h",
"sewer-water-wave-02-h-dest",
"sewer-water-wave-02-h",
"sewer-watefall-froth-01-h-dest",
"sewer-watefall-froth-01-h",
// sewi-water
"sewer-water-still-01-i-dest",
"sewer-water-still-01-i",
"sewer-waterfall-02-i-dest",
"sewer-waterfall-02-i",
"sewer-water-wave-01-i-dest",
"sewer-water-wave-01-i",
// sewj-water
"sewer-waterfall-02-j-dest",
"sewer-waterfall-02-j",
"sewer-watefall-froth-01-j-dest",
"sewer-watefall-froth-01-j",
// sewl-water
"sewer-waterfall-02-l-dest",
"sewer-waterfall-02-l",
"sewer-watefall-froth-01-l-dest",
"sewer-watefall-froth-01-l",
// sewm-water
"sewer-water-01-m-dest",
"sewer-water-01-m",
"sewer-waterfall-01-m-dest",
"sewer-waterfall-01-m",
"sewer-waterfall-02-m-dest",
"sewer-waterfall-02-m",
"sewer-water-highlight-01-m-dest",
"sewer-water-highlight-01-m",
"sewer-water-wave-01-m-dest",
"sewer-water-wave-01-m",
"sewer-water-still-01-m-dest",
"sewer-water-still-01-m",
"sewer-watefall-froth-01-m-dest",
"sewer-watefall-froth-01-m",
// sewn-water
"sewer-waterfall-01-n-dest",
"sewer-waterfall-01-n",
"sewer-waterfall-02-n-dest",
"sewer-waterfall-02-n",
// "sewer-water-highlight-01-n-dest",
// "sewer-water-highlight-01-n",
"sewer-water-wave-01-n-dest",
"sewer-water-wave-01-n",
"sewer-water-still-01-n-dest",
"sewer-water-still-01-n",
// hanga-water
// "des-thermal-01-dest",
// "des-thermal-01"
// desresc-warp
"sat-shield-dest",
"sat-shield-env-uvscroll",
"sat-shield",
// security
"security-env-dest",
"security-env-uscroll",
"security-dot-dest",
"security-dot-src",
// lgunnorm-water
"kg-target-c-forcefield-01-dest",
"kg-target-c-forcefield-01",
// templex-water
"temple-waterfall-dest",
"temple-waterfall",
// desertd-water
"des-waterfall-dest",
"des-waterfall",
// towerb-water
"tow-energy-bridge-dest",
"tow-energy-bridge",
// factoryb-water
"hemi-gradient-dest",
"hemi-gradient-rim",
"hemi-gradient-flames-dest",
"hemi-gradient-flames",
// factoryc-alpha
"facc-convey-dest",
"facc-convey",
"facc-convey-02-dest",
"facc-convey-02",
// waspal-water
"waspala-water-dest",
"waspala-water",
"waspala-waterfall-dest",
"waspala-waterfall",
// rubblea-water
"rub-water-dest",
"rub-water",
// rubblea2-water
"rub-water-desta2",
"rub-watera2",
// rubbleb-water
"rub-water-destb",
"rub-waterb",
// rubblec-water
"rub-water-destc",
"rub-waterc",
// nstb-quicksand
"nstb-quicksand-dest",
"nstb-quicksand-scroll",
// ctyslumb-water
"ctyslumb-water-dest",
"ctyslumb-water",
"ctyslumb-fountain-fall-dest",
"ctyslumb-fountain-fall",
// ctyslumc-water
"ctyslumc-water-dest",
"ctyslumc-water",
"ctyslumc-fountain-fall-dest",
"ctyslumc-fountain-fall",
// mined-tfrag
"mined-pillar-side-dest",
"mined-pillar-side-cold",
"mined-pillar-side-cooling",
"mined-pillar-side-hot",
"mined-pillar-molten",
"mined-pillar-top2side-dest",
"mined-pillar-top2side-cold",
"mined-pillar-top2side-cooling",
"mined-pillar-top2side-hot",
"mined-pillar-top-dest",
"mined-pillar-top-cold",
"mined-pillar-top-cooling",
"mined-pillar-top-hot",
"mined-pillar-molten-top",
// volcanoa-alpha
"vola-lava-01-dest",
"vola-lava-01",
"vola-lava-fall-dest",
"vola-lava-fall",
// wasstada-alpha
"wstd-lava-base-dest",
"wstd-lava-base"
],
"levels_to_extract": [
// wascity
"WASALL.DGO",
File diff suppressed because it is too large. Load diff
@@ -3,9 +3,5 @@
"(method 29 target)": 2048,
"(method 11 part-spawner)": 64,
"(method 11 elevator)": 1024,
"scene-player-init": 1024,
"task-manager-init-by-other": 2048,
"race-manager-init-by-other": 1024,
"neo-sat-shield-init-by-other": 64,
"bt-gun-manager-init-by-other": 256
"scene-player-init": 1024
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -2011,129 +2011,5 @@
"vars": {
"v0-0": ["v0-0", "saberfish-find-behavior"]
}
},
"(method 23 spider-manager)": {
"vars": {
"s3-0": ["dist", "float"]
}
},
"(method 121 sewer-frog)": {
"vars": {
"v1-10": ["name", "sound-name"]
}
},
"(trans target-board-ride-edge)": {
"vars": {
"a0-44": ["name", "sound-name"]
}
},
"(method 9 menu-create-game-option)": {
"vars": {
"a0-26": ["name", "sound-name"]
}
},
"(code active task-manager-forest-plants)": {
"vars": {
"s5-8": ["hand", "handle"]
}
},
"(method 31 dm-mine-spider-spawner)": {
"vars": {
"s3-0": ["s3-0", "float"]
}
},
"(method 26 task-manager-wascity-gungame)": {
"vars": {
"s4-1": ["sname", "sound-name"]
}
},
"terraformer-head-always": {
"vars": {
"s4-2": ["sname", "sound-name"]
}
},
"launch-mine": {
"vars": {
"v0-1": ["hand", "handle"]
}
},
"(method 42 mh-centipede)": {
"vars": {
"s0-0": ["sname", "sound-name"]
}
},
"check-enemy": {
"args": ["turret", "radius", "pfoc"]
},
"(method 202 bot)": {
"vars": {
"s4-0": ["cspec", "collide-spec"]
}
},
"(enter impact warf-projectile)": {
"vars": {
"s4-0": ["sname", "sound-name"]
}
},
"symbol->city-target-type": {
"vars": {
"v0-0": ["type", "city-target-type"]
}
},
"city-target-type->traffic-object-type": {
"vars": {
"v0-0": ["type", "traffic-type"]
}
},
"city-target-type->cty-faction": {
"vars": {
"v0-0": ["type", "cty-faction"]
}
},
"map-symbol-to-nav-territory-type": {
"vars": {
"v0-0": ["type", "nav-territory-type"]
}
},
"guard-type->city-target-type": {
"vars": {
"v0-0": ["type", "city-target-type"]
}
},
"(code die neo-sat)": {
"vars": {
"gp-0": ["hand", "handle"]
}
},
"(method 48 task-manager-desert-rescue)": {
"vars": {
"f30-0": ["f30-0", "float"]
}
},
"(method 31 gun-dummy)": {
"vars": {
"f0-0": "total-time",
"v1-0": "curr-frame"
}
},
"symbol->gun-pickup-type": {
"vars": {
"v0-0": ["type", "pickup-type"]
}
},
"symbol->faction-type": {
"vars": {
"v0-0": ["type", "assault-cmd-faction-type"]
}
},
"symbol->speech-type": {
"vars": {
"v0-0": ["type", "assault-cmd-speech-type"]
}
},
"symbol->assault-target-type": {
"vars": {
"v0-0": ["type", "assault-target-type"]
}
}
}
+3 -41
View File
@@ -515,44 +515,8 @@ TPageResultStats process_tpage(ObjectFileData& data,
// currently not needed.
break;
case int(PSM::PSMT8):
if (tex.clutpsm == (int)CPSM::PSMCT16) {
// will store output pixels, rgba (8888)
std::vector<u8> index_out;
// width is like the TEX0 register, in 64 texel units.
// not sure what the other widths are yet.
int read_width = 64 * tex.width[0];
// loop over pixels in output texture image
for (int y = 0; y < tex.h; y++) {
for (int x = 0; x < tex.w; x++) {
// read as the PSMT8 type. The dest field tells us a block offset.
auto addr8 = psmt8_addr(x, y, read_width) + tex.dest[0] * 256;
u8 value = *(u8*)(vram.data() + addr8);
index_out.push_back(value);
}
}
std::array<math::Vector4<u8>, 256> unscrambled_clut{};
for (int i = 0; i < 256; i++) {
u32 clut_chunk = i / 16;
u32 off_in_chunk = i % 16;
u8 clx = 0, cly = 0;
if (clut_chunk & 1) {
clx = 8;
}
cly = (clut_chunk >> 1) * 2;
if (off_in_chunk >= 8) {
off_in_chunk -= 8;
cly++;
}
clx += off_in_chunk;
u32 clut_addr = psmct16_addr(clx, cly, 64) + tex.clutdest * 256;
memcpy(&unscrambled_clut[i], vram.data() + clut_addr, 4);
}
texture_db.add_index_texture(texture_page.id, tex_id, index_out, unscrambled_clut,
tex.w, tex.h, tex.name, texture_page.name, level_names);
stats.successful_textures++;
} else if (tex.clutpsm == (int)PSM::PSMCT32) {
ASSERT(tex.clutpsm == int(CPSM::PSMCT32));
{
// will store output pixels, index (u8)
std::vector<u8> index_out;
@@ -591,12 +555,10 @@ TPageResultStats process_tpage(ObjectFileData& data,
texture_db.add_index_texture(texture_page.id, tex_id, index_out, unscrambled_clut,
tex.w, tex.h, tex.name, texture_page.name, level_names);
stats.successful_textures++;
} else {
ASSERT_NOT_REACHED();
}
break;
default:
lg::die("Animated texture {} format {} clut {}\n", tex.name, tex.psm, tex.clutpsm);
lg::die("Animated texture {} format {}\n", tex.name, tex.psm);
}
}
-284
View File
@@ -1,284 +0,0 @@
#include "decompilation_process.h"
#include <string>
#include <vector>
#include "config.h"
#include "common/log/log.h"
#include "common/util/Timer.h"
#include "common/util/os.h"
#include "Disasm/OpcodeInfo.h"
#include "ObjectFile/ObjectFileDB.h"
#include "data/streamed_audio.h"
#include "level_extractor/extract_level.h"
int run_decompilation_process(decompiler::Config config,
const fs::path& in_folder,
const fs::path& out_folder,
const bool minimal_for_extractor) {
using namespace decompiler;
Timer decomp_timer;
lg::info("[Mem] Top of main: {} MB\n", get_peak_rss() / (1024 * 1024));
init_opcode_info();
lg::info("[Mem] After init: {} MB\n", get_peak_rss() / (1024 * 1024));
std::vector<fs::path> dgos, objs, strs, tex_strs, art_strs;
if (minimal_for_extractor) {
// TODO - does this even matter, or can we just make the DGOs lazily loaded (does it already
// happen?)
for (const auto& dgo_name : config.dgo_names) {
std::string common_name = "GAME.CGO";
if (dgo_name.length() > 3 && dgo_name.substr(dgo_name.length() - 3) == "DGO") {
// ends in DGO, it's a level
dgos.push_back(in_folder / dgo_name);
} else if (dgo_name.length() >= common_name.length() &&
dgo_name.substr(dgo_name.length() - common_name.length()) == common_name) {
// it's COMMON.CGO, we need that too.
dgos.push_back(in_folder / dgo_name);
}
}
} else {
for (const auto& dgo_name : config.dgo_names) {
dgos.push_back(in_folder / dgo_name);
}
}
if (minimal_for_extractor) {
// TODO - does this even matter, or can we just make the DGOs lazily loaded (does it already
// happen?)
for (const auto& obj_name : config.object_file_names) {
if (obj_name.length() > 3 && obj_name.substr(obj_name.length() - 3) == "TXT") {
// ends in TXT
objs.push_back(in_folder / obj_name);
}
}
} else {
for (const auto& obj_name : config.object_file_names) {
objs.push_back(in_folder / obj_name);
}
}
if (!minimal_for_extractor) {
for (const auto& str_name : config.str_file_names) {
strs.push_back(in_folder / str_name);
}
}
for (const auto& str_name : config.str_texture_file_names) {
tex_strs.push_back(in_folder / str_name);
}
for (const auto& str_name : config.str_art_file_names) {
art_strs.push_back(in_folder / str_name);
}
lg::info("[Mem] After config read: {} MB", get_peak_rss() / (1024 * 1024));
// build file database
lg::info("Setting up object file DB...");
ObjectFileDB db(dgos, fs::path(config.obj_file_name_map_file), objs, strs, tex_strs, art_strs,
config);
// Explicitly fail if a file in the 'allowed_objects' list wasn't found in the DB
// as this is another silent error that can be confusing
if (!config.allowed_objects.empty()) {
for (const auto& expected_obj : config.allowed_objects) {
if (db.obj_files_by_name.count(expected_obj) == 0) {
// TODO - this is wrong for jak1, fix eventually as this is now done in 3 places
lg::error(
"Expected to find '{}' in the ObjectFileDB but did not. Check "
"./decompiler/config/{}/inputs.jsonc",
expected_obj, config.game_name);
return 1;
}
}
}
lg::info("[Mem] After DB setup: {} MB", get_peak_rss() / (1024 * 1024));
// write out DGO file info
file_util::create_dir_if_needed(out_folder);
file_util::write_text_file(out_folder / "dgo.txt", db.generate_dgo_listing());
// write out object file map (used for future decompilations, if desired)
file_util::write_text_file(out_folder / "obj.txt",
db.generate_obj_listing(config.merged_objects));
// dump raw objs
if (config.dump_objs) {
auto path = out_folder / "raw_obj";
file_util::create_dir_if_needed(path);
db.dump_raw_objects(path);
}
// process files (required for all analysis)
db.process_link_data(config);
lg::info("[Mem] After link data: {} MB", get_peak_rss() / (1024 * 1024));
db.find_code(config);
db.process_labels();
lg::info("[Mem] After code: {} MB", get_peak_rss() / (1024 * 1024));
// top level decompile (do this before printing asm so we get function names)
if (config.find_functions) {
db.ir2_top_level_pass(config);
}
// print disassembly
if (config.disassemble_code || config.disassemble_data) {
db.write_disassembly(out_folder, config.disassemble_data, config.disassemble_code,
config.write_hex_near_instructions);
}
if (config.process_art_groups) {
db.extract_art_info();
// dump art info to json if requested
if (config.dump_art_group_info) {
auto ag_file_name = out_folder / "dump" / "art-group-info.min.json";
nlohmann::json ag_json = db.dts.art_group_info;
file_util::create_dir_if_needed_for_file(ag_file_name);
file_util::write_text_file(ag_file_name, ag_json.dump(-1));
lg::info("[DUMP] Dumped art group info to {}", ag_file_name.string());
}
if (config.dump_joint_geo_info) {
auto jg_file_name = out_folder / "dump" / "joint-node-info.min.json";
nlohmann::json jg_json = db.dts.jg_info;
file_util::create_dir_if_needed_for_file(jg_file_name);
file_util::write_text_file(jg_file_name, jg_json.dump(-1));
lg::info("[DUMP] Dumped joint node info to {}", jg_file_name.string());
}
} else if (!config.art_group_info_dump.empty() || !config.jg_info_dump.empty()) {
// process art groups (used in decompilation)
// - if the config has a path to the art info dump, just use that
// - otherwise (or if we want to dump it fresh) extract it
if (!config.art_group_info_dump.empty()) {
db.dts.art_group_info = config.art_group_info_dump;
}
if (!config.jg_info_dump.empty()) {
db.dts.jg_info = config.jg_info_dump;
}
} else {
lg::error("`process_art_groups` was false and no art-group-info dump was provided!");
return 1;
}
if (config.process_tpages && !config.texture_info_dump.empty()) {
db.dts.textures = config.texture_info_dump;
}
// main decompile.
if (config.decompile_code) {
db.analyze_functions_ir2(out_folder, config, {}, {}, {});
}
if (config.generate_all_types) {
ASSERT_MSG(config.decompile_code, "Must decompile code to generate all-types");
db.ir2_analyze_all_types(out_folder / "new-all-types.gc", config.old_all_types_file,
config.hacks.types_with_bad_inspect_methods);
}
lg::info("[Mem] After decomp: {} MB", get_peak_rss() / (1024 * 1024));
// write out all symbols
file_util::write_text_file(out_folder / "all-syms.gc", db.dts.dump_symbol_types());
// write art groups
if (config.process_art_groups) {
db.dump_art_info(out_folder);
}
if (config.hexdump_code || config.hexdump_data) {
db.write_object_file_words(out_folder, config.hexdump_data, config.hexdump_code);
}
// data stuff
if (config.write_scripts) {
db.find_and_write_scripts(out_folder);
}
// ensure asset dir exists
file_util::create_dir_if_needed(out_folder / "assets");
if (config.process_game_text) {
auto result = db.process_game_text_files(config);
if (!result.empty()) {
file_util::write_text_file(out_folder / "assets" / "game_text.txt", result);
}
}
lg::info("[Mem] After text: {} MB", get_peak_rss() / (1024 * 1024));
if (config.process_subtitle_text || config.process_subtitle_images) {
auto result = db.process_all_spool_subtitles(
config, config.process_subtitle_images ? out_folder / "assets" / "subtitle-images" : "");
if (!result.empty()) {
file_util::write_text_file(out_folder / "assets" / "game_subs.txt", result);
}
}
lg::info("[Mem] After spool handling: {} MB", get_peak_rss() / (1024 * 1024));
TextureDB tex_db;
if (config.process_tpages || config.levels_extract) {
auto textures_out = out_folder / "textures";
auto dump_out = out_folder / "import";
file_util::create_dir_if_needed(textures_out);
auto result = db.process_tpages(tex_db, textures_out, config, dump_out);
if (!result.empty() && config.process_tpages) {
file_util::write_text_file(textures_out / "tpage-dir.txt", result);
file_util::write_text_file(textures_out / "tex-remap.txt",
tex_db.generate_texture_dest_adjustment_table());
}
if (config.dump_tex_info) {
auto texture_file_name = out_folder / "dump" / "tex-info.min.json";
nlohmann::json texture_json = db.dts.textures;
file_util::create_dir_if_needed_for_file(texture_file_name);
file_util::write_text_file(texture_file_name, texture_json.dump(-1));
lg::info("[DUMP] Dumped texture info to {}", texture_file_name.string());
}
}
lg::info("[Mem] After textures: {} MB", get_peak_rss() / (1024 * 1024));
// Merge textures before replacing them, in other words, replacements take priority
auto texture_merge_path = file_util::get_jak_project_dir() / "game" / "assets" /
game_version_names[config.game_version] / "texture_merges";
if (fs::exists(texture_merge_path)) {
tex_db.merge_textures(texture_merge_path);
}
auto replacements_path = file_util::get_jak_project_dir() / "custom_assets" /
game_version_names[config.game_version] / "texture_replacements";
if (fs::exists(replacements_path)) {
tex_db.replace_textures(replacements_path);
}
if (config.process_game_count) {
auto result = db.process_game_count_file();
if (!result.empty()) {
file_util::write_text_file(out_folder / "assets" / "game_count.txt", result);
}
}
if (config.levels_extract) {
auto level_out_path =
file_util::get_jak_project_dir() / "out" / game_version_names[config.game_version] / "fr3";
file_util::create_dir_if_needed(level_out_path);
extract_all_levels(db, tex_db, config.levels_to_extract, "GAME.CGO", config, level_out_path);
}
lg::info("[Mem] After extraction: {} MB", get_peak_rss() / (1024 * 1024));
if (config.rip_streamed_audio) {
auto streaming_audio_out = out_folder / "audio";
file_util::create_dir_if_needed(streaming_audio_out);
process_streamed_audio(config, streaming_audio_out, in_folder,
config.streamed_audio_file_names);
}
lg::info("Decompiler has finished successfully in {:.2f} seconds.", decomp_timer.getSeconds());
return 0;
}
Loaded 100 of 2590 files, more files were not shown because too many files have changed in this diff. Show more