mirror of
https://github.com/mupen64plus/mupen64plus-core.git
synced 2024-05-20 04:50:38 -04:00
176 lines
5.4 KiB
C
176 lines
5.4 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Mupen64plus - file_storage.c *
|
|
* Mupen64Plus homepage: https://mupen64plus.org/ *
|
|
* Copyright (C) 2016 Bobby Smiles *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
#include "file_storage.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "api/callbacks.h"
|
|
#include "api/m64p_types.h"
|
|
#include "backends/api/storage_backend.h"
|
|
#include "device/dd/dd_controller.h"
|
|
#include "main/util.h"
|
|
#include "main/netplay.h"
|
|
|
|
int open_file_storage(struct file_storage* fstorage, size_t size, const char* filename)
|
|
{
|
|
/* ! Take ownership of filename ! */
|
|
fstorage->filename = filename;
|
|
fstorage->size = size;
|
|
|
|
/* allocate memory for holding data */
|
|
fstorage->data = malloc(fstorage->size);
|
|
if (fstorage->data == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
/* try to load storage file content */
|
|
if (!netplay_is_init())
|
|
{
|
|
return read_from_file(fstorage->filename, fstorage->data, fstorage->size);
|
|
}
|
|
else
|
|
{
|
|
return netplay_read_storage(fstorage->filename, fstorage->data, fstorage->size);
|
|
}
|
|
}
|
|
|
|
int open_rom_file_storage(struct file_storage* fstorage, const char* filename)
|
|
{
|
|
fstorage->data = NULL;
|
|
fstorage->size = 0;
|
|
fstorage->filename = NULL;
|
|
|
|
file_status_t err = load_file(filename, (void**)&fstorage->data, &fstorage->size);
|
|
|
|
if (err == file_ok) {
|
|
/* ! take ownsership of filename ! */
|
|
fstorage->filename = filename;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
void close_file_storage(struct file_storage* fstorage)
|
|
{
|
|
free((void*)fstorage->data);
|
|
free((void*)fstorage->filename);
|
|
}
|
|
|
|
|
|
static uint8_t* file_storage_data(const void* storage)
|
|
{
|
|
struct file_storage* fstorage = (struct file_storage*)storage;
|
|
return fstorage->data;
|
|
}
|
|
|
|
static size_t file_storage_size(const void* storage)
|
|
{
|
|
struct file_storage* fstorage = (struct file_storage*)storage;
|
|
return fstorage->size;
|
|
}
|
|
|
|
static void file_storage_save(void* storage)
|
|
{
|
|
if (netplay_is_init() && netplay_get_controller(0) == -1)
|
|
return;
|
|
|
|
struct file_storage* fstorage = (struct file_storage*)storage;
|
|
|
|
switch(write_to_file(fstorage->filename, fstorage->data, fstorage->size))
|
|
{
|
|
case file_open_error:
|
|
DebugMessage(M64MSG_WARNING, "couldn't open storage file '%s' for writing", fstorage->filename);
|
|
break;
|
|
case file_write_error:
|
|
DebugMessage(M64MSG_WARNING, "failed to write storage file '%s'", fstorage->filename);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void file_storage_parent_save(void* storage)
|
|
{
|
|
struct file_storage* fstorage = (struct file_storage*)((struct file_storage*)storage)->filename;
|
|
file_storage_save(fstorage);
|
|
}
|
|
|
|
static void file_storage_dd_sdk_dump_save(void* storage)
|
|
{
|
|
static uint8_t sdk_buffer[SDK_FORMAT_DUMP_SIZE];
|
|
struct file_storage* fstorage = (struct file_storage*)storage;
|
|
|
|
/* XXX: for now, don't overwrite the original file, because we don't want to corrupt dumps... */
|
|
char* filename = formatstr("%s.save", fstorage->filename);
|
|
if (filename == NULL) {
|
|
DebugMessage(M64MSG_ERROR, "Failed to allocate memory for sdk_dump filename");
|
|
return;
|
|
}
|
|
|
|
dd_convert_to_sdk(fstorage->data, sdk_buffer);
|
|
|
|
switch(write_to_file(filename, sdk_buffer, SDK_FORMAT_DUMP_SIZE))
|
|
{
|
|
case file_open_error:
|
|
DebugMessage(M64MSG_WARNING, "couldn't open storage file '%s' for writing", fstorage->filename);
|
|
break;
|
|
case file_write_error:
|
|
DebugMessage(M64MSG_WARNING, "failed to write storage file '%s'", fstorage->filename);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
free(filename);
|
|
}
|
|
|
|
|
|
|
|
const struct storage_backend_interface g_ifile_storage =
|
|
{
|
|
file_storage_data,
|
|
file_storage_size,
|
|
file_storage_save
|
|
};
|
|
|
|
|
|
const struct storage_backend_interface g_ifile_storage_ro =
|
|
{
|
|
file_storage_data,
|
|
file_storage_size,
|
|
NULL
|
|
};
|
|
|
|
const struct storage_backend_interface g_isubfile_storage =
|
|
{
|
|
file_storage_data,
|
|
file_storage_size,
|
|
file_storage_parent_save
|
|
};
|
|
|
|
const struct storage_backend_interface g_ifile_storage_dd_sdk_dump =
|
|
{
|
|
file_storage_data,
|
|
file_storage_size,
|
|
file_storage_dd_sdk_dump_save
|
|
};
|