Skip to content

Commit

Permalink
Merge pull request #930 from Spartan322/merge/9630d4e
Browse files Browse the repository at this point in the history
  • Loading branch information
Spartan322 authored Jan 17, 2025
2 parents 3c8e8ef + 4805bc1 commit 92a8c99
Show file tree
Hide file tree
Showing 133 changed files with 2,713 additions and 1,904 deletions.
3 changes: 3 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,9 @@ env.Append(BUILDERS=GLSL_BUILDERS)
if env["compiledb"]:
env.Tool("compilation_db")
env.Alias("compiledb", env.CompilationDatabase())
env.NoCache(env.CompilationDatabase())
if not env["verbose"]:
env["COMPILATIONDB_COMSTR"] = "$GENCOMSTR"

if env["ninja"]:
if env.scons_version < (4, 2, 0):
Expand Down
41 changes: 30 additions & 11 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,30 @@ void ProjectSettings::_emit_changed() {
emit_signal("settings_changed");
}

bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset) {
bool ProjectSettings::load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset) {
return ProjectSettings::_load_resource_pack(p_pack, p_replace_files, p_offset, false);
}

bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset, bool p_main_pack) {
if (PackedData::get_singleton()->is_disabled()) {
return false;
}

bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_offset) == OK;
if (p_pack == "res://") {
// Loading the resource directory as a pack source is reserved for internal use only.
return false;
}

if (!p_main_pack && !using_datapack && !OS::get_singleton()->get_resource_dir().is_empty()) {
// Add the project's resource file system to PackedData so directory access keeps working when
// the game is running without a main pack, like in the editor or on Android.
PackedData::get_singleton()->add_pack_source(memnew(PackedSourceDirectory));
PackedData::get_singleton()->add_pack("res://", false, 0);
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
using_datapack = true;
}

bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_offset) == OK;
if (!ok) {
return false;
}
Expand All @@ -493,9 +510,11 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f
ResourceUID::get_singleton()->load_from_cache(false);
}

//if data.pck is found, all directory access will be from here
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
using_datapack = true;
// If the data pack was found, all directory access will be from here.
if (!using_datapack) {
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
using_datapack = true;
}

return true;
}
Expand Down Expand Up @@ -574,7 +593,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Attempt with a user-defined main pack first

if (!p_main_pack.is_empty()) {
bool ok = _load_resource_pack(p_main_pack);
bool ok = _load_resource_pack(p_main_pack, false, 0, true);
ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, vformat("Cannot open resource pack '%s'.", p_main_pack));

Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
Expand All @@ -593,7 +612,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// and if so, we attempt loading it at the end.

// Attempt with PCK bundled into executable.
bool found = _load_resource_pack(exec_path);
bool found = _load_resource_pack(exec_path, false, 0, true);

// Attempt with exec_name.pck.
// (This is the usual case when distributing a Redot game.)
Expand All @@ -609,20 +628,20 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
#ifdef MACOS_ENABLED
if (!found) {
// Attempt to load PCK from macOS .app bundle resources.
found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_filename + ".pck"));
found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_basename + ".pck"), false, 0, true) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_filename + ".pck"), false, 0, true);
}
#endif

if (!found) {
// Try to load data pack at the location of the executable.
// As mentioned above, we have two potential names to attempt.
found = _load_resource_pack(exec_dir.path_join(exec_basename + ".pck")) || _load_resource_pack(exec_dir.path_join(exec_filename + ".pck"));
found = _load_resource_pack(exec_dir.path_join(exec_basename + ".pck"), false, 0, true) || _load_resource_pack(exec_dir.path_join(exec_filename + ".pck"), false, 0, true);
}

if (!found) {
// If we couldn't find them next to the executable, we attempt
// the current working directory. Same story, two tests.
found = _load_resource_pack(exec_basename + ".pck") || _load_resource_pack(exec_filename + ".pck");
found = _load_resource_pack(exec_basename + ".pck", false, 0, true) || _load_resource_pack(exec_filename + ".pck", false, 0, true);
}

