| 127 | } |
| 128 | |
| 129 | extern "C" void recomp_create_object_data(uint8_t* rdram, recomp_context* ctx) { |
| 130 | u32 type_index = _arg<0, u32>(rdram, ctx); |
| 131 | u32 subtype_index = _arg<1, u32>(rdram, ctx); |
| 132 | |
| 133 | ExtensionContext& context = type_contexts[type_index]; |
| 134 | |
| 135 | std::lock_guard lock{ extension_mutex }; |
| 136 | |
| 137 | can_register = false; |
| 138 | |
| 139 | // Determine the number of bytes to allocate based on the subtype's extensions and the generic extensions. |
| 140 | u32 alloc_size = context.generic_data_size; |
| 141 | [[maybe_unused]] u32 subtype_data_size = 0; |
| 142 | |
| 143 | if (subtype_index < context.data_sizes.size()) { |
| 144 | subtype_data_size = context.data_sizes[subtype_index]; |
| 145 | alloc_size += subtype_data_size; |
| 146 | } |
| 147 | |
| 148 | // Allocate the extension data if it's of nonzero size. |
| 149 | PTR(void) data_ptr = NULLPTR; |
| 150 | if (alloc_size != 0) { |
| 151 | void* data = recomp::alloc(rdram, alloc_size); |
| 152 | context.alloc_count++; |
| 153 | data_ptr = reinterpret_cast<uint8_t*>(data) - rdram + 0xFFFFFFFF80000000U; |
| 154 | // Zero the allocated memory. |
| 155 | // A memset should be fine here since this data is aligned, but use a byteswapped loop just to be safe. |
| 156 | for (size_t i = 0; i < alloc_size; i++) { |
| 157 | MEM_B(i, data_ptr) = 0; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | // Add the object's data to the type's data slotmap. |
| 162 | u32 spawn_index = context.spawn_count++; |
| 163 | dod::slot_map_key32<ExtensionData> key = context.extension_data.emplace(ExtensionData{.object_spawn_index = spawn_index, .data_addr = data_ptr}); |
| 164 | |
| 165 | // printf("Allocated object data: type %u address 0x%08X with 0x%08X bytes total (0x%08X bytes generic and 0x%08X bytes specific), handle 0x%08X, spawn index %d\n", |
| 166 | // type_index, data_ptr, alloc_size, generic_data_size, type_data_size, key.raw, spawn_index); |
| 167 | |
| 168 | _return<u32>(ctx, key.raw); |
| 169 | } |
| 170 | |
| 171 | extern "C" void recomp_destroy_object_data(uint8_t* rdram, recomp_context* ctx) { |
| 172 | u32 type_index = _arg<0, u32>(rdram, ctx); |
no test coverage detected