mirror of
https://github.com/open-goal/jak-project.git
synced 2025-02-07 06:06:44 +00:00
[jak 2] fix texture lookup problem (#2373)
This should fix a bunch of texture-related issues by generating a table of overlapping textures and just... adjusting them slightly so they don't overlap. It's not the most elegant solution in the world, but I think it's no worse than the existing hard-coded tpage dir stuff.
This commit is contained in:
parent
f276251a3a
commit
df646282ab
@ -17,7 +17,8 @@ void TextureDB::add_texture(u32 tpage,
|
||||
const std::string& tex_name,
|
||||
const std::string& tpage_name,
|
||||
const std::vector<std::string>& level_names,
|
||||
u32 num_mips) {
|
||||
u32 num_mips,
|
||||
u32 dest) {
|
||||
auto existing_tpage_name = tpage_names.find(tpage);
|
||||
if (existing_tpage_name == tpage_names.end()) {
|
||||
tpage_names[tpage] = tpage_name;
|
||||
@ -34,6 +35,7 @@ void TextureDB::add_texture(u32 tpage,
|
||||
ASSERT(existing_tex->second.rgba_bytes == data);
|
||||
ASSERT(existing_tex->second.page == tpage);
|
||||
ASSERT(existing_tex->second.num_mips == num_mips);
|
||||
ASSERT(existing_tex->second.dest == dest);
|
||||
} else {
|
||||
auto& new_tex = textures[combo_id];
|
||||
new_tex.rgba_bytes = data;
|
||||
@ -42,6 +44,7 @@ void TextureDB::add_texture(u32 tpage,
|
||||
new_tex.h = h;
|
||||
new_tex.page = tpage;
|
||||
new_tex.num_mips = num_mips;
|
||||
new_tex.dest = dest;
|
||||
}
|
||||
for (const auto& level_name : level_names) {
|
||||
texture_ids_per_level[level_name].insert(combo_id);
|
||||
@ -68,4 +71,51 @@ void TextureDB::replace_textures(const fs::path& path) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Generate a table of offsets
|
||||
*/
|
||||
std::string TextureDB::generate_texture_dest_adjustment_table() const {
|
||||
// group textures by page
|
||||
std::map<u32, std::vector<u32>> textures_by_page;
|
||||
for (const auto& [texture_id, texture] : textures) {
|
||||
textures_by_page[texture.page].push_back(texture_id);
|
||||
}
|
||||
|
||||
std::string result = "{\n";
|
||||
// loop over pages (this overlap trick only applies within a page)
|
||||
for (const auto& [tpage, texture_ids_in_page] : textures_by_page) {
|
||||
// organize by tbp offset
|
||||
std::map<u32, std::vector<u32>> textures_by_tbp_offset;
|
||||
for (auto tid : texture_ids_in_page) {
|
||||
textures_by_tbp_offset[textures.at(tid).dest].push_back(tid);
|
||||
}
|
||||
|
||||
// find tbp's with overlaps:
|
||||
bool needs_remap = false;
|
||||
for (const auto& [tbp, tex_ids] : textures_by_tbp_offset) {
|
||||
if (tex_ids.size() > 1) {
|
||||
needs_remap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_remap) {
|
||||
result += fmt::format("{{{},{{\n", tpage);
|
||||
for (const auto& [tbp, tex_ids] : textures_by_tbp_offset) {
|
||||
if (tex_ids.size() > 1) {
|
||||
int offset = 0;
|
||||
for (auto id : tex_ids) {
|
||||
result += fmt::format("{{{}, {}}},", id & 0xffff, offset++);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.pop_back();
|
||||
result += "}},\n";
|
||||
}
|
||||
}
|
||||
result += "}\n";
|
||||
return result;
|
||||
}
|
||||
} // namespace decompiler
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@ -14,11 +15,12 @@ struct TextureDB {
|
||||
u16 w, h;
|
||||
std::string name;
|
||||
u32 page;
|
||||
u32 dest = -1;
|
||||
std::vector<u32> rgba_bytes;
|
||||
u32 num_mips = -1;
|
||||
};
|
||||
|
||||
std::unordered_map<u32, TextureData> textures;
|
||||
std::map<u32, TextureData> textures;
|
||||
std::unordered_map<u32, std::string> tpage_names;
|
||||
std::unordered_map<std::string, std::set<u32>> texture_ids_per_level;
|
||||
|
||||
@ -30,8 +32,11 @@ struct TextureDB {
|
||||
const std::string& tex_name,
|
||||
const std::string& tpage_name,
|
||||
const std::vector<std::string>& level_names,
|
||||
u32 num_mips);
|
||||
u32 num_mips,
|
||||
u32 dest);
|
||||
|
||||
void replace_textures(const fs::path& path);
|
||||
|
||||
std::string generate_texture_dest_adjustment_table() const;
|
||||
};
|
||||
} // namespace decompiler
|
||||
|
@ -537,7 +537,7 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(),
|
||||
tex.w, tex.h);
|
||||
texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name,
|
||||
texture_page.name, level_names, tex.num_mips);
|
||||
texture_page.name, level_names, tex.num_mips, tex.dest[0]);
|
||||
stats.successful_textures++;
|
||||
} else if (tex.psm == int(PSM::PSMT8) && tex.clutpsm == int(CPSM::PSMCT16)) {
|
||||
// will store output pixels, rgba (8888)
|
||||
@ -580,7 +580,7 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(),
|
||||
tex.w, tex.h);
|
||||
texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name,
|
||||
texture_page.name, level_names, tex.num_mips);
|
||||
texture_page.name, level_names, tex.num_mips, tex.dest[0]);
|
||||
stats.successful_textures++;
|
||||
} else if (tex.psm == int(PSM::PSMCT16) && tex.clutpsm == 0) {
|
||||
// not a clut.
|
||||
@ -605,7 +605,7 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(),
|
||||
tex.w, tex.h);
|
||||
texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name,
|
||||
texture_page.name, level_names, tex.num_mips);
|
||||
texture_page.name, level_names, tex.num_mips, tex.dest[0]);
|
||||
stats.successful_textures++;
|
||||
} else if (tex.psm == int(PSM::PSMT4) && tex.clutpsm == int(CPSM::PSMCT16)) {
|
||||
// will store output pixels, rgba (8888)
|
||||
@ -646,7 +646,7 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(),
|
||||
tex.w, tex.h);
|
||||
texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name,
|
||||
texture_page.name, level_names, tex.num_mips);
|
||||
texture_page.name, level_names, tex.num_mips, tex.dest[0]);
|
||||
stats.successful_textures++;
|
||||
} else if (tex.psm == int(PSM::PSMT4) && tex.clutpsm == int(CPSM::PSMCT32)) {
|
||||
// will store output pixels, rgba (8888)
|
||||
@ -687,7 +687,7 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(),
|
||||
tex.w, tex.h);
|
||||
texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name,
|
||||
texture_page.name, level_names, tex.num_mips);
|
||||
texture_page.name, level_names, tex.num_mips, tex.dest[0]);
|
||||
stats.successful_textures++;
|
||||
} else if (tex.psm == int(PSM::PSMCT32) && tex.clutpsm == 0) {
|
||||
// not a clut.
|
||||
@ -712,7 +712,7 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
file_util::write_rgba_png(texture_dump_dir / fmt::format("{}.png", tex.name), out.data(),
|
||||
tex.w, tex.h);
|
||||
texture_db.add_texture(texture_page.id, tex_id, out, tex.w, tex.h, tex.name,
|
||||
texture_page.name, level_names, tex.num_mips);
|
||||
texture_page.name, level_names, tex.num_mips, tex.dest[0]);
|
||||
stats.successful_textures++;
|
||||
}
|
||||
|
||||
|
@ -251,6 +251,8 @@ int main(int argc, char** argv) {
|
||||
auto result = db.process_tpages(tex_db, textures_out);
|
||||
if (!result.empty() && config.process_tpages) {
|
||||
file_util::write_text_file(textures_out / "tpage-dir.txt", result);
|
||||
file_util::write_text_file(textures_out / "tex-remap.txt",
|
||||
tex_db.generate_texture_dest_adjustment_table());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,7 @@ set(RUNTIME_SOURCE
|
||||
overlord/ssound.cpp
|
||||
overlord/stream.cpp
|
||||
graphics/gfx.cpp
|
||||
graphics/jak2_texture_remap.cpp
|
||||
graphics/display.cpp
|
||||
graphics/sceGraphicsInterface.cpp
|
||||
graphics/opengl_renderer/background/background_common.cpp
|
||||
|
1541
game/graphics/jak2_texture_remap.cpp
Normal file
1541
game/graphics/jak2_texture_remap.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3
game/graphics/jak2_texture_remap.h
Normal file
3
game/graphics/jak2_texture_remap.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
int lookup_jak2_texture_dest_offset(int tpage, int texture_idx);
|
@ -9,6 +9,7 @@
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
#include "game/discord.h"
|
||||
#include "game/graphics/jak2_texture_remap.h"
|
||||
#include "game/kernel/common/Symbol4.h"
|
||||
#include "game/kernel/common/fileio.h"
|
||||
#include "game/kernel/common/kboot.h"
|
||||
@ -625,6 +626,7 @@ void InitMachine_PCPort() {
|
||||
make_function_symbol_from_c("__pc-texture-relocate", (void*)pc_texture_relocate);
|
||||
make_function_symbol_from_c("__pc-get-mips2c", (void*)pc_get_mips2c);
|
||||
make_function_symbol_from_c("__pc-set-levels", (void*)pc_set_levels);
|
||||
make_function_symbol_from_c("__pc-get-tex-remap", (void*)lookup_jak2_texture_dest_offset);
|
||||
|
||||
// pad stuff
|
||||
make_function_symbol_from_c("pc-pad-get-mapped-button", (void*)Gfx::get_mapped_button);
|
||||
|
@ -2346,6 +2346,20 @@ additionally, some texture pages have a chunk system that allows more specific c
|
||||
;; set up dests (no idea why the tpage doesn't come with this set properly)
|
||||
(set! (-> obj segment 1 dest) (-> obj segment 0 size))
|
||||
(set! (-> obj segment 2 dest) (+ (-> obj segment 0 size) (-> obj segment 1 size)))
|
||||
|
||||
;; PC port: added texture remap
|
||||
(dotimes (texture-idx (-> obj length))
|
||||
(let ((tex (-> obj data texture-idx)))
|
||||
(when (and tex (nonzero? tex))
|
||||
(let ((offset (__pc-get-tex-remap (the int (-> obj id)) texture-idx)))
|
||||
(when (nonzero? offset)
|
||||
)
|
||||
(+! (-> tex dest 0) offset)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(let* ((tpage-id (-> obj id))
|
||||
(dir-entry (-> *texture-page-dir* entries tpage-id))
|
||||
)
|
||||
|
@ -150,6 +150,7 @@
|
||||
(define-extern __pc-texture-relocate (function object object object none))
|
||||
(define-extern __pc-get-mips2c (function string function))
|
||||
(define-extern __pc-set-levels (function (pointer string) none))
|
||||
(define-extern __pc-get-tex-remap (function int int int))
|
||||
(define-extern pc-pad-input-mode-set (function symbol none))
|
||||
(define-extern pc-pad-input-pad-set (function int none))
|
||||
(define-extern pc-pad-input-mode-get (function int))
|
||||
|
Loading…
x
Reference in New Issue
Block a user