mirror of
https://github.com/open-goal/jak-project.git
synced 2026-11-07 09:26:09 -10:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55204e6996 | ||
|
|
b2cfefb669 | ||
|
|
bc586f0cca | ||
|
|
13e7a28c08 | ||
|
|
17665a4615 | ||
|
|
d209766078 |
No files matched your search
@@ -1,96 +0,0 @@
|
||||
name: Compilation Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Compare
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Install Package Dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install build-essential cmake \
|
||||
clang gcc g++ lcov make nasm libxrandr-dev \
|
||||
libxinerama-dev libxcursor-dev libpulse-dev \
|
||||
libxi-dev zip ninja-build libgl1-mesa-dev libssl-dev
|
||||
|
||||
- name: Setup sccache
|
||||
uses: hendrikmuhs/[email protected]
|
||||
with:
|
||||
variant: sccache
|
||||
key: linux-ubuntu-20.04--Release-linux-clang-asan-${{ github.sha }}
|
||||
restore-keys: linux-ubuntu-20.04--Release-linux-clang-asan
|
||||
max-size: 1000M
|
||||
|
||||
- name: CMake Generation (master)
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
run: |
|
||||
cmake -B build --preset=Release-linux-clang-asan \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
|
||||
- name: Build goalc (master)
|
||||
run: cmake --build build --parallel $((`nproc`)) --target goalc
|
||||
|
||||
- name: Compile and preserve (master)
|
||||
run: |
|
||||
./build/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
|
||||
./build/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
|
||||
./build/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
|
||||
mv ./out/jak1/obj ./out/jak1/obj.master
|
||||
mv ./out/jak2/obj ./out/jak2/obj.master
|
||||
mv ./out/jak3/obj ./out/jak3/obj.master
|
||||
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
clean: "false"
|
||||
|
||||
- name: CMake Generation (PR)
|
||||
env:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
run: |
|
||||
cmake -B build --preset=Release-linux-clang-asan \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
|
||||
- name: Build goalc (PR)
|
||||
run: cmake --build build --parallel $((`nproc`)) --target goalc
|
||||
|
||||
- name: Compile and preserve (PR)
|
||||
run: |
|
||||
./build/goalc/goalc --game jak1 --cmd "(make-group \"all-code\")"
|
||||
./build/goalc/goalc --game jak2 --cmd "(make-group \"all-code\")"
|
||||
./build/goalc/goalc --game jak3 --cmd "(make-group \"all-code\")"
|
||||
mv ./out/jak1/obj ./out/jak1/obj.pr
|
||||
mv ./out/jak2/obj ./out/jak2/obj.pr
|
||||
mv ./out/jak3/obj ./out/jak3/obj.pr
|
||||
|
||||
- name: Compare Results and Produce Report
|
||||
run: |
|
||||
ls -l ./out/jak1
|
||||
ls -l ./out/jak2
|
||||
ls -l ./out/jak3
|
||||
set +e
|
||||
python ./scripts/gsrc/compare-compilation-outputs.py --base "./out/jak1/obj.master,./out/jak2/obj.master,./out/jak3/obj.master" --compare "./out/jak1/obj.pr,./out/jak2/obj.pr,./out/jak3/obj.pr" --markdown
|
||||
SCRIPT_EXIT_CODE=$?
|
||||
cat ./comp-diff-report.md >> $GITHUB_STEP_SUMMARY
|
||||
if [ "$SCRIPT_EXIT_CODE" -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
+1
-7
@@ -32,7 +32,6 @@ linux-default/
|
||||
*.bin
|
||||
*.log
|
||||
*.p2s
|
||||
out/
|
||||
savestate-out/
|
||||
savestate_out/
|
||||
failures/
|
||||
@@ -40,7 +39,6 @@ ee-results*.json
|
||||
search-results.json
|
||||
.env
|
||||
/search-results.json
|
||||
comp-diff-report.md
|
||||
|
||||
# graphics debug
|
||||
debug_out/
|
||||
@@ -60,15 +58,11 @@ custom_assets/jak1/texture_replacements/*
|
||||
custom_assets/jak2/texture_replacements/*
|
||||
custom_assets/jak3/texture_replacements/*
|
||||
|
||||
# merc replacements
|
||||
custom_assets/jak1/merc_replacements/*
|
||||
custom_assets/jak2/merc_replacements/*
|
||||
custom_assets/jak3/merc_replacements/*
|
||||
|
||||
# generated cmake files
|
||||
svnrev.h
|
||||
common/versions/revision.h
|
||||
ci-artifacts/
|
||||
out/build/
|
||||
__pycache__/
|
||||
|
||||
# sqlite stuff
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
"name": "Game - Jak 1 - Runtime (boot)",
|
||||
"args": [
|
||||
"-v",
|
||||
"--portable",
|
||||
"--game",
|
||||
"jak1",
|
||||
"--",
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "fmt/core.h"
|
||||
|
||||
std::string DmaTag::print() const {
|
||||
std::string DmaTag::print() {
|
||||
std::string result;
|
||||
const char* mode_names[8] = {"refe", "cnt", "next", "ref", "refs", "call", "ret", "end"};
|
||||
result += fmt::format("TAG: 0x{:08x} {:4s} qwc 0x{:04x}", addr, mode_names[(int)kind], qwc);
|
||||
@@ -15,7 +15,7 @@ std::string DmaTag::print() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string VifCode::print() const {
|
||||
std::string VifCode::print() {
|
||||
std::string result;
|
||||
|
||||
switch (kind) {
|
||||
|
||||
+2
-2
@@ -52,7 +52,7 @@ struct DmaTag {
|
||||
|
||||
bool operator!=(const DmaTag& other) const { return !((*this) == other); }
|
||||
|
||||
std::string print() const;
|
||||
std::string print();
|
||||
};
|
||||
|
||||
inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32 dadr) {
|
||||
@@ -148,7 +148,7 @@ struct VifCode {
|
||||
u16 num;
|
||||
u16 immediate;
|
||||
|
||||
std::string print() const;
|
||||
std::string print();
|
||||
};
|
||||
|
||||
struct VifCodeStcycl {
|
||||
|
||||
@@ -240,7 +240,6 @@ static FormFormattingConfig new_top_level_inline_form(bool elide_new_line) {
|
||||
|
||||
const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config = {
|
||||
{"case", new_pair_rule(true)},
|
||||
{"case-str", new_pair_rule(true)},
|
||||
{"cond", new_pair_rule(false)},
|
||||
{"#cond", new_pair_rule(false)},
|
||||
{"in-package", new_top_level_inline_form(true)},
|
||||
|
||||
@@ -26,8 +26,6 @@ u64 get_current_tid() {
|
||||
}
|
||||
#endif
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/compress.h"
|
||||
#include "common/util/string_util.h"
|
||||
// clang-format on
|
||||
|
||||
u64 get_current_ts() {
|
||||
@@ -36,12 +34,12 @@ u64 get_current_ts() {
|
||||
|
||||
GlobalProfiler::GlobalProfiler() {
|
||||
m_t0 = get_current_ts();
|
||||
m_nodes.resize(m_max_events);
|
||||
set_max_events(65536);
|
||||
}
|
||||
|
||||
void GlobalProfiler::update_event_buffer_size(size_t new_size) {
|
||||
m_max_events = new_size;
|
||||
m_nodes.resize(m_max_events);
|
||||
void GlobalProfiler::set_max_events(size_t event_count) {
|
||||
ASSERT(!m_enabled);
|
||||
m_nodes.resize(event_count);
|
||||
}
|
||||
|
||||
void GlobalProfiler::set_waiting_for_event(const std::string& event_name) {
|
||||
@@ -74,10 +72,6 @@ void GlobalProfiler::root_event() {
|
||||
instant_event("ROOT");
|
||||
}
|
||||
|
||||
size_t GlobalProfiler::get_next_idx() {
|
||||
return (m_next_idx % m_nodes.size());
|
||||
}
|
||||
|
||||
void GlobalProfiler::begin_event(const char* name) {
|
||||
event(name, ProfNode::BEGIN);
|
||||
}
|
||||
@@ -102,10 +96,8 @@ void GlobalProfiler::set_enable(bool en) {
|
||||
m_enabled = en;
|
||||
}
|
||||
|
||||
void GlobalProfiler::dump_to_json() {
|
||||
if (m_enabled) {
|
||||
set_enable(false);
|
||||
}
|
||||
void GlobalProfiler::dump_to_json(const std::string& path) {
|
||||
ASSERT(!m_enabled);
|
||||
|
||||
nlohmann::json json;
|
||||
auto& trace_events = json["traceEvents"];
|
||||
@@ -193,20 +185,7 @@ void GlobalProfiler::dump_to_json() {
|
||||
t.second.highest_at_target);
|
||||
}
|
||||
|
||||
if (m_enable_compression) {
|
||||
const auto json_str = json.dump();
|
||||
const auto compressed_data =
|
||||
compression::compress_zstd_no_header(json_str.data(), json_str.size());
|
||||
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
|
||||
fmt::format("prof-{}.json.zst", str_util::current_local_timestamp_no_colons());
|
||||
file_util::create_dir_if_needed_for_file(file_path);
|
||||
file_util::write_binary_file(file_path, compressed_data.data(), compressed_data.size());
|
||||
} else {
|
||||
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
|
||||
fmt::format("prof-{}.json", str_util::current_local_timestamp_no_colons());
|
||||
file_util::create_dir_if_needed_for_file(file_path);
|
||||
file_util::write_text_file(file_path, json.dump());
|
||||
}
|
||||
file_util::write_text_file(path, json.dump());
|
||||
}
|
||||
|
||||
GlobalProfiler gprof;
|
||||
|
||||
@@ -17,8 +17,7 @@ struct ProfNode {
|
||||
class GlobalProfiler {
|
||||
public:
|
||||
GlobalProfiler();
|
||||
size_t get_max_events() { return m_max_events; }
|
||||
void update_event_buffer_size(size_t new_size);
|
||||
void set_max_events(size_t event_count);
|
||||
void set_waiting_for_event(const std::string& event_name);
|
||||
void instant_event(const char* name);
|
||||
void begin_event(const char* name);
|
||||
@@ -26,16 +25,11 @@ class GlobalProfiler {
|
||||
void end_event();
|
||||
void clear();
|
||||
void set_enable(bool en);
|
||||
void dump_to_json();
|
||||
void dump_to_json(const std::string& path);
|
||||
void root_event();
|
||||
bool is_enabled() { return m_enabled; }
|
||||
size_t get_next_idx();
|
||||
|
||||
bool m_enable_compression = false;
|
||||
|
||||
private:
|
||||
std::atomic_bool m_enabled = false;
|
||||
size_t m_max_events = 65536;
|
||||
u64 m_t0 = 0;
|
||||
std::atomic_size_t m_next_idx = 0;
|
||||
std::vector<ProfNode> m_nodes;
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ void printstd(const char* format, va_list arg_list) {
|
||||
internal::log_vprintf(format, arg_list);
|
||||
}
|
||||
|
||||
// how many extra log files for a single program should be kept
|
||||
// how many extra log files for a single program should be kept?
|
||||
constexpr int LOG_ROTATE_MAX = 10;
|
||||
|
||||
void set_file(const std::string& filename,
|
||||
|
||||
@@ -29,11 +29,8 @@ class Wrapper {
|
||||
Wrapper(const std::string& _username,
|
||||
const Config& config,
|
||||
const StartupFile& startup,
|
||||
bool _nrepl_alive)
|
||||
: username(_username),
|
||||
repl_config(config),
|
||||
startup_file(startup),
|
||||
nrepl_alive(_nrepl_alive) {}
|
||||
bool nrepl_alive)
|
||||
: username(_username), repl_config(config), startup_file(startup), nrepl_alive(nrepl_alive) {}
|
||||
replxx::Replxx& get_repl() { return repl; }
|
||||
void init_settings();
|
||||
void reload_startup_file();
|
||||
|
||||
@@ -43,151 +43,7 @@ std::vector<std::string> jak2_slots = {
|
||||
};
|
||||
|
||||
std::vector<std::string> jak3_slots = {
|
||||
"skull-gem-dest",
|
||||
"jakc-arm",
|
||||
"jakc-eyebrow",
|
||||
"jakc-face",
|
||||
"jakc-finger",
|
||||
"jakc-hair",
|
||||
"jakchires-arm",
|
||||
"jakchires-eye",
|
||||
"jakchires-eyebrow",
|
||||
"jakchires-eyelid",
|
||||
"jakchires-facelft",
|
||||
"jakchires-facert",
|
||||
"jakchires-hair",
|
||||
// default-water
|
||||
"bomb-gradient",
|
||||
"blue-beam-dest",
|
||||
"lightjak-wings",
|
||||
"mushroom-dest",
|
||||
// default-warp
|
||||
"shield-env-rim-dest",
|
||||
// templea-water
|
||||
"templea-waterfall-dest",
|
||||
// templea-warp
|
||||
"holograph-env-rim-dest",
|
||||
// hanga-sprite
|
||||
"glider-ring-dest2",
|
||||
"glider-ring-dest",
|
||||
// foresta-water
|
||||
"fora-water-dest",
|
||||
"fora-waterfall-01-dest",
|
||||
"fora-water-wave-01-dest",
|
||||
// forestb-water
|
||||
"forb-water-dest",
|
||||
"forb-waterfall-01-dest",
|
||||
"forb-water-wave-01-dest",
|
||||
// lforplnt-pris
|
||||
"mh-gem-dest",
|
||||
// lmhcitya-tfrag
|
||||
"mhcitya-base-goo-01-dest",
|
||||
// lmhcityb-tfrag
|
||||
"mhcityb-base-goo-01-dest",
|
||||
// mhcitya-pris
|
||||
// "mhcity-de-door-skin-01-dest",
|
||||
// templec-water
|
||||
"tplc-water-dest",
|
||||
// sewc-water
|
||||
"sewer-water-01-c-dest",
|
||||
"sewer-waterfall-01-c-dest",
|
||||
"sewer-waterfall-02-c-dest",
|
||||
"sewer-water-wave-01-c-dest",
|
||||
"sewer-water-highlight-01-c-dest",
|
||||
// sewd-water
|
||||
"sewer-water-01-d-dest",
|
||||
"sewer-waterfall-02-d-dest",
|
||||
"sewer-water-highlight-01-d-dest",
|
||||
"sewer-water-wave-01-d-dest",
|
||||
"sewer-water-wave-02-d-dest",
|
||||
"sewer-water-still-01-d-dest",
|
||||
// sewe-water
|
||||
"sewer-water-01-e-dest",
|
||||
"sewer-waterfall-01-e-dest",
|
||||
"sewer-waterfall-02-e-dest",
|
||||
"sewer-water-highlight-01-e-dest",
|
||||
// sewg-water
|
||||
"sewer-water-01-g-dest",
|
||||
"sewer-waterfall-02-g-dest",
|
||||
"sewer-water-wave-01-g-dest",
|
||||
// sewh-water
|
||||
"sewer-water-01-h-dest",
|
||||
"sewer-waterfall-02-h-dest",
|
||||
"sewer-water-wave-02-h-dest",
|
||||
"sewer-watefall-froth-01-h-dest",
|
||||
// sewi-water
|
||||
"sewer-water-still-01-i-dest",
|
||||
"sewer-waterfall-02-i-dest",
|
||||
"sewer-water-wave-01-i-dest",
|
||||
// sewj-water
|
||||
"sewer-waterfall-02-j-dest",
|
||||
"sewer-watefall-froth-01-j-dest",
|
||||
// sewl-water
|
||||
"sewer-waterfall-02-l-dest",
|
||||
"sewer-watefall-froth-01-l-dest",
|
||||
// sewm-water
|
||||
"sewer-water-01-m-dest",
|
||||
"sewer-waterfall-01-m-dest",
|
||||
"sewer-waterfall-02-m-dest",
|
||||
"sewer-water-highlight-01-m-dest",
|
||||
"sewer-water-wave-01-m-dest",
|
||||
"sewer-water-still-01-m-dest",
|
||||
"sewer-watefall-froth-01-m-dest",
|
||||
// sewn-water
|
||||
"sewer-waterfall-01-n-dest",
|
||||
"sewer-waterfall-02-n-dest",
|
||||
// "sewer-water-highlight-01-n-dest",
|
||||
"sewer-water-wave-01-n-dest",
|
||||
"sewer-water-still-01-n-dest",
|
||||
// hanga-water
|
||||
// "des-thermal-01-dest",
|
||||
// desresc-warp
|
||||
"sat-shield-dest",
|
||||
// security
|
||||
"security-env-dest",
|
||||
"security-dot-dest",
|
||||
// lgunnorm-water
|
||||
"kg-target-c-forcefield-01-dest",
|
||||
// templex-water
|
||||
"temple-waterfall-dest",
|
||||
// desertd-water
|
||||
"des-waterfall-dest",
|
||||
// towerb-water
|
||||
"tow-energy-bridge-dest",
|
||||
// factoryb-water
|
||||
"hemi-gradient-dest",
|
||||
"hemi-gradient-flames-dest",
|
||||
// factoryc-alpha
|
||||
"facc-convey-dest",
|
||||
"facc-convey-02-dest",
|
||||
// waspal-water
|
||||
"waspala-water-dest",
|
||||
"waspala-waterfall-dest",
|
||||
// rubblea-water
|
||||
"rub-water-dest",
|
||||
// rubblea2-water
|
||||
"rub-water-desta2",
|
||||
// rubbleb-water
|
||||
"rub-water-destb",
|
||||
// rubblec-water
|
||||
"rub-water-destc",
|
||||
// nstb-quicksand
|
||||
"nstb-quicksand-dest",
|
||||
// ctyslumb-water
|
||||
"ctyslumb-water-dest",
|
||||
"ctyslumb-fountain-fall-dest",
|
||||
// ctyslumc-water
|
||||
"ctyslumc-water-dest",
|
||||
"ctyslumc-fountain-fall-dest",
|
||||
// mined-tfrag
|
||||
"mined-pillar-side-dest",
|
||||
"mined-pillar-top2side-dest",
|
||||
"mined-pillar-top-dest",
|
||||
// volcanoa-alpha
|
||||
"vola-lava-01-dest",
|
||||
"vola-lava-fall-dest",
|
||||
// wasstada-alpha
|
||||
"wstd-lava-base-dest",
|
||||
"skull-gem-dest", "jakc-arm", "jakc-eyebrow", "jakc-face", "jakc-finger", "jakc-hair",
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#include "BinaryWriter.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
void build_dgo(const DgoDescription& description, const std::string& output_prefix) {
|
||||
BinaryWriter writer;
|
||||
// dgo header
|
||||
@@ -17,14 +15,8 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
|
||||
writer.add_cstr_len(description.dgo_name.c_str(), 60);
|
||||
|
||||
for (auto& obj : description.entries) {
|
||||
// Ensure the directory exists
|
||||
const auto file_path =
|
||||
file_util::get_jak_project_dir() / "out" / output_prefix / "obj" / obj.file_name;
|
||||
if (!file_util::file_exists(file_path.string())) {
|
||||
lg::warn("tried to build a DGO with a file that doesn't exist: {}", file_path.string());
|
||||
continue;
|
||||
}
|
||||
auto obj_data = file_util::read_binary_file(file_path);
|
||||
auto obj_data = file_util::read_binary_file(file_util::get_jak_project_dir() / "out" /
|
||||
output_prefix / "obj" / obj.file_name);
|
||||
// size
|
||||
writer.add<uint32_t>(obj_data.size());
|
||||
// name
|
||||
@@ -37,9 +29,6 @@ void build_dgo(const DgoDescription& description, const std::string& output_pref
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the output directory exists
|
||||
const auto dgo_path =
|
||||
file_util::get_jak_project_dir() / "out" / output_prefix / "iso" / description.dgo_name;
|
||||
file_util::create_dir_if_needed_for_file(dgo_path);
|
||||
writer.write_to_file(dgo_path);
|
||||
writer.write_to_file(file_util::get_jak_project_dir() / "out" / output_prefix / "iso" /
|
||||
description.dgo_name);
|
||||
}
|
||||
@@ -46,17 +46,4 @@ std::vector<u8> decompress_zstd(const void* data, size_t size) {
|
||||
ASSERT(decomp_size == decompressed_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<u8> compress_zstd_no_header(const void* data, size_t size) {
|
||||
size_t max_compressed = ZSTD_compressBound(size);
|
||||
std::vector<u8> result(max_compressed);
|
||||
|
||||
size_t compressed_size = ZSTD_compress(result.data(), max_compressed, data, size, 1);
|
||||
if (ZSTD_isError(compressed_size)) {
|
||||
ASSERT_MSG(false, fmt::format("ZSTD error: {}", ZSTD_getErrorName(compressed_size)));
|
||||
}
|
||||
|
||||
result.resize(compressed_size);
|
||||
return result;
|
||||
}
|
||||
} // namespace compression
|
||||
@@ -8,5 +8,4 @@ namespace compression {
|
||||
// compress and decompress data with zstd
|
||||
std::vector<u8> compress_zstd(const void* data, size_t size);
|
||||
std::vector<u8> decompress_zstd(const void* data, size_t size);
|
||||
std::vector<u8> compress_zstd_no_header(const void* data, size_t size);
|
||||
} // namespace compression
|
||||
} // namespace compression
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
inline u64 fnv64(const void* data, u64 len) {
|
||||
u64 ret = 0xcbf29ce484222325;
|
||||
const auto* ptr = (const u8*)data;
|
||||
for (u64 i = 0; i < len; i++) {
|
||||
ret = 1099511628211 * (((u64)*ptr) ^ ret);
|
||||
ptr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline u64 fnv64(const std::string& str) {
|
||||
return fnv64(str.data(), str.length());
|
||||
}
|
||||
@@ -27,11 +27,11 @@ Range<int> parse_json_optional_integer_range(const nlohmann::json& json);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void json_get_optional(const nlohmann::json& j,
|
||||
void json_get_optional(const nlohmann::json& json,
|
||||
const std::string& key,
|
||||
std::optional<T>& optionalValue) {
|
||||
if (j.contains(key) && !j[key].is_null()) {
|
||||
optionalValue = j[key].get<T>();
|
||||
if (json.contains(key) && !json[key].is_null()) {
|
||||
optionalValue = json[key].get<T>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
// Note: You will still have to add them to your level's .gd file.
|
||||
// "art_groups": ["plat-ag"],
|
||||
|
||||
// If you have any custom models in the "custom_assets/jak1/models/custom_levels" folder that you want to use in your level, add them to this list.
|
||||
// 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"],
|
||||
|
||||
|
||||
File renamed without changes.
@@ -68,7 +68,6 @@ add_library(
|
||||
level_extractor/fr3_to_gltf.cpp
|
||||
level_extractor/MercData.cpp
|
||||
level_extractor/tfrag_tie_fixup.cpp
|
||||
level_extractor/merc_replacement.cpp
|
||||
|
||||
ObjectFile/LinkedObjectFile.cpp
|
||||
ObjectFile/LinkedObjectFileCreation.cpp
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace decompiler {
|
||||
*/
|
||||
class LinkedObjectFile {
|
||||
public:
|
||||
LinkedObjectFile(GameVersion _version) : version(_version) {}
|
||||
LinkedObjectFile(GameVersion version) : version(version){};
|
||||
void set_segment_count(int n_segs);
|
||||
void push_back_word_to_segment(uint32_t word, int segment);
|
||||
int get_label_id_for(int seg, int offset);
|
||||
|
||||
@@ -54,8 +54,12 @@ void append_body_to_function_definition(goos::Object* top_form,
|
||||
body_elements.insert(body_elements.end(), inline_body.begin(), inline_body.end());
|
||||
// If the first element in the body is a docstring, add it first
|
||||
if (body_elements.size() > 0 && body_elements.at(0).is_string()) {
|
||||
initial_top_level_forms.push_back(
|
||||
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
|
||||
if (version > GameVersion::Jak2) {
|
||||
initial_top_level_forms.push_back(
|
||||
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
|
||||
} else {
|
||||
initial_top_level_forms.push_back(inline_body.at(0));
|
||||
}
|
||||
body_elements.erase(body_elements.begin());
|
||||
}
|
||||
|
||||
|
||||
@@ -21102,7 +21102,7 @@
|
||||
:size-assert #x94
|
||||
:flag-assert #xf00300094
|
||||
(:methods
|
||||
(spawn-particles! (_type_) none))
|
||||
(dumb-15 (_type_) none))
|
||||
(:states
|
||||
hud-normal
|
||||
hud-coming-in
|
||||
|
||||
@@ -2515,7 +2515,6 @@
|
||||
(iop-mem 48)
|
||||
(cancel-dgo 49)
|
||||
(set-stereo-mode 50) ;; sound-rpc-set-stereo-mode
|
||||
(set-mirror 201)
|
||||
)
|
||||
|
||||
(defenum sound-group
|
||||
@@ -2830,17 +2829,6 @@
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
; added
|
||||
(defenum sound-mirror-mode
|
||||
:type uint8
|
||||
(normal)
|
||||
(mirrored)
|
||||
)
|
||||
|
||||
; added for mirror mode
|
||||
(deftype sound-rpc-set-mirror-mode (sound-rpc-cmd)
|
||||
((mirror sound-mirror-mode)))
|
||||
|
||||
(deftype sound-rpc-union (structure)
|
||||
((data uint32 20 :offset-assert 0)
|
||||
(load-bank sound-rpc-load-bank :offset 0)
|
||||
@@ -2864,7 +2852,6 @@
|
||||
(shutdown sound-rpc-shutdown :offset 0)
|
||||
(list-sounds sound-rpc-list-sounds :offset 0)
|
||||
(unload-music sound-rpc-unload-music :offset 0)
|
||||
(mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0))
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x50
|
||||
|
||||
+108
-177
@@ -15147,8 +15147,8 @@
|
||||
:size-assert #x4
|
||||
:flag-assert #xb00000004
|
||||
(:methods
|
||||
(update! (_type_) int) ;; 9
|
||||
(setup-from-params! (_type_ cloth-params handle) int) ;; 10
|
||||
(init! (_type_) int) ;; 9
|
||||
(cloth-base-method-10 (_type_ cloth-params handle) int) ;; 10
|
||||
)
|
||||
)
|
||||
|
||||
@@ -25908,33 +25908,8 @@
|
||||
:flag-assert #xe00000010
|
||||
)
|
||||
|
||||
;; doesn't exist, but referenced by type ref in the entity table.
|
||||
(deftype sail-boat-a (process-drawable-reserved)
|
||||
()
|
||||
)
|
||||
|
||||
(deftype cty-window-a (process-drawable-reserved)
|
||||
()
|
||||
)
|
||||
|
||||
(deftype city-window-a (process-drawable-reserved)
|
||||
()
|
||||
)
|
||||
|
||||
(deftype cty-guard-turret (process-drawable-reserved)
|
||||
()
|
||||
)
|
||||
|
||||
(deftype cty-fruit-stand (process-drawable-reserved)
|
||||
()
|
||||
)
|
||||
|
||||
(deftype torn (process-drawable-reserved)
|
||||
()
|
||||
)
|
||||
|
||||
(deftype entity-info (basic)
|
||||
((ptype object :offset-assert 4) ;; guessed by decompiler
|
||||
((ptype type :offset-assert 4) ;; guessed by decompiler
|
||||
(pool symbol :offset-assert 8) ;; guessed by decompiler
|
||||
(heap-size int32 :offset-assert 12)
|
||||
)
|
||||
@@ -33975,7 +33950,7 @@
|
||||
)
|
||||
|
||||
(deftype particle-array (inline-array-class)
|
||||
((data verlet-particle :dynamic :inline :offset-assert 16 :score 1)
|
||||
((data verlet-particle :dynamic :inline :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 14
|
||||
:size-assert #x10
|
||||
@@ -34042,12 +34017,12 @@
|
||||
:size-assert #x40
|
||||
:flag-assert #x1000000040
|
||||
(:methods
|
||||
(accumulate-external-forces!
|
||||
(calculate-wind!
|
||||
"If this cloth system has the wind flag, calculate the wind force."
|
||||
(_type_) none) ;; 11
|
||||
(compute-verlet-step (_type_ float) none) ;; 12
|
||||
(run-one-iteration "Run one iteration of the system." (_type_) none) ;; 13
|
||||
(reset! "Reset to stationary/default state." (_type_) none) ;; 14
|
||||
(verlet-particle-system-method-12 (_type_ float) none) ;; 12
|
||||
(verlet-particle-system-method-13 (_type_) none) ;; 13
|
||||
(verlet-particle-system-method-14 (_type_) none) ;; 14
|
||||
(debug-draw (_type_) none) ;; 15
|
||||
)
|
||||
)
|
||||
@@ -34107,9 +34082,9 @@
|
||||
"Set up this cloth system with the given [[cloth-params]]."
|
||||
(_type_ cloth-params) none) ;; 16
|
||||
(debug-draw-spheres (_type_) none) ;; 17
|
||||
(post-physics-update (_type_) int) ;; 18
|
||||
(enforce-constraints-1 (_type_) none) ;; 19
|
||||
(enforce-constraints-2 (_type_) none) ;; 20
|
||||
(cloth-system-method-18 (_type_) int) ;; 18
|
||||
(cloth-system-method-19 (_type_) none) ;; 19
|
||||
(cloth-system-method-20 (_type_) none) ;; 20
|
||||
(cloth-system-method-21 (_type_) none) ;; 21
|
||||
(cloth-system-method-22 (_type_) none) ;; 22
|
||||
(cloth-system-method-23 (_type_) none) ;; 23
|
||||
@@ -34123,9 +34098,9 @@
|
||||
(cloth-system-method-31 (_type_ current-position-info) none) ;; 31
|
||||
(cloth-system-method-32 (_type_ vector int int current-position-info) none) ;; 32
|
||||
(cloth-system-method-33 (_type_ vu-lights) none) ;; 33
|
||||
(hide! (_type_) none) ;; 34
|
||||
(reset-locations (_type_) none) ;; 35
|
||||
(pre-physics-update "Callback to update prior to running verlet integration. Can handle movement of the entire system in the world, for example" (_type_) none) ;; 36
|
||||
(cloth-system-method-34 (_type_) none) ;; 34
|
||||
(cloth-system-method-35 (_type_) none) ;; 35
|
||||
(cloth-system-method-36 (_type_) none) ;; 36
|
||||
(cloth-system-cmd-handler (_type_ pair) none) ;; 37
|
||||
)
|
||||
)
|
||||
@@ -34147,8 +34122,8 @@
|
||||
;; cloth ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern get-neighboring-faces (function vector4w int int int int int))
|
||||
(define-extern *normal-array* (inline-array vector))
|
||||
(define-extern get-neighboring-faces (function vector int int int int int))
|
||||
(define-extern *normal-array* (pointer vector))
|
||||
(define-extern light-vertex (function current-position-info vector rgba))
|
||||
(define-extern *once* symbol)
|
||||
(define-extern *cloth-fade-alpha* gs-alpha)
|
||||
@@ -34221,17 +34196,7 @@
|
||||
;; curves ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defenum loop-behavior
|
||||
:type uint64
|
||||
:bitfield #f
|
||||
(wrap)
|
||||
(clamp)
|
||||
(b2)
|
||||
(use-default)
|
||||
)
|
||||
|
||||
(deftype float-pair (structure)
|
||||
"Two floats. Specifies one point on a piecewise linear curve."
|
||||
((first float :offset-assert 0)
|
||||
(second float :offset-assert 4)
|
||||
(x float :offset 0)
|
||||
@@ -34243,7 +34208,6 @@
|
||||
)
|
||||
|
||||
(deftype float-pair-array (inline-array-class)
|
||||
"Array of points used to make a piecewise linear curve."
|
||||
((data float-pair :dynamic :inline :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 14
|
||||
@@ -34252,50 +34216,39 @@
|
||||
)
|
||||
|
||||
(deftype curve2d (basic)
|
||||
"Interface for evaluating a 2d curve.
|
||||
The input is a float (x-position) and the output is a float (y-position).
|
||||
The curve is over (0, 1). Values outside of the range are either clamped
|
||||
or wrapped depending on the loop-behavior flag."
|
||||
()
|
||||
:method-count-assert 10
|
||||
:size-assert #x4
|
||||
:flag-assert #xa00000004
|
||||
(:methods
|
||||
(evaluate "Compute value of curve at the given position." (_type_ float loop-behavior) float) ;; 9
|
||||
(curve2d-method-9 (_type_ float int) float) ;; 9
|
||||
)
|
||||
)
|
||||
|
||||
(deftype curve-color (basic)
|
||||
"Interface for evaluating a color curve. The input is a float, representing
|
||||
progress through the curve, and the result is a floating point rgba color."
|
||||
()
|
||||
:method-count-assert 10
|
||||
:size-assert #x4
|
||||
:flag-assert #xa00000004
|
||||
(:methods
|
||||
(evaluate "Compute value of curve at the given position." (_type_ float rgbaf loop-behavior) rgbaf) ;; 9
|
||||
(curve-color-method-9 (_type_ float rgbaf int) rgbaf) ;; 9
|
||||
)
|
||||
)
|
||||
|
||||
(deftype curve2d-piecewise (curve2d)
|
||||
"Implementation of 2d-curve for a piecewise linear curve.
|
||||
Not particularly efficient - each evaluation needs to check each point."
|
||||
((pts float-pair-array :offset-assert 4)
|
||||
(default-loop-behavior loop-behavior :offset-assert 8)
|
||||
(default-loop-behavior uint64 :offset-assert 8)
|
||||
)
|
||||
:method-count-assert 12
|
||||
:size-assert #x10
|
||||
:flag-assert #xc00000010
|
||||
(:methods
|
||||
(allocate! "Allocate memory for points." (_type_ int symbol symbol) none) ;; 10
|
||||
(curve2d-piecewise-method-10 (_type_ int symbol int) none) ;; 10
|
||||
(curve2d-piecewise-method-11 (_type_) none) ;; 11
|
||||
)
|
||||
)
|
||||
|
||||
(deftype curve2d-fast (curve2d)
|
||||
"Implementation of 2d piecewise linear curve which tries to be faster.
|
||||
While it is faster, it places the huge restriction that you can only have 4 points.
|
||||
Note that the xs should be negative here."
|
||||
((xs vector :inline :offset-assert 16)
|
||||
(ys vector :inline :offset-assert 32)
|
||||
(one-over-x-deltas vector :inline :offset-assert 48)
|
||||
@@ -34306,9 +34259,6 @@
|
||||
)
|
||||
|
||||
(deftype curve-color-fast (curve-color)
|
||||
"Implementation of color curve which tries to be faster.
|
||||
While it is faster, it again has the restriction that you only
|
||||
get 4 piecewise sections."
|
||||
((xs vector :inline :offset-assert 16)
|
||||
(ys vector 4 :inline :offset-assert 32)
|
||||
(one-over-x-deltas vector :inline :offset-assert 96)
|
||||
@@ -34319,8 +34269,6 @@
|
||||
)
|
||||
|
||||
(deftype color-pair (structure)
|
||||
"Single section of a piecewise linear color curve.
|
||||
Unlike the fast version, this stores x values exactly like you'd expect."
|
||||
((first float :offset-assert 0)
|
||||
(second rgbaf :inline :offset-assert 16)
|
||||
(x float :offset 0)
|
||||
@@ -34332,7 +34280,6 @@
|
||||
)
|
||||
|
||||
(deftype color-pair-array (inline-array-class)
|
||||
"Array of points for piecewise linear color curve."
|
||||
((data color-pair :dynamic :inline :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 14
|
||||
@@ -34341,22 +34288,21 @@
|
||||
)
|
||||
|
||||
(deftype curve-color-piecewise (curve-color)
|
||||
"Implementation of curve-color."
|
||||
((pts color-pair-array :offset-assert 4)
|
||||
(default-loop-behavior loop-behavior :offset-assert 8)
|
||||
(default-loop-behavior uint64 :offset-assert 8)
|
||||
)
|
||||
:method-count-assert 11
|
||||
:size-assert #x10
|
||||
:flag-assert #xb00000010
|
||||
(:methods
|
||||
(allocate! "Allocate memory for points." (_type_ int symbol symbol) none) ;; 10
|
||||
(curve-color-piecewise-method-10 (_type_ int symbol uint) none) ;; 10
|
||||
)
|
||||
)
|
||||
|
||||
(define-extern rgbaf-lerp! "Lerp all four components of rgba." (function rgbaf rgbaf rgbaf float rgbaf))
|
||||
(define-extern evaluate-curve-fast "Evaluate a curve2d-fast at the given value." (function curve2d-fast float float))
|
||||
(define-extern evaluate-color-curve-fast "Evaluate a color-curve-fast at the given value." (function curve-color-fast float rgbaf rgbaf))
|
||||
(define-extern rgba<-rgbaf "Convert rgbaf to rgba. Seems like the input rgba's value is not used in any way." (function rgba rgbaf rgba))
|
||||
(define-extern rgbaf-lerp! (function rgbaf rgbaf rgbaf float rgbaf))
|
||||
(define-extern evaluate-curve-fast (function curve2d-fast rgbaf rgbaf float))
|
||||
(define-extern evaluate-color-curve-fast (function curve-color-fast rgbaf rgbaf rgbaf))
|
||||
(define-extern rgba<-rgbaf (function rgba rgbaf int))
|
||||
(define-extern *curve-unity* curve2d-fast)
|
||||
(define-extern *curve-linear-up* curve2d-fast)
|
||||
(define-extern *curve-linear-down* curve2d-fast)
|
||||
@@ -34733,14 +34679,6 @@
|
||||
:flag-assert #xe00000010
|
||||
)
|
||||
|
||||
(defenum lie-mode
|
||||
:type uint64
|
||||
(appearance0)
|
||||
(appearance1)
|
||||
(appearance2)
|
||||
(use-two-strips 3)
|
||||
)
|
||||
|
||||
(deftype light-trail-composition (structure)
|
||||
((color-mode uint64 :offset-assert 0)
|
||||
(color-curve curve-color-piecewise :offset-assert 8)
|
||||
@@ -34758,8 +34696,8 @@
|
||||
(uv-mode uint64 :offset-assert 72)
|
||||
(uv-repeat-dist float :offset-assert 80)
|
||||
(max-age time-frame :offset-assert 88)
|
||||
(tex-id texture-id :offset-assert 96)
|
||||
(lie-mode lie-mode :offset-assert 104)
|
||||
(tex-id uint32 :offset-assert 96)
|
||||
(lie-mode uint64 :offset-assert 104)
|
||||
(lie-vector vector :inline :offset-assert 112)
|
||||
(zbuffer? symbol :offset-assert 128)
|
||||
(use-tape-mode? symbol :offset-assert 132)
|
||||
@@ -34773,7 +34711,7 @@
|
||||
|
||||
(deftype light-trail-breadcrumb (structure)
|
||||
((pos vector :inline :offset-assert 0)
|
||||
(birth-time uint32 :offset 12 :decomp-as time-frame :score 1)
|
||||
(birth-time uint32 :offset 12 :decomp-as time-frame)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
@@ -34788,22 +34726,15 @@
|
||||
:flag-assert #xe00000010
|
||||
)
|
||||
|
||||
(defenum light-trail-decision
|
||||
:type uint64
|
||||
(added 0)
|
||||
(not-added 1)
|
||||
(reset 2)
|
||||
)
|
||||
|
||||
(deftype light-trail (basic)
|
||||
((crumb-array (array uint8) :offset-assert 4)
|
||||
((crumb-array (array light-trail-breadcrumb) :offset-assert 4)
|
||||
(crumb-size uint8 :offset-assert 8)
|
||||
(crumb-count int16 :offset-assert 10)
|
||||
(max-crumb-count int16 :offset-assert 12)
|
||||
(appearance light-trail-composition :offset-assert 16)
|
||||
(start-marker uint64 :offset-assert 24)
|
||||
(end-marker uint64 :offset-assert 32)
|
||||
(decision light-trail-decision :offset-assert 40)
|
||||
(decision uint64 :offset-assert 40)
|
||||
(total-distance-traveled float :offset-assert 48)
|
||||
(strip prim-strip :offset-assert 52)
|
||||
(strip2 prim-strip :offset-assert 56)
|
||||
@@ -34813,19 +34744,19 @@
|
||||
:size-assert #x80
|
||||
:flag-assert #x1600000080
|
||||
(:methods
|
||||
(setup! "Initialize, including allocation of crumbs and strips on the process heap." (_type_ light-trail-composition int) none) ;; 9
|
||||
(reset! "Clear all tracked crumbs." (_type_) none) ;; 10
|
||||
(add-crumb! "Try adding a crumb, kicking out the oldest if there's not enough room. This may reject if it's too close to the previous." (_type_ vector time-frame) int) ;; 11
|
||||
(build-prim-strip! "Build the mesh for this light trail." (_type_) none) ;; 12
|
||||
(common-trans! "Call this on each frame to handle max-age." (_type_) int) ;; 13
|
||||
(expire-old-points! "Internal function to kill off points that are too old." (_type_) none) ;; 14
|
||||
(light-trail-method-9 (_type_ light-trail-composition int) none) ;; 9
|
||||
(light-trail-method-10 (_type_) none) ;; 10
|
||||
(light-trail-method-11 (_type_ vector time-frame) int) ;; 11
|
||||
(light-trail-method-12 (_type_) none) ;; 12
|
||||
(light-trail-method-13 (_type_) int) ;; 13
|
||||
(light-trail-method-14 (_type_) none) ;; 14
|
||||
(light-trail-method-15 (_type_) none) ;; 15
|
||||
(add-vert-to-prim-strip! "Add a single vertex to the prim." (_type_ prim-strip vector rgba float float) none) ;; 16
|
||||
(add-tri-pair-to-prim! "Add two vertices to the prim strip to add two triangles" (_type_ vector rgba float vector float) symbol) ;; 17
|
||||
(calc-vertex-pos! (_type_ light-trail-breadcrumb int vector vector) none) ;; 18
|
||||
(crumb-age-out-callback "To be implemented by the user to smoothly interpolate out non-default entries in their crumb type." (_type_ float int) none) ;; 19
|
||||
(add-vert! (_type_ prim-strip vector float float float) none) ;; 16
|
||||
(light-trail-method-17 (_type_ vector float float vector float) symbol) ;; 17
|
||||
(light-trail-method-18 (_type_ light-trail-breadcrumb int vector vector) none) ;; 18
|
||||
(light-trail-method-19 (_type_ float int) none) ;; 19
|
||||
(reset-crumbs! (_type_) none) ;; 20
|
||||
(replace-last-crumb! "Similar to add-crumb, but will modify the last crumb instead of advancing." (_type_ vector) none) ;; 21
|
||||
(light-trail-method-21 (_type_ vector) none) ;; 21
|
||||
)
|
||||
)
|
||||
|
||||
@@ -34843,7 +34774,7 @@
|
||||
:size-assert #x80
|
||||
:flag-assert #x1800000080
|
||||
(:methods
|
||||
(add-crumb-with-offset "Given two points, add the first and offset to a crumb." (_type_ vector vector) light-trail-breadcrumb) ;; 22
|
||||
(weapon-trail-method-22 (_type_ vector vector) light-trail-breadcrumb) ;; 22
|
||||
(weapon-trail-method-23 (_type_ vector vector) none) ;; 23
|
||||
)
|
||||
)
|
||||
@@ -34862,8 +34793,8 @@
|
||||
:size-assert #x80
|
||||
:flag-assert #x1800000080
|
||||
(:methods
|
||||
(add-crumb-with-offset (_type_ vector vector) none) ;; 22
|
||||
(tread-trail-method-23 (_type_ vector vector) none) ;; 23
|
||||
(tread-trail-method-22 (_type_ vector vector) light-trail-breadcrumb) ;; 22
|
||||
(tread-trail-method-23 (_type_ vector vector) light-trail-breadcrumb) ;; 23
|
||||
)
|
||||
)
|
||||
|
||||
@@ -34903,11 +34834,11 @@
|
||||
die ;; 15
|
||||
)
|
||||
(:methods
|
||||
(get-tracked-object-pos (_type_ process-focusable vector) vector) ;; 16
|
||||
(should-track? (_type_ process-focusable) symbol) ;; 17
|
||||
(should-end? (_type_ process-focusable) symbol) ;; 18
|
||||
(should-draw? (_type_) symbol) ;; 19
|
||||
(add-crumb! (_type_ vector) none) ;; 20
|
||||
(light-trail-tracker-method-16 (_type_ process-focusable vector) vector) ;; 16
|
||||
(light-trail-tracker-method-17 (_type_ process-focusable) symbol) ;; 17
|
||||
(light-trail-tracker-method-18 (_type_ process-focusable) symbol) ;; 18
|
||||
(light-trail-tracker-method-19 (_type_) symbol) ;; 19
|
||||
(light-trail-tracker-method-20 (_type_ vector) none) ;; 20
|
||||
)
|
||||
)
|
||||
|
||||
@@ -42848,7 +42779,7 @@
|
||||
:size-assert #xfc
|
||||
:flag-assert #x22008000fc
|
||||
(:methods
|
||||
(get-mgr-name (_type_) string) ;; 32
|
||||
(task-manager-desert-bbush-ring-method-32 (_type_) none) ;; 32
|
||||
(task-manager-desert-bbush-ring-method-33 (_type_) none) ;; 33
|
||||
)
|
||||
)
|
||||
@@ -44565,12 +44496,12 @@
|
||||
;; templea-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *templea-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *templea-warp-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern templea-warp-texture-anim-func (function none))
|
||||
(define-extern *templeb-warp-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern templeb-warp-texture-anim-func (function none))
|
||||
(define-extern *templec-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *templea-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *templea-warp-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern templea-warp-texture-anim-func function)
|
||||
;; (define-extern *templeb-warp-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern templeb-warp-texture-anim-func function)
|
||||
;; (define-extern *templec-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; hover-training ;;
|
||||
@@ -46353,16 +46284,16 @@
|
||||
;; sewer-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *sewc-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewd-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewe-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewg-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewh-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewi-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewj-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewl-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewm-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *sewn-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *sewc-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewd-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewe-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewg-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewh-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewi-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewj-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewl-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewm-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *sewn-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; kg-hopper ;;
|
||||
@@ -50356,7 +50287,7 @@
|
||||
;; desresc-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *desresc-warp-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *desresc-warp-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; desert-rescue ;;
|
||||
@@ -51053,7 +50984,7 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern check-drop-level-ctyslumb-drop-userdata (function sparticle-system sparticle-cpuinfo vector none))
|
||||
(define-extern *ctyslumb-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *ctyslumb-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; mech-part ;;
|
||||
@@ -51159,7 +51090,7 @@
|
||||
;; nstb-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *nstb-quicksand-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *nstb-quicksand-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; nst-mood ;;
|
||||
@@ -51802,7 +51733,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
(define-extern *ctyslumc-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *ctyslumc-water-texture-anim-array* texture-anim-array)
|
||||
(define-extern ctyslumc-flag-init-by-other (function vector entity-actor object :behavior ctyslumc-flag))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -51977,8 +51908,8 @@
|
||||
;; factoryc-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *factoryc-alpha-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern set-facc-conveyor-speed! (function float float))
|
||||
;; (define-extern *factoryc-alpha-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern set-facc-conveyor-speed! function)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; conveyor ;;
|
||||
@@ -52627,7 +52558,7 @@
|
||||
|
||||
(define-extern wang-texture-anim-init (function texture-anim none))
|
||||
(define-extern real-wang-texture-anim-func (function texture-anim texture-anim none))
|
||||
(define-extern wang-texture-anim-func (function texture-anim texture-anim none))
|
||||
(define-extern wang-texture-anim-func (function none))
|
||||
(define-extern *hfrag-texture-anim-array* (texture-anim-array texture-anim))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -54251,7 +54182,7 @@
|
||||
;; glider-ring-part ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *hanga-sprite-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *hanga-sprite-texture-anim-array* texture-anim-array)
|
||||
(define-extern cloud-shadow-find-ground (function vector matrix vector vector float))
|
||||
(define-extern birth-func-fader (function sparticle-system sparticle-cpuinfo sparticle-launchinfo none))
|
||||
(define-extern sparticle-fader (function sparticle-system sparticle-cpuinfo sparticle-launchinfo none))
|
||||
@@ -54454,7 +54385,7 @@
|
||||
(define-extern hanga-login (function level none))
|
||||
(define-extern hanga-activate (function level none))
|
||||
(define-extern hanga-deactivate (function level none))
|
||||
(define-extern *hanga-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *hanga-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; elec-gate ;;
|
||||
@@ -57106,7 +57037,7 @@
|
||||
;; desertd-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *desertd-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *desertd-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ctyfarm-obs ;;
|
||||
@@ -57930,7 +57861,7 @@
|
||||
|
||||
(deftype tire-trail-crumb (light-trail-breadcrumb)
|
||||
((offset vector :inline :offset-assert 16)
|
||||
(uu float :offset 28 :score 1)
|
||||
(uu float :offset 28)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
@@ -57943,13 +57874,13 @@
|
||||
:size-assert #x80
|
||||
:flag-assert #x1800000080
|
||||
(:methods
|
||||
(add-crumb-with-offset-and-uu (_type_ vector vector float) none) ;; 22
|
||||
(tire-trail-method-23 (_type_ vector vector float) none) ;; 23
|
||||
(tire-trail-method-22 (_type_) none) ;; 22
|
||||
(tire-trail-method-23 (_type_) none) ;; 23
|
||||
)
|
||||
)
|
||||
|
||||
(deftype tire-trail-tracker (light-trail-tracker)
|
||||
((trail tire-trail :override))
|
||||
()
|
||||
:method-count-assert 21
|
||||
:size-assert #xac
|
||||
:flag-assert #x15003000ac
|
||||
@@ -60350,7 +60281,7 @@
|
||||
;; mhcityb-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *lmhcityb-tfrag-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *lmhcityb-tfrag-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; rublcst-scenes ;;
|
||||
@@ -61360,7 +61291,7 @@
|
||||
(define-extern init-mood-tower (function mood-context float))
|
||||
(define-extern update-tower-lights (function mood-context none))
|
||||
(define-extern update-mood-tower (function mood-context float int none :behavior time-of-day-proc))
|
||||
(define-extern *towerb-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *towerb-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; tower-scenes ;;
|
||||
@@ -63400,7 +63331,7 @@
|
||||
;; wasstada-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *wasstada-alpha-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *wasstada-alpha-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; wasstada-mood ;;
|
||||
@@ -63424,7 +63355,7 @@
|
||||
;; factorya-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *factoryb-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *factoryb-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; factoryb-init ;;
|
||||
@@ -63436,9 +63367,9 @@
|
||||
;; mhcitya-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *lmhcitya-tfrag-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *mhcitya-pris-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern set-mhcity-de-door-skin! (function float float))
|
||||
;; (define-extern *lmhcitya-tfrag-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *mhcitya-pris-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern set-mhcity-de-door-skin! function)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ctyinda-part ;;
|
||||
@@ -63746,10 +63677,10 @@
|
||||
;; rubble-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *rubblea-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *rubblea2-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *rubbleb-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *rubblec-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *rubblea-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *rubblea2-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *rubbleb-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *rubblec-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; stadiuma-part ;;
|
||||
@@ -65220,9 +65151,9 @@
|
||||
;; forest-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *foresta-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *forestb-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *lforplnt-pris-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *foresta-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *forestb-water-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern *lforplnt-pris-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; forest-ring-chase ;;
|
||||
@@ -65479,8 +65410,8 @@
|
||||
;; ltnfxhip-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *ltnfxhip-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern ltnfxhip-texture-anim-func (function none))
|
||||
;; (define-extern *ltnfxhip-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern ltnfxhip-texture-anim-func function)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ctygenb-part ;;
|
||||
@@ -67881,7 +67812,7 @@
|
||||
;; gungame-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *lgunnorm-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *lgunnorm-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; gungame-obs ;;
|
||||
@@ -68161,8 +68092,8 @@
|
||||
;; ljkdxvin-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *ljkdxvin-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern ljkdxvin-texture-anim-func (function none))
|
||||
;; (define-extern *ljkdxvin-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern ljkdxvin-texture-anim-func function)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; target-tube ;;
|
||||
@@ -71558,7 +71489,7 @@
|
||||
;; waspal-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *waspal-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *waspal-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; throne-scenes ;;
|
||||
@@ -72734,7 +72665,7 @@
|
||||
;; mined-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *mined-tfrag-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern *mined-tfrag-texture-anim-array* texture-anim-array)
|
||||
(define-extern set-mined-pillar-texture! (function float none))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -73120,8 +73051,8 @@
|
||||
;; volcanox-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *volcanox-warp-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern volcanox-warp-texture-anim-func (function none))
|
||||
;; (define-extern *volcanox-warp-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern volcanox-warp-texture-anim-func function)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; volcanox-mood ;;
|
||||
@@ -73321,7 +73252,7 @@
|
||||
;; templex-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *templex-water-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *templex-water-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; templex-scenes ;;
|
||||
@@ -73704,7 +73635,7 @@
|
||||
;; volcano-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *volcanoa-alpha-texture-anim-array* (texture-anim-array texture-anim))
|
||||
;; (define-extern *volcanoa-alpha-texture-anim-array* texture-anim-array)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; spiky-frog ;;
|
||||
@@ -74417,8 +74348,8 @@
|
||||
;; deshover-texture ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *deshover-texture-anim-array* (texture-anim-array texture-anim))
|
||||
(define-extern deshover-texture-anim-func (function none))
|
||||
;; (define-extern *deshover-texture-anim-array* texture-anim-array)
|
||||
;; (define-extern deshover-texture-anim-func function)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; terraformer-head ;;
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
[7, "(function none)"],
|
||||
[3, "(function symbol :behavior process)"]
|
||||
],
|
||||
"scene": [[4, "(function symbol :behavior scene-player)"]],
|
||||
"scene": [[4, "(function none :behavior scene-player)"]],
|
||||
"pov-camera": [
|
||||
[
|
||||
7,
|
||||
|
||||
@@ -361,315 +361,11 @@
|
||||
"jakc-finger-dark",
|
||||
"jakc-hair-dark",
|
||||
|
||||
// darkjak-highres
|
||||
"jakchires-arm",
|
||||
"jakchires-arm-norm",
|
||||
"jakchires-arm-dark",
|
||||
"jakchires-eye",
|
||||
"jakchires-eye-norm",
|
||||
"jakchires-eye-dark",
|
||||
"jakchires-eyebrow",
|
||||
"jakchires-eyebrow-norm",
|
||||
"jakchires-eyebrow-dark",
|
||||
"jakchires-eyelid",
|
||||
"jakchires-eyelid-norm",
|
||||
"jakchires-eyelid-dark",
|
||||
"jakchires-facelft",
|
||||
"jakchires-facelft-norm",
|
||||
"jakchires-facelft-dark",
|
||||
"jakchires-facert",
|
||||
"jakchires-facert-norm",
|
||||
"jakchires-facert-dark",
|
||||
"jakchires-hair",
|
||||
"jakchires-hair-norm",
|
||||
"jakchires-hair-dark",
|
||||
|
||||
// Skull Gem
|
||||
"skull-gem-dest",
|
||||
"skull-gem-alpha-00",
|
||||
"skull-gem-alpha-01",
|
||||
"skull-gem-alpha-02",
|
||||
|
||||
// default-water
|
||||
"bomb-gradient",
|
||||
"bomb-gradient-rim",
|
||||
"bomb-gradient-flames",
|
||||
"lightjak-wings",
|
||||
"lighjak-wings-u-src",
|
||||
"lightjak-wings-v-src",
|
||||
"mushroom-dest",
|
||||
"mushroom-src",
|
||||
|
||||
// default-warp
|
||||
"shield-env-rim-dest",
|
||||
"common-white",
|
||||
"shield-env-uscroll",
|
||||
"shield-env-rim-src",
|
||||
|
||||
// hanga-sprite
|
||||
"glider-ring-dest2",
|
||||
"glider-ring-dest",
|
||||
"splash-foam",
|
||||
"racegate",
|
||||
|
||||
// templea-water
|
||||
"templea-waterfall-dest",
|
||||
"templea-waterfall",
|
||||
|
||||
// templea-warp
|
||||
"holograph-env-rim-dest",
|
||||
"holograph-env-noise",
|
||||
"holograph-env-scan",
|
||||
"holograph-env-rim",
|
||||
"environment-phong-rim",
|
||||
|
||||
// foresta-water
|
||||
"fora-water-dest",
|
||||
"fora-water",
|
||||
"fora-waterfall-01-dest",
|
||||
"fora-waterfall-01",
|
||||
"fora-water-wave-01-dest",
|
||||
"fora-water-wave-01",
|
||||
|
||||
// forestb-water
|
||||
"forb-water-dest",
|
||||
"forb-water",
|
||||
"forb-waterfall-01-dest",
|
||||
"forb-waterfall-01",
|
||||
"forb-water-wave-01-dest",
|
||||
"forb-water-wave-01",
|
||||
|
||||
// lforplnt-pris
|
||||
"mh-gem-dest",
|
||||
"mh-gem",
|
||||
"mh-gem-alpha-01",
|
||||
"mh-gem-alpha-02",
|
||||
|
||||
// lmhcitya-tfrag
|
||||
"mhcitya-base-goo-01-dest",
|
||||
"mhcitya-base-goo-01",
|
||||
|
||||
// lmhcityb-tfrag
|
||||
"mhcityb-base-goo-01-dest",
|
||||
"mhcityb-base-goo-01",
|
||||
|
||||
// mhcitya-pris
|
||||
// "mhcity-de-door-skin-01-dest",
|
||||
// "mhcity-de-door-skin-01",
|
||||
// "mhcity-de-door-skin-02"
|
||||
|
||||
// templec-water
|
||||
"tplc-water-dest",
|
||||
"tplc-water",
|
||||
|
||||
// sewc-water
|
||||
"sewer-water-01-c-dest",
|
||||
"sewer-water-01-c",
|
||||
"sewer-waterfall-01-c-dest",
|
||||
"sewer-waterfall-01-c",
|
||||
"sewer-waterfall-02-c-dest",
|
||||
"sewer-waterfall-02-c",
|
||||
"sewer-water-wave-01-c-dest",
|
||||
"sewer-water-wave-01-c",
|
||||
"sewer-water-highlight-01-c-dest",
|
||||
"sewer-water-highlight-01-c",
|
||||
|
||||
// sewd-water
|
||||
"sewer-water-01-d-dest",
|
||||
"sewer-water-01-d",
|
||||
"sewer-waterfall-02-d-dest",
|
||||
"sewer-waterfall-02-d",
|
||||
"sewer-water-highlight-01-d-dest",
|
||||
"sewer-water-highlight-01-d",
|
||||
"sewer-water-wave-01-d-dest",
|
||||
"sewer-water-wave-01-d",
|
||||
"sewer-water-wave-02-d-dest",
|
||||
"sewer-water-wave-02-d",
|
||||
"sewer-water-still-01-d-dest",
|
||||
"sewer-water-still-01-d",
|
||||
|
||||
// sewe-water
|
||||
"sewer-water-01-e-dest",
|
||||
"sewer-water-01-e",
|
||||
"sewer-waterfall-01-e-dest",
|
||||
"sewer-waterfall-01-e",
|
||||
"sewer-waterfall-02-e-dest",
|
||||
"sewer-waterfall-02-e",
|
||||
"sewer-water-highlight-01-e-dest",
|
||||
"sewer-water-highlight-01-e",
|
||||
|
||||
// sewg-water
|
||||
"sewer-water-01-g-dest",
|
||||
"sewer-water-01-g",
|
||||
"sewer-waterfall-02-g-dest",
|
||||
"sewer-waterfall-02-g",
|
||||
"sewer-water-wave-01-g-dest",
|
||||
"sewer-water-wave-01-g",
|
||||
|
||||
// sewh-water
|
||||
"sewer-water-01-h-dest",
|
||||
"sewer-water-01-h",
|
||||
"sewer-waterfall-02-h-dest",
|
||||
"sewer-waterfall-02-h",
|
||||
"sewer-water-wave-02-h-dest",
|
||||
"sewer-water-wave-02-h",
|
||||
"sewer-watefall-froth-01-h-dest",
|
||||
"sewer-watefall-froth-01-h",
|
||||
|
||||
// sewi-water
|
||||
"sewer-water-still-01-i-dest",
|
||||
"sewer-water-still-01-i",
|
||||
"sewer-waterfall-02-i-dest",
|
||||
"sewer-waterfall-02-i",
|
||||
"sewer-water-wave-01-i-dest",
|
||||
"sewer-water-wave-01-i",
|
||||
|
||||
// sewj-water
|
||||
"sewer-waterfall-02-j-dest",
|
||||
"sewer-waterfall-02-j",
|
||||
"sewer-watefall-froth-01-j-dest",
|
||||
"sewer-watefall-froth-01-j",
|
||||
|
||||
// sewl-water
|
||||
"sewer-waterfall-02-l-dest",
|
||||
"sewer-waterfall-02-l",
|
||||
"sewer-watefall-froth-01-l-dest",
|
||||
"sewer-watefall-froth-01-l",
|
||||
|
||||
// sewm-water
|
||||
"sewer-water-01-m-dest",
|
||||
"sewer-water-01-m",
|
||||
"sewer-waterfall-01-m-dest",
|
||||
"sewer-waterfall-01-m",
|
||||
"sewer-waterfall-02-m-dest",
|
||||
"sewer-waterfall-02-m",
|
||||
"sewer-water-highlight-01-m-dest",
|
||||
"sewer-water-highlight-01-m",
|
||||
"sewer-water-wave-01-m-dest",
|
||||
"sewer-water-wave-01-m",
|
||||
"sewer-water-still-01-m-dest",
|
||||
"sewer-water-still-01-m",
|
||||
"sewer-watefall-froth-01-m-dest",
|
||||
"sewer-watefall-froth-01-m",
|
||||
|
||||
// sewn-water
|
||||
"sewer-waterfall-01-n-dest",
|
||||
"sewer-waterfall-01-n",
|
||||
"sewer-waterfall-02-n-dest",
|
||||
"sewer-waterfall-02-n",
|
||||
// "sewer-water-highlight-01-n-dest",
|
||||
// "sewer-water-highlight-01-n",
|
||||
"sewer-water-wave-01-n-dest",
|
||||
"sewer-water-wave-01-n",
|
||||
"sewer-water-still-01-n-dest",
|
||||
"sewer-water-still-01-n",
|
||||
|
||||
// hanga-water
|
||||
// "des-thermal-01-dest",
|
||||
// "des-thermal-01"
|
||||
|
||||
// desresc-warp
|
||||
"sat-shield-dest",
|
||||
"sat-shield-env-uvscroll",
|
||||
"sat-shield",
|
||||
|
||||
// security
|
||||
"security-env-dest",
|
||||
"security-env-uscroll",
|
||||
"security-dot-dest",
|
||||
"security-dot-src",
|
||||
|
||||
// lgunnorm-water
|
||||
"kg-target-c-forcefield-01-dest",
|
||||
"kg-target-c-forcefield-01",
|
||||
|
||||
// templex-water
|
||||
"temple-waterfall-dest",
|
||||
"temple-waterfall",
|
||||
|
||||
// desertd-water
|
||||
"des-waterfall-dest",
|
||||
"des-waterfall",
|
||||
|
||||
// towerb-water
|
||||
"tow-energy-bridge-dest",
|
||||
"tow-energy-bridge",
|
||||
|
||||
// factoryb-water
|
||||
"hemi-gradient-dest",
|
||||
"hemi-gradient-rim",
|
||||
"hemi-gradient-flames-dest",
|
||||
"hemi-gradient-flames",
|
||||
|
||||
// factoryc-alpha
|
||||
"facc-convey-dest",
|
||||
"facc-convey",
|
||||
"facc-convey-02-dest",
|
||||
"facc-convey-02",
|
||||
|
||||
// waspal-water
|
||||
"waspala-water-dest",
|
||||
"waspala-water",
|
||||
"waspala-waterfall-dest",
|
||||
"waspala-waterfall",
|
||||
|
||||
// rubblea-water
|
||||
"rub-water-dest",
|
||||
"rub-water",
|
||||
|
||||
// rubblea2-water
|
||||
"rub-water-desta2",
|
||||
"rub-watera2",
|
||||
|
||||
// rubbleb-water
|
||||
"rub-water-destb",
|
||||
"rub-waterb",
|
||||
|
||||
// rubblec-water
|
||||
"rub-water-destc",
|
||||
"rub-waterc",
|
||||
|
||||
// nstb-quicksand
|
||||
"nstb-quicksand-dest",
|
||||
"nstb-quicksand-scroll",
|
||||
|
||||
// ctyslumb-water
|
||||
"ctyslumb-water-dest",
|
||||
"ctyslumb-water",
|
||||
"ctyslumb-fountain-fall-dest",
|
||||
"ctyslumb-fountain-fall",
|
||||
|
||||
// ctyslumc-water
|
||||
"ctyslumc-water-dest",
|
||||
"ctyslumc-water",
|
||||
"ctyslumc-fountain-fall-dest",
|
||||
"ctyslumc-fountain-fall",
|
||||
|
||||
// mined-tfrag
|
||||
"mined-pillar-side-dest",
|
||||
"mined-pillar-side-cold",
|
||||
"mined-pillar-side-cooling",
|
||||
"mined-pillar-side-hot",
|
||||
"mined-pillar-molten",
|
||||
"mined-pillar-top2side-dest",
|
||||
"mined-pillar-top2side-cold",
|
||||
"mined-pillar-top2side-cooling",
|
||||
"mined-pillar-top2side-hot",
|
||||
"mined-pillar-top-dest",
|
||||
"mined-pillar-top-cold",
|
||||
"mined-pillar-top-cooling",
|
||||
"mined-pillar-top-hot",
|
||||
"mined-pillar-molten-top",
|
||||
|
||||
// volcanoa-alpha
|
||||
"vola-lava-01-dest",
|
||||
"vola-lava-01",
|
||||
"vola-lava-fall-dest",
|
||||
"vola-lava-fall",
|
||||
|
||||
// wasstada-alpha
|
||||
"wstd-lava-base-dest",
|
||||
"wstd-lava-base"
|
||||
"skull-gem-alpha-02"
|
||||
],
|
||||
|
||||
"levels_to_extract": [
|
||||
|
||||
@@ -1850,8 +1850,6 @@
|
||||
["_stack_", 148, "float"],
|
||||
["_stack_", 152, "float"],
|
||||
["_stack_", 156, "float"],
|
||||
[25, "a1", "light-trail-breadcrumb"],
|
||||
[178, "s4", "light-trail-breadcrumb"],
|
||||
[556, "a0", "vector"]
|
||||
],
|
||||
"compute-trail-scaled-t": [[17, "v1", "float"]],
|
||||
@@ -2685,13 +2683,8 @@
|
||||
[[21, 25], "a0", "prim-strip"]
|
||||
],
|
||||
"(event tracking light-trail-tracker)": [[55, "v1", "float"]],
|
||||
"(method 21 light-trail)": [[[18, 64], "gp", "light-trail-breadcrumb"]],
|
||||
"(method 14 light-trail)": [
|
||||
[47, "a0", "uint"],
|
||||
[[10, 32], "a1", "light-trail-breadcrumb"],
|
||||
[[34, 60], "s3", "light-trail-breadcrumb"],
|
||||
[[34, 73], "s2", "light-trail-breadcrumb"]
|
||||
],
|
||||
"(method 21 light-trail)": [[50, "v1", "light-trail-breadcrumb"]],
|
||||
"(method 14 light-trail)": [[47, "a0", "uint"]],
|
||||
"debug-menu-item-var-update-display-str": [
|
||||
[48, "v1", "int"],
|
||||
[63, "v1", "int"],
|
||||
@@ -2742,12 +2735,16 @@
|
||||
[27, "gp", "process-drawable"],
|
||||
[30, "gp", "process-drawable"]
|
||||
],
|
||||
"(method 23 weapon-trail)": [[[0, 100], "gp", "weapon-trail-crumb"]],
|
||||
"(method 23 weapon-trail)": [
|
||||
[62, "v1", "light-trail-breadcrumb"],
|
||||
[65, "v1", "light-trail-breadcrumb"]
|
||||
],
|
||||
"(method 22 weapon-trail)": [[32, "v0", "light-trail-breadcrumb"]],
|
||||
"(method 22 tread-trail)": [[19, "v0", "light-trail-breadcrumb"]],
|
||||
"(method 23 tread-trail)": [[[0, 100], "s5", "tread-trail-crumb"]],
|
||||
"(method 23 tire-trail)": [[[0, 74], "s5", "tire-trail-crumb"]],
|
||||
"(method 22 tire-trail)": [[[18, 24], "v1", "tire-trail-crumb"]],
|
||||
"(method 23 tread-trail)": [
|
||||
[51, "v1", "light-trail-breadcrumb"],
|
||||
[67, "v0", "light-trail-breadcrumb"]
|
||||
],
|
||||
"(trans idle fma-sphere)": [[39, "a2", "process-drawable"]],
|
||||
"part-water-splash-callback": [[3, "v1", "float"]],
|
||||
"(method 15 water-control)": [[48, "v1", "float"]],
|
||||
@@ -6431,11 +6428,11 @@
|
||||
],
|
||||
"cshape-reaction-scorp-shot": [[15, "v1", "v-scorp-shot"]],
|
||||
"(method 78 wvehicle)": [
|
||||
[262, "s1", "tire-trail-tracker"],
|
||||
[271, "s1", "tire-trail-tracker"],
|
||||
[287, "s1", "tire-trail-tracker"],
|
||||
[309, "s1", "tire-trail-tracker"],
|
||||
[322, "s1", "tire-trail-tracker"],
|
||||
[262, "s1", "process-focusable"],
|
||||
[271, "s1", "process-focusable"],
|
||||
[287, "s1", "process-focusable"],
|
||||
[309, "s1", "process-focusable"],
|
||||
[322, "s1", "process-focusable"],
|
||||
[358, "v1", "collide-shape-prim-group"]
|
||||
],
|
||||
"(method 97 wvehicle)": [
|
||||
@@ -6554,10 +6551,7 @@
|
||||
[15, "v1", "process-drawable"],
|
||||
[22, "v1", "process-drawable"]
|
||||
],
|
||||
"(method 19 tire-trail)": [
|
||||
[[5, 28], "s5", "tire-trail-crumb"],
|
||||
[[5, 28], "s4", "tire-trail-crumb"]
|
||||
],
|
||||
"(method 19 tire-trail)": [],
|
||||
"vehicle-spawn": [[93, "gp", "vehicle"]],
|
||||
"vehicle-spawn-hack": [[41, "gp", "vehicle"]],
|
||||
"(method 11 w-parking-spot)": [[42, "v0", "vector"]],
|
||||
|
||||
@@ -515,44 +515,8 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
// currently not needed.
|
||||
break;
|
||||
case int(PSM::PSMT8):
|
||||
if (tex.clutpsm == (int)CPSM::PSMCT16) {
|
||||
// will store output pixels, rgba (8888)
|
||||
std::vector<u8> index_out;
|
||||
|
||||
// width is like the TEX0 register, in 64 texel units.
|
||||
// not sure what the other widths are yet.
|
||||
int read_width = 64 * tex.width[0];
|
||||
|
||||
// loop over pixels in output texture image
|
||||
for (int y = 0; y < tex.h; y++) {
|
||||
for (int x = 0; x < tex.w; x++) {
|
||||
// read as the PSMT8 type. The dest field tells us a block offset.
|
||||
auto addr8 = psmt8_addr(x, y, read_width) + tex.dest[0] * 256;
|
||||
u8 value = *(u8*)(vram.data() + addr8);
|
||||
index_out.push_back(value);
|
||||
}
|
||||
}
|
||||
std::array<math::Vector4<u8>, 256> unscrambled_clut{};
|
||||
for (int i = 0; i < 256; i++) {
|
||||
u32 clut_chunk = i / 16;
|
||||
u32 off_in_chunk = i % 16;
|
||||
u8 clx = 0, cly = 0;
|
||||
if (clut_chunk & 1) {
|
||||
clx = 8;
|
||||
}
|
||||
cly = (clut_chunk >> 1) * 2;
|
||||
if (off_in_chunk >= 8) {
|
||||
off_in_chunk -= 8;
|
||||
cly++;
|
||||
}
|
||||
clx += off_in_chunk;
|
||||
u32 clut_addr = psmct16_addr(clx, cly, 64) + tex.clutdest * 256;
|
||||
memcpy(&unscrambled_clut[i], vram.data() + clut_addr, 4);
|
||||
}
|
||||
texture_db.add_index_texture(texture_page.id, tex_id, index_out, unscrambled_clut,
|
||||
tex.w, tex.h, tex.name, texture_page.name, level_names);
|
||||
stats.successful_textures++;
|
||||
} else if (tex.clutpsm == (int)PSM::PSMCT32) {
|
||||
ASSERT(tex.clutpsm == int(CPSM::PSMCT32));
|
||||
{
|
||||
// will store output pixels, index (u8)
|
||||
std::vector<u8> index_out;
|
||||
|
||||
@@ -591,12 +555,10 @@ TPageResultStats process_tpage(ObjectFileData& data,
|
||||
texture_db.add_index_texture(texture_page.id, tex_id, index_out, unscrambled_clut,
|
||||
tex.w, tex.h, tex.name, texture_page.name, level_names);
|
||||
stats.successful_textures++;
|
||||
} else {
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lg::die("Animated texture {} format {} clut {}\n", tex.name, tex.psm, tex.clutpsm);
|
||||
lg::die("Animated texture {} format {}\n", tex.name, tex.psm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -322,8 +322,7 @@ void extract_common(const ObjectFileDB& db,
|
||||
compressed.data(), compressed.size());
|
||||
|
||||
if (config.rip_levels) {
|
||||
auto file_path = file_util::get_jak_project_dir() / "glb_out" /
|
||||
game_version_names[config.game_version] / "common.glb";
|
||||
auto file_path = file_util::get_jak_project_dir() / "glb_out" / "common.glb";
|
||||
file_util::create_dir_if_needed_for_file(file_path);
|
||||
save_level_foreground_as_gltf(tfrag_level, art_group_data, file_path);
|
||||
}
|
||||
@@ -361,17 +360,15 @@ void extract_from_level(const ObjectFileDB& db,
|
||||
|
||||
if (config.rip_levels) {
|
||||
auto back_file_path = file_util::get_jak_project_dir() / "glb_out" /
|
||||
game_version_names[config.game_version] /
|
||||
fmt::format("{}-background.glb", level_data.level_name);
|
||||
fmt::format("{}_background.glb", level_data.level_name);
|
||||
file_util::create_dir_if_needed_for_file(back_file_path);
|
||||
save_level_background_as_gltf(level_data, back_file_path);
|
||||
auto fore_file_path = file_util::get_jak_project_dir() / "glb_out" /
|
||||
game_version_names[config.game_version] /
|
||||
fmt::format("{}-foreground.glb", level_data.level_name);
|
||||
fmt::format("{}_foreground.glb", level_data.level_name);
|
||||
file_util::create_dir_if_needed_for_file(fore_file_path);
|
||||
save_level_foreground_as_gltf(level_data, art_group_data, fore_file_path);
|
||||
}
|
||||
file_util::write_text_file(entities_folder / fmt::format("{}-actors.json", level_data.level_name),
|
||||
file_util::write_text_file(entities_folder / fmt::format("{}_actors.json", level_data.level_name),
|
||||
extract_actors_to_json(bsp_header.actors));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "extract_merc.h"
|
||||
|
||||
#include "merc_replacement.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/BitUtils.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
@@ -1599,60 +1597,6 @@ void create_modifiable_vertex_data(
|
||||
}
|
||||
}
|
||||
|
||||
void replace_model(tfrag3::Level& lvl, tfrag3::MercModel& model, const fs::path& mdl_path) {
|
||||
if (model.max_bones < 100) {
|
||||
auto lvl_name = lvl.level_name == "" ? "common" : lvl.level_name;
|
||||
lg::info("Replacing {} for {}: {} effects, {} max bones, {} max draws\n", model.name, lvl_name,
|
||||
model.effects.size(), model.max_bones, model.max_draws);
|
||||
|
||||
std::vector<tfrag3::MercVertex> old_verts;
|
||||
for (auto& e : model.effects) {
|
||||
for (auto& d : e.all_draws) {
|
||||
for (size_t i = 0; i < d.index_count; i++) {
|
||||
auto idx = lvl.merc_data.indices.at(i + d.first_index);
|
||||
if (idx != UINT32_MAX) {
|
||||
old_verts.push_back(lvl.merc_data.vertices[idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto swap_info = load_replacement_merc_model(model.name, lvl.merc_data.indices.size(),
|
||||
lvl.merc_data.vertices.size(), lvl.textures.size(),
|
||||
mdl_path.string(), old_verts, false);
|
||||
model = swap_info.new_model;
|
||||
size_t old_start = lvl.merc_data.vertices.size();
|
||||
for (auto& ind : swap_info.new_indices) {
|
||||
ASSERT(ind >= old_start);
|
||||
}
|
||||
lvl.merc_data.indices.insert(lvl.merc_data.indices.end(), swap_info.new_indices.begin(),
|
||||
swap_info.new_indices.end());
|
||||
lvl.merc_data.vertices.insert(lvl.merc_data.vertices.end(), swap_info.new_vertices.begin(),
|
||||
swap_info.new_vertices.end());
|
||||
lvl.textures.insert(lvl.textures.end(), swap_info.new_textures.begin(),
|
||||
swap_info.new_textures.end());
|
||||
}
|
||||
}
|
||||
|
||||
void add_custom_model_to_level(tfrag3::Level& lvl,
|
||||
const std::string& name,
|
||||
const fs::path& mdl_path) {
|
||||
auto lvl_name = lvl.level_name == "" ? "common" : lvl.level_name;
|
||||
lg::info("Adding custom model {} to {}", name, lvl_name);
|
||||
auto merc_data =
|
||||
load_replacement_merc_model(name, lvl.merc_data.indices.size(), lvl.merc_data.vertices.size(),
|
||||
lvl.textures.size(), mdl_path.string(), {}, true);
|
||||
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());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Top-level merc extraction
|
||||
*/
|
||||
@@ -1787,33 +1731,5 @@ void extract_merc(const ObjectFileData& ag_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do model replacements if present
|
||||
auto merc_replacement_folder = file_util::get_jak_project_dir() / "custom_assets" /
|
||||
game_version_names[version] / "merc_replacements";
|
||||
if (file_util::file_exists(merc_replacement_folder.string())) {
|
||||
auto merc_replacements =
|
||||
file_util::find_files_in_dir(merc_replacement_folder, std::regex(".*\\.glb"));
|
||||
for (auto& path : merc_replacements) {
|
||||
auto name = path.stem().string();
|
||||
auto it = std::find_if(out.merc_data.models.begin(), out.merc_data.models.end(),
|
||||
[&](const auto& m) { return m.name == name; });
|
||||
if (it != out.merc_data.models.end()) {
|
||||
auto& model = *it;
|
||||
replace_model(out, model, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add custom models if present
|
||||
auto lvl_name = out.level_name == "" ? "common" : out.level_name;
|
||||
auto models_folder = file_util::get_jak_project_dir() / "custom_assets" /
|
||||
game_version_names[version] / "models" / lvl_name;
|
||||
if (file_util::file_exists(models_folder.string())) {
|
||||
auto custom_models = file_util::find_files_in_dir(models_folder, std::regex(".*\\.glb"));
|
||||
for (auto& mdl : custom_models) {
|
||||
add_custom_model_to_level(out, mdl.stem().string(), mdl);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace decompiler
|
||||
@@ -1,211 +0,0 @@
|
||||
#include "merc_replacement.h"
|
||||
|
||||
using namespace gltf_util;
|
||||
|
||||
namespace decompiler {
|
||||
void extract(const std::string& name,
|
||||
MercExtractData& out,
|
||||
const tinygltf::Model& model,
|
||||
const std::vector<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.extras.Has("set_invisible") && node.extras.Get("set_invisible").Get<int>()) {
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
draw.no_strip = true;
|
||||
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;
|
||||
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 = 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 = 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());
|
||||
e.has_mod_draw = false;
|
||||
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());
|
||||
}
|
||||
|
||||
const tfrag3::MercVertex& find_closest(const std::vector<tfrag3::MercVertex>& old,
|
||||
float x,
|
||||
float y,
|
||||
float z) {
|
||||
float best_dist = 1e10;
|
||||
int best_idx = 0;
|
||||
|
||||
for (int i = 0; i < old.size(); i++) {
|
||||
auto& v = old[i];
|
||||
float dx = v.pos[0] - x;
|
||||
float dy = v.pos[1] - y;
|
||||
float dz = v.pos[2] - z;
|
||||
float dist = (dx * dx) + (dy * dy) + (dz * dz);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return old[best_idx];
|
||||
}
|
||||
|
||||
void merc_convert_replacement(MercSwapData& out,
|
||||
const MercExtractData& in,
|
||||
const std::vector<tfrag3::MercVertex>& old_verts) {
|
||||
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];
|
||||
const auto& copy_from = find_closest(old_verts, y.x, y.y, y.z);
|
||||
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] = copy_from.normal[0];
|
||||
x.normal[1] = copy_from.normal[1];
|
||||
x.normal[2] = copy_from.normal[2];
|
||||
x.weights[0] = copy_from.weights[0];
|
||||
x.weights[1] = copy_from.weights[1];
|
||||
x.weights[2] = copy_from.weights[2];
|
||||
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] = copy_from.mats[0];
|
||||
x.mats[1] = copy_from.mats[1];
|
||||
x.mats[2] = copy_from.mats[2];
|
||||
}
|
||||
}
|
||||
|
||||
void merc_convert_custom(MercSwapData& out, const MercExtractData& in) {
|
||||
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_replacement_merc_model(const std::string& name,
|
||||
u32 current_idx_count,
|
||||
u32 current_vtx_count,
|
||||
u32 current_tex_count,
|
||||
const std::string& path,
|
||||
const std::vector<tfrag3::MercVertex>& old_verts,
|
||||
bool custom_mdl) {
|
||||
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 = 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);
|
||||
if (custom_mdl) {
|
||||
merc_convert_custom(result, extract_data);
|
||||
} else {
|
||||
merc_convert_replacement(result, extract_data, old_verts);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace decompiler
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/gltf_util.h"
|
||||
|
||||
namespace decompiler {
|
||||
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;
|
||||
};
|
||||
|
||||
MercSwapData load_replacement_merc_model(const std::string& name,
|
||||
u32 current_idx_count,
|
||||
u32 current_vtx_count,
|
||||
u32 current_tex_count,
|
||||
const std::string& path,
|
||||
const std::vector<tfrag3::MercVertex>& old_verts,
|
||||
bool custom_mdl);
|
||||
} // namespace decompiler
|
||||
@@ -2576,6 +2576,7 @@ void CallOp::propagate_types2(types2::Instruction& instr,
|
||||
|
||||
if (can_use_call_parent) {
|
||||
out_types[Register(Reg::GPR, Reg::V0)]->type = TP_Type::make_from_ts(call_parent_result_type);
|
||||
lg::print("used special {}\n", call_parent_result_type.print());
|
||||
use_normal_last_arg = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,6 @@ set(RUNTIME_SOURCE
|
||||
mips2c/jak3_functions/sky.cpp
|
||||
mips2c/jak3_functions/texture.cpp
|
||||
mips2c/jak3_functions/particle_curves.cpp
|
||||
mips2c/jak3_functions/cloth.cpp
|
||||
mips2c/jak3_functions/collide_cache.cpp
|
||||
mips2c/jak3_functions/collide_hash.cpp
|
||||
mips2c/jak3_functions/collide_edge_grab.cpp
|
||||
@@ -255,29 +254,6 @@ set(RUNTIME_SOURCE
|
||||
overlord/jak2/streamlfo.cpp
|
||||
overlord/jak2/streamlist.cpp
|
||||
overlord/jak2/vag.cpp
|
||||
overlord/jak3/overlord.cpp
|
||||
overlord/jak3/pagemanager.cpp
|
||||
overlord/jak3/iso_cd.cpp
|
||||
overlord/jak3/dma.cpp
|
||||
overlord/jak3/iso.cpp
|
||||
overlord/jak3/iso_queue.cpp
|
||||
overlord/jak3/srpc.cpp
|
||||
overlord/jak3/vag.cpp
|
||||
overlord/jak3/ssound.cpp
|
||||
overlord/jak3/iso_api.cpp
|
||||
overlord/jak3/spustreams.cpp
|
||||
overlord/jak3/list.cpp
|
||||
overlord/jak3/vblank_handler.cpp
|
||||
overlord/jak3/dvd_driver.cpp
|
||||
overlord/jak3/basefile.cpp
|
||||
overlord/jak3/basefilesystem.cpp
|
||||
overlord/jak3/ramdisk.cpp
|
||||
overlord/jak3/isocommon.cpp
|
||||
overlord/jak3/init.cpp
|
||||
overlord/jak3/stream.cpp
|
||||
overlord/jak3/sbank.cpp
|
||||
overlord/jak3/soundcommon.cpp
|
||||
overlord/jak3/streamlist.cpp
|
||||
runtime.cpp
|
||||
sce/deci2.cpp
|
||||
sce/iop.cpp
|
||||
@@ -322,6 +298,3 @@ endif()
|
||||
|
||||
add_executable(gk main.cpp)
|
||||
target_link_libraries(gk runtime)
|
||||
if(WIN32)
|
||||
set_target_properties(gk PROPERTIES VS_DPI_AWARE "PerMonitor")
|
||||
endif()
|
||||
File diff suppressed because it is too large.
Load diff
@@ -46,7 +46,7 @@
|
||||
"VISMÄNNEN HAR BLIVIT KIDNAPPADE,",
|
||||
"GOL OCH MAIA HAR SAMLAT IHOP TILLRÄCKLIGT MED ECO",
|
||||
"FÖR ATT KUNNA GENOMFÖRA SIN HEMSKA PLAN,",
|
||||
"OCH FÖR ATT KUNNA STOPPA DOM, SÅ MÅSTE NI",
|
||||
"OCH FÖR ATT KUNNA STOPPA DEM, SÅ MÅSTE NI",
|
||||
"SLÅ ER FRAM HELA VÄGEN GENOM DERAS CITADELL!",
|
||||
"EH... JA. SÅ KAN MAN, EH... NOG SAMMANFATTA DET HELA.",
|
||||
"NI MÅSTE RÄDDA MIN FAR INNAN DET ÄR FÖR SENT!",
|
||||
@@ -323,7 +323,7 @@
|
||||
],
|
||||
"explorer-resolution": [
|
||||
"JAG SER ATT NI TVÅ ÄR TILLBAKA FÖR ATT GENOMFÖRA BYTET. BRA, BRA, MYCKET BRA!",
|
||||
"ÄH, NI HAR MED ER ÖH, DOM PRECURSOR-KULOR VI KOM ÖVERENS OM?",
|
||||
"ÄH, DU HAR MED DIG ÖH, DOM PRECURSOR-KULOR VI KOM ÖVERENS OM?",
|
||||
"JAG HOPPAS ATT DU FÅR ANVÄNDNING AV DEN HÄR SURT FÖRVÄRVADE KRAFTCELLEN.",
|
||||
"TACK SÅ MYCKET, GODDAG, ADJÖ!"
|
||||
],
|
||||
@@ -2242,7 +2242,7 @@
|
||||
],
|
||||
"sksp0079": [
|
||||
"AH! JAG KOMMER ATT DÖ! JAG KOMMER, FARFAR!",
|
||||
"NI MÅSTE FÅ DEN HÄR SAKEN ÖVER TILL ANDRA SIDAN INNAN DEN BLIR ÖVERHETTAD!"
|
||||
"DU MÅSTE FÅ DEN HÄR SAKEN ÖVER TILL ANDRA SIDAN INNAN DEN BLIR ÖVERHETTAD!"
|
||||
],
|
||||
"sksp0080": [
|
||||
"ANVÄND KURVAN FÖR ATT KUNNA STYRA BÄTTRE!"
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -6,16 +6,16 @@
|
||||
"0107": "HALUATKO PELATA UUDELLEEN?",
|
||||
"0108": "LOPETA",
|
||||
"0109": "TAUKO",
|
||||
"010a": "ÄÄNITEHOSTEET",
|
||||
"010b": "MUSIIKKI",
|
||||
"010c": "PUHE",
|
||||
"010a": "EFEKTIEN VOIMAKKUUS",
|
||||
"010b": "MUSIIKIN VOIMAKKUUS",
|
||||
"010c": "PUHEEN VOIMAKKUUS",
|
||||
"010d": "KIELI",
|
||||
"010e": "VÄRINÄTOIMINTO",
|
||||
"010e": "VÄRÄHTELYT",
|
||||
"010f": "VINKIT",
|
||||
"0110": "KESKITÄ RUUTU",
|
||||
"0111": "PÄÄLLÄ",
|
||||
"0112": "POIS",
|
||||
"0113": "KÄYTÄ SUUNTANÄPPÄIMIÄ",
|
||||
"0113": "KÄYTÄ D-PAD:IA",
|
||||
"0114": "ENGLISH",
|
||||
"0115": "FRANÇAIS",
|
||||
"0116": "DEUTSCH",
|
||||
@@ -24,36 +24,36 @@
|
||||
"0119": "にほんご",
|
||||
"011a": "PAINA <PAD_CIRCLE> VAIHTAAKSESI 90 HELMEÄ VOIMAKENNOON.",
|
||||
"011b": "PAINA <PAD_CIRCLE> VAIHTAAKSESI 120 HELMEÄ VOIMAKENNOON.",
|
||||
"011c": "MATKUSTA PAINAMALLA <PAD_CIRCLE>.",
|
||||
"011d": "PERU PAINAMALLA <PAD_TRIANGLE>.",
|
||||
"011c": "PAINA <PAD_CIRCLE> MENNÄKSESI.",
|
||||
"011d": "PAINA <PAD_TRIANGLE> PERUAKSESI.",
|
||||
"011e": "GEYSIRSAARI",
|
||||
"011f": "VIHREÄN TIETÄJÄN MÖKKI",
|
||||
"0120": "SINISEN TIETÄJÄN MÖKKI",
|
||||
"0121": "PUNAISEN TIETÄJÄN MÖKKI",
|
||||
"0122": "GOLIN AND MAIAN LINNOITUS",
|
||||
"0123": "PAINA <PAD_CIRCLE> PUHUAKSESI SAMOSILLE.",
|
||||
"0124": "PAINA <PAD_CIRCLE> PUHUAKSESI KEIRALLE.",
|
||||
"0123": "PAINA <PAD_CIRCLE> PUHUAKSESI SAMOSILLE",
|
||||
"0124": "PAINA <PAD_CIRCLE> PUHUAKSESI KEIRALLE",
|
||||
"0125": "KUVASUHDE",
|
||||
"0126": "VIDEOTILA",
|
||||
"0126": "VIDEON TILA",
|
||||
"0127": "PELIASETUKSET",
|
||||
"0128": "GRAFIIKKA-ASETUKSET",
|
||||
"0129": "ÄÄNIASETUKSET",
|
||||
"012a": "4X3",
|
||||
"012b": "16X9",
|
||||
"012c": "60 HZ",
|
||||
"012d": "50 HZ",
|
||||
"012c": "60HZ",
|
||||
"012d": "50HZ",
|
||||
"012e": "JAK AND DAXTER",
|
||||
"012f": "LÖYDÄ KÄTKETTY VOIMAKENNO",
|
||||
"0130": "EI TARPEEKSI TILAA MUISTIKORTILLA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D",
|
||||
"0131": "EI MEMORY_CARD_(PS2) LIITETTYNÄ PAIKASSA MEMORY_CARD_SLOT_~D",
|
||||
"0132": "MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D ON ALUSTAMATON",
|
||||
"0133": "JAK AND DAXTER VAATII ~D KT VAPAATA TILAA",
|
||||
"0134": "SYÖTÄ MEMORY_CARD_(PS2), JOSSA ON TARPEEKSI TILAA, MUUTEN PELITIETOJASI EI VOIDA TALLENTAA",
|
||||
"0130": "LIIAN VÄHÄN TILAA MUISTIKORTILLA MEMORY_CARD_(PS2, INSERTED IN MEMORY_CARD_SLOT_~D",
|
||||
"0131": "EI MEMORY_CARD_(PS2, LIITETTYNÄ IN MEMORY_CARD_SLOT_~D",
|
||||
"0132": "MEMORY_CARD_(PS2, PAIKASSA MEMORY_CARD_SLOT_~D ON ALUSTAMATON",
|
||||
"0133": "JAK AND DAXTER VAATII ~DKB VAPAATA TILAA",
|
||||
"0134": "KIINNITÄ MEMORY_CARD_(PS2, JOSSA ON TARPEEKSI TILAA, MUUTEN PELITIETOJA EI VOIDA TALLENTAA",
|
||||
"0135": "ILMAN ALUSTAMISTA PELITIETOJA EI VOIDA TALLENTAA",
|
||||
"0136": "TALLENNETAAN TIETOJA",
|
||||
"0137": "LADATAAN TIETOJA",
|
||||
"0138": "ÄLÄ POISTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D TAI SAMMUTA LAITETTASI",
|
||||
"0139": "HALUATKO KORVATA SEN?",
|
||||
"0138": "ÄLÄ POISTA MEMORY_CARD_(PS2, IN MEMORY_CARD_SLOT_~D TAI SAMMUTA LAITETTASI",
|
||||
"0139": "HALUATKO PÄÄLLEKIRJOITTAA TÄMÄN?",
|
||||
"013a": "ALUSTA?",
|
||||
"013c": "KYLLÄ",
|
||||
"013d": "EI",
|
||||
@@ -62,7 +62,7 @@
|
||||
"0140": "VALITSE TALLENNUSPAIKKA",
|
||||
"0141": "VALITSE LADATTAVA TALLENNUS",
|
||||
"0142": "JAK AND DAXTER -TALLENNUS ON JO OLEMASSA VALITSEMASSASI TIEDOSTOSSA",
|
||||
"0143": "SYÖTÄ JAK AND DAXTER -PELITIETOJA SISÄLTÄVÄ MEMORY_CARD_(PS2) PAIKKAAN MEMORY_CARD_SLOT_~D",
|
||||
"0143": "SYÖTÄ MEMORY_CARD_(PS2, JOKA SISÄLTÄÄ JAK AND DAXTER -TALLENNUSTIETOJA PAIKKAAN MEMORY_CARD_SLOT_~D",
|
||||
"0144": "JATKA?",
|
||||
"014b": "LATAA PELI",
|
||||
"014c": "TALLENNA PELI",
|
||||
@@ -72,29 +72,29 @@
|
||||
"0150": "ASETUKSET",
|
||||
"0151": "VIRHE LADATTAESSA",
|
||||
"0152": "VIRHE TALLENTAESSA",
|
||||
"0153": "VIRHE ALUSTAESSA",
|
||||
"0153": "VIRHE ALUSTAMISESSA",
|
||||
"0154": "VIRHE LUODESSA TALLENNUSTIEDOSTOA",
|
||||
"0156": "MEMORY_CARD_(PS2) PAIKASTA MEMORY_CARD_SLOT_~D POISTETTIIN",
|
||||
"0157": "AUTOMAATTINEN TALLENNUS ON POISTETTU KÄYTÖSTÄ",
|
||||
"0158": "TALLENNA PELISI MANUAALISESTI, NIIN AUTOMAATTINEN TALLENNUS PALAUTETAAN KÄYTTÖÖN",
|
||||
"0159": "JAK AND DAXTER -TALLENNUSTIETOJA EI LÖYTYNYT KORITLTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D",
|
||||
"0156": "MEMORY_CARD_(PS2, PAIKASTA MEMORY_CARD_SLOT_~D POISTETTIIN",
|
||||
"0157": "AUTOMAATTITALLENNUS ON POISTETTU KÄYTÖSTÄ",
|
||||
"0158": "KÄYTÄ TALLENNA PELI -ASETUSTA TALLENTAAKSESI PELIN MANUAALISESTI JA UUDELLEENKÄYNNISTÄÄKSESI AUTOMAATTITALLENNUKSEN",
|
||||
"0159": "JAK AND DAXTER -TALLENNUSTIETOJA EI LÖYTYNYT MEMORY_CARD_(PS2, PAIKASSA MEMORY_CARD_SLOT_~D",
|
||||
"015a": "HALUATKO LUODA UUDEN JAK AND DAXTER -TALLENNUKSEN?",
|
||||
"015b": "TARKISTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D",
|
||||
"015b": "TARKISTA MEMORY_CARD_(PS2, PAIKASSA MEMORY_CARD_SLOT_~D",
|
||||
"015c": "UUSI PELI",
|
||||
"015d": "TAKAISIN?",
|
||||
"015e": "OK",
|
||||
"015f": "POISTU DEMOSTA",
|
||||
"0160": "KUN OHEINEN KUVAKE ILMESTYY, EDISTYKSESI TALLENNETAAN",
|
||||
"0161": "KUN TÄMÄ KUVAKE ON RUUDULLA, ÄLÄ IRROTA MEMORY_CARD_(PS2) TAI SAMMUTA LAITETTASI",
|
||||
"0161": "KUN TÄMÄ KUVAKE ON RUUDULLA, ÄLÄ POISTA THE MEMORY_CARD_(PS2, TAI SAMMUTA LAITETTASI",
|
||||
"0162": "TEHTÄVÄ SUORITETTU",
|
||||
"0163": "TARKISTA MEMORY_CARD_(PS2) PAIKASSA MEMORY_CARD_SLOT_~D JA YRITÄ UUDELLEEN",
|
||||
"0163": "TARKISTA MEMORY_CARD_(PS2, IN MEMORY_CARD_SLOT_~D JA YRITÄ UUDELLEEN",
|
||||
"0164": "RUUTU OTTAA NYT KÄYTTÖÖN 60HZ-TILAN",
|
||||
"0165": "JOS KUVA NÄKYY VIRHEELLISENÄ, TELEVISIOSI EI TUE TÄTÄ TILAA",
|
||||
"0166": "JOS NIIN KÄY, ODOTA 10 SEKUNTIA, NIIN RUUTU PALAUTUU TAKAISIN",
|
||||
"0166": "JOS NÄIN KÄY, ODOTA 10 SEKUNTIA NIIN RUUTU PALAUTETAAN TAKAISIN",
|
||||
"0167": "RUUTU ON NYT 60HZ-TILASSA",
|
||||
"0168": "HALUATKO PITÄÄ TÄMÄN TILAN KÄYTÖSSÄ?",
|
||||
"0169": "VALITSE TASO SUUNTANÄPPÄIMILLÄ",
|
||||
"016a": "LEVY POISTETTIIN",
|
||||
"0169": "KÄYTÄ D-PAD:IA VALITAKSESI TASON",
|
||||
"016a": "LEVY ON POISTETTU",
|
||||
"016b": "SYÖTÄ JAK AND DAXTER -LEVY SISÄÄN, JOTTA VOIT JATKAA PELAAMISTA",
|
||||
"016c": "VIRHE TIETOJEN LUKEMISESSA",
|
||||
"016d": "TARKISTA JAK AND DAXTER -LEVYSI JA YRITÄ UUDELLEEN",
|
||||
@@ -104,7 +104,7 @@
|
||||
"0171": "YHTEENSÄ KERÄTTY:",
|
||||
"0200": "TUO 90 HELMEÄ PORMESTARILLE",
|
||||
"0201": "TUO 90 HELMEÄ ENOLLESI",
|
||||
"0202": "PAIMENNA NAUKIT TAKAISIN AITAUKSEEN",
|
||||
"0202": "PAIMENNA NAUKIT TAKAISIN AITAUKSEENSA",
|
||||
"0203": "PALAA VILJELIJÄN LUO",
|
||||
"0204": "TUO 120 HELMEÄ ORAAKKELILLE",
|
||||
"0205": "AVAA ECO-KERÄIMIEN TUKOKSET",
|
||||
@@ -117,9 +117,9 @@
|
||||
"020c": "YHDISTÄ ECO-SÄTEET",
|
||||
"020d": "KIIPEÄ TEMPPELIN HUIPULLE",
|
||||
"020e": "ETSI SINISEN ECON KATKAISIN",
|
||||
"020f": "PÄIHITÄ PIMEÄ ECO-KASVI",
|
||||
"020f": "PÄIHITÄ PIMEÄN ECON KASVI",
|
||||
"0210": "NAPPAA 200 KILOA KALAA",
|
||||
"0211": "NAPPAA KIINNI VEISTÄJÄN MUUSA",
|
||||
"0211": "OTA KIINNI VEISTÄJÄN MUUSA",
|
||||
"0212": "VIE MUUSA TAKAISIN VEISTÄJÄLLE",
|
||||
"0213": "KIIPEÄ VAANIJAPAATTIIN",
|
||||
"0214": "PYSÄYTÄ KANUUNA",
|
||||
@@ -135,7 +135,7 @@
|
||||
"021e": "VIHREÄN TIETÄJÄN MÖKKI",
|
||||
"021f": "KEIRAN TALLI",
|
||||
"0220": "SANDOVERIN KYLÄ",
|
||||
"0221": "VAHTIRANTA",
|
||||
"0221": "VARTIJARANTA",
|
||||
"0222": "KIELLETTY VIIDAKKO",
|
||||
"0223": "USVASAARI",
|
||||
"0224": "TULIKANJONI",
|
||||
@@ -145,14 +145,14 @@
|
||||
"0228": "FLUT FLUT",
|
||||
"0229": "HELMIORAAKKELI",
|
||||
"022a": "TRANS-ALUSTA",
|
||||
"022b": "VIHREÄT ECO-KERÄIMET",
|
||||
"022b": "VIHREÄN ECON KERÄIMET",
|
||||
"022c": "EDELTÄJÄHELMI",
|
||||
"022d": "VOIMAKENNO",
|
||||
"022e": "NAPPAA PUDONNUT VOIMAKENNO",
|
||||
"022f": "KORJAA ECO-SÄDE",
|
||||
"0230": "PALAA PORMESTARIN LUO",
|
||||
"0262": "TUTKI RANNIKKOA",
|
||||
"0263": "KIIPEÄ VAHDIN PÄÄLLE",
|
||||
"0263": "KIIPEÄ VARTIJAN PÄÄLLE",
|
||||
"0264": "SEURAA ROTKOA MERENRANNALLE",
|
||||
"0265": "AVAA LUKITTU TEMPPELIN OVI",
|
||||
"0266": "YLLÄ VOIMAKENNOLLE ZOOMERILLA",
|
||||
@@ -223,7 +223,7 @@
|
||||
"040e": "KIIPEÄ VALTAVAA ROBOTTIA",
|
||||
"040f": "TUTKI PIMEÄÄ LUOLAA",
|
||||
"0410": "AMMU JAUHAVAT VAANIJAT KIIKARIESI AVULLA",
|
||||
"0411": "TUHOA PIMEÄT ECO-KRISTALLIT",
|
||||
"0411": "TUHOA PIMEÄN ECON KRISTALLIT",
|
||||
"0412": "PÄIHITÄ LUOLAN LEPAKOT",
|
||||
"0413": "VAPAUTA 7 PARTIOKÄRPÄSTÄ",
|
||||
"0414": "PUNAISEN TIETÄJÄN LABRA",
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
"1601": "CONTROLLER AUSWÄHLEN",
|
||||
"1602": "STICK DEADZONE",
|
||||
"1603": "IGNORIERE WENN UNFOKUSIERT",
|
||||
"1604": "CONTROLLER LED FÜR HP",
|
||||
"1604": "CONTROLLER LED FÜR LEBEN",
|
||||
"1605": "CONTROLLER LED FÜR ECO",
|
||||
"1606": "KAMERA VERFOLGEN",
|
||||
"1607": "HORIZONTALE SENSITIVITÄT",
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
"1000": "KUVAKULMA-ASETUKSET",
|
||||
"1001": "NORMAALI",
|
||||
"1002": "KÄÄNTEINEN",
|
||||
"1003": "VAAKAOHJAUS (1. PERSOONA)",
|
||||
"1004": "PYSTYOHJAUS (1. PERSOONA)",
|
||||
"1005": "VAAKAOHJAUS (3. PERSOONA)",
|
||||
"1006": "PYSTYOHJAUS (3. PERSOONA)",
|
||||
"1003": "ENSIMMÄISEN PERSOONAN VAAKAKAMERA",
|
||||
"1004": "ENSIMMÄISEN PERSOONAN PYSTYKAMERA",
|
||||
"1005": "KOLMANNEN PERSOONAN VAAKAKAMERA",
|
||||
"1006": "KOLMANNEN PERSOONAN PYSTYKAMERA",
|
||||
"1007": "PALAUTA OLETUKSET",
|
||||
"1010": "HELPPOKÄYTTÖISYYS",
|
||||
"1011": "EDELTÄJÄHELMIEN HEHKU",
|
||||
"1020": "PS2-ASETUKSET",
|
||||
"1021": "PS2-LATAUSNOPEUS",
|
||||
"1021": "PS2 LATAUSNOPEUS",
|
||||
"1022": "PARTIKKELEIDEN VÄHENNYS",
|
||||
"1023": "MUSIIKIN ULOS HÄIVYTYS",
|
||||
"1024": "MUSIIKIN SISÄÄN HÄIVYTYS",
|
||||
@@ -24,11 +24,11 @@
|
||||
"1034": "KOKORUUTU",
|
||||
"1035": "RESOLUUTIO",
|
||||
"1036": "~D X ~D",
|
||||
"1037": "PS2-KUVASUHDE",
|
||||
"1038": "KUN PS2-KUVASUHDE ON KÄYTÖSSÄ, VAIN KUVASUHTEET 4X3 JA 16X9 OVAT VALITTAVISSA. JATKA?",
|
||||
"1037": "PS2 KUVASUHDE",
|
||||
"1038": "KUN PS2 KUVASUHDE ON KÄYTÖSSÄ, VAIN KUVASUHTEET 4X3 JA 16X9 OVAT VALITTAVISSA. JATKA?",
|
||||
"1039": "KUVASUHDE (PS2)",
|
||||
"1040": "TEKSTITYS KÄYTÖSSÄ",
|
||||
"1041": "TEKSTITYS EI KÄYTÖSSÄ",
|
||||
"1040": "TEKSTITYKSET KÄYTÖSSÄ",
|
||||
"1041": "TEKSTITYKSET EI KÄYTÖSSÄ",
|
||||
"1042": "TEKSTIN KIELI",
|
||||
"1043": "NÄYTTÖ",
|
||||
"1044": "NÄYTTÖ ~D",
|
||||
@@ -50,8 +50,8 @@
|
||||
"1075": "ALHAINEN",
|
||||
"1076": "MINIMI",
|
||||
"1077": "PS2",
|
||||
"1078": "TEKSTITYS",
|
||||
"1079": "VINKKIEN TEKSTITYS",
|
||||
"1078": "TEKSTITYKSET",
|
||||
"1079": "VINKKITEKSTITYKSET",
|
||||
"1080": "HUIJAUKSET",
|
||||
"1081": "SALAISUUDET",
|
||||
"1082": "VALITSE KAPPALE",
|
||||
@@ -68,8 +68,8 @@
|
||||
"1093": "LOPUTON KELTAINEN ECO",
|
||||
"1094": "VAIHTOEHTOINEN DAXTER",
|
||||
"1095": "HAAVOITTUMATTOMUUS",
|
||||
"1096": "KAIKKI MUSIIKKITYYLIT",
|
||||
"1097": "TODELLINEN VUOROKAUDENAIKA",
|
||||
"1096": "KAIKKI MUSIIKKIKAPPALEET",
|
||||
"1097": "TODELLINEN VUOROKAUDEN AIKA",
|
||||
"1098": "LÄPÄISE PELI 100%",
|
||||
"1099": "LÄPÄISE PELI",
|
||||
"1100": "KELTAINEN TIETÄJÄ",
|
||||
@@ -96,17 +96,17 @@
|
||||
"1500": "SPEEDRUN-TILA",
|
||||
"138": "ÄLÄ LISÄÄ TAI POISTA MITÄÄN OHEISLAITTEITA, SAMMUTA LAITETTASI TAI SAMMUTA PELIÄ",
|
||||
"161": "KUN TÄMÄ KUVAKE ON RUUDULLA, ÄLÄ LISÄÄ TAI POISTA MITÄÄN OHEISLAITTEITA, SAMMUTA LAITETTASI TAI SAMMUTA PELIÄ",
|
||||
"100c": "AUTOM. TALLENNUS POIS",
|
||||
"100d": "HALUATKO VARMASTI LOPETTAA AUTOMAATTISEN TALLENNUKSEN?",
|
||||
"100e": "LOPETA AUTOM. TALLENNUS",
|
||||
"100c": "AUTO-TALLENNUS POIS PÄÄLTÄ",
|
||||
"100d": "HALUATKO VARMASTI LOPETTAA AUTO-TALLENTAMISEN?",
|
||||
"100e": "LOPETA AUTO-TALLENNUS",
|
||||
"100f": "SEKALAISET",
|
||||
"103a": "SOVITA RUUTUUN",
|
||||
"103b": "PYSTYTAHDISTUS",
|
||||
"103c": "4X3 (PS2)",
|
||||
"103d": "16X9 (PS2)",
|
||||
"103e": "~DX~D",
|
||||
"103f": "OTA TEKSTITYS KÄYTTÖÖN PAINAMALLA <PAD_SQUARE>",
|
||||
"107a": "TEKSTITYKSEN KIELI",
|
||||
"103f": "OTA TEKSTITYKSET KÄYTTÖÖN PAINAMALLA <PAD_SQUARE>",
|
||||
"107a": "TEKSTITYSTEN KIELI",
|
||||
"107b": "NÄYTÄ PUHUJA TEKSTITYKSISSÄ",
|
||||
"107c": "AINA",
|
||||
"107d": "EI KOSKAAN",
|
||||
@@ -120,7 +120,7 @@
|
||||
"109f": "KÄÄNTEINEN MAAILMA",
|
||||
"10a0": "SUURIPÄINEN JAK",
|
||||
"10c0": "MUSIIKKISOITIN",
|
||||
"10c1": "VÄLINÄYTÖSSSOITIN",
|
||||
"10c1": "VÄLIANIMAATIO-SOITIN",
|
||||
"10c2": "TOISTA LOPPUTEKSTIT",
|
||||
"10c3": "LEIKEKIRJA",
|
||||
"10d0": "OLETUS",
|
||||
@@ -160,7 +160,7 @@
|
||||
"10f2": "SOLAN LOPPUOSA",
|
||||
"10f3": "HÄMÄHÄKKILUOLAAN",
|
||||
"10f4": "LUMIVUORILLE",
|
||||
"10f5": "MAINARIT",
|
||||
"10f5": "KAIVOSMIEHET",
|
||||
"10f6": "ROBOTTILUOLAN TELINEET",
|
||||
"10f7": "EDELTÄJÄROBOTIN HUIPPU",
|
||||
"10f8": "PÄÄLUOLA",
|
||||
@@ -171,10 +171,10 @@
|
||||
"10fd": "LUMIPALLOT",
|
||||
"10fe": "TUNNELIN KESKIOSA",
|
||||
"10ff": "TUNNELIN LOPPU",
|
||||
"1501": "VÄLINÄYTÖSTEN OHITUKSET",
|
||||
"1501": "OHITA VÄLIANIMAATIOT",
|
||||
"1502": "VALITSE TARKISTUSPISTE",
|
||||
"1503": "SPEEDRUN-ASETUKSET",
|
||||
"1504": "VAROITUS: NÄMÄ ASETUKSET TALLENTAVAT AUTOMAATTISESTI ENSIMMÄISEEN TALLENNUSPAIKKAAN!",
|
||||
"1504": "VAROITUS: NÄMÄ ASETUKSET AUTOMAATTITALLENTAVAT ENSIMMÄISEEN TALLENNUSPAIKKAAN!",
|
||||
"1505": "ALOITA SPEEDRUN UUDELLEEN",
|
||||
"1506": "UUSI TÄYDEN PELIN SPEEDRUN",
|
||||
"150e": "UUSI YKSITTÄISEN TASON SPEEDRUN",
|
||||
@@ -199,16 +199,16 @@
|
||||
"1521": "HUBI 1 100%",
|
||||
"1522": "HUBI 2 100%",
|
||||
"1523": "HUBI 3 100%",
|
||||
"1524": "KAIKKI VÄLINÄYTÖKSET",
|
||||
"1524": "KAIKKI VÄLIANIMAATIOT",
|
||||
"1600": "OHJAUSSYÖTTEEN ASETUKSET",
|
||||
"1601": "VALITSE OHJAIN",
|
||||
"1602": "ANALOGISAUVAN KATVEALUE",
|
||||
"1603": "ÄLÄ HUOMIOI TYÖPÖYDÄLLÄ",
|
||||
"1603": "ÄLÄ HUOMIOI, JOS IKKUNA EI AKTIIVINEN",
|
||||
"1604": "OHJAIMEN LED TERVEYDELLE",
|
||||
"1605": "OHJAIMEN LED ECO-VOIMILLE",
|
||||
"1606": "KAMERAN OHJAUS HIIRELLÄ",
|
||||
"1607": "HERKKYYS (VAAKASUUNTA)",
|
||||
"1608": "HERKKYYS (PYSTYSUUNTA)",
|
||||
"1607": "VAAKASUUNTAINEN HERKKYYS",
|
||||
"1608": "PYSTYSUUNTAINEN HERKKYYS",
|
||||
"1609": "PELAAJAN OHJAUS HIIRELLÄ",
|
||||
"160a": "PELIOHJAIMEN KYTKENNÄT",
|
||||
"160b": "NÄPPÄIMISTÖN KYTKENNÄT",
|
||||
@@ -220,8 +220,8 @@
|
||||
"1611": "MUUTA KYTKENTÖJÄ",
|
||||
"1612": "OHJAIN ~D",
|
||||
"1613": "PIILOTA OSOITIN AUTOMAATTISESTI",
|
||||
"1614": "TYHJÄ",
|
||||
"1614": "MÄÄRITTÄMÄTÖN",
|
||||
"1615": "TUNTEMATON",
|
||||
"1616": "MUITA KUVASUHTEITA EI OLE SAATAVILLA",
|
||||
"1616": "MUITA ASETUKSIA RUUDUN KOOLLE EI SAATAVISSA",
|
||||
"1617": "OHJAIMEN LED LÄMPÖMITTARILLE"
|
||||
}
|
||||
@@ -16,59 +16,59 @@
|
||||
"1024": "ミュージック ゲイン",
|
||||
"1025": "アクター カリング",
|
||||
"1026": "バックグラウンド カリング",
|
||||
"1027": "??マッピングを???に?行",
|
||||
"1027": "かんきょう マッピングを きょうせいする",
|
||||
"1030": "DISCORDリッチプレゼンス",
|
||||
"1031": "スクリーンモード",
|
||||
"1032": "ウィンドウ",
|
||||
"1033": "ボーダレス",
|
||||
"1034": "フルスクリーン",
|
||||
"1035": "?像?",
|
||||
"1035": "かいぞうど",
|
||||
"1036": "~D X ~D",
|
||||
"1037": "PS2 アスペクト?",
|
||||
"1038": "PS2アスペクト?が??になると、4?3と16?9しかのアスペクト?が??できません.?行しますか?",
|
||||
"1039": "アスペクト? (PS2)",
|
||||
"1040": "??あり",
|
||||
"1041": "??なし",
|
||||
"1042": "テキスト??",
|
||||
"1043": "ディスプレイ",
|
||||
"1044": "ディスプレイ ~D",
|
||||
"1037": "PS2 アスペクト ひ",
|
||||
"1038": "PS2アスペクトひが ゆうこうになると、4X3と16X9しか せんたくできません ぞっこうしますか?",
|
||||
"1039": "アスペクト ひ (PS2)",
|
||||
"1040": "じまくあり",
|
||||
"1041": "じまくなし",
|
||||
"1042": "テキストのことば",
|
||||
"1043": "ディスプレー",
|
||||
"1044": "ディスプレー ~D",
|
||||
"1050": "MSAA",
|
||||
"1051": "~DX",
|
||||
"1052": "2X",
|
||||
"1053": "4X",
|
||||
"1054": "8X",
|
||||
"1055": "16X",
|
||||
"1060": "フレームレート (???)",
|
||||
"1060": "フレームレート (じっけんてき)",
|
||||
"1061": "60",
|
||||
"1062": "100",
|
||||
"1063": "150",
|
||||
"1070": "LEVEL OF DETAIL (はいけい)",
|
||||
"1071": "LEVEL OF DETAIL (ぜんけい)",
|
||||
"1072": "??",
|
||||
"1073": "?",
|
||||
"1074": "中",
|
||||
"1075": "?",
|
||||
"1076": "??",
|
||||
"1072": "さいこう",
|
||||
"1073": "たかい",
|
||||
"1074": "ふつう",
|
||||
"1075": "ひくい",
|
||||
"1076": "さいてい",
|
||||
"1077": "PS2",
|
||||
"1078": "??",
|
||||
"1079": "ヒント??",
|
||||
"1078": "じまく",
|
||||
"1079": "ヒントじまく",
|
||||
"1080": "チート",
|
||||
"1081": "シークレット",
|
||||
"1082": "?を??する",
|
||||
"1083": "スタイルを??する",
|
||||
"1082": "きょくをせんたくする",
|
||||
"1083": "スタイルをせんたくする",
|
||||
"1084": "チューンドプリカーソルロボット",
|
||||
"1085": "スタッフロール",
|
||||
"1086": "?????",
|
||||
"1087": "ハイブリッドラーカー クロウ",
|
||||
"1088": "サカナとりゲームのテーマ",
|
||||
"1089": "チャレンジーのテーマ",
|
||||
"1090": "??の青のエコ",
|
||||
"1091": "??の赤のエコ",
|
||||
"1092": "??の緑のエコ",
|
||||
"1093": "??の黄のエコ",
|
||||
"1094": "?わりのダクスター",
|
||||
"1095": "??",
|
||||
"1096": "???トラック",
|
||||
"1090": "むげんの青のエコ",
|
||||
"1091": "むげんの赤のエコ",
|
||||
"1092": "むげんの緑のエコ",
|
||||
"1093": "むげんの黄のエコ",
|
||||
"1094": "へんかのダクスター",
|
||||
"1095": "むてき",
|
||||
"1096": "すべてBGMのへんか",
|
||||
"1097": "リアルタイムオブデイ",
|
||||
"1098": "100%クリア",
|
||||
"1099": "ゲームクリア",
|
||||
@@ -76,8 +76,8 @@
|
||||
"1101": "赤の賢者",
|
||||
"1102": "青の賢者",
|
||||
"1103": "城のハブ",
|
||||
"1104": "プリカーソルロボットの中?",
|
||||
"1105": "プリカーソルロボットの?わり",
|
||||
"1104": "プリカーソルロボットの中かん",
|
||||
"1105": "プリカーソルロボットのけつまつ",
|
||||
"1106": "スタイル 1",
|
||||
"1107": "スタイル 2",
|
||||
"1110": "ENGLISH (UK)",
|
||||
@@ -94,37 +94,37 @@
|
||||
"111b": "POLSKI",
|
||||
"111c": "LIETUVIŲ KALBA",
|
||||
"1500": "スピードラン モード",
|
||||
"138": "????をぬいたり, さしたり, ??を?ったりは しないでください",
|
||||
"161": "このアイコンが あらわれている?、????をぬいたり, さしたり, ??を?ったりは しないでください",
|
||||
"138": "しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
|
||||
"161": "このアイコンが あらわれているあいだ、しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
|
||||
"100c": "オートセーブ オフ",
|
||||
"100d": "オートセーブを?っても よろしいでしょうか?",
|
||||
"100e": "オートセーブを??にする",
|
||||
"100f": "その?",
|
||||
"103a": "スクリーンに合わせる",
|
||||
"103b": "????",
|
||||
"100d": "オートセーブをきっても よろしいでしょうか?",
|
||||
"100e": "DISABLE AUTO-SAVE",
|
||||
"100f": "そのほか",
|
||||
"103a": "FIT TO SCREEN",
|
||||
"103b": "すいちょくどうき",
|
||||
"103c": "4X3 (PS2)",
|
||||
"103d": "16X9 (PS2)",
|
||||
"103e": "~DX~D",
|
||||
"103f": "<PAD_SQUARE> で ??の?り?え",
|
||||
"107a": "??の??",
|
||||
"107b": "??にスピーカーを??",
|
||||
"107c": "いつも",
|
||||
"103f": "<PAD_SQUARE> で じまくのきりかえ",
|
||||
"107a": "じまくのことば",
|
||||
"107b": "じまくではなしてをひょうじする",
|
||||
"107c": "イツモ",
|
||||
"107d": "いつもしなく",
|
||||
"107e": "オフ スクリーン",
|
||||
"107f": "ヒントログ",
|
||||
"107e": "OFF-SCREEN",
|
||||
"107f": "ヒントロッグ",
|
||||
"109a": "ビッグヘッド ジャック",
|
||||
"109b": "スモールヘッド ジャック",
|
||||
"109c": "ビッグハンドジャック",
|
||||
"109d": "ビッグヘッドキャラクター",
|
||||
"109d": "あたまがおおきいキャラクター",
|
||||
"109e": "テクスチャなしモード",
|
||||
"109f": "??世界",
|
||||
"10a0": "ビッグヘッド ジャック",
|
||||
"10c0": "ミュージックプレイヤー",
|
||||
"10c1": "プレイヤーを??",
|
||||
"109f": "かがみ世界",
|
||||
"10a0": "でかいヘッド ジャック",
|
||||
"10c0": "BGM プレイヤー",
|
||||
"10c1": "SCENE PLAYER",
|
||||
"10c2": "スタッフロール",
|
||||
"10c3": "スクラップブック",
|
||||
"10d0": "デフォルト",
|
||||
"10d1": "???",
|
||||
"10d1": "みしよう",
|
||||
"10d2": "セイジィ",
|
||||
"10d3": "セイジィの家",
|
||||
"10d4": "小鳥のオバチャマ",
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
{
|
||||
"cutscenes": {},
|
||||
"other": {
|
||||
"DSbop001": [
|
||||
"Tu as l'air vraiment en colère, Jak."
|
||||
],
|
||||
"agnt001": [
|
||||
"Hé, conduisez prudemment !"
|
||||
],
|
||||
@@ -2019,22 +2016,22 @@
|
||||
"Les scanners indiquent des oeufs de Metal Heads toujours actifs."
|
||||
],
|
||||
"daxm001": [
|
||||
"Vise la plateforme, Jak."
|
||||
"Shoot the platform, Jak."
|
||||
],
|
||||
"daxm002": [
|
||||
"Il nous faut quelque chose pour passer ce portail !"
|
||||
"We need something to get through that gate!"
|
||||
],
|
||||
"daxm003": [
|
||||
"Tire sur le Metal Head dès qu'il bouge son bouclier !"
|
||||
"Shoot the Metal Head when he moves his shield!"
|
||||
],
|
||||
"daxm004": [
|
||||
"Vise l'estomac !"
|
||||
"Hit him in his stomach!"
|
||||
],
|
||||
"daxm005": [
|
||||
"Waouh, ce sentier plonge... à pic !"
|
||||
"Whoa! That path dropped like uh... a rock!"
|
||||
],
|
||||
"daxm006": [
|
||||
"Trop de la balle, mon chou !"
|
||||
"Smack the box, baby!"
|
||||
],
|
||||
"daxm007": [
|
||||
"That's what I call a rocky road!"
|
||||
@@ -2043,10 +2040,10 @@
|
||||
"We gotta get to the top!"
|
||||
],
|
||||
"daxm009": [
|
||||
"On l'a fait !!"
|
||||
"We made it!!"
|
||||
],
|
||||
"daxm010": [
|
||||
"Le délire !"
|
||||
"Rock 'n roll!"
|
||||
],
|
||||
"ds001": [
|
||||
"On doit trouver le Baron, Jak."
|
||||
@@ -6556,6 +6553,18 @@
|
||||
"kwbf042": [
|
||||
"Arghh ! Espèce de... !"
|
||||
],
|
||||
"mtn-plat-buried-rocks-a": [
|
||||
"*Tremblement de terre*"
|
||||
],
|
||||
"mtn-step-plat-rocks-a": [
|
||||
"*Une plateforme apparait dans le mur*"
|
||||
],
|
||||
"mtn-step-plat-rocks-b": [
|
||||
"*Des plateformes apparaissent dans le mur*"
|
||||
],
|
||||
"mtn-step-plat-rocks-c": [
|
||||
"*Des plateformes apparaissent dans le mur et le rocher*"
|
||||
],
|
||||
"ora006": [
|
||||
"Rapportez-moi encore 200 Gemmes Crâniennes de Metal Heads",
|
||||
"et je vous montrerai une autre énergie noire."
|
||||
@@ -7550,6 +7559,12 @@
|
||||
"c'est sûrement quelque chose de précieux.",
|
||||
"Vous devriez jeter un oeil."
|
||||
],
|
||||
"tombplta": [
|
||||
"*Les pilliers prennent de la hauteur*"
|
||||
],
|
||||
"tombpltb": [
|
||||
"*Un escalier apparait et s'assemble*"
|
||||
],
|
||||
"tor001": [
|
||||
"L'opération est un véritable succès. Tous les membres des Souterrains sont sains et saufs.",
|
||||
"Rentrez à la cachette, j'ai une nouvelle mission à vous confier en attendant que ça se calme."
|
||||
@@ -7791,6 +7806,12 @@
|
||||
"Ils entrent de force !!",
|
||||
"Ils sont trop nombreux !! Jak !!! AHHHH !!!"
|
||||
],
|
||||
"wtrdrain": [
|
||||
"*L'eau se vide du SAS*"
|
||||
],
|
||||
"wtrfill": [
|
||||
"*Le SAS se remplit d'eau*"
|
||||
],
|
||||
"ys001": [
|
||||
"Excellent les gars ! Revenez à la cachette,",
|
||||
"j'ai une autre mission pour vous."
|
||||
@@ -7829,7 +7850,7 @@
|
||||
"mog": "Mog",
|
||||
"onin": "Onin",
|
||||
"oracle": "Oracle",
|
||||
"pecker": "Mog",
|
||||
"pecker": "Pecker",
|
||||
"precursor": "Precurseur",
|
||||
"samos": "Samos",
|
||||
"sig": "Sig",
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -5,14 +5,14 @@
|
||||
"You sure seem angry, Jak."
|
||||
],
|
||||
"DSbop002": [
|
||||
"ジャンプできる?"
|
||||
"Do you remember how to jump?"
|
||||
],
|
||||
"DSbop003": [
|
||||
"Jump onto that crate to get over the barricade."
|
||||
],
|
||||
"DSbop004": [
|
||||
"Ooh, that's a high ledge!",
|
||||
"デカイ段差!ジャンプして空中でもう一度ジャンプだよ!!",
|
||||
"Try jumping once, then jump again while in the air",
|
||||
"to reach that one."
|
||||
],
|
||||
"DSbop005": [
|
||||
@@ -1705,7 +1705,7 @@
|
||||
"This sector is closed."
|
||||
],
|
||||
"cityv039": [
|
||||
"警告:脱獄者が発生"
|
||||
"Alert: Prison escape in progress."
|
||||
],
|
||||
"cityv040": [
|
||||
"Alert: City under attack."
|
||||
@@ -2128,7 +2128,7 @@
|
||||
"Break those tubes in the center."
|
||||
],
|
||||
"ds020": [
|
||||
"なあ転がり方、覚えてる?"
|
||||
"Please tell me you remember how to roll..."
|
||||
],
|
||||
"ds023": [
|
||||
"Let's rock!"
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -65,6 +65,50 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"mtn-plat-buried-rocks-a": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 168,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mtn-step-plat-rocks-a": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 88,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mtn-step-plat-rocks-b": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 92,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mtn-step-plat-rocks-c": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 80,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sam001": {
|
||||
"lines": [
|
||||
{
|
||||
@@ -126,6 +170,50 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"tombplta": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 129,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tombpltb": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 350,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"wtrdrain": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 163,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"wtrfill": {
|
||||
"lines": [
|
||||
{
|
||||
"frame_end": 165,
|
||||
"frame_start": 0,
|
||||
"merge": false,
|
||||
"offscreen": true,
|
||||
"speaker": "none"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ys002": {
|
||||
"lines": [
|
||||
{
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"1a3": "Bitte entferne oder verbinde kein Zubehör und schalte weder das System noch das Spiel aus",
|
||||
"1a3": "Bitte entferne oder verbinde kein Zubehör und schalte nicht das System oder Spiel aus",
|
||||
"1b5": "Während dieses Symbol angezeigt wird, entferne oder verbinde kein Zubehör und schalte nicht das System oder das Spiel aus",
|
||||
"1100": "Keine Mission",
|
||||
"1100": "Nicht in einer Mission",
|
||||
"1101": "Spielt eine Bonusmission",
|
||||
"1102": "Scatter Waffen-Training",
|
||||
"1102": "Blaster-Trainingskurs",
|
||||
"1103": "Blaster-Trainingskurs",
|
||||
"1104": "Vulcan-Fury-Trainingskurs",
|
||||
"1105": "Friedensstifter-Trainingskurs",
|
||||
"1106": "Onins Spiel",
|
||||
"1107": "Metal Head Matsch",
|
||||
"1200": "Anzeigemodus",
|
||||
"1201": "Fenstermodus",
|
||||
"1201": "Fenster",
|
||||
"1202": "Vollbild",
|
||||
"1203": "Randlos",
|
||||
"1204": "Automatisch",
|
||||
@@ -28,7 +28,7 @@
|
||||
"1210": "Breite",
|
||||
"1211": "Höhe",
|
||||
"1212": "??????????",
|
||||
"1213": "Wird gerade gespielt...",
|
||||
"1213": "Jetzt spielt...",
|
||||
"1214": "Kein Titel",
|
||||
"1215": "Standard",
|
||||
"1216": "Morph-Waffe",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"1a3": "Sauvegarde en cours. Veillez à ne retirer ou n'insérer aucun périphérique, ni éteindre votre système ou arrêter le jeu.",
|
||||
"1b5": "Lorsque cette icône apparait, ne retirez ou n'insérez aucun périphérique, ni éteindre votre système ou arrêter le jeu.",
|
||||
"1100": "Pas en mission",
|
||||
"1a3": "Sauvegarde en cours. Veuillez à ne retirer ou n'insérer aucun périphérique, ni éteindre votre système ou arrêter le jeu.",
|
||||
"1b5": "Lorsque cette icône est à l'écran, ne retirez ou n'insérez aucun périphérique, ni éteindre votre système ou arrêter le jeu.",
|
||||
"1100": "Pas dans une mission",
|
||||
"1101": "Jouer une mission bonus",
|
||||
"1102": "Pulvérisator (Entraînement)",
|
||||
"1103": "Blaster (Entraînement)",
|
||||
"1104": "Vulcanobarillet (Entraînement)",
|
||||
"1105": "Pacificateur (Entraînement)",
|
||||
"1102": "Pulvérisator (Entrainement)",
|
||||
"1103": "Blaster (Entrainement)",
|
||||
"1104": "Vulcanobarillet (Entrainement)",
|
||||
"1105": "Pacificateur (Entrainement)",
|
||||
"1106": "Le jeu d'Onin",
|
||||
"1107": "Chasse-taupe",
|
||||
"1200": "Mode d'affichage",
|
||||
@@ -113,7 +113,7 @@
|
||||
"1266": "Réduire la population d'Abriville de ~D",
|
||||
"1267": "Réduire le nombre de véhicules d'Abriville de ~D",
|
||||
"1268": "Chassez toutes les espèces de Metal Head",
|
||||
"1269": "Utilisez le JET-Board pour casser les caisses",
|
||||
"1269": "Use the JET-Board to break open containers",
|
||||
"126a": "Transport the Rift Rider while leaving Samos and Young Samos unscathed",
|
||||
"1280": "Options de caméra",
|
||||
"1281": "Horizontal (1ère Personne)",
|
||||
@@ -155,24 +155,24 @@
|
||||
"12a5": "Bestiaire",
|
||||
"12a6": "Autres statistiques",
|
||||
"12a7": "Total Tué",
|
||||
"12a8": "Tué par Jak",
|
||||
"12a9": "Tué par Dark Jak",
|
||||
"12aa": "Tué par Daxter",
|
||||
"12ab": "Tué par d'autres",
|
||||
"12a8": "Killed by Jak",
|
||||
"12a9": "Killed by Dark Jak",
|
||||
"12aa": "Killed by Daxter",
|
||||
"12ab": "Killed by Others",
|
||||
"12ac": "Blaster",
|
||||
"12ad": "Pulvérisator",
|
||||
"12ae": "Vulcanobarillet",
|
||||
"12af": "Pacificateur",
|
||||
"12ad": "Scatter Gun",
|
||||
"12ae": "Vulcan Fury",
|
||||
"12af": "Peacemaker",
|
||||
"12b0": "JET-Board",
|
||||
"12b1": "Figure de JET-Board",
|
||||
"12b2": "Coup de poing de la Combinaison Titan",
|
||||
"12b3": "Combinaison Titan",
|
||||
"12b1": "JET-Board Trick",
|
||||
"12b2": "Titan Suit Punch",
|
||||
"12b3": "Titan Suit Body",
|
||||
"12b4": "Gunpod",
|
||||
"12b5": "Coup de poing",
|
||||
"12b5": "Punch",
|
||||
"12b6": "Flop",
|
||||
"12b7": "Uppercut",
|
||||
"12b8": "Spin",
|
||||
"12b9": "Rouler",
|
||||
"12b9": "Roll",
|
||||
"12bf": "Dark Bomb",
|
||||
"12c0": "Dark Blast",
|
||||
"12c3": "Grenagarde",
|
||||
@@ -230,7 +230,7 @@
|
||||
"1334": "Actor Culling",
|
||||
"1335": "Force Environment Mapping",
|
||||
"1336": "Menu de pause rapide",
|
||||
"1337": "Distance du niveau de détail PS2",
|
||||
"1338": "Non",
|
||||
"1337": "PS2 LOD Distance",
|
||||
"1338": "Off",
|
||||
"1339": "Écran"
|
||||
}
|
||||
@@ -1,46 +1,46 @@
|
||||
{
|
||||
"1a3": "??機器をぬいたり, さしたり, 電源を切ったりは しないでください",
|
||||
"1b5": "このアイコンが あらわれている間、??機器をぬいたり, さしたり, 電源を切ったりは しないでください",
|
||||
"1100": "ミッションがありません",
|
||||
"1101": "ボーナスミッションをプレイする",
|
||||
"1102": "レッドバースト・ガン トレーニングコース",
|
||||
"1103": "イエローブラスター・ガン トレーニングコース",
|
||||
"1104": "ブルーバルカン・ガン トレーニングコース",
|
||||
"1105": "ピースメーカー トレーニングコース",
|
||||
"1106": "オニンゲーム",
|
||||
"1107": "メタルたたき",
|
||||
"1200": "ディスプレイモード",
|
||||
"1a3": "しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
|
||||
"1b5": "このアイコンが あらわれているあいだ、しゅうへんききをぬいたり, さしたり, でんげんを きったりは しないでください",
|
||||
"1100": "Not in a mission",
|
||||
"1101": "Playing a bonus mission",
|
||||
"1102": "Scatter Gun Training Course",
|
||||
"1103": "Blaster Training Course",
|
||||
"1104": "Vulcan Fury Training Course",
|
||||
"1105": "Peace Maker Training Course",
|
||||
"1106": "Onin Game",
|
||||
"1107": "Metal Head Mash",
|
||||
"1200": "スクリーンモード",
|
||||
"1201": "ウィンドウ",
|
||||
"1202": "フルスクリーン",
|
||||
"1203": "ボーダレス",
|
||||
"1204": "自動",
|
||||
"1205": "カスタム",
|
||||
"1204": "Automatic",
|
||||
"1205": "Custom",
|
||||
"1206": "4x3 (PS2)",
|
||||
"1207": "16x9 (PS2)",
|
||||
"1208": "?と高さの??を選?",
|
||||
"1209": "<PAD_X> を押して??して終了します",
|
||||
"120a": "<PAD_CIRCLE> を押して??して終了します",
|
||||
"120b": "??は4x3より低くてはなりません!",
|
||||
"120c": "ミュージックプレイヤー",
|
||||
"120d": "????",
|
||||
"1208": "Choose width and height ratio",
|
||||
"1209": "Press <PAD_X> to confirm and exit.",
|
||||
"120a": "Press <PAD_CIRCLE> to confirm and exit.",
|
||||
"120b": "Ratio must not be lower than 4x3!",
|
||||
"120c": "BGMプレイヤー",
|
||||
"120d": "すいちょくどうき",
|
||||
"120e": "テキストの言語",
|
||||
"120f": "OpenGOALシークレット",
|
||||
"1210": "??",
|
||||
"1211": "高さ",
|
||||
"120f": "OpenGOAL Secrets",
|
||||
"1210": "Width",
|
||||
"1211": "Height",
|
||||
"1212": "??????????",
|
||||
"1213": "Now playing...",
|
||||
"1214": "トラックなし",
|
||||
"1214": "No Track",
|
||||
"1215": "デフォルト",
|
||||
"1216": "モーフィング・ガン",
|
||||
"1217": "ジェットボード",
|
||||
"1218": "タイタンスーツ",
|
||||
"1219": "ダークジャック",
|
||||
"121a": "乗り物",
|
||||
"121b": "??",
|
||||
"121b": "Danger",
|
||||
"121c": "None",
|
||||
"121d": "低",
|
||||
"121e": "中",
|
||||
"121f": "高",
|
||||
"121d": "Low",
|
||||
"121e": "Medium",
|
||||
"121f": "High",
|
||||
"1220": "Haven Exploration",
|
||||
"1221": "Guard Pursuit",
|
||||
"1222": "Ram Head Battle (Alt)",
|
||||
@@ -65,172 +65,172 @@
|
||||
"1235": "Weapons Factory",
|
||||
"1236": "Arena Race",
|
||||
"1237": "Dead Town",
|
||||
"1238": "ウィンドウサイズ",
|
||||
"1239": "ウィンドウサイズを選?",
|
||||
"123a": "解像?",
|
||||
"123b": "ゲーム解像?を選?",
|
||||
"123c": "???(バックグラウンド)",
|
||||
"123d": "???(フォアグラウンド)",
|
||||
"123f": "字幕にスピーカーを表示",
|
||||
"1238": "Window Size",
|
||||
"1239": "Select Window Size",
|
||||
"123a": "かいぞうど",
|
||||
"123b": "Select Game Resolution",
|
||||
"123c": "Level Of Detail (はいけい)",
|
||||
"123d": "Level Of Detail (ぜんけい)",
|
||||
"123f": "じまくではなしてをひょうじする",
|
||||
"1240": "いつもしなく",
|
||||
"1241": "オフスクリーン",
|
||||
"1242": "?時",
|
||||
"1243": "ゲーム地?",
|
||||
"1241": "Off-Screen",
|
||||
"1242": "イツモ",
|
||||
"1243": "ゲームのこくど",
|
||||
"1244": "アメリカ(SCEA)",
|
||||
"1245": "ヨーロッパ(SCEE)",
|
||||
"1246": "にほん(SCEI)",
|
||||
"1247": "かんこく(SCEK)",
|
||||
"1248": "MSAA",
|
||||
"1249": "~DX",
|
||||
"124a": "コントローラーLEDオプション",
|
||||
"124b": "プレイヤーステータスを表示",
|
||||
"124c": "?力を表示",
|
||||
"124a": "Controller LED Options",
|
||||
"124b": "Show Player State",
|
||||
"124c": "Show Amount of Health",
|
||||
"124d": "オートセーブを無?にする",
|
||||
"124e": "オートセーブ オフ",
|
||||
"124f": "オートセーブをきっても よろしいでしょうか?",
|
||||
"1250": "ヘイブンシティのターボジェットボード",
|
||||
"1251": "敵の?力バー",
|
||||
"1252": "??の?力バー",
|
||||
"1253": "??の無敵",
|
||||
"1254": "????",
|
||||
"1255": "コレクションを自動?に??する",
|
||||
"1256": "ミュージックプレイヤー",
|
||||
"1257": "テクスチャなしモード",
|
||||
"1258": "?いムービー",
|
||||
"1259": "?いムービー",
|
||||
"125a": "高?ゲームプレイ",
|
||||
"125b": "低?ゲームプレイ",
|
||||
"125c": "ヘイブンシティの???行",
|
||||
"125d": "プリカーソルオーブトラッカー",
|
||||
"1250": "Turbo JET-Board in Haven City",
|
||||
"1251": "Enemy Health Bars",
|
||||
"1252": "Vehicle Health Bars",
|
||||
"1253": "Vehicle Invulnerability",
|
||||
"1254": "Statistics",
|
||||
"1255": "Automatically Grab Collectables",
|
||||
"1256": "Music Player",
|
||||
"1257": "No Textures Mode",
|
||||
"1258": "Fast Movies",
|
||||
"1259": "Slow Movies",
|
||||
"125a": "Fast Gameplay",
|
||||
"125b": "Slow Gameplay",
|
||||
"125c": "Instant Travel in Haven City",
|
||||
"125d": "Precursor Orb Tracker",
|
||||
"125e": "リアルタイムオブデイ",
|
||||
"125f": "??なヘブンシティ",
|
||||
"1260": "ジェットボードトリックディスプレイ",
|
||||
"1261": "?い天?",
|
||||
"1262": "?い天?",
|
||||
"1263": "??ハイジャック??ライン",
|
||||
"1264": "ロック中",
|
||||
"1265": "3つのバルブをすべてヒットさせ、~D秒以内に?~S?のマールの像を見つける",
|
||||
"1266": "ヘブンシティの??を~D人?らす",
|
||||
"1267": "ヘブンシティの??を~D台?らす",
|
||||
"1268": "??な種?のメタルヘッドを?る",
|
||||
"1269": "ジェットボードを使って開いているコンテナを破壊する",
|
||||
"126a": "セイジィと?いセイジィを無?のままリフト・ライダーまで輸送する",
|
||||
"125f": "Pacified Haven City",
|
||||
"1260": "JET-Board Trick Display",
|
||||
"1261": "Bad Weather",
|
||||
"1262": "Nice Weather",
|
||||
"1263": "Vehicle Hijack Voice Lines",
|
||||
"1264": "Locked",
|
||||
"1265": "Hit all 3 valves and find Mar's Statue in \"~S\" in under ~D seconds",
|
||||
"1266": "Reduce Haven City's population count by ~D",
|
||||
"1267": "Reduce Haven City's vehicle count by ~D",
|
||||
"1268": "Hunt every species of Metal Head",
|
||||
"1269": "Use the JET-Board to break open containers",
|
||||
"126a": "Transport the Rift Rider while leaving Samos and Young Samos unscathed",
|
||||
"1280": "カメラ オプション",
|
||||
"1281": "左/右 (1人?)",
|
||||
"1282": "上/下(1人?)",
|
||||
"1283": "左/右 (3人?)",
|
||||
"1284": "上/下(3人?)",
|
||||
"1285": "デフォルトに戻す",
|
||||
"1281": "Left/Right (1st Person)",
|
||||
"1282": "Up/Down (1st Person)",
|
||||
"1283": "Left/Right (3rd Person)",
|
||||
"1284": "Up/Down (3rd Person)",
|
||||
"1285": "Reset to Default",
|
||||
"1286": "ノーマル",
|
||||
"1287": "リバース",
|
||||
"1288": "パーティクル カリング",
|
||||
"1289": "Discordリッチプレゼンス",
|
||||
"128a": "デフォルト",
|
||||
"128b": "低",
|
||||
"128c": "高",
|
||||
"128d": "クレジット",
|
||||
"128a": "Default",
|
||||
"128b": "Low",
|
||||
"128c": "High",
|
||||
"128d": "Credits",
|
||||
"128e": "フレームレート",
|
||||
"128f": "その?",
|
||||
"128f": "そのほか",
|
||||
"1290": "スピードラン モード",
|
||||
"1291": "入力??",
|
||||
"1292": "????に戻す",
|
||||
"1293": "コントローラーオプション",
|
||||
"1294": "コントローラーを選?する",
|
||||
"1295": "アナログデッドゾーン",
|
||||
"1296": "ウィンドウのフォーカスが外れているときは無?する",
|
||||
"1297": "コントローラーのLEDで?力を表示する",
|
||||
"1298": "LEDを?の??で使用",
|
||||
"1299": "キーボードを??にする",
|
||||
"129a": "マウスを??にする",
|
||||
"1291": "Input Options",
|
||||
"1292": "リセット デフォルト",
|
||||
"1293": "コントローラオプション",
|
||||
"1294": "コントローラをせんたくする",
|
||||
"1295": "Analog Deadzone",
|
||||
"1296": "Ignore If Window Unfocused",
|
||||
"1297": "コントローラのLedでたい力をひょうじする",
|
||||
"1298": "Use LED for Other States",
|
||||
"1299": "Enable Keyboard",
|
||||
"129a": "Enable Mouse",
|
||||
"129b": "マウスオプション",
|
||||
"129c": "?跡カメラ",
|
||||
"129d": "水?感?",
|
||||
"129e": "??感?",
|
||||
"129f": "プレイヤーの?動",
|
||||
"12a0": "オブジェクトの?",
|
||||
"12a1": "ノーマル",
|
||||
"12a2": "??",
|
||||
"12a3": "??な解像?が見つかりませんでした",
|
||||
"12a4": "自動",
|
||||
"12a5": "ベスティアリー",
|
||||
"12a6": "その?の????",
|
||||
"12a7": "?キル数",
|
||||
"12a8": "ジャックに倒された",
|
||||
"12a9": "ダークジャックに倒された",
|
||||
"12aa": "ダクスターに倒された",
|
||||
"12ab": "?者に倒された",
|
||||
"12ac": "イエローブラスター",
|
||||
"12ad": "レッドバースト",
|
||||
"12ae": "ブルーバルカン",
|
||||
"12af": "ピースメーカー",
|
||||
"12b0": "ジェットボード",
|
||||
"12b1": "ジェットボードトリック",
|
||||
"12b2": "タイタンスーツのパンチ",
|
||||
"12b3": "タイタンスーツのボディ",
|
||||
"12b4": "砲撃台",
|
||||
"12b5": "パンチ",
|
||||
"12b6": "フロップ",
|
||||
"12b7": "アッパーカット",
|
||||
"12b8": "スピン",
|
||||
"12b9": "ロール",
|
||||
"12bf": "ダークボム",
|
||||
"12c0": "ダークブラスト",
|
||||
"12c3": "クリムゾンガード",
|
||||
"12c4": "ジーグ",
|
||||
"12c5": "アシュリン",
|
||||
"12c6": "ジンクス",
|
||||
"12c7": "グリム",
|
||||
"12c8": "モグ",
|
||||
"12c9": "メタルヘッド",
|
||||
"12ca": "?の友?",
|
||||
"12cb": "?の敵",
|
||||
"1300": "自動でカーソルを?す",
|
||||
"1301": "バインドの??り?て",
|
||||
"129c": "Track Camera",
|
||||
"129d": "Horizontal Sensitivity",
|
||||
"129e": "Vertical Sensitivity",
|
||||
"129f": "Player Movement",
|
||||
"12a0": "Object Shadows",
|
||||
"12a1": "Normal",
|
||||
"12a2": "Extended",
|
||||
"12a3": "No valid resolutions found.",
|
||||
"12a4": "Automatic",
|
||||
"12a5": "Bestiary",
|
||||
"12a6": "Other Statistics",
|
||||
"12a7": "Total Killed",
|
||||
"12a8": "Killed by Jak",
|
||||
"12a9": "Killed by Dark Jak",
|
||||
"12aa": "Killed by Daxter",
|
||||
"12ab": "Killed by Others",
|
||||
"12ac": "Blaster",
|
||||
"12ad": "Scatter Gun",
|
||||
"12ae": "Vulcan Fury",
|
||||
"12af": "Peacemaker",
|
||||
"12b0": "JET-Board",
|
||||
"12b1": "JET-Board Trick",
|
||||
"12b2": "Titan Suit Punch",
|
||||
"12b3": "Titan Suit Body",
|
||||
"12b4": "Gunpod",
|
||||
"12b5": "Punch",
|
||||
"12b6": "Flop",
|
||||
"12b7": "Uppercut",
|
||||
"12b8": "Spin",
|
||||
"12b9": "Roll",
|
||||
"12bf": "Dark Bomb",
|
||||
"12c0": "Dark Blast",
|
||||
"12c3": "Krimzon Guard",
|
||||
"12c4": "Sig",
|
||||
"12c5": "Ashelin",
|
||||
"12c6": "Jinx",
|
||||
"12c7": "Grim",
|
||||
"12c8": "Mog",
|
||||
"12c9": "Metal Heads",
|
||||
"12ca": "Other Friends",
|
||||
"12cb": "Other Enemies",
|
||||
"1300": "Auto Hide Cursor",
|
||||
"1301": "Reassign Binds",
|
||||
"1302": "コントローラのバインド",
|
||||
"1303": "キーボードのバインド",
|
||||
"1304": "マウスのバインド",
|
||||
"1305": "オプションなし",
|
||||
"1306": "?機中",
|
||||
"1307": "???",
|
||||
"1308": "??",
|
||||
"1309": "高解像?の空",
|
||||
"130a": "高?エアロックとドア",
|
||||
"130b": "高?エレベーター",
|
||||
"130c": "スピードラン",
|
||||
"1305": "No Options",
|
||||
"1306": "Waiting",
|
||||
"1307": "みけってい",
|
||||
"1308": "?られていない",
|
||||
"1309": "High-Resolution Sky",
|
||||
"130a": "Fast Airlocks and Doors",
|
||||
"130b": "Fast Elevators",
|
||||
"130c": "Speedrun",
|
||||
"130d": "Any%",
|
||||
"130e": "Any% - Hoverless",
|
||||
"130f": "All Missions",
|
||||
"1310": "100%",
|
||||
"1311": "Any% - All Orbs",
|
||||
"1312": "Any% - Hero Mode",
|
||||
"1313": "ローカルタイム",
|
||||
"1314": "警告!",
|
||||
"1315": "この??は??に???なものです.?秒60フレームで??されていない場合、???な??やゲームプレイの??が発?する?能性があります.",
|
||||
"1316": "ローカルスコア",
|
||||
"1313": "Local Time",
|
||||
"1314": "Warning!",
|
||||
"1315": "This setting is highly experimental. When not played at 60 frames per second, visual and gameplay issues may arise as a result.",
|
||||
"1316": "Local Score",
|
||||
"1320": "なし",
|
||||
"1321": "スピン",
|
||||
"1322": "ブースト",
|
||||
"1323": "フリップ",
|
||||
"1324": "レールグラインド",
|
||||
"1325": "レールジャンプ",
|
||||
"1326": "ノーズグラブ",
|
||||
"1327": "メソッド",
|
||||
"1326": "Nosegrab",
|
||||
"1327": "Method",
|
||||
"1328": "ボードスピン",
|
||||
"1329": "ボードフリップ",
|
||||
"132a": "ノーズフリップ",
|
||||
"132a": "Noseflip",
|
||||
"132b": "キックフリップ",
|
||||
"132c": "ジャンプ",
|
||||
"132d": "ダックジャンプ",
|
||||
"132e": "クイックジャンプ",
|
||||
"132d": "Duck Jump",
|
||||
"132e": "Quick Jump",
|
||||
"132f": "ダークジャック",
|
||||
"1330": "ダークボム",
|
||||
"1331": "ダークブラスト",
|
||||
"1332": "ダークジャイアント",
|
||||
"1333": "PS2オプション",
|
||||
"1334": "アクターカリング",
|
||||
"1335": "?制?に??マッピング",
|
||||
"1336": "高?進行??メニュー",
|
||||
"1337": "PS2 LOD ??",
|
||||
"1338": "オフ",
|
||||
"1339": "ディスプレイ"
|
||||
"1330": "Dark Bomb",
|
||||
"1331": "Dark Blast",
|
||||
"1332": "Dark Giant",
|
||||
"1333": "PS2 Options",
|
||||
"1334": "Actor Culling",
|
||||
"1335": "Force Environment Mapping",
|
||||
"1336": "Fast Progress Menu",
|
||||
"1337": "PS2 LOD Distance",
|
||||
"1338": "Off",
|
||||
"1339": "Display"
|
||||
}
|
||||
@@ -484,7 +484,7 @@
|
||||
03000000f0250000c183000000000000,PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||
030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d620000011a7000000000000,PowerA Core Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d620000011a7000000000000,PowerA Core Plus GameCube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||
03000000dd62000015a7000000000000,PowerA Fusion Nintendo Switch Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000d620000012a7000000000000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
03000000dd62000016a7000000000000,PowerA Fusion Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||
@@ -873,7 +873,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||
03000000050b00000579000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000503200000110000045010000,Atari VCS Classic,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:MacOSX
|
||||
03000000503200000110000047010000,Atari VCS Classic Controller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b3,start:b2,platform:Mac OS X,
|
||||
03000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000008a3500000102000000010000,Backbone One,a:b0,b:b1,back:b16,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b17,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b15,x:b2,y:b3,platform:Mac OS X,
|
||||
@@ -1081,7 +1080,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X,
|
||||
030000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||
030000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
@@ -1091,7 +1090,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000005e040000130b000015050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000005e040000130b000007050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000005e040000130b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
030000005e040000220b000017050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
03000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||
@@ -1390,7 +1388,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e0400008e02000030110000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b00000b050000,Microsoft Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000120b000001050000,Microsoft Xbox Series X Controller,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,platform:Linux,
|
||||
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||
03000000790000001c18000010010000,Mobapad Chitu HD,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
@@ -1468,7 +1465,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
03000000d620000011a7000011010000,PowerA Core Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000d620000011a7000011010000,PowerA Core Plus Gamecube Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||
03000000dd62000015a7000011010000,PowerA Fusion Nintendo Switch Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000d620000012a7000011010000,PowerA Fusion Nintendo Switch Fight Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||
03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
@@ -1690,7 +1687,6 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
030000005e040000ea02000011050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
050082795e040000e002000003090000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
@@ -1698,8 +1694,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
|
||||
030000005e040000120b000007050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b000009050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b000015050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000120b00000f050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||
|
||||
@@ -31,3 +31,19 @@ struct RPC_Dgo_Cmd {
|
||||
// a buffer.
|
||||
uint8_t pad[32];
|
||||
};
|
||||
|
||||
namespace jak3 {
|
||||
struct RPC_Dgo_Cmd {
|
||||
uint16_t rsvd;
|
||||
uint16_t result;
|
||||
uint32_t buffer1;
|
||||
uint32_t buffer2;
|
||||
uint32_t buffer_heap_top;
|
||||
char name[16];
|
||||
uint16_t cgo_id;
|
||||
uint8_t pad[30];
|
||||
};
|
||||
static_assert(sizeof(RPC_Dgo_Cmd) == 0x40);
|
||||
} // namespace jak3
|
||||
|
||||
static_assert(sizeof(RPC_Dgo_Cmd) == sizeof(jak3::RPC_Dgo_Cmd));
|
||||
@@ -3,10 +3,6 @@
|
||||
#include "fmt/core.h"
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
std::string BucketRenderer::name() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
std::string BucketRenderer::name_and_id() const {
|
||||
return fmt::format("[{:2d}] {}", (int)m_my_id, m_name);
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ class EyeRenderer;
|
||||
struct SharedRenderState {
|
||||
explicit SharedRenderState(std::shared_ptr<TexturePool> _texture_pool,
|
||||
std::shared_ptr<Loader> _loader,
|
||||
GameVersion _version)
|
||||
: shaders(_version), texture_pool(_texture_pool), loader(_loader), version(_version) {}
|
||||
GameVersion version)
|
||||
: shaders(version), texture_pool(_texture_pool), loader(_loader) {}
|
||||
ShaderLibrary shaders;
|
||||
std::shared_ptr<TexturePool> texture_pool;
|
||||
std::shared_ptr<Loader> loader;
|
||||
@@ -98,7 +98,6 @@ class BucketRenderer {
|
||||
virtual void render(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof) = 0;
|
||||
std::string name() const;
|
||||
std::string name_and_id() const;
|
||||
virtual ~BucketRenderer() = default;
|
||||
bool& enabled() { return m_enabled; }
|
||||
@@ -159,4 +158,4 @@ class PrintRenderer : public BucketRenderer {
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
bool empty() const override { return true; }
|
||||
void draw_debug_window() override {}
|
||||
};
|
||||
};
|
||||
@@ -579,7 +579,6 @@ u32 get_direct_qwc_or_nop(const VifCode& code) {
|
||||
return code.immediate;
|
||||
}
|
||||
default:
|
||||
printf("expected direct, got %s\n", code.print().c_str());
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ EyeRenderer::SpriteInfo decode_sprite(const DmaTransfer& dma) {
|
||||
memcpy(&result.a, dma.data + 16 + 12, 1); // a
|
||||
|
||||
// uv0
|
||||
memcpy(&result.uv0, &dma.data[32], 8);
|
||||
memcpy(&result.uv0[0], &dma.data[32], 8);
|
||||
|
||||
// xyz0
|
||||
memcpy(&result.xyz0[0], &dma.data[48], 12);
|
||||
@@ -236,11 +236,8 @@ std::vector<EyeRenderer::SingleEyeDraws> EyeRenderer::get_draws(DmaFollower& dma
|
||||
bool using_64 = false;
|
||||
{
|
||||
auto draw0 = read_eye_draw(dma);
|
||||
// ASSERT(draw0.sprite.uv0[0] == 0);
|
||||
// ASSERT(draw0.sprite.uv0[1] == 0);
|
||||
// printf("hashed name is 0x%x 0x%x\n", draw0.sprite.uv0[0], draw0.sprite.uv0[1]);
|
||||
l_draw.fnv_name_hash = draw0.sprite.uv0;
|
||||
r_draw.fnv_name_hash = draw0.sprite.uv0;
|
||||
ASSERT(draw0.sprite.uv0[0] == 0);
|
||||
ASSERT(draw0.sprite.uv0[1] == 0);
|
||||
ASSERT(draw0.sprite.uv1[0] == 0);
|
||||
ASSERT(draw0.sprite.uv1[1] == 0);
|
||||
if (draw0.scissor.y1 - draw0.scissor.y0 == 63) {
|
||||
@@ -512,9 +509,7 @@ void EyeRenderer::run_gpu(const std::vector<SingleEyeDraws>& draws,
|
||||
buffer_idx = 0;
|
||||
for (size_t draw_idx = 0; draw_idx < draws.size(); draw_idx++) {
|
||||
const auto& draw = draws[draw_idx];
|
||||
auto& out_tex = m_gpu_eye_textures[draw.tex_slot()];
|
||||
out_tex.fnv_name_hash = draw.fnv_name_hash;
|
||||
out_tex.lr = draw.lr;
|
||||
const auto& out_tex = m_gpu_eye_textures[draw.tex_slot()];
|
||||
|
||||
// first, the clear
|
||||
float clear[4] = {0, 0, 0, 0};
|
||||
@@ -579,30 +574,15 @@ std::optional<u64> EyeRenderer::lookup_eye_texture(u8 eye_id) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<u64> EyeRenderer::lookup_eye_texture_hash(u64 hash, bool lr) {
|
||||
for (auto& slot : m_gpu_eye_textures) {
|
||||
if (slot.fnv_name_hash == hash && slot.lr == lr) {
|
||||
auto* gpu_tex = slot.gpu_tex;
|
||||
if (gpu_tex) {
|
||||
return gpu_tex->gpu_textures.at(0).gl;
|
||||
} else {
|
||||
fmt::print("lookup eye failed for {} (1)\n", hash);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt::print("lookup eye failed for {} (2)\n", hash);
|
||||
return {};
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// DMA Decode
|
||||
//////////////////////
|
||||
|
||||
std::string EyeRenderer::SpriteInfo::print() const {
|
||||
std::string result;
|
||||
result += fmt::format("a: {:x} uv: ({}), ({}, {}) xyz: ({}, {}, {}), ({}, {}, {})", a, uv0,
|
||||
uv1[0], uv1[1], xyz0[0], xyz0[1], xyz0[2], xyz1[0], xyz1[1], xyz1[2]);
|
||||
result +=
|
||||
fmt::format("a: {:x} uv: ({}, {}), ({}, {}) xyz: ({}, {}, {}), ({}, {}, {})", a, uv0[0],
|
||||
uv0[1], uv1[0], uv1[1], xyz0[0], xyz0[1], xyz0[2], xyz1[0], xyz1[1], xyz1[2]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,10 @@ class EyeRenderer : public BucketRenderer {
|
||||
|
||||
void handle_eye_dma2(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
std::optional<u64> lookup_eye_texture(u8 eye_id);
|
||||
std::optional<u64> lookup_eye_texture_hash(u64 hash, bool lr);
|
||||
|
||||
struct SpriteInfo {
|
||||
u8 a;
|
||||
u64 uv0; // stores hashed name of merc-ctrl that reads this eye.
|
||||
u32 uv0[2];
|
||||
u32 uv1[2];
|
||||
u32 xyz0[3];
|
||||
u32 xyz1[3];
|
||||
@@ -54,8 +53,6 @@ class EyeRenderer : public BucketRenderer {
|
||||
GpuTexture* gpu_tex = nullptr;
|
||||
u32 tbp;
|
||||
FramebufferTexturePair fb;
|
||||
u64 fnv_name_hash = 0;
|
||||
bool lr = false;
|
||||
|
||||
// note: eye texture increased to 128x128 (originally 32x32) here.
|
||||
GpuEyeTex() : fb(128, 128, GL_UNSIGNED_INT_8_8_8_8_REV) {}
|
||||
@@ -68,7 +65,6 @@ class EyeRenderer : public BucketRenderer {
|
||||
GLuint m_gl_vertex_buffer;
|
||||
|
||||
struct SingleEyeDraws {
|
||||
u64 fnv_name_hash = 0;
|
||||
int lr;
|
||||
int pair;
|
||||
bool using_64 = false;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "game/graphics/pipelines/opengl.h"
|
||||
|
||||
#include "third-party/imgui/imgui.h"
|
||||
#include "third-party/imgui/imgui_stdlib.h"
|
||||
|
||||
// for the vif callback
|
||||
#include "game/kernel/common/kmachine.h"
|
||||
@@ -37,7 +36,6 @@
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#include "common/util/string_util.h"
|
||||
|
||||
namespace {
|
||||
std::string g_current_renderer;
|
||||
@@ -86,11 +84,7 @@ OpenGLRenderer::OpenGLRenderer(std::shared_ptr<TexturePool> texture_pool,
|
||||
&gl_error_ignores_api_other[0], GL_FALSE);
|
||||
#endif
|
||||
|
||||
lg::info("OpenGL context version: {}", (const char*)glGetString(GL_VERSION));
|
||||
lg::info("OpenGL context renderer: {}", (const char*)glGetString(GL_RENDERER));
|
||||
lg::info("OpenGL context vendor: {}", (const char*)glGetString(GL_VENDOR));
|
||||
lg::info("OpenGL context shading language version: {}",
|
||||
(const char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
lg::debug("OpenGL context information: {}", (const char*)glGetString(GL_VERSION));
|
||||
|
||||
const tfrag3::Level* common_level = nullptr;
|
||||
{
|
||||
@@ -269,11 +263,6 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC_L0_PRIS, BucketId::GMERC_L1_PRIS, i), m_generic2,
|
||||
Generic2::Mode::NORMAL);
|
||||
|
||||
init_bucket_renderer<Generic2BucketRenderer>(
|
||||
fmt::format("gmerc2-l{}-pris", i), BucketCategory::GENERIC,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC2_L0_PRIS, BucketId::GMERC2_L1_PRIS, i), m_generic2,
|
||||
Generic2::Mode::PRIM);
|
||||
|
||||
init_bucket_renderer<Merc2BucketRenderer>(
|
||||
fmt::format("merc-l{}-pris2", i), BucketCategory::MERC,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::MERC_L0_PRIS2, BucketId::MERC_L1_PRIS2, i), m_merc2);
|
||||
@@ -281,10 +270,6 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
fmt::format("gmerc-l{}-pris2", i), BucketCategory::GENERIC,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC_L0_PRIS2, BucketId::GMERC_L1_PRIS2, i), m_generic2,
|
||||
Generic2::Mode::NORMAL);
|
||||
init_bucket_renderer<Generic2BucketRenderer>(
|
||||
fmt::format("gmerc2-l{}-pris2", i), BucketCategory::GENERIC,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC2_L0_PRIS2, BucketId::GMERC2_L1_PRIS2, i),
|
||||
m_generic2, Generic2::Mode::PRIM);
|
||||
}
|
||||
|
||||
// 401
|
||||
@@ -296,10 +281,6 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
BucketId::GMERC_LCOM_PRIS, m_generic2,
|
||||
Generic2::Mode::NORMAL);
|
||||
|
||||
init_bucket_renderer<Generic2BucketRenderer>("gmerc2-lcom-pris", BucketCategory::GENERIC,
|
||||
BucketId::GMERC2_LCOM_PRIS, m_generic2,
|
||||
Generic2::Mode::PRIM);
|
||||
|
||||
// 461
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-sky-post", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_SKY_POST, m_texture_animator);
|
||||
@@ -325,10 +306,6 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
fmt::format("tfrag-l{}-water", i), BucketCategory::TFRAG,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::TFRAG_L0_WATER, BucketId::TFRAG_L1_WATER, i),
|
||||
std::vector{tfrag3::TFragmentTreeKind::WATER}, false, i, anim_slot_array());
|
||||
init_bucket_renderer<Generic2BucketRenderer>(
|
||||
fmt::format("gmerc2-l{}-water", i), BucketCategory::GENERIC,
|
||||
GET_BUCKET_ID_FOR_LIST(BucketId::GMERC2_L0_WATER, BucketId::GMERC2_L1_WATER, i),
|
||||
m_generic2, Generic2::Mode::PRIM);
|
||||
}
|
||||
|
||||
// 563
|
||||
@@ -336,20 +313,11 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
BucketId::TEX_LCOM_WATER, m_texture_animator);
|
||||
init_bucket_renderer<Merc2BucketRenderer>("merc-lcom-water", BucketCategory::MERC,
|
||||
BucketId::MERC_LCOM_WATER, m_merc2);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("generic2-lcom-water", BucketCategory::GENERIC,
|
||||
BucketId::GMERC2_LCOM_WATER, m_generic2,
|
||||
Generic2::Mode::PRIM);
|
||||
|
||||
// 568
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-sprite", BucketCategory::TEX,
|
||||
BucketId::TEX_SPRITE, m_texture_animator);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-1", BucketCategory::GENERIC,
|
||||
BucketId::GENERIC_SPRITE_1, m_generic2,
|
||||
Generic2::Mode::PRIM);
|
||||
init_bucket_renderer<Sprite3>("particles", BucketCategory::SPRITE, BucketId::PARTICLES);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-2", BucketCategory::GENERIC,
|
||||
BucketId::GENERIC_SPRITE_2, m_generic2,
|
||||
Generic2::Mode::PRIM);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("generic-sprite-3", BucketCategory::OTHER,
|
||||
BucketId::GENERIC_SPRITE_3, m_generic2,
|
||||
Generic2::Mode::LIGHTNING);
|
||||
@@ -1110,13 +1078,8 @@ void OpenGLRenderer::draw_renderer_selection_window() {
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::InputText("Renderer Filter", &m_renderer_filter);
|
||||
|
||||
for (size_t i = 0; i < m_bucket_renderers.size(); i++) {
|
||||
auto renderer = m_bucket_renderers[i].get();
|
||||
if (!m_renderer_filter.empty() && !str_util::contains(renderer->name(), m_renderer_filter)) {
|
||||
continue;
|
||||
}
|
||||
if (renderer && !renderer->empty()) {
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::TreeNode(renderer->name_and_id().c_str())) {
|
||||
|
||||
@@ -123,7 +123,6 @@ class OpenGLRenderer {
|
||||
|
||||
float m_last_pmode_alp = 1.;
|
||||
bool m_enable_fast_blackout_loads = true;
|
||||
std::string m_renderer_filter = "";
|
||||
|
||||
struct FboState {
|
||||
struct {
|
||||
|
||||
@@ -60,48 +60,23 @@
|
||||
* A simple list of preallocated textures by size. If a texture needs to be resized, it's faster
|
||||
* to swap to a different OpenGL texture from this pool than glTexImage2D with a different size.
|
||||
*/
|
||||
OpenGLTexturePool::OpenGLTexturePool(GameVersion version) {
|
||||
OpenGLTexturePool::OpenGLTexturePool() {
|
||||
struct Alloc {
|
||||
u64 w, h, n;
|
||||
};
|
||||
// list of sizes to preallocate: {width, height, count}.
|
||||
PerGameVersion<std::vector<Alloc>> tex_allocs{{{4, 4, 2},
|
||||
{4, 64, 2},
|
||||
{16, 16, 5},
|
||||
{32, 16, 1},
|
||||
{32, 32, 10},
|
||||
{32, 64, 1},
|
||||
{64, 32, 6},
|
||||
{64, 64, 30},
|
||||
{64, 128, 4},
|
||||
{128, 128, 10},
|
||||
{256, 1, 2},
|
||||
{256, 256, 7}},
|
||||
{{4, 4, 2},
|
||||
{4, 64, 2},
|
||||
{16, 16, 5},
|
||||
{32, 16, 1},
|
||||
{32, 32, 10},
|
||||
{32, 64, 1},
|
||||
{64, 32, 6},
|
||||
{64, 64, 30},
|
||||
{64, 128, 4},
|
||||
{128, 128, 10},
|
||||
{256, 1, 2},
|
||||
{256, 256, 7}},
|
||||
{{4, 4, 3},
|
||||
{4, 64, 6},
|
||||
{16, 16, 5},
|
||||
{32, 16, 1},
|
||||
{32, 32, 20},
|
||||
{32, 64, 1},
|
||||
{64, 32, 15},
|
||||
{64, 64, 85},
|
||||
{64, 128, 4},
|
||||
{128, 128, 185},
|
||||
{256, 1, 2},
|
||||
{256, 256, 7}}};
|
||||
for (const auto& a : tex_allocs[version]) {
|
||||
for (const auto& a : std::vector<Alloc>{{4, 4, 2},
|
||||
{4, 64, 2},
|
||||
{16, 16, 5},
|
||||
{32, 16, 1},
|
||||
{32, 32, 10},
|
||||
{32, 64, 1},
|
||||
{64, 32, 6},
|
||||
{64, 64, 30},
|
||||
{64, 128, 4},
|
||||
{128, 128, 10},
|
||||
{256, 1, 2},
|
||||
{256, 256, 7}}) {
|
||||
auto& l = textures[(a.w << 32) | a.h];
|
||||
l.resize(a.n);
|
||||
glGenTextures(a.n, l.data());
|
||||
@@ -395,7 +370,6 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders,
|
||||
const tfrag3::Level* common_level,
|
||||
GameVersion version)
|
||||
: m_common_level(common_level),
|
||||
m_opengl_texture_pool(version),
|
||||
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),
|
||||
@@ -446,7 +420,6 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders,
|
||||
m_shader_id = shader.id();
|
||||
m_uniforms.rgba = glGetUniformLocation(shader.id(), "rgba");
|
||||
m_uniforms.enable_tex = glGetUniformLocation(shader.id(), "enable_tex");
|
||||
m_uniforms.set_alpha = glGetUniformLocation(shader.id(), "set_alpha");
|
||||
m_uniforms.positions = glGetUniformLocation(shader.id(), "positions");
|
||||
m_uniforms.uvs = glGetUniformLocation(shader.id(), "uvs");
|
||||
m_uniforms.channel_scramble = glGetUniformLocation(shader.id(), "channel_scramble");
|
||||
@@ -669,7 +642,7 @@ GLuint TextureAnimator::get_by_slot(int idx) {
|
||||
}
|
||||
|
||||
// IDs sent from GOAL telling us what texture operation to perform.
|
||||
enum class PcTextureAnimCodesJak2 : u16 {
|
||||
enum PcTextureAnimCodes {
|
||||
FINISH_ARRAY = 13,
|
||||
ERASE_DEST_TEXTURE = 14,
|
||||
UPLOAD_CLUT_16_16 = 15,
|
||||
@@ -700,361 +673,6 @@ enum class PcTextureAnimCodesJak2 : u16 {
|
||||
CLOUDS_HIRES = 43,
|
||||
};
|
||||
|
||||
struct FixedAnimInfoJak2 {
|
||||
PcTextureAnimCodesJak2 code = (PcTextureAnimCodesJak2)0;
|
||||
std::string name;
|
||||
int anim_array_idx = -1;
|
||||
};
|
||||
|
||||
FixedAnimInfoJak2 anim_code_to_info(PcTextureAnimCodesJak2 code, const TextureAnimator& animator) {
|
||||
ASSERT(code > (PcTextureAnimCodesJak2)0);
|
||||
FixedAnimInfoJak2 anim;
|
||||
anim.code = code;
|
||||
switch (code) {
|
||||
case PcTextureAnimCodesJak2::SKULL_GEM: {
|
||||
anim.name = "skull-gem";
|
||||
anim.anim_array_idx = animator.m_skull_gem_fixed_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::BOMB: {
|
||||
anim.name = "bomb";
|
||||
anim.anim_array_idx = animator.m_bomb_fixed_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::CAS_CONVEYOR: {
|
||||
anim.name = "cas-conveyor";
|
||||
anim.anim_array_idx = animator.m_cas_conveyor_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::SECURITY: {
|
||||
anim.name = "security";
|
||||
anim.anim_array_idx = animator.m_security_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::WATERFALL: {
|
||||
anim.name = "waterfall";
|
||||
anim.anim_array_idx = animator.m_waterfall_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::WATERFALL_B: {
|
||||
anim.name = "waterfall-b";
|
||||
anim.anim_array_idx = animator.m_waterfall_b_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::LAVA: {
|
||||
anim.name = "lava";
|
||||
anim.anim_array_idx = animator.m_lava_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::LAVA_B: {
|
||||
anim.name = "lava-b";
|
||||
anim.anim_array_idx = animator.m_lava_b_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::STADIUMB: {
|
||||
anim.name = "stadiumb";
|
||||
anim.anim_array_idx = animator.m_stadiumb_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::FORTRESS_PRIS: {
|
||||
anim.name = "fort-pris";
|
||||
anim.anim_array_idx = animator.m_fortress_pris_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::FORTRESS_WARP: {
|
||||
anim.name = "fort-warp";
|
||||
anim.anim_array_idx = animator.m_fortress_warp_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::METKOR: {
|
||||
anim.name = "metkor";
|
||||
anim.anim_array_idx = animator.m_metkor_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::SHIELD: {
|
||||
anim.name = "shield";
|
||||
anim.anim_array_idx = animator.m_shield_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::KREW_HOLO: {
|
||||
anim.name = "krew-holo";
|
||||
anim.anim_array_idx = animator.m_krew_holo_anim_array_idx;
|
||||
} break;
|
||||
default:
|
||||
anim.name = "unknown";
|
||||
lg::error("Unknown texture anim code {}", (int)code);
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
|
||||
enum class PcTextureAnimCodesJak3 : u16 {
|
||||
FINISH_ARRAY = 13,
|
||||
ERASE_DEST_TEXTURE = 14,
|
||||
UPLOAD_CLUT_16_16 = 15,
|
||||
GENERIC_UPLOAD = 16,
|
||||
SET_SHADER = 17,
|
||||
DRAW = 18,
|
||||
DARKJAK = 22,
|
||||
DARKJAK_HIGHRES = 23,
|
||||
SKULL_GEM = 27,
|
||||
DEFAULT_WATER = 28,
|
||||
DEFAULT_WARP = 29,
|
||||
TEMPLEA_WATER = 30,
|
||||
TEMPLEA_WARP = 31,
|
||||
TEMPLEB_WARP = 32,
|
||||
TEMPLEC_WATER = 33,
|
||||
SEWC_WATER = 34,
|
||||
SEWD_WATER = 35,
|
||||
SEWE_WATER = 36,
|
||||
SEWG_WATER = 37,
|
||||
SEWH_WATER = 38,
|
||||
SEWI_WATER = 39,
|
||||
SEWJ_WATER = 40,
|
||||
SEWL_WATER = 41,
|
||||
SEWM_WATER = 42,
|
||||
SEWN_WATER = 43,
|
||||
DESRESC_WARP = 44,
|
||||
CTYSLUMB_WATER = 45,
|
||||
NSTB_QUICKSAND = 46,
|
||||
CTYSLUMC_WATER = 47,
|
||||
FACTORYC_ALPHA = 48,
|
||||
HFRAG = 49,
|
||||
HANGA_SPRITE = 50,
|
||||
HANGA_WATER = 51,
|
||||
DESERTD_WATER = 52,
|
||||
LMHCITYB_TFRAG = 53,
|
||||
TOWERB_WATER = 54,
|
||||
COMB_FIELD = 55,
|
||||
WASSTADA_ALPHA = 56,
|
||||
FACTORYB_WATER = 57,
|
||||
LMHCITYA_TFRAG = 58,
|
||||
MHCITYA_PRIS = 59,
|
||||
RUBBLEA_WATER = 60,
|
||||
RUBBLEA2_WATER = 61,
|
||||
RUBBLEB_WATER = 62,
|
||||
RUBBLEC_WATER = 63,
|
||||
FORESTA_WATER = 64,
|
||||
FORESTB_WATER = 65,
|
||||
LFORPLNT_PRIS = 66,
|
||||
LTNFXHIP = 67,
|
||||
LGUNNORM_WATER = 68,
|
||||
LJKDXVIN = 69,
|
||||
SECURITY = 70,
|
||||
WASPAL_WATER = 71,
|
||||
MINED_TFRAG = 72,
|
||||
VOLCANOX_WARP = 73,
|
||||
TEMPLEX_WATER = 74,
|
||||
VOLCANOA_WATER = 75,
|
||||
DESHOVER = 76,
|
||||
CLOUDS_AND_FOG = 77,
|
||||
CLOUDS_HIRES = 78,
|
||||
};
|
||||
|
||||
struct FixedAnimInfoJak3 {
|
||||
PcTextureAnimCodesJak3 code = (PcTextureAnimCodesJak3)0;
|
||||
std::string name;
|
||||
int anim_array_idx = -1;
|
||||
};
|
||||
|
||||
FixedAnimInfoJak3 anim_code_to_info(PcTextureAnimCodesJak3 code, const TextureAnimator& animator) {
|
||||
ASSERT(code > (PcTextureAnimCodesJak3)0);
|
||||
FixedAnimInfoJak3 anim;
|
||||
anim.code = code;
|
||||
switch (code) {
|
||||
case PcTextureAnimCodesJak3::SKULL_GEM: {
|
||||
anim.name = "skull-gem";
|
||||
anim.anim_array_idx = animator.m_skull_gem_fixed_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DEFAULT_WATER: {
|
||||
anim.name = "default-water";
|
||||
anim.anim_array_idx = animator.m_default_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DEFAULT_WARP: {
|
||||
anim.name = "default-warp";
|
||||
anim.anim_array_idx = animator.m_default_warp_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::TEMPLEA_WATER: {
|
||||
anim.name = "templea-water";
|
||||
anim.anim_array_idx = animator.m_templea_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::TEMPLEA_WARP: {
|
||||
anim.name = "templea-warp";
|
||||
anim.anim_array_idx = animator.m_templea_warp_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::TEMPLEB_WARP: {
|
||||
anim.name = "templeb-warp";
|
||||
anim.anim_array_idx = animator.m_templeb_warp_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::TEMPLEC_WATER: {
|
||||
anim.name = "templec-water";
|
||||
anim.anim_array_idx = animator.m_templec_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWC_WATER: {
|
||||
anim.name = "sewc-water";
|
||||
anim.anim_array_idx = animator.m_sewc_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWD_WATER: {
|
||||
anim.name = "sewd-water";
|
||||
anim.anim_array_idx = animator.m_sewd_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWE_WATER: {
|
||||
anim.name = "sewe-water";
|
||||
anim.anim_array_idx = animator.m_sewe_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWG_WATER: {
|
||||
anim.name = "sewg-water";
|
||||
anim.anim_array_idx = animator.m_sewg_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWH_WATER: {
|
||||
anim.name = "sewh-water";
|
||||
anim.anim_array_idx = animator.m_sewh_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWI_WATER: {
|
||||
anim.name = "sewi-water";
|
||||
anim.anim_array_idx = animator.m_sewi_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWJ_WATER: {
|
||||
anim.name = "sewj-water";
|
||||
anim.anim_array_idx = animator.m_sewj_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWL_WATER: {
|
||||
anim.name = "sewl-water";
|
||||
anim.anim_array_idx = animator.m_sewl_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWM_WATER: {
|
||||
anim.name = "sewm-water";
|
||||
anim.anim_array_idx = animator.m_sewm_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SEWN_WATER: {
|
||||
anim.name = "sewn-water";
|
||||
anim.anim_array_idx = animator.m_sewn_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DESRESC_WARP: {
|
||||
anim.name = "desresc-warp";
|
||||
anim.anim_array_idx = animator.m_desresc_warp_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::CTYSLUMB_WATER: {
|
||||
anim.name = "ctyslumb-water";
|
||||
anim.anim_array_idx = animator.m_ctyslumb_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::NSTB_QUICKSAND: {
|
||||
anim.name = "nstb-quicksand";
|
||||
anim.anim_array_idx = animator.m_nstb_quicksand_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::CTYSLUMC_WATER: {
|
||||
anim.name = "ctyslumc-water";
|
||||
anim.anim_array_idx = animator.m_ctyslumc_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::FACTORYC_ALPHA: {
|
||||
anim.name = "factoryc-alpha";
|
||||
anim.anim_array_idx = animator.m_factoryc_alpha_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::HFRAG: {
|
||||
anim.name = "hfrag";
|
||||
anim.anim_array_idx = animator.m_hfrag_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::HANGA_SPRITE: {
|
||||
anim.name = "hanga-sprite";
|
||||
anim.anim_array_idx = animator.m_hanga_sprite_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::HANGA_WATER: {
|
||||
anim.name = "hanga-water";
|
||||
anim.anim_array_idx = animator.m_hanga_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DESERTD_WATER: {
|
||||
anim.name = "desertd-water";
|
||||
anim.anim_array_idx = animator.m_desertd_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::LMHCITYB_TFRAG: {
|
||||
anim.name = "lmhcityb-tfrag";
|
||||
anim.anim_array_idx = animator.m_lmhcityb_tfrag_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::TOWERB_WATER: {
|
||||
anim.name = "towerb-water";
|
||||
anim.anim_array_idx = animator.m_towerb_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::COMB_FIELD: {
|
||||
anim.name = "comb-field";
|
||||
anim.anim_array_idx = animator.m_comb_field_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::WASSTADA_ALPHA: {
|
||||
anim.name = "wasstada-alpha";
|
||||
anim.anim_array_idx = animator.m_wasstada_alpha_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::FACTORYB_WATER: {
|
||||
anim.name = "factoryb-water";
|
||||
anim.anim_array_idx = animator.m_factoryb_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::LMHCITYA_TFRAG: {
|
||||
anim.name = "lmhcitya-tfrag";
|
||||
anim.anim_array_idx = animator.m_lmhcitya_tfrag_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::MHCITYA_PRIS: {
|
||||
anim.name = "mhcitya-pris";
|
||||
anim.anim_array_idx = animator.m_mhcitya_pris_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::RUBBLEA_WATER: {
|
||||
anim.name = "rubblea-water";
|
||||
anim.anim_array_idx = animator.m_rubblea_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::RUBBLEA2_WATER: {
|
||||
anim.name = "rubblea2-water";
|
||||
anim.anim_array_idx = animator.m_rubblea2_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::RUBBLEB_WATER: {
|
||||
anim.name = "rubbleb-water";
|
||||
anim.anim_array_idx = animator.m_rubbleb_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::RUBBLEC_WATER: {
|
||||
anim.name = "rubblec-water";
|
||||
anim.anim_array_idx = animator.m_rubblec_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::FORESTA_WATER: {
|
||||
anim.name = "foresta-water";
|
||||
anim.anim_array_idx = animator.m_foresta_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::FORESTB_WATER: {
|
||||
anim.name = "forestb-water";
|
||||
anim.anim_array_idx = animator.m_forestb_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::LFORPLNT_PRIS: {
|
||||
anim.name = "lforplnt-pris";
|
||||
anim.anim_array_idx = animator.m_lforplnt_pris_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::LTNFXHIP: {
|
||||
anim.name = "ltnfxhip";
|
||||
anim.anim_array_idx = animator.m_ltnfxhip_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::LGUNNORM_WATER: {
|
||||
anim.name = "lgunnorm-water";
|
||||
anim.anim_array_idx = animator.m_lgunnorm_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::LJKDXVIN: {
|
||||
anim.name = "ljkdxvin";
|
||||
anim.anim_array_idx = animator.m_ljkdxvin_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SECURITY: {
|
||||
anim.name = "security";
|
||||
anim.anim_array_idx = animator.m_security_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::WASPAL_WATER: {
|
||||
anim.name = "waspal-water";
|
||||
anim.anim_array_idx = animator.m_waspal_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::MINED_TFRAG: {
|
||||
anim.name = "mined-tfrag";
|
||||
anim.anim_array_idx = animator.m_mined_tfrag_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::VOLCANOX_WARP: {
|
||||
anim.name = "volcanox-warp";
|
||||
anim.anim_array_idx = animator.m_volcanox_warp_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::TEMPLEX_WATER: {
|
||||
anim.name = "templex-water";
|
||||
anim.anim_array_idx = animator.m_templex_water_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::VOLCANOA_WATER: {
|
||||
anim.name = "volcanoa-water";
|
||||
anim.anim_array_idx = animator.m_volcanoa_anim_array_idx;
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DESHOVER: {
|
||||
anim.name = "deshover";
|
||||
anim.anim_array_idx = animator.m_deshover_anim_array_idx;
|
||||
} break;
|
||||
default:
|
||||
anim.name = "unknown";
|
||||
lg::error("Unknown texture anim code {}", (int)code);
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
|
||||
// metadata for an upload from GOAL memory
|
||||
struct TextureAnimPcUpload {
|
||||
u32 data; // goal pointer
|
||||
@@ -1108,191 +726,117 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma,
|
||||
auto tf = dma.read_and_advance();
|
||||
auto vif0 = tf.vifcode0();
|
||||
if (vif0.kind == VifCode::Kind::PC_PORT) {
|
||||
switch (this->m_version) {
|
||||
case GameVersion::Jak2:
|
||||
switch (static_cast<PcTextureAnimCodesJak2>(vif0.immediate)) {
|
||||
case PcTextureAnimCodesJak2::UPLOAD_CLUT_16_16: {
|
||||
auto p = scoped_prof("clut-16-16");
|
||||
handle_upload_clut_16_16(tf, ee_mem);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::ERASE_DEST_TEXTURE: {
|
||||
auto p = scoped_prof("erase");
|
||||
handle_erase_dest(dma);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::GENERIC_UPLOAD: {
|
||||
auto p = scoped_prof("generic-upload");
|
||||
handle_generic_upload(tf, ee_mem);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::SET_SHADER: {
|
||||
auto p = scoped_prof("set-shader");
|
||||
handle_set_shader(dma);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::DRAW: {
|
||||
auto p = scoped_prof("draw");
|
||||
handle_draw(dma, *texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::FINISH_ARRAY:
|
||||
done = true;
|
||||
break;
|
||||
case PcTextureAnimCodesJak2::DARKJAK: {
|
||||
auto p = scoped_prof("darkjak");
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::PRISON_JAK: {
|
||||
auto p = scoped_prof("prisonjak");
|
||||
run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::ORACLE_JAK: {
|
||||
auto p = scoped_prof("oraclejak");
|
||||
run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::NEST_JAK: {
|
||||
auto p = scoped_prof("nestjak");
|
||||
run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::KOR_TRANSFORM: {
|
||||
auto p = scoped_prof("kor");
|
||||
run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::SKULL_GEM:
|
||||
case PcTextureAnimCodesJak2::BOMB:
|
||||
case PcTextureAnimCodesJak2::CAS_CONVEYOR:
|
||||
case PcTextureAnimCodesJak2::SECURITY:
|
||||
case PcTextureAnimCodesJak2::WATERFALL:
|
||||
case PcTextureAnimCodesJak2::WATERFALL_B:
|
||||
case PcTextureAnimCodesJak2::LAVA:
|
||||
case PcTextureAnimCodesJak2::LAVA_B:
|
||||
case PcTextureAnimCodesJak2::STADIUMB:
|
||||
case PcTextureAnimCodesJak2::FORTRESS_PRIS:
|
||||
case PcTextureAnimCodesJak2::FORTRESS_WARP:
|
||||
case PcTextureAnimCodesJak2::METKOR:
|
||||
case PcTextureAnimCodesJak2::SHIELD:
|
||||
case PcTextureAnimCodesJak2::KREW_HOLO: {
|
||||
auto anim =
|
||||
anim_code_to_info(static_cast<PcTextureAnimCodesJak2>(vif0.immediate), *this);
|
||||
auto p = scoped_prof(anim.name.c_str());
|
||||
run_fixed_animation_array(anim.anim_array_idx, tf, texture_pool);
|
||||
break;
|
||||
}
|
||||
case PcTextureAnimCodesJak2::CLOUDS_AND_FOG:
|
||||
case PcTextureAnimCodesJak2::CLOUDS_HIRES: {
|
||||
auto p = scoped_prof("clouds-and-fog");
|
||||
handle_clouds_and_fog(tf, texture_pool,
|
||||
vif0.immediate == (u16)PcTextureAnimCodesJak2::CLOUDS_HIRES);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::SLIME: {
|
||||
auto p = scoped_prof("slime");
|
||||
handle_slime(tf, texture_pool);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lg::print("bad imm: {}\n", vif0.immediate);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
case GameVersion::Jak3:
|
||||
switch (static_cast<PcTextureAnimCodesJak3>(vif0.immediate)) {
|
||||
case PcTextureAnimCodesJak3::UPLOAD_CLUT_16_16: {
|
||||
auto p = scoped_prof("clut-16-16");
|
||||
handle_upload_clut_16_16(tf, ee_mem);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::ERASE_DEST_TEXTURE: {
|
||||
auto p = scoped_prof("erase");
|
||||
handle_erase_dest(dma);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::GENERIC_UPLOAD: {
|
||||
auto p = scoped_prof("generic-upload");
|
||||
handle_generic_upload(tf, ee_mem);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SET_SHADER: {
|
||||
auto p = scoped_prof("set-shader");
|
||||
handle_set_shader(dma);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DRAW: {
|
||||
auto p = scoped_prof("draw");
|
||||
handle_draw(dma, *texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::FINISH_ARRAY:
|
||||
done = true;
|
||||
break;
|
||||
case PcTextureAnimCodesJak3::DARKJAK: {
|
||||
auto p = scoped_prof("darkjak");
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DARKJAK_HIGHRES: {
|
||||
auto p = scoped_prof("darkjak-highres");
|
||||
run_clut_blender_group(tf, m_darkjak_highres_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SKULL_GEM:
|
||||
case PcTextureAnimCodesJak3::DEFAULT_WATER:
|
||||
case PcTextureAnimCodesJak3::DEFAULT_WARP:
|
||||
case PcTextureAnimCodesJak3::TEMPLEA_WATER:
|
||||
case PcTextureAnimCodesJak3::TEMPLEA_WARP:
|
||||
case PcTextureAnimCodesJak3::TEMPLEB_WARP:
|
||||
case PcTextureAnimCodesJak3::TEMPLEC_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWC_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWD_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWE_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWG_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWH_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWI_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWJ_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWL_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWM_WATER:
|
||||
case PcTextureAnimCodesJak3::SEWN_WATER:
|
||||
case PcTextureAnimCodesJak3::DESRESC_WARP:
|
||||
case PcTextureAnimCodesJak3::CTYSLUMB_WATER:
|
||||
case PcTextureAnimCodesJak3::NSTB_QUICKSAND:
|
||||
case PcTextureAnimCodesJak3::CTYSLUMC_WATER:
|
||||
case PcTextureAnimCodesJak3::FACTORYC_ALPHA:
|
||||
case PcTextureAnimCodesJak3::HFRAG:
|
||||
case PcTextureAnimCodesJak3::HANGA_SPRITE:
|
||||
case PcTextureAnimCodesJak3::HANGA_WATER:
|
||||
case PcTextureAnimCodesJak3::DESERTD_WATER:
|
||||
case PcTextureAnimCodesJak3::LMHCITYB_TFRAG:
|
||||
case PcTextureAnimCodesJak3::TOWERB_WATER:
|
||||
case PcTextureAnimCodesJak3::COMB_FIELD:
|
||||
case PcTextureAnimCodesJak3::WASSTADA_ALPHA:
|
||||
case PcTextureAnimCodesJak3::FACTORYB_WATER:
|
||||
case PcTextureAnimCodesJak3::LMHCITYA_TFRAG:
|
||||
case PcTextureAnimCodesJak3::MHCITYA_PRIS:
|
||||
case PcTextureAnimCodesJak3::RUBBLEA_WATER:
|
||||
case PcTextureAnimCodesJak3::RUBBLEA2_WATER:
|
||||
case PcTextureAnimCodesJak3::RUBBLEB_WATER:
|
||||
case PcTextureAnimCodesJak3::RUBBLEC_WATER:
|
||||
case PcTextureAnimCodesJak3::FORESTA_WATER:
|
||||
case PcTextureAnimCodesJak3::FORESTB_WATER:
|
||||
case PcTextureAnimCodesJak3::LFORPLNT_PRIS:
|
||||
case PcTextureAnimCodesJak3::LTNFXHIP:
|
||||
case PcTextureAnimCodesJak3::LGUNNORM_WATER:
|
||||
case PcTextureAnimCodesJak3::LJKDXVIN:
|
||||
case PcTextureAnimCodesJak3::SECURITY:
|
||||
case PcTextureAnimCodesJak3::WASPAL_WATER:
|
||||
case PcTextureAnimCodesJak3::MINED_TFRAG:
|
||||
case PcTextureAnimCodesJak3::VOLCANOX_WARP:
|
||||
case PcTextureAnimCodesJak3::TEMPLEX_WATER:
|
||||
case PcTextureAnimCodesJak3::VOLCANOA_WATER:
|
||||
case PcTextureAnimCodesJak3::DESHOVER: {
|
||||
auto anim =
|
||||
anim_code_to_info(static_cast<PcTextureAnimCodesJak3>(vif0.immediate), *this);
|
||||
auto p = scoped_prof(anim.name.c_str());
|
||||
run_fixed_animation_array(anim.anim_array_idx, tf, texture_pool);
|
||||
break;
|
||||
}
|
||||
case PcTextureAnimCodesJak3::CLOUDS_AND_FOG:
|
||||
case PcTextureAnimCodesJak3::CLOUDS_HIRES: {
|
||||
auto p = scoped_prof("clouds-and-fog");
|
||||
handle_clouds_and_fog(tf, texture_pool,
|
||||
vif0.immediate == (u16)PcTextureAnimCodesJak3::CLOUDS_HIRES);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lg::print("bad imm: {}\n", vif0.immediate);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
switch (vif0.immediate) {
|
||||
case UPLOAD_CLUT_16_16: {
|
||||
auto p = scoped_prof("clut-16-16");
|
||||
handle_upload_clut_16_16(tf, ee_mem);
|
||||
} break;
|
||||
case ERASE_DEST_TEXTURE: {
|
||||
auto p = scoped_prof("erase");
|
||||
handle_erase_dest(dma);
|
||||
} break;
|
||||
case GENERIC_UPLOAD: {
|
||||
auto p = scoped_prof("generic-upload");
|
||||
handle_generic_upload(tf, ee_mem);
|
||||
} break;
|
||||
case SET_SHADER: {
|
||||
auto p = scoped_prof("set-shader");
|
||||
handle_set_shader(dma);
|
||||
} break;
|
||||
case DRAW: {
|
||||
auto p = scoped_prof("draw");
|
||||
handle_draw(dma, *texture_pool);
|
||||
} break;
|
||||
case FINISH_ARRAY:
|
||||
done = true;
|
||||
break;
|
||||
case DARKJAK: {
|
||||
auto p = scoped_prof("darkjak");
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PRISON_JAK: {
|
||||
auto p = scoped_prof("prisonjak");
|
||||
run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case ORACLE_JAK: {
|
||||
auto p = scoped_prof("oraclejak");
|
||||
run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case NEST_JAK: {
|
||||
auto p = scoped_prof("nestjak");
|
||||
run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case KOR_TRANSFORM: {
|
||||
auto p = scoped_prof("kor");
|
||||
run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case SKULL_GEM: {
|
||||
auto p = scoped_prof("skull-gem");
|
||||
run_fixed_animation_array(m_skull_gem_fixed_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case BOMB: {
|
||||
auto p = scoped_prof("bomb");
|
||||
run_fixed_animation_array(m_bomb_fixed_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case CAS_CONVEYOR: {
|
||||
auto p = scoped_prof("cas-conveyor");
|
||||
run_fixed_animation_array(m_cas_conveyor_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case SECURITY: {
|
||||
auto p = scoped_prof("security");
|
||||
run_fixed_animation_array(m_security_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case WATERFALL: {
|
||||
auto p = scoped_prof("waterfall");
|
||||
run_fixed_animation_array(m_waterfall_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case WATERFALL_B: {
|
||||
auto p = scoped_prof("waterfall-b");
|
||||
run_fixed_animation_array(m_waterfall_b_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case LAVA: {
|
||||
auto p = scoped_prof("lava");
|
||||
run_fixed_animation_array(m_lava_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case LAVA_B: {
|
||||
auto p = scoped_prof("lava-b");
|
||||
run_fixed_animation_array(m_lava_b_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case STADIUMB: {
|
||||
auto p = scoped_prof("stadiumb");
|
||||
run_fixed_animation_array(m_stadiumb_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case FORTRESS_PRIS: {
|
||||
auto p = scoped_prof("fort-pris");
|
||||
run_fixed_animation_array(m_fortress_pris_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case FORTRESS_WARP: {
|
||||
auto p = scoped_prof("fort-warp");
|
||||
run_fixed_animation_array(m_fortress_warp_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case METKOR: {
|
||||
auto p = scoped_prof("metkor");
|
||||
run_fixed_animation_array(m_metkor_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case SHIELD: {
|
||||
auto p = scoped_prof("shield");
|
||||
run_fixed_animation_array(m_shield_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case KREW_HOLO: {
|
||||
auto p = scoped_prof("krew-holo");
|
||||
run_fixed_animation_array(m_krew_holo_anim_array_idx, tf, texture_pool);
|
||||
} break;
|
||||
case CLOUDS_AND_FOG:
|
||||
case CLOUDS_HIRES: {
|
||||
auto p = scoped_prof("clouds-and-fog");
|
||||
handle_clouds_and_fog(tf, texture_pool, vif0.immediate == CLOUDS_HIRES);
|
||||
} break;
|
||||
case SLIME: {
|
||||
auto p = scoped_prof("slime");
|
||||
handle_slime(tf, texture_pool);
|
||||
} break;
|
||||
default:
|
||||
lg::print("unsupported game version {}\n", (int)this->m_version);
|
||||
lg::print("bad imm: {}\n", vif0.immediate);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
} else {
|
||||
@@ -2274,21 +1818,6 @@ void TextureAnimator::set_up_opengl_for_fixed(const FixedLayerDef& def,
|
||||
blend_c == GsAlpha::BlendMode::SOURCE && blend_d == GsAlpha::BlendMode::DEST) {
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
} else if (blend_a == GsAlpha::BlendMode::SOURCE &&
|
||||
blend_b == GsAlpha::BlendMode::ZERO_OR_FIXED &&
|
||||
blend_c == GsAlpha::BlendMode::ZERO_OR_FIXED &&
|
||||
blend_d == GsAlpha::BlendMode::ZERO_OR_FIXED && def.blend_fix == 128) {
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
} else if (blend_a == GsAlpha::BlendMode::SOURCE &&
|
||||
blend_b == GsAlpha::BlendMode::ZERO_OR_FIXED &&
|
||||
blend_c == GsAlpha::BlendMode::ZERO_OR_FIXED &&
|
||||
blend_d == GsAlpha::BlendMode::DEST) {
|
||||
// 0, 2, 2, 1
|
||||
// (Cs - 0) * FIX / 128 + Cd
|
||||
// So source is fix / 128, and dest is 1
|
||||
float color = (float)def.blend_fix / 128.f;
|
||||
glBlendColor(color, color, color, color);
|
||||
glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE, GL_ONE, GL_ZERO);
|
||||
} else {
|
||||
lg::print("unhandled blend: {} {} {} {}\n", (int)blend_a, (int)blend_b, (int)blend_c,
|
||||
(int)blend_d);
|
||||
@@ -2429,23 +1958,14 @@ void TextureAnimator::set_draw_data_from_interpolated(DrawData* result,
|
||||
const LayerVals& vals,
|
||||
int w,
|
||||
int h) {
|
||||
ASSERT(vals.rot == 0);
|
||||
result->color = (vals.color * 128.f).cast<u32>();
|
||||
math::Vector2f pos_scale(vals.scale.x() * w, vals.scale.y() * h);
|
||||
math::Vector2f pos_offset(2048.f + (vals.offset.x() * w), 2048.f + (vals.offset.y() * h));
|
||||
math::Vector2f st_scale = vals.st_scale;
|
||||
math::Vector2f st_offset = vals.st_offset;
|
||||
math::Vector2f corners[4] = {math::Vector2f{-0.5, -0.5}, math::Vector2f{0.5, -0.5},
|
||||
math::Vector2f{-0.5, 0.5}, math::Vector2f{0.5, 0.5}};
|
||||
if (vals.rot) {
|
||||
const float rotation_radians = 2.f * M_PI * vals.rot / 65536.f;
|
||||
const float sine = std::sin(rotation_radians);
|
||||
const float cosine = std::cos(rotation_radians);
|
||||
math::Vector2f vx(sine, cosine);
|
||||
math::Vector2f vy(cosine, -sine);
|
||||
for (auto& corner : corners) {
|
||||
corner = vx * corner.x() + vy * corner.y();
|
||||
}
|
||||
}
|
||||
const math::Vector2f corners[4] = {math::Vector2f{-0.5, -0.5}, math::Vector2f{0.5, -0.5},
|
||||
math::Vector2f{-0.5, 0.5}, math::Vector2f{0.5, 0.5}};
|
||||
math::Vector2f sts[4];
|
||||
math::Vector2<u32> poss[4];
|
||||
|
||||
@@ -2536,14 +2056,8 @@ void TextureAnimator::run_fixed_animation(FixedAnim& anim, float time) {
|
||||
if (true) { // todo
|
||||
glColorMask(true, true, true, false);
|
||||
glUniform1f(m_uniforms.alpha_multiply, 2.f);
|
||||
glUniform1i(m_uniforms.set_alpha, 0);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glColorMask(false, false, false, true);
|
||||
if (anim.def.set_alpha) {
|
||||
glUniform1i(m_uniforms.set_alpha, 1);
|
||||
glUniform4f(m_uniforms.rgba, draw_data.color.x(), draw_data.color.x(),
|
||||
draw_data.color.x(), 128.f);
|
||||
}
|
||||
glUniform1f(m_uniforms.alpha_multiply, 1.f);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
} else {
|
||||
|
||||
@@ -59,7 +59,7 @@ struct ShaderContext {
|
||||
};
|
||||
|
||||
struct OpenGLTexturePool {
|
||||
OpenGLTexturePool(GameVersion version);
|
||||
OpenGLTexturePool();
|
||||
~OpenGLTexturePool();
|
||||
GLuint allocate(u64 w, u64 h);
|
||||
void free(GLuint texture, u64 w, u64 h);
|
||||
@@ -148,18 +148,6 @@ struct FixedLayerDef {
|
||||
GsAlpha::BlendMode blend_modes[4]; // abcd
|
||||
u8 blend_fix = 0;
|
||||
|
||||
void set_blend(GsAlpha::BlendMode a,
|
||||
GsAlpha::BlendMode b,
|
||||
GsAlpha::BlendMode c,
|
||||
GsAlpha::BlendMode d,
|
||||
u8 fix) {
|
||||
blend_modes[0] = a;
|
||||
blend_modes[1] = b;
|
||||
blend_modes[2] = c;
|
||||
blend_modes[3] = d;
|
||||
blend_fix = fix;
|
||||
}
|
||||
|
||||
void set_blend_b2_d1() {
|
||||
blend_modes[0] = GsAlpha::BlendMode::SOURCE;
|
||||
blend_modes[1] = GsAlpha::BlendMode::ZERO_OR_FIXED;
|
||||
@@ -193,15 +181,6 @@ struct FixedAnimDef {
|
||||
// alpha blend off, so alpha doesn't matter i think.
|
||||
std::vector<FixedLayerDef> layers;
|
||||
bool move_to_pool = false;
|
||||
bool set_alpha = false;
|
||||
void set_times(std::vector<std::pair<float, float>> times) {
|
||||
ASSERT(layers.size() >= times.size());
|
||||
for (size_t i = 0; i < layers.size(); i++) {
|
||||
auto& layer = layers.at(i);
|
||||
layer.start_time = times.at(i).first;
|
||||
layer.end_time = times.at(i).second;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct DynamicLayerData {
|
||||
@@ -364,7 +343,6 @@ class TextureAnimator {
|
||||
GLuint tcc;
|
||||
GLuint alpha_multiply;
|
||||
GLuint minimum, maximum;
|
||||
GLuint set_alpha;
|
||||
} m_uniforms;
|
||||
|
||||
struct {
|
||||
@@ -418,8 +396,6 @@ class TextureAnimator {
|
||||
m_psm32_to_psm8_64_64;
|
||||
ClutReader m_clut_table;
|
||||
|
||||
public:
|
||||
// jak 2
|
||||
int m_skull_gem_fixed_anim_array_idx = -1;
|
||||
int m_bomb_fixed_anim_array_idx = -1;
|
||||
int m_cas_conveyor_anim_array_idx = -1;
|
||||
@@ -435,59 +411,9 @@ class TextureAnimator {
|
||||
int m_shield_anim_array_idx = -1;
|
||||
int m_krew_holo_anim_array_idx = -1;
|
||||
|
||||
// jak 3
|
||||
int m_default_water_anim_array_idx = -1;
|
||||
int m_default_warp_anim_array_idx = -1;
|
||||
int m_templea_water_anim_array_idx = -1;
|
||||
int m_templea_warp_anim_array_idx = -1;
|
||||
int m_templeb_warp_anim_array_idx = -1;
|
||||
int m_templec_water_anim_array_idx = -1;
|
||||
int m_sewc_water_anim_array_idx = -1;
|
||||
int m_sewd_water_anim_array_idx = -1;
|
||||
int m_sewe_water_anim_array_idx = -1;
|
||||
int m_sewg_water_anim_array_idx = -1;
|
||||
int m_sewh_water_anim_array_idx = -1;
|
||||
int m_sewi_water_anim_array_idx = -1;
|
||||
int m_sewj_water_anim_array_idx = -1;
|
||||
int m_sewl_water_anim_array_idx = -1;
|
||||
int m_sewm_water_anim_array_idx = -1;
|
||||
int m_sewn_water_anim_array_idx = -1;
|
||||
int m_desresc_warp_anim_array_idx = -1;
|
||||
int m_ctyslumb_water_anim_array_idx = -1;
|
||||
int m_nstb_quicksand_anim_array_idx = -1;
|
||||
int m_ctyslumc_water_anim_array_idx = -1;
|
||||
int m_factoryc_alpha_anim_array_idx = -1;
|
||||
int m_hfrag_anim_array_idx = -1;
|
||||
int m_hanga_sprite_anim_array_idx = -1;
|
||||
int m_hanga_water_anim_array_idx = -1;
|
||||
int m_desertd_water_anim_array_idx = -1;
|
||||
int m_lmhcityb_tfrag_anim_array_idx = -1;
|
||||
int m_towerb_water_anim_array_idx = -1;
|
||||
int m_comb_field_anim_array_idx = -1;
|
||||
int m_wasstada_alpha_anim_array_idx = -1;
|
||||
int m_factoryb_water_anim_array_idx = -1;
|
||||
int m_lmhcitya_tfrag_anim_array_idx = -1;
|
||||
int m_mhcitya_pris_anim_array_idx = -1;
|
||||
int m_rubblea_water_anim_array_idx = -1;
|
||||
int m_rubblea2_water_anim_array_idx = -1;
|
||||
int m_rubbleb_water_anim_array_idx = -1;
|
||||
int m_rubblec_water_anim_array_idx = -1;
|
||||
int m_foresta_water_anim_array_idx = -1;
|
||||
int m_forestb_water_anim_array_idx = -1;
|
||||
int m_lforplnt_pris_anim_array_idx = -1;
|
||||
int m_ltnfxhip_anim_array_idx = -1;
|
||||
int m_lgunnorm_water_anim_array_idx = -1;
|
||||
int m_ljkdxvin_anim_array_idx = -1;
|
||||
int m_waspal_water_anim_array_idx = -1;
|
||||
int m_mined_tfrag_anim_array_idx = -1;
|
||||
int m_volcanox_warp_anim_array_idx = -1;
|
||||
int m_templex_water_anim_array_idx = -1;
|
||||
int m_volcanoa_anim_array_idx = -1;
|
||||
int m_deshover_anim_array_idx = -1;
|
||||
int m_darkjak_highres_clut_blender_idx = -1;
|
||||
|
||||
std::vector<FixedAnimArray> m_fixed_anim_arrays;
|
||||
|
||||
public:
|
||||
// note: for now these can't be easily changed because each layer has its own hand-tuned
|
||||
// parameters from the original game. If you want to change it, you'll need to make up parameters
|
||||
// for those new layers.
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -119,7 +119,3 @@ void TextureUploadHandler::draw_debug_window() {
|
||||
m_direct->draw_debug_window();
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureUploadHandler::empty() const {
|
||||
return m_upload_count == 0;
|
||||
}
|
||||
@@ -18,7 +18,6 @@ class TextureUploadHandler : public BucketRenderer {
|
||||
bool add_direct = false);
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
void draw_debug_window() override;
|
||||
bool empty() const override;
|
||||
|
||||
private:
|
||||
struct TextureUpload {
|
||||
|
||||
@@ -129,8 +129,8 @@ Hfrag::HfragLevel* Hfrag::get_hfrag_level(const std::string& name,
|
||||
// first, see if this level is loaded. If not, there's nothing we can do.
|
||||
auto lev_data = render_state->loader->get_tfrag3_level(name);
|
||||
if (!lev_data) {
|
||||
// printf("[hfrag] can't display %s because it's not loaded.\n", name.c_str());
|
||||
// render_state->loader->debug_print_loaded_levels();
|
||||
printf("[hfrag] can't display %s because it's not loaded.\n", name.c_str());
|
||||
render_state->loader->debug_print_loaded_levels();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
#include "debug_gui.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/global_profiler/GlobalProfiler.h"
|
||||
#include "common/util/string_util.h"
|
||||
|
||||
#include "game/graphics/display.h"
|
||||
#include "game/graphics/gfx.h"
|
||||
@@ -162,27 +164,10 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Event Profiler")) {
|
||||
if (ImGui::Checkbox("Record Events", &record_events)) {
|
||||
if (ImGui::Checkbox("Record", &record_events)) {
|
||||
prof().set_enable(record_events);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(fmt::format("({}/{})", prof().get_next_idx(), prof().get_max_events()).c_str());
|
||||
ImGui::InputInt("Event Buffer Size", &max_event_buffer_size);
|
||||
if (ImGui::Button("Resize")) {
|
||||
prof().update_event_buffer_size(max_event_buffer_size);
|
||||
}
|
||||
if (ImGui::Button("Reset Events")) {
|
||||
prof().clear();
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox("Enable Compression", &prof().m_enable_compression);
|
||||
if (ImGui::Button("Dump to File")) {
|
||||
record_events = false;
|
||||
prof().dump_to_json();
|
||||
}
|
||||
// if (ImGui::Button("Open dump folder")) {
|
||||
// // TODO - https://github.com/mlabbe/nativefiledialog
|
||||
// }
|
||||
ImGui::MenuItem("Dump to file", nullptr, &dump_events);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class OpenGlDebugGui {
|
||||
|
||||
bool small_profiler = false;
|
||||
bool record_events = false;
|
||||
int max_event_buffer_size = 65536;
|
||||
bool dump_events = false;
|
||||
bool want_reboot_in_debug = false;
|
||||
|
||||
bool screenshot_hotkey_enabled = true;
|
||||
|
||||
@@ -70,16 +70,11 @@ void Generic2::render_in_mode(DmaFollower& dma,
|
||||
case Mode::LIGHTNING:
|
||||
process_dma_lightning(dma, render_state->next_bucket);
|
||||
break;
|
||||
case Mode::PRIM:
|
||||
process_dma_prim(dma, render_state->next_bucket);
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
m_empty = m_next_free_vert == 0;
|
||||
|
||||
{
|
||||
// the next pass is to look at all of that data, and figure out the best order to draw it
|
||||
// using OpenGL
|
||||
@@ -89,7 +84,6 @@ void Generic2::render_in_mode(DmaFollower& dma,
|
||||
setup_draws(true, true);
|
||||
break;
|
||||
case Mode::LIGHTNING:
|
||||
case Mode::PRIM:
|
||||
setup_draws(false, true);
|
||||
break;
|
||||
case Mode::WARP:
|
||||
|
||||
@@ -11,7 +11,7 @@ class Generic2 {
|
||||
u32 num_buckets = 800);
|
||||
~Generic2();
|
||||
|
||||
enum class Mode { NORMAL, LIGHTNING, WARP, PRIM };
|
||||
enum class Mode { NORMAL, LIGHTNING, WARP };
|
||||
|
||||
void render_in_mode(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
@@ -19,7 +19,6 @@ class Generic2 {
|
||||
Mode mode);
|
||||
|
||||
void draw_debug_window();
|
||||
bool empty() { return m_empty; }
|
||||
|
||||
struct Vertex {
|
||||
math::Vector<float, 3> xyz;
|
||||
@@ -43,7 +42,6 @@ class Generic2 {
|
||||
void process_dma_jak1(DmaFollower& dma, u32 next_bucket);
|
||||
void process_dma_lightning(DmaFollower& dma, u32 next_bucket);
|
||||
void process_dma_jak2(DmaFollower& dma, u32 next_bucket);
|
||||
void process_dma_prim(DmaFollower& dma, u32 next_bucket);
|
||||
void setup_draws(bool enable_at, bool default_fog);
|
||||
void do_draws(SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void do_draws_for_alpha(SharedRenderState* render_state,
|
||||
@@ -86,8 +84,6 @@ class Generic2 {
|
||||
float hud_mat_23, hud_mat_32, hud_mat_33;
|
||||
|
||||
bool uses_hud = false;
|
||||
bool uses_full_matrix = false;
|
||||
math::Vector4f full_matrix[4];
|
||||
} m_drawing_config;
|
||||
|
||||
struct GsState {
|
||||
@@ -202,10 +198,8 @@ class Generic2 {
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
GLuint alpha_reject, color_mult, fog_color, scale, mat_23, mat_32, mat_33, fog_consts,
|
||||
hvdf_offset, use_full_matrix, full_matrix;
|
||||
hvdf_offset;
|
||||
GLuint gfx_hack_no_tex;
|
||||
GLuint warp_sample_mode;
|
||||
} m_ogl;
|
||||
|
||||
bool m_empty = false;
|
||||
};
|
||||
@@ -22,9 +22,4 @@ void Generic2BucketRenderer::render(DmaFollower& dma,
|
||||
return;
|
||||
}
|
||||
m_generic->render_in_mode(dma, render_state, prof, m_mode);
|
||||
m_empty = m_generic->empty();
|
||||
}
|
||||
|
||||
bool Generic2BucketRenderer::empty() const {
|
||||
return m_empty;
|
||||
}
|
||||
@@ -11,10 +11,8 @@ class Generic2BucketRenderer : public BucketRenderer {
|
||||
Generic2::Mode mode);
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
void draw_debug_window() override;
|
||||
bool empty() const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Generic2> m_generic;
|
||||
Generic2::Mode m_mode;
|
||||
bool m_empty = false;
|
||||
};
|
||||
@@ -190,16 +190,6 @@ void Generic2::determine_draw_modes(bool enable_at, bool default_fog) {
|
||||
current_mode.set_alpha_fail(reg.afail());
|
||||
current_mode.set_zt(reg.zte());
|
||||
current_mode.set_depth_test(reg.ztest());
|
||||
|
||||
// detect a strange way of disabling z writes by light-trail.
|
||||
// we don't actually handle alpha_fail later on in Direct - it doesn't map well to modern
|
||||
// graphics and would require a draw call per primitive.
|
||||
if (current_mode.get_alpha_fail() == GsTest::AlphaFail::FB_ONLY &&
|
||||
current_mode.get_aref() == 0x80 &&
|
||||
current_mode.get_alpha_test() == DrawMode::AlphaTest::GEQUAL) {
|
||||
current_mode.set_alpha_test(DrawMode::AlphaTest::ALWAYS);
|
||||
current_mode.disable_depth_write();
|
||||
}
|
||||
}
|
||||
|
||||
m_adgifs[i].mode = current_mode;
|
||||
@@ -281,10 +271,6 @@ void Generic2::process_matrices() {
|
||||
bool found_proj_matrix = false;
|
||||
std::array<math::Vector4f, 4> projection_matrix, hud_matrix;
|
||||
for (u32 i = 0; i < m_next_free_frag; i++) {
|
||||
if (m_drawing_config.uses_full_matrix) {
|
||||
memcpy(&m_drawing_config.full_matrix, m_fragments[i].header, 64);
|
||||
break;
|
||||
}
|
||||
float mat_33;
|
||||
memcpy(&mat_33, m_fragments[i].header + 15 * sizeof(float), sizeof(float));
|
||||
if (mat_33 == 0) {
|
||||
|
||||
@@ -550,83 +550,6 @@ void unpack_vertex(Generic2::Vertex* out, const u8* in, int count) {
|
||||
}
|
||||
}
|
||||
|
||||
void Generic2::process_dma_prim(DmaFollower& dma, u32 next_bucket) {
|
||||
reset_buffers();
|
||||
auto first_data = dma.read_and_advance();
|
||||
|
||||
// handle the stuff at the beginning.
|
||||
// if the engine didn't run the generic renderer setup function, this bucket will end here.
|
||||
if (is_nop_zero(first_data) && next_bucket == dma.current_tag_offset()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MARK NOP (for profiling)
|
||||
auto v0k = first_data.vifcode0().kind;
|
||||
ASSERT((v0k == VifCode::Kind::MARK || v0k == VifCode::Kind::NOP) &&
|
||||
first_data.vifcode1().kind == VifCode::Kind::NOP);
|
||||
|
||||
// NOP DIRECT (set up GS, from generic setup)
|
||||
auto direct_setup = dma.read_and_advance();
|
||||
ASSERT(direct_setup.size_bytes == 32 && direct_setup.vifcode0().kind == VifCode::Kind::NOP &&
|
||||
direct_setup.vifcode1().kind == VifCode::Kind::DIRECT);
|
||||
m_drawing_config.zmsk = false;
|
||||
m_drawing_config.uses_full_matrix = true;
|
||||
|
||||
// STYCYCL to set up generic VU1 constants
|
||||
auto constants = dma.read_and_advance();
|
||||
ASSERT(constants.size_bytes == 128);
|
||||
ASSERT(constants.vifcode0().kind == VifCode::Kind::STCYCL);
|
||||
ASSERT(constants.vifcode1().kind == VifCode::Kind::UNPACK_V4_32);
|
||||
memcpy(&m_drawing_config.pfog0, constants.data + 0, 4);
|
||||
memcpy(&m_drawing_config.fog_min, constants.data + 4, 4);
|
||||
memcpy(&m_drawing_config.fog_max, constants.data + 8, 4);
|
||||
memcpy(m_drawing_config.hvdf_offset.data(), constants.data + 32, 16);
|
||||
|
||||
// 32: MSCALF 0x0 STMOD 0b0 init generic VU1
|
||||
auto mscalf = dma.read_and_advance();
|
||||
ASSERT(mscalf.vifcode0().kind == VifCode::Kind::MSCALF &&
|
||||
mscalf.vifcode1().kind == VifCode::Kind::STMOD);
|
||||
|
||||
// 0: NOP NOP
|
||||
// auto another_nop = dma.read_and_advance();
|
||||
// ASSERT(is_nop_zero(another_nop));
|
||||
|
||||
while (dma.current_tag_offset() != next_bucket) {
|
||||
auto up1 = dma.read_and_advance();
|
||||
while (up1.vifcode0().kind == VifCode::Kind::NOP && up1.vifcode1().kind == VifCode::Kind::NOP) {
|
||||
up1 = dma.read_and_advance();
|
||||
}
|
||||
if (up1.vifcode0().kind == VifCode::Kind::FLUSHA) {
|
||||
while (dma.current_tag_offset() != next_bucket) {
|
||||
auto it = dma.read_and_advance();
|
||||
}
|
||||
break;
|
||||
}
|
||||
auto up2 = dma.read_and_advance();
|
||||
auto call = dma.read_and_advance();
|
||||
|
||||
// up1 is a 12 qw upload for control:
|
||||
// up2 is vertex upload.
|
||||
|
||||
auto* frag = &next_frag();
|
||||
ASSERT(up1.size_bytes == Generic2::FRAG_HEADER_SIZE + 5 * 16); // header + adgif
|
||||
memcpy(frag->header, up1.data, Generic2::FRAG_HEADER_SIZE);
|
||||
frag->adgif_idx = m_next_free_adgif;
|
||||
frag->adgif_count = 1;
|
||||
frag->mscal_addr = 6;
|
||||
frag->uses_hud = false;
|
||||
auto* adgif = &next_adgif();
|
||||
memcpy(&adgif->data, up1.data + Generic2::FRAG_HEADER_SIZE, sizeof(AdGifData));
|
||||
// (new 'static 'gif-tag-regs-32 :regs0 (gif-reg-id st) :regs1 (gif-reg-id rgbaq) :regs2
|
||||
// (gif-reg-id xyzf2))
|
||||
int num_vtx = up2.size_bytes / (16 * 3);
|
||||
frag->vtx_count = num_vtx;
|
||||
frag->vtx_idx = m_next_free_vert;
|
||||
alloc_vtx(num_vtx);
|
||||
unpack_vertex(&m_verts[frag->vtx_idx], up2.data, num_vtx);
|
||||
}
|
||||
}
|
||||
|
||||
void Generic2::process_dma_lightning(DmaFollower& dma, u32 next_bucket) {
|
||||
reset_buffers();
|
||||
auto first_data = dma.read_and_advance();
|
||||
|
||||
@@ -74,8 +74,6 @@ void Generic2::opengl_setup(ShaderLibrary& shaders) {
|
||||
m_ogl.hvdf_offset = glGetUniformLocation(id, "hvdf_offset");
|
||||
m_ogl.gfx_hack_no_tex = glGetUniformLocation(id, "gfx_hack_no_tex");
|
||||
m_ogl.warp_sample_mode = glGetUniformLocation(id, "warp_sample_mode");
|
||||
m_ogl.use_full_matrix = glGetUniformLocation(id, "use_full_matrix");
|
||||
m_ogl.full_matrix = glGetUniformLocation(id, "full_matrix");
|
||||
}
|
||||
|
||||
void Generic2::opengl_cleanup() {
|
||||
@@ -309,12 +307,6 @@ void Generic2::do_draws(SharedRenderState* render_state, ScopedProfilerNode& pro
|
||||
glPrimitiveRestartIndex(UINT32_MAX);
|
||||
|
||||
opengl_bind_and_setup_proj(render_state);
|
||||
if (m_drawing_config.uses_full_matrix) {
|
||||
glUniform1i(m_ogl.use_full_matrix, 1);
|
||||
glUniformMatrix4fv(m_ogl.full_matrix, 1, GL_FALSE, m_drawing_config.full_matrix[0].data());
|
||||
} else {
|
||||
glUniform1i(m_ogl.use_full_matrix, 0);
|
||||
}
|
||||
constexpr DrawMode::AlphaBlend alpha_order[ALPHA_MODE_COUNT] = {
|
||||
DrawMode::AlphaBlend::SRC_0_FIX_DST, DrawMode::AlphaBlend::SRC_SRC_SRC_SRC,
|
||||
DrawMode::AlphaBlend::SRC_DST_SRC_DST, DrawMode::AlphaBlend::SRC_0_SRC_DST,
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#endif
|
||||
|
||||
#include "common/global_profiler/GlobalProfiler.h"
|
||||
#include "common/util/fnv.h"
|
||||
|
||||
#include "game/graphics/opengl_renderer/EyeRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/background/background_common.h"
|
||||
@@ -55,8 +54,6 @@ std::mutex g_merc_data_mutex;
|
||||
|
||||
Merc2::Merc2(ShaderLibrary& shaders, const std::vector<GLuint>* anim_slot_array)
|
||||
: m_anim_slot_array(anim_slot_array) {
|
||||
ASSERT(fnv64("the quick brown fox jumps over the lazy dog") == 0x7404cea13ff89bb0);
|
||||
|
||||
// Set up main vertex array. This will point to the data stored in the .FR3 level file, and will
|
||||
// be uploaded to the GPU by the Loader.
|
||||
glGenVertexArrays(1, &m_vao);
|
||||
@@ -538,14 +535,11 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
|
||||
auto* flags = (const PcMercFlags*)input_data;
|
||||
int num_effects = flags->effect_count; // mostly just a sanity check
|
||||
ASSERT(num_effects < kMaxEffect);
|
||||
// hack for custom models to disable blerc/mod draws
|
||||
bool is_custom_model = model->effects.at(0).all_draws.at(0).no_strip;
|
||||
u64 current_ignore_alpha_bits = flags->ignore_alpha_mask; // shader settings
|
||||
u64 current_effect_enable_bits = flags->enable_mask; // mask for game to disable an effect
|
||||
bool model_uses_mod =
|
||||
flags->bitflags & 1 && !is_custom_model; // if we should update vertices from game.
|
||||
bool model_uses_mod = flags->bitflags & 1; // if we should update vertices from game.
|
||||
bool model_disables_fog = flags->bitflags & 2;
|
||||
bool model_uses_pc_blerc = flags->bitflags & 4 && !is_custom_model;
|
||||
bool model_uses_pc_blerc = flags->bitflags & 4;
|
||||
bool model_disables_envmap = flags->bitflags & 8;
|
||||
input_data += 32;
|
||||
|
||||
@@ -615,8 +609,6 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
|
||||
u32 lights = alloc_lights(current_lights);
|
||||
stats->num_lights++;
|
||||
|
||||
u64 hash = fnv64(model->name);
|
||||
|
||||
// loop over effects, creating draws for each
|
||||
for (size_t ei = 0; ei < model->effects.size(); ei++) {
|
||||
// game has disabled it?
|
||||
@@ -641,7 +633,7 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
|
||||
// do fixed draws:
|
||||
for (auto& fdraw : effect.mod.fix_draw) {
|
||||
alloc_normal_draw(fdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water,
|
||||
model_disables_fog, hash);
|
||||
model_disables_fog);
|
||||
if (should_envmap) {
|
||||
try_alloc_envmap_draw(fdraw, effect.envmap_mode, effect.envmap_texture, lev_bucket,
|
||||
fade_buffer + 4 * ei, first_bone, lights, uses_water);
|
||||
@@ -651,7 +643,7 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
|
||||
// do mod draws
|
||||
for (auto& mdraw : effect.mod.mod_draw) {
|
||||
auto n = alloc_normal_draw(mdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water,
|
||||
model_disables_fog, hash);
|
||||
model_disables_fog);
|
||||
// modify the draw, set the mod flag and point it to the opengl buffer
|
||||
n->flags |= MOD_VTX;
|
||||
n->mod_vtx_buffer = mod_opengl_buffers[ei];
|
||||
@@ -673,7 +665,7 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
|
||||
fade_buffer + 4 * ei, first_bone, lights, uses_water);
|
||||
}
|
||||
alloc_normal_draw(draw, ignore_alpha, lev_bucket, first_bone, lights, uses_water,
|
||||
model_disables_fog, hash);
|
||||
model_disables_fog);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -769,9 +761,7 @@ void Merc2::render(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof,
|
||||
MercDebugStats* stats) {
|
||||
bool hack = stats->collect_debug_model_list;
|
||||
*stats = {};
|
||||
stats->collect_debug_model_list = hack;
|
||||
if (stats->collect_debug_model_list) {
|
||||
stats->model_list.clear();
|
||||
}
|
||||
@@ -1063,7 +1053,6 @@ Merc2::Draw* Merc2::try_alloc_envmap_draw(const tfrag3::MercDraw& mdraw,
|
||||
draw->first_index = mdraw.first_index;
|
||||
draw->index_count = mdraw.index_count;
|
||||
draw->mode = envmap_mode;
|
||||
draw->hash = 0;
|
||||
if (jak1_water_mode) {
|
||||
draw->mode.enable_ab();
|
||||
draw->mode.disable_depth_write();
|
||||
@@ -1084,14 +1073,12 @@ Merc2::Draw* Merc2::alloc_normal_draw(const tfrag3::MercDraw& mdraw,
|
||||
u32 first_bone,
|
||||
u32 lights,
|
||||
bool jak1_water_mode,
|
||||
bool disable_fog,
|
||||
u64 hash) {
|
||||
bool disable_fog) {
|
||||
Draw* draw = &lev_bucket->draws[lev_bucket->next_free_draw++];
|
||||
draw->flags = 0;
|
||||
draw->first_index = mdraw.first_index;
|
||||
draw->index_count = mdraw.index_count;
|
||||
draw->mode = mdraw.mode;
|
||||
draw->hash = hash;
|
||||
if (jak1_water_mode) {
|
||||
draw->mode.set_ab(true);
|
||||
draw->mode.disable_depth_write();
|
||||
@@ -1218,7 +1205,7 @@ void Merc2::do_draws(const Draw* draw_array,
|
||||
bool set_fade,
|
||||
SharedRenderState* render_state) {
|
||||
glBindVertexArray(m_vao);
|
||||
s32 last_tex = INT32_MIN;
|
||||
int last_tex = -1;
|
||||
int last_light = -1;
|
||||
bool normal_vtx_buffer_bound = true;
|
||||
|
||||
@@ -1257,19 +1244,10 @@ void Merc2::do_draws(const Draw* draw_array,
|
||||
if (draw.texture < (int)lev->textures.size() && draw.texture >= 0) {
|
||||
glBindTexture(GL_TEXTURE_2D, lev->textures.at(draw.texture));
|
||||
} else if ((draw.texture & 0xffffff00) == 0xefffff00) {
|
||||
if (render_state->version >= GameVersion::Jak3) {
|
||||
auto maybe_eye =
|
||||
render_state->eye_renderer->lookup_eye_texture_hash(draw.hash, (draw.texture & 1));
|
||||
if (maybe_eye) {
|
||||
glBindTexture(GL_TEXTURE_2D, *maybe_eye);
|
||||
}
|
||||
} else {
|
||||
auto maybe_eye = render_state->eye_renderer->lookup_eye_texture(draw.texture & 0xff);
|
||||
if (maybe_eye) {
|
||||
glBindTexture(GL_TEXTURE_2D, *maybe_eye);
|
||||
}
|
||||
auto maybe_eye = render_state->eye_renderer->lookup_eye_texture(draw.texture & 0xff);
|
||||
if (maybe_eye) {
|
||||
glBindTexture(GL_TEXTURE_2D, *maybe_eye);
|
||||
}
|
||||
|
||||
use_mipmaps_for_filtering = false;
|
||||
} else if (draw.texture < 0) {
|
||||
int slot = -(draw.texture + 1);
|
||||
|
||||
@@ -192,7 +192,6 @@ class Merc2 {
|
||||
u8 fade[4];
|
||||
// no strip hack for custom models
|
||||
u8 no_strip;
|
||||
u64 hash;
|
||||
};
|
||||
|
||||
struct LevelDrawBucket {
|
||||
@@ -214,8 +213,7 @@ class Merc2 {
|
||||
u32 first_bone,
|
||||
u32 lights,
|
||||
bool jak1_water_mode,
|
||||
bool disable_fog,
|
||||
u64 hash);
|
||||
bool disable_fog);
|
||||
|
||||
Draw* try_alloc_envmap_draw(const tfrag3::MercDraw& mdraw,
|
||||
const DrawMode& envmap_mode,
|
||||
|
||||
@@ -17,14 +17,8 @@ void Merc2BucketRenderer::render(DmaFollower& dma,
|
||||
}
|
||||
|
||||
m_renderer->render(dma, render_state, prof, &m_debug_stats);
|
||||
|
||||
m_empty = m_debug_stats.num_predicted_draws == 0;
|
||||
}
|
||||
|
||||
void Merc2BucketRenderer::draw_debug_window() {
|
||||
m_renderer->draw_debug_window(&m_debug_stats);
|
||||
}
|
||||
|
||||
bool Merc2BucketRenderer::empty() const {
|
||||
return m_empty;
|
||||
}
|
||||
@@ -8,10 +8,8 @@ class Merc2BucketRenderer : public BucketRenderer {
|
||||
Merc2BucketRenderer(const std::string& name, int my_id, std::shared_ptr<Merc2> merc);
|
||||
void draw_debug_window() override;
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
bool empty() const override;
|
||||
|
||||
private:
|
||||
bool m_empty = false;
|
||||
std::shared_ptr<Merc2> m_renderer;
|
||||
MercDebugStats m_debug_stats;
|
||||
};
|
||||
@@ -10,8 +10,6 @@ uniform vec3 fog_constants;
|
||||
uniform vec4 scale;
|
||||
uniform float mat_23;
|
||||
uniform float mat_33;
|
||||
uniform bool use_full_matrix;
|
||||
uniform mat4 full_matrix;
|
||||
uniform vec4 hvdf_offset;
|
||||
uniform uint warp_sample_mode;
|
||||
|
||||
@@ -40,17 +38,11 @@ void main() {
|
||||
|
||||
// maddax.xyzw ACC, vf08, vf16 matrix multiply X
|
||||
// vu.acc.madda(Mask::xyzw, gen.mat0, gen.vtx_load0.x());
|
||||
if (use_full_matrix) {
|
||||
transformed = -full_matrix[3];
|
||||
transformed -= full_matrix[0] * position_in.x ;
|
||||
transformed -= full_matrix[1] * position_in.y;
|
||||
transformed -= full_matrix[2] * position_in.z ;
|
||||
} else {
|
||||
transformed.xyz = position_in * scale.xyz;
|
||||
transformed.z += mat_32;
|
||||
transformed.w = mat_23 * position_in.z + mat_33;
|
||||
transformed *= -1;
|
||||
}
|
||||
transformed.xyz = position_in * scale.xyz;
|
||||
transformed.z += mat_32;
|
||||
transformed.w = mat_23 * position_in.z + mat_33;
|
||||
|
||||
transformed *= -1; // todo?
|
||||
|
||||
|
||||
// div Q, vf01.x, vf12.w perspective divide
|
||||
|
||||
@@ -4,7 +4,6 @@ out vec4 color;
|
||||
|
||||
uniform vec4 rgba;
|
||||
uniform int enable_tex;
|
||||
uniform int set_alpha;
|
||||
uniform int tcc;
|
||||
uniform ivec4 channel_scramble;
|
||||
uniform float alpha_multiply;
|
||||
@@ -58,9 +57,5 @@ void main() {
|
||||
} else {
|
||||
color = (rgba / 128.);
|
||||
}
|
||||
if (set_alpha == 1) {
|
||||
color.a = 0.5;
|
||||
} else {
|
||||
color.a *= alpha_multiply;
|
||||
}
|
||||
color.a *= alpha_multiply;
|
||||
}
|
||||
@@ -448,6 +448,23 @@ void render_game_frame(int game_width,
|
||||
}
|
||||
}
|
||||
|
||||
void update_global_profiler() {
|
||||
if (g_gfx_data->debug_gui.dump_events) {
|
||||
prof().set_enable(false);
|
||||
g_gfx_data->debug_gui.dump_events = false;
|
||||
|
||||
// TODO - the file rotation code had an infinite loop here if it couldn't find anything
|
||||
// matching the format
|
||||
//
|
||||
// Does the existing log rotation code have that problem?
|
||||
|
||||
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
|
||||
fmt::format("prof-{}.json", str_util::current_local_timestamp_no_colons());
|
||||
file_util::create_dir_if_needed_for_file(file_path);
|
||||
prof().dump_to_json(file_path.string());
|
||||
}
|
||||
}
|
||||
|
||||
void GLDisplay::process_sdl_events() {
|
||||
SDL_Event evt;
|
||||
while (SDL_PollEvent(&evt) != 0) {
|
||||
@@ -586,6 +603,7 @@ void GLDisplay::render() {
|
||||
// Start timing for the next frame.
|
||||
g_gfx_data->debug_gui.start_frame();
|
||||
prof().instant_event("ROOT");
|
||||
update_global_profiler();
|
||||
|
||||
// toggle even odd and wake up engine waiting on vsync.
|
||||
// TODO: we could play with moving this earlier, right after the final bucket renderer.
|
||||
|
||||
@@ -125,6 +125,7 @@ struct link_control {
|
||||
}
|
||||
};
|
||||
|
||||
void klink_init_globals();
|
||||
Ptr<u8> c_symlink2(Ptr<u8> objData, Ptr<u8> linkObj, Ptr<u8> relocTable);
|
||||
|
||||
extern link_control saved_link_control;
|
||||
|
||||
@@ -448,19 +448,6 @@ u64 pc_get_mips2c(u32 name) {
|
||||
return Mips2C::gLinkedFunctionTable.get(n);
|
||||
}
|
||||
|
||||
u64 pc_get_display_id() {
|
||||
if (Display::GetMainDisplay()) {
|
||||
return Display::GetMainDisplay()->get_display_manager()->get_active_display_id();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pc_set_display_id(u64 display_id) {
|
||||
if (Display::GetMainDisplay()) {
|
||||
Display::GetMainDisplay()->get_display_manager()->enqueue_set_display_id(display_id);
|
||||
}
|
||||
}
|
||||
|
||||
u64 pc_get_display_name(u32 id, u32 str_dest_ptr) {
|
||||
std::string name = "";
|
||||
if (Display::GetMainDisplay()) {
|
||||
@@ -482,16 +469,17 @@ u64 pc_get_display_name(u32 id, u32 str_dest_ptr) {
|
||||
}
|
||||
|
||||
u32 pc_get_display_mode() {
|
||||
auto display_mode = game_settings::DisplaySettings::DisplayMode::Windowed;
|
||||
auto display_mode = WindowDisplayMode::Windowed;
|
||||
if (Display::GetMainDisplay()) {
|
||||
display_mode = Display::GetMainDisplay()->get_display_manager()->get_display_mode();
|
||||
display_mode = Display::GetMainDisplay()->get_display_manager()->get_window_display_mode();
|
||||
}
|
||||
switch (display_mode) {
|
||||
case game_settings::DisplaySettings::DisplayMode::Borderless:
|
||||
case WindowDisplayMode::Borderless:
|
||||
return g_pc_port_funcs.intern_from_c("borderless").offset;
|
||||
case game_settings::DisplaySettings::DisplayMode::Fullscreen:
|
||||
case WindowDisplayMode::Fullscreen:
|
||||
return g_pc_port_funcs.intern_from_c("fullscreen").offset;
|
||||
default:
|
||||
case WindowDisplayMode::Windowed:
|
||||
return g_pc_port_funcs.intern_from_c("windowed").offset;
|
||||
}
|
||||
}
|
||||
@@ -502,13 +490,13 @@ void pc_set_display_mode(u32 symptr) {
|
||||
}
|
||||
if (symptr == g_pc_port_funcs.intern_from_c("windowed").offset || symptr == s7.offset) {
|
||||
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_display_mode(
|
||||
game_settings::DisplaySettings::DisplayMode::Windowed);
|
||||
WindowDisplayMode::Windowed);
|
||||
} else if (symptr == g_pc_port_funcs.intern_from_c("borderless").offset) {
|
||||
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_display_mode(
|
||||
game_settings::DisplaySettings::DisplayMode::Borderless);
|
||||
WindowDisplayMode::Borderless);
|
||||
} else if (symptr == g_pc_port_funcs.intern_from_c("fullscreen").offset) {
|
||||
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_display_mode(
|
||||
game_settings::DisplaySettings::DisplayMode::Fullscreen);
|
||||
WindowDisplayMode::Fullscreen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,6 +568,12 @@ void pc_get_window_scale(u32 x_ptr, u32 y_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
void pc_get_fullscreen_display(u64 display_id) {
|
||||
if (Display::GetMainDisplay()) {
|
||||
Display::GetMainDisplay()->get_display_manager()->enqueue_set_fullscreen_display_id(display_id);
|
||||
}
|
||||
}
|
||||
|
||||
void pc_set_window_size(u64 width, u64 height) {
|
||||
if (Display::GetMainDisplay()) {
|
||||
Display::GetMainDisplay()->get_display_manager()->enqueue_set_window_size(width, height);
|
||||
@@ -607,14 +601,6 @@ void pc_get_resolution(u32 id, u32 w_ptr, u32 h_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
u64 pc_is_supported_resolution(u64 width, u64 height) {
|
||||
if (Display::GetMainDisplay()) {
|
||||
return bool_to_symbol(
|
||||
Display::GetMainDisplay()->get_display_manager()->is_supported_resolution(width, height));
|
||||
}
|
||||
return bool_to_symbol(false);
|
||||
}
|
||||
|
||||
u64 pc_get_controller_name(u32 id, u32 str_dest_ptr) {
|
||||
std::string name = "";
|
||||
if (Display::GetMainDisplay()) {
|
||||
@@ -926,11 +912,9 @@ void init_common_pc_port_functions(
|
||||
|
||||
// -- DISPLAY RELATED --
|
||||
// Returns the name of the display with the given id or #f if not found / empty
|
||||
make_func_symbol_func("pc-get-display-id", (void*)pc_get_display_id);
|
||||
make_func_symbol_func("pc-set-display-id!", (void*)pc_set_display_id);
|
||||
make_func_symbol_func("pc-get-display-name", (void*)pc_get_display_name);
|
||||
make_func_symbol_func("pc-get-display-mode", (void*)pc_get_display_mode);
|
||||
make_func_symbol_func("pc-set-display-mode!", (void*)pc_set_display_mode);
|
||||
make_func_symbol_func("pc-set-display-mode", (void*)pc_set_display_mode);
|
||||
make_func_symbol_func("pc-get-display-count", (void*)pc_get_display_count);
|
||||
// Returns resolution of the monitor's current display mode
|
||||
make_func_symbol_func("pc-get-active-display-size", (void*)pc_get_active_display_size);
|
||||
@@ -941,10 +925,10 @@ void init_common_pc_port_functions(
|
||||
make_func_symbol_func("pc-get-window-size", (void*)pc_get_window_size);
|
||||
// Returns scale of window. This is for DPI stuff.
|
||||
make_func_symbol_func("pc-get-window-scale", (void*)pc_get_window_scale);
|
||||
make_func_symbol_func("pc-set-window-size!", (void*)pc_set_window_size);
|
||||
make_func_symbol_func("pc-set-fullscreen-display", (void*)pc_get_fullscreen_display);
|
||||
make_func_symbol_func("pc-set-window-size", (void*)pc_set_window_size);
|
||||
make_func_symbol_func("pc-get-num-resolutions", (void*)pc_get_num_resolutions);
|
||||
make_func_symbol_func("pc-get-resolution", (void*)pc_get_resolution);
|
||||
make_func_symbol_func("pc-is-supported-resolution?", (void*)pc_is_supported_resolution);
|
||||
|
||||
// -- INPUT RELATED --
|
||||
// Returns the name of the display with the given id or #f if not found / empty
|
||||
|
||||
@@ -16,6 +16,7 @@ void load_and_link_dgo_from_c_fast(const char* name,
|
||||
Ptr<kheapinfo> heap,
|
||||
u32 linkFlag,
|
||||
s32 bufferSize);
|
||||
void load_and_link_dgo(u64 name_gstr, u64 heap_info, u64 flag, u64 buffer_size);
|
||||
void kdgo_init_globals();
|
||||
extern RPC_Dgo_Cmd sMsg[2];
|
||||
extern RPC_Dgo_Cmd* sLastMsg;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "game/kernel/common/kdgo.h"
|
||||
#include "game/kernel/common/kmalloc.h"
|
||||
#include "game/kernel/jak3/klink.h"
|
||||
#include "game/overlord/jak3/rpc_interface.h"
|
||||
|
||||
namespace jak3 {
|
||||
|
||||
@@ -40,7 +39,7 @@ void BeginLoadingDGO(const char* name, Ptr<u8> buffer1, Ptr<u8> buffer2, Ptr<u8>
|
||||
RpcSync(DGO_RPC_CHANNEL); // make sure old RPC is finished
|
||||
|
||||
// put a dummy value here just to make sure the IOP overwrites it.
|
||||
sMsg[msgID].status = DGO_RPC_RESULT_INIT; // !! this is 666
|
||||
sMsg[msgID].result = DGO_RPC_RESULT_INIT; // !! this is 666
|
||||
|
||||
// inform IOP of buffers
|
||||
sMsg[msgID].buffer1 = buffer1.offset;
|
||||
@@ -79,13 +78,13 @@ Ptr<u8> GetNextDGO(u32* lastObjectFlag) {
|
||||
Ptr<u8> buffer(0);
|
||||
if (sLastMsg) {
|
||||
// if we got a good result, get pointer to object
|
||||
if ((sLastMsg->status == DGO_RPC_RESULT_MORE) || (sLastMsg->status == DGO_RPC_RESULT_DONE)) {
|
||||
if ((sLastMsg->result == DGO_RPC_RESULT_MORE) || (sLastMsg->result == DGO_RPC_RESULT_DONE)) {
|
||||
buffer.offset =
|
||||
sLastMsg->buffer1; // buffer 1 always contains location of most recently loaded object.
|
||||
}
|
||||
|
||||
// not the last one, so don't set the flag.
|
||||
if (sLastMsg->status == DGO_RPC_RESULT_MORE) {
|
||||
if (sLastMsg->result == DGO_RPC_RESULT_MORE) {
|
||||
*lastObjectFlag = 0;
|
||||
}
|
||||
|
||||
@@ -112,7 +111,7 @@ void ContinueLoadingDGO(Ptr<u8> b1, Ptr<u8> b2, Ptr<u8> heapPtr) {
|
||||
u32 msgID = sMsgNum;
|
||||
jak3::RPC_Dgo_Cmd* sendBuff = sMsg + sMsgNum;
|
||||
sMsgNum = sMsgNum ^ 1;
|
||||
sendBuff->status = DGO_RPC_RESULT_INIT;
|
||||
sendBuff->result = DGO_RPC_RESULT_INIT;
|
||||
sMsg[msgID].buffer1 = b1.offset;
|
||||
sMsg[msgID].buffer2 = b2.offset;
|
||||
sMsg[msgID].buffer_heap_top = heapPtr.offset;
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
//--------------------------MIPS2C---------------------
|
||||
// clang-format off
|
||||
#include "game/mips2c/mips2c_private.h"
|
||||
#include "game/kernel/jak3/kscheme.h"
|
||||
using ::jak3::intern_from_c;
|
||||
namespace Mips2C::jak3 {
|
||||
namespace method_21_cloth_system {
|
||||
u64 execute(void* ctxt) {
|
||||
auto* c = (ExecutionContext*)ctxt;
|
||||
bool bc = false;
|
||||
u32 call_addr = 0;
|
||||
c->daddiu(sp, sp, -80); // daddiu sp, sp, -80
|
||||
c->daddiu(a3, sp, 16); // daddiu a3, sp, 16
|
||||
c->daddiu(t0, sp, 32); // daddiu t0, sp, 32
|
||||
c->lwu(v1, 68, a0); // lwu v1, 68(a0)
|
||||
c->lw(v1, 0, v1); // lw v1, 0(v1)
|
||||
c->lw(a1, 96, a0); // lw a1, 96(a0)
|
||||
c->daddiu(a1, a1, -1); // daddiu a1, a1, -1
|
||||
c->lw(a2, 100, a0); // lw a2, 100(a0)
|
||||
c->daddiu(a2, a2, -1); // daddiu a2, a2, -1
|
||||
c->addiu(t1, r0, 0); // addiu t1, r0, 0
|
||||
c->addiu(t1, r0, 0); // addiu t1, r0, 0
|
||||
c->mov64(t1, a3); // or t1, a3, r0
|
||||
c->lui(t2, 16000); // lui t2, 16000
|
||||
c->mtc1(f0, t2); // mtc1 f0, t2
|
||||
c->swc1(f0, 0, t1); // swc1 f0, 0(t1)
|
||||
c->lui(t2, 16000); // lui t2, 16000
|
||||
c->mtc1(f0, t2); // mtc1 f0, t2
|
||||
c->swc1(f0, 4, t1); // swc1 f0, 4(t1)
|
||||
c->lui(t2, 16000); // lui t2, 16000
|
||||
c->mtc1(f0, t2); // mtc1 f0, t2
|
||||
c->swc1(f0, 8, t1); // swc1 f0, 8(t1)
|
||||
c->lui(t2, 16000); // lui t2, 16000
|
||||
c->mtc1(f0, t2); // mtc1 f0, t2
|
||||
c->swc1(f0, 12, t1); // swc1 f0, 12(t1)
|
||||
c->mov64(t1, t0); // or t1, t0, r0
|
||||
c->mtc1(f0, r0); // mtc1 f0, r0
|
||||
c->swc1(f0, 0, t1); // swc1 f0, 0(t1)
|
||||
c->mtc1(f0, r0); // mtc1 f0, r0
|
||||
c->swc1(f0, 4, t1); // swc1 f0, 4(t1)
|
||||
c->mtc1(f0, r0); // mtc1 f0, r0
|
||||
c->swc1(f0, 8, t1); // swc1 f0, 8(t1)
|
||||
c->lwc1(f0, 144, a0); // lwc1 f0, 144(a0)
|
||||
c->swc1(f0, 12, t1); // swc1 f0, 12(t1)
|
||||
c->vmax_bc(DEST::xyzw, BC::w, vf1, vf0, vf0); // vmaxw.xyzw vf1, vf0, vf0
|
||||
c->lqc2(vf10, 0, a3); // lqc2 vf10, 0(a3)
|
||||
c->lqc2(vf15, 0, t0); // lqc2 vf15, 0(t0)
|
||||
c->sd(r0, 48, sp); // sd r0, 48(sp)
|
||||
c->addiu(a3, r0, 0); // addiu a3, r0, 0
|
||||
//beq r0, r0, L187 // beq r0, r0, L187
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_10; // branch always
|
||||
|
||||
|
||||
block_1:
|
||||
c->addiu(t0, r0, 0); // addiu t0, r0, 0
|
||||
//beq r0, r0, L186 // beq r0, r0, L186
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_8; // branch always
|
||||
|
||||
|
||||
block_2:
|
||||
c->addiu(t1, r0, 48); // addiu t1, r0, 48
|
||||
c->ld(t2, 48, sp); // ld t2, 48(sp)
|
||||
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
|
||||
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
|
||||
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
|
||||
c->daddu(t1, t1, t2); // daddu t1, t1, t2
|
||||
c->sw(t1, 56, sp); // sw t1, 56(sp)
|
||||
c->addiu(t1, r0, 48); // addiu t1, r0, 48
|
||||
c->ld(t2, 48, sp); // ld t2, 48(sp)
|
||||
c->daddiu(t2, t2, 1); // daddiu t2, t2, 1
|
||||
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
|
||||
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
|
||||
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
|
||||
c->daddu(t1, t1, t2); // daddu t1, t1, t2
|
||||
c->sw(t1, 60, sp); // sw t1, 60(sp)
|
||||
c->addiu(t1, r0, 48); // addiu t1, r0, 48
|
||||
c->ld(t2, 48, sp); // ld t2, 48(sp)
|
||||
c->lw(t3, 96, a0); // lw t3, 96(a0)
|
||||
c->daddu(t2, t2, t3); // daddu t2, t2, t3
|
||||
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
|
||||
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
|
||||
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
|
||||
c->daddu(t1, t1, t2); // daddu t1, t1, t2
|
||||
c->sw(t1, 64, sp); // sw t1, 64(sp)
|
||||
c->addiu(t1, r0, 48); // addiu t1, r0, 48
|
||||
c->lw(t2, 96, a0); // lw t2, 96(a0)
|
||||
c->daddiu(t2, t2, 1); // daddiu t2, t2, 1
|
||||
c->ld(t3, 48, sp); // ld t3, 48(sp)
|
||||
c->daddu(t2, t2, t3); // daddu t2, t2, t3
|
||||
c->mult3(t1, t1, t2); // mult3 t1, t1, t2
|
||||
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
|
||||
c->lwu(t2, 0, a0); // lwu t2, 0(a0)
|
||||
c->daddu(t1, t1, t2); // daddu t1, t1, t2
|
||||
c->sw(t1, 68, sp); // sw t1, 68(sp)
|
||||
c->lwu(t1, 56, sp); // lwu t1, 56(sp)
|
||||
c->lqc2(vf2, 0, t1); // lqc2 vf2, 0(t1)
|
||||
c->lwu(t1, 68, sp); // lwu t1, 68(sp)
|
||||
c->lqc2(vf5, 0, t1); // lqc2 vf5, 0(t1)
|
||||
c->lwu(t1, 60, sp); // lwu t1, 60(sp)
|
||||
c->lqc2(vf3, 0, t1); // lqc2 vf3, 0(t1)
|
||||
c->lwu(t1, 64, sp); // lwu t1, 64(sp)
|
||||
c->lqc2(vf4, 0, t1); // lqc2 vf4, 0(t1)
|
||||
c->lwu(t1, 56, sp); // lwu t1, 56(sp)
|
||||
c->lqc2(vf20, 32, t1); // lqc2 vf20, 32(t1)
|
||||
c->lwu(t1, 68, sp); // lwu t1, 68(sp)
|
||||
c->lqc2(vf23, 32, t1); // lqc2 vf23, 32(t1)
|
||||
c->lwu(t1, 60, sp); // lwu t1, 60(sp)
|
||||
c->lqc2(vf21, 32, t1); // lqc2 vf21, 32(t1)
|
||||
c->lwu(t1, 64, sp); // lwu t1, 64(sp)
|
||||
c->lqc2(vf22, 32, t1); // lqc2 vf22, 32(t1)
|
||||
c->vmula_bc(DEST::xyzw, BC::x, vf2, vf20); // vmulax.xyzw acc, vf2, vf20
|
||||
c->vmadda_bc(DEST::xyzw, BC::x, vf3, vf21); // vmaddax.xyzw acc, vf3, vf21
|
||||
c->vmadda_bc(DEST::xyzw, BC::x, vf5, vf23); // vmaddax.xyzw acc, vf5, vf23
|
||||
c->vmadd_bc(DEST::xyzw, BC::x, vf8, vf4, vf22); // vmaddx.xyzw vf8, vf4, vf22
|
||||
c->vmul_bc(DEST::xyzw, BC::x, vf8, vf8, vf10); // vmulx.xyzw vf8, vf8, vf10
|
||||
c->lwu(t1, 68, a0); // lwu t1, 68(a0)
|
||||
c->daddiu(t1, t1, 12); // daddiu t1, t1, 12
|
||||
c->addiu(t2, r0, 0); // addiu t2, r0, 0
|
||||
//beq r0, r0, L185 // beq r0, r0, L185
|
||||
// nop // sll r0, r0, 0
|
||||
goto block_6; // branch always
|
||||
|
||||
|
||||
block_3:
|
||||
c->lqc2(vf11, 0, t1); // lqc2 vf11, 0(t1)
|
||||
c->vsub(DEST::xyzw, vf13, vf8, vf11); // vsub.xyzw vf13, vf8, vf11
|
||||
c->vmul(DEST::xyzw, vf9, vf13, vf13); // vmul.xyzw vf9, vf13, vf13
|
||||
c->vmula_bc(DEST::xyzw, BC::x, vf1, vf9); // vmulax.xyzw acc, vf1, vf9
|
||||
c->vmadda_bc(DEST::xyzw, BC::y, vf1, vf9); // vmadday.xyzw acc, vf1, vf9
|
||||
c->vmadd_bc(DEST::xyzw, BC::z, vf14, vf1, vf9); // vmaddz.xyzw vf14, vf1, vf9
|
||||
c->vadd_bc(DEST::w, BC::w, vf11, vf11, vf15); // vaddw.w vf11, vf11, vf15
|
||||
c->vmul(DEST::xyzw, vf12, vf11, vf11); // vmul.xyzw vf12, vf11, vf11
|
||||
c->vsub_bc(DEST::xyzw, BC::w, vf9, vf14, vf12); // vsubw.xyzw vf9, vf14, vf12
|
||||
c->mov128_gpr_vf(t3, vf9); // qmfc2.i t3, vf9
|
||||
bc = ((s64)c->sgpr64(t3)) >= 0; // bgez t3, L184
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_5;} // branch non-likely
|
||||
|
||||
c->vrsqrt(vf11, BC::w, vf14, BC::x); // vrsqrt Q, vf11.w, vf14.x
|
||||
c->vmax_bc(DEST::xyz, BC::x, vf20, vf0, vf20); // vmaxx.xyz vf20, vf0, vf20
|
||||
c->vmax_bc(DEST::xyz, BC::x, vf21, vf0, vf21); // vmaxx.xyz vf21, vf0, vf21
|
||||
c->vmax_bc(DEST::xyz, BC::x, vf22, vf0, vf22); // vmaxx.xyz vf22, vf0, vf22
|
||||
c->vmax_bc(DEST::xyz, BC::x, vf23, vf0, vf23); // vmaxx.xyz vf23, vf0, vf23
|
||||
c->vwaitq(); // vwaitq
|
||||
// Unknown instr: vmulaq.xyzw acc, vf13, Q
|
||||
c->vmula_q(DEST::xyzw, vf13);
|
||||
c->vmsuba(DEST::xyzw, vf1, vf13); // vmsuba.xyzw acc, vf1, vf13
|
||||
c->vmadd(DEST::xyzw, vf2, vf1, vf2); // vmadd.xyzw vf2, vf1, vf2
|
||||
c->vmadd(DEST::xyzw, vf3, vf1, vf3); // vmadd.xyzw vf3, vf1, vf3
|
||||
c->vmadd(DEST::xyzw, vf5, vf1, vf5); // vmadd.xyzw vf5, vf1, vf5
|
||||
c->vmadd(DEST::xyzw, vf4, vf1, vf4); // vmadd.xyzw vf4, vf1, vf4
|
||||
c->vmadd(DEST::xyzw, vf8, vf1, vf8); // vmadd.xyzw vf8, vf1, vf8
|
||||
|
||||
block_5:
|
||||
c->daddiu(t1, t1, 16); // daddiu t1, t1, 16
|
||||
c->daddiu(t2, t2, 1); // daddiu t2, t2, 1
|
||||
|
||||
block_6:
|
||||
c->slt(t3, t2, v1); // slt t3, t2, v1
|
||||
bc = c->sgpr64(t3) != 0; // bne t3, r0, L183
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_3;} // branch non-likely
|
||||
|
||||
c->mov64(t1, s7); // or t1, s7, r0
|
||||
c->mov64(t1, s7); // or t1, s7, r0
|
||||
c->lwu(t1, 56, sp); // lwu t1, 56(sp)
|
||||
c->sqc2(vf2, 0, t1); // sqc2 vf2, 0(t1)
|
||||
c->lwu(t1, 68, sp); // lwu t1, 68(sp)
|
||||
c->sqc2(vf5, 0, t1); // sqc2 vf5, 0(t1)
|
||||
c->lwu(t1, 60, sp); // lwu t1, 60(sp)
|
||||
c->sqc2(vf3, 0, t1); // sqc2 vf3, 0(t1)
|
||||
c->lwu(t1, 64, sp); // lwu t1, 64(sp)
|
||||
c->sqc2(vf4, 0, t1); // sqc2 vf4, 0(t1)
|
||||
c->mov128_gpr_vf(t1, vf4); // qmfc2.i t1, vf4
|
||||
c->ld(t1, 48, sp); // ld t1, 48(sp)
|
||||
c->daddiu(t1, t1, 1); // daddiu t1, t1, 1
|
||||
c->sd(t1, 48, sp); // sd t1, 48(sp)
|
||||
c->daddiu(t0, t0, 1); // daddiu t0, t0, 1
|
||||
|
||||
block_8:
|
||||
c->slt(t1, t0, a1); // slt t1, t0, a1
|
||||
bc = c->sgpr64(t1) != 0; // bne t1, r0, L182
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_2;} // branch non-likely
|
||||
|
||||
c->mov64(t0, s7); // or t0, s7, r0
|
||||
c->mov64(t0, s7); // or t0, s7, r0
|
||||
c->ld(t0, 48, sp); // ld t0, 48(sp)
|
||||
c->daddiu(t0, t0, 1); // daddiu t0, t0, 1
|
||||
c->sd(t0, 48, sp); // sd t0, 48(sp)
|
||||
c->daddiu(a3, a3, 1); // daddiu a3, a3, 1
|
||||
|
||||
block_10:
|
||||
c->slt(t0, a3, a2); // slt t0, a3, a2
|
||||
bc = c->sgpr64(t0) != 0; // bne t0, r0, L181
|
||||
// nop // sll r0, r0, 0
|
||||
if (bc) {goto block_1;} // branch non-likely
|
||||
|
||||
c->mov64(v1, s7); // or v1, s7, r0
|
||||
c->mov64(v0, s7); // or v0, s7, r0
|
||||
//jr ra // jr ra
|
||||
c->daddiu(sp, sp, 80); // daddiu sp, sp, 80
|
||||
goto end_of_function; // return
|
||||
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
// nop // sll r0, r0, 0
|
||||
end_of_function:
|
||||
return c->gprs[v0].du64[0];
|
||||
}
|
||||
|
||||
void link() {
|
||||
gLinkedFunctionTable.reg("(method 21 cloth-system)", execute, 256);
|
||||
}
|
||||
|
||||
} // namespace method_21_cloth_system
|
||||
} // namespace Mips2C
|
||||
|
||||
@@ -905,16 +905,6 @@ struct ExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
void vmula_q(DEST mask, int src0) {
|
||||
auto s0 = vf_src(src0);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if ((u64)mask & (1 << i)) {
|
||||
acc.f[i] = s0.f[i] * Q;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vadda_bc(DEST mask, BC bc, int src0, int src1) {
|
||||
auto s0 = vf_src(src0);
|
||||
auto s1 = vf_src(src1);
|
||||
|
||||
@@ -393,7 +393,6 @@ 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(); }
|
||||
namespace method_21_cloth_system { extern void link(); }
|
||||
|
||||
}
|
||||
// clang-format on
|
||||
@@ -655,8 +654,7 @@ PerGameVersion<std::unordered_map<std::string, std::vector<void (*)()>>> gMips2C
|
||||
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}},
|
||||
{"cloth", {jak3::method_21_cloth_system::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>()}});
|
||||
|
||||
@@ -460,9 +460,6 @@ void* RPC_Loader(unsigned int /*fno*/, void* data, int size) {
|
||||
snd_SetPlayBackMode(0);
|
||||
}
|
||||
} break;
|
||||
case Jak2SoundCommand::mirror_mode: {
|
||||
gMirrorMode = cmd->mirror.value;
|
||||
} break;
|
||||
default:
|
||||
ASSERT_MSG(false, fmt::format("Unhandled RPC Loader command {}", int(cmd->j2command)));
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ enum class Jak2SoundCommand : u16 {
|
||||
iop_mem = 48,
|
||||
cancel_dgo = 49,
|
||||
set_stereo_mode = 50,
|
||||
mirror_mode = 201,
|
||||
};
|
||||
|
||||
struct SoundRpcCommand {
|
||||
|
||||
@@ -30,7 +30,7 @@ void StopVAG(VagCmd* cmd, int /*param_2*/);
|
||||
enum VolumeCategory {
|
||||
DIALOGUE = 2, // VAG streams. Copied "dialogue" name from jak 1.
|
||||
};
|
||||
int MasterVolume[32];
|
||||
int MasterVolume[17];
|
||||
|
||||
void vag_init_globals() {
|
||||
memset(VagCmds, 0, sizeof(VagCmds));
|
||||
|
||||
@@ -113,7 +113,7 @@ extern int TrapSRAM[N_VAG_CMDS];
|
||||
extern int StreamVoice[N_VAG_CMDS];
|
||||
|
||||
extern int ActiveVagStreams;
|
||||
extern int MasterVolume[32];
|
||||
extern int MasterVolume[17];
|
||||
|
||||
void vag_init_globals();
|
||||
|
||||
|
||||
@@ -1,333 +0,0 @@
|
||||
#include "basefile.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/Assert.h"
|
||||
|
||||
#include "game/overlord/jak3/overlord.h"
|
||||
#include "game/overlord/jak3/pagemanager.h"
|
||||
#include "game/overlord/jak3/vag.h"
|
||||
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_basefile() {}
|
||||
|
||||
/*!
|
||||
* Construct a CBaseFile in an unused state.
|
||||
*/
|
||||
CBaseFile::CBaseFile() {
|
||||
m_Buffer.m_pCurrentData = nullptr;
|
||||
m_Buffer.m_pCurrentPageStart = nullptr;
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_Buffer.m_nMaxNumPages = kDefaultBufferPageCount;
|
||||
m_Buffer.m_nDataLength = 0;
|
||||
m_Buffer.m_pPageList = nullptr;
|
||||
m_Buffer.m_pIsoCmd = nullptr;
|
||||
m_Buffer.m_eBufferType = CBuffer::BufferType::EBT_FREE;
|
||||
|
||||
m_ProcessDataSemaphore = -1;
|
||||
m_FileDef = nullptr;
|
||||
m_FileKind = Kind::UNKNOWN;
|
||||
m_Status = EIsoStatus::NONE_0;
|
||||
m_ReadRate = 0;
|
||||
m_LengthPages = 0;
|
||||
m_PageOffset = 0;
|
||||
m_nNumPages = kDefaultBufferPageCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Construct a CBaseFile for a given file, but keep it in the "idle" state, with no buffer
|
||||
* allocated.
|
||||
*/
|
||||
CBaseFile::CBaseFile(const jak3::ISOFileDef* file, int semaphore) {
|
||||
m_Buffer.m_pCurrentData = nullptr;
|
||||
m_Buffer.m_nMaxNumPages = kDefaultBufferPageCount;
|
||||
m_Buffer.m_nDataLength = 0;
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_Buffer.m_pPageList = nullptr;
|
||||
m_Buffer.m_pIsoCmd = nullptr;
|
||||
m_Buffer.m_pCurrentPageStart = nullptr;
|
||||
m_Buffer.m_eBufferType = CBuffer::BufferType::EBT_FREE;
|
||||
|
||||
m_nNumPages = kDefaultBufferPageCount;
|
||||
m_FileDef = file;
|
||||
m_ProcessDataSemaphore = semaphore;
|
||||
m_FileKind = Kind::UNKNOWN;
|
||||
m_Status = EIsoStatus::IDLE_1;
|
||||
m_ReadRate = 0;
|
||||
m_LengthPages = 0;
|
||||
m_PageOffset = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Update our buffer to handle crossing page boundaries, return pointer to next data.
|
||||
*/
|
||||
uint8_t* CBaseFile::CheckPageBoundary() {
|
||||
// Can't check page boundary if the buffer is not allocated.
|
||||
ASSERT(m_Buffer.m_eBufferType != CBuffer::BufferType::EBT_FREE);
|
||||
|
||||
// Can't check page boundary if there is no manager
|
||||
ASSERT(m_Buffer.m_pPageList);
|
||||
|
||||
CPageList* page_list = m_Buffer.m_pPageList;
|
||||
CPage* page = page_list->m_pCurrentActivePage;
|
||||
|
||||
// can only return data if there's an active page
|
||||
if (!page || page_list->m_nNumActivePages <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// buffer doesn't know the current page, just reset it to the start of the active page.
|
||||
if (m_Buffer.m_pCurrentPageStart == nullptr) {
|
||||
m_Buffer.m_pCurrentData = page->m_pPageMemStart;
|
||||
m_Buffer.m_pCurrentPageStart = page->m_pPageMemStart;
|
||||
} else {
|
||||
uint8_t* end_ptr = page->m_pPageMemEnd;
|
||||
// check if our data pointer crossed the page boundary
|
||||
if (end_ptr <= m_Buffer.m_pCurrentData) {
|
||||
// it did!
|
||||
uint8_t* past_boundary_ptr = m_Buffer.m_pCurrentData;
|
||||
|
||||
// get the next active page
|
||||
CPage* next_page = page_list->StepActivePage();
|
||||
if (!next_page) {
|
||||
// no more active pages, no data to process
|
||||
m_Buffer.m_pCurrentPageStart = nullptr;
|
||||
m_Buffer.m_pCurrentData = nullptr;
|
||||
ovrld_log(LogCategory::PAGING, "File {} ran out of pages in CheckPageBoundary",
|
||||
m_FileDef->name.data);
|
||||
} else {
|
||||
// this is a little weird, but if we went past the end of the previous page, we actually
|
||||
// start at an offset into the next page - perhaps the user could know that pages are
|
||||
// consecutive in memory?
|
||||
uint8_t* new_page_mem = next_page->m_pPageMemStart;
|
||||
m_Buffer.m_pCurrentData = new_page_mem + (end_ptr + 1 - past_boundary_ptr);
|
||||
m_Buffer.m_pCurrentPageStart = new_page_mem;
|
||||
ovrld_log(LogCategory::PAGING, "File {} advanced to next page (wrapped {} bytes)",
|
||||
m_FileDef->name.data, (end_ptr + 1 - past_boundary_ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_Buffer.m_pCurrentData;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Allocate pages and set up the CBuffer for the given ISO Msg and type.
|
||||
*/
|
||||
int CBaseFile::InitBuffer(CBuffer::BufferType type, jak3::ISO_Hdr* msg) {
|
||||
ASSERT(msg);
|
||||
m_Buffer.m_pCurrentData = nullptr;
|
||||
m_Buffer.m_pPageList = nullptr;
|
||||
m_Buffer.m_pIsoCmd = msg;
|
||||
m_Buffer.m_pCurrentPageStart = nullptr;
|
||||
m_Buffer.m_nDataLength = 0;
|
||||
m_Buffer.m_eBufferType = CBuffer::BufferType::EBT_FREE;
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_Buffer.m_nMaxNumPages = kDefaultBufferPageCount;
|
||||
m_nNumPages = 4;
|
||||
|
||||
// adjust size based on the request buffer type
|
||||
switch (type) {
|
||||
case CBuffer::BufferType::REQUEST_NORMAL: { // 3
|
||||
m_Buffer.m_pCurrentData = nullptr;
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_Buffer.m_nMaxNumPages = 4;
|
||||
m_nNumPages = 4;
|
||||
m_Buffer.m_nDataLength = 0;
|
||||
m_Buffer.m_pCurrentPageStart = nullptr;
|
||||
m_Buffer.m_eBufferType = CBuffer::BufferType::NORMAL; // 1
|
||||
|
||||
// and the iso msg request.
|
||||
switch (msg->msg_type) {
|
||||
case ISO_Hdr::MsgType::LOAD_EE:
|
||||
case ISO_Hdr::MsgType::LOAD_IOP:
|
||||
case ISO_Hdr::MsgType::LOAD_EE_CHUNK:
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_nNumPages = 4;
|
||||
m_Buffer.m_nMaxNumPages = 4;
|
||||
break;
|
||||
case ISO_Hdr::MsgType::LOAD_SOUNDBANK:
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_Buffer.m_nMaxNumPages = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} break;
|
||||
case CBuffer::BufferType::REQUEST_VAG: {
|
||||
m_Buffer.m_pCurrentData = nullptr;
|
||||
m_Buffer.m_eBufferType = CBuffer::BufferType::VAG;
|
||||
m_Buffer.m_nMinNumPages = 1;
|
||||
m_nNumPages = 0x10;
|
||||
m_Buffer.m_nDataLength = 0;
|
||||
m_Buffer.m_pCurrentPageStart = nullptr;
|
||||
m_Buffer.m_nMaxNumPages = 0x10;
|
||||
} break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED(); // bad buffer type
|
||||
}
|
||||
|
||||
ovrld_log(LogCategory::PAGING, "File {} initializing buffer ({} pages {} min {} max)",
|
||||
m_FileDef->name.data, m_nNumPages, m_Buffer.m_nMinNumPages, m_Buffer.m_nMaxNumPages);
|
||||
|
||||
// Actual allocation of page data
|
||||
CPageList* page_list = AllocPages();
|
||||
if (page_list) {
|
||||
// set up the current pointers of the buffer.
|
||||
m_Buffer.m_pCurrentPageStart = page_list->m_pFirstPage->m_pPageMemStart;
|
||||
m_Buffer.m_pCurrentData = m_Buffer.m_pCurrentPageStart;
|
||||
return 1;
|
||||
} else {
|
||||
ovrld_log(LogCategory::WARN, "File {} failed to allocate a page list.", m_FileDef->name.data);
|
||||
// if it failed, terminate the buffer
|
||||
TerminateBuffer();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Free page memory, clear event flags for cpages.
|
||||
*/
|
||||
void CBaseFile::TerminateBuffer() {
|
||||
ovrld_log(LogCategory::PAGING, "File {} terminating buffer.", m_FileDef->name.data);
|
||||
|
||||
auto buffer_type = m_Buffer.m_eBufferType;
|
||||
if (buffer_type != CBuffer::BufferType::EBT_FREE) {
|
||||
// clean up our pages
|
||||
auto* page_list = m_Buffer.m_pPageList;
|
||||
if (page_list) {
|
||||
// stop try to load
|
||||
page_list->CancelActivePages();
|
||||
}
|
||||
|
||||
switch (buffer_type) {
|
||||
case CBuffer::BufferType::EBT_FREE:
|
||||
case CBuffer::BufferType::NORMAL:
|
||||
case CBuffer::BufferType::VAG:
|
||||
case CBuffer::BufferType::REQUEST_NORMAL:
|
||||
case CBuffer::BufferType::REQUEST_VAG:
|
||||
// return memory
|
||||
FreePages();
|
||||
|
||||
// reset our buffer
|
||||
m_Buffer.m_nDataLength = 0;
|
||||
m_Buffer.m_pCurrentPageStart = 0;
|
||||
m_Buffer.m_eBufferType = CBuffer::BufferType::EBT_FREE;
|
||||
|
||||
// reset our command
|
||||
if (buffer_type != CBuffer::BufferType::EBT_FREE) {
|
||||
ASSERT(m_Buffer.m_pIsoCmd);
|
||||
m_Buffer.m_pIsoCmd = nullptr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED(); // Invalid buffer type
|
||||
}
|
||||
} else {
|
||||
ASSERT_NOT_REACHED(); // Buffer already terminated, shouldn't happen again.
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Allocate CPage and CPageList as needed to reach the target number of pages.
|
||||
*/
|
||||
CPageList* CBaseFile::AllocPages() {
|
||||
// should have picked a buffer type
|
||||
ASSERT(m_Buffer.m_eBufferType != CBuffer::BufferType::EBT_FREE);
|
||||
|
||||
if (m_Buffer.m_eBufferType == CBuffer::BufferType::EBT_FREE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We might have a PageList or not
|
||||
auto* old_plist = m_Buffer.m_pPageList;
|
||||
int old_unstepped_pages = 0;
|
||||
bool have_plist = old_plist != nullptr;
|
||||
CPageList* ret_plist = nullptr;
|
||||
|
||||
// if we do have a pagelist, we'll reuse it and any unstepped pages.
|
||||
if (have_plist) {
|
||||
old_unstepped_pages = old_plist->m_nNumUnsteppedPages;
|
||||
ret_plist = old_plist;
|
||||
}
|
||||
|
||||
int page_alloc_count = 0;
|
||||
|
||||
// to increase unstepped pages to the target m_nNumPages, we need to allocate this many more.
|
||||
page_alloc_count = m_nNumPages - old_unstepped_pages;
|
||||
// lg::warn("page counts in AllocPages: {} {}", m_nNumPages, old_unstepped_pages);
|
||||
if (old_plist) {
|
||||
// lg::warn(" {} {}", old_plist->m_nNumPages, old_plist->m_nNumActivePages);
|
||||
}
|
||||
|
||||
if (old_unstepped_pages < (int)m_nNumPages) {
|
||||
// alloc count will be positive.
|
||||
|
||||
// reduce allocation count to at most the number of free pages
|
||||
if (get_page_manager()->m_CCache.m_nNumFreePages < page_alloc_count) {
|
||||
page_alloc_count = get_page_manager()->m_CCache.m_nNumFreePages;
|
||||
}
|
||||
|
||||
} else {
|
||||
// alloc count would be negative, don't allocate
|
||||
page_alloc_count = 0;
|
||||
}
|
||||
|
||||
switch (m_Buffer.m_eBufferType) {
|
||||
case CBuffer::BufferType::NORMAL:
|
||||
case CBuffer::BufferType::REQUEST_NORMAL: {
|
||||
// don't do anything special
|
||||
} break;
|
||||
case CBuffer::BufferType::VAG:
|
||||
case CBuffer::BufferType::REQUEST_VAG: {
|
||||
// for VAG commands, we don't bother buffering more than the DMA transfer size
|
||||
int dma_xfer_size = ((ISO_VAGCommand*)m_Buffer.m_pIsoCmd)->xfer_size;
|
||||
if (dma_xfer_size) {
|
||||
ASSERT(dma_xfer_size > 0);
|
||||
int limit = (dma_xfer_size + 0x7fff) >> 0xf;
|
||||
if (page_alloc_count > limit) {
|
||||
ovrld_log(LogCategory::WARN, "File {} wants {} pages, but VAG DMA sizes limit us to ",
|
||||
m_FileDef->name.data, page_alloc_count, limit);
|
||||
lg::info("page count dma limit {} -> {}\n", page_alloc_count, limit);
|
||||
page_alloc_count = limit;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED(); // bad buffer type.
|
||||
}
|
||||
|
||||
if (page_alloc_count == 0) {
|
||||
return ret_plist;
|
||||
}
|
||||
|
||||
ovrld_log(LogCategory::PAGING, "File {} wants {} more pages in AllocPages.", m_FileDef->name.data,
|
||||
page_alloc_count);
|
||||
if (have_plist) {
|
||||
ret_plist = get_page_manager()->GrowPageList(m_Buffer.m_pPageList, page_alloc_count);
|
||||
} else {
|
||||
ret_plist = get_page_manager()->AllocPageList(page_alloc_count, 0);
|
||||
}
|
||||
|
||||
if (ret_plist) {
|
||||
m_Buffer.m_pPageList = ret_plist;
|
||||
if (!have_plist) {
|
||||
m_Buffer.m_pCurrentData = ret_plist->m_pFirstPage->m_pPageMemStart;
|
||||
}
|
||||
} else {
|
||||
ASSERT_NOT_REACHED(); // might be ok.
|
||||
}
|
||||
return ret_plist;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Free all pages and the page list.
|
||||
*/
|
||||
void CBaseFile::FreePages() {
|
||||
ASSERT(m_Buffer.m_eBufferType != CBuffer::BufferType::EBT_FREE);
|
||||
if (m_Buffer.m_pPageList) {
|
||||
get_page_manager()->FreePageList(m_Buffer.m_pPageList);
|
||||
}
|
||||
m_Buffer.m_pPageList = nullptr;
|
||||
}
|
||||
|
||||
} // namespace jak3
|
||||
@@ -1,76 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "game/overlord/jak3/isocommon.h"
|
||||
#include "game/overlord/jak3/pagemanager.h"
|
||||
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_basefile();
|
||||
|
||||
struct CPageList;
|
||||
struct ISOFileDef;
|
||||
struct ISO_Hdr;
|
||||
|
||||
constexpr int kDefaultBufferPageCount = 4;
|
||||
|
||||
/*!
|
||||
* Base class for a file that the ISO system is processing.
|
||||
* This represents an "open" file, and contains references to the buffer holding this file's data
|
||||
*/
|
||||
struct CBaseFile {
|
||||
CBaseFile();
|
||||
CBaseFile(const ISOFileDef* file, int semaphore);
|
||||
virtual ~CBaseFile() = default;
|
||||
|
||||
uint8_t* CheckPageBoundary();
|
||||
int InitBuffer(CBuffer::BufferType type, ISO_Hdr* msg);
|
||||
CPageList* AllocPages();
|
||||
void TerminateBuffer();
|
||||
void FreePages();
|
||||
|
||||
// buffer that stores some contents of this file
|
||||
CBuffer m_Buffer;
|
||||
|
||||
// the number of pages that were allocated for reading this file.
|
||||
u32 m_nNumPages;
|
||||
|
||||
// Metadata about the file
|
||||
const ISOFileDef* m_FileDef;
|
||||
|
||||
// The compression format used on the file
|
||||
enum class Kind {
|
||||
UNKNOWN = 0,
|
||||
NORMAL = 1,
|
||||
LZO_COMPRESSED = 2,
|
||||
} m_FileKind = Kind::UNKNOWN;
|
||||
|
||||
EIsoStatus m_Status = EIsoStatus::NONE_0;
|
||||
|
||||
// The expected read rate for streaming, used to prioritize CD reads. Can be 0 if unknown/not
|
||||
// applicable.
|
||||
int m_ReadRate = 0;
|
||||
|
||||
// Number of sectors that we should read in total, decided based on the file size and request from
|
||||
// user when they opened this file.
|
||||
int m_LengthPages = 0; // really, in pages...
|
||||
|
||||
// The current offset. (todo: is this for data we read, processed?)
|
||||
int m_PageOffset = 0;
|
||||
|
||||
// Semaphore that we should wait on before handing new data to the process callback.
|
||||
// Set to -1 if there is no semaphore.
|
||||
// (this is a bit of hack, only used for VAG streaming).
|
||||
int m_ProcessDataSemaphore = 0;
|
||||
|
||||
// virtual methods
|
||||
virtual EIsoStatus BeginRead() = 0;
|
||||
virtual EIsoStatus SyncRead() = 0;
|
||||
virtual void Close() = 0;
|
||||
virtual int RecoverPages(int num_pages) = 0;
|
||||
virtual int GetSector() = 0;
|
||||
// ??
|
||||
// ??
|
||||
// ??
|
||||
};
|
||||
} // namespace jak3
|
||||
@@ -1,26 +0,0 @@
|
||||
#include "basefilesystem.h"
|
||||
|
||||
#include "common/util/Assert.h"
|
||||
|
||||
#include "game/sce/iop.h"
|
||||
|
||||
using namespace iop;
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_basefilesystem() {}
|
||||
|
||||
CBaseFileSystem::CBaseFileSystem() {
|
||||
for (auto& sema : m_Sema) {
|
||||
sema = -1;
|
||||
|
||||
SemaParam param;
|
||||
param.max_count = 1;
|
||||
param.attr = 0;
|
||||
param.init_count = 1;
|
||||
param.option = 0;
|
||||
sema = CreateSema(¶m);
|
||||
if (sema < 0) {
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace jak3
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_basefilesystem();
|
||||
|
||||
struct ISOFileDef;
|
||||
struct ISOName;
|
||||
struct CBaseFile;
|
||||
struct VagDirEntry;
|
||||
|
||||
constexpr int kMaxOpenFiles = 16;
|
||||
|
||||
/*!
|
||||
* Base class for "FileSystem", which supports finding and opening files.
|
||||
* The only implementation we have is CISOCDFileSystem
|
||||
*/
|
||||
struct CBaseFileSystem {
|
||||
CBaseFileSystem();
|
||||
virtual ~CBaseFileSystem() = default;
|
||||
|
||||
// semaphores for processing open files
|
||||
int m_Sema[kMaxOpenFiles];
|
||||
|
||||
virtual int Init() = 0;
|
||||
// polldrive
|
||||
virtual ISOFileDef* Find(const char* name) = 0;
|
||||
virtual ISOFileDef* FindIN(const ISOName* name) = 0;
|
||||
virtual int GetLength(const ISOFileDef* file) = 0;
|
||||
virtual CBaseFile* Open(const ISOFileDef* file_def, int sector_offset, int file_kind) = 0;
|
||||
virtual CBaseFile* OpenWAD(const ISOFileDef* file_def, int page_offset) = 0;
|
||||
virtual VagDirEntry* FindVAGFile(const char* name) = 0;
|
||||
};
|
||||
} // namespace jak3
|
||||
@@ -1,526 +0,0 @@
|
||||
#include "dma.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/Assert.h"
|
||||
|
||||
#include "game/overlord/jak3/basefile.h"
|
||||
#include "game/overlord/jak3/overlord.h"
|
||||
#include "game/overlord/jak3/vag.h"
|
||||
#include "game/sce/iop.h"
|
||||
#include "game/sound/sdshim.h"
|
||||
#include "game/sound/sndshim.h"
|
||||
|
||||
#define VOICE_BIT(voice) (1 << ((voice) >> 1))
|
||||
|
||||
namespace jak3 {
|
||||
using namespace iop;
|
||||
namespace {
|
||||
|
||||
// most recent call to voice_trans_wrapper's arguments
|
||||
u32 g_voiceTransMode = 0;
|
||||
u32 g_voiceTransSize = 0;
|
||||
s16 g_voiceTransChannel = 0;
|
||||
const void* g_voiceTransAddr = nullptr;
|
||||
u32 g_voiceTransSpuAddr = 0;
|
||||
|
||||
// if we've started a transfer recently
|
||||
bool g_voiceTransRunning = false;
|
||||
// when that transfer was started
|
||||
u32 g_voiceTransTime = 0;
|
||||
|
||||
// despite the name, this is really an indicator that the SPU streaming system is waiting
|
||||
// for a SPU interrupt on completion.
|
||||
bool g_bSpuDmaBusy = false;
|
||||
int g_nSpuDmaChannel = 0;
|
||||
|
||||
ISO_VAGCommand* g_pDmaVagCmd = nullptr;
|
||||
ISO_VAGCommand* g_pDmaStereoVagCmd = nullptr;
|
||||
|
||||
int g_nSpuDmaChunks = 0;
|
||||
|
||||
std::array<DmaQueueEntry, 16> g_aSpuDmaQueue;
|
||||
int g_nSpuDmaQueueHead = 0;
|
||||
int g_nSpuDmaQueueTail = 0;
|
||||
int g_nSpuDmaQueueCount = 0;
|
||||
|
||||
struct DmaInterruptHandlerHack {
|
||||
s32 chan = 0;
|
||||
sceSdTransIntrHandler cb = nullptr;
|
||||
void* data;
|
||||
int countdown = 0;
|
||||
} g_DmaInterruptHack;
|
||||
|
||||
} // namespace
|
||||
|
||||
void jak3_overlord_init_globals_dma() {
|
||||
g_voiceTransMode = 0;
|
||||
g_voiceTransSize = 0;
|
||||
g_voiceTransChannel = 0;
|
||||
g_voiceTransAddr = nullptr;
|
||||
g_voiceTransSpuAddr = 0;
|
||||
g_voiceTransRunning = false;
|
||||
g_voiceTransTime = 0;
|
||||
g_bSpuDmaBusy = false;
|
||||
g_nSpuDmaChannel = 0;
|
||||
g_pDmaVagCmd = nullptr;
|
||||
g_pDmaStereoVagCmd = nullptr;
|
||||
g_nSpuDmaChunks = 0;
|
||||
g_aSpuDmaQueue = {};
|
||||
g_nSpuDmaQueueHead = 0;
|
||||
g_nSpuDmaQueueCount = 0;
|
||||
g_nSpuDmaQueueTail = 0;
|
||||
g_DmaInterruptHack = {};
|
||||
}
|
||||
|
||||
// The DMA callback hack below is used to defer dma completion "interrupts" until the next run
|
||||
// of the ISO Thread. This avoids re-entry type problems where the original design would set off
|
||||
// a dma transfer in the completion handler of the previous transfer, and expect a few instructions
|
||||
// to run after.
|
||||
|
||||
void uninstall_dma_intr() {
|
||||
g_DmaInterruptHack = {};
|
||||
}
|
||||
|
||||
void set_dma_intr_handler_hack(s32 chan, sceSdTransIntrHandler cb, void* data) {
|
||||
ASSERT(!g_DmaInterruptHack.cb);
|
||||
g_DmaInterruptHack.chan = chan;
|
||||
g_DmaInterruptHack.cb = cb;
|
||||
g_DmaInterruptHack.data = data;
|
||||
g_DmaInterruptHack.countdown = 10;
|
||||
}
|
||||
|
||||
int SPUDmaIntr(int channel, void* userdata);
|
||||
|
||||
void dma_intr_hack() {
|
||||
if (g_DmaInterruptHack.countdown) {
|
||||
g_DmaInterruptHack.countdown--;
|
||||
if (g_DmaInterruptHack.countdown == 0) {
|
||||
int chan = g_DmaInterruptHack.chan;
|
||||
void* data = g_DmaInterruptHack.data;
|
||||
g_DmaInterruptHack = {};
|
||||
SPUDmaIntr(chan, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function is used to set up a DMA transfer to SPU DMA.
|
||||
*
|
||||
* This wrapper was added very close to the end of Jak 3's development.
|
||||
*
|
||||
* I believe it basically checks for dma transfers that are somehow "dropped", and retries them.
|
||||
* Since I don't think our IOP framework will ever do this, we have an assert if the dropped logic
|
||||
* ever goes off.
|
||||
*/
|
||||
int voice_trans_wrapper(s16 chan, u32 mode, const void* iop_addr, u32 spu_addr, u32 size) {
|
||||
// remember the transfer settings. If there's a transfer in progress, so we can't start here,
|
||||
// we'll use these to start the transfer later.
|
||||
g_voiceTransMode = mode;
|
||||
g_voiceTransSize = size;
|
||||
g_voiceTransChannel = chan;
|
||||
g_voiceTransAddr = iop_addr;
|
||||
g_voiceTransSpuAddr = spu_addr;
|
||||
|
||||
if (g_voiceTransRunning) {
|
||||
// I claim this should never happen, and this is their workaround for a bug.
|
||||
ASSERT_NOT_REACHED();
|
||||
return -0xd2; // busy
|
||||
} else {
|
||||
g_voiceTransRunning = true;
|
||||
g_voiceTransTime = GetSystemTimeLow();
|
||||
return sceSdVoiceTrans(chan, mode, iop_addr, spu_addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
u32 read_rate_calc(u32 pitch) {
|
||||
u64 pitch1 = (pitch >> 3);
|
||||
u64 mult_result = pitch1 * 0x2492'4925ull;
|
||||
return mult_result >> 32;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The worst function of all time - the SPU DMA completion interrupt.
|
||||
*/
|
||||
int SPUDmaIntr(int channel, void* userdata) {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr enter! {} 0x{:x}", channel, (u64)userdata);
|
||||
|
||||
if (!g_bSpuDmaBusy) {
|
||||
// we got an interrupt, but weren't expecting it, or no longer have the need for the data.
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr exit - not busy");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (channel != g_nSpuDmaChannel) {
|
||||
// interrupt was for the wrong channel, somehow.
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr exit - not our channel ??");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// since we're in the completion handler, we know that there is no voice trans (SPU DMA) running.
|
||||
g_voiceTransRunning = false;
|
||||
|
||||
// This next block will handle updating the playback command that triggered this dma:
|
||||
if (g_pDmaVagCmd) {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDma for cmd {}", g_pDmaVagCmd->name);
|
||||
if (!g_pDmaStereoVagCmd) {
|
||||
// non-stereo audio
|
||||
|
||||
// set a flag to indicate even/odd number of chunks have been dma'd
|
||||
if ((g_nSpuDmaChunks & 1) == 0) {
|
||||
g_pDmaVagCmd->flags.dma_complete_even_chunk_count = 1;
|
||||
} else {
|
||||
g_pDmaVagCmd->flags.dma_complete_odd_chunk_count = 1;
|
||||
}
|
||||
} else {
|
||||
// stereo audio. This requires two uploads, one for left/right audio. If we've finished the
|
||||
// first, start the second one here:
|
||||
if (g_pDmaStereoVagCmd->xfer_size) {
|
||||
// parameters for second upload
|
||||
int chan = g_pDmaVagCmd->dma_chan;
|
||||
const u8* iop_addr = g_pDmaStereoVagCmd->dma_iop_mem_ptr;
|
||||
int size = g_pDmaStereoVagCmd->xfer_size;
|
||||
|
||||
// SPU addr - toggle the buffer based on stereo side:
|
||||
// TODO: better explanation of why this picks the correct buffer.
|
||||
int spu_addr;
|
||||
if ((g_nSpuDmaChunks & 1) == 0) {
|
||||
spu_addr = g_pDmaStereoVagCmd->stream_sram;
|
||||
} else {
|
||||
spu_addr = g_pDmaStereoVagCmd->stream_sram + 0x2000;
|
||||
}
|
||||
|
||||
// these lines reordered to possibly support immediate dma completion callback??
|
||||
|
||||
// clear flag so we know not to transfer the next part
|
||||
g_pDmaStereoVagCmd->xfer_size = 0;
|
||||
g_pDmaStereoVagCmd->dma_iop_mem_ptr = nullptr;
|
||||
|
||||
// start next transfer
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr starting stereo sibling transfer");
|
||||
set_dma_intr_handler_hack(g_nSpuDmaChannel, SPUDmaIntr, userdata);
|
||||
voice_trans_wrapper(chan, 0, iop_addr, spu_addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// second stereo upload completed - update double-buffering flags
|
||||
if ((g_nSpuDmaChunks & 1) == 0) {
|
||||
g_pDmaVagCmd->flags.dma_complete_even_chunk_count = 1;
|
||||
g_pDmaStereoVagCmd->flags.dma_complete_even_chunk_count = 1;
|
||||
} else {
|
||||
g_pDmaVagCmd->flags.dma_complete_odd_chunk_count = 1;
|
||||
g_pDmaStereoVagCmd->flags.dma_complete_odd_chunk_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if this is the first chunk, we'll start the actual audio here:
|
||||
// lg::warn("----------> interrupt with chunks {}\n", g_nSpuDmaChunks);
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr chunks count {}", g_nSpuDmaChunks);
|
||||
|
||||
if (g_nSpuDmaChunks == 0) {
|
||||
// compute pitch/playback rate
|
||||
int pitch = CalculateVAGPitch(g_pDmaVagCmd->pitch1, g_pDmaVagCmd->pitch_cmd);
|
||||
ASSERT(pitch == (pitch & 0xffff));
|
||||
|
||||
// inform the ISO system how fast we're reading
|
||||
if (g_pDmaVagCmd->m_pBaseFile) {
|
||||
// unlike actual playback, this is done with the pitch1 value from the file itself - so if
|
||||
// we speed up/slow down stuff in debug, it won't change streaming modes
|
||||
const int pitch_from_file =
|
||||
CalculateVAGPitch(g_pDmaVagCmd->pitch1_file, g_pDmaVagCmd->pitch_cmd);
|
||||
int rate = g_pDmaStereoVagCmd ? pitch_from_file * 0x2ee : pitch_from_file * 0x177;
|
||||
g_pDmaVagCmd->m_pBaseFile->m_ReadRate = read_rate_calc(rate);
|
||||
}
|
||||
|
||||
// start!
|
||||
u32 voice_mask = 0;
|
||||
if (!g_pDmaStereoVagCmd) {
|
||||
// forget any previous spu address
|
||||
g_pDmaVagCmd->current_spu_address = 0;
|
||||
|
||||
static_assert(SD_VA_SSA == 0x2040);
|
||||
static_assert(SD_S_KOFF == 0x1600);
|
||||
static_assert(SD_S_KON == 0x1500);
|
||||
|
||||
static_assert(SD_VP_ADSR1 == 0x300);
|
||||
static_assert(SD_VP_ADSR2 == 0x400);
|
||||
static_assert(SD_VP_PITCH == 0x200);
|
||||
|
||||
// before touching SPU2 hardware, wait for voice safety:
|
||||
BlockUntilVoiceSafe(g_pDmaVagCmd->voice, 0x900);
|
||||
|
||||
// set address and ADSR settings
|
||||
sceSdSetAddr(g_pDmaVagCmd->voice | SD_VA_SSA, g_pDmaVagCmd->stream_sram + 0x30);
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_ADSR1, 0xff);
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_ADSR2, 0x1fc0);
|
||||
if (g_pDmaVagCmd->flags.paused) {
|
||||
pitch = 0;
|
||||
}
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_PITCH, pitch);
|
||||
voice_mask = VOICE_BIT(g_pDmaVagCmd->voice);
|
||||
} else {
|
||||
// forget any previous spu address
|
||||
g_pDmaVagCmd->current_spu_address = 0;
|
||||
g_pDmaStereoVagCmd->current_spu_address = 0;
|
||||
|
||||
// wait for voices to be safe to adjust
|
||||
BlockUntilVoiceSafe(g_pDmaVagCmd->voice, 0x900);
|
||||
BlockUntilVoiceSafe(g_pDmaStereoVagCmd->voice, 0x900);
|
||||
|
||||
// set voice params
|
||||
sceSdSetAddr(g_pDmaVagCmd->voice | SD_VA_SSA, g_pDmaVagCmd->stream_sram + 0x30);
|
||||
sceSdSetAddr(g_pDmaStereoVagCmd->voice | SD_VA_SSA, g_pDmaStereoVagCmd->stream_sram + 0x30);
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_ADSR1, 0xff);
|
||||
sceSdSetParam(g_pDmaStereoVagCmd->voice | SD_VP_ADSR1, 0xff);
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_ADSR2, 0x1fc0);
|
||||
sceSdSetParam(g_pDmaStereoVagCmd->voice | SD_VP_ADSR2, 0x1fc0);
|
||||
if (g_pDmaVagCmd->flags.paused) {
|
||||
pitch = 0;
|
||||
}
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_PITCH, pitch);
|
||||
sceSdSetParam(g_pDmaStereoVagCmd->voice | SD_VP_PITCH, pitch);
|
||||
voice_mask = VOICE_BIT(g_pDmaVagCmd->voice) | VOICE_BIT(g_pDmaStereoVagCmd->voice);
|
||||
}
|
||||
|
||||
// do key-on or key-off
|
||||
if (g_pDmaVagCmd->flags.paused) {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr chunks 0, key off");
|
||||
BlockUntilAllVoicesSafe();
|
||||
sceSdSetSwitch(SD_S_KOFF | (g_pDmaVagCmd->voice & 1), voice_mask);
|
||||
} else {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr chunks 0, key on");
|
||||
BlockUntilAllVoicesSafe();
|
||||
sceSdSetSwitch(SD_S_KON | (g_pDmaVagCmd->voice & 1), voice_mask);
|
||||
}
|
||||
|
||||
// remember the time of the key-on/off. This is used to avoid sending voice commands
|
||||
// quickly, which somehow confuses the sound hardware.
|
||||
auto sys_time = GetSystemTimeLow();
|
||||
MarkVoiceKeyedOnOff(g_pDmaVagCmd->voice, sys_time);
|
||||
if (g_pDmaStereoVagCmd) {
|
||||
MarkVoiceKeyedOnOff(g_pDmaStereoVagCmd->voice, sys_time);
|
||||
}
|
||||
} else if (g_nSpuDmaChunks == 1) {
|
||||
g_pDmaVagCmd->flags.saw_chunks1 = 1;
|
||||
if (g_pDmaStereoVagCmd) {
|
||||
g_pDmaStereoVagCmd->flags.saw_chunks1 = 1;
|
||||
}
|
||||
|
||||
if (g_pDmaVagCmd->flags.paused) {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr chunks 1, pausing");
|
||||
u32 voice_mask = 0;
|
||||
if (!g_pDmaStereoVagCmd) {
|
||||
// pause by setting pitches to 0
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_PITCH, 0);
|
||||
BlockUntilVoiceSafe(VOICE_BIT(g_pDmaVagCmd->voice), 0x900);
|
||||
voice_mask = VOICE_BIT(g_pDmaVagCmd->voice);
|
||||
} else {
|
||||
sceSdSetParam(g_pDmaStereoVagCmd->voice | SD_VP_PITCH, 0);
|
||||
sceSdSetParam(g_pDmaVagCmd->voice | SD_VP_PITCH, 0);
|
||||
BlockUntilVoiceSafe(VOICE_BIT(g_pDmaVagCmd->voice), 0x900);
|
||||
BlockUntilVoiceSafe(VOICE_BIT(g_pDmaStereoVagCmd->voice), 0x900);
|
||||
voice_mask = VOICE_BIT(g_pDmaVagCmd->voice) | VOICE_BIT(g_pDmaStereoVagCmd->voice);
|
||||
}
|
||||
|
||||
// switch off
|
||||
BlockUntilAllVoicesSafe();
|
||||
sceSdSetSwitch(SD_S_KOFF | (g_pDmaVagCmd->voice & 1), voice_mask);
|
||||
auto sys_time = GetSystemTimeLow();
|
||||
MarkVoiceKeyedOnOff(g_pDmaVagCmd->voice, sys_time);
|
||||
if (g_pDmaStereoVagCmd) {
|
||||
MarkVoiceKeyedOnOff(g_pDmaStereoVagCmd->voice, sys_time);
|
||||
}
|
||||
} else {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr chunks 1, unpausing by call to UnPauseVAG");
|
||||
g_pDmaVagCmd->flags.paused = 1;
|
||||
UnPauseVAG(g_pDmaVagCmd);
|
||||
}
|
||||
}
|
||||
|
||||
// now that we've processed the command from this interrupt, mark it as safe to modify
|
||||
g_pDmaVagCmd->safe_to_modify_dma = 1;
|
||||
if (g_pDmaStereoVagCmd) {
|
||||
g_pDmaStereoVagCmd->safe_to_modify_dma = 1;
|
||||
}
|
||||
// and forget it!
|
||||
g_pDmaVagCmd = nullptr;
|
||||
g_pDmaStereoVagCmd = nullptr;
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr dma handling of VAG cmd is complete");
|
||||
}
|
||||
|
||||
// release ref on this page. (interestingly, not a dma ref...)
|
||||
if (userdata) {
|
||||
CPage* page = (CPage*)userdata;
|
||||
int ret = page->ReleaseRef();
|
||||
ASSERT(ret >= 0);
|
||||
}
|
||||
|
||||
// now - see if we have another queued dma transfer
|
||||
ASSERT(g_nSpuDmaQueueCount >= 0);
|
||||
if (g_nSpuDmaQueueCount == 0) {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr dma queue is empty, disabling interrupt");
|
||||
// we're done!
|
||||
// set_dma_intr_handler_hack(channel, nullptr, nullptr);
|
||||
uninstall_dma_intr();
|
||||
// if (-1 < channel) {
|
||||
// snd_FreeSPUDMA(channel);
|
||||
// }
|
||||
g_bSpuDmaBusy = false;
|
||||
} else {
|
||||
ovrld_log(LogCategory::SPU_DMA_STR,
|
||||
"SPUDmaIntr dma queue is not empty, preparing to run {} ({} pending)",
|
||||
g_nSpuDmaQueueHead, g_nSpuDmaQueueCount);
|
||||
// nope, more dma to run
|
||||
auto* next_xfer = &g_aSpuDmaQueue[g_nSpuDmaQueueHead];
|
||||
|
||||
// set up the next interrupt handler
|
||||
set_dma_intr_handler_hack(channel, SPUDmaIntr, next_xfer->user_data);
|
||||
|
||||
// args for the dma transfer
|
||||
int next_chan = channel;
|
||||
int next_mode = 0;
|
||||
const void* next_iop = next_xfer->iop_mem;
|
||||
u32 next_spu = next_xfer->spu_addr;
|
||||
u32 next_length = next_xfer->length;
|
||||
|
||||
// load up the commands to handle
|
||||
g_pDmaVagCmd = next_xfer->command;
|
||||
g_pDmaStereoVagCmd = nullptr;
|
||||
if (g_pDmaVagCmd) {
|
||||
g_pDmaStereoVagCmd = g_pDmaVagCmd->stereo_sibling;
|
||||
}
|
||||
g_nSpuDmaChunks = next_xfer->num_isobuffered_chunks;
|
||||
|
||||
// advance the queue!
|
||||
g_nSpuDmaQueueCount = g_nSpuDmaQueueCount + -1;
|
||||
g_nSpuDmaQueueHead = g_nSpuDmaQueueHead + 1;
|
||||
if (0xf < g_nSpuDmaQueueHead) {
|
||||
g_nSpuDmaQueueHead = 0;
|
||||
}
|
||||
|
||||
// start the next one!
|
||||
// set_dma_intr_handler_hack(g_nSpuDmaChannel, SPUDmaIntr, userdata);
|
||||
voice_trans_wrapper(next_chan, next_mode, next_iop, next_spu, next_length);
|
||||
}
|
||||
|
||||
ovrld_log(LogCategory::SPU_DMA_STR, "SPUDmaIntr exit - end of function");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Start DMA to EE.
|
||||
*/
|
||||
void DMA_SendToEE(void* ee_dest,
|
||||
const void* iop_src,
|
||||
u32 length,
|
||||
void callback(void*),
|
||||
void* callback_arg) {
|
||||
ASSERT(iop_src);
|
||||
ASSERT(ee_dest);
|
||||
ASSERT(((uintptr_t)iop_src & 3) == 0);
|
||||
ASSERT(((uintptr_t)ee_dest & 0xf) == 0);
|
||||
ASSERT(length < 0xffff0);
|
||||
sceSifDmaData cmd; // DMA settings
|
||||
|
||||
// setup command
|
||||
cmd.mode = 0;
|
||||
cmd.data = iop_src;
|
||||
cmd.addr = ee_dest;
|
||||
cmd.size = length;
|
||||
|
||||
// instant DMA
|
||||
// ovrld_log(LogCategory::EE_DMA, "DMA_SendToEE: 0x{:x}, size {}", (u64)ee_dest, length);
|
||||
sceSifSetDma(&cmd, 1);
|
||||
|
||||
// for now, we'll do the callback here, but I bet it will cause problems
|
||||
if (callback) {
|
||||
callback(callback_arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Start DMA transfer to SPU. Despite the name, this does not actually "sync" - the transfer will
|
||||
* be ongoing. If there is an ongoing transfer when this is called, the transfer will be queued.
|
||||
*/
|
||||
int DMA_SendToSPUAndSync(const u8* iop_mem,
|
||||
int length,
|
||||
int spu_addr,
|
||||
ISO_VAGCommand* cmd,
|
||||
void* user_data) {
|
||||
// CpuSuspendIntr(local_28);
|
||||
int ret = 1;
|
||||
bool defer = false;
|
||||
|
||||
ovrld_log(LogCategory::SPU_DMA_STR,
|
||||
"DMA to SPU requested for {}, {} bytes to 0x{:x}, currently busy? {}",
|
||||
cmd ? cmd->name : "NO-CMD", length, spu_addr, g_bSpuDmaBusy);
|
||||
if (g_bSpuDmaBusy == 0) {
|
||||
// not busy, we can actually start dma now.
|
||||
g_nSpuDmaChannel = snd_GetFreeSPUDMA();
|
||||
if (g_nSpuDmaChannel == -1) {
|
||||
return 0;
|
||||
}
|
||||
// set globals for DMA processing
|
||||
if (cmd) {
|
||||
g_nSpuDmaChunks = cmd->num_isobuffered_chunks;
|
||||
g_pDmaStereoVagCmd = cmd->stereo_sibling;
|
||||
g_pDmaVagCmd = cmd;
|
||||
}
|
||||
|
||||
} else {
|
||||
// busy, need to queue the dma
|
||||
ASSERT(g_nSpuDmaQueueCount <= (int)g_aSpuDmaQueue.size());
|
||||
|
||||
// set values:
|
||||
g_aSpuDmaQueue[g_nSpuDmaQueueTail].length = length;
|
||||
g_aSpuDmaQueue[g_nSpuDmaQueueTail].spu_addr = spu_addr;
|
||||
g_aSpuDmaQueue[g_nSpuDmaQueueTail].user_data = user_data;
|
||||
g_aSpuDmaQueue[g_nSpuDmaQueueTail].num_isobuffered_chunks =
|
||||
cmd ? cmd->num_isobuffered_chunks : 0;
|
||||
g_aSpuDmaQueue[g_nSpuDmaQueueTail].command = cmd;
|
||||
g_aSpuDmaQueue[g_nSpuDmaQueueTail].iop_mem = iop_mem;
|
||||
g_nSpuDmaQueueCount = g_nSpuDmaQueueCount + 1;
|
||||
g_nSpuDmaQueueTail = g_nSpuDmaQueueTail + 1;
|
||||
if (0xf < g_nSpuDmaQueueTail) {
|
||||
g_nSpuDmaQueueTail = 0;
|
||||
}
|
||||
defer = true;
|
||||
}
|
||||
|
||||
// set up the stereo command
|
||||
if (cmd) {
|
||||
cmd->safe_to_modify_dma = 0;
|
||||
auto* stereo = cmd->stereo_sibling;
|
||||
if (stereo) {
|
||||
stereo->num_isobuffered_chunks = cmd->num_isobuffered_chunks;
|
||||
stereo->dma_iop_mem_ptr = iop_mem + length;
|
||||
cmd->dma_chan = g_nSpuDmaChannel;
|
||||
stereo->xfer_size = length;
|
||||
}
|
||||
}
|
||||
|
||||
// kick off dma, if we decided not to queue.
|
||||
if (!defer) {
|
||||
g_bSpuDmaBusy = true;
|
||||
set_dma_intr_handler_hack(g_nSpuDmaChannel, SPUDmaIntr, user_data);
|
||||
voice_trans_wrapper(g_nSpuDmaChannel, 0, iop_mem, spu_addr, length);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Run a dma transfer that was delayed or dropped.
|
||||
*/
|
||||
void RunDeferredVoiceTrans() {
|
||||
// only if there's a currently happening transfer.
|
||||
if (g_voiceTransRunning) {
|
||||
if (GetSystemTimeLow() - g_voiceTransTime > 0x384000) {
|
||||
ovrld_log(LogCategory::WARN, "DeferredVoiceTrans has detected hung dma... expect problems.");
|
||||
// original game also check sceSdVoiceTransStatus here, we'll possibly need to mess with this
|
||||
// if we delay dma completion interrupts...
|
||||
g_voiceTransRunning = false;
|
||||
voice_trans_wrapper(g_voiceTransChannel, g_voiceTransMode, g_voiceTransAddr,
|
||||
g_voiceTransSpuAddr, g_voiceTransSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace jak3
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_dma();
|
||||
struct ISO_VAGCommand;
|
||||
|
||||
int voice_trans_wrapper(s16 chan, u32 mode, const void* iop_addr, u32 spu_addr, u32 size);
|
||||
void DMA_SendToEE(void* ee_dest,
|
||||
const void* iop_src,
|
||||
u32 length,
|
||||
void callback(void*),
|
||||
void* callback_arg);
|
||||
int DMA_SendToSPUAndSync(const u8* iop_mem,
|
||||
int length,
|
||||
int spu_addr,
|
||||
ISO_VAGCommand* cmd,
|
||||
void* user_data);
|
||||
void RunDeferredVoiceTrans();
|
||||
struct ISO_VAGCommand;
|
||||
|
||||
struct DmaQueueEntry {
|
||||
ISO_VAGCommand* command = nullptr;
|
||||
const void* iop_mem = nullptr;
|
||||
u32 spu_addr = 0;
|
||||
u32 length = 0;
|
||||
void* user_data = nullptr;
|
||||
u32 num_isobuffered_chunks = 0;
|
||||
};
|
||||
void dma_intr_hack();
|
||||
} // namespace jak3
|
||||
@@ -1,583 +0,0 @@
|
||||
#include "dvd_driver.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include "common/log/log.h"
|
||||
#include "common/util/Assert.h"
|
||||
#include "common/util/FileUtil.h"
|
||||
|
||||
#include "game/overlord/jak3/isocommon.h"
|
||||
#include "game/overlord/jak3/overlord.h"
|
||||
#include "game/sce/iop.h"
|
||||
|
||||
namespace jak3 {
|
||||
using namespace iop;
|
||||
std::unique_ptr<CDvdDriver> g_DvdDriver;
|
||||
s32 g_nDvdDriverThread = -1;
|
||||
|
||||
void jak3_overlord_init_globals_dvd_driver() {
|
||||
g_DvdDriver = std::make_unique<CDvdDriver>();
|
||||
g_nDvdDriverThread = -1;
|
||||
}
|
||||
|
||||
CDvdDriver* get_driver() {
|
||||
return g_DvdDriver.get();
|
||||
}
|
||||
|
||||
CMsg::CMsg(jak3::CMsg::MsgKind msg) : m_msg(msg) {
|
||||
m_ret = 1;
|
||||
m_thread = GetThreadId();
|
||||
}
|
||||
|
||||
int CMsg::send() {
|
||||
// note: changed from passing data
|
||||
// and removed corresponding -4 to skip back past the vtable in DVD thread
|
||||
// (what were they thinking?)
|
||||
s32 ret = SendMbx(get_driver()->msgbox, this);
|
||||
if (ret == 0) {
|
||||
get_driver()->KickDvdThread();
|
||||
SleepThread();
|
||||
return m_ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// CMsgLock::CMsgLock() : CMsg(CMsg::MsgKind::LOCK) {}
|
||||
//
|
||||
// void CMsgLock::handler() {
|
||||
// get_driver()->Lock();
|
||||
// m_ret = 0;
|
||||
// }
|
||||
|
||||
// CMsgReadRaw::CMsgReadRaw(jak3::BlockParams* params) : CMsg(CMsg::MsgKind::READ_RAW) {
|
||||
// m_block_params = *params;
|
||||
// }
|
||||
//
|
||||
// void CMsgReadRaw::handler() {
|
||||
// m_ret = get_driver()->ReadDirect(&m_block_params);
|
||||
// }
|
||||
|
||||
CMsgCancelRead::CMsgCancelRead(jak3::CDescriptor* desc) : CMsg(CMsg::MsgKind::CANCEL_READ) {
|
||||
m_desc = desc;
|
||||
}
|
||||
|
||||
void CMsgCancelRead::handler() {
|
||||
get_driver()->CancelRead(m_desc);
|
||||
m_ret = 0;
|
||||
}
|
||||
|
||||
u32 DvdThread();
|
||||
|
||||
CDvdDriver::CDvdDriver() {
|
||||
fifo_entry_sema = -1;
|
||||
current_thread_priority = 0x13;
|
||||
disk_type = 5;
|
||||
tray_flag = 1;
|
||||
// m_nLockCount = 0;
|
||||
event_flag = -1;
|
||||
fifo_access_sema = -1;
|
||||
tray_flag2 = 1;
|
||||
initialized = 0;
|
||||
m_nNumFifoEntries = 0;
|
||||
ring_head = 0;
|
||||
ring_tail = 0;
|
||||
read_in_progress = 0;
|
||||
callback = nullptr;
|
||||
// locked = false;
|
||||
trayflag3 = 0;
|
||||
m_nDvdThreadAccessSemaCount = 0;
|
||||
memset(ring, 0, sizeof(Block) * 16);
|
||||
}
|
||||
|
||||
void CDvdDriver::Initialize() {
|
||||
if (!initialized) {
|
||||
*this = {};
|
||||
ThreadParam thread_param;
|
||||
thread_param.attr = 0x2000000;
|
||||
// mbox_param.option = gDvdDriverThreadOptions; // ???
|
||||
thread_param.entry = DvdThread;
|
||||
thread_param.stackSize = 0x800;
|
||||
thread_param.initPriority = 0x13;
|
||||
thread_param.option = 0;
|
||||
strcpy(thread_param.name, "dvd");
|
||||
// mbox_param.attr = (int)PTR_DvdThread_00015c98; // ???
|
||||
g_nDvdDriverThread = CreateThread(&thread_param);
|
||||
ASSERT(g_nDvdDriverThread >= 0);
|
||||
|
||||
SemaParam sema_param;
|
||||
sema_param.attr = 0;
|
||||
sema_param.init_count = 1;
|
||||
sema_param.max_count = 1;
|
||||
sema_param.option = 0;
|
||||
fifo_access_sema = CreateSema(&sema_param);
|
||||
ASSERT(fifo_access_sema >= 0);
|
||||
sema_param.max_count = 0x10;
|
||||
sema_param.attr = 0;
|
||||
sema_param.init_count = 0x10;
|
||||
sema_param.option = 0;
|
||||
fifo_entry_sema = CreateSema(&sema_param);
|
||||
ASSERT(fifo_entry_sema >= 0);
|
||||
MbxParam mbox_param;
|
||||
mbox_param.attr = 0;
|
||||
mbox_param.option = 0;
|
||||
msgbox = CreateMbx(&mbox_param);
|
||||
ASSERT(msgbox >= 0);
|
||||
|
||||
EventFlagParam param;
|
||||
param.attr = 0;
|
||||
param.option = 0;
|
||||
param.init_pattern = 0;
|
||||
event_flag = CreateEventFlag(¶m);
|
||||
ASSERT(event_flag >= 0);
|
||||
StartThread(g_nDvdDriverThread, 0); // this...
|
||||
}
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
void CDvdDriver::SetDriverCallback(std::function<void(int)> f) {
|
||||
callback = f;
|
||||
}
|
||||
|
||||
// GetDriveCallback
|
||||
|
||||
// Poll - would kick the thread...
|
||||
|
||||
// void CDvdDriver::Lock() {
|
||||
// ASSERT_NOT_REACHED();
|
||||
// if (GetThreadId() == g_nDvdDriverThread) {
|
||||
// m_nLockCount++;
|
||||
// locked = true;
|
||||
// // needs break HACK
|
||||
// needs_break = false;
|
||||
// } else {
|
||||
// CMsgLock lock;
|
||||
// lock.send();
|
||||
// }
|
||||
// }
|
||||
|
||||
// Read
|
||||
|
||||
int CDvdDriver::ReadMultiple(CDescriptor* descriptor,
|
||||
int* pages_read_out,
|
||||
BlockParams* params,
|
||||
int num_blocks,
|
||||
bool block_if_queue_full) {
|
||||
*pages_read_out = 0;
|
||||
s32 ret = 1;
|
||||
|
||||
// check block parameters are reasonable
|
||||
if (ValidateBlockParams(params, num_blocks) != 0) {
|
||||
bool from_dvd_thread = GetThreadId() == g_nDvdDriverThread;
|
||||
if (from_dvd_thread) {
|
||||
// there is a setting to control if this function should block if there are too many
|
||||
// queued reads. If the is called from the DVD thread, then this would deadlock.
|
||||
// the original game ignored the block argument, but I'm asserting
|
||||
block_if_queue_full = 0;
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
ovrld_log(LogCategory::DRIVER, "[driver] ReadMultiple (from our thread? {}) num_blocks {}",
|
||||
from_dvd_thread, num_blocks);
|
||||
|
||||
ret = 0;
|
||||
if (0 < num_blocks) {
|
||||
// loop, until we've done all the requested reads.
|
||||
do {
|
||||
s32 acquired_slots = 0;
|
||||
if (0 < num_blocks) {
|
||||
// loop to try to get up to num_blocks slots in the fifo
|
||||
// but, if we get less, we'll take that too
|
||||
do {
|
||||
if (PollSema(this->fifo_entry_sema) == -0x1a3)
|
||||
break;
|
||||
acquired_slots = acquired_slots + 1;
|
||||
} while (acquired_slots < num_blocks);
|
||||
}
|
||||
ovrld_log(LogCategory::DRIVER, "[driver] ReadMultiple acquired {} slots in ring",
|
||||
acquired_slots);
|
||||
|
||||
// if we are blocking, and we acquired no slots, then we'll wait here until we get one slot.
|
||||
if ((block_if_queue_full != 0) && (acquired_slots < 1)) {
|
||||
ovrld_log(LogCategory::DRIVER, "[driver] ring is full, blocking!");
|
||||
acquired_slots = 1; // the one we'll get from the WaitSema below
|
||||
do {
|
||||
} while (WaitSema(fifo_entry_sema) != 0);
|
||||
}
|
||||
|
||||
// lock, now that we've gotten the slots
|
||||
AcquireFIFOSema(from_dvd_thread);
|
||||
num_blocks = num_blocks - acquired_slots;
|
||||
|
||||
// if we didn't get any slots, bail.
|
||||
if (acquired_slots < 1) {
|
||||
ovrld_log(LogCategory::DRIVER, "[driver] ring is full, bailing!");
|
||||
ReleaseFIFOSema(from_dvd_thread);
|
||||
if (0 < *pages_read_out) {
|
||||
KickDvdThread();
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
// loop, updating the ring for each slot we aquired
|
||||
do {
|
||||
auto* slot = ring + ring_tail;
|
||||
ovrld_log(LogCategory::DRIVER, "[driver] inserting in ring slot {}", ring_tail);
|
||||
|
||||
ring_tail++;
|
||||
if (0xf < ring_tail) {
|
||||
ring_tail = 0;
|
||||
}
|
||||
m_nNumFifoEntries++;
|
||||
|
||||
auto* tail = descriptor->m_pTail;
|
||||
slot->descriptor = descriptor;
|
||||
slot->params = params[*pages_read_out];
|
||||
*pages_read_out = (*pages_read_out) + 1;
|
||||
if (!tail) {
|
||||
descriptor->m_pHead = slot;
|
||||
} else {
|
||||
tail->next = slot;
|
||||
}
|
||||
acquired_slots = acquired_slots + -1;
|
||||
descriptor->m_pTail = slot;
|
||||
slot->next = nullptr;
|
||||
} while (acquired_slots != 0);
|
||||
ReleaseFIFOSema(from_dvd_thread);
|
||||
KickDvdThread();
|
||||
ret = 0;
|
||||
} while (0 < num_blocks);
|
||||
}
|
||||
} else {
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CDvdDriver::CancelRead(jak3::CDescriptor* desc) {
|
||||
if (GetThreadId() == g_nDvdDriverThread) {
|
||||
AcquireFIFOSema(true);
|
||||
if ((read_in_progress != 0) && (ring[ring_head].descriptor == desc)) {
|
||||
// while (iVar1 = sceCdBreak(), iVar1 == 0) {
|
||||
// DelayThread(8000);
|
||||
// sceCdSync(0);
|
||||
// }
|
||||
// sceCdSync(0);
|
||||
read_in_progress = 0;
|
||||
}
|
||||
|
||||
Block* iter = desc->m_pHead;
|
||||
Block* tail = desc->m_pTail;
|
||||
while (iter) {
|
||||
if (iter->descriptor) {
|
||||
CompletionHandler(iter, 6);
|
||||
}
|
||||
iter->descriptor = nullptr;
|
||||
iter->next = nullptr;
|
||||
if (iter == tail)
|
||||
break;
|
||||
iter = desc->m_pHead;
|
||||
}
|
||||
|
||||
if (desc->m_pTail == tail) {
|
||||
desc->m_pTail = nullptr;
|
||||
}
|
||||
ReleaseFIFOSema(true);
|
||||
} else {
|
||||
CMsgCancelRead msg(desc);
|
||||
msg.send();
|
||||
}
|
||||
}
|
||||
|
||||
s32 CDvdDriver::ValidateBlockParams(jak3::BlockParams* params, int num_params) {
|
||||
if (!params) {
|
||||
lg::die("Invalid BlockParams: nullptr");
|
||||
return 0;
|
||||
}
|
||||
if (num_params < 1) {
|
||||
lg::die("Invalid BlockParams: size == 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_params; i++) {
|
||||
auto& p = params[i];
|
||||
if (p.destination == nullptr) {
|
||||
lg::die("Invalid BlockParams: {} had nullptr dest", i);
|
||||
return 0;
|
||||
}
|
||||
int kMaxSector = 1000000;
|
||||
if (p.sector_num > kMaxSector) {
|
||||
// this is just a sanity check - if we ever have larger files this is okay to increase.
|
||||
lg::die("Invalid BlockParams: {} had sector num {}", i, p.sector_num);
|
||||
return 0;
|
||||
}
|
||||
if (p.num_sectors > 0x1d0) {
|
||||
lg::die("Invalid BlockParams: {} had sector count {}", i, p.num_sectors);
|
||||
return 0;
|
||||
}
|
||||
if (!p.file_def) {
|
||||
lg::die("Invalid BlockParams: {} had no file", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CDvdDriver::KickDvdThread() {
|
||||
while (SetEventFlag(event_flag, 1)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
int CDvdDriver::AcquireFIFOSema(bool from_dvd_thread) {
|
||||
int iVar1;
|
||||
int iVar2;
|
||||
|
||||
if ((from_dvd_thread != 0) &&
|
||||
(iVar2 = m_nDvdThreadAccessSemaCount, m_nDvdThreadAccessSemaCount = iVar2 + 1, 0 < iVar2)) {
|
||||
return 0;
|
||||
}
|
||||
iVar1 = WaitSema(this->fifo_access_sema);
|
||||
iVar2 = 0;
|
||||
if ((iVar1 != 0) && (iVar2 = iVar1, from_dvd_thread != 0)) {
|
||||
m_nDvdThreadAccessSemaCount = m_nDvdThreadAccessSemaCount + -1;
|
||||
iVar2 = iVar1;
|
||||
}
|
||||
return iVar2;
|
||||
}
|
||||
|
||||
int CDvdDriver::ReleaseFIFOSema(bool from_dvd_thread) {
|
||||
int iVar1;
|
||||
int iVar2;
|
||||
|
||||
if (from_dvd_thread != 0) {
|
||||
iVar2 = m_nDvdThreadAccessSemaCount + -1;
|
||||
if (m_nDvdThreadAccessSemaCount < 1) {
|
||||
return -0x1a4;
|
||||
}
|
||||
m_nDvdThreadAccessSemaCount = iVar2;
|
||||
if (0 < iVar2) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
iVar1 = SignalSema(fifo_access_sema);
|
||||
iVar2 = 0;
|
||||
if ((iVar1 != 0) && (iVar2 = iVar1, from_dvd_thread != 0)) {
|
||||
m_nDvdThreadAccessSemaCount = m_nDvdThreadAccessSemaCount + 1;
|
||||
iVar2 = iVar1;
|
||||
}
|
||||
return iVar2;
|
||||
}
|
||||
|
||||
/*!
|
||||
* PC port added function to actually do a read of a block.
|
||||
*/
|
||||
void CDvdDriver::read_from_file(const jak3::Block* block) {
|
||||
const auto* fd = block->params.file_def;
|
||||
ASSERT(fd);
|
||||
FileCacheEntry* selected_entry = nullptr;
|
||||
|
||||
// get a cache entry
|
||||
for (auto& entry : m_file_cache) {
|
||||
// if we already opened this file, use that
|
||||
if (entry.def == fd) {
|
||||
selected_entry = &entry;
|
||||
break;
|
||||
}
|
||||
|
||||
// otherwise pick the least recently used
|
||||
if (!selected_entry) {
|
||||
selected_entry = &entry;
|
||||
} else {
|
||||
if (selected_entry->last_use_count > entry.last_use_count) {
|
||||
selected_entry = &entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// open a new file if needed
|
||||
if (selected_entry->def != fd) {
|
||||
lg::debug("CDvdDriver swapping files {} - > {}",
|
||||
selected_entry->def ? selected_entry->def->name.data : "NONE", fd->name.data);
|
||||
if (selected_entry->def) {
|
||||
fclose(selected_entry->fp);
|
||||
}
|
||||
|
||||
selected_entry->def = fd;
|
||||
selected_entry->fp = file_util::open_file(fd->full_path, "rb");
|
||||
if (!selected_entry->fp) {
|
||||
lg::die("Failed to open {} {}", fd->full_path, strerror(errno));
|
||||
}
|
||||
selected_entry->offset_in_file = 0;
|
||||
}
|
||||
|
||||
// increment use counter
|
||||
selected_entry->last_use_count = m_file_cache_counter++;
|
||||
|
||||
const u64 desired_offset = block->params.sector_num * 0x800;
|
||||
|
||||
// see if we're reading entirely past the end of the file
|
||||
if (desired_offset >= fd->length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected_entry->offset_in_file != desired_offset) {
|
||||
lg::debug("CDvdDriver jumping in file {}: {} -> {}", fd->name.data,
|
||||
selected_entry->offset_in_file, desired_offset);
|
||||
if (fseek(selected_entry->fp, desired_offset, SEEK_SET)) {
|
||||
ASSERT_NOT_REACHED_MSG("Failed to fseek");
|
||||
}
|
||||
selected_entry->offset_in_file = desired_offset;
|
||||
}
|
||||
|
||||
// read
|
||||
s64 read_length = block->params.num_sectors * 0x800;
|
||||
s64 extra_length = read_length + desired_offset - fd->length;
|
||||
if (extra_length > 0) {
|
||||
read_length -= extra_length;
|
||||
}
|
||||
auto ret = fread(block->params.destination, read_length, 1, selected_entry->fp);
|
||||
if (ret != 1) {
|
||||
lg::die("Failed to read {} {}, size {} of {} (ret {})", fd->full_path, strerror(errno),
|
||||
read_length, fd->length, ret);
|
||||
}
|
||||
selected_entry->offset_in_file += read_length;
|
||||
}
|
||||
|
||||
u32 DvdThread() {
|
||||
auto* driver = get_driver();
|
||||
|
||||
while (true) {
|
||||
// Poll for messages
|
||||
CMsg* msg = nullptr;
|
||||
while (true) {
|
||||
int poll_status = PollMbx((MsgPacket**)&msg, driver->msgbox);
|
||||
if (poll_status || !msg) {
|
||||
break;
|
||||
}
|
||||
// run message code
|
||||
msg->handler();
|
||||
// wake the waiting thread.
|
||||
WakeupThread(msg->m_thread);
|
||||
}
|
||||
|
||||
bool completed = false;
|
||||
|
||||
// if a read is in progress, wait for it to finish.
|
||||
if (driver->read_in_progress) {
|
||||
// TODO: if we switch to async reads, this is where we'd want to sync.
|
||||
// sceCdSync(0);
|
||||
completed = true;
|
||||
// error checking
|
||||
}
|
||||
|
||||
driver->AcquireFIFOSema(true);
|
||||
// error handling
|
||||
|
||||
// handle ring book-keeping.
|
||||
// note that these are somewhat double-buffered - we'll sync on read i-1, start read i, then
|
||||
// run the completion handler for read i - 1.
|
||||
// the completion is what actually removes stuff from the ring.
|
||||
|
||||
s32 fifo_slots_freed = completed ? 1 : 0;
|
||||
s32 ring_entry = driver->ring_head + (completed ? 1 : 0);
|
||||
if (ring_entry > 15) {
|
||||
ring_entry = 0;
|
||||
}
|
||||
Block* block = driver->ring + ring_entry;
|
||||
s32 fifo_entries = driver->m_nNumFifoEntries - fifo_slots_freed;
|
||||
|
||||
if (fifo_entries) {
|
||||
// start a new read.
|
||||
driver->read_in_progress = 1;
|
||||
ovrld_log(LogCategory::DRIVER, "[driver thread] Reading for slot {}", block - driver->ring);
|
||||
driver->read_from_file(block);
|
||||
|
||||
} else {
|
||||
driver->read_in_progress = 0;
|
||||
}
|
||||
|
||||
// run completion handler for the previous read - not the one we just started!
|
||||
Block sblock;
|
||||
if (completed) {
|
||||
auto* last_block = &driver->ring[driver->ring_head];
|
||||
ovrld_log(LogCategory::DRIVER, "[driver thread] Completion handler for {}",
|
||||
driver->ring_head);
|
||||
sblock = *last_block;
|
||||
|
||||
if (sblock.descriptor && sblock.descriptor->m_pHead) {
|
||||
ASSERT(sblock.descriptor->m_pHead == last_block);
|
||||
}
|
||||
if (((sblock.descriptor)->m_pHead == last_block) &&
|
||||
((sblock.descriptor)->m_pHead = &sblock, (sblock.descriptor)->m_pTail == last_block)) {
|
||||
(sblock.descriptor)->m_pTail = &sblock;
|
||||
}
|
||||
}
|
||||
driver->ring_head = ring_entry;
|
||||
driver->m_nNumFifoEntries = fifo_entries;
|
||||
while (0 < fifo_slots_freed) {
|
||||
fifo_slots_freed = fifo_slots_freed + -1;
|
||||
SignalSema(driver->fifo_entry_sema);
|
||||
}
|
||||
if (completed != 0) {
|
||||
driver->CompletionHandler(&sblock, 0);
|
||||
}
|
||||
driver->ReleaseFIFOSema(true);
|
||||
|
||||
// this logic here was modified - we go to waiting if we have no more reads.
|
||||
if (driver->m_nNumFifoEntries == 0) {
|
||||
ovrld_log(LogCategory::DRIVER, "[driver thread] No work, waiting.");
|
||||
WaitEventFlag(driver->event_flag, 1, 0x11);
|
||||
ovrld_log(LogCategory::DRIVER, "[driver thread] Woken up!");
|
||||
}
|
||||
|
||||
// s32 status;
|
||||
// if ((((driver->locked != false)) ||
|
||||
// ((driver->needs_break == 0 && (driver->m_nNumFifoEntries == 0)))) &&
|
||||
// ((status = WaitEventFlag(driver->event_flag, 1, 0x11),
|
||||
// status != 0 && (status != -0x1a2)))) {
|
||||
// if (status == -0x1a9) {
|
||||
// do {
|
||||
// SleepThread();
|
||||
// } while (true);
|
||||
// }
|
||||
// DelayThread(8000);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
void CDvdDriver::CompletionHandler(jak3::Block* block, int code) {
|
||||
// there is some janky thread priority changes here,
|
||||
// but they do not seem to be needed with the changes to the ISO thread.
|
||||
|
||||
// PushPri(this,local_20,0x35);
|
||||
auto* desc = block->descriptor;
|
||||
if (desc && desc->m_pHead) {
|
||||
desc->m_status = code;
|
||||
int thread = desc->m_ThreadID;
|
||||
if (desc->m_Callback) {
|
||||
(desc->m_Callback)(desc->m_File, block, code);
|
||||
}
|
||||
if (0 < thread) {
|
||||
WakeupThread(thread);
|
||||
}
|
||||
|
||||
Block* next;
|
||||
if ((desc->m_pHead == block) && (next = block->next, desc->m_pHead = next, next == nullptr)) {
|
||||
desc->m_pTail = nullptr;
|
||||
}
|
||||
}
|
||||
block->next = nullptr;
|
||||
block->descriptor = nullptr;
|
||||
// PopPri(this, local_20[0]);
|
||||
}
|
||||
|
||||
CDvdDriver::~CDvdDriver() {
|
||||
for (auto& entry : m_file_cache) {
|
||||
if (entry.fp) {
|
||||
fclose(entry.fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace jak3
|
||||
@@ -1,144 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "game/overlord/jak3/isocommon.h"
|
||||
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_dvd_driver();
|
||||
|
||||
/*!
|
||||
* The DVD Driver is what actually called the Sony CD library functions.
|
||||
* It also had many special cases for handling errors, open trays, retries, etc that are not
|
||||
* recreated in this port.
|
||||
*
|
||||
* The original DVD driver thread didn't run the actual reads - the Sony CD library had its own
|
||||
* threads for async reads. However, they would call sceCdSync() to wait until a read finished.
|
||||
* It's not clear if sceCdSync would allow other threads to run while waiting on the read to finish.
|
||||
* but if it did, this is a bit of a difference in the blocking behavior.
|
||||
*
|
||||
* This is something that could be revisited, as freads will now essentially block the entire
|
||||
* overlord, including refilling sound RAM.
|
||||
*/
|
||||
|
||||
struct CDescriptor;
|
||||
struct BlockParams;
|
||||
struct CPage;
|
||||
struct ISOFileDef;
|
||||
|
||||
// The CMSG system is used to pass messages from external threads to the driver. It's mostly used
|
||||
// internally by the driver, when functions are called on it from outside threads. In these cases
|
||||
// the Cmsg will get send to the driver thread and handler will run on it here.
|
||||
|
||||
struct CMsg {
|
||||
enum class MsgKind {
|
||||
// LOCK = 0,
|
||||
READ_RAW = 1,
|
||||
CANCEL_READ = 2,
|
||||
};
|
||||
CMsg(MsgKind msg);
|
||||
virtual int send();
|
||||
virtual void handler() = 0;
|
||||
|
||||
u8 data[8];
|
||||
MsgKind m_msg;
|
||||
int m_thread;
|
||||
int m_ret;
|
||||
};
|
||||
|
||||
// struct CMsgLock : public CMsg {
|
||||
// CMsgLock();
|
||||
// void handler() override;
|
||||
// };
|
||||
|
||||
// struct CMsgReadRaw : public CMsg {
|
||||
// explicit CMsgReadRaw(BlockParams* params);
|
||||
// void handler() override;
|
||||
// BlockParams m_block_params;
|
||||
// };
|
||||
|
||||
struct CMsgCancelRead : public CMsg {
|
||||
explicit CMsgCancelRead(CDescriptor* desc);
|
||||
void handler() override;
|
||||
CDescriptor* m_desc;
|
||||
};
|
||||
|
||||
struct CISOCDFile;
|
||||
|
||||
/*!
|
||||
* Reference to an ongoing or requested read at the driver level, possibly made up of multiple
|
||||
* blocks. In this case, the head/tail pointers point to Blocks stored inside the CDvdDriver's
|
||||
* internal FIFO.
|
||||
*/
|
||||
struct CDescriptor {
|
||||
CDescriptor() = default;
|
||||
int m_unk0 = 0;
|
||||
void (*m_Callback)(CISOCDFile*, Block*, s32) = nullptr;
|
||||
int m_ThreadID = 0;
|
||||
int m_status = 0;
|
||||
CISOCDFile* m_File = nullptr;
|
||||
Block* m_pHead = nullptr;
|
||||
Block* m_pTail = nullptr;
|
||||
};
|
||||
|
||||
class CDvdDriver {
|
||||
public:
|
||||
CDvdDriver();
|
||||
~CDvdDriver();
|
||||
void Initialize();
|
||||
void CancelRead(CDescriptor* descriptor);
|
||||
int ReadMultiple(CDescriptor* descriptor,
|
||||
int* pages_read_out,
|
||||
BlockParams* params,
|
||||
int num_pages,
|
||||
bool block_if_queue_full);
|
||||
void SetDriverCallback(std::function<void(int)> f);
|
||||
// int ReadDirect(BlockParams* params);
|
||||
void KickDvdThread();
|
||||
// void Lock();
|
||||
int GetDiskType() const { return disk_type; }
|
||||
s32 ValidateBlockParams(BlockParams* params, int num_params);
|
||||
int ReleaseFIFOSema(bool from_dvd_thread);
|
||||
int AcquireFIFOSema(bool from_dvd_thread);
|
||||
void read_from_file(const Block* block);
|
||||
void CompletionHandler(Block* block, int code);
|
||||
|
||||
u8 initialized = 0;
|
||||
s32 event_flag = -1;
|
||||
s32 fifo_access_sema = -1;
|
||||
s32 fifo_entry_sema = -1;
|
||||
s32 msgbox = -1;
|
||||
s32 m_nNumFifoEntries = 0;
|
||||
s32 ring_head = 0;
|
||||
s32 ring_tail = 0;
|
||||
Block ring[16];
|
||||
u8 read_in_progress; // more likely: read in progress
|
||||
std::function<void(int)> callback;
|
||||
s32 current_thread_priority = 0;
|
||||
// s32 m_nLockCount = 0;
|
||||
// bool locked = false;
|
||||
//
|
||||
s32 disk_type;
|
||||
u8 tray_flag2;
|
||||
u8 trayflag3;
|
||||
u8 tray_flag;
|
||||
s32 m_nDvdThreadAccessSemaCount = 0;
|
||||
|
||||
private:
|
||||
struct FileCacheEntry {
|
||||
const ISOFileDef* def = nullptr;
|
||||
FILE* fp = nullptr;
|
||||
u32 last_use_count = 0;
|
||||
u64 offset_in_file = 0;
|
||||
};
|
||||
u32 m_file_cache_counter = 0;
|
||||
static constexpr int kNumFileCacheEntries = 6;
|
||||
FileCacheEntry m_file_cache[kNumFileCacheEntries];
|
||||
};
|
||||
|
||||
// replacement for g_DvdDriver
|
||||
CDvdDriver* get_driver();
|
||||
|
||||
} // namespace jak3
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
#include "game/overlord/jak3/basefile.h"
|
||||
#include "game/overlord/jak3/basefilesystem.h"
|
||||
#include "game/overlord/jak3/dma.h"
|
||||
#include "game/overlord/jak3/dvd_driver.h"
|
||||
#include "game/overlord/jak3/iso.h"
|
||||
#include "game/overlord/jak3/iso_api.h"
|
||||
#include "game/overlord/jak3/iso_cd.h"
|
||||
#include "game/overlord/jak3/iso_queue.h"
|
||||
#include "game/overlord/jak3/isocommon.h"
|
||||
#include "game/overlord/jak3/list.h"
|
||||
#include "game/overlord/jak3/overlord.h"
|
||||
#include "game/overlord/jak3/pagemanager.h"
|
||||
#include "game/overlord/jak3/ramdisk.h"
|
||||
#include "game/overlord/jak3/sbank.h"
|
||||
#include "game/overlord/jak3/soundcommon.h"
|
||||
#include "game/overlord/jak3/spustreams.h"
|
||||
#include "game/overlord/jak3/srpc.h"
|
||||
#include "game/overlord/jak3/ssound.h"
|
||||
#include "game/overlord/jak3/stream.h"
|
||||
#include "game/overlord/jak3/streamlist.h"
|
||||
#include "game/overlord/jak3/vag.h"
|
||||
#include "game/overlord/jak3/vblank_handler.h"
|
||||
|
||||
namespace jak3 {
|
||||
void jak3_overlord_init_globals_all() {
|
||||
jak3_overlord_init_globals_overlord();
|
||||
jak3_overlord_init_globals_pagemanager();
|
||||
jak3_overlord_init_globals_iso_cd();
|
||||
jak3_overlord_init_globals_dma();
|
||||
jak3_overlord_init_globals_iso();
|
||||
jak3_overlord_init_globals_iso_queue();
|
||||
jak3_overlord_init_globals_srpc();
|
||||
jak3_overlord_init_globals_vag();
|
||||
jak3_overlord_init_globals_ssound();
|
||||
jak3_overlord_init_globals_iso_api();
|
||||
jak3_overlord_init_globals_spustreams();
|
||||
jak3_overlord_init_globals_list();
|
||||
jak3_overlord_init_globals_vblank_handler();
|
||||
jak3_overlord_init_globals_dvd_driver();
|
||||
jak3_overlord_init_globals_basefile();
|
||||
jak3_overlord_init_globals_basefilesystem();
|
||||
jak3_overlord_init_globals_ramdisk();
|
||||
jak3_overlord_init_globals_isocommon();
|
||||
jak3_overlord_init_globals_stream();
|
||||
jak3_overlord_init_globals_sbank();
|
||||
jak3_overlord_init_globals_soundcommon();
|
||||
jak3_overlord_init_globals_streamlist();
|
||||
}
|
||||
} // namespace jak3
|
||||
Loaded 100 of 623 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user