1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2011-2017 - Daniel De Matteis
3  *  Copyright (C) 2016-2019 - Brad Parker
4  *
5  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
6  *  of the GNU General Public License as published by the Free Software Found-
7  *  ation, either version 3 of the License, or (at your option) any later version.
8  *
9  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  *  PURPOSE.  See the GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License along with RetroArch.
14  *  If not, see <http://www.gnu.org/licenses/>.
15  */
16 #include <stdint.h>
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <string.h>
20 #include <time.h>
21 
22 #ifdef _WIN32
23 #include <direct.h>
24 #else
25 #include <unistd.h>
26 #endif
27 #include <errno.h>
28 
29 #include <compat/strl.h>
30 #include <retro_assert.h>
31 #include <lists/string_list.h>
32 #include <streams/interface_stream.h>
33 #include <streams/file_stream.h>
34 #include <streams/rzip_stream.h>
35 #include <rthreads/rthreads.h>
36 #include <file/file_path.h>
37 #include <retro_miscellaneous.h>
38 #include <string/stdstring.h>
39 #include <time/rtime.h>
40 
41 #ifdef HAVE_CONFIG_H
42 #include "../core.h"
43 #endif
44 
45 #ifdef HAVE_NETWORKING
46 #include "../network/netplay/netplay.h"
47 #endif
48 
49 #ifdef HAVE_CHEEVOS
50 #include "../cheevos/cheevos.h"
51 #endif
52 
53 #include "../content.h"
54 #include "../core.h"
55 #include "../file_path_special.h"
56 #include "../configuration.h"
57 #include "../msg_hash.h"
58 #include "../retroarch.h"
59 #include "../verbosity.h"
60 #include "tasks_internal.h"
61 #ifdef HAVE_CHEATS
62 #include "../cheat_manager.h"
63 #endif
64 
65 #if defined(HAVE_LIBNX) || defined(_3DS)
66 #define SAVE_STATE_CHUNK 4096 * 10
67 #else
68 #define SAVE_STATE_CHUNK 4096
69 #endif
70 
71 #define RASTATE_VERSION 1
72 #define RASTATE_MEM_BLOCK "MEM "
73 #define RASTATE_CHEEVOS_BLOCK "ACHV"
74 #define RASTATE_END_BLOCK "END "
75 
76 struct ram_type
77 {
78    const char *path;
79    int type;
80 };
81 
82 struct save_state_buf
83 {
84    void* data;
85    size_t size;
86    char path[PATH_MAX_LENGTH];
87 };
88 
89 struct sram_block
90 {
91    void *data;
92    size_t size;
93    unsigned type;
94 };
95 
96 typedef struct
97 {
98    intfstream_t *file;
99    void *data;
100    void *undo_data;
101    ssize_t size;
102    ssize_t undo_size;
103    ssize_t written;
104    ssize_t bytes_read;
105    int state_slot;
106    char path[PATH_MAX_LENGTH];
107    bool load_to_backup_buffer;
108    bool autoload;
109    bool autosave;
110    bool undo_save;
111    bool mute;
112    bool thumbnail_enable;
113    bool has_valid_framebuffer;
114    bool compress_files;
115 } save_task_state_t;
116 
117 #ifdef HAVE_THREADS
118 typedef struct autosave autosave_t;
119 
120 /* Autosave support. */
121 struct autosave_st
122 {
123    autosave_t **list;
124    unsigned num;
125 };
126 
127 struct autosave
128 {
129    void *buffer;
130    const void *retro_buffer;
131    const char *path;
132    slock_t *lock;
133    slock_t *cond_lock;
134    scond_t *cond;
135    sthread_t *thread;
136    size_t bufsize;
137    unsigned interval;
138    volatile bool quit;
139    bool compress_files;
140 };
141 #endif
142 
143 typedef save_task_state_t load_task_data_t;
144 
145 /* Holds the previous saved state
146  * Can be restored to disk with undo_save_state(). */
147 /* TODO/FIXME - global state - perhaps move outside this file */
148 static struct save_state_buf undo_save_buf;
149 
150 /* Holds the data from before a load_state() operation
151  * Can be restored with undo_load_state(). */
152 static struct save_state_buf undo_load_buf;
153 
154 #ifdef HAVE_THREADS
155 /* TODO/FIXME - global state - perhaps move outside this file */
156 static struct autosave_st autosave_state;
157 #endif
158 
159 /* TODO/FIXME - global state - perhaps move outside this file */
160 static bool save_state_in_background       = false;
161 static struct string_list *task_save_files = NULL;
162 
163 typedef struct rastate_size_info
164 {
165    size_t total_size;
166    size_t coremem_size;
167 #ifdef HAVE_CHEEVOS
168    size_t cheevos_size;
169 #endif
170 } rastate_size_info_t;
171 
172 #ifdef HAVE_THREADS
173 /**
174  * autosave_thread:
175  * @data            : pointer to autosave object
176  *
177  * Callback function for (threaded) autosave.
178  **/
autosave_thread(void * data)179 static void autosave_thread(void *data)
180 {
181    autosave_t *save = (autosave_t*)data;
182 
183    while (!save->quit)
184    {
185       bool differ;
186 
187       slock_lock(save->lock);
188       differ = string_is_not_equal_fast(save->buffer, save->retro_buffer,
189             save->bufsize);
190       if (differ)
191          memcpy(save->buffer, save->retro_buffer, save->bufsize);
192       slock_unlock(save->lock);
193 
194       if (differ)
195       {
196          intfstream_t *file = NULL;
197 
198          /* Should probably deal with this more elegantly. */
199          if (save->compress_files)
200             file = intfstream_open_rzip_file(save->path,
201                   RETRO_VFS_FILE_ACCESS_WRITE);
202          else
203             file = intfstream_open_file(save->path,
204                   RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
205 
206          if (file)
207          {
208             intfstream_write(file, save->buffer, save->bufsize);
209             intfstream_flush(file);
210             intfstream_close(file);
211             free(file);
212          }
213       }
214 
215       slock_lock(save->cond_lock);
216 
217       if (!save->quit)
218       {
219 #if defined(_MSC_VER) && _MSC_VER <= 1200
220          int64_t timeout_us = 1000000;
221 #else
222          int64_t timeout_us = 1000000LL;
223 #endif
224          scond_wait_timeout(save->cond, save->cond_lock,
225                save->interval * timeout_us);
226       }
227 
228       slock_unlock(save->cond_lock);
229    }
230 }
231 
232 /**
233  * autosave_new:
234  * @path            : path to autosave file
235  * @data            : pointer to buffer
236  * @size            : size of @data buffer
237  * @interval        : interval at which saves should be performed.
238  *
239  * Create and initialize autosave object.
240  *
241  * Returns: pointer to new autosave_t object if successful, otherwise
242  * NULL.
243  **/
autosave_new(const char * path,const void * data,size_t size,unsigned interval,bool compress)244 static autosave_t *autosave_new(const char *path,
245       const void *data, size_t size,
246       unsigned interval, bool compress)
247 {
248    void       *buf               = NULL;
249    autosave_t *handle            = (autosave_t*)malloc(sizeof(*handle));
250    if (!handle)
251       return NULL;
252 
253    handle->quit                  = false;
254    handle->bufsize               = size;
255    handle->interval              = interval;
256    handle->compress_files        = compress;
257    handle->retro_buffer          = data;
258    handle->path                  = path;
259 
260    buf                           = malloc(size);
261 
262    if (!buf)
263    {
264       free(handle);
265       return NULL;
266    }
267 
268    handle->buffer                = buf;
269 
270    memcpy(handle->buffer, handle->retro_buffer, handle->bufsize);
271 
272    handle->lock                  = slock_new();
273    handle->cond_lock             = slock_new();
274    handle->cond                  = scond_new();
275    handle->thread                = sthread_create(autosave_thread, handle);
276 
277    return handle;
278 }
279 
280 /**
281  * autosave_free:
282  * @handle          : pointer to autosave object
283  *
284  * Frees autosave object.
285  **/
autosave_free(autosave_t * handle)286 static void autosave_free(autosave_t *handle)
287 {
288    slock_lock(handle->cond_lock);
289    handle->quit = true;
290    slock_unlock(handle->cond_lock);
291    scond_signal(handle->cond);
292    sthread_join(handle->thread);
293 
294    slock_free(handle->lock);
295    slock_free(handle->cond_lock);
296    scond_free(handle->cond);
297 
298    if (handle->buffer)
299       free(handle->buffer);
300    handle->buffer = NULL;
301 }
302 
autosave_init(void)303 bool autosave_init(void)
304 {
305    unsigned i;
306    autosave_t **list          = NULL;
307    settings_t *settings       = config_get_ptr();
308    unsigned autosave_interval = settings->uints.autosave_interval;
309 #if defined(HAVE_ZLIB)
310    bool compress_files        = settings->bools.save_file_compression;
311 #else
312    bool compress_files        = false;
313 #endif
314 
315    if (autosave_interval < 1 || !task_save_files)
316       return false;
317 
318    list                       = (autosave_t**)
319       calloc(task_save_files->size,
320             sizeof(*autosave_state.list));
321 
322    if (!list)
323       return false;
324 
325    autosave_state.list = list;
326    autosave_state.num  = (unsigned)task_save_files->size;
327 
328    for (i = 0; i < task_save_files->size; i++)
329    {
330       retro_ctx_memory_info_t mem_info;
331       autosave_t *auto_st = NULL;
332       const char *path    = task_save_files->elems[i].data;
333       unsigned    type    = task_save_files->elems[i].attr.i;
334 
335       mem_info.id         = type;
336 
337       core_get_memory(&mem_info);
338 
339       if (mem_info.size <= 0)
340          continue;
341 
342       auto_st             = autosave_new(path,
343             mem_info.data,
344             mem_info.size,
345             autosave_interval,
346             compress_files);
347 
348       if (!auto_st)
349       {
350          RARCH_WARN("%s\n", msg_hash_to_str(MSG_AUTOSAVE_FAILED));
351          continue;
352       }
353 
354       autosave_state.list[i] = auto_st;
355    }
356 
357    return true;
358 }
359 
autosave_deinit(void)360 void autosave_deinit(void)
361 {
362    unsigned i;
363 
364    for (i = 0; i < autosave_state.num; i++)
365    {
366       autosave_t *handle = autosave_state.list[i];
367       if (handle)
368       {
369          autosave_free(handle);
370          free(autosave_state.list[i]);
371       }
372       autosave_state.list[i] = NULL;
373    }
374 
375    free(autosave_state.list);
376 
377    autosave_state.list     = NULL;
378    autosave_state.num      = 0;
379 }
380 
381 /**
382  * autosave_lock:
383  *
384  * Lock autosave.
385  **/
autosave_lock(void)386 void autosave_lock(void)
387 {
388    unsigned i;
389 
390    for (i = 0; i < autosave_state.num; i++)
391    {
392       autosave_t *handle = autosave_state.list[i];
393       if (handle)
394          slock_lock(handle->lock);
395    }
396 }
397 
398 /**
399  * autosave_unlock:
400  *
401  * Unlocks autosave.
402  **/
autosave_unlock(void)403 void autosave_unlock(void)
404 {
405    unsigned i;
406 
407    for (i = 0; i < autosave_state.num; i++)
408    {
409       autosave_t *handle = autosave_state.list[i];
410       if (handle)
411          slock_unlock(handle->lock);
412    }
413 }
414 #endif
415 
416 /**
417  * undo_load_state:
418  * Revert to the state before a state was loaded.
419  *
420  * Returns: true if successful, false otherwise.
421  **/
content_undo_load_state(void)422 bool content_undo_load_state(void)
423 {
424    unsigned i;
425    size_t temp_data_size;
426    bool ret                  = false;
427    unsigned num_blocks       = 0;
428    void* temp_data           = NULL;
429    struct sram_block *blocks = NULL;
430    settings_t *settings      = config_get_ptr();
431    bool block_sram_overwrite = settings->bools.block_sram_overwrite;
432 
433    RARCH_LOG("[State]: %s \"%s\", %u %s.\n",
434          msg_hash_to_str(MSG_LOADING_STATE),
435          undo_load_buf.path,
436          (unsigned)undo_load_buf.size,
437          msg_hash_to_str(MSG_BYTES));
438 
439    /* TODO/FIXME - This checking of SRAM overwrite,
440     * the backing up of it and
441     * its flushing could all be in their
442     * own functions... */
443    if (block_sram_overwrite && task_save_files
444          && task_save_files->size)
445    {
446       RARCH_LOG("[SRAM]: %s.\n",
447             msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE));
448       blocks = (struct sram_block*)
449          calloc(task_save_files->size, sizeof(*blocks));
450 
451       if (blocks)
452       {
453          num_blocks = (unsigned)task_save_files->size;
454          for (i = 0; i < num_blocks; i++)
455             blocks[i].type = task_save_files->elems[i].attr.i;
456       }
457    }
458 
459    for (i = 0; i < num_blocks; i++)
460    {
461       retro_ctx_memory_info_t    mem_info;
462 
463       mem_info.id = blocks[i].type;
464       core_get_memory(&mem_info);
465 
466       blocks[i].size = mem_info.size;
467    }
468 
469    for (i = 0; i < num_blocks; i++)
470       if (blocks[i].size)
471          blocks[i].data = malloc(blocks[i].size);
472 
473    /* Backup current SRAM which is overwritten by unserialize. */
474    for (i = 0; i < num_blocks; i++)
475    {
476       if (blocks[i].data)
477       {
478          retro_ctx_memory_info_t    mem_info;
479          const void *ptr = NULL;
480 
481          mem_info.id = blocks[i].type;
482 
483          core_get_memory(&mem_info);
484 
485          ptr = mem_info.data;
486          if (ptr)
487             memcpy(blocks[i].data, ptr, blocks[i].size);
488       }
489    }
490 
491    /* We need to make a temporary copy of the buffer, to allow the swap below */
492    temp_data              = malloc(undo_load_buf.size);
493    temp_data_size         = undo_load_buf.size;
494    memcpy(temp_data, undo_load_buf.data, undo_load_buf.size);
495 
496    /* Swap the current state with the backup state. This way, we can undo
497    what we're undoing */
498    content_save_state("RAM", false, false);
499 
500    ret                    = content_deserialize_state(temp_data, temp_data_size);
501 
502    /* Clean up the temporary copy */
503    free(temp_data);
504    temp_data              = NULL;
505 
506     /* Flush back. */
507    for (i = 0; i < num_blocks; i++)
508    {
509       if (blocks[i].data)
510       {
511          retro_ctx_memory_info_t    mem_info;
512          void *ptr   = NULL;
513 
514          mem_info.id = blocks[i].type;
515 
516          core_get_memory(&mem_info);
517 
518          ptr = mem_info.data;
519          if (ptr)
520             memcpy(ptr, blocks[i].data, blocks[i].size);
521       }
522    }
523 
524    for (i = 0; i < num_blocks; i++)
525       free(blocks[i].data);
526    free(blocks);
527 
528    if (!ret)
529    {
530       RARCH_ERR("[State]: %s \"%s\".\n",
531          msg_hash_to_str(MSG_FAILED_TO_UNDO_LOAD_STATE),
532          undo_load_buf.path);
533    }
534 
535    return ret;
536 }
537 
undo_save_state_cb(retro_task_t * task,void * task_data,void * user_data,const char * error)538 static void undo_save_state_cb(retro_task_t *task,
539       void *task_data,
540       void *user_data, const char *error)
541 {
542    save_task_state_t *state = (save_task_state_t*)task_data;
543 
544    /* Wipe the save file buffer as it's intended to be one use only */
545    undo_save_buf.path[0] = '\0';
546    undo_save_buf.size    = 0;
547    if (undo_save_buf.data)
548    {
549       free(undo_save_buf.data);
550       undo_save_buf.data = NULL;
551    }
552 
553    free(state);
554 }
555 
556 /**
557  * task_save_handler_finished:
558  * @task : the task to finish
559  * @state : the state associated with this task
560  *
561  * Close the save state file and finish the task.
562  **/
task_save_handler_finished(retro_task_t * task,save_task_state_t * state)563 static void task_save_handler_finished(retro_task_t *task,
564       save_task_state_t *state)
565 {
566    save_task_state_t *task_data = NULL;
567 
568    task_set_finished(task, true);
569 
570    intfstream_close(state->file);
571    free(state->file);
572 
573    if (!task_get_error(task) && task_get_cancelled(task))
574       task_set_error(task, strdup("Task canceled"));
575 
576    task_data = (save_task_state_t*)calloc(1, sizeof(*task_data));
577    memcpy(task_data, state, sizeof(*state));
578 
579    task_set_data(task, task_data);
580 
581    if (state->data)
582    {
583       if (state->undo_save && state->data == undo_save_buf.data)
584          undo_save_buf.data = NULL;
585       free(state->data);
586       state->data = NULL;
587    }
588 
589    free(state);
590 }
591 
content_align_size(size_t size)592 static size_t content_align_size(size_t size)
593 {
594    /* align to 8-byte boundary */
595    return ((size + 7) & ~7);
596 }
597 
content_get_rastate_size(rastate_size_info_t * size)598 static bool content_get_rastate_size(rastate_size_info_t* size)
599 {
600    retro_ctx_size_info_t info;
601 
602    core_serialize_size(&info);
603    if (!info.size)
604       return false;
605 
606    size->coremem_size = info.size;
607    /* 8-byte identifier, 8-byte block header, content, 8-byte terminator */
608    size->total_size = 8 + 8 + content_align_size(info.size) + 8;
609 
610 #ifdef HAVE_CHEEVOS
611    size->cheevos_size = rcheevos_get_serialize_size();
612    if (size->cheevos_size > 0)
613       size->total_size += 8 + content_align_size(size->cheevos_size); /* 8-byte block header + content */
614 #endif
615 
616    return true;
617 }
618 
content_get_serialized_size(void)619 size_t content_get_serialized_size(void)
620 {
621    rastate_size_info_t size;
622    if (!content_get_rastate_size(&size))
623       return 0;
624 
625    return size.total_size;
626 }
627 
content_write_block_header(unsigned char * output,const char * header,size_t size)628 static void content_write_block_header(unsigned char* output, const char* header, size_t size)
629 {
630    memcpy(output, header, 4);
631    output[4] = ((size) & 0xFF);
632    output[5] = ((size >> 8) & 0xFF);
633    output[6] = ((size >> 16) & 0xFF);
634    output[7] = ((size >> 24) & 0xFF);
635 }
636 
content_write_serialized_state(void * buffer,rastate_size_info_t * size)637 static bool content_write_serialized_state(void* buffer, rastate_size_info_t* size)
638 {
639    retro_ctx_serialize_info_t serial_info;
640    unsigned char* output = (unsigned char*)buffer;
641 
642    /* 8-byte identifier "RASTATE1" where 1 is the version */
643    memcpy(output, "RASTATE", 7);
644    output[7] = RASTATE_VERSION;
645    output += 8;
646 
647    /* important - write the unaligned size - some cores fail if they aren't passed the exact right size. */
648    content_write_block_header(output, RASTATE_MEM_BLOCK, size->coremem_size);
649    output += 8;
650 
651    /* important - pass the unaligned size to the core. some fail if it isn't exactly what they're expecting. */
652    serial_info.size = size->coremem_size;
653    serial_info.data = (void*)output;
654    if (!core_serialize(&serial_info))
655       return false;
656 
657    output += content_align_size(size->coremem_size);
658 
659 #ifdef HAVE_CHEEVOS
660    if (size->cheevos_size)
661    {
662       content_write_block_header(output, RASTATE_CHEEVOS_BLOCK, size->cheevos_size);
663 
664       if (rcheevos_get_serialized_data(output + 8))
665          output += content_align_size(size->cheevos_size) + 8;
666    }
667 #endif
668 
669    content_write_block_header(output, RASTATE_END_BLOCK, 0);
670 
671    return true;
672 }
673 
content_serialize_state(void * buffer,size_t buffer_size)674 bool content_serialize_state(void* buffer, size_t buffer_size)
675 {
676    rastate_size_info_t size;
677    if (!content_get_rastate_size(&size))
678       return false;
679 
680    if (size.total_size > buffer_size)
681       return false;
682 
683    return content_write_serialized_state(buffer, &size);
684 }
685 
content_get_serialized_data(size_t * serial_size)686 static void *content_get_serialized_data(size_t* serial_size)
687 {
688    void* data;
689 
690    rastate_size_info_t size;
691    if (!content_get_rastate_size(&size))
692       return NULL;
693 
694    /* Ensure buffer is initialised to zero
695     * > Prevents inconsistent compressed state file
696     *   sizes when core requests a larger buffer
697     *   than it needs (and leaves the excess
698     *   as uninitialised garbage) */
699    data = calloc(size.total_size, 1);
700    if (!data)
701       return NULL;
702 
703    if (!content_write_serialized_state(data, &size))
704    {
705       free(data);
706       return NULL;
707    }
708 
709    *serial_size = size.total_size;
710    return data;
711 }
712 
713 /**
714  * task_save_handler:
715  * @task : the task being worked on
716  *
717  * Write a chunk of data to the save state file.
718  **/
task_save_handler(retro_task_t * task)719 static void task_save_handler(retro_task_t *task)
720 {
721    int written;
722    ssize_t remaining;
723    save_task_state_t *state = (save_task_state_t*)task->state;
724 
725    if (!state->file)
726    {
727       if (state->compress_files)
728          state->file   = intfstream_open_rzip_file(
729                state->path, RETRO_VFS_FILE_ACCESS_WRITE);
730       else
731          state->file   = intfstream_open_file(
732                state->path, RETRO_VFS_FILE_ACCESS_WRITE,
733                RETRO_VFS_FILE_ACCESS_HINT_NONE);
734 
735       if (!state->file)
736          return;
737    }
738 
739    if (!state->data)
740    {
741       size_t size;
742       state->data = content_get_serialized_data(&size);
743       state->size = (ssize_t)size;
744    }
745 
746    remaining       = MIN(state->size - state->written, SAVE_STATE_CHUNK);
747 
748    if (state->data)
749       written      = (int)intfstream_write(state->file,
750          (uint8_t*)state->data + state->written, remaining);
751    else
752       written      = 0;
753 
754    state->written += written;
755 
756    task_set_progress(task, (state->written / (float)state->size) * 100);
757 
758    if (task_get_cancelled(task) || written != remaining)
759    {
760       size_t err_size = 8192 * sizeof(char);
761       char *err       = (char*)malloc(err_size);
762       err[0]          = '\0';
763 
764       if (state->undo_save)
765       {
766          RARCH_ERR("[State]: %s \"%s\".\n",
767             msg_hash_to_str(MSG_FAILED_TO_UNDO_SAVE_STATE),
768             undo_save_buf.path);
769 
770          snprintf(err, err_size - 1, "%s \"%s\".",
771                   msg_hash_to_str(MSG_FAILED_TO_UNDO_SAVE_STATE),
772                   "RAM");
773       }
774       else
775          snprintf(err, err_size - 1,
776                "%s %s",
777                msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO), state->path);
778 
779       task_set_error(task, strdup(err));
780       free(err);
781       task_save_handler_finished(task, state);
782       return;
783    }
784 
785    if (state->written == state->size)
786    {
787       char       *msg      = NULL;
788 
789       task_free_title(task);
790 
791       if (state->undo_save)
792          msg = strdup(msg_hash_to_str(MSG_RESTORED_OLD_SAVE_STATE));
793       else if (state->state_slot < 0)
794          msg = strdup(msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT_AUTO));
795       else
796       {
797          char new_msg[128];
798          new_msg[0] = '\0';
799 
800          snprintf(new_msg, sizeof(new_msg), msg_hash_to_str(MSG_SAVED_STATE_TO_SLOT),
801                state->state_slot);
802          msg = strdup(new_msg);
803       }
804 
805       if (!task_get_mute(task) && msg)
806       {
807          task_set_title(task, msg);
808          msg = NULL;
809       }
810 
811       task_save_handler_finished(task, state);
812 
813       if (!string_is_empty(msg))
814          free(msg);
815 
816       return;
817    }
818 }
819 
820 /**
821  * task_push_undo_save_state:
822  * @path : file path of the save state
823  * @data : the save state data to write
824  * @size : the total size of the save state
825  *
826  * Create a new task to undo the last save of the content state.
827  **/
task_push_undo_save_state(const char * path,void * data,size_t size)828 static bool task_push_undo_save_state(const char *path, void *data, size_t size)
829 {
830    retro_task_t       *task = task_init();
831    save_task_state_t *state = (save_task_state_t*)calloc(1, sizeof(*state));
832    settings_t     *settings = config_get_ptr();
833 #if defined(HAVE_ZLIB)
834    bool compress_files      = settings->bools.savestate_file_compression;
835 #else
836    bool compress_files      = false;
837 #endif
838 
839    if (!task || !state)
840       goto error;
841 
842    strlcpy(state->path, path, sizeof(state->path));
843    state->data                   = data;
844    state->size                   = size;
845    state->undo_save              = true;
846    state->state_slot             = settings->ints.state_slot;
847    state->has_valid_framebuffer  = video_driver_cached_frame_has_valid_framebuffer();
848    state->compress_files         = compress_files;
849 
850    task->type                    = TASK_TYPE_BLOCKING;
851    task->state                   = state;
852    task->handler                 = task_save_handler;
853    task->callback                = undo_save_state_cb;
854    task->title                   = strdup(msg_hash_to_str(MSG_UNDOING_SAVE_STATE));
855 
856    task_queue_push(task);
857 
858    return true;
859 
860 error:
861    if (data)
862       free(data);
863    if (state)
864       free(state);
865    if (task)
866       free(task);
867 
868    return false;
869 }
870 
871 /**
872  * undo_save_state:
873  * Reverts the last save operation
874  *
875  * Returns: true if successful, false otherwise.
876  **/
content_undo_save_state(void)877 bool content_undo_save_state(void)
878 {
879    return task_push_undo_save_state(undo_save_buf.path,
880                              undo_save_buf.data,
881                              undo_save_buf.size);
882 }
883 
884 /**
885  * task_load_handler_finished:
886  * @task : the task to finish
887  * @state : the state associated with this task
888  *
889  * Close the loaded state file and finish the task.
890  **/
task_load_handler_finished(retro_task_t * task,save_task_state_t * state)891 static void task_load_handler_finished(retro_task_t *task,
892       save_task_state_t *state)
893 {
894    load_task_data_t *task_data = NULL;
895 
896    task_set_finished(task, true);
897 
898    if (state->file)
899    {
900       intfstream_close(state->file);
901       free(state->file);
902    }
903 
904    if (!task_get_error(task) && task_get_cancelled(task))
905       task_set_error(task, strdup("Task canceled"));
906 
907    task_data = (load_task_data_t*)calloc(1, sizeof(*task_data));
908 
909    if (!task_data)
910       return;
911 
912    memcpy(task_data, state, sizeof(*task_data));
913 
914    task_set_data(task, task_data);
915 
916    free(state);
917 }
918 
919 /**
920  * task_load_handler:
921  * @task : the task being worked on
922  *
923  * Load a chunk of data from the save state file.
924  **/
task_load_handler(retro_task_t * task)925 static void task_load_handler(retro_task_t *task)
926 {
927    ssize_t remaining, bytes_read;
928    save_task_state_t *state = (save_task_state_t*)task->state;
929 
930    if (!state->file)
931    {
932 #if defined(HAVE_ZLIB)
933       /* Always use RZIP interface when reading state
934        * files - this will automatically handle uncompressed
935        * data */
936       state->file = intfstream_open_rzip_file(state->path,
937             RETRO_VFS_FILE_ACCESS_READ);
938 #else
939       state->file = intfstream_open_file(state->path,
940             RETRO_VFS_FILE_ACCESS_READ,
941             RETRO_VFS_FILE_ACCESS_HINT_NONE);
942 #endif
943 
944       if (!state->file)
945          goto end;
946 
947       state->size = intfstream_get_size(state->file);
948 
949       if (state->size < 0)
950          goto end;
951 
952       state->data = malloc(state->size + 1);
953 
954       if (!state->data)
955          goto end;
956    }
957 
958 #ifdef HAVE_CHEEVOS
959    if (rcheevos_hardcore_active())
960       task_set_cancelled(task, true);
961 #endif
962 
963    remaining          = MIN(state->size - state->bytes_read, SAVE_STATE_CHUNK);
964    bytes_read         = intfstream_read(state->file,
965          (uint8_t*)state->data + state->bytes_read, remaining);
966    state->bytes_read += bytes_read;
967 
968    if (state->size > 0)
969       task_set_progress(task, (state->bytes_read / (float)state->size) * 100);
970 
971    if (task_get_cancelled(task) || bytes_read != remaining)
972    {
973       if (state->autoload)
974       {
975          char *msg = (char*)malloc(8192 * sizeof(char));
976 
977          msg[0] = '\0';
978 
979          snprintf(msg,
980                8192 * sizeof(char),
981                "%s \"%s\" %s.",
982                msg_hash_to_str(MSG_AUTOLOADING_SAVESTATE_FROM),
983                state->path,
984                msg_hash_to_str(MSG_FAILED));
985          task_set_error(task, strdup(msg));
986          free(msg);
987       }
988       else
989          task_set_error(task, strdup(msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE)));
990 
991       free(state->data);
992       state->data = NULL;
993       task_load_handler_finished(task, state);
994       return;
995    }
996 
997    if (state->bytes_read == state->size)
998    {
999       task_free_title(task);
1000 
1001       if (!task_get_mute(task))
1002       {
1003          size_t msg_size   = 8192 * sizeof(char);
1004          char *msg         = (char*)malloc(msg_size);
1005 
1006          msg[0]            = '\0';
1007 
1008          if (state->autoload)
1009             snprintf(msg, msg_size - 1,
1010                   "%s \"%s\" %s.",
1011                   msg_hash_to_str(MSG_AUTOLOADING_SAVESTATE_FROM),
1012                   state->path,
1013                   msg_hash_to_str(MSG_SUCCEEDED));
1014          else
1015          {
1016             if (state->state_slot < 0)
1017                strlcpy(msg, msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT_AUTO),
1018                      msg_size - 1);
1019             else
1020                snprintf(msg, msg_size - 1,
1021                      msg_hash_to_str(MSG_LOADED_STATE_FROM_SLOT),
1022                      state->state_slot);
1023          }
1024 
1025          task_set_title(task, strdup(msg));
1026          free(msg);
1027       }
1028 
1029       goto end;
1030    }
1031 
1032    return;
1033 
1034 end:
1035    task_load_handler_finished(task, state);
1036 }
1037 
content_load_rastate1(unsigned char * input,size_t size)1038 static bool content_load_rastate1(unsigned char* input, size_t size)
1039 {
1040    unsigned char* stop = input + size;
1041    unsigned char* marker;
1042    bool seen_core = false;
1043 #ifdef HAVE_CHEEVOS
1044    bool seen_cheevos = false;
1045 #endif
1046 
1047    input += 8;
1048    while (input < stop)
1049    {
1050       size_t block_size = (input[7] << 24 | input[6] << 16 | input[5] << 8 | input[4]);
1051       marker = input;
1052       input += 8;
1053 
1054       if (memcmp(marker, RASTATE_MEM_BLOCK, 4) == 0)
1055       {
1056          retro_ctx_serialize_info_t serial_info;
1057          serial_info.data_const = (void*)input;
1058          serial_info.size = block_size;
1059          if (!core_unserialize(&serial_info))
1060             return false;
1061 
1062          seen_core = true;
1063       }
1064 #ifdef HAVE_CHEEVOS
1065       else if (memcmp(marker, RASTATE_CHEEVOS_BLOCK, 4) == 0)
1066       {
1067          if (rcheevos_set_serialized_data((void*)input))
1068             seen_cheevos = true;
1069       }
1070 #endif
1071       else if (memcmp(marker, RASTATE_END_BLOCK, 4) == 0)
1072       {
1073          break;
1074       }
1075 
1076       input += content_align_size(block_size);
1077    }
1078 
1079    if (!seen_core)
1080       return false;
1081 
1082 #ifdef HAVE_CHEEVOS
1083    if (!seen_cheevos)
1084       rcheevos_set_serialized_data(NULL);
1085 #endif
1086 
1087    return true;
1088 }
1089 
content_deserialize_state(const void * serialized_data,size_t serialized_size)1090 bool content_deserialize_state(const void* serialized_data, size_t serialized_size)
1091 {
1092    if (memcmp(serialized_data, "RASTATE", 7) != 0)
1093    {
1094       /* old format is just core data, load it directly */
1095       retro_ctx_serialize_info_t serial_info;
1096       serial_info.data_const = serialized_data;
1097       serial_info.size = serialized_size;
1098       if (!core_unserialize(&serial_info))
1099          return false;
1100 
1101 #ifdef HAVE_CHEEVOS
1102       rcheevos_set_serialized_data(NULL);
1103 #endif
1104    }
1105    else
1106    {
1107       unsigned char* input = (unsigned char*)serialized_data;
1108       switch (input[7]) /* version */
1109       {
1110          case 1:
1111             if (!content_load_rastate1(input, serialized_size))
1112                return false;
1113             break;
1114 
1115          default:
1116             return false;
1117       }
1118    }
1119 
1120    return true;
1121 }
1122 
1123 /**
1124  * content_load_state_cb:
1125  * @path      : path that state will be loaded from.
1126  * Load a state from disk to memory.
1127  *
1128  **/
content_load_state_cb(retro_task_t * task,void * task_data,void * user_data,const char * error)1129 static void content_load_state_cb(retro_task_t *task,
1130       void *task_data,
1131       void *user_data, const char *error)
1132 {
1133    unsigned i;
1134    bool ret;
1135    load_task_data_t *load_data = (load_task_data_t*)task_data;
1136    ssize_t size                = load_data->size;
1137    unsigned num_blocks         = 0;
1138    void *buf                   = load_data->data;
1139    struct sram_block *blocks   = NULL;
1140    settings_t *settings        = config_get_ptr();
1141    bool block_sram_overwrite   = settings->bools.block_sram_overwrite;
1142 
1143 #ifdef HAVE_CHEEVOS
1144    if (rcheevos_hardcore_active())
1145       goto error;
1146 #endif
1147 
1148    RARCH_LOG("[State]: %s \"%s\", %u %s.\n",
1149          msg_hash_to_str(MSG_LOADING_STATE),
1150          load_data->path,
1151          (unsigned)size,
1152          msg_hash_to_str(MSG_BYTES));
1153 
1154    if (size < 0 || !buf)
1155       goto error;
1156 
1157    /* This means we're backing up the file in memory,
1158     * so content_undo_save_state()
1159     * can restore it */
1160    if (load_data->load_to_backup_buffer)
1161    {
1162       /* If we were previously backing up a file, let go of it first */
1163       if (undo_save_buf.data)
1164       {
1165          free(undo_save_buf.data);
1166          undo_save_buf.data = NULL;
1167       }
1168 
1169       undo_save_buf.data = malloc(size);
1170       if (!undo_save_buf.data)
1171          goto error;
1172 
1173       memcpy(undo_save_buf.data, buf, size);
1174       undo_save_buf.size = size;
1175       strlcpy(undo_save_buf.path, load_data->path, sizeof(undo_save_buf.path));
1176 
1177       free(buf);
1178       free(load_data);
1179       return;
1180    }
1181 
1182    if (block_sram_overwrite && task_save_files
1183          && task_save_files->size)
1184    {
1185       RARCH_LOG("[SRAM]: %s.\n",
1186             msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE));
1187       blocks = (struct sram_block*)
1188          calloc(task_save_files->size, sizeof(*blocks));
1189 
1190       if (blocks)
1191       {
1192          num_blocks = (unsigned)task_save_files->size;
1193          for (i = 0; i < num_blocks; i++)
1194             blocks[i].type = task_save_files->elems[i].attr.i;
1195       }
1196    }
1197 
1198    for (i = 0; i < num_blocks; i++)
1199    {
1200       retro_ctx_memory_info_t    mem_info;
1201 
1202       mem_info.id = blocks[i].type;
1203       core_get_memory(&mem_info);
1204 
1205       blocks[i].size = mem_info.size;
1206    }
1207 
1208    for (i = 0; i < num_blocks; i++)
1209       if (blocks[i].size)
1210          blocks[i].data = malloc(blocks[i].size);
1211 
1212    /* Backup current SRAM which is overwritten by unserialize. */
1213    for (i = 0; i < num_blocks; i++)
1214    {
1215       if (blocks[i].data)
1216       {
1217          retro_ctx_memory_info_t    mem_info;
1218          const void *ptr = NULL;
1219 
1220          mem_info.id = blocks[i].type;
1221 
1222          core_get_memory(&mem_info);
1223 
1224          ptr = mem_info.data;
1225          if (ptr)
1226             memcpy(blocks[i].data, ptr, blocks[i].size);
1227       }
1228    }
1229 
1230    /* Backup the current state so we can undo this load */
1231    content_save_state("RAM", false, false);
1232 
1233    ret = content_deserialize_state(buf, size);
1234 
1235    /* Flush back. */
1236    for (i = 0; i < num_blocks; i++)
1237    {
1238       if (blocks[i].data)
1239       {
1240          retro_ctx_memory_info_t    mem_info;
1241          void *ptr = NULL;
1242 
1243          mem_info.id = blocks[i].type;
1244 
1245          core_get_memory(&mem_info);
1246 
1247          ptr = mem_info.data;
1248          if (ptr)
1249             memcpy(ptr, blocks[i].data, blocks[i].size);
1250       }
1251    }
1252 
1253    for (i = 0; i < num_blocks; i++)
1254       free(blocks[i].data);
1255    free(blocks);
1256 
1257    if (!ret)
1258       goto error;
1259 
1260    free(buf);
1261    free(load_data);
1262 
1263    return;
1264 
1265 error:
1266    RARCH_ERR("[State]: %s \"%s\".\n",
1267          msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE),
1268          load_data->path);
1269    if (buf)
1270       free(buf);
1271    free(load_data);
1272 }
1273 
1274 /**
1275  * save_state_cb:
1276  *
1277  * Called after the save state is done. Takes a screenshot if needed.
1278  **/
save_state_cb(retro_task_t * task,void * task_data,void * user_data,const char * error)1279 static void save_state_cb(retro_task_t *task,
1280       void *task_data,
1281       void *user_data, const char *error)
1282 {
1283    save_task_state_t *state   = (save_task_state_t*)task_data;
1284 #ifdef HAVE_SCREENSHOTS
1285    char               *path   = strdup(state->path);
1286    settings_t     *settings   = config_get_ptr();
1287    const char *dir_screenshot = settings->paths.directory_screenshot;
1288 
1289    if (state->thumbnail_enable)
1290       take_screenshot(dir_screenshot,
1291             path, true, state->has_valid_framebuffer, false, true);
1292    free(path);
1293 #endif
1294 
1295    free(state);
1296 }
1297 
1298 /**
1299  * task_push_save_state:
1300  * @path : file path of the save state
1301  * @data : the save state data to write
1302  * @size : the total size of the save state
1303  *
1304  * Create a new task to save the content state.
1305  **/
task_push_save_state(const char * path,void * data,size_t size,bool autosave)1306 static void task_push_save_state(const char *path, void *data, size_t size, bool autosave)
1307 {
1308    retro_task_t       *task        = task_init();
1309    save_task_state_t *state        = (save_task_state_t*)calloc(1, sizeof(*state));
1310    settings_t     *settings        = config_get_ptr();
1311    bool savestate_thumbnail_enable = settings->bools.savestate_thumbnail_enable;
1312    int state_slot                  = settings->ints.state_slot;
1313 #if defined(HAVE_ZLIB)
1314    bool compress_files             = settings->bools.savestate_file_compression;
1315 #else
1316    bool compress_files             = false;
1317 #endif
1318 
1319    if (!task || !state)
1320       goto error;
1321 
1322    strlcpy(state->path, path, sizeof(state->path));
1323    state->data                   = data;
1324    state->size                   = size;
1325    state->autosave               = autosave;
1326    state->mute                   = autosave; /* don't show OSD messages if we are auto-saving */
1327    state->thumbnail_enable       = savestate_thumbnail_enable;
1328    state->state_slot             = state_slot;
1329    state->has_valid_framebuffer  = video_driver_cached_frame_has_valid_framebuffer();
1330    state->compress_files         = compress_files;
1331 
1332    task->type              = TASK_TYPE_BLOCKING;
1333    task->state             = state;
1334    task->handler           = task_save_handler;
1335    task->callback          = save_state_cb;
1336    task->title             = strdup(msg_hash_to_str(MSG_SAVING_STATE));
1337    task->mute              = state->mute;
1338 
1339    if (!task_queue_push(task))
1340    {
1341       /* Another blocking task is already active. */
1342       if (data)
1343          free(data);
1344       if (task->title)
1345          task_free_title(task);
1346       free(task);
1347       free(state);
1348    }
1349 
1350    return;
1351 
1352 error:
1353    if (data)
1354       free(data);
1355    if (state)
1356       free(state);
1357    if (task)
1358    {
1359       if (task->title)
1360          task_free_title(task);
1361       free(task);
1362    }
1363 }
1364 
1365 /**
1366  * content_load_and_save_state_cb:
1367  * @path      : path that state will be loaded from.
1368  * Load then save a state.
1369  *
1370  **/
content_load_and_save_state_cb(retro_task_t * task,void * task_data,void * user_data,const char * error)1371 static void content_load_and_save_state_cb(retro_task_t *task,
1372       void *task_data,
1373       void *user_data, const char *error)
1374 {
1375    load_task_data_t *load_data = (load_task_data_t*)task_data;
1376    char                  *path = strdup(load_data->path);
1377    void                  *data = load_data->undo_data;
1378    size_t                 size = load_data->undo_size;
1379    bool               autosave = load_data->autosave;
1380 
1381    content_load_state_cb(task, task_data, user_data, error);
1382 
1383    task_push_save_state(path, data, size, autosave);
1384 
1385    free(path);
1386 }
1387 
1388 /**
1389  * task_push_load_and_save_state:
1390  * @path : file path of the save state
1391  * @data : the save state data to write
1392  * @size : the total size of the save state
1393  * @load_to_backup_buffer : If true, the state will be loaded into undo_save_buf.
1394  *
1395  * Create a new task to load current state first into a backup buffer (for undo)
1396  * and then save the content state.
1397  **/
task_push_load_and_save_state(const char * path,void * data,size_t size,bool load_to_backup_buffer,bool autosave)1398 static void task_push_load_and_save_state(const char *path, void *data,
1399       size_t size, bool load_to_backup_buffer, bool autosave)
1400 {
1401    retro_task_t      *task     = NULL;
1402    settings_t        *settings = config_get_ptr();
1403    int state_slot              = settings->ints.state_slot;
1404 #if defined(HAVE_ZLIB)
1405    bool compress_files         = settings->bools.savestate_file_compression;
1406 #else
1407    bool compress_files         = false;
1408 #endif
1409    save_task_state_t *state    = (save_task_state_t*)
1410       calloc(1, sizeof(*state));
1411 
1412    if (!state)
1413       return;
1414 
1415    task                        = task_init();
1416 
1417    if (!task)
1418    {
1419       free(state);
1420       return;
1421    }
1422 
1423 
1424    strlcpy(state->path, path, sizeof(state->path));
1425    state->load_to_backup_buffer = load_to_backup_buffer;
1426    state->undo_size  = size;
1427    state->undo_data  = data;
1428    state->autosave   = autosave;
1429    state->mute       = autosave; /* don't show OSD messages if we
1430                                     are auto-saving */
1431    if (load_to_backup_buffer)
1432       state->mute                = true;
1433    state->state_slot             = state_slot;
1434    state->has_valid_framebuffer  =
1435       video_driver_cached_frame_has_valid_framebuffer();
1436    state->compress_files         = compress_files;
1437 
1438    task->state       = state;
1439    task->type        = TASK_TYPE_BLOCKING;
1440    task->handler     = task_load_handler;
1441    task->callback    = content_load_and_save_state_cb;
1442    task->title       = strdup(msg_hash_to_str(MSG_LOADING_STATE));
1443    task->mute        = state->mute;
1444 
1445    if (!task_queue_push(task))
1446    {
1447       /* Another blocking task is already active. */
1448       if (data)
1449          free(data);
1450       if (task->title)
1451          task_free_title(task);
1452       free(task);
1453       free(state);
1454    }
1455 }
1456 
1457 /**
1458  * content_save_state:
1459  * @path      : path of saved state that shall be written to.
1460  * @save_to_disk: If false, saves the state onto undo_load_buf.
1461  * Save a state from memory to disk.
1462  *
1463  * Returns: true if successful, false otherwise.
1464  **/
content_save_state(const char * path,bool save_to_disk,bool autosave)1465 bool content_save_state(const char *path, bool save_to_disk, bool autosave)
1466 {
1467    retro_ctx_size_info_t info;
1468    void *data  = NULL;
1469    size_t serial_size;
1470 
1471    core_serialize_size(&info);
1472 
1473    if (info.size == 0)
1474       return false;
1475    serial_size = info.size;
1476 
1477    if (!save_state_in_background)
1478    {
1479       data = content_get_serialized_data(&serial_size);
1480 
1481       if (!data)
1482       {
1483          RARCH_ERR("[State]: %s \"%s\".\n",
1484                msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
1485                path);
1486          return false;
1487       }
1488 
1489       RARCH_LOG("[State]: %s \"%s\", %u %s.\n",
1490             msg_hash_to_str(MSG_SAVING_STATE),
1491             path,
1492             (unsigned)serial_size,
1493             msg_hash_to_str(MSG_BYTES));
1494    }
1495 
1496    if (save_to_disk)
1497    {
1498       if (path_is_valid(path) && !autosave)
1499       {
1500          /* Before overwriting the savestate file, load it into a buffer
1501          to allow undo_save_state() to work */
1502          /* TODO/FIXME - Use msg_hash_to_str here */
1503          RARCH_LOG("[State]: %s ...\n",
1504                msg_hash_to_str(MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER));
1505 
1506          task_push_load_and_save_state(path, data, serial_size, true, autosave);
1507       }
1508       else
1509          task_push_save_state(path, data, serial_size, autosave);
1510    }
1511    else
1512    {
1513       if (!data)
1514          data = content_get_serialized_data(&serial_size);
1515 
1516       if (!data)
1517       {
1518          RARCH_ERR("[State]: %s \"%s\".\n",
1519                msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
1520                path);
1521          return false;
1522       }
1523       /* save_to_disk is false, which means we are saving the state
1524       in undo_load_buf to allow content_undo_load_state() to restore it */
1525 
1526       /* If we were holding onto an old state already, clean it up first */
1527       if (undo_load_buf.data)
1528       {
1529          free(undo_load_buf.data);
1530          undo_load_buf.data = NULL;
1531       }
1532 
1533       undo_load_buf.data = malloc(serial_size);
1534       if (!undo_load_buf.data)
1535       {
1536          free(data);
1537          return false;
1538       }
1539 
1540       memcpy(undo_load_buf.data, data, serial_size);
1541       free(data);
1542       undo_load_buf.size = serial_size;
1543       strlcpy(undo_load_buf.path, path, sizeof(undo_load_buf.path));
1544    }
1545 
1546    return true;
1547 }
1548 
task_save_state_finder(retro_task_t * task,void * user_data)1549 static bool task_save_state_finder(retro_task_t *task, void *user_data)
1550 {
1551    if (!task)
1552       return false;
1553 
1554    if (task->handler == task_save_handler)
1555       return true;
1556 
1557    return false;
1558 }
1559 
1560 /* Returns true if a save state task is in progress */
content_save_state_in_progress(void * data)1561 static bool content_save_state_in_progress(void* data)
1562 {
1563    task_finder_data_t find_data;
1564 
1565    find_data.func     = task_save_state_finder;
1566    find_data.userdata = NULL;
1567 
1568    if (task_queue_find(&find_data))
1569       return true;
1570 
1571    return false;
1572 }
1573 
content_wait_for_save_state_task(void)1574 void content_wait_for_save_state_task(void)
1575 {
1576    task_queue_wait(content_save_state_in_progress, NULL);
1577 }
1578 
1579 /**
1580  * content_load_state:
1581  * @path      : path that state will be loaded from.
1582  * @load_to_backup_buffer: If true, the state will be loaded into undo_save_buf.
1583  * Load a state from disk to memory.
1584  *
1585  * Returns: true if successful, false otherwise.
1586  *
1587  *
1588  **/
content_load_state(const char * path,bool load_to_backup_buffer,bool autoload)1589 bool content_load_state(const char *path,
1590       bool load_to_backup_buffer, bool autoload)
1591 {
1592    retro_task_t       *task     = task_init();
1593    save_task_state_t *state     = (save_task_state_t*)calloc(1, sizeof(*state));
1594    settings_t *settings         = config_get_ptr();
1595    int state_slot               = settings->ints.state_slot;
1596 #if defined(HAVE_ZLIB)
1597    bool compress_files          = settings->bools.savestate_file_compression;
1598 #else
1599    bool compress_files          = false;
1600 #endif
1601 
1602    if (!task || !state)
1603       goto error;
1604 
1605    strlcpy(state->path, path, sizeof(state->path));
1606    state->load_to_backup_buffer = load_to_backup_buffer;
1607    state->autoload              = autoload;
1608    state->state_slot            = state_slot;
1609    state->has_valid_framebuffer =
1610       video_driver_cached_frame_has_valid_framebuffer();
1611    state->compress_files        = compress_files;
1612 
1613    task->type                   = TASK_TYPE_BLOCKING;
1614    task->state                  = state;
1615    task->handler                = task_load_handler;
1616    task->callback               = content_load_state_cb;
1617    task->title                  = strdup(msg_hash_to_str(MSG_LOADING_STATE));
1618 
1619    task_queue_push(task);
1620 
1621    return true;
1622 
1623 error:
1624    if (state)
1625       free(state);
1626    if (task)
1627       free(task);
1628 
1629    return false;
1630 }
1631 
content_rename_state(const char * origin,const char * dest)1632 bool content_rename_state(const char *origin, const char *dest)
1633 {
1634    int ret = 0;
1635    if (filestream_exists(dest))
1636       filestream_delete(dest);
1637 
1638    ret = filestream_rename(origin, dest);
1639    if (!ret)
1640       return true;
1641 
1642    RARCH_ERR("[State]: Error %d renaming file \"%s\".\n", ret, origin);
1643    return false;
1644 }
1645 
1646 /*
1647 *
1648 * TODO/FIXME: Figure out when and where this should be called.
1649 * As it is, when e.g. closing Gambatte, we get the
1650 * same printf message 4 times.
1651 */
content_reset_savestate_backups(void)1652 bool content_reset_savestate_backups(void)
1653 {
1654    if (undo_save_buf.data)
1655    {
1656       free(undo_save_buf.data);
1657       undo_save_buf.data = NULL;
1658    }
1659 
1660    undo_save_buf.path[0] = '\0';
1661    undo_save_buf.size    = 0;
1662 
1663    if (undo_load_buf.data)
1664    {
1665       free(undo_load_buf.data);
1666       undo_load_buf.data = NULL;
1667    }
1668 
1669    undo_load_buf.path[0] = '\0';
1670    undo_load_buf.size    = 0;
1671 
1672    return true;
1673 }
1674 
content_undo_load_buf_is_empty(void)1675 bool content_undo_load_buf_is_empty(void)
1676 {
1677    return undo_load_buf.data == NULL || undo_load_buf.size == 0;
1678 }
1679 
content_undo_save_buf_is_empty(void)1680 bool content_undo_save_buf_is_empty(void)
1681 {
1682    return undo_save_buf.data == NULL || undo_save_buf.size == 0;
1683 }
1684 
content_get_memory(retro_ctx_memory_info_t * mem_info,struct ram_type * ram,unsigned slot)1685 static bool content_get_memory(retro_ctx_memory_info_t *mem_info,
1686       struct ram_type *ram, unsigned slot)
1687 {
1688    ram->type = task_save_files->elems[slot].attr.i;
1689    ram->path = task_save_files->elems[slot].data;
1690 
1691    mem_info->id  = ram->type;
1692 
1693    core_get_memory(mem_info);
1694 
1695    if (!mem_info->data || mem_info->size == 0)
1696       return false;
1697 
1698    return true;
1699 }
1700 
1701 /**
1702  * content_load_ram_file:
1703  * @path             : path of RAM state that will be loaded from.
1704  * @type             : type of memory
1705  *
1706  * Load a RAM state from disk to memory.
1707  */
content_load_ram_file(unsigned slot)1708 bool content_load_ram_file(unsigned slot)
1709 {
1710    int64_t rc;
1711    struct ram_type ram;
1712    retro_ctx_memory_info_t mem_info;
1713    void *buf        = NULL;
1714 
1715    if (!content_get_memory(&mem_info, &ram, slot))
1716       return false;
1717 
1718    /* On first run of content, SRAM file will
1719     * not exist. This is a common enough occurrence
1720     * that we should check before attempting to
1721     * invoke the relevant read_file() function */
1722    if (string_is_empty(ram.path) ||
1723        !path_is_valid(ram.path))
1724       return false;
1725 
1726 #if defined(HAVE_ZLIB)
1727    /* Always use RZIP interface when reading SRAM
1728     * files - this will automatically handle uncompressed
1729     * data */
1730    if (!rzipstream_read_file(ram.path, &buf, &rc))
1731 #else
1732    if (!filestream_read_file(ram.path, &buf, &rc))
1733 #endif
1734       return false;
1735 
1736    if (rc > 0)
1737    {
1738       if (rc > (ssize_t)mem_info.size)
1739       {
1740          RARCH_WARN("[SRAM]: SRAM is larger than implementation expects, "
1741                "doing partial load (truncating %u %s %s %u).\n",
1742                (unsigned)rc,
1743                msg_hash_to_str(MSG_BYTES),
1744                msg_hash_to_str(MSG_TO),
1745                (unsigned)mem_info.size);
1746          rc = mem_info.size;
1747       }
1748       memcpy(mem_info.data, buf, (size_t)rc);
1749    }
1750 
1751    if (buf)
1752       free(buf);
1753 
1754    return true;
1755 }
1756 
1757 /**
1758  * dump_to_file_desperate:
1759  * @data         : pointer to data buffer.
1760  * @size         : size of @data.
1761  * @type         : type of file to be saved.
1762  *
1763  * Attempt to save valuable RAM data somewhere.
1764  **/
dump_to_file_desperate(const void * data,size_t size,unsigned type)1765 static bool dump_to_file_desperate(const void *data,
1766       size_t size, unsigned type)
1767 {
1768    time_t time_;
1769    struct tm tm_;
1770    char timebuf[256];
1771    char path[PATH_MAX_LENGTH];
1772    char application_data[PATH_MAX_LENGTH];
1773 
1774    application_data[0]    = '\0';
1775    path            [0]    = '\0';
1776    timebuf         [0]    = '\0';
1777 
1778    if (!fill_pathname_application_data(application_data,
1779             sizeof(application_data)))
1780       return false;
1781 
1782    time(&time_);
1783 
1784    rtime_localtime(&time_, &tm_);
1785 
1786    strftime(timebuf,
1787          256 * sizeof(char),
1788          "%Y-%m-%d-%H-%M-%S", &tm_);
1789 
1790    snprintf(path, sizeof(path),
1791          "%s/RetroArch-recovery-%u%s",
1792          application_data, type,
1793          timebuf);
1794 
1795    /* Fallback (emergency) saves are always
1796     * uncompressed
1797     * > If a regular save fails, then the host
1798     *   system is experiencing serious technical
1799     *   difficulties (most likely some kind of
1800     *   hardware failure)
1801     * > In this case, we don't want to further
1802     *   complicate matters by introducing zlib
1803     *   compression overheads */
1804    if (!filestream_write_file(path, data, size))
1805       return false;
1806 
1807    RARCH_WARN("[SRAM]: Succeeded in saving RAM data to \"%s\".\n", path);
1808    return true;
1809 }
1810 
1811 /**
1812  * content_save_ram_file:
1813  * @path             : path of RAM state that shall be written to.
1814  * @type             : type of memory
1815  *
1816  * Save a RAM state from memory to disk.
1817  *
1818  */
content_save_ram_file(unsigned slot,bool compress)1819 bool content_save_ram_file(unsigned slot, bool compress)
1820 {
1821    struct ram_type ram;
1822    retro_ctx_memory_info_t mem_info;
1823    bool write_success;
1824 
1825    if (!content_get_memory(&mem_info, &ram, slot))
1826       return false;
1827 
1828    RARCH_LOG("[SRAM]: %s #%u %s \"%s\".\n",
1829          msg_hash_to_str(MSG_SAVING_RAM_TYPE),
1830          ram.type,
1831          msg_hash_to_str(MSG_TO),
1832          ram.path);
1833 
1834 #if defined(HAVE_ZLIB)
1835    if (compress)
1836       write_success = rzipstream_write_file(
1837             ram.path, mem_info.data, mem_info.size);
1838    else
1839 #endif
1840       write_success = filestream_write_file(
1841             ram.path, mem_info.data, mem_info.size);
1842 
1843    if (!write_success)
1844    {
1845       RARCH_ERR("[SRAM]: %s.\n",
1846             msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM));
1847       RARCH_WARN("[SRAM]: Attempting to recover ...\n");
1848 
1849       /* In case the file could not be written to,
1850        * the fallback function 'dump_to_file_desperate'
1851        * will be called. */
1852       if (!dump_to_file_desperate(
1853                mem_info.data, mem_info.size, ram.type))
1854       {
1855          RARCH_WARN("[SRAM]: Failed ... Cannot recover save file.\n");
1856       }
1857       return false;
1858    }
1859 
1860    RARCH_LOG("[SRAM]: %s \"%s\".\n",
1861          msg_hash_to_str(MSG_SAVED_SUCCESSFULLY_TO),
1862          ram.path);
1863 
1864    return true;
1865 }
1866 
event_save_files(bool is_sram_used)1867 bool event_save_files(bool is_sram_used)
1868 {
1869    unsigned i;
1870    settings_t *settings            = config_get_ptr();
1871 #ifdef HAVE_CHEATS
1872    const char *path_cheat_database = settings->paths.path_cheat_database;
1873 #endif
1874 #if defined(HAVE_ZLIB)
1875    bool compress_files             = settings->bools.save_file_compression;
1876 #else
1877    bool compress_files             = false;
1878 #endif
1879 
1880 #ifdef HAVE_CHEATS
1881    cheat_manager_save_game_specific_cheats(
1882          path_cheat_database);
1883 #endif
1884    if (!task_save_files || !is_sram_used)
1885       return false;
1886 
1887    for (i = 0; i < task_save_files->size; i++)
1888       content_save_ram_file(i, compress_files);
1889 
1890    return true;
1891 }
1892 
event_load_save_files(bool is_sram_load_disabled)1893 bool event_load_save_files(bool is_sram_load_disabled)
1894 {
1895    unsigned i;
1896 
1897    if (!task_save_files || is_sram_load_disabled)
1898       return false;
1899 
1900    for (i = 0; i < task_save_files->size; i++)
1901       content_load_ram_file(i);
1902 
1903    return true;
1904 }
1905 
path_init_savefile_rtc(const char * savefile_path)1906 void path_init_savefile_rtc(const char *savefile_path)
1907 {
1908    union string_list_elem_attr attr;
1909    char savefile_name_rtc[PATH_MAX_LENGTH];
1910 
1911    savefile_name_rtc[0] = '\0';
1912 
1913    attr.i = RETRO_MEMORY_SAVE_RAM;
1914    string_list_append(task_save_files, savefile_path, attr);
1915 
1916    /* Infer .rtc save path from save ram path. */
1917    attr.i = RETRO_MEMORY_RTC;
1918    fill_pathname(savefile_name_rtc,
1919          savefile_path, ".rtc",
1920          sizeof(savefile_name_rtc));
1921    string_list_append(task_save_files, savefile_name_rtc, attr);
1922 }
1923 
path_deinit_savefile(void)1924 void path_deinit_savefile(void)
1925 {
1926    if (task_save_files)
1927       string_list_free(task_save_files);
1928    task_save_files = NULL;
1929 }
1930 
path_init_savefile_new(void)1931 void path_init_savefile_new(void)
1932 {
1933    task_save_files = string_list_new();
1934    retro_assert(task_save_files);
1935 }
1936 
savefile_ptr_get(void)1937 void *savefile_ptr_get(void)
1938 {
1939    return task_save_files;
1940 }
1941 
set_save_state_in_background(bool state)1942 void set_save_state_in_background(bool state)
1943 {
1944    save_state_in_background = state;
1945 }
1946