mirror of
https://github.com/open-goal/jak-project
synced 2026-09-08 20:02:39 -04:00
Merge remote-tracking branch 'origin/master' into v/format-jak1
This commit is contained in:
@@ -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_levels $DEST/data
|
||||
cp -r $SOURCE/custom_assets $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_levels $DEST/data
|
||||
cp -r $SOURCE/custom_assets $DEST/data
|
||||
|
||||
+3
-1
@@ -54,7 +54,9 @@ imgui.ini
|
||||
node_modules/
|
||||
|
||||
# texture replacements
|
||||
texture_replacements/*
|
||||
custom_assets/jak1/texture_replacements/*
|
||||
custom_assets/jak2/texture_replacements/*
|
||||
custom_assets/jak3/texture_replacements/*
|
||||
|
||||
# generated cmake files
|
||||
svnrev.h
|
||||
|
||||
@@ -87,9 +87,11 @@ add_library(common
|
||||
util/term_util.cpp
|
||||
util/Timer.cpp
|
||||
util/unicode_util.cpp
|
||||
versions/versions.cpp)
|
||||
util/gltf_util.cpp
|
||||
versions/versions.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(common fmt lzokay replxx libzstd_static tree-sitter sqlite3 libtinyfiledialogs)
|
||||
target_link_libraries(common fmt lzokay replxx libzstd_static tree-sitter sqlite3 libtinyfiledialogs tiny_gltf)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(common wsock32 ws2_32 windowsapp)
|
||||
|
||||
@@ -42,7 +42,9 @@ std::vector<std::string> jak2_slots = {
|
||||
"cas-toxic-slime-scroll-dest",
|
||||
};
|
||||
|
||||
std::vector<std::string> jak3_slots = {};
|
||||
std::vector<std::string> jak3_slots = {
|
||||
"skull-gem-dest", "jakc-arm", "jakc-eyebrow", "jakc-face", "jakc-finger", "jakc-hair",
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
#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
|
||||
@@ -0,0 +1,71 @@
|
||||
#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
|
||||
@@ -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_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_assets/jak1/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/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/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.
|
||||
|
||||
# 3: Modify the build system
|
||||
Modify `goal_src/game.gp` and add a custom level target:
|
||||
Modify `goal_src/jak1/game.gp` and add a custom level target:
|
||||
```lisp
|
||||
(build-custom-level "test-zone")
|
||||
;; the DGO file
|
||||
@@ -21,7 +21,7 @@ Modify `goal_src/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_level/your_level`
|
||||
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`
|
||||
|
||||
# 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.
|
||||
+22
-10
@@ -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_levels/jak1/test-zone/test-zone2.glb",
|
||||
"gltf_file": "custom_assets/jak1/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,
|
||||
@@ -55,20 +55,22 @@
|
||||
// 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": [],
|
||||
|
||||
// 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": [
|
||||
// If you have any custom models in the "custom_assets/jak1/models" 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": [
|
||||
// all textures required for the zoomer HUD
|
||||
// "zoomerhud",
|
||||
// "zoomerhud-dial",
|
||||
@@ -130,6 +132,16 @@
|
||||
"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
|
||||
+3
-1
@@ -4,6 +4,8 @@
|
||||
;; the actual file name still needs to be 8.3
|
||||
("TSZ.DGO"
|
||||
("static-screen.o"
|
||||
"test-zone.go"
|
||||
"test-zone-obs.o"
|
||||
"plat-ag.go"
|
||||
"test-actor-ag.go"
|
||||
"test-zone.go"
|
||||
))
|
||||
Binary file not shown.
+1
-1
@@ -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_levels/jak2/test-zone/test-zone2.glb",
|
||||
"gltf_file": "custom_assets/jak2/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,
|
||||
+1
-1
@@ -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_levels/jak3/test-zone/test-zone2.glb",
|
||||
"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,
|
||||
@@ -6754,7 +6754,12 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(deftype texture-anim-layer (structure)
|
||||
((extra vector :inline :offset 240)
|
||||
((interpolated-color vector :inline) ;; added
|
||||
(interpolated-scale-offset vector :inline)
|
||||
(interpolated-st-scale-offset vector :inline)
|
||||
(interpolated-qs vector :inline)
|
||||
(interpolated-rot vector :inline)
|
||||
(extra vector :inline :offset 240)
|
||||
(func (function dma-buffer uint int int texture-anim-layer float int) :offset-assert 256) ;; guessed by decompiler
|
||||
(func-id symbol :offset-assert 256 :overlay-at func) ;; guessed by decompiler
|
||||
(init-func (function texture-anim-layer int) :offset-assert 260) ;; guessed by decompiler
|
||||
@@ -6766,6 +6771,8 @@
|
||||
(test gs-test :offset-assert 280) ;; gs-test
|
||||
(alpha gs-alpha :offset-assert 288) ;; gs-alpha
|
||||
(clamp gs-clamp :offset-assert 296) ;; gs-clamp
|
||||
(start-vectors vector 5 :inline :offset 80 :score -10) ;; added
|
||||
|
||||
(start-color vector :inline :offset 80)
|
||||
(start-scale vector2 :inline :offset 96)
|
||||
(start-offset vector2 :inline :offset 104)
|
||||
@@ -6774,6 +6781,8 @@
|
||||
(start-qs vector :inline :offset 128)
|
||||
(start-rot degrees :offset 144) ;; degrees
|
||||
(start-st-rot degrees :offset 148) ;; degrees
|
||||
(end-vectors vector 5 :inline :offset 160 :score -10) ;; added
|
||||
|
||||
(end-color vector :inline :offset 160)
|
||||
(end-scale vector2 :inline :offset 176)
|
||||
(end-offset vector2 :inline :offset 184)
|
||||
@@ -13101,7 +13110,7 @@
|
||||
|
||||
(deftype drawable-tree-region-prim (drawable-tree)
|
||||
"Top-level container for all regions of a level."
|
||||
((name basic :offset 8)
|
||||
((name symbol :offset 8)
|
||||
(data2 drawable-inline-array :dynamic :offset 32 :score 1))
|
||||
:method-count-assert 19
|
||||
:size-assert #x20
|
||||
@@ -30840,7 +30849,6 @@
|
||||
;; shadow-cpu ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
#|
|
||||
(deftype shadow-stats (structure)
|
||||
((num-single-tris uint32 :offset-assert 0)
|
||||
(num-double-tris uint32 :offset-assert 4)
|
||||
@@ -30853,9 +30861,7 @@
|
||||
:size-assert #x14
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|#
|
||||
|
||||
#|
|
||||
(deftype shadow-dcache (structure)
|
||||
((vtx-table uint32 :offset-assert 0)
|
||||
(single-edge-table uint32 :offset-assert 4)
|
||||
@@ -30883,40 +30889,38 @@
|
||||
:size-assert #xb0
|
||||
:flag-assert #x9000000b0
|
||||
)
|
||||
|#
|
||||
|
||||
;; (define-extern *shadow-data* object) ;; shadow-data
|
||||
;; (define-extern shadow-invert-z-buf function) ;; (function dma-buffer none)
|
||||
;; (define-extern shadow-make-invert-buf function) ;; (function none)
|
||||
;; (define-extern *shadow-dma-invert-call* object) ;; pointer
|
||||
;; (define-extern shadow-dma-init function) ;; (function dma-buffer none)
|
||||
;; (define-extern shadow-dma-end function) ;; (function dma-buffer gs-rgbaq symbol int none)
|
||||
;; (define-extern shadow-vu0-block object) ;; vu-function
|
||||
;; (define-extern shadow-xform-verts function) ;; function
|
||||
;; (define-extern shadow-calc-dual-verts function) ;; function
|
||||
;; (define-extern shadow-scissor-edges function) ;; function
|
||||
;; (define-extern shadow-scissor-top function) ;; function
|
||||
;; (define-extern shadow-init-vars function) ;; function
|
||||
;; (define-extern shadow-find-facing-single-tris function) ;; function
|
||||
;; (define-extern shadow-find-single-edges function) ;; function
|
||||
;; (define-extern shadow-find-facing-double-tris function) ;; function
|
||||
;; (define-extern shadow-find-double-edges function) ;; function
|
||||
;; (define-extern shadow-add-verts function) ;; function
|
||||
;; (define-extern shadow-add-facing-single-tris function) ;; function
|
||||
;; (define-extern shadow-add-single-edges function) ;; function
|
||||
;; (define-extern shadow-add-single-tris function) ;; function
|
||||
;; (define-extern shadow-add-double-tris function) ;; function
|
||||
;; (define-extern shadow-add-double-edges function) ;; function
|
||||
;; (define-extern debug-draw-settings function) ;; (function shadow-settings symbol)
|
||||
;; (define-extern shadow-execute function) ;; (function shadow-dma-packet pointer pointer)
|
||||
;; (define-extern shadow-vu0-upload function) ;; (function none)
|
||||
(define-extern *shadow-data* shadow-data)
|
||||
(define-extern shadow-invert-z-buf (function dma-buffer none))
|
||||
(define-extern shadow-make-invert-buf (function none))
|
||||
(define-extern *shadow-dma-invert-call* pointer)
|
||||
(define-extern shadow-dma-init (function dma-buffer none))
|
||||
(define-extern shadow-dma-end (function dma-buffer gs-rgbaq symbol int none))
|
||||
(define-extern shadow-vu0-block vu-function)
|
||||
(define-extern shadow-xform-verts function)
|
||||
(define-extern shadow-calc-dual-verts function)
|
||||
(define-extern shadow-scissor-edges function)
|
||||
(define-extern shadow-scissor-top function)
|
||||
(define-extern shadow-init-vars function)
|
||||
(define-extern shadow-find-facing-single-tris function)
|
||||
(define-extern shadow-find-single-edges function)
|
||||
(define-extern shadow-find-facing-double-tris function)
|
||||
(define-extern shadow-find-double-edges function)
|
||||
(define-extern shadow-add-verts function)
|
||||
(define-extern shadow-add-facing-single-tris function)
|
||||
(define-extern shadow-add-single-edges function)
|
||||
(define-extern shadow-add-single-tris function)
|
||||
(define-extern shadow-add-double-tris function)
|
||||
(define-extern shadow-add-double-edges function)
|
||||
(define-extern debug-draw-settings (function shadow-settings symbol))
|
||||
(define-extern shadow-execute (function shadow-dma-packet pointer pointer))
|
||||
(define-extern shadow-vu0-upload (function none))
|
||||
(define-extern shadow-execute-all (function dma-buffer none))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; shadow-vu1 ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
#|
|
||||
(deftype shadow-vu1-constants (structure)
|
||||
((hmgescale vector :inline :offset-assert 0)
|
||||
(invhscale vector :inline :offset-assert 16)
|
||||
@@ -30924,7 +30928,7 @@
|
||||
(texscale vector :inline :offset-assert 48)
|
||||
(hvdfoff vector :inline :offset-assert 64)
|
||||
(fog vector :inline :offset-assert 80)
|
||||
(clrs vector 2 :offset-assert 96) ;; guessed by decompiler
|
||||
(clrs vector 2 :inline :offset-assert 96) ;; guessed by decompiler
|
||||
(adgif gs-gif-tag :inline :offset-assert 128)
|
||||
(texflush gs-adcmd :inline :offset-assert 144)
|
||||
(flush gs-adcmd :inline :offset-assert 160)
|
||||
@@ -30935,9 +30939,7 @@
|
||||
:size-assert #xd0
|
||||
:flag-assert #x9000000d0
|
||||
)
|
||||
|#
|
||||
|
||||
#|
|
||||
(deftype shadow-vu1-data (structure)
|
||||
((adgif gs-gif-tag :inline :offset-assert 0)
|
||||
(ad gs-adcmd :inline :offset-assert 16)
|
||||
@@ -30946,20 +30948,19 @@
|
||||
(quadgif gs-gif-tag :inline :offset-assert 64)
|
||||
(texoffset vector :inline :offset-assert 80)
|
||||
(texscale vector :inline :offset-assert 96)
|
||||
(clrs qword 2 :offset-assert 112) ;; guessed by decompiler
|
||||
(clrs qword 2 :inline :offset-assert 112) ;; guessed by decompiler
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x90
|
||||
:flag-assert #x900000090
|
||||
)
|
||||
|#
|
||||
|
||||
;; (define-extern *shadow-vu1-data* object) ;; shadow-vu1-data
|
||||
;; (define-extern shadow-vu1-block object) ;; vu-function
|
||||
;; (define-extern shadow-vu1-add-constants function) ;; (function dma-buffer int none)
|
||||
;; (define-extern shadow-vu1-patch-consts function) ;; (function symbol int none)
|
||||
;; (define-extern shadow-vu1-add-matrix function) ;; (function dma-buffer math-camera none)
|
||||
;; (define-extern shadow-vu1-init-buffer function) ;; (function dma-buffer int none)
|
||||
(define-extern *shadow-vu1-data* shadow-vu1-data)
|
||||
(define-extern shadow-vu1-block vu-function)
|
||||
(define-extern shadow-vu1-add-constants (function dma-buffer int none))
|
||||
(define-extern shadow-vu1-patch-consts (function symbol int none))
|
||||
(define-extern shadow-vu1-add-matrix (function dma-buffer math-camera none))
|
||||
(define-extern shadow-vu1-init-buffer (function dma-buffer int none))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; warp ;;
|
||||
@@ -30975,57 +30976,57 @@
|
||||
;; texture-anim ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; (define-extern *texture-anim-work* object) ;; texture-anim-work
|
||||
;; (define-extern texture-anim-layer-interp function) ;; (function texture-anim-layer float none)
|
||||
;; (define-extern texture-anim-layer-add-shader function) ;; (function dma-buffer texture-anim-layer int none)
|
||||
;; (define-extern texture-anim-layer-add-clut-shader function) ;; (function dma-buffer texture-anim-layer int none)
|
||||
;; (define-extern texture-anim-layer-draw function) ;; (function dma-buffer int int texture-anim-layer none)
|
||||
;; (define-extern default-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern blend-clut-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern add-clut-texture-anim-layer-func function)
|
||||
;; (define-extern dest-blend-clut-texture-anim-layer-func function)
|
||||
;; (define-extern move-rg-to-ba-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern fill-rgb-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern texture-anim-draw-mip-shader function)
|
||||
;; (define-extern clear-texture-ids function)
|
||||
;; (define-extern texture-anim-draw-mips function)
|
||||
(define-extern *texture-anim-work* texture-anim-work)
|
||||
(define-extern texture-anim-layer-interp (function texture-anim-layer float none))
|
||||
(define-extern texture-anim-layer-add-shader (function dma-buffer texture-anim-layer int none))
|
||||
(define-extern texture-anim-layer-add-clut-shader (function dma-buffer texture-anim-layer int none))
|
||||
(define-extern texture-anim-layer-draw (function dma-buffer int int texture-anim-layer none))
|
||||
(define-extern default-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern blend-clut-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern add-clut-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern dest-blend-clut-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern move-rg-to-ba-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern fill-rgb-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern texture-anim-draw-mip-shader (function dma-buffer texture int none))
|
||||
(define-extern clear-texture-ids (function texture none))
|
||||
(define-extern texture-anim-draw-mips (function dma-buffer texture none))
|
||||
(define-extern update-texture-anim (function bucket-id texture-anim-array none))
|
||||
;; (define-extern no-alpha-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern copy-alpha-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern copy-clut-alpha-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern set-alpha-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern set-clut-alpha-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern dest-texture-init function) ;; (function texture-anim none)
|
||||
;; (define-extern src-texture-init function) ;; (function texture-anim-layer none)
|
||||
;; (define-extern src-texture-init-mt8 function) ;; (function texture-anim-layer none)
|
||||
;; (define-extern make-noise-texture function) ;; (function pointer int int int none)
|
||||
;; (define-extern make-cloud-clut function) ;; (function (pointer uint32) float float none)
|
||||
;; (define-extern texture-anim-cloud-clut-upload function) ;; (function dma-buffer texture-anim none)
|
||||
;; (define-extern texture-anim-cloud-clut-init function) ;; (function texture-anim none)
|
||||
;; (define-extern make-slime-clut function) ;; (function (pointer uint32) none)
|
||||
;; (define-extern texture-anim-slime-clut-upload function) ;; (function dma-buffer texture-anim none)
|
||||
;; (define-extern texture-anim-slime-clut-init function) ;; (function texture-anim none)
|
||||
;; (define-extern make-ramp-clut function) ;; (function (pointer uint32) pointer object none)
|
||||
;; (define-extern make-alpha-ramp-clut function) ;; (function (pointer uint32) none)
|
||||
;; (define-extern noise-texture-init function) ;; (function texture-anim-layer none)
|
||||
;; (define-extern texture-anim-alpha-ramp-clut-upload function) ;; (function dma-buffer texture-anim none)
|
||||
;; (define-extern texture-anim-alpha-ramp-clut-init function) ;; (function texture-anim none)
|
||||
;; (define-extern texture-anim-overide-size-init function) ;; (function texture-anim none)
|
||||
;; (define-extern texture-anim-change-mt8h-init function) ;; (function texture-anim none)
|
||||
;; (define-extern *texture-anim-pages-table* object)
|
||||
;; (define-extern *texture-anim-mip-array* object)
|
||||
(define-extern no-alpha-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern copy-alpha-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern copy-clut-alpha-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern set-alpha-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern set-clut-alpha-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern dest-texture-init (function texture-anim none))
|
||||
(define-extern src-texture-init (function texture-anim-layer none))
|
||||
(define-extern src-texture-init-mt8 (function texture-anim-layer none))
|
||||
(define-extern make-noise-texture (function pointer int int int none))
|
||||
(define-extern make-cloud-clut (function (pointer uint32) float float none))
|
||||
(define-extern texture-anim-cloud-clut-upload (function dma-buffer texture-anim none))
|
||||
(define-extern texture-anim-cloud-clut-init (function texture-anim none))
|
||||
(define-extern make-slime-clut (function (pointer uint32) none))
|
||||
(define-extern texture-anim-slime-clut-upload (function dma-buffer texture-anim none))
|
||||
(define-extern texture-anim-slime-clut-init (function texture-anim none))
|
||||
(define-extern make-ramp-clut (function (pointer uint32) pointer object none))
|
||||
(define-extern make-alpha-ramp-clut (function (pointer uint32) none))
|
||||
(define-extern noise-texture-init (function texture-anim-layer none))
|
||||
(define-extern texture-anim-alpha-ramp-clut-upload (function dma-buffer texture-anim none))
|
||||
(define-extern texture-anim-alpha-ramp-clut-init (function texture-anim none))
|
||||
(define-extern texture-anim-overide-size-init (function texture-anim none))
|
||||
(define-extern texture-anim-change-mt8h-init (function texture-anim none))
|
||||
(define-extern *texture-anim-pages-table* (pointer uint8))
|
||||
(define-extern *texture-anim-mip-array* (pointer uint16))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; texture-anim-funcs ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; (define-extern noise-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern cloud-texture-anim-layer-func function) ;; (function dma-buffer uint int int texture-anim-layer float int)
|
||||
;; (define-extern cloud-texture-anim-func function) ;; (function dma-buffer texture-anim int)
|
||||
;; (define-extern fog-texture-anim-init function) ;; (function texture-anim int)
|
||||
(define-extern noise-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern cloud-texture-anim-layer-func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(define-extern cloud-texture-anim-func (function dma-buffer texture-anim int))
|
||||
(define-extern fog-texture-anim-init (function texture-anim int))
|
||||
(define-extern *fog-texture-work* fog-texture-work)
|
||||
;; (define-extern real-fog-texture-anim-func function) ;; (function dma-buffer texture-anim int)
|
||||
;; (define-extern fog-texture-anim-func function) ;; (function dma-buffer texture-anim int)
|
||||
(define-extern real-fog-texture-anim-func (function dma-buffer texture-anim int))
|
||||
(define-extern fog-texture-anim-func (function dma-buffer texture-anim int))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; texture-anim-tables ;;
|
||||
|
||||
@@ -78,10 +78,6 @@
|
||||
"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)",
|
||||
@@ -715,7 +711,23 @@
|
||||
"live-func-curve",
|
||||
"birth-func-curve",
|
||||
"sparticle-motion-blur-dirt",
|
||||
"foreground-draw-hud"
|
||||
"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"
|
||||
],
|
||||
|
||||
"mips2c_jump_table_functions": {},
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"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",
|
||||
|
||||
// Skull Gem
|
||||
"skull-gem-dest",
|
||||
"skull-gem-alpha-00",
|
||||
"skull-gem-alpha-01",
|
||||
"skull-gem-alpha-02"
|
||||
],
|
||||
|
||||
"levels_to_extract": [
|
||||
// wascity
|
||||
"WASALL.DGO",
|
||||
|
||||
@@ -2460,5 +2460,9 @@
|
||||
["L575", "vector4w"],
|
||||
["L576", "vector4w"],
|
||||
["L577", "vector4w"]
|
||||
],
|
||||
"texture-anim": [
|
||||
["L198", "(pointer uint8)", 16],
|
||||
["L197", "(pointer uint16)", 48]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2507,5 +2507,6 @@
|
||||
"(post idle precur-bridge-blocks-break)": [
|
||||
[16, "vector"],
|
||||
[32, "vector"]
|
||||
]
|
||||
],
|
||||
"texture-anim-layer-draw": [[16, "matrix"], [80, "matrix"], [144, "matrix"], [208, "matrix"]]
|
||||
}
|
||||
|
||||
@@ -10851,6 +10851,9 @@
|
||||
["_stack_", 76, "float"],
|
||||
["_stack_", 100, "float"]
|
||||
],
|
||||
"real-wang-texture-anim-func": [
|
||||
[[3, 31], "v1", "mood-context"]
|
||||
],
|
||||
"(method 24 sky-work)": [
|
||||
[256, "s4", "(pointer int32)"],
|
||||
[261, "s4", "(pointer int32)"]
|
||||
@@ -11102,5 +11105,166 @@
|
||||
],
|
||||
"(method 10 neon-baron)": [[11, "s5", "uint"]],
|
||||
"(method 15 neon-baron)": [[29, "s5", "int"]],
|
||||
"(method 16 neon-baron)": [[5, "a1", "int"]]
|
||||
"(method 16 neon-baron)": [[5, "a1", "int"]],
|
||||
"texture-anim-layer-add-clut-shader": [
|
||||
[[23, 30], "a3", "dma-packet"],
|
||||
[[32, 39], "a3", "gs-gif-tag"],
|
||||
[49, "a1", "(pointer gs-tex0)"],
|
||||
[51, "a1", "(pointer gs-reg64)"],
|
||||
[52, "a1", "(pointer gs-tex1)"],
|
||||
[54, "a1", "(pointer gs-reg64)"],
|
||||
[56, "a1", "(pointer gs-test)"],
|
||||
[58, "a1", "(pointer gs-reg64)"],
|
||||
[60, "a1", "(pointer gs-clamp)"],
|
||||
[62, "a1", "(pointer gs-reg64)"],
|
||||
[64, "a1", "(pointer gs-alpha)"],
|
||||
[66, "a1", "(pointer gs-reg64)"]
|
||||
],
|
||||
"texture-anim-layer-draw": [
|
||||
[[24, 182], "s4", "(pointer uint128)"]
|
||||
],
|
||||
"update-texture-anim": [
|
||||
[213, "v1", "(pointer uint128)"],
|
||||
[[214, 230], "t0", "vector4w"],
|
||||
[[230, 238], "t0", "vector4w"],
|
||||
[[239, 247], "v1", "vector4w"]
|
||||
],
|
||||
"(method 9 texture-anim-layer)": [
|
||||
[5, "v1", "symbol"],
|
||||
[11, "v1", "symbol"]
|
||||
],
|
||||
"(method 9 texture-anim)": [
|
||||
[5, "v1", "symbol"],
|
||||
[11, "v1", "symbol"],
|
||||
["_stack_", 16, "texture-page"]
|
||||
],
|
||||
"shadow-vu1-init-buffer": [[[18, 27], "a0", "dma-packet"]],
|
||||
"shadow-vu1-add-constants": [
|
||||
[[7, 16], "a2", "dma-packet"],
|
||||
[[20, 66], "v1", "shadow-vu1-constants"],
|
||||
[[72, 77], "a1", "dma-packet"],
|
||||
[[82, 94], "a1", "shadow-vu1-data"]
|
||||
],
|
||||
"shadow-vu1-add-matrix": [
|
||||
[[11, 19], "a3", "dma-packet"],
|
||||
[[26, 30], "v1", "matrix"]
|
||||
],
|
||||
"shadow-vu0-upload": [[[16, 18], "a0", "dma-packet"]],
|
||||
"shadow-make-invert-buf": [[[13, 16], "v1", "dma-packet"]],
|
||||
"shadow-invert-z-buf": [
|
||||
[[4, 8], "a2", "dma-packet"],
|
||||
[[13, 16], "a2", "gs-gif-tag"],
|
||||
[27, "t1", "(pointer gs-reg)"],
|
||||
[28, "t1", "(pointer gs-reg64)"],
|
||||
[30, "t1", "(pointer gs-reg)"],
|
||||
[32, "t1", "(pointer gs-frame)"],
|
||||
[34, "t1", "(pointer gs-reg)"],
|
||||
[38, "t1", "(pointer gs-reg)"],
|
||||
[42, "t1", "(pointer gs-reg)"],
|
||||
[36, "t1", "(pointer gs-zbuf)"],
|
||||
[40, "t1", "(pointer gs-test)"],
|
||||
[44, "t1", "(pointer gs-alpha)"],
|
||||
[45, "t1", "(pointer gs-reg)"],
|
||||
[47, "t1", "(pointer gs-reg64)"],
|
||||
[49, "t1", "(pointer gs-reg)"],
|
||||
[51, "t1", "(pointer gs-rgbaq)"],
|
||||
[[61, 64], "t2", "gs-gif-tag"],
|
||||
[89, "t4", "(pointer gs-xyzf)"],
|
||||
[79, "t4", "(pointer gs-xyzf)"],
|
||||
[[106, 117], "v1", "(pointer uint64)"]
|
||||
],
|
||||
"shadow-dma-init": [
|
||||
[[18, 21], "t4", "dma-packet"],
|
||||
[[27, 31], "t6", "dma-packet"],
|
||||
[[36, 39], "t6", "gs-gif-tag"],
|
||||
[43, "t4", "(pointer gs-reg64)"],
|
||||
[47, "t4", "(pointer gs-test)"],
|
||||
[45, "t4", "(pointer gs-reg64)"],
|
||||
[49, "t4", "(pointer gs-reg64)"],
|
||||
[51, "t4", "(pointer gs-alpha)"],
|
||||
[53, "t4", "(pointer gs-reg64)"],
|
||||
[58, "t4", "(pointer gs-frame)"],
|
||||
[60, "t4", "(pointer gs-reg64)"],
|
||||
[64, "t4", "(pointer gs-reg64)"],
|
||||
[73, "t4", "(pointer gs-reg64)"],
|
||||
[81, "t4", "(pointer gs-reg)"],
|
||||
[84, "t4", "(pointer gs-reg)"],
|
||||
[62, "t4", "(pointer gs-zbuf)"],
|
||||
[71, "t4", "(pointer gs-xy-offset)"],
|
||||
[79, "t4", "(pointer gs-tex0)"],
|
||||
[82, "t4", "(pointer gs-tex1)"],
|
||||
[85, "t4", "(pointer gs-miptbp)"],
|
||||
[87, "t4", "(pointer gs-reg)"],
|
||||
[96, "t4", "(pointer gs-clamp)"],
|
||||
[[103, 106], "t3", "gs-gif-tag"],
|
||||
[[122, 125], "t3", "gs-gif-tag"],
|
||||
[111, "t3", "(pointer gs-prim)"],
|
||||
[113, "t3", "(pointer gs-rgbaq)"],
|
||||
[143, "t5", "(pointer gs-xyzf)"],
|
||||
[156, "t5", "(pointer gs-xyzf)"],
|
||||
[[167, 170], "a3", "gs-gif-tag"],
|
||||
[177, "a3", "(pointer gs-test)"],
|
||||
[179, "a3", "(pointer gs-reg64)"],
|
||||
[183, "a3", "(pointer gs-reg64)"],
|
||||
[193, "a3", "(pointer gs-reg64)"],
|
||||
[190, "a3", "(pointer gs-reg64)"],
|
||||
[202, "a3", "(pointer gs-reg64)"],
|
||||
[181, "a3", "(pointer gs-zbuf)"],
|
||||
[188, "a3", "(pointer gs-frame)"],
|
||||
[191, "a3", "(pointer uint64)"],
|
||||
[206, "a3", "(pointer gs-reg64)"],
|
||||
[213, "a3", "(pointer gs-reg64)"],
|
||||
[214, "a3", "(pointer uint64)"],
|
||||
[216, "a3", "(pointer gs-reg64)"],
|
||||
[211, "a3", "(pointer gs-frame)"],
|
||||
[204, "a3", "(pointer gs-zbuf)"],
|
||||
[200, "a3", "(pointer gs-test)"],
|
||||
[229, "v1", "(pointer uint64)"],
|
||||
[225, "v1", "(pointer uint64)"],
|
||||
[230, "v1", "(pointer uint64)"],
|
||||
[235, "v1", "(pointer uint64)"]
|
||||
],
|
||||
"shadow-dma-end": [
|
||||
[34, "a1", "dma-packet"],
|
||||
[33, "a1", "dma-packet"],
|
||||
[36, "a1", "dma-packet"],
|
||||
[25, "v1", "(pointer uint64)"],
|
||||
[41, "v1", "dma-packet"],
|
||||
[42, "v1", "(pointer uint64)"],
|
||||
[[113, 116], "a0", "gs-gif-tag"],
|
||||
[[102, 107], "a0", "dma-packet"],
|
||||
[120, "a0", "(pointer uint64)"],
|
||||
[122, "a0", "(pointer gs-reg64)"],
|
||||
[126, "a0", "(pointer gs-reg64)"],
|
||||
[133, "a0", "(pointer gs-reg64)"],
|
||||
[134, "a0", "(pointer uint64)"],
|
||||
[136, "a0", "(pointer gs-reg64)"],
|
||||
[137, "a0", "(pointer uint64)"],
|
||||
[139, "a0", "(pointer gs-reg64)"],
|
||||
[124, "a0", "(pointer gs-test)"],
|
||||
[131, "a0", "(pointer gs-frame)"],
|
||||
[[146, 151], "a1", "dma-packet"],
|
||||
[201, "t0", "(pointer uint64)"],
|
||||
[214, "t0", "(pointer uint64)"],
|
||||
[237, "t0", "(pointer uint64)"],
|
||||
[250, "t0", "(pointer uint64)"],
|
||||
[[156, 159], "a1", "gs-gif-tag"],
|
||||
[160, "a1", "(pointer gs-prim)"],
|
||||
[161, "a1", "(pointer gs-rgbaq)"],
|
||||
[[166, 169], "a1", "(inline-array gs-gif-tag)"],
|
||||
[268, "v1", "(pointer uint64)"],
|
||||
[264, "v1", "(pointer uint64)"],
|
||||
[269, "v1", "(pointer uint64)"],
|
||||
[274, "v1", "(pointer uint64)"]
|
||||
],
|
||||
"shadow-execute-all": [
|
||||
[[56, 63], "v1", "shadow-dcache"],
|
||||
[114, "v1", "shadow-dcache"],
|
||||
[119, "a0", "uint32"],
|
||||
[[191, 249], "gp", "shadow-dcache"],
|
||||
[96, "v1", "shadow-dcache"]
|
||||
],
|
||||
"real-fog-texture-anim-func": [
|
||||
[[6, 160], "s2", "(pointer uint32)"]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -191,7 +191,8 @@ void decompile(const fs::path& iso_data_path,
|
||||
}
|
||||
|
||||
// texture replacements
|
||||
auto replacements_path = file_util::get_jak_project_dir() / "texture_replacements";
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "decompiler/level_extractor/extract_tfrag.h"
|
||||
#include "decompiler/level_extractor/extract_tie.h"
|
||||
#include "decompiler/level_extractor/fr3_to_gltf.h"
|
||||
#include "goalc/build_actor/jak1/build_actor.h"
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
|
||||
+2
-1
@@ -322,7 +322,8 @@ int main(int argc, char** argv) {
|
||||
tex_db.merge_textures(texture_merge_path);
|
||||
}
|
||||
|
||||
auto replacements_path = file_util::get_jak_project_dir() / "texture_replacements";
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ set(RUNTIME_SOURCE
|
||||
graphics/opengl_renderer/sprite/Sprite3_Glow.cpp
|
||||
graphics/opengl_renderer/sprite/Sprite3.cpp
|
||||
graphics/opengl_renderer/TextureAnimator.cpp
|
||||
graphics/opengl_renderer/TextureAnimatorDefs.cpp
|
||||
graphics/opengl_renderer/TextureUploadHandler.cpp
|
||||
graphics/opengl_renderer/VisDataHandler.cpp
|
||||
graphics/opengl_renderer/Warp.cpp
|
||||
@@ -212,6 +213,7 @@ set(RUNTIME_SOURCE
|
||||
mips2c/jak3_functions/merc_blend_shape.cpp
|
||||
mips2c/jak3_functions/wvehicle_part.cpp
|
||||
mips2c/jak3_functions/ripple.cpp
|
||||
mips2c/jak3_functions/shadow.cpp
|
||||
mips2c/jak3_functions/ocean.cpp
|
||||
mips2c/jak3_functions/ocean_vu0.cpp
|
||||
mips2c/jak3_functions/generic_merc.cpp
|
||||
|
||||
@@ -97,10 +97,9 @@ OpenGLRenderer::OpenGLRenderer(std::shared_ptr<TexturePool> texture_pool,
|
||||
case GameVersion::Jak1:
|
||||
break;
|
||||
case GameVersion::Jak2:
|
||||
m_texture_animator = std::make_shared<TextureAnimator>(m_render_state.shaders, common_level);
|
||||
break;
|
||||
case GameVersion::Jak3:
|
||||
// for now, no texture animation for jak3...
|
||||
m_texture_animator =
|
||||
std::make_shared<TextureAnimator>(m_render_state.shaders, common_level, m_version);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
@@ -130,7 +129,6 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
using namespace jak3;
|
||||
m_bucket_renderers.resize((int)BucketId::MAX_BUCKETS);
|
||||
m_bucket_categories.resize((int)BucketId::MAX_BUCKETS, BucketCategory::OTHER);
|
||||
std::shared_ptr<TextureAnimator> texture_animator = nullptr; // todo tex anim
|
||||
{
|
||||
auto p = scoped_prof("render-inits");
|
||||
|
||||
@@ -140,7 +138,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
|
||||
// 4
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-sky-pre", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_SKY_PRE, texture_animator);
|
||||
BucketId::TEX_LCOM_SKY_PRE, m_texture_animator);
|
||||
init_bucket_renderer<DirectRenderer>("sky", BucketCategory::OTHER, BucketId::SKY, 1024 * 8);
|
||||
|
||||
init_bucket_renderer<OceanMidAndFar>("ocean-mid-far", BucketCategory::OCEAN,
|
||||
@@ -156,7 +154,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
init_bucket_renderer<TextureUploadHandler>(
|
||||
fmt::format("tex-l{}-tfrag", i), BucketCategory::TEX,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::TEX_L0_TFRAG, BucketId::TEX_L1_TFRAG, i),
|
||||
texture_animator);
|
||||
m_texture_animator);
|
||||
// 11
|
||||
init_bucket_renderer<TFragment>(
|
||||
fmt::format("tfrag-l{}-tfrag", i), BucketCategory::TFRAG,
|
||||
@@ -230,7 +228,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
|
||||
// 340
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-tfrag", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_TFRAG, texture_animator);
|
||||
BucketId::TEX_LCOM_TFRAG, m_texture_animator);
|
||||
init_bucket_renderer<Merc2BucketRenderer>("merc-lcom-tfrag", BucketCategory::MERC,
|
||||
BucketId::MERC_LCOM_TFRAG, m_merc2);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("gmerc-lcom-tfrag", BucketCategory::GENERIC,
|
||||
@@ -238,20 +236,24 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
Generic2::Mode::NORMAL);
|
||||
// 345
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-shrub", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_SHRUB, texture_animator);
|
||||
BucketId::TEX_LCOM_SHRUB, m_texture_animator);
|
||||
init_bucket_renderer<Merc2BucketRenderer>("merc-lcom-shrub", BucketCategory::MERC,
|
||||
BucketId::MERC_LCOM_SHRUB, m_merc2);
|
||||
|
||||
// 350
|
||||
init_bucket_renderer<Shadow2>("shadow", BucketCategory::OTHER, BucketId::SHADOW);
|
||||
|
||||
// 351
|
||||
for (int i = 0; i < LEVEL_MAX; i++) {
|
||||
#define GET_BUCKET_ID_FOR_LIST(bkt1, bkt2, idx) ((int)(bkt1) + ((int)(bkt2) - (int)(bkt1)) * (idx))
|
||||
init_bucket_renderer<TextureUploadHandler>(
|
||||
fmt::format("tex-l{}-pris", i), BucketCategory::TEX,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::TEX_L0_PRIS, BucketId::TEX_L1_PRIS, i),
|
||||
texture_animator);
|
||||
m_texture_animator);
|
||||
init_bucket_renderer<TextureUploadHandler>(
|
||||
fmt::format("tex-l{}-pris2", i), BucketCategory::TEX,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::TEX_L0_PRIS2, BucketId::TEX_L1_PRIS2, i),
|
||||
texture_animator);
|
||||
m_texture_animator);
|
||||
|
||||
init_bucket_renderer<Merc2BucketRenderer>(
|
||||
fmt::format("merc-l{}-pris", i), BucketCategory::MERC,
|
||||
@@ -272,7 +274,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
|
||||
// 401
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-pris", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_PRIS, texture_animator);
|
||||
BucketId::TEX_LCOM_PRIS, m_texture_animator);
|
||||
init_bucket_renderer<Merc2BucketRenderer>("merc-lcom-pris", BucketCategory::MERC,
|
||||
BucketId::MERC_LCOM_PRIS, m_merc2);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("gmerc-lcom-pris", BucketCategory::GENERIC,
|
||||
@@ -281,7 +283,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
|
||||
// 461
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-sky-post", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_SKY_POST, texture_animator);
|
||||
BucketId::TEX_LCOM_SKY_POST, m_texture_animator);
|
||||
init_bucket_renderer<OceanNear>("ocean-near", BucketCategory::OCEAN, BucketId::OCEAN_NEAR);
|
||||
|
||||
// 463
|
||||
@@ -291,7 +293,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
init_bucket_renderer<TextureUploadHandler>(
|
||||
fmt::format("tex-l{}-water", i), BucketCategory::TEX,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::TEX_L0_WATER, BucketId::TEX_L1_WATER, i),
|
||||
texture_animator);
|
||||
m_texture_animator);
|
||||
init_bucket_renderer<Merc2BucketRenderer>(
|
||||
fmt::format("merc-l{}-water", i), BucketCategory::MERC,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::MERC_L0_WATER, BucketId::MERC_L1_WATER, i), m_merc2);
|
||||
@@ -308,20 +310,23 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
|
||||
// 563
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-water", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_WATER, texture_animator);
|
||||
BucketId::TEX_LCOM_WATER, m_texture_animator);
|
||||
init_bucket_renderer<Merc2BucketRenderer>("merc-lcom-water", BucketCategory::MERC,
|
||||
BucketId::MERC_LCOM_WATER, m_merc2);
|
||||
|
||||
// 568
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-sprite", BucketCategory::TEX,
|
||||
BucketId::TEX_SPRITE, texture_animator);
|
||||
BucketId::TEX_SPRITE, m_texture_animator);
|
||||
init_bucket_renderer<Sprite3>("particles", BucketCategory::SPRITE, BucketId::PARTICLES);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-3", BucketCategory::OTHER,
|
||||
BucketId::GENERIC_SPRITE_3, m_generic2,
|
||||
Generic2::Mode::LIGHTNING);
|
||||
|
||||
init_bucket_renderer<Shadow2>("shadow2", BucketCategory::OTHER, BucketId::SHADOW2);
|
||||
init_bucket_renderer<Shadow2>("shadow3", BucketCategory::OTHER, BucketId::SHADOW3);
|
||||
// 575
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-warp", BucketCategory::TEX, BucketId::TEX_WARP,
|
||||
texture_animator);
|
||||
m_texture_animator);
|
||||
init_bucket_renderer<Warp>("generic-warp", BucketCategory::GENERIC, BucketId::GENERIC_WARP,
|
||||
m_generic2);
|
||||
|
||||
@@ -329,16 +334,16 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
BucketId::DEBUG_NO_ZBUF1, m_texture_animator, true);
|
||||
// 578
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-hud-hud-alpha", BucketCategory::TEX,
|
||||
BucketId::TEX_HUD_HUD_ALPHA, texture_animator);
|
||||
BucketId::TEX_HUD_HUD_ALPHA, m_texture_animator);
|
||||
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-hud-hud-alpha", BucketCategory::TEX,
|
||||
BucketId::TEX_HUD_HUD_ALPHA, texture_animator);
|
||||
BucketId::TEX_HUD_HUD_ALPHA, m_texture_animator);
|
||||
init_bucket_renderer<ProgressRenderer>("hud-draw-hud-alpha", BucketCategory::OTHER,
|
||||
BucketId::HUD_DRAW_HUD_ALPHA, 0x8000);
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-hud-pris2", BucketCategory::TEX,
|
||||
BucketId::TEX_HUD_PRIS2, texture_animator);
|
||||
BucketId::TEX_HUD_PRIS2, m_texture_animator);
|
||||
init_bucket_renderer<TextureUploadHandler>("hud-draw-pris2", BucketCategory::TEX,
|
||||
BucketId::HUD_DRAW_PRIS2, texture_animator);
|
||||
BucketId::HUD_DRAW_PRIS2, m_texture_animator);
|
||||
init_bucket_renderer<ProgressRenderer>("progress", BucketCategory::OTHER, BucketId::BUCKET582,
|
||||
0x8000);
|
||||
|
||||
|
||||
@@ -208,6 +208,9 @@ int output_slot_by_idx(GameVersion version, const std::string& name) {
|
||||
case GameVersion::Jak2:
|
||||
v = &jak2_animated_texture_slots();
|
||||
break;
|
||||
case GameVersion::Jak3:
|
||||
v = &jak3_animated_texture_slots();
|
||||
break;
|
||||
default:
|
||||
case GameVersion::Jak1:
|
||||
ASSERT_NOT_REACHED();
|
||||
@@ -352,12 +355,26 @@ Psm32ToPsm8Scrambler::Psm32ToPsm8Scrambler(int w, int h, int write_tex_width, in
|
||||
}
|
||||
}
|
||||
|
||||
TextureAnimator::TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* common_level)
|
||||
const std::vector<std::string>& animated_texture_slots(GameVersion version) {
|
||||
switch (version) {
|
||||
case GameVersion::Jak2:
|
||||
return jak2_animated_texture_slots();
|
||||
case GameVersion::Jak3:
|
||||
return jak3_animated_texture_slots();
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
TextureAnimator::TextureAnimator(ShaderLibrary& shaders,
|
||||
const tfrag3::Level* common_level,
|
||||
GameVersion version)
|
||||
: m_common_level(common_level),
|
||||
m_psm32_to_psm8_8_8(8, 8, 8, 64),
|
||||
m_psm32_to_psm8_16_16(16, 16, 16, 64),
|
||||
m_psm32_to_psm8_32_32(32, 32, 16, 64),
|
||||
m_psm32_to_psm8_64_64(64, 64, 64, 64),
|
||||
m_version(version),
|
||||
m_sky_blend_texture(kFinalSkyTextureSize, kFinalSkyTextureSize, GL_UNSIGNED_INT_8_8_8_8_REV),
|
||||
m_sky_final_texture(kFinalSkyTextureSize, kFinalSkyTextureSize, GL_UNSIGNED_INT_8_8_8_8_REV),
|
||||
m_sky_hires_blend_texture(kFinalSkyHiresTextureSize,
|
||||
@@ -462,12 +479,22 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* co
|
||||
m_index_to_clut_addr[i] = clx + cly * 16;
|
||||
}
|
||||
|
||||
m_public_output_slots.resize(jak2_animated_texture_slots().size(), m_dummy_texture);
|
||||
m_public_output_slots.resize(animated_texture_slots(m_version).size(), m_dummy_texture);
|
||||
m_private_output_slots = m_public_output_slots;
|
||||
m_output_debug_flags.resize(jak2_animated_texture_slots().size());
|
||||
m_output_debug_flags.resize(animated_texture_slots(m_version).size());
|
||||
|
||||
// animation-specific stuff
|
||||
setup_texture_anims();
|
||||
setup_texture_anims_common();
|
||||
switch (m_version) {
|
||||
case GameVersion::Jak2:
|
||||
setup_texture_anims_jak2();
|
||||
break;
|
||||
case GameVersion::Jak3:
|
||||
setup_texture_anims_jak3();
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
setup_sky();
|
||||
}
|
||||
@@ -485,7 +512,7 @@ int TextureAnimator::create_fixed_anim_array(const std::vector<FixedAnimDef>& de
|
||||
anim.def = def;
|
||||
|
||||
// set up the destination texture.
|
||||
anim.dest_slot = output_slot_by_idx(GameVersion::Jak2, anim.def.tex_name);
|
||||
anim.dest_slot = output_slot_by_idx(m_version, anim.def.tex_name);
|
||||
auto* dtex = tex_by_name(m_common_level, anim.def.tex_name);
|
||||
if (anim.def.override_size) {
|
||||
anim.fbt.emplace(anim.def.override_size->x(), anim.def.override_size->y(),
|
||||
@@ -552,7 +579,7 @@ void TextureAnimator::draw_debug_window() {
|
||||
imgui_show_tex(m_sky_hires_noise_textures[i].new_tex);
|
||||
}
|
||||
|
||||
auto& slots = jak2_animated_texture_slots();
|
||||
auto& slots = animated_texture_slots(m_version);
|
||||
for (size_t i = 0; i < slots.size(); i++) {
|
||||
ImGui::Text("Slot %d %s (%d)", (int)i, slots[i].c_str(), (int)m_private_output_slots[i]);
|
||||
imgui_show_tex(m_private_output_slots[i]);
|
||||
@@ -562,7 +589,7 @@ void TextureAnimator::draw_debug_window() {
|
||||
}
|
||||
|
||||
void TextureAnimator::copy_private_to_public() {
|
||||
auto& slots = jak2_animated_texture_slots();
|
||||
auto& slots = animated_texture_slots(m_version);
|
||||
for (size_t i = 0; i < slots.size(); i++) {
|
||||
if (m_output_debug_flags[i].b) {
|
||||
m_public_output_slots[i] = m_dummy_texture;
|
||||
@@ -598,7 +625,7 @@ void TextureAnimator::add_to_clut_blender_group(int idx,
|
||||
grp.blenders.emplace_back(prefix,
|
||||
std::array<std::string, 2>{prefix + suffix0, prefix + suffix1}, dgo,
|
||||
m_common_level, &m_opengl_texture_pool);
|
||||
grp.outputs.push_back(output_slot_by_idx(GameVersion::Jak2, prefix));
|
||||
grp.outputs.push_back(output_slot_by_idx(m_version, prefix));
|
||||
m_private_output_slots.at(grp.outputs.back()) = grp.blenders.back().texture();
|
||||
}
|
||||
}
|
||||
@@ -984,7 +1011,7 @@ void TextureAnimator::force_to_gpu(int tbp) {
|
||||
PcTextureId TextureAnimator::get_id_for_tbp(TexturePool* pool, u64 tbp, u64 other_id) {
|
||||
const auto& it = m_ids_by_vram.find(tbp | (other_id << 32));
|
||||
if (it == m_ids_by_vram.end()) {
|
||||
auto ret = pool->allocate_pc_port_texture(GameVersion::Jak2);
|
||||
auto ret = pool->allocate_pc_port_texture(m_version);
|
||||
m_ids_by_vram[tbp] = ret;
|
||||
return ret;
|
||||
} else {
|
||||
@@ -2047,471 +2074,6 @@ void TextureAnimator::run_fixed_animation(FixedAnim& anim, float time) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void TextureAnimator::setup_texture_anims() {
|
||||
// DARKJAK
|
||||
m_darkjak_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakbsmall-eyebrow", "jakbsmall-face", "jakbsmall-finger", "jakbsmall-hair"}, "-norm",
|
||||
"-dark", {});
|
||||
|
||||
// PRISON
|
||||
// MISSING EYELID
|
||||
m_jakb_prison_clut_blender_idx = create_clut_blender_group(
|
||||
{"jak-orig-arm-formorph", "jak-orig-eyebrow-formorph", "jak-orig-finger-formorph"}, "-start",
|
||||
"-end", "LDJAKBRN.DGO");
|
||||
add_to_clut_blender_group(m_jakb_prison_clut_blender_idx,
|
||||
{"jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm", "-dark",
|
||||
"LDJAKBRN.DGO");
|
||||
|
||||
// ORACLE
|
||||
// MISSING FINGER
|
||||
m_jakb_oracle_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm",
|
||||
"-dark", "ORACLE.DGO");
|
||||
|
||||
// NEST
|
||||
// MISSING FINGER
|
||||
m_jakb_nest_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm",
|
||||
"-dark", "NEB.DGO");
|
||||
|
||||
// KOR (doesn't work??)
|
||||
m_kor_transform_clut_blender_idx = create_clut_blender_group(
|
||||
{
|
||||
// "kor-eyeeffect-formorph",
|
||||
// "kor-hair-formorph",
|
||||
// "kor-head-formorph",
|
||||
// "kor-head-formorph-noreflect",
|
||||
// "kor-lowercaps-formorph",
|
||||
// "kor-uppercaps-formorph",
|
||||
},
|
||||
"-start", "-end", {});
|
||||
|
||||
// Skull Gem
|
||||
{
|
||||
FixedAnimDef skull_gem;
|
||||
skull_gem.move_to_pool = true;
|
||||
skull_gem.tex_name = "skull-gem-dest";
|
||||
skull_gem.color = math::Vector4<u8>{0, 0, 0, 0x80};
|
||||
// overriden in texture-finish.gc
|
||||
skull_gem.override_size = math::Vector2<int>(32, 32);
|
||||
|
||||
auto& skull_gem_0 = skull_gem.layers.emplace_back();
|
||||
skull_gem_0.end_time = 300.;
|
||||
skull_gem_0.tex_name = "skull-gem-alpha-00";
|
||||
skull_gem_0.set_blend_b2_d1();
|
||||
skull_gem_0.set_no_z_write_no_z_test();
|
||||
|
||||
auto& skull_gem_1 = skull_gem.layers.emplace_back();
|
||||
skull_gem_1.end_time = 300.;
|
||||
skull_gem_1.tex_name = "skull-gem-alpha-01";
|
||||
skull_gem_1.set_blend_b2_d1();
|
||||
skull_gem_1.set_no_z_write_no_z_test();
|
||||
|
||||
auto& skull_gem_2 = skull_gem.layers.emplace_back();
|
||||
skull_gem_2.end_time = 300.;
|
||||
skull_gem_2.tex_name = "skull-gem-alpha-02";
|
||||
skull_gem_2.set_blend_b2_d1();
|
||||
skull_gem_2.set_no_z_write_no_z_test();
|
||||
|
||||
m_skull_gem_fixed_anim_array_idx = create_fixed_anim_array({skull_gem});
|
||||
}
|
||||
|
||||
// Bomb
|
||||
{
|
||||
FixedAnimDef bomb;
|
||||
bomb.tex_name = "bomb-gradient";
|
||||
bomb.color = math::Vector4<u8>{0, 0, 0, 0x80};
|
||||
|
||||
auto& bomb_0 = bomb.layers.emplace_back();
|
||||
bomb_0.end_time = 300.;
|
||||
bomb_0.tex_name = "bomb-gradient-rim";
|
||||
bomb_0.set_blend_b2_d1();
|
||||
bomb_0.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
bomb_0.channel_masks[3] = false; // no alpha writes.
|
||||
|
||||
auto& bomb_1 = bomb.layers.emplace_back();
|
||||
bomb_1.end_time = 300.;
|
||||
bomb_1.tex_name = "bomb-gradient-flames";
|
||||
bomb_1.set_blend_b2_d1();
|
||||
bomb_1.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
bomb_1.channel_masks[3] = false; // no alpha writes.
|
||||
|
||||
m_bomb_fixed_anim_array_idx = create_fixed_anim_array({bomb});
|
||||
}
|
||||
|
||||
// CAS conveyor
|
||||
{
|
||||
FixedAnimDef conveyor_0;
|
||||
conveyor_0.tex_name = "cas-conveyor-dest";
|
||||
conveyor_0.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_0.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c0 = conveyor_0.layers.emplace_back();
|
||||
c0.set_blend_b2_d1();
|
||||
c0.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c0.channel_masks[3] = false; // no alpha writes.
|
||||
c0.end_time = 300.;
|
||||
c0.tex_name = "cas-conveyor";
|
||||
|
||||
FixedAnimDef conveyor_1;
|
||||
conveyor_1.tex_name = "cas-conveyor-dest-01";
|
||||
conveyor_1.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_1.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c1 = conveyor_1.layers.emplace_back();
|
||||
c1.set_blend_b2_d1();
|
||||
c1.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c1.channel_masks[3] = false; // no alpha writes.
|
||||
c1.end_time = 300.;
|
||||
c1.tex_name = "cas-conveyor";
|
||||
|
||||
FixedAnimDef conveyor_2;
|
||||
conveyor_2.tex_name = "cas-conveyor-dest-02";
|
||||
conveyor_2.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_2.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c2 = conveyor_2.layers.emplace_back();
|
||||
c2.set_blend_b2_d1();
|
||||
c2.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c2.channel_masks[3] = false; // no alpha writes.
|
||||
c2.end_time = 300.;
|
||||
c2.tex_name = "cas-conveyor";
|
||||
|
||||
FixedAnimDef conveyor_3;
|
||||
conveyor_3.tex_name = "cas-conveyor-dest-03";
|
||||
conveyor_3.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_3.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c3 = conveyor_3.layers.emplace_back();
|
||||
c3.set_blend_b2_d1();
|
||||
c3.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c3.channel_masks[3] = false; // no alpha writes.
|
||||
c3.end_time = 300.;
|
||||
c3.tex_name = "cas-conveyor";
|
||||
|
||||
m_cas_conveyor_anim_array_idx =
|
||||
create_fixed_anim_array({conveyor_0, conveyor_1, conveyor_2, conveyor_3});
|
||||
}
|
||||
|
||||
// SECURITY
|
||||
{
|
||||
FixedAnimDef env;
|
||||
env.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
env.tex_name = "security-env-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& env1 = env.layers.emplace_back();
|
||||
env1.tex_name = "security-env-uscroll";
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
env1.set_no_z_write_no_z_test();
|
||||
env1.channel_masks[3] = false; // no alpha writes.
|
||||
// :alpha (new 'static 'gs-alpha :b #x2 :d #x1)
|
||||
env1.set_blend_b2_d1();
|
||||
env1.end_time = 4800.f;
|
||||
}
|
||||
|
||||
FixedAnimDef dot;
|
||||
dot.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
dot.tex_name = "security-dot-dest";
|
||||
|
||||
auto& cwhite = dot.layers.emplace_back();
|
||||
cwhite.set_blend_b2_d1();
|
||||
cwhite.set_no_z_write_no_z_test();
|
||||
cwhite.tex_name = "common-white";
|
||||
cwhite.end_time = 4800.f;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& dsrc = dot.layers.emplace_back();
|
||||
dsrc.set_blend_b2_d1();
|
||||
dsrc.set_no_z_write_no_z_test();
|
||||
dsrc.end_time = 600.f;
|
||||
dsrc.tex_name = "security-dot-src";
|
||||
}
|
||||
|
||||
m_security_anim_array_idx = create_fixed_anim_array({env, dot});
|
||||
}
|
||||
|
||||
// WATERFALL
|
||||
{
|
||||
FixedAnimDef waterfall;
|
||||
waterfall.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
waterfall.tex_name = "waterfall-dest";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& src = waterfall.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 450.f;
|
||||
src.tex_name = "waterfall";
|
||||
}
|
||||
m_waterfall_anim_array_idx = create_fixed_anim_array({waterfall});
|
||||
}
|
||||
|
||||
{
|
||||
FixedAnimDef waterfall;
|
||||
waterfall.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
waterfall.tex_name = "waterfall-dest";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& src = waterfall.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 450.f;
|
||||
src.tex_name = "waterfall";
|
||||
}
|
||||
m_waterfall_b_anim_array_idx = create_fixed_anim_array({waterfall});
|
||||
}
|
||||
|
||||
// LAVA
|
||||
{
|
||||
FixedAnimDef lava;
|
||||
lava.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
lava.tex_name = "dig-lava-01-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& src = lava.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 3600.f;
|
||||
src.tex_name = "dig-lava-01";
|
||||
}
|
||||
m_lava_anim_array_idx = create_fixed_anim_array({lava});
|
||||
}
|
||||
|
||||
{
|
||||
FixedAnimDef lava;
|
||||
lava.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
lava.tex_name = "dig-lava-01-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& src = lava.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 3600.f;
|
||||
src.tex_name = "dig-lava-01";
|
||||
}
|
||||
m_lava_b_anim_array_idx = create_fixed_anim_array({lava});
|
||||
}
|
||||
|
||||
// Stadiumb
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "stdmb-energy-wall-01-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 300.f;
|
||||
src.tex_name = "stdmb-energy-wall-01";
|
||||
}
|
||||
m_stadiumb_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// Fortress pris
|
||||
{
|
||||
FixedAnimDef l_tread;
|
||||
l_tread.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
l_tread.tex_name = "robotank-tread-l-dest";
|
||||
auto& l_src = l_tread.layers.emplace_back();
|
||||
l_src.set_blend_b1_d1();
|
||||
l_src.set_no_z_write_no_z_test();
|
||||
l_src.channel_masks[3] = false; // no alpha writes.
|
||||
l_src.end_time = 1.f;
|
||||
l_src.tex_name = "robotank-tread";
|
||||
|
||||
FixedAnimDef r_tread;
|
||||
r_tread.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
r_tread.tex_name = "robotank-tread-r-dest";
|
||||
auto& r_src = r_tread.layers.emplace_back();
|
||||
r_src.set_blend_b1_d1();
|
||||
r_src.set_no_z_write_no_z_test();
|
||||
r_src.channel_masks[3] = false; // no alpha writes.
|
||||
r_src.end_time = 1.f;
|
||||
r_src.tex_name = "robotank-tread";
|
||||
|
||||
m_fortress_pris_anim_array_idx = create_fixed_anim_array({l_tread, r_tread});
|
||||
}
|
||||
|
||||
// Fortress Warp
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.move_to_pool = true;
|
||||
def.tex_name = "fort-roboscreen-dest";
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 300.f;
|
||||
src.tex_name = "fort-roboscreen-env";
|
||||
m_fortress_warp_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// metkor
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "squid-env-rim-dest";
|
||||
def.move_to_pool = true;
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-noise";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-scan";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "environment-phong-rim";
|
||||
}
|
||||
m_metkor_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// shield
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "squid-env-rim-dest";
|
||||
def.move_to_pool = true;
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "common-white";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-uscroll";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-uscroll";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-rim-src";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-rim-src";
|
||||
}
|
||||
m_shield_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// krew
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "krew-holo-dest";
|
||||
def.move_to_pool = true;
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-noise";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-scan";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-phong-env";
|
||||
}
|
||||
m_krew_holo_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
}
|
||||
|
||||
// initial values of the random table for cloud texture generation.
|
||||
constexpr Vector16ub kInitialRandomTable[TextureAnimator::kRandomTableSize] = {
|
||||
{0x20, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x89, 0x67, 0x45, 0x23, 0x1},
|
||||
@@ -2614,28 +2176,6 @@ void TextureAnimator::setup_sky() {
|
||||
m_random_table, dim, m_random_index);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
m_slime_output_slot = output_slot_by_idx(GameVersion::Jak2, "cas-toxic-slime-dest");
|
||||
m_slime_scroll_output_slot =
|
||||
output_slot_by_idx(GameVersion::Jak2, "cas-toxic-slime-scroll-dest");
|
||||
const float max_times[4] = {600.f, 300.f, 150.f, 75.f};
|
||||
const float scales[4] = {0.55, 0.6, 0.3, 0.1f};
|
||||
for (int i = 0, dim = kFinalSlimeTextureSize >> (kNumSlimeNoiseLayers - 1);
|
||||
i < kNumSlimeNoiseLayers; i++, dim *= 2) {
|
||||
auto& tex = m_slime_noise_textures[i];
|
||||
tex.temp_data.resize(dim * dim);
|
||||
tex.max_time = max_times[i];
|
||||
tex.scale = scales[i];
|
||||
tex.dim = dim;
|
||||
glGenTextures(1, &tex.new_tex);
|
||||
m_random_index = update_opengl_noise_texture(tex.new_tex, tex.temp_data.data(),
|
||||
m_random_table, dim, m_random_index);
|
||||
glGenTextures(1, &tex.old_tex);
|
||||
m_random_index = update_opengl_noise_texture(tex.old_tex, tex.temp_data.data(),
|
||||
m_random_table, dim, m_random_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLint TextureAnimator::run_clouds(const SkyInput& input, bool hires) {
|
||||
|
||||
@@ -246,7 +246,7 @@ class TexturePool;
|
||||
|
||||
class TextureAnimator {
|
||||
public:
|
||||
TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* common_level);
|
||||
TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* common_level, GameVersion version);
|
||||
~TextureAnimator();
|
||||
void handle_texture_anim_data(DmaFollower& dma,
|
||||
const u8* ee_mem,
|
||||
@@ -259,7 +259,10 @@ class TextureAnimator {
|
||||
|
||||
private:
|
||||
void copy_private_to_public();
|
||||
void setup_texture_anims();
|
||||
void setup_texture_anims_common();
|
||||
void setup_texture_anims_jak2();
|
||||
void setup_texture_anims_jak3();
|
||||
|
||||
void setup_sky();
|
||||
void handle_upload_clut_16_16(const DmaTransfer& tf, const u8* ee_mem);
|
||||
void handle_generic_upload(const DmaTransfer& tf, const u8* ee_mem);
|
||||
@@ -429,6 +432,7 @@ class TextureAnimator {
|
||||
static constexpr int kNumSlimeNoiseLayers = 4;
|
||||
|
||||
private:
|
||||
GameVersion m_version;
|
||||
Vector16ub m_random_table[kRandomTableSize];
|
||||
int m_random_index = 0;
|
||||
|
||||
@@ -451,3 +455,10 @@ class TextureAnimator {
|
||||
int m_slime_output_slot = -1;
|
||||
int m_slime_scroll_output_slot = -1;
|
||||
};
|
||||
|
||||
int output_slot_by_idx(GameVersion version, const std::string& name);
|
||||
int update_opengl_noise_texture(GLuint texture,
|
||||
u8* temp,
|
||||
Vector16ub* random_table,
|
||||
int dim,
|
||||
int random_index_in);
|
||||
@@ -0,0 +1,494 @@
|
||||
#include "game/graphics/opengl_renderer/TextureAnimator.h"
|
||||
|
||||
void TextureAnimator::setup_texture_anims_jak3() {
|
||||
m_darkjak_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakc-arm", "jakc-eyebrow", "jakc-face", "jakc-finger", "jakc-hair"}, "-norm", "-dark", {});
|
||||
}
|
||||
|
||||
void TextureAnimator::setup_texture_anims_common() {
|
||||
// Skull Gem
|
||||
{
|
||||
FixedAnimDef skull_gem;
|
||||
skull_gem.move_to_pool = true;
|
||||
skull_gem.tex_name = "skull-gem-dest";
|
||||
skull_gem.color = math::Vector4<u8>{0, 0, 0, 0x80};
|
||||
// overriden in texture-finish.gc
|
||||
skull_gem.override_size = math::Vector2<int>(32, 32);
|
||||
|
||||
auto& skull_gem_0 = skull_gem.layers.emplace_back();
|
||||
skull_gem_0.end_time = 300.;
|
||||
skull_gem_0.tex_name = "skull-gem-alpha-00";
|
||||
skull_gem_0.set_blend_b2_d1();
|
||||
skull_gem_0.set_no_z_write_no_z_test();
|
||||
|
||||
auto& skull_gem_1 = skull_gem.layers.emplace_back();
|
||||
skull_gem_1.end_time = 300.;
|
||||
skull_gem_1.tex_name = "skull-gem-alpha-01";
|
||||
skull_gem_1.set_blend_b2_d1();
|
||||
skull_gem_1.set_no_z_write_no_z_test();
|
||||
|
||||
auto& skull_gem_2 = skull_gem.layers.emplace_back();
|
||||
skull_gem_2.end_time = 300.;
|
||||
skull_gem_2.tex_name = "skull-gem-alpha-02";
|
||||
skull_gem_2.set_blend_b2_d1();
|
||||
skull_gem_2.set_no_z_write_no_z_test();
|
||||
|
||||
m_skull_gem_fixed_anim_array_idx = create_fixed_anim_array({skull_gem});
|
||||
}
|
||||
}
|
||||
|
||||
void TextureAnimator::setup_texture_anims_jak2() {
|
||||
// DARKJAK
|
||||
m_darkjak_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakbsmall-eyebrow", "jakbsmall-face", "jakbsmall-finger", "jakbsmall-hair"}, "-norm",
|
||||
"-dark", {});
|
||||
|
||||
// PRISON
|
||||
// MISSING EYELID
|
||||
m_jakb_prison_clut_blender_idx = create_clut_blender_group(
|
||||
{"jak-orig-arm-formorph", "jak-orig-eyebrow-formorph", "jak-orig-finger-formorph"}, "-start",
|
||||
"-end", "LDJAKBRN.DGO");
|
||||
add_to_clut_blender_group(m_jakb_prison_clut_blender_idx,
|
||||
{"jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm", "-dark",
|
||||
"LDJAKBRN.DGO");
|
||||
|
||||
// ORACLE
|
||||
// MISSING FINGER
|
||||
m_jakb_oracle_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm",
|
||||
"-dark", "ORACLE.DGO");
|
||||
|
||||
// NEST
|
||||
// MISSING FINGER
|
||||
m_jakb_nest_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm",
|
||||
"-dark", "NEB.DGO");
|
||||
|
||||
// KOR (doesn't work??)
|
||||
m_kor_transform_clut_blender_idx = create_clut_blender_group(
|
||||
{
|
||||
// "kor-eyeeffect-formorph",
|
||||
// "kor-hair-formorph",
|
||||
// "kor-head-formorph",
|
||||
// "kor-head-formorph-noreflect",
|
||||
// "kor-lowercaps-formorph",
|
||||
// "kor-uppercaps-formorph",
|
||||
},
|
||||
"-start", "-end", {});
|
||||
|
||||
// Bomb
|
||||
{
|
||||
FixedAnimDef bomb;
|
||||
bomb.tex_name = "bomb-gradient";
|
||||
bomb.color = math::Vector4<u8>{0, 0, 0, 0x80};
|
||||
|
||||
auto& bomb_0 = bomb.layers.emplace_back();
|
||||
bomb_0.end_time = 300.;
|
||||
bomb_0.tex_name = "bomb-gradient-rim";
|
||||
bomb_0.set_blend_b2_d1();
|
||||
bomb_0.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
bomb_0.channel_masks[3] = false; // no alpha writes.
|
||||
|
||||
auto& bomb_1 = bomb.layers.emplace_back();
|
||||
bomb_1.end_time = 300.;
|
||||
bomb_1.tex_name = "bomb-gradient-flames";
|
||||
bomb_1.set_blend_b2_d1();
|
||||
bomb_1.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
bomb_1.channel_masks[3] = false; // no alpha writes.
|
||||
|
||||
m_bomb_fixed_anim_array_idx = create_fixed_anim_array({bomb});
|
||||
}
|
||||
|
||||
// CAS conveyor
|
||||
{
|
||||
FixedAnimDef conveyor_0;
|
||||
conveyor_0.tex_name = "cas-conveyor-dest";
|
||||
conveyor_0.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_0.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c0 = conveyor_0.layers.emplace_back();
|
||||
c0.set_blend_b2_d1();
|
||||
c0.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c0.channel_masks[3] = false; // no alpha writes.
|
||||
c0.end_time = 300.;
|
||||
c0.tex_name = "cas-conveyor";
|
||||
|
||||
FixedAnimDef conveyor_1;
|
||||
conveyor_1.tex_name = "cas-conveyor-dest-01";
|
||||
conveyor_1.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_1.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c1 = conveyor_1.layers.emplace_back();
|
||||
c1.set_blend_b2_d1();
|
||||
c1.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c1.channel_masks[3] = false; // no alpha writes.
|
||||
c1.end_time = 300.;
|
||||
c1.tex_name = "cas-conveyor";
|
||||
|
||||
FixedAnimDef conveyor_2;
|
||||
conveyor_2.tex_name = "cas-conveyor-dest-02";
|
||||
conveyor_2.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_2.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c2 = conveyor_2.layers.emplace_back();
|
||||
c2.set_blend_b2_d1();
|
||||
c2.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c2.channel_masks[3] = false; // no alpha writes.
|
||||
c2.end_time = 300.;
|
||||
c2.tex_name = "cas-conveyor";
|
||||
|
||||
FixedAnimDef conveyor_3;
|
||||
conveyor_3.tex_name = "cas-conveyor-dest-03";
|
||||
conveyor_3.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
conveyor_3.override_size = math::Vector2<int>(64, 32);
|
||||
auto& c3 = conveyor_3.layers.emplace_back();
|
||||
c3.set_blend_b2_d1();
|
||||
c3.set_no_z_write_no_z_test();
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
c3.channel_masks[3] = false; // no alpha writes.
|
||||
c3.end_time = 300.;
|
||||
c3.tex_name = "cas-conveyor";
|
||||
|
||||
m_cas_conveyor_anim_array_idx =
|
||||
create_fixed_anim_array({conveyor_0, conveyor_1, conveyor_2, conveyor_3});
|
||||
}
|
||||
|
||||
// SECURITY
|
||||
{
|
||||
FixedAnimDef env;
|
||||
env.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
env.tex_name = "security-env-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& env1 = env.layers.emplace_back();
|
||||
env1.tex_name = "security-env-uscroll";
|
||||
// :test (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always))
|
||||
env1.set_no_z_write_no_z_test();
|
||||
env1.channel_masks[3] = false; // no alpha writes.
|
||||
// :alpha (new 'static 'gs-alpha :b #x2 :d #x1)
|
||||
env1.set_blend_b2_d1();
|
||||
env1.end_time = 4800.f;
|
||||
}
|
||||
|
||||
FixedAnimDef dot;
|
||||
dot.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
dot.tex_name = "security-dot-dest";
|
||||
|
||||
auto& cwhite = dot.layers.emplace_back();
|
||||
cwhite.set_blend_b2_d1();
|
||||
cwhite.set_no_z_write_no_z_test();
|
||||
cwhite.tex_name = "common-white";
|
||||
cwhite.end_time = 4800.f;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& dsrc = dot.layers.emplace_back();
|
||||
dsrc.set_blend_b2_d1();
|
||||
dsrc.set_no_z_write_no_z_test();
|
||||
dsrc.end_time = 600.f;
|
||||
dsrc.tex_name = "security-dot-src";
|
||||
}
|
||||
|
||||
m_security_anim_array_idx = create_fixed_anim_array({env, dot});
|
||||
}
|
||||
|
||||
// WATERFALL
|
||||
{
|
||||
FixedAnimDef waterfall;
|
||||
waterfall.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
waterfall.tex_name = "waterfall-dest";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& src = waterfall.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 450.f;
|
||||
src.tex_name = "waterfall";
|
||||
}
|
||||
m_waterfall_anim_array_idx = create_fixed_anim_array({waterfall});
|
||||
}
|
||||
|
||||
{
|
||||
FixedAnimDef waterfall;
|
||||
waterfall.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
waterfall.tex_name = "waterfall-dest";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto& src = waterfall.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 450.f;
|
||||
src.tex_name = "waterfall";
|
||||
}
|
||||
m_waterfall_b_anim_array_idx = create_fixed_anim_array({waterfall});
|
||||
}
|
||||
|
||||
// LAVA
|
||||
{
|
||||
FixedAnimDef lava;
|
||||
lava.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
lava.tex_name = "dig-lava-01-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& src = lava.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 3600.f;
|
||||
src.tex_name = "dig-lava-01";
|
||||
}
|
||||
m_lava_anim_array_idx = create_fixed_anim_array({lava});
|
||||
}
|
||||
|
||||
{
|
||||
FixedAnimDef lava;
|
||||
lava.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
lava.tex_name = "dig-lava-01-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& src = lava.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 3600.f;
|
||||
src.tex_name = "dig-lava-01";
|
||||
}
|
||||
m_lava_b_anim_array_idx = create_fixed_anim_array({lava});
|
||||
}
|
||||
|
||||
// Stadiumb
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "stdmb-energy-wall-01-dest";
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b1_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 300.f;
|
||||
src.tex_name = "stdmb-energy-wall-01";
|
||||
}
|
||||
m_stadiumb_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// Fortress pris
|
||||
{
|
||||
FixedAnimDef l_tread;
|
||||
l_tread.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
l_tread.tex_name = "robotank-tread-l-dest";
|
||||
auto& l_src = l_tread.layers.emplace_back();
|
||||
l_src.set_blend_b1_d1();
|
||||
l_src.set_no_z_write_no_z_test();
|
||||
l_src.channel_masks[3] = false; // no alpha writes.
|
||||
l_src.end_time = 1.f;
|
||||
l_src.tex_name = "robotank-tread";
|
||||
|
||||
FixedAnimDef r_tread;
|
||||
r_tread.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
r_tread.tex_name = "robotank-tread-r-dest";
|
||||
auto& r_src = r_tread.layers.emplace_back();
|
||||
r_src.set_blend_b1_d1();
|
||||
r_src.set_no_z_write_no_z_test();
|
||||
r_src.channel_masks[3] = false; // no alpha writes.
|
||||
r_src.end_time = 1.f;
|
||||
r_src.tex_name = "robotank-tread";
|
||||
|
||||
m_fortress_pris_anim_array_idx = create_fixed_anim_array({l_tread, r_tread});
|
||||
}
|
||||
|
||||
// Fortress Warp
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.move_to_pool = true;
|
||||
def.tex_name = "fort-roboscreen-dest";
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.end_time = 300.f;
|
||||
src.tex_name = "fort-roboscreen-env";
|
||||
m_fortress_warp_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// metkor
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "squid-env-rim-dest";
|
||||
def.move_to_pool = true;
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-noise";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-scan";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "environment-phong-rim";
|
||||
}
|
||||
m_metkor_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// shield
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "squid-env-rim-dest";
|
||||
def.move_to_pool = true;
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "common-white";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-uscroll";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-uscroll";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-rim-src";
|
||||
}
|
||||
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "squid-env-rim-src";
|
||||
}
|
||||
m_shield_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
// krew
|
||||
{
|
||||
FixedAnimDef def;
|
||||
def.color = math::Vector4<u8>(0, 0, 0, 0x80);
|
||||
def.tex_name = "krew-holo-dest";
|
||||
def.move_to_pool = true;
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-noise";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-scan";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-head-env-rim";
|
||||
}
|
||||
{
|
||||
auto& src = def.layers.emplace_back();
|
||||
src.set_blend_b2_d1();
|
||||
src.channel_masks[3] = false; // no alpha writes.
|
||||
src.set_no_z_write_no_z_test();
|
||||
src.set_clamp();
|
||||
src.end_time = 1200.f;
|
||||
src.tex_name = "metkor-phong-env";
|
||||
}
|
||||
m_krew_holo_anim_array_idx = create_fixed_anim_array({def});
|
||||
}
|
||||
|
||||
{
|
||||
m_slime_output_slot = output_slot_by_idx(m_version, "cas-toxic-slime-dest");
|
||||
m_slime_scroll_output_slot = output_slot_by_idx(m_version, "cas-toxic-slime-scroll-dest");
|
||||
const float max_times[4] = {600.f, 300.f, 150.f, 75.f};
|
||||
const float scales[4] = {0.55, 0.6, 0.3, 0.1f};
|
||||
for (int i = 0, dim = kFinalSlimeTextureSize >> (kNumSlimeNoiseLayers - 1);
|
||||
i < kNumSlimeNoiseLayers; i++, dim *= 2) {
|
||||
auto& tex = m_slime_noise_textures[i];
|
||||
tex.temp_data.resize(dim * dim);
|
||||
tex.max_time = max_times[i];
|
||||
tex.scale = scales[i];
|
||||
tex.dim = dim;
|
||||
glGenTextures(1, &tex.new_tex);
|
||||
m_random_index = update_opengl_noise_texture(tex.new_tex, tex.temp_data.data(),
|
||||
m_random_table, dim, m_random_index);
|
||||
glGenTextures(1, &tex.old_tex);
|
||||
m_random_index = update_opengl_noise_texture(tex.old_tex, tex.temp_data.data(),
|
||||
m_random_table, dim, m_random_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -349,7 +349,9 @@ void Hfrag::render_hfrag_level(Hfrag::HfragLevel* lev,
|
||||
b = false;
|
||||
}
|
||||
lev->stats = {};
|
||||
for (u32 bucket_idx = 0; bucket_idx < lev->hfrag->buckets.size(); bucket_idx++) {
|
||||
|
||||
// bucket 0 is not drawn, although there is data there.
|
||||
for (u32 bucket_idx = 1; bucket_idx < lev->hfrag->buckets.size(); bucket_idx++) {
|
||||
const auto& bucket = lev->hfrag->buckets[bucket_idx];
|
||||
for (u32 corner_idx : bucket.corners) {
|
||||
const auto& corner = lev->hfrag->corners[corner_idx];
|
||||
|
||||
@@ -551,8 +551,8 @@ void Shadow2::draw_buffers(SharedRenderState* render_state,
|
||||
|
||||
if (have_darken) {
|
||||
glColorMask(darken_channel[0], darken_channel[1], darken_channel[2], false);
|
||||
glUniform4f(m_ogl.uniforms.color, (128 - m_color[0]) / 256.f, (128 - m_color[1]) / 256.f,
|
||||
(128 - m_color[2]) / 256.f, 0);
|
||||
glUniform4f(m_ogl.uniforms.color, (m_color[3] - m_color[0]) / 256.f,
|
||||
(m_color[3] - m_color[1]) / 256.f, (m_color[3] - m_color[2]) / 256.f, 0);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT,
|
||||
(void*)(sizeof(u32) * (m_front_index_buffer_used - 6)));
|
||||
@@ -560,8 +560,8 @@ void Shadow2::draw_buffers(SharedRenderState* render_state,
|
||||
|
||||
if (have_lighten) {
|
||||
glColorMask(lighten_channel[0], lighten_channel[1], lighten_channel[2], false);
|
||||
glUniform4f(m_ogl.uniforms.color, (m_color[0] - 128) / 256.f, (m_color[1] - 128) / 256.f,
|
||||
(m_color[2] - 128) / 256.f, 0);
|
||||
glUniform4f(m_ogl.uniforms.color, (m_color[0] - m_color[3]) / 256.f,
|
||||
(m_color[1] - m_color[3]) / 256.f, (m_color[2] - m_color[3]) / 256.f, 0);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT,
|
||||
(void*)(sizeof(u32) * (m_front_index_buffer_used - 6)));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -377,6 +377,22 @@ namespace method_34_sky_work { extern void link(); }
|
||||
namespace method_35_sky_work { extern void link(); }
|
||||
namespace method_32_sky_work { extern void link(); }
|
||||
namespace set_sky_vf23_value { extern void link(); }
|
||||
namespace shadow_xform_verts { extern void link(); }
|
||||
namespace shadow_calc_dual_verts { extern void link(); }
|
||||
namespace shadow_scissor_edges { extern void link(); }
|
||||
namespace shadow_scissor_top { extern void link(); }
|
||||
namespace shadow_init_vars { extern void link(); }
|
||||
namespace shadow_find_facing_single_tris { extern void link(); }
|
||||
namespace shadow_find_facing_double_tris { extern void link(); }
|
||||
namespace shadow_find_single_edges { extern void link(); }
|
||||
namespace shadow_find_double_edges { extern void link(); }
|
||||
namespace shadow_add_verts { extern void link(); }
|
||||
namespace shadow_add_facing_single_tris { extern void link(); }
|
||||
namespace shadow_add_single_edges { extern void link(); }
|
||||
namespace shadow_add_double_edges { extern void link(); }
|
||||
namespace shadow_add_single_tris { extern void link(); }
|
||||
namespace shadow_add_double_tris { extern void link(); }
|
||||
namespace shadow_execute { extern void link(); }
|
||||
|
||||
}
|
||||
// clang-format on
|
||||
@@ -629,7 +645,16 @@ PerGameVersion<std::unordered_map<std::string, std::vector<void (*)()>>> gMips2C
|
||||
jak3::method_29_sky_work::link, jak3::method_30_sky_work::link,
|
||||
jak3::method_31_sky_work::link, jak3::method_34_sky_work::link,
|
||||
jak3::method_35_sky_work::link, jak3::method_32_sky_work::link,
|
||||
jak3::set_sky_vf23_value::link, jak3::draw_large_polygon::link}}}};
|
||||
jak3::set_sky_vf23_value::link, jak3::draw_large_polygon::link}},
|
||||
{"shadow-cpu",
|
||||
{jak3::shadow_xform_verts::link, jak3::shadow_execute::link,
|
||||
jak3::shadow_calc_dual_verts::link, jak3::shadow_scissor_edges::link,
|
||||
jak3::shadow_scissor_top::link, jak3::shadow_init_vars::link,
|
||||
jak3::shadow_find_facing_single_tris::link, jak3::shadow_find_facing_double_tris::link,
|
||||
jak3::shadow_find_single_edges::link, jak3::shadow_find_double_edges::link,
|
||||
jak3::shadow_add_verts::link, jak3::shadow_add_facing_single_tris::link,
|
||||
jak3::shadow_add_single_edges::link, jak3::shadow_add_double_edges::link,
|
||||
jak3::shadow_add_single_tris::link, jak3::shadow_add_double_tris::link}}}};
|
||||
|
||||
void LinkedFunctionTable::reg(const std::string& name, u64 (*exec)(void*), u32 stack_size) {
|
||||
const auto& it = m_executes.insert({name, {exec, Ptr<u8>()}});
|
||||
|
||||
+26
-5
@@ -153,10 +153,21 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defun custom-level-cgo (output-name desc-file-name)
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_levels/jak1/)"
|
||||
(defun custom-actor-cgo (output-name desc-file-name)
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_assets/jak1/models/)"
|
||||
(let ((out-name (string-append "$OUT/iso/" output-name)))
|
||||
(defstep :in (string-append "custom_levels/jak1/" desc-file-name)
|
||||
(defstep :in (string-append "custom_assets/jak1/models/" desc-file-name)
|
||||
:tool 'dgo
|
||||
:out `(,out-name)
|
||||
)
|
||||
(set! *all-cgos* (cons out-name *all-cgos*))
|
||||
)
|
||||
)
|
||||
|
||||
(defun custom-level-cgo (output-name desc-file-name)
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_assets/jak1/levels/)"
|
||||
(let ((out-name (string-append "$OUT/iso/" output-name)))
|
||||
(defstep :in (string-append "custom_assets/jak1/levels/" desc-file-name)
|
||||
:tool 'dgo
|
||||
:out `(,out-name)
|
||||
)
|
||||
@@ -208,11 +219,16 @@
|
||||
)
|
||||
|
||||
(defmacro build-custom-level (name)
|
||||
(let* ((path (string-append "custom_levels/jak1/" name "/" name ".jsonc")))
|
||||
(let* ((path (string-append "custom_assets/jak1/levels/" name "/" name ".jsonc")))
|
||||
`(defstep :in ,path
|
||||
:tool 'build-level
|
||||
:out '(,(string-append "$OUT/obj/" name ".go")))))
|
||||
|
||||
(defmacro build-actor (name)
|
||||
(let* ((path (string-append "custom_assets/jak1/models/" name ".glb")))
|
||||
`(defstep :in ,path
|
||||
:tool 'build-actor
|
||||
:out '(,(string-append "$OUT/obj/" name "-ag.go")))))
|
||||
|
||||
(defun copy-iso-file (name subdir ext)
|
||||
(let* ((path (string-append "$ISO/" subdir name ext))
|
||||
@@ -1636,12 +1652,16 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Set up the build system to build the level geometry
|
||||
;; this path is relative to the custom_levels/jak1 folder
|
||||
;; this path is relative to the custom_assets/jak1/levels/ folder
|
||||
;; it should point to the .jsonc file that specifies the level.
|
||||
(build-custom-level "test-zone")
|
||||
;; the DGO file
|
||||
(custom-level-cgo "TSZ.DGO" "test-zone/testzone.gd")
|
||||
|
||||
;; generate the art group for a custom actor.
|
||||
;; requires a .glb model file in custom_assets/jak1/models
|
||||
(build-actor "test-actor")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Game Engine Code
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -2080,6 +2100,7 @@
|
||||
(goal-src "pc/debug/default-menu-pc.gc" "anim-tester-x" "part-tester" "entity-debug")
|
||||
(goal-src "pc/debug/pc-debug-common.gc" "pckernel-impl" "entity-h" "game-info-h" "level-h" "settings-h" "gsound-h" "target-util")
|
||||
(goal-src "pc/debug/pc-debug-methods.gc" "pc-debug-common")
|
||||
(goal-src "levels/test-zone/test-zone-obs.gc" "process-drawable")
|
||||
|
||||
(group-list "all-code"
|
||||
`(,@(reverse *all-gc*))
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
(deftype test-actor (process-drawable)
|
||||
((root collide-shape-moving :override)
|
||||
(birth-time time-frame)
|
||||
(base vector :inline)
|
||||
(old-base vector :inline)
|
||||
(bob-offset int64)
|
||||
(bob-amount float)
|
||||
)
|
||||
(:methods (init-collision! (_type_) none))
|
||||
(:state-methods idle)
|
||||
)
|
||||
|
||||
(def-art-elt test-actor-ag test-actor-lod0-jg 0)
|
||||
(def-art-elt test-actor-ag test-actor-lod0-mg 1)
|
||||
(def-art-elt test-actor-ag test-actor-idle-ja 2)
|
||||
|
||||
(defskelgroup *test-actor-sg* test-actor test-actor-lod0-jg test-actor-idle-ja
|
||||
((test-actor-lod0-mg (meters 9999999)))
|
||||
:bounds (static-spherem 0 0 0 4.5)
|
||||
:texture-level 2
|
||||
)
|
||||
|
||||
(defmethod init-collision! ((this test-actor))
|
||||
(let ((cshape (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
|
||||
(set! (-> cshape dynam) (copy *standard-dynamics* 'process))
|
||||
(set! (-> cshape reaction) default-collision-reaction)
|
||||
(set! (-> cshape no-reaction)
|
||||
(the (function collide-shape-moving collide-shape-intersect vector vector none) nothing)
|
||||
)
|
||||
;; (let ((mesh (new 'process 'collide-shape-prim-mesh cshape (the uint 0) (the uint 0))))
|
||||
;; (set! (-> mesh prim-core collide-as) (collide-kind enemy))
|
||||
;; (set! (-> mesh collide-with) (collide-kind target))
|
||||
;; (set! (-> mesh transform-index) 6)
|
||||
;; (set-vector! (-> mesh local-sphere) 0.0 0.0 0.0 (meters 4.5))
|
||||
;; (set-root-prim! cshape mesh)
|
||||
;; )
|
||||
(let ((sphere (new 'process 'collide-shape-prim-sphere cshape (the uint 0))))
|
||||
(set! (-> sphere prim-core collide-as) (collide-kind enemy))
|
||||
(set! (-> sphere collide-with) (collide-kind target))
|
||||
(set! (-> sphere prim-core action) (collide-action solid))
|
||||
(set! (-> sphere prim-core offense) (collide-offense normal-attack))
|
||||
(set-vector! (-> sphere local-sphere) 0.0 0.0 0.0 (meters 2))
|
||||
(set-root-prim! cshape sphere)
|
||||
)
|
||||
(set! (-> cshape nav-radius) (* 0.75 (-> cshape root-prim local-sphere w)))
|
||||
(backup-collide-with-as cshape)
|
||||
(set! (-> this root) cshape)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmethod init-from-entity! ((this test-actor) (e entity-actor))
|
||||
(logior! (-> this mask) (process-mask enemy))
|
||||
(init-collision! this)
|
||||
(process-drawable-from-entity! this e)
|
||||
(set! (-> this bob-amount) 1024.0)
|
||||
(set! (-> this bob-offset) (+ (the int (-> this root trans x)) (the int (-> this root trans y)) (the int (-> this root trans z))))
|
||||
(set-time! (-> this birth-time))
|
||||
(vector-copy! (-> this base) (-> this root trans))
|
||||
(vector-copy! (-> this old-base) (-> this root trans))
|
||||
(initialize-skeleton this *test-actor-sg* '())
|
||||
(logclear! (-> this mask) (process-mask actor-pause))
|
||||
(transform-post)
|
||||
(go-virtual idle :proc this)
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
(defbehavior test-actor-init-by-other test-actor ((pos vector))
|
||||
(logior! (-> self mask) (process-mask enemy))
|
||||
(init-collision! self)
|
||||
(initialize-skeleton self *test-actor-sg* '())
|
||||
(vector-copy! (-> self root trans) pos)
|
||||
(quaternion-identity! (-> self root quat))
|
||||
(vector-identity! (-> self root scale))
|
||||
(set! (-> self bob-amount) 1024.0)
|
||||
(set! (-> self bob-offset) (+ (the int (-> self root trans x)) (the int (-> self root trans y)) (the int (-> self root trans z))))
|
||||
(set-time! (-> self birth-time))
|
||||
(vector-copy! (-> self base) (-> self root trans))
|
||||
(vector-copy! (-> self old-base) (-> self root trans))
|
||||
(logclear! (-> self mask) (process-mask actor-pause))
|
||||
(transform-post)
|
||||
(go-virtual idle)
|
||||
)
|
||||
|
||||
(defstate idle (test-actor)
|
||||
:virtual #t
|
||||
:event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
|
||||
(case message
|
||||
(('attack 'touch)
|
||||
(if (= (-> proc type) target)
|
||||
(send-event proc 'attack #f (static-attack-info ((shove-up (meters 2.5)) (shove-back (meters 7.5)))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
:code (behavior ()
|
||||
(loop
|
||||
(quaternion-rotate-y! (-> self root quat) (-> self root quat) (* (degrees 45) (seconds-per-frame)))
|
||||
(let ((bob (-> self bob-amount)))
|
||||
(when (< 0.0 bob)
|
||||
(set! (-> self root trans y)
|
||||
(+ (-> self base y)
|
||||
(* bob (sin (* 109.22667 (the float (mod (+ (- (current-time) (-> self birth-time)) (-> self bob-offset)) (seconds 2))))))
|
||||
)
|
||||
)
|
||||
(update-transforms! (-> self root))
|
||||
)
|
||||
)
|
||||
; (dotimes (i (-> self node-list length))
|
||||
; (let* ((joint (-> self node-list data i)) (jpos (vector<-cspace! (new-stack-vector0) joint)))
|
||||
; (add-debug-sphere #t (bucket-id debug) jpos (meters 0.1) (static-rgba 0 #xff 0 #x40))
|
||||
; (add-debug-text-sphere (!= (-> joint joint) #f) (bucket-id debug) jpos (meters 0.1) (-> joint joint name) (static-rgba 0 #xff 0 #x40))
|
||||
; )
|
||||
; )
|
||||
(suspend)
|
||||
)
|
||||
)
|
||||
:post transform-post
|
||||
)
|
||||
@@ -296,7 +296,7 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Set up the build system to build the level geometry
|
||||
;; this path is relative to the custom_levels/jak2 folder
|
||||
;; this path is relative to the custom_assets/jak2/levels folder
|
||||
;; it should point to the .jsonc file that specifies the level.
|
||||
(build-custom-level "test-zone")
|
||||
;; the DGO file
|
||||
|
||||
@@ -405,7 +405,7 @@
|
||||
(let ((s5-3 (-> this draw shadow-ctrl)))
|
||||
(when (!= *nav-enemy-dummy-shadow-control* s5-3)
|
||||
(let ((f0-7 (vector-vector-distance (camera-pos) (-> this root trans))))
|
||||
(#when PC_PORT
|
||||
(#when PC_PORT ;; og:preserve-this shadow cull toggle
|
||||
(if (not (-> *pc-settings* ps2-shadow?))
|
||||
(set! f0-7 0.0)))
|
||||
(cond
|
||||
|
||||
@@ -706,7 +706,7 @@
|
||||
(let ((s5-0 (-> this draw shadow-ctrl)))
|
||||
(when (!= *vehicle-shadow-control-disabled* s5-0)
|
||||
(let ((f30-0 (vector-vector-xz-distance (camera-pos) (-> this root trans))))
|
||||
;; og:preserve-this Shadow fix of some sort
|
||||
;; og:preserve-this shadow cull toggle
|
||||
(#when PC_PORT
|
||||
(if (not (-> *pc-settings* ps2-shadow?))
|
||||
(set! f30-0 0.0)))
|
||||
|
||||
@@ -84,9 +84,9 @@
|
||||
)
|
||||
|
||||
(defun custom-level-cgo (output-name desc-file-name)
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_levels/jak2/)"
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_assets/jak2/levels/)"
|
||||
(let ((out-name (string-append "$OUT/iso/" output-name)))
|
||||
(defstep :in (string-append "custom_levels/jak2/" desc-file-name)
|
||||
(defstep :in (string-append "custom_assets/jak2/levels/" desc-file-name)
|
||||
:tool 'dgo
|
||||
:out `(,out-name)
|
||||
)
|
||||
@@ -136,7 +136,7 @@
|
||||
)
|
||||
|
||||
(defmacro build-custom-level (name)
|
||||
(let* ((path (string-append "custom_levels/jak2/" name "/" name ".jsonc")))
|
||||
(let* ((path (string-append "custom_assets/jak2/levels/" name "/" name ".jsonc")))
|
||||
`(defstep :in ,path
|
||||
:tool 'build-level2
|
||||
:out '(,(string-append "$OUT/obj/" name ".go")))))
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
(set! (-> obj flava-unlocked i) #f))
|
||||
|
||||
(set! (-> obj stats) *statistics*)
|
||||
(initialize (-> obj stats kill-stats))
|
||||
0)
|
||||
|
||||
(defmethod reset-input ((obj pc-settings-jak2) (device symbol) (call-handlers symbol))
|
||||
|
||||
@@ -4058,7 +4058,7 @@
|
||||
:virtual #t
|
||||
:trans (behavior ()
|
||||
(set! (-> self task-counter) (-> *game-info* task-counter))
|
||||
(if (and *bigmap* (nonzero? *bigmap*))
|
||||
(if *bigmap*
|
||||
(bigmap-method-16 *bigmap*)
|
||||
)
|
||||
(let ((gp-0 (res-lump-struct (-> self entity) 'on-running structure)))
|
||||
|
||||
@@ -1455,7 +1455,7 @@
|
||||
(bones-init gp-0)
|
||||
(bones-mtx-calc-execute)
|
||||
(generic-merc-execute-all gp-0)
|
||||
;; (shadow-execute-all gp-0)
|
||||
(shadow-execute-all gp-0)
|
||||
)
|
||||
(lightning-draw-all)
|
||||
;(prim-engine-execute)
|
||||
@@ -1960,7 +1960,7 @@
|
||||
(true! draw?)
|
||||
)
|
||||
(when draw?
|
||||
(set! *debug-region-color-alt* (= tree-name 'camera))
|
||||
(set! *debug-region-tree-name* tree-name)
|
||||
(debug-draw-region region 0)))
|
||||
(set! i (+ i 1))
|
||||
(set! region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i))
|
||||
@@ -1976,6 +1976,7 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! *debug-region-tree-name* #f)
|
||||
)
|
||||
(if *debug-track-skill*
|
||||
(debug-track-skill))
|
||||
|
||||
@@ -1577,6 +1577,11 @@
|
||||
(s1-4 (-> s4-8 bsp region-trees s2-4))
|
||||
)
|
||||
(while (< s2-4 s3-6)
|
||||
;; og:preserve-this pc port note: added this name and water check
|
||||
(let ((tree-name (-> s1-4 name)))
|
||||
(when (or (!= tree-name 'water) (not *debug-region-hide-water*))
|
||||
(set! *debug-region-tree-name* tree-name)
|
||||
|
||||
(let ((s0-4 (-> s1-4 data2 (+ (-> s1-4 length) -1) length)))
|
||||
(set! sv-128 0)
|
||||
(let ((a0-128 (the-as object (+ (+ (* sv-128 32) 32) (the-as int (-> s1-4 data2 (+ (-> s1-4 length) -1)))))))
|
||||
@@ -1587,6 +1592,7 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
(+! s2-4 1)
|
||||
(set! s1-4 (-> s4-8 bsp region-trees s2-4))
|
||||
)
|
||||
|
||||
@@ -587,7 +587,7 @@
|
||||
(dotimes (v1-96 (-> this game-score length))
|
||||
(set! (-> this game-score v1-96) 0.0)
|
||||
)
|
||||
(when (nonzero? *bigmap*) ;; og:preserve-this not-yet-implemented check
|
||||
(when *bigmap* ;; og:preserve-this not-yet-implemented check
|
||||
(format 0 "skipping bigmap init in game-info~%")
|
||||
((method-of-object *bigmap* bigmap-method-9))
|
||||
)
|
||||
|
||||
@@ -852,6 +852,9 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(#when PC_PORT ;; og:preserve-this
|
||||
(if (not (-> *pc-settings* ps2-shadow?))
|
||||
(set! t0-0 0.0)))
|
||||
(let ((t1-5 (-> a3-3 flags)))
|
||||
(-> arg0 cur-lod)
|
||||
(when (not (logtest? t1-5 (shadow-flags disable-fade)))
|
||||
|
||||
@@ -5,10 +5,832 @@
|
||||
;; name in dgo: shadow-cpu
|
||||
;; dgos: GAME
|
||||
|
||||
(define-extern shadow-vu1-patch-consts (function symbol int none))
|
||||
(define-extern shadow-vu1-init-buffer (function dma-buffer int none))
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
;; stub
|
||||
(format 0 "shadow-cpu: stubbed shadow-control::14~%")
|
||||
(defmethod shadow-control-method-14 ((this shadow-control) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float) (arg4 float))
|
||||
;; WARN: Return type mismatch uint vs int.
|
||||
(defmethod asize-of ((this shadow-geo))
|
||||
(the-as int (* (-> this total-qwc) 16))
|
||||
)
|
||||
|
||||
(defmethod mem-usage ((this shadow-geo) (usage memory-usage-block) (flags int))
|
||||
(set! (-> usage length) (max 112 (-> usage length)))
|
||||
(set! (-> usage data 111 name) "shadow-geo")
|
||||
(+! (-> usage data 111 count) 1)
|
||||
(let ((v1-6 (* (-> this total-qwc) 16)))
|
||||
(+! (-> usage data 111 used) v1-6)
|
||||
(+! (-> usage data 111 total) (logand -16 (+ v1-6 15)))
|
||||
)
|
||||
this
|
||||
)
|
||||
|
||||
(define *shadow-data* (new 'static 'shadow-data
|
||||
:dma-unpack-template (new 'static 'dma-packet
|
||||
:dma (new 'static 'dma-tag :id (dma-tag-id cnt))
|
||||
:vif0 (new 'static 'vif-tag :cmd (vif-cmd flush) :msk #x1)
|
||||
:vif1 (new 'static 'vif-tag :cmd (vif-cmd unpack-v4-32))
|
||||
)
|
||||
:dma-cnt (new 'static 'dma-tag :id (dma-tag-id cnt))
|
||||
:vif-unpack-v4-8 (new 'static 'vif-tag :cmd (vif-cmd unpack-v4-8))
|
||||
)
|
||||
)
|
||||
|
||||
(defun shadow-invert-z-buf ((arg0 dma-buffer))
|
||||
(let ((v1-0 (-> arg0 base)))
|
||||
(let* ((a1-0 arg0)
|
||||
(a2-0 (the-as object (-> a1-0 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a2-0) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet a2-0) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet a2-0) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1))
|
||||
(set! (-> a1-0 base) (&+ (the-as pointer a2-0) 16))
|
||||
)
|
||||
(let* ((a1-1 arg0)
|
||||
(a2-2 (the-as object (-> a1-1 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag a2-2) tag) (new 'static 'gif-tag64 :nloop #x7 :eop #x1 :nreg #x1))
|
||||
(set! (-> (the-as gs-gif-tag a2-2) regs) (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)))
|
||||
(set! (-> a1-1 base) (&+ (the-as pointer a2-2) 16))
|
||||
)
|
||||
(let ((t1-0 (-> arg0 base))
|
||||
(t0-0 512)
|
||||
)
|
||||
416
|
||||
(let ((a1-3 1792)
|
||||
(a2-4 1840)
|
||||
)
|
||||
2304
|
||||
(let ((a3-5 2256)
|
||||
(t0-1 (/ t0-0 32))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 8) (gs-reg texflush))
|
||||
(set! (-> (the-as (pointer gs-reg64) t1-0) 0) (gs-reg64 prim))
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 24) (gs-reg frame-1))
|
||||
(set! (-> (the-as (pointer gs-frame) t1-0) 2) (new 'static 'gs-frame :fbp #x130 :fbw #x8 :fbmsk #xff000000))
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 40) (gs-reg zbuf-1))
|
||||
(set! (-> (the-as (pointer gs-zbuf) t1-0) 4) (new 'static 'gs-zbuf :zbp #x130 :psm (gs-psm ct24) :zmsk #x1))
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 56) (gs-reg test-1))
|
||||
(set! (-> (the-as (pointer gs-test) t1-0) 6)
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 72) (gs-reg alpha-1))
|
||||
(set! (-> (the-as (pointer gs-alpha) t1-0) 8) (new 'static 'gs-alpha :b #x1 :c #x2 :d #x2 :fix #x80))
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 88) (gs-reg prim))
|
||||
(set! (-> (the-as (pointer gs-reg64) t1-0) 10) (gs-reg64 colclamp))
|
||||
(set! (-> (the-as (pointer gs-reg) t1-0) 104) (gs-reg rgbaq))
|
||||
(set! (-> (the-as (pointer gs-rgbaq) t1-0) 12) (new 'static 'gs-rgbaq :r #xff :g #xff :b #xff :q 1.0))
|
||||
(&+! (-> arg0 base) 112)
|
||||
(let* ((t1-3 arg0)
|
||||
(t2-12 (the-as object (-> t1-3 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t2-12) tag)
|
||||
(new 'static 'gif-tag64 :eop #x1 :flg (gif-flag reg-list) :nreg #x2 :nloop t0-1)
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t2-12) regs)
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id xyz2) :regs1 (gif-reg-id xyz2))
|
||||
)
|
||||
(set! (-> t1-3 base) (&+ (the-as pointer t2-12) 16))
|
||||
)
|
||||
(let ((t1-4 0))
|
||||
(dotimes (t2-14 t0-1)
|
||||
(let* ((t3-3 arg0)
|
||||
(t4-2 (-> t3-3 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-xyzf) t4-2) 0) (new 'static 'gs-xyzf :y (* a2-4 16) :x (* (+ t1-4 a1-3) 16)))
|
||||
(set! (-> (the-as (pointer gs-xyzf) t4-2) 1) (new 'static 'gs-xyzf :y (* a3-5 16) :x (* (+ t1-4 32 a1-3) 16)))
|
||||
(set! (-> t3-3 base) (&+ t4-2 16))
|
||||
)
|
||||
(+! t1-4 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(nop!)
|
||||
(nop!)
|
||||
0
|
||||
(let ((a1-9 (/ (the-as int (+ (- -16 (the-as int v1-0)) (the-as int (-> arg0 base)))) 16)))
|
||||
(cond
|
||||
((nonzero? a1-9)
|
||||
(logior! (-> (the-as (pointer uint64) v1-0) 0) (shr (shl a1-9 48) 48))
|
||||
(logior! (-> (the-as (pointer uint64) v1-0) 1) (shl (shr (shl a1-9 48) 48) 32))
|
||||
)
|
||||
(else
|
||||
(set! (-> arg0 base) v1-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch pointer vs none.
|
||||
(defun shadow-make-invert-buf ()
|
||||
(let ((gp-0 *shadow-dma-buf*))
|
||||
(let ((v1-0 gp-0))
|
||||
(set! (-> v1-0 base) (-> v1-0 data))
|
||||
(set! (-> v1-0 end) (the-as pointer (+ (+ (-> v1-0 allocated-length) 28) (the-as int v1-0))))
|
||||
)
|
||||
(shadow-invert-z-buf gp-0)
|
||||
(let ((v1-1 (the-as object (-> gp-0 base))))
|
||||
(set! (-> (the-as dma-packet v1-1) dma) (new 'static 'dma-tag :id (dma-tag-id ret)))
|
||||
(set! (-> (the-as dma-packet v1-1) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet v1-1) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> gp-0 base) (&+ (the-as pointer v1-1) 16))
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
(shadow-make-invert-buf)
|
||||
|
||||
(define *shadow-dma-invert-call* (the-as pointer #f))
|
||||
|
||||
;; WARN: Return type mismatch dma-buffer vs none.
|
||||
(defun shadow-dma-init ((arg0 dma-buffer))
|
||||
(-> *display* on-screen)
|
||||
(let ((a1-0 408))
|
||||
(* a1-0 32)
|
||||
(let ((t3-0 512)
|
||||
(t2-0 416)
|
||||
(a2-0 1792)
|
||||
(a3-0 1840)
|
||||
)
|
||||
2304
|
||||
(let ((t0-0 2256)
|
||||
(t1-0 (/ t3-0 32))
|
||||
(t5-0 (* a3-0 16))
|
||||
)
|
||||
(set! *shadow-dma-invert-call* (-> arg0 base))
|
||||
(let* ((v1-6 arg0)
|
||||
(t4-0 (the-as object (-> v1-6 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet t4-0) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet t4-0) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet t4-0) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> v1-6 base) (&+ (the-as pointer t4-0) 16))
|
||||
)
|
||||
(let ((v1-7 (-> arg0 base)))
|
||||
(let* ((t4-2 arg0)
|
||||
(t6-1 (the-as object (-> t4-2 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet t6-1) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet t6-1) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet t6-1) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1))
|
||||
(set! (-> t4-2 base) (&+ (the-as pointer t6-1) 16))
|
||||
)
|
||||
(let* ((t4-3 arg0)
|
||||
(t6-3 (the-as object (-> t4-3 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t6-3) tag) (new 'static 'gif-tag64 :nloop #xa :eop #x1 :nreg #x1))
|
||||
(set! (-> (the-as gs-gif-tag t6-3) regs) (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)))
|
||||
(set! (-> t4-3 base) (&+ (the-as pointer t6-3) 16))
|
||||
)
|
||||
(let ((t4-4 (-> arg0 base)))
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 1) (gs-reg64 texflush))
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 3) (gs-reg64 test-1))
|
||||
(set! (-> (the-as (pointer gs-test) t4-4) 2)
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 5) (gs-reg64 alpha-1))
|
||||
(set! (-> (the-as (pointer gs-alpha) t4-4) 4) (new 'static 'gs-alpha :b #x1 :d #x1))
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 7) (gs-reg64 frame-1))
|
||||
(set! (-> (the-as (pointer gs-frame) t4-4) 6) (new 'static 'gs-frame :fbw #x8 :fbmsk #xffffff :fbp a1-0))
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 9) (gs-reg64 zbuf-1))
|
||||
(set! (-> (the-as (pointer gs-zbuf) t4-4) 8) (new 'static 'gs-zbuf :zbp #x130 :psm (gs-psm ct24) :zmsk #x1))
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 11) (gs-reg64 xyoffset-1))
|
||||
(set! (-> (the-as (pointer gs-xy-offset) t4-4) 10) (new 'static 'gs-xy-offset :ofx (* a2-0 16) :ofy t5-0))
|
||||
(set! (-> (the-as (pointer gs-reg64) t4-4) 13) (gs-reg64 tex0-1))
|
||||
(set! (-> (the-as (pointer gs-tex0) t4-4) 12)
|
||||
(new 'static 'gs-tex0 :tbw #x8 :tw #x9 :th #x9 :tcc #x1 :tbp0 (* a1-0 32))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg) t4-4) 120) (gs-reg tex1-1))
|
||||
(set! (-> (the-as (pointer gs-tex1) t4-4) 14) (new 'static 'gs-tex1))
|
||||
(set! (-> (the-as (pointer gs-reg) t4-4) 136) (gs-reg miptbp1-1))
|
||||
(set! (-> (the-as (pointer gs-miptbp) t4-4) 16) (new 'static 'gs-miptbp))
|
||||
(set! (-> (the-as (pointer gs-reg) t4-4) 152) (gs-reg clamp-1))
|
||||
(set! (-> (the-as (pointer gs-clamp) t4-4) 18) (new 'static 'gs-clamp
|
||||
:wms (gs-tex-wrap-mode region-clamp)
|
||||
:wmt (gs-tex-wrap-mode region-clamp)
|
||||
:maxv (+ t2-0 -1)
|
||||
:maxu (+ t3-0 -1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(&+! (-> arg0 base) 160)
|
||||
(let* ((t2-7 arg0)
|
||||
(t3-5 (the-as object (-> t2-7 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t3-5) tag)
|
||||
(new 'static 'gif-tag64 :nloop #x1 :eop #x1 :flg (gif-flag reg-list) :nreg #x2)
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t3-5) regs) (new 'static 'gif-tag-regs :regs1 (gif-reg-id rgbaq)))
|
||||
(set! (-> t2-7 base) (&+ (the-as pointer t3-5) 16))
|
||||
)
|
||||
(let* ((t2-8 arg0)
|
||||
(t3-7 (-> t2-8 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-prim) t3-7) 0) (new 'static 'gs-prim :prim (gs-prim-type sprite)))
|
||||
(set! (-> (the-as (pointer gs-rgbaq) t3-7) 1) (new 'static 'gs-rgbaq :a #x60))
|
||||
(set! (-> t2-8 base) (&+ t3-7 16))
|
||||
)
|
||||
(let* ((t2-9 arg0)
|
||||
(t3-9 (the-as object (-> t2-9 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t3-9) tag)
|
||||
(new 'static 'gif-tag64 :eop #x1 :flg (gif-flag reg-list) :nreg #x2 :nloop t1-0)
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag t3-9) regs)
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id xyz2) :regs1 (gif-reg-id xyz2))
|
||||
)
|
||||
(set! (-> t2-9 base) (&+ (the-as pointer t3-9) 16))
|
||||
)
|
||||
(let ((t2-10 0))
|
||||
(dotimes (t3-11 t1-0)
|
||||
(let* ((t4-12 arg0)
|
||||
(t5-12 (-> t4-12 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-xyzf) t5-12) 0)
|
||||
(new 'static 'gs-xyzf :z #x1ffff :y (* a3-0 16) :x (* (+ a2-0 t2-10) 16))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-xyzf) t5-12) 1)
|
||||
(new 'static 'gs-xyzf :z #x1ffff :y (* t0-0 16) :x (* (+ t2-10 32 a2-0) 16))
|
||||
)
|
||||
(set! (-> t4-12 base) (&+ t5-12 16))
|
||||
)
|
||||
(+! t2-10 32)
|
||||
)
|
||||
)
|
||||
(let* ((a2-3 arg0)
|
||||
(a3-1 (the-as object (-> a2-3 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag a3-1) tag) (new 'static 'gif-tag64 :nloop #x4 :eop #x1 :nreg #x1))
|
||||
(set! (-> (the-as gs-gif-tag a3-1) regs) (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)))
|
||||
(set! (-> a2-3 base) (&+ (the-as pointer a3-1) 16))
|
||||
)
|
||||
(cond
|
||||
(*shadow-debug*
|
||||
(let* ((a2-5 arg0)
|
||||
(a3-3 (-> a2-5 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-test) a3-3) 0)
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest greater-equal))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-3) 1) (gs-reg64 test-1))
|
||||
(set! (-> (the-as (pointer gs-zbuf) a3-3) 2) (new 'static 'gs-zbuf :zbp #x130 :psm (gs-psm ct24)))
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-3) 3) (gs-reg64 zbuf-1))
|
||||
(set! (-> (the-as (pointer gs-frame) a3-3) 4) (new 'static 'gs-frame :fbw #x8 :fbp a1-0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-3) 5) (gs-reg64 frame-1))
|
||||
(set! (-> (the-as (pointer uint64) a3-3) 6) (the-as uint 0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-3) 7) (gs-reg64 texflush))
|
||||
(set! (-> a2-5 base) (&+ a3-3 64))
|
||||
)
|
||||
)
|
||||
(else
|
||||
(let* ((a2-6 arg0)
|
||||
(a3-4 (-> a2-6 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-test) a3-4) 0)
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest greater-equal))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-4) 1) (gs-reg64 test-1))
|
||||
(set! (-> (the-as (pointer gs-zbuf) a3-4) 2) (new 'static 'gs-zbuf :zbp #x130 :psm (gs-psm ct24) :zmsk #x1))
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-4) 3) (gs-reg64 zbuf-1))
|
||||
(set! (-> (the-as (pointer gs-frame) a3-4) 4) (new 'static 'gs-frame :fbw #x8 :fbmsk #xffffff :fbp a1-0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-4) 5) (gs-reg64 frame-1))
|
||||
(set! (-> (the-as (pointer uint64) a3-4) 6) (the-as uint 0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a3-4) 7) (gs-reg64 texflush))
|
||||
(set! (-> a2-6 base) (&+ a3-4 64))
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((a2-10 (/ (the-as int (+ (- -16 (the-as int v1-7)) (the-as int (-> arg0 base)))) 16)))
|
||||
(cond
|
||||
((nonzero? a2-10)
|
||||
(logior! (-> (the-as (pointer uint64) v1-7) 0) (shr (shl a2-10 48) 48))
|
||||
(logior! (-> (the-as (pointer uint64) v1-7) 1) (shl (shr (shl a2-10 48) 48) 32))
|
||||
)
|
||||
(else
|
||||
(set! (-> arg0 base) v1-7)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch dma-buffer vs none.
|
||||
(defun shadow-dma-end ((arg0 dma-buffer) (arg1 gs-rgbaq) (arg2 symbol) (arg3 int))
|
||||
(local-vars (sv-16 int))
|
||||
(set! sv-16 arg3)
|
||||
(-> *display* on-screen)
|
||||
(let ((s0-0 408))
|
||||
(* s0-0 32)
|
||||
(let ((v1-4 512)
|
||||
(s3-0 416)
|
||||
(s5-0 1792)
|
||||
(s4-0 1840)
|
||||
)
|
||||
2304
|
||||
2256
|
||||
(let ((s2-0 (/ v1-4 32)))
|
||||
(* s4-0 16)
|
||||
(let ((v1-6 (the-as object *shadow-dma-invert-call*))
|
||||
(a0-3 *shadow-dma-buf*)
|
||||
)
|
||||
(cond
|
||||
(arg2
|
||||
(set! (-> (the-as (pointer uint64) v1-6)) (logior #x50000000 (shr (shl (the-as int (-> a0-3 data)) 33) 1)))
|
||||
(set! (-> (the-as (pointer uint64) v1-6) 1) (the-as uint 0))
|
||||
(let* ((v1-7 arg0)
|
||||
(a1-3 (the-as object (-> v1-7 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a1-3) dma)
|
||||
(new 'static 'dma-tag :id (dma-tag-id call) :addr (the-as int (-> a0-3 data)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a1-3) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet a1-3) vif1) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1))
|
||||
(set! (-> v1-7 base) (&+ (the-as pointer a1-3) 16))
|
||||
)
|
||||
)
|
||||
(else
|
||||
(set! (-> (the-as dma-packet v1-6) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as (pointer uint64) v1-6) 1) (the-as uint 0))
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
(shadow-vu1-patch-consts arg2 sv-16)
|
||||
(cond
|
||||
((= sv-16 2)
|
||||
(dma-buffer-add-gs-set-flusha arg0
|
||||
(texflush 0)
|
||||
(test-1
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest not-equal) :aref #x60 :zte #x1 :ztst (gs-ztest always))
|
||||
)
|
||||
(tex0-1 (new 'static 'gs-tex0 :tbp0 #x3300 :tbw #x8 :tw #x9 :th #x9 :tcc #x1 :tfx #x3))
|
||||
(frame-1 (new 'static 'gs-frame :fbw #x8 :fbp s0-0))
|
||||
(alpha-1 (new 'static 'gs-alpha))
|
||||
(texflush 0)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(let* ((v1-13 arg0)
|
||||
(a0-19 (the-as object (-> v1-13 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a0-19) dma) (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet a0-19) vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1))
|
||||
(set! (-> (the-as dma-packet a0-19) vif1) (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1))
|
||||
(set! (-> v1-13 base) (&+ (the-as pointer a0-19) 16))
|
||||
)
|
||||
(let* ((v1-14 arg0)
|
||||
(a0-21 (the-as object (-> v1-14 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag a0-21) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x5))
|
||||
(set! (-> (the-as gs-gif-tag a0-21) regs) GIF_REGS_ALL_AD)
|
||||
(set! (-> v1-14 base) (&+ (the-as pointer a0-21) 16))
|
||||
)
|
||||
(let* ((v1-15 arg0)
|
||||
(a0-23 (-> v1-15 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer uint64) a0-23) 0) (the-as uint 0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a0-23) 1) (gs-reg64 texflush))
|
||||
(set! (-> (the-as (pointer gs-test) a0-23) 2)
|
||||
(new 'static 'gs-test :ate #x1 :atst (gs-atest not-equal) :aref #x60 :zte #x1 :ztst (gs-ztest always))
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-reg64) a0-23) 3) (gs-reg64 test-1))
|
||||
(set! (-> (the-as (pointer gs-frame) a0-23) 4) (new 'static 'gs-frame :fbw #x8 :fbp s0-0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a0-23) 5) (gs-reg64 frame-1))
|
||||
(set! (-> (the-as (pointer uint64) a0-23) 6) (the-as uint 0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a0-23) 7) (gs-reg64 alpha-1))
|
||||
(set! (-> (the-as (pointer uint64) a0-23) 8) (the-as uint 0))
|
||||
(set! (-> (the-as (pointer gs-reg64) a0-23) 9) (gs-reg64 texflush))
|
||||
(set! (-> v1-15 base) (&+ a0-23 80))
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((v1-16 (-> arg0 base)))
|
||||
(let* ((a0-25 arg0)
|
||||
(a1-35 (the-as object (-> a0-25 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a1-35) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet a1-35) vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1))
|
||||
(set! (-> (the-as dma-packet a1-35) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1))
|
||||
(set! (-> a0-25 base) (&+ (the-as pointer a1-35) 16))
|
||||
)
|
||||
(let* ((a0-26 arg0)
|
||||
(a1-37 (the-as object (-> a0-26 base)))
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag a1-37) tag)
|
||||
(new 'static 'gif-tag64 :nloop #x1 :flg (gif-flag reg-list) :nreg #x2)
|
||||
)
|
||||
(set! (-> (the-as gs-gif-tag a1-37) regs) (new 'static 'gif-tag-regs :regs1 (gif-reg-id rgbaq)))
|
||||
(set! (-> (the-as (pointer gs-prim) a1-37) 2)
|
||||
(new 'static 'gs-prim :prim (gs-prim-type sprite) :tme #x1 :abe #x1)
|
||||
)
|
||||
(set! (-> (the-as (pointer gs-rgbaq) a1-37) 3) arg1)
|
||||
(set! (-> (the-as (inline-array gs-gif-tag) a1-37) 2 tag)
|
||||
(new 'static 'gif-tag64 :eop #x1 :flg (gif-flag reg-list) :nreg #x4 :nloop s2-0)
|
||||
)
|
||||
(set! (-> (the-as (inline-array gs-gif-tag) a1-37) 2 regs) (new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id st)
|
||||
:regs1 (gif-reg-id xyz2)
|
||||
:regs2 (gif-reg-id st)
|
||||
:regs3 (gif-reg-id xyz2)
|
||||
)
|
||||
)
|
||||
(set! (-> a0-26 base) (&+ (the-as pointer a1-37) 48))
|
||||
)
|
||||
(let ((a0-27 0)
|
||||
(a1-39 0)
|
||||
)
|
||||
(dotimes (a2-14 s2-0)
|
||||
(let ((t1-0 a0-27))
|
||||
(+! a0-27 32)
|
||||
(let* ((a3-7 arg0)
|
||||
(t0-0 (-> a3-7 base))
|
||||
)
|
||||
(set! (-> (the-as (pointer uint64) t0-0) 0)
|
||||
(the-as
|
||||
uint
|
||||
(logior (shl (the-as int (* 0.001953125 (+ 0.5 (the float a1-39)))) 32)
|
||||
(shr (shl (the-as int (* 0.001953125 (+ 0.5 (the float t1-0)))) 32) 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as (pointer uint64) t0-0) 1)
|
||||
(the-as
|
||||
uint
|
||||
(logior (logior (shl #x1ffff 32) (shr (shl (* (+ s5-0 t1-0) 16) 48) 48))
|
||||
(shr (shl (* (+ s4-0 a1-39) 16) 48) 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as (pointer uint64) t0-0) 2)
|
||||
(the-as
|
||||
uint
|
||||
(logior (shl (the-as int (* 0.001953125 (+ 0.5 (the float s3-0)))) 32)
|
||||
(shr (shl (the-as int (* 0.001953125 (+ 0.5 (the float a0-27)))) 32) 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as (pointer uint64) t0-0) 3)
|
||||
(the-as uint (logior (logior (shl #x1ffff 32) (shr (shl (* (+ s5-0 a0-27) 16) 48) 48))
|
||||
(shr (shl (* (+ s4-0 s3-0) 16) 48) 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> a3-7 base) (&+ t0-0 32))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((a1-43 (/ (the-as int (+ (- -16 (the-as int v1-16)) (the-as int (-> arg0 base)))) 16)))
|
||||
(cond
|
||||
((nonzero? a1-43)
|
||||
(logior! (-> (the-as (pointer uint64) v1-16) 0) (shr (shl a1-43 48) 48))
|
||||
(logior! (-> (the-as (pointer uint64) v1-16) 1) (shl (shr (shl a1-43 48) 48) 32))
|
||||
)
|
||||
(else
|
||||
(set! (-> arg0 base) v1-16)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(reset-display-gs-state *display* arg0)
|
||||
(none)
|
||||
)
|
||||
|
||||
(deftype shadow-stats (structure)
|
||||
((num-single-tris uint32)
|
||||
(num-double-tris uint32)
|
||||
(num-single-edges uint32)
|
||||
(num-double-edges uint32)
|
||||
(num-fragments uint16)
|
||||
(num-objects uint16)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftype shadow-dcache (structure)
|
||||
((vtx-table uint32)
|
||||
(single-edge-table uint32)
|
||||
(double-edge-table uint32)
|
||||
(double-tri-table uint32)
|
||||
(dcache-top uint32)
|
||||
(num-facing-single-tris uint32)
|
||||
(num-single-edges uint32)
|
||||
(num-double-edges uint32)
|
||||
(single-tri-list uint32)
|
||||
(single-edge-list uint32)
|
||||
(double-edge-list uint32)
|
||||
(ptr-dual-verts uint32)
|
||||
(stats shadow-stats :inline)
|
||||
(frag-qwc uint32)
|
||||
(center vector :inline)
|
||||
(plane vector :inline)
|
||||
(top-plane vector :inline)
|
||||
(near-plane vector :inline)
|
||||
(light-dir vector :inline)
|
||||
(vtx-min vector :inline)
|
||||
(data uint8 :dynamic)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(define shadow-vu0-block (new 'static 'vu-function :length 88 :qlength 44))
|
||||
|
||||
(def-mips2c shadow-xform-verts function)
|
||||
|
||||
(def-mips2c shadow-calc-dual-verts function)
|
||||
|
||||
(def-mips2c shadow-scissor-edges function)
|
||||
|
||||
(def-mips2c shadow-scissor-top function)
|
||||
|
||||
(def-mips2c shadow-init-vars function)
|
||||
|
||||
(def-mips2c shadow-find-facing-single-tris function)
|
||||
|
||||
(def-mips2c shadow-find-single-edges function)
|
||||
|
||||
(def-mips2c shadow-find-facing-double-tris function)
|
||||
|
||||
(def-mips2c shadow-find-double-edges function)
|
||||
|
||||
(def-mips2c shadow-add-verts function)
|
||||
|
||||
(def-mips2c shadow-add-facing-single-tris function)
|
||||
|
||||
(def-mips2c shadow-add-single-edges function)
|
||||
|
||||
(def-mips2c shadow-add-single-tris function)
|
||||
|
||||
(def-mips2c shadow-add-double-tris function)
|
||||
|
||||
(def-mips2c shadow-add-double-edges function)
|
||||
|
||||
(defmethod shadow-control-method-14 ((this shadow-control) (arg0 vector) (arg1 vector) (arg2 float) (arg3 float) (arg4 float))
|
||||
(let ((gp-0 (-> this settings)))
|
||||
(let ((s4-0 (-> gp-0 shadow-dir)))
|
||||
(vector-normalize-copy! s4-0 arg1 1.0)
|
||||
(set! (-> gp-0 shadow-dir w) (- arg2))
|
||||
(when *shadow-debug*
|
||||
(add-debug-x #t (bucket-id debug-no-zbuf1) arg0 *color-red*)
|
||||
(add-debug-vector #t (bucket-id debug-no-zbuf1) arg0 s4-0 (meters 3) *color-red*)
|
||||
)
|
||||
(let ((s1-2 (vector+float*! (new 'stack-no-clear 'vector) arg0 s4-0 arg3))
|
||||
(s5-2 (vector+float*! (new 'stack-no-clear 'vector) arg0 s4-0 arg4))
|
||||
)
|
||||
(vector-negate! (-> gp-0 top-plane) s4-0)
|
||||
(vector-negate! (-> gp-0 bot-plane) s4-0)
|
||||
(set! (-> gp-0 top-plane w) (- (vector-dot s1-2 (the-as vector (-> gp-0 top-plane)))))
|
||||
(set! (-> gp-0 bot-plane w) (- (vector-dot s5-2 (the-as vector (-> gp-0 bot-plane)))))
|
||||
)
|
||||
)
|
||||
(logior! (-> gp-0 flags) (shadow-flags shdf02 shdf03 shdf04 shdf07))
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun debug-draw-settings ((arg0 shadow-settings))
|
||||
(let ((s4-0 (-> arg0 shadow-dir))
|
||||
(s5-0 (-> arg0 center))
|
||||
(s3-0 (-> arg0 top-plane))
|
||||
(s2-0 (-> arg0 bot-plane))
|
||||
(s1-0 (new 'stack-no-clear 'vector))
|
||||
(s0-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
(cond
|
||||
((logtest? (-> arg0 flags) (shadow-flags shdf02))
|
||||
(vector+float*! s1-0 s5-0 s4-0 (- (vector-dot (the-as vector s3-0) s5-0) (-> s3-0 w)))
|
||||
(vector+float*! s0-0 s5-0 s4-0 (- (vector-dot (the-as vector s2-0) s5-0) (-> s2-0 w)))
|
||||
)
|
||||
(else
|
||||
(let ((v1-7 (vector+float*! (new 'stack-no-clear 'vector) s5-0 s4-0 (-> s4-0 w))))
|
||||
(vector+float*! s1-0 v1-7 s4-0 (- (vector-dot (the-as vector s3-0) v1-7) (-> s3-0 w)))
|
||||
(vector+float*! s0-0 v1-7 s4-0 (- (vector-dot (the-as vector s2-0) v1-7) (-> s2-0 w)))
|
||||
)
|
||||
)
|
||||
)
|
||||
(add-debug-sphere #t (bucket-id debug-no-zbuf1) s5-0 (meters 0.8) *color-magenta*)
|
||||
(add-debug-vector #t (bucket-id debug-no-zbuf1) s5-0 s4-0 (meters 4) *color-magenta*)
|
||||
(add-debug-x #t (bucket-id debug-no-zbuf1) s1-0 *color-blue*)
|
||||
(add-debug-vector #t (bucket-id debug-no-zbuf1) s1-0 s3-0 (meters 2) *color-blue*)
|
||||
(add-debug-line #t (bucket-id debug-no-zbuf1) (-> arg0 center) s1-0 *color-blue* #f (the-as rgba -1))
|
||||
(add-debug-x #t (bucket-id debug-no-zbuf1) s0-0 *color-green*)
|
||||
(add-debug-vector #t (bucket-id debug-no-zbuf1) s0-0 s2-0 (meters 2) *color-green*)
|
||||
(add-debug-line #t (bucket-id debug-no-zbuf1) s1-0 s0-0 *color-green* #f (the-as rgba -1))
|
||||
)
|
||||
)
|
||||
|
||||
(def-mips2c shadow-execute (function shadow-dma-packet pointer pointer))
|
||||
|
||||
;; ERROR: Failed store: (s.d! (+ (the-as dma-packet a0-5) 8) 0) at op 17
|
||||
(defun shadow-vu0-upload ()
|
||||
(#unless PC_PORT
|
||||
(let ((gp-0 *vu0-dma-list*))
|
||||
(let ((v1-0 gp-0))
|
||||
(set! (-> v1-0 base) (-> v1-0 data))
|
||||
(set! (-> v1-0 end) (&-> v1-0 data-buffer (-> v1-0 allocated-length)))
|
||||
)
|
||||
(dma-buffer-add-vu-function gp-0 shadow-vu0-block 0)
|
||||
(let* ((v1-1 gp-0)
|
||||
(a0-5 (the-as object (-> v1-1 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a0-5) dma) (new 'static 'dma-tag :id (dma-tag-id end)))
|
||||
(s.d! (+ (the-as dma-packet a0-5) 8) 0)
|
||||
(set! (-> v1-1 base) (&+ (the-as pointer a0-5) 16))
|
||||
)
|
||||
(.sync.l)
|
||||
(dma-buffer-send-chain (the-as dma-bank-source #x10008000) gp-0)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; ERROR: Failed store: (s.h! (+ v1-25 18) 0) at op 61
|
||||
;; ERROR: Failed store: (s.h! (+ v1-25 16) 0) at op 62
|
||||
(defun shadow-execute-all ((arg0 dma-buffer))
|
||||
(when *debug-segment*
|
||||
(let ((gp-0 (-> *display* frames (-> *display* on-screen) profile-array data 0))
|
||||
(v1-7 'other)
|
||||
(s5-0 *profile-other-color*)
|
||||
)
|
||||
(when (and *dproc* *debug-segment*)
|
||||
(let ((s4-0 (-> gp-0 data (-> gp-0 count))))
|
||||
(let ((s3-0 (-> gp-0 base-time)))
|
||||
(set! (-> s4-0 name) v1-7)
|
||||
(set! (-> s4-0 start-time) (the-as int (- (timer-count (the-as timer-bank #x10000800)) (the-as uint s3-0))))
|
||||
)
|
||||
(set! (-> s4-0 depth) (the-as uint (-> gp-0 depth)))
|
||||
(set! (-> s4-0 color) s5-0)
|
||||
(set! (-> gp-0 segment (-> gp-0 depth)) s4-0)
|
||||
)
|
||||
(set! (-> gp-0 count) (min 1023 (+ (-> gp-0 count) 1)))
|
||||
(+! (-> gp-0 depth) 1)
|
||||
(set! (-> gp-0 max-depth) (max (-> gp-0 max-depth) (-> gp-0 depth)))
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
(when (logtest? (vu1-renderer-mask rn32) (-> *display* vu1-enable-user))
|
||||
(let ((gp-1 *shadow-globals*))
|
||||
(let ((v1-25 (the-as shadow-dcache (-> (the-as shadow-dcache *gsf-buffer*) stats))))
|
||||
(set! (-> v1-25 vtx-table) (the-as uint 0))
|
||||
(set! (-> v1-25 single-edge-table) (the-as uint 0))
|
||||
(set! (-> v1-25 double-edge-table) (the-as uint 0))
|
||||
(set! (-> v1-25 double-tri-table) (the-as uint 0))
|
||||
;; (s.h! (+ v1-25 18) 0)
|
||||
;; (s.h! (+ v1-25 16) 0)
|
||||
(set! (-> v1-25 dcache-top) (the-as uint 0))
|
||||
)
|
||||
0
|
||||
(let ((v1-27 #f))
|
||||
(dotimes (a0-13 3)
|
||||
(if (nonzero? (-> gp-1 bucket a0-13 first))
|
||||
(set! v1-27 #t)
|
||||
)
|
||||
)
|
||||
(when v1-27
|
||||
(shadow-vu0-upload)
|
||||
(dotimes (s5-1 3)
|
||||
(let* ((s4-1 (-> gp-1 bucket s5-1))
|
||||
(s1-0 (-> s4-1 first))
|
||||
)
|
||||
(when (nonzero? s1-0)
|
||||
(with-dma-buffer-add-bucket ((s2-0 (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
(-> s4-1 bucket-id)
|
||||
)
|
||||
(set! (-> (scratchpad-object shadow-dcache) ptr-dual-verts) (the-as uint 0))
|
||||
(shadow-vu1-init-buffer s2-0 s5-1)
|
||||
(flush-cache 0)
|
||||
(shadow-dma-init s2-0)
|
||||
(set! (-> s2-0 base) (shadow-execute (the-as shadow-dma-packet s1-0) (-> s2-0 base)))
|
||||
(let ((a2-1 (nonzero? (-> (scratchpad-object shadow-dcache) ptr-dual-verts)))
|
||||
(a1-9 (logior (shl #x3f800000 32) (shr (shl (the-as int (the-as uint32 (-> s4-1 shadow-color))) 32) 32)))
|
||||
)
|
||||
(let ((v1-43 (-> *time-of-day-context* current-shadow-color)))
|
||||
(if (zero? s5-1)
|
||||
(set! a1-9
|
||||
(logior (logand (logior (logand (logior (logand a1-9 -256) (shr (shl (the int (* 128.0 (-> v1-43 x))) 56) 56)) -65281)
|
||||
(shr (shl (the int (* 128.0 (-> v1-43 y))) 56) 48)
|
||||
)
|
||||
-16711681
|
||||
)
|
||||
(shr (shl (the int (* 128.0 (-> v1-43 z))) 56) 40)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
;; modified in pc port so we don't have to do the crazy z buffer flipping stuff.
|
||||
(shadow-dma-end s2-0 (the-as gs-rgbaq a1-9) #f #|a2-1|# s5-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((gp-2 *gsf-buffer*))
|
||||
(let ((v1-61 (-> *terrain-stats* shadow)))
|
||||
(+! (-> v1-61 groups) (-> (the-as shadow-dcache gp-2) stats num-objects))
|
||||
(+! (-> v1-61 fragments) (-> (the-as shadow-dcache gp-2) stats num-objects))
|
||||
(+! (-> v1-61 tris)
|
||||
(* (+ (-> (the-as shadow-dcache gp-2) stats num-single-tris)
|
||||
(-> (the-as shadow-dcache gp-2) stats num-double-tris)
|
||||
(-> (the-as shadow-dcache gp-2) stats num-single-edges)
|
||||
(-> (the-as shadow-dcache gp-2) stats num-double-edges)
|
||||
)
|
||||
2
|
||||
)
|
||||
)
|
||||
(+! (-> v1-61 dverts)
|
||||
(* (the-as uint 6) (-> (the-as shadow-dcache gp-2) stats num-single-tris))
|
||||
(* (the-as uint 6) (-> (the-as shadow-dcache gp-2) stats num-double-tris))
|
||||
(* (-> (the-as shadow-dcache gp-2) stats num-single-edges) 4)
|
||||
(* (-> (the-as shadow-dcache gp-2) stats num-double-edges) 4)
|
||||
)
|
||||
)
|
||||
(when #f
|
||||
(format *stdcon* "~%~%~%~%#single tris : ~4d~%" (-> (the-as shadow-dcache gp-2) stats num-single-tris))
|
||||
(format *stdcon* "#double tris : ~4d~%" (-> (the-as shadow-dcache gp-2) stats num-double-tris))
|
||||
(format *stdcon* "#single edges: ~4d~%" (-> (the-as shadow-dcache gp-2) stats num-single-edges))
|
||||
(format *stdcon* "#double edges: ~4d~%" (-> (the-as shadow-dcache gp-2) stats num-double-edges))
|
||||
)
|
||||
)
|
||||
)
|
||||
(when *debug-segment*
|
||||
(let ((gp-3 (-> *display* frames (-> *display* on-screen) profile-array data 0)))
|
||||
(when (and *dproc* *debug-segment*)
|
||||
(let* ((v1-75 (+ (-> gp-3 depth) -1))
|
||||
(s5-2 (-> gp-3 segment v1-75))
|
||||
(s4-2 (-> gp-3 base-time))
|
||||
)
|
||||
(when (>= v1-75 0)
|
||||
(set! (-> s5-2 end-time) (the-as int (- (timer-count (the-as timer-bank #x10000800)) (the-as uint s4-2))))
|
||||
(+! (-> gp-3 depth) -1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmethod probe-line-for-shadow ((this shadow-control) (arg0 vector) (arg1 float) (arg2 float) (arg3 float))
|
||||
(with-pp
|
||||
(let ((s4-0 (new 'stack-no-clear 'collide-query)))
|
||||
(let ((v1-0 pp))
|
||||
(set! (-> s4-0 start-pos quad) (-> arg0 quad))
|
||||
(+! (-> s4-0 start-pos y) 4096.0)
|
||||
(set-vector! (-> s4-0 move-dist) 0.0 (- arg3) 0.0 1.0)
|
||||
(let ((a0-4 s4-0))
|
||||
(set! (-> a0-4 radius) 8192.0)
|
||||
(set! (-> a0-4 collide-with) (collide-spec backgnd))
|
||||
(set! (-> a0-4 ignore-process0) v1-0)
|
||||
(set! (-> a0-4 ignore-process1) #f)
|
||||
(set! (-> a0-4 ignore-pat)
|
||||
(new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1 :board #x1)
|
||||
)
|
||||
(set! (-> a0-4 action-mask) (collide-action solid))
|
||||
)
|
||||
)
|
||||
(cond
|
||||
((>= (fill-and-probe-using-line-sphere *collide-cache* s4-0) 0.0)
|
||||
(let ((v1-5 this))
|
||||
(logclear! (-> v1-5 settings flags) (shadow-flags disable-draw))
|
||||
)
|
||||
0
|
||||
(let ((v1-7 this))
|
||||
(set! (-> v1-7 settings bot-plane w) (- (+ (-> s4-0 best-other-tri intersect y) arg1)))
|
||||
)
|
||||
0
|
||||
(set! (-> this settings top-plane w) (- (+ (-> s4-0 best-other-tri intersect y) arg2)))
|
||||
0
|
||||
)
|
||||
(else
|
||||
(let ((v1-10 this))
|
||||
(logior! (-> v1-10 settings flags) (shadow-flags disable-draw))
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -7,3 +7,222 @@
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(deftype shadow-vu1-constants (structure)
|
||||
((hmgescale vector :inline)
|
||||
(invhscale vector :inline)
|
||||
(texoffset vector :inline)
|
||||
(texscale vector :inline)
|
||||
(hvdfoff vector :inline)
|
||||
(fog vector :inline)
|
||||
(clrs vector 2 :inline)
|
||||
(adgif gs-gif-tag :inline)
|
||||
(texflush gs-adcmd :inline)
|
||||
(flush gs-adcmd :inline)
|
||||
(trigif gs-gif-tag :inline)
|
||||
(quadgif gs-gif-tag :inline)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftype shadow-vu1-data (structure)
|
||||
((adgif gs-gif-tag :inline)
|
||||
(ad gs-adcmd :inline)
|
||||
(flush gs-adcmd :inline)
|
||||
(trigif gs-gif-tag :inline)
|
||||
(quadgif gs-gif-tag :inline)
|
||||
(texoffset vector :inline)
|
||||
(texscale vector :inline)
|
||||
(clrs qword 2 :inline)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(define *shadow-vu1-data* (new 'static 'shadow-vu1-data
|
||||
:adgif (new 'static 'gs-gif-tag
|
||||
:tag (new 'static 'gif-tag64 :nloop #x1 :nreg #x1)
|
||||
:regs (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d))
|
||||
)
|
||||
:ad (new 'static 'gs-adcmd :cmds (gs-reg64 texflush))
|
||||
:flush (new 'static 'gs-adcmd :cmds (gs-reg64 rgbaq) :y #x3f800000)
|
||||
:trigif (new 'static 'gs-gif-tag
|
||||
:tag (new 'static 'gif-tag64
|
||||
:nloop #x1
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x7
|
||||
)
|
||||
:regs (new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id rgbaq)
|
||||
:regs1 (gif-reg-id st)
|
||||
:regs2 (gif-reg-id xyzf2)
|
||||
:regs3 (gif-reg-id st)
|
||||
:regs4 (gif-reg-id xyzf2)
|
||||
:regs5 (gif-reg-id st)
|
||||
:regs6 (gif-reg-id xyzf2)
|
||||
)
|
||||
)
|
||||
:quadgif (new 'static 'gs-gif-tag
|
||||
:tag (new 'static 'gif-tag64
|
||||
:nloop #x1
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x9
|
||||
)
|
||||
:regs (new 'static 'gif-tag-regs
|
||||
:regs0 (gif-reg-id rgbaq)
|
||||
:regs1 (gif-reg-id st)
|
||||
:regs2 (gif-reg-id xyzf2)
|
||||
:regs3 (gif-reg-id st)
|
||||
:regs4 (gif-reg-id xyzf2)
|
||||
:regs5 (gif-reg-id st)
|
||||
:regs6 (gif-reg-id xyzf2)
|
||||
:regs7 (gif-reg-id st)
|
||||
:regs8 (gif-reg-id xyzf2)
|
||||
)
|
||||
)
|
||||
:texoffset (new 'static 'vector :x 256.5 :y 208.5)
|
||||
:texscale (new 'static 'vector :x 0.001953125 :y 0.001953125)
|
||||
:clrs (new 'static 'inline-array qword 2
|
||||
(new 'static 'qword :data (new 'static 'array uint32 4 #x80 #x0 #x0 #x82))
|
||||
(new 'static 'qword :data (new 'static 'array uint32 4 #x0 #x80 #x0 #x7f))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(define shadow-vu1-block (new 'static 'vu-function #| :length #x2e9 :qlength #x175 |#))
|
||||
|
||||
;; WARN: Return type mismatch dma-buffer vs none.
|
||||
(defun shadow-vu1-add-constants ((arg0 dma-buffer) (arg1 int))
|
||||
(let* ((a3-0 13)
|
||||
(v1-0 arg0)
|
||||
(a2-0 (the-as object (-> v1-0 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a2-0) dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc a3-0))
|
||||
(set! (-> (the-as dma-packet a2-0) vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> (the-as dma-packet a2-0) vif1)
|
||||
(new 'static 'vif-tag :imm #x370 :cmd (vif-cmd unpack-v4-32) :num a3-0)
|
||||
)
|
||||
(set! (-> v1-0 base) (the-as pointer (&+ (the-as dma-packet a2-0) 16)))
|
||||
)
|
||||
(let ((v1-1 (the-as object (-> arg0 base))))
|
||||
(let ((a3-4 *math-camera*)
|
||||
(a2-2 *shadow-vu1-data*)
|
||||
)
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) hmgescale quad) (-> a3-4 hmge-scale quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) invhscale quad) (-> a3-4 inv-hmge-scale quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) hvdfoff quad) (-> a3-4 hvdf-off quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) hvdfoff x) 2048.0)
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) hvdfoff y) 2048.0)
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) fog x) (-> a3-4 pfog0))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) clrs 0 quad) (-> a2-2 clrs 0 quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) clrs 1 quad) (-> a2-2 clrs 1 quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) texoffset quad) (-> a2-2 texoffset quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) texscale quad) (-> a2-2 texscale quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) adgif qword) (-> a2-2 adgif qword))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) texflush quad) (-> a2-2 ad quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) flush quad) (-> a2-2 flush quad))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) trigif qword) (-> a2-2 trigif qword))
|
||||
(set! (-> (the-as shadow-vu1-constants v1-1) quadgif qword) (-> a2-2 quadgif qword))
|
||||
)
|
||||
(set! (-> *shadow-globals* bucket arg1 constants) (the-as shadow-vu1-constants v1-1))
|
||||
)
|
||||
(&+! (-> arg0 base) 208)
|
||||
(let* ((v1-4 arg0)
|
||||
(a1-3 (the-as object (-> v1-4 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a1-3) dma) (new 'static 'dma-tag :qwc #x4 :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet a1-3) vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> (the-as dma-packet a1-3) vif1)
|
||||
(new 'static 'vif-tag :imm #x3ac :num #x4 :cmd (vif-cmd unpack-v4-32))
|
||||
)
|
||||
(set! (-> v1-4 base) (&+ (the-as pointer a1-3) 16))
|
||||
)
|
||||
(let* ((v1-5 arg0)
|
||||
(a1-5 (the-as object (-> v1-5 base)))
|
||||
)
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) adgif tag) (new 'static 'gif-tag64 :nloop #x1 :nreg #x2))
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) adgif regs)
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d) :regs1 (gif-reg-id rgbaq))
|
||||
)
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) ad data) (the-as uint 0))
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) ad cmds) (gs-reg64 texflush))
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) flush data) (the-as uint 0))
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) flush cmds) (gs-reg64 prim))
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) trigif tag)
|
||||
(new 'static 'gif-tag64
|
||||
:nloop #x3
|
||||
:eop #x1
|
||||
:pre #x1
|
||||
:prim (new 'static 'gs-prim :prim (gs-prim-type tri-fan) :tme #x1)
|
||||
:nreg #x2
|
||||
)
|
||||
)
|
||||
(set! (-> (the-as shadow-vu1-data a1-5) trigif regs)
|
||||
(new 'static 'gif-tag-regs :regs0 (gif-reg-id st) :regs1 (gif-reg-id xyzf2))
|
||||
)
|
||||
(set! (-> v1-5 base) (&+ (the-as pointer a1-5) 64))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun shadow-vu1-patch-consts ((arg0 symbol) (arg1 int))
|
||||
(let ((v1-2 (-> *shadow-globals* bucket arg1 constants)))
|
||||
(cond
|
||||
(arg0
|
||||
(set! (-> v1-2 hvdfoff z) (- 1.0 (-> v1-2 hvdfoff z)))
|
||||
(set! (-> v1-2 fog w) -1.0)
|
||||
)
|
||||
(else
|
||||
(set! (-> v1-2 fog w) 1.0)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch dma-buffer vs none.
|
||||
(defun shadow-vu1-add-matrix ((arg0 dma-buffer) (arg1 math-camera))
|
||||
(let ((v1-0 4))
|
||||
(let* ((a2-4 arg0)
|
||||
(a3-0 (the-as object (-> a2-4 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a3-0) dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc v1-0))
|
||||
(set! (-> (the-as dma-packet a3-0) vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
|
||||
(set! (-> (the-as dma-packet a3-0) vif1) (new 'static 'vif-tag :cmd (vif-cmd unpack-v4-32) :num v1-0))
|
||||
(set! (-> a2-4 base) (&+ (the-as pointer a3-0) 16))
|
||||
)
|
||||
)
|
||||
(let ((v1-5 (the-as object (-> arg0 base))))
|
||||
(let ((a2-5 (-> arg1 perspective rvec quad))
|
||||
(a3-1 (-> arg1 perspective uvec quad))
|
||||
(t0-4 (-> arg1 perspective fvec quad))
|
||||
(a1-1 (-> arg1 perspective trans quad))
|
||||
)
|
||||
(set! (-> (the-as matrix v1-5) rvec quad) a2-5)
|
||||
(set! (-> (the-as matrix v1-5) uvec quad) a3-1)
|
||||
(set! (-> (the-as matrix v1-5) fvec quad) t0-4)
|
||||
(set! (-> (the-as matrix v1-5) trans quad) a1-1)
|
||||
)
|
||||
(set! (-> arg0 base) (&+ (the-as pointer v1-5) 64))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch dma-buffer vs none.
|
||||
(defun shadow-vu1-init-buffer ((arg0 dma-buffer) (arg1 int))
|
||||
(dma-buffer-add-vu-function arg0 shadow-vu1-block 1)
|
||||
(shadow-vu1-add-constants arg0 arg1)
|
||||
(shadow-vu1-add-matrix arg0 *math-camera*)
|
||||
(let* ((v1-0 arg0)
|
||||
(a0-4 (the-as object (-> v1-0 base)))
|
||||
)
|
||||
(set! (-> (the-as dma-packet a0-4) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
|
||||
(set! (-> (the-as dma-packet a0-4) vif0) (new 'static 'vif-tag :cmd (vif-cmd mscalf) :msk #x1 :imm #xa))
|
||||
(set! (-> (the-as dma-packet a0-4) vif1) (new 'static 'vif-tag :cmd (vif-cmd flushe) :msk #x1))
|
||||
(set! (-> v1-0 base) (&+ (the-as pointer a0-4) 16))
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
@@ -678,8 +678,6 @@
|
||||
(mem-copy! (the-as pointer s4-1) (the-as pointer this) #x2814)
|
||||
(setup-stars s4-1 (-> s4-1 star-mat) (-> this upload-data))
|
||||
(when (nonzero? (-> s4-1 star-colors 0 x))
|
||||
(format *stdcon* "doing stars asm!~%")
|
||||
(format *stdcon* "~`matrix`I~%" (-> s4-1 star-mat))
|
||||
(stars-transform-asm s4-1)
|
||||
)
|
||||
(cond
|
||||
|
||||
@@ -897,7 +897,16 @@
|
||||
)
|
||||
(add-debug-matrix *display-sprite-marks* (bucket-id debug) (-> this origin) (meters 2))
|
||||
)
|
||||
(sphere-in-view-frustum? (the-as sphere s5-1))
|
||||
;; og:preserve-this
|
||||
;; can we see it?
|
||||
(#if (not PC_PORT)
|
||||
(sphere-in-view-frustum? (the-as sphere s5-1))
|
||||
(if (-> *pc-settings* ps2-parts?)
|
||||
;; og:preserve-this launchers have larger bsphere if you have ps2 parts off
|
||||
(sphere-in-view-frustum? (the-as sphere s5-1))
|
||||
(sphere-in-view-frustum? (the-as sphere (begin (*! (-> s5-1 w) 4.0) s5-1)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1205,6 +1214,12 @@
|
||||
(if (nonzero? (-> this matrix))
|
||||
(set! f30-0 0.0)
|
||||
)
|
||||
|
||||
;; og:preserve-this if we have ps2 particles off, say we're at the camera
|
||||
(with-pc
|
||||
(if (not (-> *pc-settings* ps2-parts?))
|
||||
(set! f30-0 0.0)))
|
||||
|
||||
(let ((s2-1 (-> this length)))
|
||||
(b! #t cfg-102 :delay (nop!))
|
||||
(label cfg-26)
|
||||
|
||||
@@ -51,6 +51,11 @@
|
||||
(arg3 pointer)
|
||||
(arg4 (inline-array adgif-shader))
|
||||
)
|
||||
;; og:preserve-this
|
||||
(#when PC_BIG_MEMORY
|
||||
(*! arg0 SPRITE_MAX_AMOUNT_MULT)
|
||||
; (*! arg1 SPRITE_MAX_AMOUNT_MULT)
|
||||
)
|
||||
(let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
|
||||
(let* ((v1-3 (/ (+ arg0 63) 64))
|
||||
(a0-2 (/ (+ arg1 63) 64))
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
(define-extern sprite-glow-init-engine (function dma-buffer none))
|
||||
(define-extern sprite-glow-draw (function dma-buffer none))
|
||||
|
||||
(#when PC_BIG_MEMORY (defconstant SPRITE_MAX_AMOUNT_MULT 12))
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(deftype sprite-vec-data-2d (structure)
|
||||
|
||||
@@ -80,6 +80,10 @@ The glow and distort renderers will pull sprites from here."
|
||||
|
||||
|
||||
(defmethod new sprite-aux-list ((allocation symbol) (type-to-make type) (arg0 int))
|
||||
;; og:preserve-this
|
||||
(#when PC_BIG_MEMORY
|
||||
(*! arg0 SPRITE_MAX_AMOUNT_MULT))
|
||||
|
||||
(let ((v0-0 (object-new allocation type-to-make (the-as int (+ (-> type-to-make size) (* arg0 16))))))
|
||||
(set! (-> v0-0 num-entries) arg0)
|
||||
(set! (-> v0-0 entry) 0)
|
||||
@@ -335,6 +339,12 @@ The glow and distort renderers will pull sprites from here."
|
||||
(define sprite-vu1-block (new 'static 'vu-function #|:length #x37b :qlength #x1be|#))
|
||||
|
||||
(defmethod new sprite-array-2d ((allocation symbol) (type-to-make type) (arg0 int) (arg1 int))
|
||||
;; og:preserve-this
|
||||
(#when PC_BIG_MEMORY
|
||||
(*! arg0 SPRITE_MAX_AMOUNT_MULT)
|
||||
; (*! arg1 SPRITE_MAX_AMOUNT_MULT)
|
||||
)
|
||||
|
||||
(let* ((v1-0 (+ arg0 arg1))
|
||||
(s4-0 (* 3 v1-0))
|
||||
(a2-3 (* 5 v1-0))
|
||||
@@ -351,6 +361,12 @@ The glow and distort renderers will pull sprites from here."
|
||||
)
|
||||
|
||||
(defmethod new sprite-array-3d ((allocation symbol) (type-to-make type) (arg0 int) (arg1 int))
|
||||
;; og:preserve-this
|
||||
(#when PC_BIG_MEMORY
|
||||
(*! arg0 SPRITE_MAX_AMOUNT_MULT)
|
||||
; (*! arg1 SPRITE_MAX_AMOUNT_MULT)
|
||||
)
|
||||
|
||||
(let* ((v1-0 (+ arg0 arg1))
|
||||
(s4-0 (* 3 v1-0))
|
||||
(a2-3 (* 5 v1-0))
|
||||
|
||||
@@ -9,3 +9,234 @@
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(defun noise-texture-anim-layer-func ((arg0 dma-buffer) (arg1 uint) (arg2 int) (arg3 int) (arg4 texture-anim-layer) (arg5 float))
|
||||
(format 0 "unsupported noise-texture-anim-layer-func~%")
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
|
||||
(defun cloud-texture-anim-layer-func ((arg0 dma-buffer) (arg1 uint) (arg2 int) (arg3 int) (arg4 texture-anim-layer) (arg5 float))
|
||||
(format 0 "unsupported cloud-texture-anim-layer-func~%")
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
|
||||
(defun cloud-texture-anim-func ((arg0 dma-buffer) (arg1 texture-anim))
|
||||
(format 0 "unsupported cloud-texture-anim-func~%")
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
|
||||
(defun fog-texture-anim-init ((arg0 texture-anim))
|
||||
(let ((gp-0 (new 'loading-level 'fog8x256))
|
||||
(s4-0 (new 'loading-level 'clut16x16))
|
||||
)
|
||||
(when (and gp-0 s4-0)
|
||||
(let ((v1-5 (new 'loading-level 'texture)))
|
||||
(let ((a0-4 (the int (-> arg0 extra x)))
|
||||
(a1-3 (the int (-> arg0 extra y)))
|
||||
)
|
||||
(set! (-> arg0 tex) v1-5)
|
||||
(set! (-> v1-5 pad 0) (the-as uint gp-0))
|
||||
(set! (-> v1-5 pad 1) (the-as uint s4-0))
|
||||
(set! (-> v1-5 w) 256)
|
||||
(set! (-> v1-5 h) 1)
|
||||
(set! (-> v1-5 num-mips) (the-as uint 1))
|
||||
(set! (-> v1-5 psm) (gs-psm mt8))
|
||||
(set! (-> v1-5 clutpsm) (the-as uint 0))
|
||||
(set! (-> v1-5 dest 0) (the-as uint (* a0-4 32)))
|
||||
(set! (-> v1-5 clutdest) (the-as uint (* a1-3 32)))
|
||||
)
|
||||
(set! (-> v1-5 width 0) (the-as uint 4))
|
||||
(set! (-> v1-5 masks data 0 mask quad) (the-as uint128 0))
|
||||
(set! (-> v1-5 masks data 1 mask quad) (the-as uint128 0))
|
||||
(set! (-> v1-5 masks data 2 mask quad) (the-as uint128 0))
|
||||
)
|
||||
0
|
||||
(dotimes (v1-7 256)
|
||||
(nop!)
|
||||
(nop!)
|
||||
(nop!)
|
||||
(nop!)
|
||||
(set! (-> gp-0 image v1-7) (the-as uint v1-7))
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
)
|
||||
|
||||
(define *fog-texture-work* (new 'static 'fog-texture-work :const (new 'static 'vector :x 0.00390625)))
|
||||
|
||||
|
||||
(defun real-fog-texture-anim-func ((arg0 dma-buffer) (arg1 texture-anim))
|
||||
(local-vars (v1-11 float))
|
||||
(rlet ((vf1 :class vf)
|
||||
(vf2 :class vf)
|
||||
)
|
||||
(let ((s4-0 (new 'stack-no-clear 'vector))
|
||||
(s3-0 (new 'stack-no-clear 'vector))
|
||||
(s1-0 *fog-texture-work*)
|
||||
(s2-0 (the-as (pointer uint32) (-> arg1 tex pad 1)))
|
||||
)
|
||||
(let ((v1-1 (-> s1-0 color)))
|
||||
(dotimes (a0-1 256)
|
||||
(set! (-> s2-0 a0-1) (the-as uint v1-1))
|
||||
)
|
||||
)
|
||||
(vector+! (-> s1-0 max-corner) (the-as vector (-> s1-0 corner)) (-> s1-0 corner 1))
|
||||
(vector-float*! (-> s1-0 max-corner) (-> s1-0 max-corner) 0.5)
|
||||
(vector+! (-> s1-0 min-corner) (-> s1-0 corner 2) (-> s1-0 corner 3))
|
||||
(vector-float*! (-> s1-0 min-corner) (-> s1-0 min-corner) 0.5)
|
||||
(when (< (-> s1-0 max-corner y) (-> s1-0 min-corner y))
|
||||
(.lvf vf1 (&-> s1-0 min-corner quad))
|
||||
(.lvf vf2 (&-> s1-0 max-corner quad))
|
||||
(.svf (&-> s1-0 max-corner quad) vf1)
|
||||
(.svf (&-> s1-0 min-corner quad) vf2)
|
||||
(.mov v1-11 vf2)
|
||||
)
|
||||
(let* ((f0-3 (-> s1-0 corner 0 y))
|
||||
(f2-0 (-> s1-0 corner 1 y))
|
||||
(f1-1 (fmin f0-3 f2-0))
|
||||
(f2-1 (fmax f0-3 f2-0))
|
||||
(f3-0 (-> s1-0 corner 2 y))
|
||||
(f0-4 (-> s1-0 corner 3 y))
|
||||
(f1-3 (fmin (fmin f1-1 f3-0) f0-4))
|
||||
(f0-5 (fmax (fmax f2-1 f3-0) f0-4))
|
||||
)
|
||||
(set! (-> s1-0 min-corner y) f1-3)
|
||||
(set! (-> s1-0 max-corner y) f0-5)
|
||||
)
|
||||
(set! (-> s4-0 quad) (-> s1-0 min-corner quad))
|
||||
(vector-! s3-0 (-> s1-0 max-corner) (-> s1-0 min-corner))
|
||||
(vector-float/! s3-0 s3-0 256.0)
|
||||
0.0
|
||||
0.0
|
||||
(let ((f0-9 (fmax 4096.0 (-> *math-camera* trans y)))
|
||||
(f1-5 (-> arg1 extra z))
|
||||
(f2-3 (-> s1-0 alpha-near))
|
||||
(f3-1 (-> s1-0 alpha-far))
|
||||
(f4-0 (-> s1-0 alpha-delta))
|
||||
(f5-0 (-> s1-0 fog-near))
|
||||
(f6-0 (-> s1-0 fog-far))
|
||||
(f7-0 (-> s1-0 fog-delta))
|
||||
)
|
||||
(dotimes (v1-17 256)
|
||||
(let* ((f8-0 (-> s4-0 y))
|
||||
(f8-1 (cond
|
||||
((= f8-0 0.0)
|
||||
f3-1
|
||||
)
|
||||
((< f8-0 0.0)
|
||||
(let ((f9-4 (fmin f6-0 (/ (* f0-9 (vector-length s4-0)) (- f8-0)))))
|
||||
(+ f2-3 (* f4-0 (/ (fmax 0.0 (- f9-4 f5-0)) f7-0)))
|
||||
)
|
||||
)
|
||||
(else
|
||||
(let ((f9-8 (fmin f6-0 (/ (* f1-5 (vector-length s4-0)) f8-0))))
|
||||
(+ f2-3 (* f4-0 (/ (fmax 0.0 (- f9-8 f5-0)) f7-0)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> s2-0 (-> *clut-translate* v1-17))
|
||||
(logior (logand (-> s2-0 (-> *clut-translate* v1-17)) (the-as uint #xffffffff00ffffff))
|
||||
(shr (shl (the int (* 128.0 f8-1)) 56) 32)
|
||||
)
|
||||
)
|
||||
)
|
||||
(vector+! s4-0 s4-0 s3-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((s5-1 (-> arg1 tex))
|
||||
(v1-20 *display*)
|
||||
(a0-26 144)
|
||||
)
|
||||
(+! (-> v1-20 mem-reserve-size) a0-26)
|
||||
(the-as
|
||||
int
|
||||
(when (not (-> v1-20 dma-buffer-overflow))
|
||||
(let ((a2-3 (-> v1-20 frames (-> v1-20 on-screen) global-buf)))
|
||||
(if (< (-> a2-3 real-buffer-end) (the-as int (&+ (-> a2-3 base) a0-26)))
|
||||
(set! (-> v1-20 dma-buffer-overflow) #t)
|
||||
)
|
||||
)
|
||||
(when (not (-> v1-20 dma-buffer-overflow))
|
||||
;; PC port of texture upload:
|
||||
(pc-texture-anim-flag upload-generic-vram arg0 :qwc 1)
|
||||
(let ((upload-record (the texture-anim-pc-upload (-> arg0 base))))
|
||||
(set! (-> upload-record data) (the-as pointer (-> s5-1 pad 0))) ;; the texture data
|
||||
(set! (-> upload-record width) (-> s5-1 w)) ;; see fog-texture-anim-init, there's not cropping.
|
||||
(set! (-> upload-record height) (-> s5-1 h))
|
||||
(set! (-> upload-record dest) (-> s5-1 dest 0))
|
||||
(set! (-> upload-record format) (-> s5-1 psm))
|
||||
(set! (-> upload-record force-to-gpu) 1)
|
||||
)
|
||||
(&+! (-> arg0 base) 16)
|
||||
;; original upload
|
||||
; (dma-buffer-add-gs-set arg0
|
||||
; (bitbltbuf
|
||||
; (new 'static 'gs-bitbltbuf :dpsm (the-as int (-> s5-1 psm)) :dbp (-> s5-1 dest 0) :dbw (-> s5-1 width 0))
|
||||
; )
|
||||
; (trxpos (new 'static 'gs-trxpos))
|
||||
; (trxreg (new 'static 'gs-trxreg :rrw (-> s5-1 w) :rrh (-> s5-1 h)))
|
||||
; (trxdir (new 'static 'gs-trxdir))
|
||||
; )
|
||||
; (dma-buffer-add-ref-texture arg0 (the-as pointer (-> s5-1 pad 0)) (-> s5-1 w) (-> s5-1 h) (-> s5-1 psm))
|
||||
|
||||
|
||||
;; PC port of clut upload
|
||||
;;(upload-vram-data arg0 (the-as int (-> s5-1 clutdest)) (the-as pointer (-> s5-1 pad 1)) 16 16)
|
||||
(pc-texture-anim-flag upload-clut-16-16 arg0 :qwc 1)
|
||||
(let ((upload-record (the texture-anim-pc-upload (-> arg0 base))))
|
||||
(set! (-> upload-record data) (the-as pointer (-> s5-1 pad 1))) ;; the clut16x16 object
|
||||
(set! (-> upload-record width) 16)
|
||||
(set! (-> upload-record height) 16)
|
||||
(set! (-> upload-record dest) (-> s5-1 clutdest))
|
||||
(set! (-> upload-record format) (gs-psm ct32))
|
||||
)
|
||||
(&+! (-> arg0 base) 16)
|
||||
(set! (-> *texture-pool* ids (shr (-> s5-1 clutdest) 6)) (the-as uint 0))
|
||||
; (let* ((v1-29 arg0)
|
||||
; (a0-39 (-> v1-29 base))
|
||||
; )
|
||||
; (set! (-> (the-as (pointer int64) a0-39)) #x10000002)
|
||||
; (s.w! (+ a0-39 8) 0)
|
||||
; (let ((a1-52 #x50000002))
|
||||
; (s.w! (+ a0-39 12) a1-52)
|
||||
; )
|
||||
; (set! (-> v1-29 base) (&+ a0-39 16))
|
||||
; )
|
||||
; (let* ((v1-30 arg0)
|
||||
; (a0-41 (-> v1-30 base))
|
||||
; )
|
||||
; (set! (-> (the-as (pointer uint64) a0-41)) (make-u128 0 (the-as uint #x1000000000008001)))
|
||||
; (let ((a1-55 (the-as uint #xeeeeeeeeeeeeeeee)))
|
||||
; (s.d! (+ a0-41 8) a1-55)
|
||||
; )
|
||||
; (set! (-> v1-30 base) (&+ a0-41 16))
|
||||
; )
|
||||
; (let ((v1-31 (-> arg0 base)))
|
||||
; (set! (-> (the-as (pointer int64) v1-31)) 0)
|
||||
; (let ((a0-43 63))
|
||||
; (s.d! (+ v1-31 8) a0-43)
|
||||
; )
|
||||
; (set! (-> arg0 base) (&+ v1-31 16))
|
||||
; )
|
||||
(let ((v1-34 (shr (-> s5-1 dest 0) 6)))
|
||||
(dotimes (a0-44 3)
|
||||
(set! (-> *texture-pool* ids (+ v1-34 a0-44)) (the-as uint 0))
|
||||
)
|
||||
)
|
||||
#f
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun fog-texture-anim-func ((arg0 dma-buffer) (arg1 texture-anim))
|
||||
(real-fog-texture-anim-func arg0 arg1)
|
||||
)
|
||||
|
||||
@@ -11,34 +11,41 @@
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(deftype texture-anim-layer (structure)
|
||||
((extra vector :inline :offset 240)
|
||||
(func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(func-id symbol :overlay-at func)
|
||||
(init-func (function texture-anim-layer int))
|
||||
(init-func-id symbol :overlay-at init-func)
|
||||
(tex texture)
|
||||
(start-time float)
|
||||
(end-time float)
|
||||
(tex-name string)
|
||||
(test gs-test)
|
||||
(alpha gs-alpha)
|
||||
(clamp gs-clamp)
|
||||
(start-color vector :inline :offset 80)
|
||||
(start-scale vector2 :inline :offset 96)
|
||||
(start-offset vector2 :inline :offset 104)
|
||||
(start-st-scale vector2 :inline :offset 112)
|
||||
(start-st-offset vector2 :inline :offset 120)
|
||||
(start-qs vector :inline :offset 128)
|
||||
(start-rot degrees :offset 144)
|
||||
(start-st-rot degrees :offset 148)
|
||||
(end-color vector :inline :offset 160)
|
||||
(end-scale vector2 :inline :offset 176)
|
||||
(end-offset vector2 :inline :offset 184)
|
||||
(end-st-scale vector2 :inline :offset 192)
|
||||
(end-st-offset vector2 :inline :offset 200)
|
||||
(end-qs vector :inline :offset 208)
|
||||
(end-rot degrees :offset 224)
|
||||
(end-st-rot degrees :offset 228)
|
||||
((interpolated-color vector :inline)
|
||||
(interpolated-scale-offset vector :inline)
|
||||
(interpolated-st-scale-offset vector :inline)
|
||||
(interpolated-qs vector :inline)
|
||||
(interpolated-rot vector :inline)
|
||||
(extra vector :inline :offset 240)
|
||||
(func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(func-id symbol :overlay-at func)
|
||||
(init-func (function texture-anim-layer int))
|
||||
(init-func-id symbol :overlay-at init-func)
|
||||
(tex texture)
|
||||
(start-time float)
|
||||
(end-time float)
|
||||
(tex-name string)
|
||||
(test gs-test)
|
||||
(alpha gs-alpha)
|
||||
(clamp gs-clamp)
|
||||
(start-vectors vector 5 :inline :offset 80) ;; added
|
||||
(start-color vector :inline :offset 80)
|
||||
(start-scale vector2 :inline :offset 96)
|
||||
(start-offset vector2 :inline :offset 104)
|
||||
(start-st-scale vector2 :inline :offset 112)
|
||||
(start-st-offset vector2 :inline :offset 120)
|
||||
(start-qs vector :inline :offset 128)
|
||||
(start-rot degrees :offset 144)
|
||||
(start-st-rot degrees :offset 148)
|
||||
(end-vectors vector 5 :inline :offset 160) ;; added
|
||||
(end-color vector :inline :offset 160)
|
||||
(end-scale vector2 :inline :offset 176)
|
||||
(end-offset vector2 :inline :offset 184)
|
||||
(end-st-scale vector2 :inline :offset 192)
|
||||
(end-st-offset vector2 :inline :offset 200)
|
||||
(end-qs vector :inline :offset 208)
|
||||
(end-rot degrees :offset 224)
|
||||
(end-st-rot degrees :offset 228)
|
||||
)
|
||||
(:methods
|
||||
(initialize-texture! (_type_) _type_)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -18,11 +18,11 @@
|
||||
)
|
||||
|
||||
(format #t "skipping init in texture-finish.~%")
|
||||
; (init! *sky-texture-anim-array*)
|
||||
; (init! *darkjak-texture-anim-array*)
|
||||
; (init! *skull-gem-texture-anim-array*)
|
||||
; (init! *default-water-texture-anim-array*)
|
||||
; (init! *default-warp-texture-anim-array*)
|
||||
(init! *sky-texture-anim-array*)
|
||||
(init! *darkjak-texture-anim-array*)
|
||||
(init! *skull-gem-texture-anim-array*)
|
||||
(init! *default-water-texture-anim-array*)
|
||||
(init! *default-warp-texture-anim-array*)
|
||||
|
||||
(kmemclose)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Note that all child classes of this must be 32-bytes."
|
||||
|
||||
(deftype drawable-tree-region-prim (drawable-tree)
|
||||
"Top-level container for all regions of a level."
|
||||
((name basic :offset 8)
|
||||
((name symbol :offset 8)
|
||||
(data2 drawable-inline-array :dynamic :offset 32)
|
||||
)
|
||||
(:methods
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
(local-vars (sv-32 vector2h) (sv-36 vector))
|
||||
(set! sv-32 (new 'stack 'vector2h))
|
||||
(set! sv-36 (-> this bsphere))
|
||||
(add-debug-x #t (bucket-id debug-no-zbuf1) sv-36 (new 'static 'rgba :r #xff :g #xff :a #x80))
|
||||
(add-debug-x #t (bucket-id debug-no-zbuf1) sv-36 (#if PC_PORT (region-enter-color #x80) (new 'static 'rgba :r #xff :g #xff :a #x80)))
|
||||
(when (nonzero? (-> this region))
|
||||
(let ((s5-0 add-debug-text-3d)
|
||||
(s4-0 #t)
|
||||
@@ -202,11 +202,15 @@
|
||||
)
|
||||
|
||||
(defmethod debug-draw-region ((this drawable-region-sphere) (arg0 int))
|
||||
(#when PC_PORT
|
||||
(when (and *debug-region-hide-empty* (not (or (-> this region on-enter) (-> this region on-exit) (-> this region on-inside))))
|
||||
;; no scripts to run means the region is "empty" so do not render (unless enabled)
|
||||
(return 0)))
|
||||
(let ((t9-0 (method-of-type drawable-region-prim debug-draw-region)))
|
||||
(t9-0 this arg0)
|
||||
)
|
||||
(let ((a2-0 (-> this bsphere)))
|
||||
(add-debug-sphere #t (bucket-id debug) a2-0 (-> this bsphere w) (new 'static 'rgba :r #xff :a #x80))
|
||||
(add-debug-sphere #t (bucket-id debug) a2-0 (-> this bsphere w) (#if PC_PORT (region-enter-color #x80) (new 'static 'rgba :r #xff :a #x80)))
|
||||
)
|
||||
0
|
||||
(none)
|
||||
@@ -237,30 +241,32 @@
|
||||
)
|
||||
|
||||
(defmethod debug-draw-region ((this drawable-region-face) (arg0 int))
|
||||
(#when PC_PORT
|
||||
(when (and *debug-region-hide-empty* (not (or (-> this region on-enter) (-> this region on-exit) (-> this region on-inside))))
|
||||
;; no scripts to run means the region is "empty" so do not render (unless enabled)
|
||||
(return 0)))
|
||||
(when (zero? arg0)
|
||||
(let ((t9-0 (method-of-type drawable-region-prim debug-draw-region)))
|
||||
(t9-0 this arg0)
|
||||
)
|
||||
)
|
||||
(let ((s5-0 (-> this bsphere)))
|
||||
(add-debug-vector
|
||||
#t
|
||||
(bucket-id debug-no-zbuf1)
|
||||
s5-0
|
||||
(-> this data normal)
|
||||
(meters 2)
|
||||
(new 'static 'rgba :r #xff :g #xff :a #x80)
|
||||
(#cond
|
||||
(PC_PORT
|
||||
(when *debug-region-show-bsphere*
|
||||
(let ((s5-0 (-> this bsphere)))
|
||||
(add-debug-vector #t (bucket-id debug-no-zbuf1) s5-0 (-> this data normal) (meters 2) (region-enter-color #x80))
|
||||
(add-debug-sphere #t (bucket-id debug) s5-0 (-> this bsphere w) (region-exit-color #x30))
|
||||
)
|
||||
)
|
||||
(add-debug-bound (bucket-id debug) (-> this data points) (the-as int (-> this data num-points)) (region-enter-color #x40) (region-exit-color #x40) 0)
|
||||
)
|
||||
(add-debug-sphere #t (bucket-id debug) s5-0 (-> this bsphere w) (new 'static 'rgba :r #xff :a #x30))
|
||||
)
|
||||
(add-debug-bound
|
||||
(bucket-id debug)
|
||||
(-> this data points)
|
||||
(the-as int (-> this data num-points))
|
||||
(new 'static 'rgba :r #x80 :g #x80 :a #x40)
|
||||
(new 'static 'rgba :r #x80 :a #x40)
|
||||
0
|
||||
)
|
||||
(#t
|
||||
(let ((s5-0 (-> this bsphere)))
|
||||
(add-debug-vector #t (bucket-id debug-no-zbuf1) s5-0 (-> this data normal) (meters 2) (new 'static 'rgba :r #xff :g #xff :a #x80))
|
||||
(add-debug-sphere #t (bucket-id debug) s5-0 (-> this bsphere w) (new 'static 'rgba :r #xff :a #x30))
|
||||
)
|
||||
(add-debug-bound (bucket-id debug) (-> this data points) (the-as int (-> this data num-points)) (new 'static 'rgba :r #x80 :g #x80 :a #x40) (new 'static 'rgba :r #x80 :a #x40) 0)
|
||||
))
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmethod cloth-system-cmd-handler ((this cloth-system) (cmds pair))
|
||||
(format 0 "unimplemented cloth-system-cmd-handler~%")
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmethod init! ((this cloth-base))
|
||||
;; this looks more like run! than init to me.
|
||||
|
||||
@@ -7,3 +7,9 @@
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
(kmemopen global "bigmap")
|
||||
|
||||
;; og:preserve-this
|
||||
(define-perm *bigmap* bigmap #f)
|
||||
|
||||
(kmemclose)
|
||||
@@ -1885,7 +1885,7 @@
|
||||
(while s3-0
|
||||
(let ((s4-0 (-> s3-0 next)))
|
||||
;; og:preserve-this not-yet-implemented check
|
||||
(when (or (and (nonzero? *bigmap*) (bigmap-method-11 *bigmap*)) (not (paused?)))
|
||||
(when (or (and *bigmap* (bigmap-method-11 *bigmap*)) (not (paused?)))
|
||||
(cond
|
||||
((logtest? (-> s3-0 flags) (minimap-flag fade-out))
|
||||
(logclear! (-> s3-0 flags) (minimap-flag fade-in))
|
||||
|
||||
@@ -453,7 +453,7 @@
|
||||
(process-spawn hud-ring-cell 11 (* -1.0 f30-0) 9 :name "hud-ring-cell" :to self)
|
||||
)
|
||||
(clear *stdcon1*)
|
||||
(if (nonzero? *bigmap*)
|
||||
(if *bigmap*
|
||||
(enable-drawing *bigmap*)
|
||||
)
|
||||
(set-setting! 'scanlines 'abs 0.0 0)
|
||||
@@ -505,7 +505,7 @@
|
||||
(set! (-> *progress-work* hero-mode-save) #f)
|
||||
(remove-setting-by-arg0 *setting-control* 'extra-bank)
|
||||
;; og:preserve-this not-yet-implemented check
|
||||
(if (nonzero? *bigmap*) (disable-drawing *bigmap*))
|
||||
(if *bigmap* (disable-drawing *bigmap*))
|
||||
(set-menu-mode *blit-displays-work* #f)
|
||||
(set! *progress-process* (the-as (pointer progress) #f))
|
||||
(enable-level-text-file-loading)
|
||||
@@ -1863,7 +1863,7 @@
|
||||
:virtual #t
|
||||
:code (behavior ()
|
||||
;; og:preserve-this not-yet-implemented check
|
||||
(if (nonzero? *bigmap*) (disable-drawing *bigmap*))
|
||||
(if *bigmap* (disable-drawing *bigmap*))
|
||||
(set-menu-mode *blit-displays-work* #f)
|
||||
(while (or (-> *blit-displays-work* screen-copied) (nonzero? (-> *blit-displays-work* count-down)))
|
||||
(suspend)
|
||||
|
||||
@@ -561,6 +561,9 @@
|
||||
(let ((s5-6 (-> this draw shadow-ctrl)))
|
||||
(when (!= *nav-enemy-dummy-shadow-control* s5-6)
|
||||
(let ((f0-10 (vector-vector-distance (camera-pos) (-> this root trans))))
|
||||
(#when PC_PORT ;; og:preserve-this shadow cull toggle
|
||||
(if (not (-> *pc-settings* ps2-shadow?))
|
||||
(set! f0-10 0.0)))
|
||||
(cond
|
||||
((< 163840.0 f0-10)
|
||||
(logior! (-> s5-6 settings flags) (shadow-flags disable-draw))
|
||||
|
||||
@@ -223,6 +223,10 @@
|
||||
(when (!= *vehicle-shadow-control-disabled* s5-0)
|
||||
(let ((s4-0 (new 'stack-no-clear 'inline-array 'vector 2)))
|
||||
(set! (-> s4-0 0 y) (vector-vector-xz-distance-squared (camera-pos) (-> this root trans)))
|
||||
;; og:preserve-this shadow cull toggle
|
||||
(#when PC_PORT
|
||||
(if (not (-> *pc-settings* ps2-shadow?))
|
||||
(set! (-> s4-0 0 y) 0.0)))
|
||||
(let ((f0-1 245760.0))
|
||||
(cond
|
||||
((< (* f0-1 f0-1) (-> s4-0 0 y))
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
(set! (-> this minimap-temple) #f)
|
||||
)
|
||||
;; og:preserve-this not-yet-implemented check
|
||||
(if (nonzero? *bigmap*) (bigmap-method-16 *bigmap*))
|
||||
(if *bigmap* (bigmap-method-16 *bigmap*))
|
||||
(when (and (not (-> this rod-of-god))
|
||||
; (!= (-> *bigmap* load-index) 18)
|
||||
; (!= (-> *bigmap* load-index) 19)
|
||||
|
||||
@@ -237,9 +237,9 @@
|
||||
))
|
||||
|
||||
(defun custom-level-cgo (output-name desc-file-name)
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_levels/jak3/)"
|
||||
"Add a CGO with the given output name (in $OUT/iso) and input name (in custom_assets/jak3/levels/)"
|
||||
(let ((out-name (string-append "$OUT/iso/" output-name)))
|
||||
(defstep :in (string-append "custom_levels/jak3/" desc-file-name)
|
||||
(defstep :in (string-append "custom_assets/jak3/levels/" desc-file-name)
|
||||
:tool 'dgo
|
||||
:out `(,out-name)
|
||||
)
|
||||
@@ -248,7 +248,7 @@
|
||||
)
|
||||
|
||||
(defmacro build-custom-level (name)
|
||||
(let* ((path (string-append "custom_levels/jak3/" name "/" name ".jsonc")))
|
||||
(let* ((path (string-append "custom_assets/jak3/levels/" name "/" name ".jsonc")))
|
||||
`(defstep :in ,path
|
||||
:tool 'build-level3
|
||||
:out '(,(string-append "$OUT/obj/" name ".go")))))
|
||||
@@ -179,6 +179,61 @@
|
||||
0)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; region debugging
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
|
||||
(define *debug-region-tree-name* #f)
|
||||
(define *debug-region-show-bsphere* #f)
|
||||
(define *debug-region-hide-water* #t)
|
||||
(define *debug-region-hide-empty* #t)
|
||||
|
||||
(deftype debug-region-color (structure)
|
||||
((enter rgba)
|
||||
(exit rgba))
|
||||
)
|
||||
|
||||
(define *debug-region-color-table* (new 'static 'inline-array debug-region-color 3
|
||||
(new 'static 'debug-region-color :enter (static-rgba #xff #xff #x00 #x80) :exit (static-rgba #xff #x00 #x00 #x80))
|
||||
(new 'static 'debug-region-color :enter (static-rgba #x00 #xff #x00 #x80) :exit (static-rgba #xff #x00 #xff #x80))
|
||||
(new 'static 'debug-region-color :enter (static-rgba #x00 #xff #xff #x80) :exit (static-rgba #x00 #x00 #xff #x80))
|
||||
))
|
||||
|
||||
|
||||
(defmacro rgba-with-a (color a)
|
||||
"return a color but with alpha set to a"
|
||||
`(begin
|
||||
(let ((newcol ,color))
|
||||
(set! (-> newcol a) ,a)
|
||||
newcol)))
|
||||
|
||||
(defun-debug get-region-enter-color ((name symbol) (alpha int))
|
||||
(rgba-with-a (case name
|
||||
(('target) (-> *debug-region-color-table* 0 enter))
|
||||
(('camera) (-> *debug-region-color-table* 1 enter))
|
||||
(('water) (-> *debug-region-color-table* 2 enter))
|
||||
(else (-> *debug-region-color-table* 0 enter)))
|
||||
alpha))
|
||||
|
||||
(defun-debug get-region-exit-color ((name symbol) (alpha int))
|
||||
(rgba-with-a (case name
|
||||
(('target) (-> *debug-region-color-table* 0 exit))
|
||||
(('camera) (-> *debug-region-color-table* 1 exit))
|
||||
(('water) (-> *debug-region-color-table* 2 exit))
|
||||
(else (-> *debug-region-color-table* 0 exit)))
|
||||
alpha))
|
||||
|
||||
(defmacro region-enter-color (alpha)
|
||||
"return color for the enter side of this region"
|
||||
`(get-region-enter-color *debug-region-tree-name* ,alpha))
|
||||
(defmacro region-exit-color (alpha)
|
||||
"return color for the exit side of this region"
|
||||
`(get-region-exit-color *debug-region-tree-name* ,alpha))
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; other
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -186,10 +241,6 @@
|
||||
|
||||
|
||||
(define *hires-sky* #t)
|
||||
(define *debug-region-color-alt* #t)
|
||||
(define *debug-region-show-bsphere* #f)
|
||||
(define *debug-region-hide-water* #t)
|
||||
(define *debug-region-hide-empty* #t)
|
||||
(define *fallback-text-lookup?* #t)
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ add_library(compiler
|
||||
emitter/Register.cpp
|
||||
debugger/disassemble.cpp
|
||||
build_level/common/build_level.cpp
|
||||
build_actor/common/MercExtract.cpp
|
||||
build_level/jak1/build_level.cpp
|
||||
build_level/jak2/build_level.cpp
|
||||
build_level/jak3/build_level.cpp
|
||||
@@ -57,6 +58,7 @@ add_library(compiler
|
||||
data_compiler/dir_tpages.cpp
|
||||
data_compiler/game_count.cpp
|
||||
data_compiler/DataObjectGenerator.cpp
|
||||
build_actor/jak1/build_actor.cpp
|
||||
debugger/Debugger.cpp
|
||||
debugger/DebugInfo.cpp
|
||||
listener/Listener.cpp
|
||||
@@ -80,8 +82,9 @@ add_executable(goalc main.cpp)
|
||||
add_executable(goalc-simple simple_main.cpp)
|
||||
|
||||
add_executable(build_level build_level/main.cpp)
|
||||
add_executable(build_actor build_actor/main.cpp)
|
||||
|
||||
target_link_libraries(goalc common Zydis compiler)
|
||||
target_link_libraries(goalc-simple common Zydis compiler)
|
||||
target_link_libraries(build_level common Zydis compiler)
|
||||
|
||||
target_link_libraries(build_actor common Zydis compiler)
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
#include "MercExtract.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
void extract(const std::string& name,
|
||||
MercExtractData& out,
|
||||
const tinygltf::Model& model,
|
||||
const std::vector<gltf_util::NodeWithTransform>& all_nodes,
|
||||
u32 index_offset,
|
||||
u32 vertex_offset,
|
||||
u32 tex_offset) {
|
||||
ASSERT(out.new_vertices.empty());
|
||||
|
||||
std::map<int, tfrag3::MercDraw> draw_by_material;
|
||||
int mesh_count = 0;
|
||||
int prim_count = 0;
|
||||
|
||||
for (const auto& n : all_nodes) {
|
||||
const auto& node = model.nodes[n.node_idx];
|
||||
if (node.mesh >= 0) {
|
||||
const auto& mesh = model.meshes[node.mesh];
|
||||
mesh_count++;
|
||||
for (const auto& prim : mesh.primitives) {
|
||||
prim_count++;
|
||||
// extract index buffer
|
||||
std::vector<u32> prim_indices = gltf_util::gltf_index_buffer(
|
||||
model, prim.indices, out.new_vertices.size() + vertex_offset);
|
||||
ASSERT_MSG(prim.mode == TINYGLTF_MODE_TRIANGLES, "Unsupported triangle mode");
|
||||
// extract vertices
|
||||
auto verts =
|
||||
gltf_util::gltf_vertices(model, prim.attributes, n.w_T_node, true, true, mesh.name);
|
||||
out.new_vertices.insert(out.new_vertices.end(), verts.vtx.begin(), verts.vtx.end());
|
||||
out.new_colors.insert(out.new_colors.end(), verts.vtx_colors.begin(),
|
||||
verts.vtx_colors.end());
|
||||
out.normals.insert(out.normals.end(), verts.normals.begin(), verts.normals.end());
|
||||
ASSERT(out.new_colors.size() == out.new_vertices.size());
|
||||
|
||||
// TODO: just putting it all in one material
|
||||
auto& draw = draw_by_material[prim.material];
|
||||
draw.mode = gltf_util::make_default_draw_mode(); // todo rm
|
||||
draw.tree_tex_id = 0; // todo rm
|
||||
draw.num_triangles += prim_indices.size() / 3;
|
||||
// if (draw.vis_groups.empty()) {
|
||||
// auto& grp = draw.vis_groups.emplace_back();
|
||||
// grp.num_inds += prim_indices.size();
|
||||
// grp.num_tris += draw.num_triangles;
|
||||
// grp.vis_idx_in_pc_bvh = UINT32_MAX;
|
||||
// } else {
|
||||
// auto& grp = draw.vis_groups.back();
|
||||
// grp.num_inds += prim_indices.size();
|
||||
// grp.num_tris += draw.num_triangles;
|
||||
// grp.vis_idx_in_pc_bvh = UINT32_MAX;
|
||||
// }
|
||||
draw.index_count = prim_indices.size();
|
||||
draw.first_index = index_offset + out.new_indices.size();
|
||||
|
||||
out.new_indices.insert(out.new_indices.end(), prim_indices.begin(), prim_indices.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tfrag3::MercEffect e;
|
||||
out.new_model.name = name;
|
||||
out.new_model.max_bones = 120; // idk
|
||||
out.new_model.max_draws = 200;
|
||||
for (const auto& [mat_idx, d_] : draw_by_material) {
|
||||
e.all_draws.push_back(d_);
|
||||
auto& draw = e.all_draws.back();
|
||||
draw.mode = gltf_util::make_default_draw_mode();
|
||||
|
||||
if (mat_idx == -1) {
|
||||
lg::warn("Draw had a material index of -1, using default texture.");
|
||||
draw.tree_tex_id = 0;
|
||||
continue;
|
||||
}
|
||||
const auto& mat = model.materials[mat_idx];
|
||||
int tex_idx = mat.pbrMetallicRoughness.baseColorTexture.index;
|
||||
if (tex_idx == -1) {
|
||||
lg::warn("Material {} has no texture, using default texture.", mat.name);
|
||||
draw.tree_tex_id = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& tex = model.textures[tex_idx];
|
||||
ASSERT(tex.sampler >= 0);
|
||||
ASSERT(tex.source >= 0);
|
||||
draw.mode = gltf_util::draw_mode_from_sampler(model.samplers.at(tex.sampler));
|
||||
|
||||
const auto& img = model.images[tex.source];
|
||||
draw.tree_tex_id = tex_offset + texture_pool_add_texture(&out.tex_pool, img);
|
||||
}
|
||||
lg::info("total of {} unique materials", e.all_draws.size());
|
||||
out.new_model.effects.push_back(e);
|
||||
out.new_model.effects.push_back(e);
|
||||
out.new_model.effects.push_back(e);
|
||||
out.new_model.effects.push_back(e);
|
||||
|
||||
lg::info("Merged {} meshes and {} prims into {} vertices", mesh_count, prim_count,
|
||||
out.new_vertices.size());
|
||||
}
|
||||
|
||||
void merc_convert(MercSwapData& out, const MercExtractData& in) {
|
||||
// easy
|
||||
out.new_model = in.new_model;
|
||||
out.new_indices = in.new_indices;
|
||||
out.new_textures = in.tex_pool.textures_by_idx;
|
||||
|
||||
// convert vertices
|
||||
for (size_t i = 0; i < in.new_vertices.size(); i++) {
|
||||
const auto& y = in.new_vertices[i];
|
||||
auto& x = out.new_vertices.emplace_back();
|
||||
x.pos[0] = y.x;
|
||||
x.pos[1] = y.y;
|
||||
x.pos[2] = y.z;
|
||||
x.normal[0] = in.normals.at(i).x();
|
||||
x.normal[1] = in.normals.at(i).y();
|
||||
x.normal[2] = in.normals.at(i).z();
|
||||
x.weights[0] = 1.0f;
|
||||
x.weights[1] = 0.0f;
|
||||
x.weights[2] = 0.0f;
|
||||
x.st[0] = y.s;
|
||||
x.st[1] = y.t;
|
||||
x.rgba[0] = in.new_colors[i][0];
|
||||
x.rgba[1] = in.new_colors[i][1];
|
||||
x.rgba[2] = in.new_colors[i][2];
|
||||
x.rgba[3] = in.new_colors[i][3];
|
||||
x.mats[0] = 3;
|
||||
x.mats[1] = 0;
|
||||
x.mats[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MercSwapData load_merc_model(u32 current_idx_count,
|
||||
u32 current_vtx_count,
|
||||
u32 current_tex_count,
|
||||
const std::string& path,
|
||||
const std::string& name) {
|
||||
MercSwapData result;
|
||||
lg::info("Reading gltf mesh: {}", path);
|
||||
tinygltf::TinyGLTF loader;
|
||||
tinygltf::Model model;
|
||||
std::string err, warn;
|
||||
bool res = loader.LoadBinaryFromFile(&model, &err, &warn, path);
|
||||
ASSERT_MSG(warn.empty(), warn.c_str());
|
||||
ASSERT_MSG(err.empty(), err.c_str());
|
||||
ASSERT_MSG(res, "Failed to load GLTF file!");
|
||||
auto all_nodes = gltf_util::flatten_nodes_from_all_scenes(model);
|
||||
|
||||
MercExtractData extract_data;
|
||||
extract(name, extract_data, model, all_nodes, current_idx_count, current_vtx_count,
|
||||
current_tex_count);
|
||||
merc_convert(result, extract_data);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/util/gltf_util.h"
|
||||
|
||||
struct MercExtractData {
|
||||
gltf_util::TexturePool tex_pool;
|
||||
std::vector<u32> new_indices;
|
||||
std::vector<tfrag3::PreloadedVertex> new_vertices;
|
||||
std::vector<math::Vector<u8, 4>> new_colors;
|
||||
std::vector<math::Vector3f> normals;
|
||||
|
||||
tfrag3::MercModel new_model;
|
||||
};
|
||||
|
||||
// Data produced by loading a replacement model
|
||||
struct MercSwapData {
|
||||
std::vector<u32> new_indices;
|
||||
std::vector<tfrag3::MercVertex> new_vertices;
|
||||
std::vector<tfrag3::Texture> new_textures;
|
||||
tfrag3::MercModel new_model;
|
||||
};
|
||||
|
||||
void extract(const std::string& name,
|
||||
MercExtractData& out,
|
||||
const tinygltf::Model& model,
|
||||
const std::vector<gltf_util::NodeWithTransform>& all_nodes,
|
||||
u32 index_offset,
|
||||
u32 vertex_offset,
|
||||
u32 tex_offset);
|
||||
void merc_convert(MercSwapData& out, const MercExtractData& in);
|
||||
MercSwapData load_merc_model(u32 current_idx_count,
|
||||
u32 current_vtx_count,
|
||||
u32 current_tex_count,
|
||||
const std::string& path,
|
||||
const std::string& name);
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
|
||||
#include "decompiler/level_extractor/MercData.h"
|
||||
#include "decompiler/level_extractor/common_formats.h"
|
||||
#include "goalc/build_level/common/Entity.h"
|
||||
#include "goalc/build_level/common/FileInfo.h"
|
||||
#include "goalc/data_compiler/DataObjectGenerator.h"
|
||||
|
||||
struct Art {
|
||||
std::string name;
|
||||
s32 length;
|
||||
ResLump lump;
|
||||
};
|
||||
|
||||
struct ArtElement : Art {
|
||||
u8 pad[12];
|
||||
};
|
||||
|
||||
struct MercEyeAnimFrame {
|
||||
s8 pupil_trans_x;
|
||||
s8 pupil_trans_y;
|
||||
s8 blink;
|
||||
s8 iris_scale;
|
||||
s8 pupil_scale;
|
||||
s8 lid_scale;
|
||||
};
|
||||
|
||||
struct MercEyeAnimBlock {
|
||||
s16 max_frame;
|
||||
std::vector<MercEyeAnimFrame> frames;
|
||||
};
|
||||
@@ -0,0 +1,445 @@
|
||||
#include "build_actor.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
#include "third-party/tiny_gltf/tiny_gltf.h"
|
||||
|
||||
using namespace gltf_util;
|
||||
namespace jak1 {
|
||||
|
||||
std::map<int, size_t> g_joint_map;
|
||||
|
||||
size_t Joint::generate(DataObjectGenerator& gen) const {
|
||||
gen.align_to_basic();
|
||||
gen.add_type_tag("joint");
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_ref_to_string_in_pool(name);
|
||||
gen.add_word(number);
|
||||
if (parent == -1) {
|
||||
gen.add_symbol_link("#f");
|
||||
} else {
|
||||
gen.link_word_to_byte(gen.add_word(0), g_joint_map[parent]);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
gen.add_word_float(bind_pose(i, j));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t JointAnimCompressed::generate(DataObjectGenerator& gen) const {
|
||||
gen.align_to_basic();
|
||||
gen.add_type_tag("joint-anim-compressed");
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_ref_to_string_in_pool(name);
|
||||
gen.add_word((length << 16) + number);
|
||||
// for (auto& word : data) {
|
||||
// gen.add_word(word);
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t JointAnimCompressedFrame::generate(DataObjectGenerator& gen) const {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_word(offset_64); // 0
|
||||
gen.add_word(offset_32); // 4
|
||||
gen.add_word(offset_16); // 8
|
||||
gen.add_word(reserved); // 12
|
||||
gen.align(4);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t JointAnimCompressedHDR::generate(DataObjectGenerator& gen) const {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
for (auto& bit : control_bits) {
|
||||
gen.add_word(bit);
|
||||
}
|
||||
gen.add_word(num_joints);
|
||||
gen.add_word(matrix_bits);
|
||||
gen.align(4);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t JointAnimCompressedFixed::generate(DataObjectGenerator& gen) const {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
hdr.generate(gen); // 0-64 (inline)
|
||||
gen.add_word(offset_64); // 64
|
||||
gen.add_word(offset_32); // 68
|
||||
gen.add_word(offset_16); // 72
|
||||
gen.add_word(reserved); // 76
|
||||
// default joint poses (taken from money-idle)
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
gen.add_word_float(data[i].x());
|
||||
gen.add_word_float(data[i].y());
|
||||
gen.add_word_float(data[i].z());
|
||||
gen.add_word_float(data[i].w());
|
||||
}
|
||||
gen.add_word(0);
|
||||
gen.add_word(0x7fff0000);
|
||||
gen.add_word(0x2250000);
|
||||
gen.add_word(0x10001000);
|
||||
gen.add_word(0x10000000);
|
||||
gen.add_word(0);
|
||||
gen.add_word(0);
|
||||
gen.add_word(0);
|
||||
gen.align(4);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t JointAnimCompressedControl::generate(DataObjectGenerator& gen) const {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_word(num_frames); // 0
|
||||
gen.add_word(fixed_qwc); // 4
|
||||
gen.add_word(frame_qwc); // 8
|
||||
|
||||
auto ja_fixed_slot = gen.add_word(0);
|
||||
auto ja_frame_slot = gen.add_word(0);
|
||||
gen.align(4);
|
||||
gen.link_word_to_byte(ja_fixed_slot, fixed.generate(gen));
|
||||
gen.link_word_to_byte(ja_frame_slot, frame[0].generate(gen));
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t ArtJointGeo::generate_res_lump(DataObjectGenerator& gen) const {
|
||||
gen.align_to_basic();
|
||||
gen.add_type_tag("res-lump");
|
||||
size_t result = gen.current_offset_bytes();
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t ArtJointGeo::generate(DataObjectGenerator& gen) const {
|
||||
gen.align_to_basic();
|
||||
gen.add_type_tag("art-joint-geo");
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_word(0); // 4
|
||||
gen.add_ref_to_string_in_pool(name); // 8
|
||||
gen.add_word(length); // 12
|
||||
auto res_slot = gen.add_word(0); // 16 (res-lump)
|
||||
gen.add_word(0); // 20
|
||||
gen.add_word(0);
|
||||
gen.add_word(0);
|
||||
std::vector<size_t> joint_slots;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
joint_slots.push_back(gen.add_word(0));
|
||||
}
|
||||
gen.align(4);
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
auto joint = data.at(i).generate(gen);
|
||||
gen.link_word_to_byte(joint_slots.at(i), joint);
|
||||
g_joint_map[data.at(i).number] = joint;
|
||||
}
|
||||
auto res_header = lump.generate_header(gen, "res-lump");
|
||||
gen.link_word_to_byte(res_slot, res_header);
|
||||
lump.generate_tag_list_and_data(gen, res_header);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t ArtJointAnim::generate(DataObjectGenerator& gen) const {
|
||||
gen.align_to_basic();
|
||||
gen.add_type_tag("art-joint-anim");
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_symbol_link("#f"); // 4 (eye block)
|
||||
gen.add_ref_to_string_in_pool(name); // 8
|
||||
gen.add_word(length); // 12
|
||||
gen.add_symbol_link("#f"); // 16 (res-lump)
|
||||
gen.add_word_float(speed); // 20
|
||||
gen.add_word_float(artist_base); // 24
|
||||
gen.add_word_float(artist_step); // 28
|
||||
gen.add_ref_to_string_in_pool(master_art_group_name); // 32
|
||||
gen.add_word(master_art_group_index); // 36
|
||||
gen.add_symbol_link("#f"); // 40 (blerc)
|
||||
auto ctrl_slot = gen.add_word(0);
|
||||
std::vector<size_t> frame_slots;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
frame_slots.push_back(gen.add_word(0));
|
||||
}
|
||||
gen.align(4);
|
||||
gen.link_word_to_byte(ctrl_slot, frames.generate(gen));
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
gen.link_word_to_byte(frame_slots.at(i), data.at(i).generate(gen));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static size_t gen_dummy_frag_geo(DataObjectGenerator& gen) {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
// frag geo stolen from money-lod0
|
||||
static std::vector<u32> words = {
|
||||
0xa4320c04, 0x8000026, 0x302a0000, 0x604, 0xa910, 0xac16, 0x100af1c,
|
||||
0xb23d, 0x100b585, 0x100b870, 0xbb76, 0xbe52, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x0, 0x0, 0x89b78086, 0xf1a910a, 0x3a4b7000, 0x5f818086,
|
||||
0xf1a1094, 0x29347014, 0x49648186, 0x91313, 0x4e5d8024, 0x354b8186, 0xf1a6416,
|
||||
0x3a497024, 0x40538186, 0x91919, 0x647b8034, 0x24348186, 0xf1a371c, 0x647f7034,
|
||||
0x495d8186, 0x91f1f, 0x7a9c8044, 0x35498086, 0xf1a2231, 0x8eb57044, 0x5f7b8186,
|
||||
0x92525, 0x83ad8054, 0x5f7f8186, 0xf1a2828, 0x9fcc7054, 0x759c8186, 0x92b2b,
|
||||
0x7aa38064, 0x1c257f86, 0x273b2e2e, 0x94b86040, 0xe198186, 0x2737d034, 0x71936038,
|
||||
0xe188186, 0x273bcd3a, 0x57676030, 0x1c2a8186, 0x2737613d, 0x34456028, 0xe1b8086,
|
||||
0x485d40c7, 0x2e3c5028, 0x293c8186, 0x485d5b43, 0x131a5020, 0x26398186, 0x6e804646,
|
||||
0xf164020, 0x4b688186, 0x6e805549, 0x34018, 0x4c688186, 0x979f4c4c, 0x5073018,
|
||||
0x72978086, 0x979f4fc1, 0x5073010, 0x73988086, 0x6e807352, 0x34010, 0x4c698186,
|
||||
0x485d6d58, 0x5085018, 0x2f488086, 0x273b5e67, 0x21256020, 0x526d8186, 0x2737a66a,
|
||||
0x13196018, 0x72988186, 0x485da070, 0x5085010, 0x98c78086, 0x6e80767f, 0xf164008,
|
||||
0x95c48186, 0x979fc479, 0x13193008, 0xb0e68186, 0x979f7c7c, 0x2e3b3000, 0xb4ea8186,
|
||||
0x6e808282, 0x2b394000, 0x95c48186, 0x485d9d85, 0x131b5008, 0xb0e68186, 0x485d8888,
|
||||
0x2e3c5000, 0x8fbb8186, 0x2737978b, 0x212a6008, 0xa2db8186, 0x273b8e8e, 0x34486000,
|
||||
0x6c998086, 0x273b9aa3, 0x13186010, 0x87f86, 0x485dcaca, 0x51685030, 0x75a37f86,
|
||||
0x90707, 0x4e648000, 0x5f858186, 0x90d0d, 0x45538014, 0x0, 0x0,
|
||||
0xcb01005f, 0xcb00fffa, 0xcb010064, 0x5101e01, 0x0, 0x0, 0x306,
|
||||
0x60030000, 0x120, 0x0, 0x1cf02c14, 0x2008044, 0x0, 0x0,
|
||||
0x34, 0x81010000, 0x0, 0x0, 0x8, 0x6d100000, 0x44,
|
||||
0x80, 0x42, 0x30000, 0x86321604, 0x400001c, 0x2422440e, 0x4,
|
||||
0x1004f28, 0x1008b4c, 0xb225, 0xca4c, 0x1000128, 0x1000422, 0x1000a2e,
|
||||
0x10064ca, 0x6a34, 0x1006d2e, 0x70ca, 0x1007340, 0x7946, 0x7f4c,
|
||||
0x100884c, 0x8e4f, 0x9479, 0x9a7c, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x0, 0x0, 0x131a8086,
|
||||
0x215d0d9d, 0x87c45040, 0x38186, 0x4780a313, 0x65984038, 0x38186, 0x47806116,
|
||||
0x3d684030, 0x5078186, 0x709fa919, 0x3e693030, 0x13198186, 0x709f5b1c, 0x1b3c3028,
|
||||
0x21208186, 0x96bbaf1f, 0x21452028, 0x34428186, 0x96bf5522, 0xe242020, 0x3a408086,
|
||||
0xb6da252e, 0x27411024, 0x647f8186, 0xb6da4628, 0x16261014, 0x647a8186, 0xcbf1402b,
|
||||
0x32450014, 0x4e528086, 0xcbf1313a, 0x3b5b0024, 0x29268086, 0xb6da34b5, 0x51811034,
|
||||
0x45458186, 0xcbf13737, 0x51860034, 0x64808186, 0xd3ff3d3d, 0x51800040, 0x7aa58186,
|
||||
0xcbf14343, 0x3b520000, 0x8ebf8186, 0xb6dac749, 0x27401000, 0x71948186, 0x96bf854c,
|
||||
0x132010, 0x57668186, 0x96bb8252, 0x122018, 0x2e3b8186, 0x709f7c58, 0x1a3020,
|
||||
0xf168186, 0x4780765e, 0x18394028, 0x94bb8086, 0x96bb91c4, 0xe202008, 0xa7dc8086,
|
||||
0x96bf97c1, 0x21422000, 0xf167f86, 0x4780a0a0, 0x8ac74040, 0x5078186, 0x709fbea6,
|
||||
0x64983038, 0x13138186, 0x96bfb8ac, 0x446c2030, 0x13128186, 0x96bbbbbb, 0x5e9a2038,
|
||||
0x34458186, 0x370707, 0x94d66048, 0x5088186, 0x215d6710, 0x64975038, 0xcb010064,
|
||||
0xcb00ffd3, 0xcb010051, 0x5021000, 0x4088003, 0x10306060, 0x3, 0x0,
|
||||
0x8d301104, 0x300001f, 0x2624430a, 0x4, 0x910a, 0x100a928, 0xc42b,
|
||||
0x1006aa0, 0x70a6, 0x73bb, 0x9a07, 0xa00d, 0x100a3a0, 0x100a6bb,
|
||||
0xac34, 0xb237, 0xb83d, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x8ccc8186,
|
||||
0xf1a4c07, 0x16817074, 0x7bb58186, 0xf1a550a, 0x40b77064, 0x94d68186, 0x2737460d,
|
||||
0x46bb6068, 0x81b88186, 0x273b8e10, 0x59db6060, 0x87c48186, 0x485d4013, 0x67e65060,
|
||||
0x64978186, 0x485d8816, 0x75f85058, 0x65988186, 0x6e803a19, 0x7afd4058, 0x3d688186,
|
||||
0x6e80821c, 0x7afd4050, 0x3e698186, 0x979f341f, 0x75f93050, 0x1b3c8186, 0x979f7c22,
|
||||
0x67e73048, 0x21458086, 0xbdbb252e, 0x59e02048, 0xe248086, 0xbdbf2876, 0x46be2040,
|
||||
0x27418186, 0xdddaaf2b, 0x40c01044, 0x446c8186, 0xbdbfc731, 0x67ed2050, 0x64988186,
|
||||
0x979f3737, 0x75f93058, 0x8ac78186, 0x6e803d3d, 0x6bea4060, 0xa2e58186, 0x485d4343,
|
||||
0x4cc45068, 0xa2e88186, 0x273b4949, 0x23996070, 0x679c7f86, 0x95252, 0x2ca38064,
|
||||
0x517f8086, 0xf1a5894, 0x51cc7054, 0x5e938186, 0x27378b5b, 0x67e76058, 0x44678086,
|
||||
0x273b5e97, 0x67e86050, 0x3e688186, 0x485d8561, 0x75f85050, 0x1b3c8186, 0x485d9d64,
|
||||
0x67e55048, 0x18398186, 0x6e807f67, 0x6bea4048, 0x1a8186, 0x979f796d, 0x4cc53040,
|
||||
0x3b5b8086, 0xf2f1b5be, 0x2cae0044, 0x51868186, 0xf2f1bbbb, 0x35bb0054, 0x51818186,
|
||||
0xdddac1c1, 0x51da1054, 0x67a37f86, 0x90101, 0x648080, 0x70ad7f86, 0x94f04,
|
||||
0x16858074, 0x0, 0x0, 0x0, 0xcb010051, 0xcb00fffa, 0xcb010016,
|
||||
0x5021000, 0xc008003, 0x81860080, 0x0, 0x0, 0x92351604, 0x300001f,
|
||||
0x2826450f, 0x4, 0xac31, 0x100af5e, 0x100c449, 0xa01, 0x1000d07,
|
||||
0x6143, 0x100643d, 0x10079c1, 0x8537, 0x883d, 0x1008b07, 0x1008e49,
|
||||
0x100b243, 0xb549, 0x100b837, 0xbe31, 0xc1c1, 0xc7bb, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x0, 0x0, 0x0, 0x808186, 0x707,
|
||||
0x39800040, 0x2ab78186, 0x141a1010, 0xf4b7080, 0x51e78186, 0x2c379113, 0x2c6d6078,
|
||||
0x43db8186, 0x2c3b1616, 0x9486080, 0x5ff88186, 0x4d5d9719, 0x26695078, 0x51e68186,
|
||||
0x4d5d1c1c, 0x33c5080, 0x64fd8186, 0x73809d1f, 0x25684078, 0x55ea8186, 0x73802222,
|
||||
0x394080, 0x5ff98186, 0x9c9fa325, 0x26683078, 0x51e68186, 0x9c9f2828, 0x33b3080,
|
||||
0x51ee8186, 0xc2bba92b, 0x2c662078, 0x43dc8186, 0xc2bf2e2e, 0x9422080, 0x3bda8186,
|
||||
0xe2da4631, 0x397f1074, 0x2abf8186, 0xe2da3434, 0xf401080, 0x1fbb8086, 0xf7f13740,
|
||||
0x397a0074, 0x16a58186, 0xf7f13a3a, 0x23520080, 0x808186, 0xffffcd3d, 0x39800040,
|
||||
0x16ae8186, 0xf7f1ca43, 0x4fa50064, 0x2ac08186, 0xe2da7649, 0x63bf1064, 0x51ed8186,
|
||||
0xc2bfa64c, 0x46942070, 0x43e08186, 0xc2bb734f, 0x69bb2068, 0x5ff98186, 0x9c9fa052,
|
||||
0x4c973070, 0x51e78186, 0x9c9f6d55, 0x6fc43068, 0x64fd8186, 0x73809a58, 0x4d984070,
|
||||
0x55ea8186, 0x7380675b, 0x72c74068, 0x5ff88186, 0x4d5d945e, 0x4c985070, 0x36c58186,
|
||||
0x9c9f826a, 0x8ae63060, 0x30be8186, 0xc2bf7c70, 0x7cdc2060, 0xd9a8086, 0xc2bb7fbb,
|
||||
0x8aee2058, 0x16a37f86, 0x5090101, 0x23640000, 0x1fad7f86, 0x5090404, 0x39850074,
|
||||
0x0, 0x0, 0x0, 0xcb010000, 0xcb00ffff, 0xcb010039, 0x5021000,
|
||||
0x20001b, 0x6c00c102, 0x2, 0x0, 0x210f0904, 0x6, 0xb090b05,
|
||||
0x4, 0x101, 0x707, 0x1307, 0x1c04, 0x1f07, 0x80808080,
|
||||
0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x80808080, 0x0, 0x538186,
|
||||
0x90d0d, 0x1f7b0034, 0x95d7f86, 0x91010, 0x359c0044, 0x1f7b8186, 0x91616,
|
||||
0x3ead0054, 0x359c8186, 0x91919, 0x35a30064, 0x1f857f86, 0x90404, 0x530014,
|
||||
0x9648186, 0x90a0a, 0x95d0024, 0x0, 0x0, 0xcb01001f, 0xcb00fffa,
|
||||
0xcb01001f, 0x1021000, 0x223, 0x0, 0x0, 0x0};
|
||||
for (auto& word : words) {
|
||||
gen.add_word(word);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t gen_dummy_frag_ctrl(DataObjectGenerator& gen) {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_word(0x1067232);
|
||||
gen.add_word(0x54320603);
|
||||
gen.add_word(0x5d300002);
|
||||
gen.add_word(0x5d350002);
|
||||
gen.add_word(0x120f0002);
|
||||
gen.add_word(0x2);
|
||||
gen.add_word(0x0);
|
||||
gen.add_word(0x0);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t gen_dummy_extra_info(DataObjectGenerator& gen) {
|
||||
size_t result = gen.current_offset_bytes();
|
||||
gen.add_word(0x1);
|
||||
gen.add_word(0x0);
|
||||
gen.add_word(0x0);
|
||||
gen.add_word(0x0);
|
||||
gen.add_word(0xb74ccccd);
|
||||
gen.add_word(0x40400000);
|
||||
gen.add_word(0x8066a1ff);
|
||||
gen.add_word(0x0);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t generate_dummy_merc_ctrl(DataObjectGenerator& gen, const ArtGroup& ag) {
|
||||
gen.align_to_basic();
|
||||
gen.add_type_tag("merc-ctrl");
|
||||
size_t result = gen.current_offset_bytes();
|
||||
// excluding align and prejoint
|
||||
auto joints = ((ArtJointGeo*)ag.elts.at(0))->length - 2;
|
||||
gen.add_word(0); // 4
|
||||
gen.add_ref_to_string_in_pool(ag.name + "-lod0"); // 8
|
||||
gen.add_word(0); // 12
|
||||
gen.add_symbol_link("#f"); // 16 (res-lump)
|
||||
gen.add_word(joints); // 20 (num-joints)
|
||||
gen.add_word(0x0); // 24 (pad)
|
||||
gen.add_word(0x0); // 28 (pad)
|
||||
gen.add_word(0x4188ee86); // 32-112 (xyz-scale)
|
||||
gen.add_word(0xc780ff80); // 36 (st-magic)
|
||||
gen.add_word(0x40798000); // 40 (st-out-a)
|
||||
gen.add_word(0x40eb4000); // 44 (st-out-b)
|
||||
gen.add_word(0x4780ff80); // 48 (st-vif-add)
|
||||
gen.add_word(0x50000); // 52 ((st-int-off << 16) + st-int-scale)
|
||||
gen.add_word(0x1); // 56 (effect-count)
|
||||
gen.add_word(0x0); // 60 (blend-target-count)
|
||||
gen.add_word(0xe00005); // 64 ((fragment-count << 16) + tri-count)
|
||||
gen.add_word(0x860101); // 68
|
||||
gen.add_word(0x86011b); // 72
|
||||
gen.add_word(0x0); // 76
|
||||
gen.add_word(0x0); // 80
|
||||
gen.add_word(0x120101); // 84
|
||||
gen.add_word(0x83002c); // 88
|
||||
gen.add_word(0x3e780184); // 92
|
||||
gen.add_word(0x0); // 96
|
||||
gen.add_word(0x0); // 100
|
||||
gen.add_word(0x0); // 104
|
||||
gen.add_word(0x0); // 108
|
||||
auto frag_geo_slot = gen.add_word(0); // 112-140 (effect)
|
||||
auto frag_ctrl_slot = gen.add_word(0); // 116 (frag-ctrl)
|
||||
gen.add_word(0x0); // 120 (blend-data)
|
||||
gen.add_word(0x0); // 124 (blend-ctrl)
|
||||
gen.add_word(0x50000); // 128
|
||||
gen.add_word(0xe00000); // 132
|
||||
gen.add_word(0x100011b); // 136
|
||||
auto extra_info_slot = gen.add_word(0); // 140 (extra-info)
|
||||
gen.link_word_to_byte(extra_info_slot, gen_dummy_extra_info(gen));
|
||||
gen.link_word_to_byte(frag_ctrl_slot, gen_dummy_frag_ctrl(gen));
|
||||
gen.link_word_to_byte(frag_geo_slot, gen_dummy_frag_geo(gen));
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<u8> ArtGroup::save_object_file() const {
|
||||
DataObjectGenerator gen;
|
||||
gen.add_type_tag("art-group");
|
||||
auto ag_words = 8 + length;
|
||||
while (gen.words() < ag_words) {
|
||||
gen.add_word(0);
|
||||
}
|
||||
auto file_info_slot = info.add_to_object_file(gen);
|
||||
gen.link_word_to_byte(1, file_info_slot); // 4 (file-info)
|
||||
gen.link_word_to_string_in_pool(name, 8 / 4); // 8 (name)
|
||||
gen.set_word(12 / 4, length); // 12 (ag length)
|
||||
gen.link_word_to_symbol("#f", 16 / 4); // 16 (res-lump)
|
||||
gen.set_word(20 / 4, 0); // 20 (pad)
|
||||
gen.set_word(24 / 4, 0);
|
||||
gen.set_word(28 / 4, 0);
|
||||
if (!elts.empty()) {
|
||||
if (elts.at(0)) {
|
||||
auto jgeo = (ArtJointGeo*)elts.at(0);
|
||||
gen.link_word_to_byte(32 / 4, jgeo->generate(gen));
|
||||
}
|
||||
if (!elts.at(1)) {
|
||||
gen.link_word_to_byte(36 / 4, generate_dummy_merc_ctrl(gen, *this));
|
||||
}
|
||||
if (elts.at(2)) {
|
||||
auto ja = (ArtJointAnim*)elts.at(2);
|
||||
gen.link_word_to_byte(40 / 4, ja->generate(gen));
|
||||
}
|
||||
}
|
||||
|
||||
return gen.generate_v4();
|
||||
}
|
||||
|
||||
bool run_build_actor(const std::string& input_model,
|
||||
const std::string& ag_out,
|
||||
const std::string& output_prefix) {
|
||||
std::string ag_name;
|
||||
if (fs::exists(file_util::get_jak_project_dir() / input_model)) {
|
||||
ag_name = fs::path(input_model).stem().string();
|
||||
} else {
|
||||
ASSERT_MSG(false, "Model file not found: " + input_model);
|
||||
}
|
||||
|
||||
ArtGroup ag(ag_name);
|
||||
std::vector<Joint> joints;
|
||||
auto identity = math::Matrix4f::identity();
|
||||
joints.emplace_back("align", 0, -1, identity);
|
||||
joints.emplace_back("prejoint", 1, -1, identity);
|
||||
// matrix stolen from "egg" joint from "money" art group
|
||||
auto main_pose = math::Matrix4f::zero();
|
||||
main_pose(0, 0) = 1.0f;
|
||||
main_pose(0, 1) = -0.0f;
|
||||
main_pose(0, 2) = 0.0f;
|
||||
main_pose(0, 3) = -0.0f;
|
||||
main_pose(1, 0) = -0.0f;
|
||||
main_pose(1, 1) = 1.0f;
|
||||
main_pose(1, 2) = -0.0f;
|
||||
main_pose(1, 3) = 0.0f;
|
||||
main_pose(2, 0) = 0.0f;
|
||||
main_pose(2, 1) = -0.0f;
|
||||
main_pose(2, 2) = 1.0f;
|
||||
main_pose(2, 3) = -0.0f;
|
||||
main_pose(3, 0) = -0.0f;
|
||||
main_pose(3, 1) = -2194.1628418f;
|
||||
main_pose(3, 2) = -0.0f;
|
||||
main_pose(3, 3) = 1.0f;
|
||||
Joint main("main", 2, 1, main_pose);
|
||||
joints.emplace_back(main);
|
||||
ArtJointGeo jgeo(ag.name, joints);
|
||||
ArtJointAnim ja(ag.name, joints);
|
||||
|
||||
jgeo.lump.add_res(
|
||||
std::make_unique<ResInt32>("texture-level", std::vector<s32>{2}, DEFAULT_RES_TIME));
|
||||
// jgeo.lump.add_res(std::make_unique<ResVector>(
|
||||
// "trans-offset", std::vector<math::Vector4f>{{0.0f, 2048.0f, 0.0f, 1.0f}},
|
||||
// DEFAULT_RES_TIME));
|
||||
jgeo.lump.add_res(
|
||||
std::make_unique<ResInt32>("joint-channel", std::vector<s32>{0}, DEFAULT_RES_TIME));
|
||||
jgeo.lump.add_res(std::make_unique<ResFloat>(
|
||||
"lod-dist", std::vector<float>{5000.0f * METER_LENGTH, 6000.0f * METER_LENGTH},
|
||||
DEFAULT_RES_TIME));
|
||||
jgeo.lump.sort_res();
|
||||
|
||||
ag.elts.emplace_back(&jgeo);
|
||||
// dummy merc-ctrl
|
||||
ag.elts.emplace_back(nullptr);
|
||||
ag.elts.emplace_back(&ja);
|
||||
|
||||
ag.length = ag.elts.size();
|
||||
|
||||
auto ag_file = ag.save_object_file();
|
||||
lg::info("ag file size {} bytes", ag_file.size());
|
||||
auto save_path = fs::path(ag_out);
|
||||
file_util::create_dir_if_needed_for_file(ag_out);
|
||||
lg::info("Saving to {}", save_path.string());
|
||||
file_util::write_binary_file(file_util::get_jak_project_dir() / save_path, ag_file.data(),
|
||||
ag_file.size());
|
||||
return true;
|
||||
}
|
||||
} // namespace jak1
|
||||
@@ -0,0 +1,210 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/util/gltf_util.h"
|
||||
|
||||
#include "goalc/build_actor/common/art_types.h"
|
||||
#include "goalc/build_level/collide/common/collide_common.h"
|
||||
|
||||
namespace jak1 {
|
||||
|
||||
struct Joint {
|
||||
std::string name;
|
||||
s32 number;
|
||||
int parent;
|
||||
math::Matrix4f bind_pose{};
|
||||
|
||||
Joint(const std::string& name, int number, int parent, math::Matrix4f bind_pose) {
|
||||
this->name = name;
|
||||
this->number = number;
|
||||
this->parent = parent;
|
||||
this->bind_pose = bind_pose;
|
||||
}
|
||||
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
// basic
|
||||
struct JointAnim {
|
||||
std::string name;
|
||||
s16 number;
|
||||
s16 length;
|
||||
|
||||
explicit JointAnim(const Joint& joint) {
|
||||
this->name = joint.name;
|
||||
number = joint.number;
|
||||
length = 1;
|
||||
}
|
||||
};
|
||||
|
||||
// basic
|
||||
struct JointAnimCompressed : JointAnim {
|
||||
std::vector<u32> data;
|
||||
explicit JointAnimCompressed(const Joint& joint) : JointAnim(joint) {
|
||||
number = joint.number;
|
||||
length = 1;
|
||||
}
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct JointAnimFrame {
|
||||
math::Matrix4f matrices[2];
|
||||
std::vector<math::Matrix4f> data;
|
||||
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct JointAnimCompressedHDR {
|
||||
u32 control_bits[14];
|
||||
u32 num_joints;
|
||||
u32 matrix_bits;
|
||||
|
||||
JointAnimCompressedHDR() {
|
||||
for (auto& bit : control_bits) {
|
||||
bit = 0;
|
||||
}
|
||||
num_joints = 1;
|
||||
matrix_bits = 0;
|
||||
}
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct JointAnimCompressedFixed {
|
||||
JointAnimCompressedHDR hdr;
|
||||
u32 offset_64;
|
||||
u32 offset_32;
|
||||
u32 offset_16;
|
||||
u32 reserved;
|
||||
math::Vector4f data[133];
|
||||
|
||||
JointAnimCompressedFixed() {
|
||||
offset_64 = 0;
|
||||
offset_32 = 0x88;
|
||||
offset_16 = 0x90;
|
||||
reserved = 0;
|
||||
data[0] = math::Vector4f(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
data[1] = math::Vector4f(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
data[2] = math::Vector4f(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
data[3] = math::Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
data[4] = math::Vector4f(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
data[5] = math::Vector4f(0.0f, 1.0f, 0.0f, 0.0f);
|
||||
data[6] = math::Vector4f(0.0f, 0.0f, 1.0f, 0.0f);
|
||||
data[7] = math::Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct JointAnimCompressedFrame {
|
||||
u32 offset_64;
|
||||
u32 offset_32;
|
||||
u32 offset_16;
|
||||
u32 reserved;
|
||||
math::Vector4f data[133];
|
||||
|
||||
JointAnimCompressedFrame() {
|
||||
offset_64 = 0;
|
||||
offset_32 = 0;
|
||||
offset_16 = 0;
|
||||
reserved = 0;
|
||||
}
|
||||
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct JointAnimCompressedControl {
|
||||
u32 num_frames;
|
||||
u32 fixed_qwc;
|
||||
u32 frame_qwc;
|
||||
JointAnimCompressedFixed fixed{};
|
||||
JointAnimCompressedFrame frame[1];
|
||||
|
||||
JointAnimCompressedControl() {
|
||||
num_frames = 1;
|
||||
fixed_qwc = 0xf;
|
||||
frame_qwc = 1;
|
||||
fixed = JointAnimCompressedFixed();
|
||||
frame[0] = JointAnimCompressedFrame();
|
||||
}
|
||||
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct CollideMeshTri {
|
||||
u8 vert_idx[3];
|
||||
u8 unused;
|
||||
PatSurface pat;
|
||||
};
|
||||
|
||||
struct CollideMesh {
|
||||
s32 joint_id;
|
||||
u32 num_tris;
|
||||
u32 num_verts;
|
||||
std::vector<math::Vector4f> vertices;
|
||||
CollideMeshTri tris;
|
||||
};
|
||||
|
||||
struct ArtJointGeo : ArtElement {
|
||||
std::vector<Joint> data;
|
||||
CollideMesh mesh;
|
||||
ResLump lump;
|
||||
|
||||
explicit ArtJointGeo(const std::string& name, const std::vector<Joint>& joints) {
|
||||
this->name = name + "-lod0";
|
||||
length = joints.size();
|
||||
for (auto& joint : joints) {
|
||||
data.push_back(joint);
|
||||
}
|
||||
}
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
size_t generate_res_lump(DataObjectGenerator& gen) const;
|
||||
size_t generate_mesh(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct ArtJointAnim : ArtElement {
|
||||
MercEyeAnimBlock eye_anim_data;
|
||||
float speed;
|
||||
float artist_base;
|
||||
float artist_step;
|
||||
std::string master_art_group_name;
|
||||
s32 master_art_group_index;
|
||||
u8* blerc_data = nullptr;
|
||||
JointAnimCompressedControl frames;
|
||||
std::vector<JointAnimCompressed> data;
|
||||
|
||||
ArtJointAnim(const std::string& name, const std::vector<Joint>& joints) {
|
||||
this->name = name + "-idle";
|
||||
length = joints.size();
|
||||
speed = 1.0f;
|
||||
artist_base = 0.0f;
|
||||
artist_step = 1.0f;
|
||||
master_art_group_name = name;
|
||||
master_art_group_index = 2;
|
||||
frames = JointAnimCompressedControl();
|
||||
for (auto& joint : joints) {
|
||||
data.emplace_back(joint);
|
||||
}
|
||||
}
|
||||
size_t generate(DataObjectGenerator& gen) const;
|
||||
};
|
||||
|
||||
struct ArtGroup : Art {
|
||||
FileInfo info;
|
||||
std::vector<ArtElement*> elts;
|
||||
std::map<int, size_t> joint_map;
|
||||
|
||||
explicit ArtGroup(const std::string& file_name) {
|
||||
info.file_type = "art-group";
|
||||
info.file_name = "/src/next/data/art-group6/" + file_name + "-ag.go";
|
||||
name = file_name;
|
||||
info.major_version = versions::jak1::ART_FILE_VERSION;
|
||||
info.minor_version = 0;
|
||||
info.tool_debug = "Created by OpenGOAL buildactor";
|
||||
info.mdb_file_name = "Unknown";
|
||||
info.maya_file_name = "Unknown";
|
||||
}
|
||||
std::vector<u8> save_object_file() const;
|
||||
};
|
||||
|
||||
bool run_build_actor(const std::string& input_model,
|
||||
const std::string& output_file,
|
||||
const std::string& output_prefix);
|
||||
} // namespace jak1
|
||||
@@ -0,0 +1,63 @@
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
#include "goalc/build_actor/jak1/build_actor.h"
|
||||
|
||||
#include "third-party/CLI11.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
// logging
|
||||
lg::set_stdout_level(lg::level::info);
|
||||
lg::set_flush_level(lg::level::info);
|
||||
lg::initialize();
|
||||
|
||||
// game version
|
||||
std::string game, input_model, output_file;
|
||||
fs::path project_path_override;
|
||||
|
||||
// path
|
||||
if (!file_util::setup_project_path(std::nullopt)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
lg::info("Build Actor Tool", versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR);
|
||||
|
||||
CLI::App app{"OpenGOAL Compiler / REPL"};
|
||||
app.add_option("input-model", input_model,
|
||||
"Input model file (for example: custom_assets/jak1/models/test.glb)")
|
||||
->required();
|
||||
app.add_option("output-file", output_file,
|
||||
"Output *-ag.go file (for example: out/jak1/obj/test-ag.go)")
|
||||
->required();
|
||||
app.add_option("-g,--game", game, "Game version (only jak1 for now)")->required();
|
||||
app.add_option("--proj-path", project_path_override,
|
||||
"Specify the location of the 'data/' folder");
|
||||
app.validate_positionals();
|
||||
CLI11_PARSE(app, argc, argv)
|
||||
|
||||
GameVersion game_version = game_name_to_version(game);
|
||||
|
||||
if (!project_path_override.empty()) {
|
||||
if (!fs::exists(project_path_override)) {
|
||||
lg::error("Error: project path override '{}' does not exist", project_path_override.string());
|
||||
return 1;
|
||||
}
|
||||
if (!file_util::setup_project_path(project_path_override)) {
|
||||
lg::error("Could not setup project path!");
|
||||
return 1;
|
||||
}
|
||||
} else if (!file_util::setup_project_path(std::nullopt)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (game_version) {
|
||||
case GameVersion::Jak1:
|
||||
jak1::run_build_actor(input_model, output_file, "jak1/");
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED_MSG("unsupported game version");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
|
||||
struct TexturePool {
|
||||
std::unordered_map<std::string, int> textures_by_name;
|
||||
std::vector<tfrag3::Texture> textures_by_idx;
|
||||
};
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
|
||||
#include "goalc/build_level/common/TexturePool.h"
|
||||
|
||||
class DataObjectGenerator;
|
||||
|
||||
struct DrawableTreeTfrag {
|
||||
|
||||
@@ -41,3 +41,23 @@ std::vector<decompiler::ObjectFileRecord> find_art_groups(
|
||||
}
|
||||
return art_groups;
|
||||
}
|
||||
|
||||
void add_model_to_level(GameVersion version, const std::string& name, tfrag3::Level& lvl) {
|
||||
lg::info("custom level: adding custom model {}", name);
|
||||
auto glb = name + ".glb";
|
||||
auto merc_data = load_merc_model(lvl.merc_data.indices.size(), lvl.merc_data.vertices.size(),
|
||||
lvl.textures.size(),
|
||||
fs::path(file_util::get_jak_project_dir() / "custom_assets" /
|
||||
game_version_names[version] / "models" / glb)
|
||||
.string(),
|
||||
name + "-lod0");
|
||||
for (auto& idx : merc_data.new_indices) {
|
||||
lvl.merc_data.indices.push_back(idx);
|
||||
}
|
||||
for (auto& vert : merc_data.new_vertices) {
|
||||
lvl.merc_data.vertices.push_back(vert);
|
||||
}
|
||||
lvl.merc_data.models.push_back(merc_data.new_model);
|
||||
lvl.textures.insert(lvl.textures.end(), merc_data.new_textures.begin(),
|
||||
merc_data.new_textures.end());
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "common/util/string_util.h"
|
||||
|
||||
#include "decompiler/level_extractor/extract_level.h"
|
||||
#include <goalc/build_actor/common/MercExtract.h>
|
||||
|
||||
void save_pc_data(const std::string& nickname, tfrag3::Level& data, const fs::path& fr3_output_dir);
|
||||
std::vector<std::string> get_build_level_deps(const std::string& input_file);
|
||||
@@ -16,3 +17,4 @@ std::vector<decompiler::ObjectFileRecord> find_art_groups(
|
||||
std::vector<std::string>& processed_ags,
|
||||
const std::vector<std::string>& custom_level_ag,
|
||||
const std::vector<decompiler::ObjectFileRecord>& dgo_files);
|
||||
void add_model_to_level(GameVersion version, const std::string& name, tfrag3::Level& lvl);
|
||||
|
||||
@@ -11,474 +11,20 @@
|
||||
#include "common/log/log.h"
|
||||
#include "common/math/geometry.h"
|
||||
#include "common/util/Timer.h"
|
||||
#include "common/util/gltf_util.h"
|
||||
|
||||
#include "third-party/tiny_gltf/tiny_gltf.h"
|
||||
|
||||
using namespace gltf_util;
|
||||
namespace gltf_mesh_extract {
|
||||
|
||||
namespace {
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*!
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
|
||||
struct ExtractedVertices {
|
||||
std::vector<tfrag3::PreloadedVertex> vtx;
|
||||
std::vector<math::Vector<u8, 4>> vtx_colors;
|
||||
std::vector<math::Vector3f> normals;
|
||||
};
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
struct NodeWithTransform {
|
||||
int node_idx;
|
||||
math::Matrix4f w_T_node;
|
||||
};
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dedup_vertices(TfragOutput& data) {
|
||||
Timer timer;
|
||||
size_t original_size = data.vertices.size();
|
||||
std::vector<tfrag3::PreloadedVertex> new_verts;
|
||||
std::vector<u32> old_to_new;
|
||||
|
||||
dedup_vertices(data.vertices, new_verts, old_to_new);
|
||||
gltf_util::dedup_vertices(data.vertices, new_verts, old_to_new);
|
||||
data.vertices = std::move(new_verts);
|
||||
|
||||
for (auto& draw : data.strip_draws) {
|
||||
@@ -492,41 +38,6 @@ void dedup_vertices(TfragOutput& data) {
|
||||
data.vertices.size(), 100.f * data.vertices.size() / original_size);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void extract(const Input& in,
|
||||
TfragOutput& out,
|
||||
const tinygltf::Model& model,
|
||||
|
||||
@@ -5,13 +5,16 @@
|
||||
#include "common/custom_data/Tfrag3Data.h"
|
||||
|
||||
#include "goalc/build_level/collide/common/collide_common.h"
|
||||
#include "goalc/build_level/common/TexturePool.h"
|
||||
|
||||
namespace gltf_util {
|
||||
struct TexturePool;
|
||||
}
|
||||
|
||||
namespace gltf_mesh_extract {
|
||||
|
||||
struct Input {
|
||||
std::string filename;
|
||||
TexturePool* tex_pool = nullptr;
|
||||
gltf_util::TexturePool* tex_pool = nullptr;
|
||||
bool get_colors = true;
|
||||
bool auto_wall_enable = true;
|
||||
float auto_wall_angle = 30.f;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "build_level.h"
|
||||
|
||||
#include "common/util/gltf_util.h"
|
||||
|
||||
#include "decompiler/extractor/extractor_util.h"
|
||||
#include "decompiler/level_extractor/extract_merc.h"
|
||||
#include "goalc/build_level/collide/jak1/collide_bvh.h"
|
||||
@@ -15,9 +17,9 @@ bool run_build_level(const std::string& input_file,
|
||||
const std::string& output_prefix) {
|
||||
auto level_json = parse_commented_json(
|
||||
file_util::read_text_file(file_util::get_file_path({input_file})), input_file);
|
||||
LevelFile file; // GOAL level file
|
||||
tfrag3::Level pc_level; // PC level file
|
||||
TexturePool tex_pool; // pc level texture pool
|
||||
LevelFile file; // GOAL level file
|
||||
tfrag3::Level pc_level; // PC level file
|
||||
gltf_util::TexturePool tex_pool; // pc level texture pool
|
||||
|
||||
// process input mesh from blender
|
||||
gltf_mesh_extract::Input mesh_extract_in;
|
||||
@@ -202,6 +204,14 @@ bool run_build_level(const std::string& input_file,
|
||||
}
|
||||
}
|
||||
|
||||
// add custom models to fr3
|
||||
if (level_json.contains("custom_models") && !level_json.at("custom_models").empty()) {
|
||||
auto models = level_json.at("custom_models").get<std::vector<std::string>>();
|
||||
for (auto& name : models) {
|
||||
add_model_to_level(GameVersion::Jak1, name, pc_level);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the PC level
|
||||
save_pc_data(file.name, pc_level,
|
||||
file_util::get_jak_project_dir() / "out" / output_prefix / "fr3");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "build_level.h"
|
||||
|
||||
#include "common/util/gltf_util.h"
|
||||
|
||||
#include "decompiler/extractor/extractor_util.h"
|
||||
#include "decompiler/level_extractor/extract_merc.h"
|
||||
#include "goalc/build_level/collide/jak2/collide.h"
|
||||
@@ -14,9 +16,9 @@ bool run_build_level(const std::string& input_file,
|
||||
const std::string& output_prefix) {
|
||||
auto level_json = parse_commented_json(
|
||||
file_util::read_text_file(file_util::get_file_path({input_file})), input_file);
|
||||
LevelFile file; // GOAL level file
|
||||
tfrag3::Level pc_level; // PC level file
|
||||
TexturePool tex_pool; // pc level texture pool
|
||||
LevelFile file; // GOAL level file
|
||||
tfrag3::Level pc_level; // PC level file
|
||||
gltf_util::TexturePool tex_pool; // pc level texture pool
|
||||
|
||||
// process input mesh from blender
|
||||
gltf_mesh_extract::Input mesh_extract_in;
|
||||
|
||||
@@ -14,9 +14,9 @@ bool run_build_level(const std::string& input_file,
|
||||
const std::string& output_prefix) {
|
||||
auto level_json = parse_commented_json(
|
||||
file_util::read_text_file(file_util::get_file_path({input_file})), input_file);
|
||||
LevelFile file; // GOAL level file
|
||||
tfrag3::Level pc_level; // PC level file
|
||||
TexturePool tex_pool; // pc level texture pool
|
||||
LevelFile file; // GOAL level file
|
||||
tfrag3::Level pc_level; // PC level file
|
||||
gltf_util::TexturePool tex_pool; // pc level texture pool
|
||||
|
||||
// process input mesh from blender
|
||||
gltf_mesh_extract::Input mesh_extract_in;
|
||||
|
||||
@@ -28,8 +28,9 @@ int main(int argc, char** argv) {
|
||||
lg::info("Build Level Tool", versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR);
|
||||
|
||||
CLI::App app{"OpenGOAL Compiler / REPL"};
|
||||
app.add_option("input-json", input_json,
|
||||
"Input JSON file (for example, custom_levels/jak2/test-zone/test-zone.jsonc)")
|
||||
app.add_option(
|
||||
"input-json", input_json,
|
||||
"Input JSON file (for example, custom_assets/jak2/levels/test-zone/test-zone.jsonc)")
|
||||
->required();
|
||||
app.add_option("output-file", output_file,
|
||||
"Output .go file, (for example out/jak2/obj/test-zone.go)")
|
||||
|
||||
@@ -105,6 +105,7 @@ MakeSystem::MakeSystem(const std::optional<REPL::Config> repl_config, const std:
|
||||
add_tool<BuildLevelTool>();
|
||||
add_tool<BuildLevel2Tool>();
|
||||
add_tool<BuildLevel3Tool>();
|
||||
add_tool<BuildActorTool>();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "common/util/DgoWriter.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
#include "goalc/build_actor/jak1/build_actor.h"
|
||||
#include "goalc/build_level/jak1/build_level.h"
|
||||
#include "goalc/build_level/jak2/build_level.h"
|
||||
#include "goalc/build_level/jak3/build_level.h"
|
||||
@@ -295,4 +296,23 @@ bool BuildLevel3Tool::run(const ToolInput& task, const PathMap& path_map) {
|
||||
throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name()));
|
||||
}
|
||||
return jak3::run_build_level(task.input.at(0), task.output.at(0), path_map.output_prefix);
|
||||
}
|
||||
|
||||
BuildActorTool::BuildActorTool() : Tool("build-actor") {}
|
||||
|
||||
bool BuildActorTool::needs_run(const ToolInput& task, const PathMap& path_map) {
|
||||
(void)path_map;
|
||||
if (task.input.size() != 1) {
|
||||
throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name()));
|
||||
}
|
||||
// std::vector<std::string> deps{};
|
||||
// return Tool::needs_run({task.input, deps, task.output, task.arg}, path_map);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildActorTool::run(const ToolInput& task, const PathMap& path_map) {
|
||||
if (task.input.size() != 1) {
|
||||
throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name()));
|
||||
}
|
||||
return jak1::run_build_actor(task.input.at(0), task.output.at(0), path_map.output_prefix);
|
||||
}
|
||||
@@ -92,3 +92,10 @@ class BuildLevel3Tool : public Tool {
|
||||
bool run(const ToolInput& task, const PathMap& path_map) override;
|
||||
bool needs_run(const ToolInput& task, const PathMap& path_map) override;
|
||||
};
|
||||
|
||||
class BuildActorTool : public Tool {
|
||||
public:
|
||||
BuildActorTool();
|
||||
bool run(const ToolInput& task, const PathMap& path_map) override;
|
||||
bool needs_run(const ToolInput& task, const PathMap& path_map) override;
|
||||
};
|
||||
|
||||
+35
-28
@@ -3,34 +3,41 @@
|
||||
|
||||
;; definition of type texture-anim-layer
|
||||
(deftype texture-anim-layer (structure)
|
||||
((extra vector :inline :offset 240)
|
||||
(func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(func-id symbol :overlay-at func)
|
||||
(init-func (function texture-anim-layer int))
|
||||
(init-func-id symbol :overlay-at init-func)
|
||||
(tex texture)
|
||||
(start-time float)
|
||||
(end-time float)
|
||||
(tex-name string)
|
||||
(test gs-test)
|
||||
(alpha gs-alpha)
|
||||
(clamp gs-clamp)
|
||||
(start-color vector :inline :offset 80)
|
||||
(start-scale vector2 :inline :offset 96)
|
||||
(start-offset vector2 :inline :offset 104)
|
||||
(start-st-scale vector2 :inline :offset 112)
|
||||
(start-st-offset vector2 :inline :offset 120)
|
||||
(start-qs vector :inline :offset 128)
|
||||
(start-rot degrees :offset 144)
|
||||
(start-st-rot degrees :offset 148)
|
||||
(end-color vector :inline :offset 160)
|
||||
(end-scale vector2 :inline :offset 176)
|
||||
(end-offset vector2 :inline :offset 184)
|
||||
(end-st-scale vector2 :inline :offset 192)
|
||||
(end-st-offset vector2 :inline :offset 200)
|
||||
(end-qs vector :inline :offset 208)
|
||||
(end-rot degrees :offset 224)
|
||||
(end-st-rot degrees :offset 228)
|
||||
((interpolated-color vector :inline)
|
||||
(interpolated-scale-offset vector :inline)
|
||||
(interpolated-st-scale-offset vector :inline)
|
||||
(interpolated-qs vector :inline)
|
||||
(interpolated-rot vector :inline)
|
||||
(extra vector :inline :offset 240)
|
||||
(func (function dma-buffer uint int int texture-anim-layer float int))
|
||||
(func-id symbol :overlay-at func)
|
||||
(init-func (function texture-anim-layer int))
|
||||
(init-func-id symbol :overlay-at init-func)
|
||||
(tex texture)
|
||||
(start-time float)
|
||||
(end-time float)
|
||||
(tex-name string)
|
||||
(test gs-test)
|
||||
(alpha gs-alpha)
|
||||
(clamp gs-clamp)
|
||||
(start-vectors vector 5 :inline :offset 80)
|
||||
(start-color vector :inline :overlay-at (-> start-vectors 0))
|
||||
(start-scale vector2 :inline :offset 96)
|
||||
(start-offset vector2 :inline :offset 104)
|
||||
(start-st-scale vector2 :inline :offset 112)
|
||||
(start-st-offset vector2 :inline :offset 120)
|
||||
(start-qs vector :inline :overlay-at (-> start-vectors 3))
|
||||
(start-rot degrees :offset 144)
|
||||
(start-st-rot degrees :offset 148)
|
||||
(end-vectors vector 5 :inline :offset 160)
|
||||
(end-color vector :inline :overlay-at (-> end-vectors 0))
|
||||
(end-scale vector2 :inline :offset 176)
|
||||
(end-offset vector2 :inline :offset 184)
|
||||
(end-st-scale vector2 :inline :offset 192)
|
||||
(end-st-offset vector2 :inline :offset 200)
|
||||
(end-qs vector :inline :overlay-at (-> end-vectors 3))
|
||||
(end-rot degrees :offset 224)
|
||||
(end-st-rot degrees :offset 228)
|
||||
)
|
||||
(:methods
|
||||
(initialize-texture! (_type_) _type_)
|
||||
|
||||
+1
-5
@@ -86,7 +86,7 @@ Note that all child classes of this must be 32-bytes."
|
||||
;; definition of type drawable-tree-region-prim
|
||||
(deftype drawable-tree-region-prim (drawable-tree)
|
||||
"Top-level container for all regions of a level."
|
||||
((name basic :offset 8)
|
||||
((name symbol :offset 8)
|
||||
(data2 drawable-inline-array :dynamic :offset 32)
|
||||
)
|
||||
(:methods
|
||||
@@ -260,7 +260,3 @@ exactly the same size as the parent, so it's okay."
|
||||
|
||||
;; failed to figure out what this is:
|
||||
0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user