// If we opened our package, try and load our project.
Expand Down Expand Up @@ -1420,7 +1439,7 @@ void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "offset"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL(0));
ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "offset"), &ProjectSettings::load_resource_pack, DEFVAL(true), DEFVAL(0));

ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);

Expand Down
3 changes: 2 additions & 1 deletion core/config/project_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ class ProjectSettings : public Object {

void _convert_to_last_version(int p_from_version);

bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0);
bool load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset);
bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0, bool p_main_pack = false);

void _add_property_info_bind(const Dictionary &p_info);

Expand Down
64 changes: 59 additions & 5 deletions core/input/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1604,9 +1604,6 @@ void Input::parse_mapping(const String &p_mapping) {
return;
}

CharString uid;
uid.resize(17);

mapping.uid = entry[0];
mapping.name = entry[1];

Expand Down Expand Up @@ -1714,15 +1711,72 @@ void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) {
}

void Input::remove_joy_mapping(const String &p_guid) {
// One GUID can exist multiple times in `map_db`, and
// `add_joy_mapping` can choose not to update the existing mapping,
// so the indices can be all over the place. Therefore we need to remember them.
Vector<int> removed_idx;
int min_removed_idx = -1;
int max_removed_idx = -1;
int fallback_mapping_offset = 0;

for (int i = map_db.size() - 1; i >= 0; i--) {
if (p_guid == map_db[i].uid) {
map_db.remove_at(i);

if (max_removed_idx == -1) {
max_removed_idx = i;
}
min_removed_idx = i;
removed_idx.push_back(i);

if (i < fallback_mapping) {
fallback_mapping_offset++;
} else if (i == fallback_mapping) {
fallback_mapping = -1;
WARN_PRINT_ONCE(vformat("Removed fallback joypad input mapping \"%s\". This could lead to joypads not working as intended.", p_guid));
}
}
}

if (min_removed_idx == -1) {
return; // Nothing removed.
}

if (fallback_mapping > 0) {
// Fix the shifted index.
fallback_mapping -= fallback_mapping_offset;
}

int removed_idx_size = removed_idx.size();

// Update joypad mapping references: some
// * should use the fallback_mapping (if set; if not, they get unmapped), or
// * need their mapping reference fixed, because the deletion(s) offset them.
for (KeyValue<int, Joypad> &E : joy_names) {
Joypad &joy = E.value;
if (joy.uid == p_guid) {
_set_joypad_mapping(joy, -1);
if (joy.mapping < min_removed_idx) {
continue; // Not affected.
}

if (joy.mapping > max_removed_idx) {
_set_joypad_mapping(joy, joy.mapping - removed_idx_size);
continue; // Simple offset fix.
}

// removed_idx is in reverse order (ie. high to low), because the first loop is in reverse order.
for (int i = 0; i < removed_idx.size(); i++) {
if (removed_idx[i] == joy.mapping) {
// Set to fallback_mapping, if defined, else unmap the joypad.
// Currently, the fallback_mapping is only set internally, and only for Android.
_set_joypad_mapping(joy, fallback_mapping);
break;
}
if (removed_idx[i] < joy.mapping) {
// Complex offset fix:
// This mapping was shifted by `(removed_idx_size - i)` deletions.
_set_joypad_mapping(joy, joy.mapping - (removed_idx_size - i));
break;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/input/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class Input : public Object {

HashSet<uint32_t> ignored_device_ids;

int fallback_mapping = -1;
int fallback_mapping = -1; // Index of the guid in map_db.

CursorShape default_shape = CURSOR_ARROW;

Expand Down
38 changes: 38 additions & 0 deletions core/io/file_access_pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,44 @@ Ref<FileAccess> PackedSourcePCK::get_file(const String &p_path, PackedData::Pack

//////////////////////////////////////////////////////////////////

bool PackedSourceDirectory::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) {
// Load with offset feature only supported for PCK files.
ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with directories.");

if (p_path != "res://") {
return false;
}
add_directory(p_path, p_replace_files);
return true;
}

Ref<FileAccess> PackedSourceDirectory::get_file(const String &p_path, PackedData::PackedFile *p_file) {
Ref<FileAccess> ret = FileAccess::create_for_path(p_path);
ret->reopen(p_path, FileAccess::READ);
return ret;
}

void PackedSourceDirectory::add_directory(const String &p_path, bool p_replace_files) {
Ref<DirAccess> da = DirAccess::open(p_path);
if (da.is_null()) {
return;
}
da->set_include_hidden(true);

for (const String &file_name : da->get_files()) {
String file_path = p_path.path_join(file_name);
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
PackedData::get_singleton()->add_path(p_path, file_path, 0, 0, md5, this, p_replace_files, false);
}

for (const String &sub_dir_name : da->get_directories()) {
String sub_dir_path = p_path.path_join(sub_dir_name);
add_directory(sub_dir_path, p_replace_files);
}
}

//////////////////////////////////////////////////////////////////

Error FileAccessPack::open_internal(const String &p_path, int p_mode_flags) {
ERR_PRINT("Can't open pack-referenced file.");
return ERR_UNAVAILABLE;
Expand Down
8 changes: 8 additions & 0 deletions core/io/file_access_pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ class PackedSourcePCK : public PackSource {
virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
};

class PackedSourceDirectory : public PackSource {
void add_directory(const String &p_path, bool p_replace_files);

public:
virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) override;
virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
};

class FileAccessPack : public FileAccess {
PackedData::PackedFile pf;

Expand Down
8 changes: 4 additions & 4 deletions core/io/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3995,11 +3995,11 @@ uint32_t Image::get_format_component_mask(Format p_format) {
case FORMAT_RGBAH:
return rgba;
case FORMAT_RGBE9995:
return rgba;
return rgb;
case FORMAT_DXT1:
return rgb;
case FORMAT_DXT3:
return rgb;
return rgba;
case FORMAT_DXT5:
return rgba;
case FORMAT_RGTC_R:
Expand Down Expand Up @@ -4029,9 +4029,9 @@ uint32_t Image::get_format_component_mask(Format p_format) {
case FORMAT_ETC2_RGB8A1:
return rgba;
case FORMAT_ETC2_RA_AS_RG:
return rgba;
return rg;
case FORMAT_DXT5_RA_AS_RG:
return rgba;
return rg;
case FORMAT_ASTC_4x4:
return rgba;
case FORMAT_ASTC_4x4_HDR:
Expand Down
22 changes: 21 additions & 1 deletion core/io/resource_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,34 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin
print_verbose(vformat("Failed loading resource: %s", p_path));
}

#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
if (ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_path.get_extension()).is_valid()) {
// The format is known to the editor, but the file hasn't been imported
// (otherwise, ResourceFormatImporter would have been found as a suitable loader).
found = true;
if (r_error) {
*r_error = ERR_FILE_NOT_FOUND;
}
}
}
#endif
ERR_FAIL_COND_V_MSG(found, Ref<Resource>(),
vformat("Failed loading resource: %s. Make sure resources have been imported by opening the project in the editor at least once.", p_path));

#ifdef TOOLS_ENABLED
Ref<FileAccess> file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES);
ERR_FAIL_COND_V_MSG(!file_check->file_exists(p_path), Ref<Resource>(), vformat("Resource file not found: %s (expected type: %s)", p_path, p_type_hint));
if (!file_check->file_exists(p_path)) {
if (r_error) {
*r_error = ERR_FILE_NOT_FOUND;
}
ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Resource file not found: %s (expected type: %s)", p_path, p_type_hint));
}
#endif

if (r_error) {
*r_error = ERR_FILE_UNRECOGNIZED;
}
ERR_FAIL_V_MSG(Ref<Resource>(), vformat("No loader found for resource: %s (expected type: %s)", p_path, p_type_hint));
}

Expand Down
2 changes: 1 addition & 1 deletion core/object/method_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class MethodBind {
}

_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
ERR_FAIL_COND_V(p_argument < -1 || p_argument >= argument_count, Variant::NIL);
return argument_types[p_argument + 1];
}

Expand Down
Loading

0 comments on commit 92a8c99

Please sign in to comment.