@@ -527,6 +527,13 @@ std::string DrawableActor::print(const PrintSettings& /*settings*/, int indent)
527527 return result;
528528}
529529
530+ std::string DrawableAmbient::print (const PrintSettings& /* settings*/ , int indent) const {
531+ std::string is (indent, ' ' );
532+ std::string result;
533+ result += fmt::format (" {}bsphere: {}" , is, bsphere.print_meters ());
534+ return result;
535+ }
536+
530537void InstanceTie::read_from_file (TypedRef ref,
531538 const decompiler::DecompilerTypeSystem& dts,
532539 GameVersion /* version*/ ) {
@@ -1952,6 +1959,110 @@ void DrawableInlineArrayActor::read_from_file(TypedRef ref,
19521959 }
19531960}
19541961
1962+ void EntityAmbient::read_from_file (TypedRef ref,
1963+ const decompiler::DecompilerTypeSystem& dts,
1964+ GameVersion /* version*/ ) {
1965+ trans.read_from_file (get_field_ref (ref, " trans" , dts));
1966+ aid = read_plain_data_field<u32 >(ref, " aid" , dts);
1967+ // ambientData = read_plain_data_field<u128>(ref, "extra", dts); // to-do: get ambient-data, not
1968+ // sure if nessecary tho
1969+
1970+ int res_length = read_plain_data_field<int32_t >(ref, " length" , dts);
1971+ // int res_allocated_length = read_plain_data_field<int32_t>(ref, "allocated-length", dts);
1972+
1973+ auto tags = deref_label (get_field_ref (ref, " tag" , dts));
1974+ auto data_base = deref_label (get_field_ref (ref, " data-base" , dts));
1975+
1976+ for (int i = 0 ; i < res_length; i++) {
1977+ auto & res = res_list.emplace_back ();
1978+ res.name = read_symbol (tags);
1979+ tags.byte_offset += 4 ;
1980+ res.key_frame = deref_float (tags, 0 );
1981+ tags.byte_offset += 4 ;
1982+ res.elt_type = read_type (tags);
1983+ tags.byte_offset += 4 ;
1984+ const u32 vals = deref_u32 (tags, 0 );
1985+ const u32 offset = vals & 0xffff ; // 16 bits
1986+ res.count = (vals >> 16 ) & 0x7fff ; // 15 bits
1987+ res.inlined = vals & 0x8000'0000 ;
1988+
1989+ Ref data = data_base;
1990+ data.byte_offset += offset;
1991+
1992+ if (res.elt_type == " string" ) {
1993+ ASSERT (!res.inlined );
1994+ for (int j = 0 ; j < res.count ; j++) {
1995+ res.strings .push_back (read_string_ref (data));
1996+ data.byte_offset += 4 ;
1997+ }
1998+ } else if (res.elt_type == " symbol" ) {
1999+ ASSERT (!res.inlined );
2000+ for (int j = 0 ; j < res.count ; j++) {
2001+ res.strings .push_back (read_symbol (data));
2002+ data.byte_offset += 4 ;
2003+ }
2004+ } else if (res.elt_type == " type" ) {
2005+ ASSERT (!res.inlined );
2006+ for (int j = 0 ; j < res.count ; j++) {
2007+ res.strings .push_back (read_type (data));
2008+ data.byte_offset += 4 ;
2009+ }
2010+ } else if (res.elt_type == " vector" ) {
2011+ ASSERT (res.inlined );
2012+ res.inlined_storage = bytes_from_plain_data (data, 16 * res.count );
2013+ } else if (res.elt_type == " float" ) {
2014+ fill_res_with_value_types<float >(res, data);
2015+ } else if (res.elt_type == " int32" ) {
2016+ fill_res_with_value_types<int32_t >(res, data);
2017+ } else if (res.elt_type == " int16" ) {
2018+ fill_res_with_value_types<int16_t >(res, data);
2019+ } else if (res.elt_type == " int8" ) {
2020+ fill_res_with_value_types<int8_t >(res, data);
2021+ } else if (res.elt_type == " uint32" ) {
2022+ fill_res_with_value_types<uint32_t >(res, data);
2023+ } else if (res.elt_type == " uint8" ) {
2024+ fill_res_with_value_types<uint8_t >(res, data);
2025+ } else if (res.elt_type == " actor-group" ) {
2026+ // TODO: unsupported.
2027+ } else if (res.elt_type == " pair" ) {
2028+ ASSERT (res.count == 1 );
2029+ ASSERT (!res.inlined );
2030+ data = deref_label (data);
2031+ res.script = data.data ->to_form_script (data.seg , (data.byte_offset ) / 4 , nullptr );
2032+ } else {
2033+ fmt::print (" unhandled elt_type: {}\n " , res.elt_type );
2034+ ASSERT_NOT_REACHED ();
2035+ }
2036+
2037+ tags.byte_offset += 4 ;
2038+ }
2039+ }
2040+
2041+ void DrawableAmbient::read_from_file (TypedRef ref,
2042+ const decompiler::DecompilerTypeSystem& dts,
2043+ GameVersion version) {
2044+ bsphere.read_from_file (get_field_ref (ref, " bsphere" , dts));
2045+ ambient.read_from_file (get_and_check_ref_to_basic (ref, " ambient" , " entity-ambient" , dts), dts,
2046+ version);
2047+ }
2048+
2049+ void DrawableInlineArrayAmbient::read_from_file (TypedRef ref,
2050+ const decompiler::DecompilerTypeSystem& dts,
2051+ GameVersion version) {
2052+ int numAmbients = read_plain_data_field<int16_t >(ref, " length" , dts);
2053+ auto data_ref = get_field_ref (ref, " data" , dts);
2054+ for (int i = 0 ; i < numAmbients; i++) {
2055+ Ref obj_ref = data_ref;
2056+ obj_ref.byte_offset += 32 * i; // todo not a constant here
2057+ auto type = get_type_of_basic (obj_ref);
2058+ if (type != " drawable-ambient" ) {
2059+ throw Error (" bad drawable-ambient type: {}" , type);
2060+ }
2061+ drawable_ambients.emplace_back ();
2062+ drawable_ambients.back ().read_from_file (typed_ref_from_basic (obj_ref, dts), dts, version);
2063+ }
2064+ }
2065+
19552066void CollideHash::read_from_file (TypedRef ref,
19562067 const decompiler::DecompilerTypeSystem& dts,
19572068 GameVersion /* version*/ ) {
@@ -2065,6 +2176,11 @@ void BspHeader::read_from_file(const decompiler::LinkedObjectFile& file,
20652176 actors.read_from_file (
20662177 get_and_check_ref_to_basic (ref, " actors" , " drawable-inline-array-actor" , dts), dts,
20672178 version);
2179+ if (get_word_kind_for_field (ref, " ambients" , dts) == decompiler::LinkedWord::PTR) {
2180+ ambients.read_from_file (
2181+ get_and_check_ref_to_basic (ref, " ambients" , " drawable-inline-array-ambient" , dts), dts,
2182+ version);
2183+ }
20682184 }
20692185
20702186 if (version > GameVersion::Jak1 &&
0 commit comments