| 1163 | } |
| 1164 | |
| 1165 | bool SaveState_UnzipFromDisk(const std::string& filename, Error* error) |
| 1166 | { |
| 1167 | zip_error_t ze = {}; |
| 1168 | auto zf = zip_open_managed(filename.c_str(), ZIP_RDONLY, &ze); |
| 1169 | if (!zf) |
| 1170 | { |
| 1171 | Console.Error("Failed to open zip file '%s' for save state load: %s", filename.c_str(), zip_error_strerror(&ze)); |
| 1172 | if (zip_error_code_zip(&ze) == ZIP_ER_NOENT) |
| 1173 | Error::SetString(error, "Savestate file does not exist."); |
| 1174 | else |
| 1175 | Error::SetString(error, fmt::format("Savestate zip error: {}", zip_error_strerror(&ze))); |
| 1176 | |
| 1177 | return false; |
| 1178 | } |
| 1179 | |
| 1180 | // look for version and screenshot information in the zip stream: |
| 1181 | if (!CheckVersion(filename, zf.get(), error)) |
| 1182 | return false; |
| 1183 | |
| 1184 | // check that all parts are included |
| 1185 | const s64 internal_index = CheckFileExistsInState(zf.get(), EntryFilename_InternalStructures, true); |
| 1186 | s64 entryIndices[std::size(SavestateEntries)]; |
| 1187 | |
| 1188 | // Log any parts and pieces that are missing, and then generate an exception. |
| 1189 | bool allPresent = (internal_index >= 0); |
| 1190 | for (u32 i = 0; i < std::size(SavestateEntries); i++) |
| 1191 | { |
| 1192 | const bool required = SavestateEntries[i]->IsRequired(); |
| 1193 | entryIndices[i] = CheckFileExistsInState(zf.get(), SavestateEntries[i]->GetFilename(), required); |
| 1194 | if (entryIndices[i] < 0 && required) |
| 1195 | { |
| 1196 | allPresent = false; |
| 1197 | break; |
| 1198 | } |
| 1199 | } |
| 1200 | if (!allPresent) |
| 1201 | { |
| 1202 | Error::SetString(error, "Some required components were not found or are incomplete."); |
| 1203 | return false; |
| 1204 | } |
| 1205 | |
| 1206 | PreLoadPrep(); |
| 1207 | |
| 1208 | if (!LoadInternalStructuresState(zf.get(), internal_index, error)) |
| 1209 | { |
| 1210 | if (!error->IsValid()) |
| 1211 | Error::SetString(error, "Save state corruption in internal structures."); |
| 1212 | |
| 1213 | VMManager::Reset(); |
| 1214 | return false; |
| 1215 | } |
| 1216 | |
| 1217 | for (u32 i = 0; i < std::size(SavestateEntries); ++i) |
| 1218 | { |
| 1219 | if (entryIndices[i] < 0) |
| 1220 | { |
| 1221 | SavestateEntries[i]->FreezeIn(nullptr); |
| 1222 | continue; |
no test coverage detected