| 118 | } |
| 119 | |
| 120 | int SaveState::load(Context* context, const MovieFile& m, bool branch, bool inputEditor, int common_relative_id, uint64_t common_relative_framecount) |
| 121 | { |
| 122 | /* Check that the savestate exists (check for both savestate files and |
| 123 | * framecount, because there can be leftover savestate files from |
| 124 | * forked savestate of previous execution). */ |
| 125 | if (!std::filesystem::exists(pagemap_path) || !std::filesystem::exists(pages_path) || |
| 126 | (framecount == 0)) { |
| 127 | /* If there is no savestate but a movie file, offer to load |
| 128 | * the movie and fast-forward to the savestate movie frame. |
| 129 | */ |
| 130 | |
| 131 | if ((context->config.sc.recording != SharedConfig::NO_RECORDING) && |
| 132 | std::filesystem::exists(movie_path)) { |
| 133 | |
| 134 | /* Load the savestate movie from disk */ |
| 135 | MovieFile savedmovie(context); |
| 136 | int ret = savedmovie.loadSavestateMovie(movie_path); |
| 137 | |
| 138 | /* Checking if our movie is a prefix of the savestate movie */ |
| 139 | if ((ret == 0) && savedmovie.inputs->isEqual(m.inputs, 0, context->framecount)) { |
| 140 | return ENOSTATEMOVIEPREFIX; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | sendMessage(MSGN_OSD_MSG); |
| 145 | sendString(no_state_msg); |
| 146 | return ENOSTATE; |
| 147 | } |
| 148 | |
| 149 | /* Send the savestate index */ |
| 150 | sendMessage(MSGN_SAVESTATE_INDEX); |
| 151 | sendData(&id, sizeof(int)); |
| 152 | |
| 153 | /* Send savestate path */ |
| 154 | sendMessage(MSGN_SAVESTATE_PATH); |
| 155 | sendString(path); |
| 156 | |
| 157 | /* Check if we need to load a prefix movie when: |
| 158 | * - not loading a branch, and |
| 159 | * - being in read mode, or being in write mode with input editor opened |
| 160 | */ |
| 161 | if ((!branch) && |
| 162 | (context->config.sc.recording == SharedConfig::RECORDING_READ || |
| 163 | (context->config.sc.recording == SharedConfig::RECORDING_WRITE && |
| 164 | inputEditor))) { |
| 165 | |
| 166 | /* Checking if the savestate movie is a prefix of our movie */ |
| 167 | bool isPrefix; |
| 168 | if (!movie) |
| 169 | isPrefix = false; |
| 170 | else { |
| 171 | /* We can skip checking for inputs if we are a parent of the current state */ |
| 172 | if (common_relative_id == id) { |
| 173 | isPrefix = true; |
| 174 | } |
| 175 | else if (common_relative_id != -1) { |
| 176 | /* We can skip most of the checked inputs if we have a common relative |
| 177 | * with the current state */ |
nothing calls this directly
no test coverage detected