Compare commits

..
Author SHA1 Message Date
Tyler Wilding 55204e6996 decomp: ensure out_folder exists before being written to 2024-06-21 22:58:16 -04:00
Tyler Wilding b2cfefb669 decomp/config: simplify enabling streamed audio ripping, string wasn't even in use anymore 2024-06-19 23:43:34 -04:00
Tyler Wilding bc586f0cca lint: formatting 2024-06-15 15:43:04 -04:00
Tyler Wilding 13e7a28c08 decomp: eliminate duplicate code in extractor/decompiler
This allows the extractor's decompilation routine to do all the things the normal decompiler can (ie. extract audio)
2024-06-15 15:42:27 -04:00
Tyler Wilding 17665a4615 decomp: pull out main decompilation process into an isolated function 2024-06-15 15:41:56 -04:00
Tyler Wilding d209766078 util: support get_peak_rss on windows 2024-06-15 15:41:40 -04:00
622 changed files with 13476 additions and 55121 deletions

No files matched your search

@@ -1,90 +0,0 @@
name: Compiler Output Check
on:
pull_request:
branches:
- master
jobs:
build:
name: Clang
runs-on: ubuntu-20.04
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- 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 (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: Checkout Master
uses: actions/checkout@v4
with:
ref: master
- 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: Compare Results and Produce Report
run: |
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 -6
View File
@@ -32,7 +32,6 @@ linux-default/
*.bin
*.log
*.p2s
out/
savestate-out/
savestate_out/
failures/
@@ -59,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
+1
View File
@@ -145,6 +145,7 @@
"name": "Game - Jak 1 - Runtime (boot)",
"args": [
"-v",
"--portable",
"--game",
"jak1",
"--",
+2 -2
View File
@@ -4,7 +4,7 @@
#include "fmt/core.h"
std::string DmaTag::print() const {
std::string DmaTag::print() {
std::string result;
const char* mode_names[8] = {"refe", "cnt", "next", "ref", "refs", "call", "ret", "end"};
result += fmt::format("TAG: 0x{:08x} {:4s} qwc 0x{:04x}", addr, mode_names[(int)kind], qwc);
@@ -15,7 +15,7 @@ std::string DmaTag::print() const {
return result;
}
std::string VifCode::print() const {
std::string VifCode::print() {
std::string result;
switch (kind) {
+2 -2
View File
@@ -52,7 +52,7 @@ struct DmaTag {
bool operator!=(const DmaTag& other) const { return !((*this) == other); }
std::string print() const;
std::string print();
};
inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32 dadr) {
@@ -148,7 +148,7 @@ struct VifCode {
u16 num;
u16 immediate;
std::string print() const;
std::string print();
};
struct VifCodeStcycl {
-1
View File
@@ -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)},
+7 -28
View File
@@ -26,8 +26,6 @@ u64 get_current_tid() {
}
#endif
#include "common/log/log.h"
#include "common/util/compress.h"
#include "common/util/string_util.h"
// clang-format on
u64 get_current_ts() {
@@ -36,12 +34,12 @@ u64 get_current_ts() {
GlobalProfiler::GlobalProfiler() {
m_t0 = get_current_ts();
m_nodes.resize(m_max_events);
set_max_events(65536);
}
void GlobalProfiler::update_event_buffer_size(size_t new_size) {
m_max_events = new_size;
m_nodes.resize(m_max_events);
void GlobalProfiler::set_max_events(size_t event_count) {
ASSERT(!m_enabled);
m_nodes.resize(event_count);
}
void GlobalProfiler::set_waiting_for_event(const std::string& event_name) {
@@ -74,10 +72,6 @@ void GlobalProfiler::root_event() {
instant_event("ROOT");
}
size_t GlobalProfiler::get_next_idx() {
return (m_next_idx % m_nodes.size());
}
void GlobalProfiler::begin_event(const char* name) {
event(name, ProfNode::BEGIN);
}
@@ -102,10 +96,8 @@ void GlobalProfiler::set_enable(bool en) {
m_enabled = en;
}
void GlobalProfiler::dump_to_json() {
if (m_enabled) {
set_enable(false);
}
void GlobalProfiler::dump_to_json(const std::string& path) {
ASSERT(!m_enabled);
nlohmann::json json;
auto& trace_events = json["traceEvents"];
@@ -193,20 +185,7 @@ void GlobalProfiler::dump_to_json() {
t.second.highest_at_target);
}
if (m_enable_compression) {
const auto json_str = json.dump();
const auto compressed_data =
compression::compress_zstd_no_header(json_str.data(), json_str.size());
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
fmt::format("prof-{}.json.zst", str_util::current_local_timestamp_no_colons());
file_util::create_dir_if_needed_for_file(file_path);
file_util::write_binary_file(file_path, compressed_data.data(), compressed_data.size());
} else {
auto file_path = file_util::get_jak_project_dir() / "profile_data" /
fmt::format("prof-{}.json", str_util::current_local_timestamp_no_colons());
file_util::create_dir_if_needed_for_file(file_path);
file_util::write_text_file(file_path, json.dump());
}
file_util::write_text_file(path, json.dump());
}
GlobalProfiler gprof;
+2 -8
View File
@@ -17,8 +17,7 @@ struct ProfNode {
class GlobalProfiler {
public:
GlobalProfiler();
size_t get_max_events() { return m_max_events; }
void update_event_buffer_size(size_t new_size);
void set_max_events(size_t event_count);
void set_waiting_for_event(const std::string& event_name);
void instant_event(const char* name);
void begin_event(const char* name);
@@ -26,16 +25,11 @@ class GlobalProfiler {
void end_event();
void clear();
void set_enable(bool en);
void dump_to_json();
void dump_to_json(const std::string& path);
void root_event();
bool is_enabled() { return m_enabled; }
size_t get_next_idx();
bool m_enable_compression = false;
private:
std::atomic_bool m_enabled = false;
size_t m_max_events = 65536;
u64 m_t0 = 0;
std::atomic_size_t m_next_idx = 0;
std::vector<ProfNode> m_nodes;
+1 -1
View File
@@ -140,7 +140,7 @@ void printstd(const char* format, va_list arg_list) {
internal::log_vprintf(format, arg_list);
}
// how many extra log files for a single program should be kept
// how many extra log files for a single program should be kept?
constexpr int LOG_ROTATE_MAX = 10;
void set_file(const std::string& filename,
+2 -5
View File
@@ -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();
+1 -145
View 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
-13
View File
@@ -46,17 +46,4 @@ std::vector<u8> decompress_zstd(const void* data, size_t size) {
ASSERT(decomp_size == decompressed_size);
return result;
}
std::vector<u8> compress_zstd_no_header(const void* data, size_t size) {
size_t max_compressed = ZSTD_compressBound(size);
std::vector<u8> result(max_compressed);
size_t compressed_size = ZSTD_compress(result.data(), max_compressed, data, size, 1);
if (ZSTD_isError(compressed_size)) {
ASSERT_MSG(false, fmt::format("ZSTD error: {}", ZSTD_getErrorName(compressed_size)));
}
result.resize(compressed_size);
return result;
}
} // namespace compression
+1 -2
View File
@@ -8,5 +8,4 @@ namespace compression {
// compress and decompress data with zstd
std::vector<u8> compress_zstd(const void* data, size_t size);
std::vector<u8> decompress_zstd(const void* data, size_t size);
std::vector<u8> compress_zstd_no_header(const void* data, size_t size);
} // namespace compression
} // namespace compression
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include <string>
#include "common/common_types.h"
inline u64 fnv64(const void* data, u64 len) {
u64 ret = 0xcbf29ce484222325;
const auto* ptr = (const u8*)data;
for (u64 i = 0; i < len; i++) {
ret = 1099511628211 * (((u64)*ptr) ^ ret);
ptr++;
}
return ret;
}
inline u64 fnv64(const std::string& str) {
return fnv64(str.data(), str.length());
}
+3 -3
View File
@@ -27,11 +27,11 @@ Range<int> parse_json_optional_integer_range(const nlohmann::json& json);
}
template <typename T>
void json_get_optional(const nlohmann::json& j,
void json_get_optional(const nlohmann::json& json,
const std::string& key,
std::optional<T>& optionalValue) {
if (j.contains(key) && !j[key].is_null()) {
optionalValue = j[key].get<T>();
if (json.contains(key) && !json[key].is_null()) {
optionalValue = json[key].get<T>();
}
}
@@ -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"],
-1
View File
@@ -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
+1 -1
View File
@@ -25,7 +25,7 @@ namespace decompiler {
*/
class LinkedObjectFile {
public:
LinkedObjectFile(GameVersion _version) : version(_version) {}
LinkedObjectFile(GameVersion version) : version(version){};
void set_segment_count(int n_segs);
void push_back_word_to_segment(uint32_t word, int segment);
int get_label_id_for(int seg, int offset);
+6 -2
View File
@@ -54,8 +54,12 @@ void append_body_to_function_definition(goos::Object* top_form,
body_elements.insert(body_elements.end(), inline_body.begin(), inline_body.end());
// If the first element in the body is a docstring, add it first
if (body_elements.size() > 0 && body_elements.at(0).is_string()) {
initial_top_level_forms.push_back(
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
if (version > GameVersion::Jak2) {
initial_top_level_forms.push_back(
goos::StringObject::make_new(fix_docstring_indent(inline_body.at(0).as_string()->data)));
} else {
initial_top_level_forms.push_back(inline_body.at(0));
}
body_elements.erase(body_elements.begin());
}
+1 -1
View File
@@ -21102,7 +21102,7 @@
:size-assert #x94
:flag-assert #xf00300094
(:methods
(spawn-particles! (_type_) none))
(dumb-15 (_type_) none))
(:states
hud-normal
hud-coming-in
-13
View File
@@ -2515,7 +2515,6 @@
(iop-mem 48)
(cancel-dgo 49)
(set-stereo-mode 50) ;; sound-rpc-set-stereo-mode
(set-mirror 201)
)
(defenum sound-group
@@ -2830,17 +2829,6 @@
:flag-assert #x900000004
)
; added
(defenum sound-mirror-mode
:type uint8
(normal)
(mirrored)
)
; added for mirror mode
(deftype sound-rpc-set-mirror-mode (sound-rpc-cmd)
((mirror sound-mirror-mode)))
(deftype sound-rpc-union (structure)
((data uint32 20 :offset-assert 0)
(load-bank sound-rpc-load-bank :offset 0)
@@ -2864,7 +2852,6 @@
(shutdown sound-rpc-shutdown :offset 0)
(list-sounds sound-rpc-list-sounds :offset 0)
(unload-music sound-rpc-unload-music :offset 0)
(mirror-mode sound-rpc-set-mirror-mode :overlay-at (-> data 0))
)
:method-count-assert 9
:size-assert #x50
+108 -177
View File
@@ -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,
+1 -305
View File
@@ -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": [
+16 -22
View File
@@ -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"]],
+3 -41
View File
@@ -515,44 +515,8 @@ TPageResultStats process_tpage(ObjectFileData& data,
// currently not needed.
break;
case int(PSM::PSMT8):
if (tex.clutpsm == (int)CPSM::PSMCT16) {
// will store output pixels, rgba (8888)
std::vector<u8> index_out;
// width is like the TEX0 register, in 64 texel units.
// not sure what the other widths are yet.
int read_width = 64 * tex.width[0];
// loop over pixels in output texture image
for (int y = 0; y < tex.h; y++) {
for (int x = 0; x < tex.w; x++) {
// read as the PSMT8 type. The dest field tells us a block offset.
auto addr8 = psmt8_addr(x, y, read_width) + tex.dest[0] * 256;
u8 value = *(u8*)(vram.data() + addr8);
index_out.push_back(value);
}
}
std::array<math::Vector4<u8>, 256> unscrambled_clut{};
for (int i = 0; i < 256; i++) {
u32 clut_chunk = i / 16;
u32 off_in_chunk = i % 16;
u8 clx = 0, cly = 0;
if (clut_chunk & 1) {
clx = 8;
}
cly = (clut_chunk >> 1) * 2;
if (off_in_chunk >= 8) {
off_in_chunk -= 8;
cly++;
}
clx += off_in_chunk;
u32 clut_addr = psmct16_addr(clx, cly, 64) + tex.clutdest * 256;
memcpy(&unscrambled_clut[i], vram.data() + clut_addr, 4);
}
texture_db.add_index_texture(texture_page.id, tex_id, index_out, unscrambled_clut,
tex.w, tex.h, tex.name, texture_page.name, level_names);
stats.successful_textures++;
} else if (tex.clutpsm == (int)PSM::PSMCT32) {
ASSERT(tex.clutpsm == int(CPSM::PSMCT32));
{
// will store output pixels, index (u8)
std::vector<u8> index_out;
@@ -591,12 +555,10 @@ TPageResultStats process_tpage(ObjectFileData& data,
texture_db.add_index_texture(texture_page.id, tex_id, index_out, unscrambled_clut,
tex.w, tex.h, tex.name, texture_page.name, level_names);
stats.successful_textures++;
} else {
ASSERT_NOT_REACHED();
}
break;
default:
lg::die("Animated texture {} format {} clut {}\n", tex.name, tex.psm, tex.clutpsm);
lg::die("Animated texture {} format {}\n", tex.name, tex.psm);
}
}
+4 -7
View File
@@ -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
+1
View File
@@ -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;
}
}
-24
View File
@@ -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
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
+38 -38
View File
@@ -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"
}
+156 -156
View File
@@ -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"
}
+4 -9
View File
@@ -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,
+16
View File
@@ -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);
}
}
+7 -27
View File
@@ -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;
}
+1 -5
View File
@@ -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 {
+126 -612
View File
@@ -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;
}
+5 -20
View File
@@ -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();
}
+1 -1
View File
@@ -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;
}
+18
View File
@@ -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.
+1
View File
@@ -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;
+17 -33
View File
@@ -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
+1
View File
@@ -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;
+4 -5
View File
@@ -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;
-220
View File
@@ -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
-10
View File
@@ -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);
+1 -3
View File
@@ -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>()}});
-3
View File
@@ -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)));
}
-1
View File
@@ -58,7 +58,6 @@ enum class Jak2SoundCommand : u16 {
iop_mem = 48,
cancel_dgo = 49,
set_stereo_mode = 50,
mirror_mode = 201,
};
struct SoundRpcCommand {
+1 -1
View File
@@ -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));
+1 -1
View File
@@ -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();
-333
View File
@@ -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
-76
View File
@@ -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
-26
View File
@@ -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(&param);
if (sema < 0) {
ASSERT_NOT_REACHED();
}
}
}
} // namespace jak3
-33
View File
@@ -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
-526
View File
@@ -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
-32
View File
@@ -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
-583
View File
@@ -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(&param);
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
-144
View File
@@ -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
-50
View File
@@ -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
-5
View File
@@ -1,5 +0,0 @@
#pragma once
namespace jak3 {
void jak3_overlord_init_globals_all();
}
Loaded 100 of 622 files, more files were not shown because too many files have changed in this diff. Show more