mirror of
https://github.com/array-in-a-matrix/SAROO.git
synced 2025-04-02 10:31:43 -04:00
244 lines
4.3 KiB
C
244 lines
4.3 KiB
C
|
|
#include "stdio.h"
|
|
#include "stdlib.h"
|
|
#include "string.h"
|
|
#include "bup.h"
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
static u8 bup_mem[32768];
|
|
static int ss_bup_type;
|
|
|
|
typedef struct {
|
|
u32 total_size;
|
|
u32 total_block;
|
|
u32 block_size;
|
|
u8 block_map[64];
|
|
|
|
// 描述某个存档的信息
|
|
int dsize; // 数据大小
|
|
int bsize; // 一共有多少块
|
|
u16 blist[512];
|
|
int nbp; // blist中下一块的索引
|
|
int dp; // 块中的数据指针
|
|
}BUPINFO;
|
|
|
|
|
|
static BUPINFO bup_info;
|
|
#define GET_BUP_INFO() (&bup_info)
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
static u8 *get_block_addr(BUPINFO *binfo, int id)
|
|
{
|
|
return (u8*)(bup_mem + binfo->block_size*id);
|
|
}
|
|
|
|
|
|
static void load_blist(BUPINFO *binfo, int block)
|
|
{
|
|
int nbp, dp, i;
|
|
u8 *bp;
|
|
|
|
binfo->blist[0] = block;
|
|
binfo->bsize = 1;
|
|
bp = get_block_addr(binfo, block);
|
|
|
|
binfo->dsize = get_be32(bp+0x1e);
|
|
if(binfo->dsize<=0x1e){
|
|
// 数据可以放在起始块内
|
|
binfo->nbp = 1;
|
|
binfo->dp = 0x22;
|
|
return;
|
|
}else{
|
|
nbp = 1;
|
|
dp = 0x22;
|
|
i = 1;
|
|
while(1){
|
|
block = get_be16(bp+dp);
|
|
if(block==0)
|
|
break;
|
|
|
|
binfo->blist[i] = block;
|
|
i += 1;
|
|
dp += 2;
|
|
if(dp==binfo->block_size){
|
|
// 当前块用完了,取得块列表中下一块的地址。
|
|
bp = get_block_addr(binfo, binfo->blist[nbp]);
|
|
nbp += 1;
|
|
dp = 4;
|
|
}
|
|
}
|
|
dp += 2;
|
|
if(dp==binfo->block_size){
|
|
nbp += 1;
|
|
dp = 4;
|
|
}
|
|
|
|
binfo->bsize = i;
|
|
binfo->nbp = nbp;
|
|
binfo->dp = dp;
|
|
}
|
|
}
|
|
|
|
|
|
static int read_data(BUPINFO *binfo, u8 *data)
|
|
{
|
|
u8 *bp;
|
|
int dp, nbp, dsize;
|
|
|
|
dsize = binfo->dsize;
|
|
nbp = binfo->nbp;
|
|
|
|
bp = get_block_addr(binfo, binfo->blist[nbp-1]);
|
|
dp = binfo->dp;
|
|
//printf("read_data: %d %d\n", binfo->blist[nbp-1], dp);
|
|
while(dsize>0){
|
|
*(u16*)data = *(u16*)(bp+dp);
|
|
dp += 2;
|
|
data += 2;
|
|
dsize -= 2;
|
|
if(dp==binfo->block_size){
|
|
// 当前块用完了,取得块列表中下一块的地址。
|
|
bp = get_block_addr(binfo, binfo->blist[nbp]);
|
|
//printf("next block: %d %08x dsize=%04x\n", binfo->blist[nbp], bp, dsize);
|
|
nbp += 1;
|
|
dp = 4;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void scan_save(BUPINFO *binfo)
|
|
{
|
|
int i;
|
|
u8 *bp;
|
|
|
|
memset(binfo->block_map, 0, 64);
|
|
binfo->block_map[0] = 0x03;
|
|
|
|
for(i=2; i<binfo->total_block; i++){
|
|
bp = get_block_addr(binfo, i);
|
|
if(get_be32(bp)==0x80000000){
|
|
// 找到了save起始块
|
|
load_blist(binfo, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
int ss_bup_export(int slot_id, int index)
|
|
{
|
|
BUPINFO *binfo = GET_BUP_INFO();
|
|
int block, i;
|
|
u8 *bp;
|
|
|
|
i = 0;
|
|
for(block=2; block<binfo->total_block; block++){
|
|
bp = get_block_addr(binfo, block);
|
|
if(get_be32(bp)==0x80000000){
|
|
// 找到了save起始块
|
|
if(i == index){
|
|
memset(save_buf, 0, 32768);
|
|
strcpy((char*)save_buf, "SSAVERAW");
|
|
memcpy(save_buf+0x10, bp+4, 11); // Filename
|
|
memcpy(save_buf+0x1c, bp+0x1e, 4); // Size
|
|
memcpy(save_buf+0x20, bp+0x10, 10); // Comment
|
|
save_buf[0x2b] = bp[0x0f]; // Language
|
|
memcpy(save_buf+0x2c, bp+0x1a, 4); // Date
|
|
|
|
load_blist(binfo, block);
|
|
read_data(binfo, save_buf+0x40);
|
|
|
|
char fname[16];
|
|
int fsize = get_be32(save_buf+0x1c);
|
|
sprintf(fname, "%s.bin", save_buf+0x10);
|
|
write_file(fname, save_buf, fsize+0x40);
|
|
|
|
printf("Export Save_%d: %s\n", index, fname);
|
|
return 0;
|
|
}
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
int ss_bup_import(int slot_id, int save_id, char *save_name)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
|
|
int ss_bup_delete(int slot_id, int save_id)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
|
|
int ss_bup_create(char *game_id)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
|
|
int ss_bup_list(int slot_id)
|
|
{
|
|
BUPINFO *binfo = GET_BUP_INFO();
|
|
int i, snum;
|
|
u8 *bp;
|
|
|
|
snum = 0;
|
|
for(i=2; i<binfo->total_block; i++){
|
|
bp = get_block_addr(binfo, i);
|
|
if(get_be32(bp)==0x80000000){
|
|
// 找到了save起始块
|
|
printf("Save_%d: %s\n", snum, bp+4);
|
|
snum += 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int ss_bup_init(u8 *bbuf)
|
|
{
|
|
BUPINFO *binfo = GET_BUP_INFO();
|
|
int i;
|
|
|
|
if(bbuf[1]=='B' && bbuf[3]=='a' && bbuf[5]=='c' && bbuf[7]=='k'){
|
|
ss_bup_type = 0;
|
|
for(i=0; i<32768; i++){
|
|
bup_mem[i] = bbuf[i*2+1];
|
|
}
|
|
}else if(strncmp((char*)bbuf, "BackUpRam Format", 16)==0){
|
|
ss_bup_type = 1;
|
|
memcpy(bup_mem, bbuf, 32768);
|
|
}
|
|
|
|
memset(binfo, 0, sizeof(BUPINFO));
|
|
|
|
binfo->total_size = 0x8000;
|
|
binfo->total_block = 512;
|
|
binfo->block_size = 64;
|
|
|
|
scan_save(binfo);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|