This commit is contained in:
Paul 2001-01-03 15:55:10 +00:00
parent 6abd565b82
commit 2e872af6c2
7 changed files with 2736 additions and 0 deletions

315
source/memcard/md5.cpp Normal file
View File

@ -0,0 +1,315 @@
// PKG - PROTO_LIST stuff removed and function headers re-written inna
// C++ style
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform (UINT4 [4], unsigned char [64]);
static void Encode (unsigned char *, UINT4 *, unsigned int);
static void Decode (UINT4 *, unsigned char *, unsigned int);
static void MD5_memcpy (POINTER, POINTER, unsigned int);
static void MD5_memset (POINTER, int, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (unsigned char digest[16], MD5_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (UINT4 state[4], unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (POINTER output, int value, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

49
source/memcard/md5.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef __MEMCARD_MD5_H__
#define __MEMCARD_MD5_H__
#ifndef __MEMCARD_MD5GLOBAL_H__
#include "memcard\md5global.h"
#endif
#define MD5_CHECKSUM_SIZE 16
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init (MD5_CTX *);
void MD5Update (MD5_CTX *, unsigned char *, unsigned int);
void MD5Final (unsigned char [16], MD5_CTX *);
#endif /* __MEMCARD_MD5_H__ */

View File

@ -0,0 +1,37 @@
#ifndef __MEMCARD_MD5GLOBAL_H__
#define __MEMCARD_MD5GLOBAL_H__
/* GLOBAL.H - RSAREF types and constants
*/
///* PROTOTYPES should be set to one if and only if the compiler supports
//function argument prototyping.
//The following makes PROTOTYPES default to 0 if it has not already
//been defined with C compiler flags.
//*/
//#ifndef PROTOTYPES
//#define PROTOTYPES 0
//#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
///* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
//If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
//returns an empty list.
//*/
//#if PROTOTYPES
//#define PROTO_LIST(list) list
//#else
//#define PROTO_LIST(list) ()
//#endif
#endif /* __MEMCARD_MD5GLOBAL_H__ */

1401
source/memcard/memcard.cpp Normal file

File diff suppressed because it is too large Load Diff

266
source/memcard/memcard.h Normal file
View File

@ -0,0 +1,266 @@
/*=========================================================================
memcard.h
Author: Paul Grenfell @ Climax
Created: Febuary 1999
Project: Theme Park 2
Purpose: Memory card access
Copyright (c) 1999 Climax Development Ltd
===========================================================================*/
#ifndef __MEMCARD_MEMCARD_H__
#define __MEMCARD_MEMCARD_H__
/*----------------------------------------------------------------------
Includes
-------- */
#ifndef _GLOBAL_HEADER_
#include "system\global.h"
#endif
#ifndef __MEMCARD_MD5_H__
#include "memcard\md5.h"
#endif
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Globals
------- */
/* Class
----- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
// Definition of a memcard file callback
typedef void (* FileCallbackDef)( int _status );
class MemCard
{
public:
/*
Filenames created will be of something like "BEXXXX-00000SAVE000A". The last four characters are generated
automatically by the file create function. All files on a card need unique names so if we can't save the file
"BEXXXX-00000SAVE000A" we try and save "BEXXXX-00000SAVE000B" and so on until we succeed. If we create the filename
this way then we won't be able to copy between cards ( the first save on each card will always be called
"BEXXXX-00000SAVE000A" ). To solve this we put a random number ( or a frame count... ) into the last three
digits of the name when we save. This should at least limit the chances of files with identical names being saved
onto different cards.
*/
// PKG - Changed this now.. savegame names are fixed to "B?XXXX-00000xxxxxxxx" where
// xxxxxxxx is the users save name
// Describe the filename for this product
/* What utter tosh
#define FNAME_MAGIC "B" // Always B, 'cos it's magic
#define FNAME_PCODE_US "ASLUS-00000"
#define FNAME_PCODE_EURO "ESLES-00000"
*/
// Memcard filenames (not using else, to make sure its correct)
#if defined(__TERRITORY_USA__)
#define MEMCARD_BASE_FILENAME "BASLUS-01114"
#endif
#if defined(__TERRITORY_UK__)
#define MEMCARD_BASE_FILENAME "BESLES-03253"
#endif
#if defined(__TERRITORY_EUR__)
#define MEMCARD_BASE_FILENAME "BESLES-03286"
#endif
// Describes the status of the card in a slot
typedef enum
{
CS_NoCard, // No card in slot
CS_CardInserted, // Card in slot ( busy scanning it )
CS_ValidCard, // Totally valid, formatted and happy card
CS_UnformattedCard, // Card is valid but not formatted
} CARDSTATUS;
// Describes what a card slot is doing
typedef enum _pmcstatus
{
SS_Idle, // Slot is idle
SS_Scanning, // Slot is scanning ( card existance checks )
SS_Reading, // Slot is reading card
SS_Writing, // Slot is writing to card
SS_Formatting, // Slot is formatting card
} SLOTSTATUS;
// Memcard callbacks return one of these:
typedef enum _pmccallbackstatus
{
CCS_ReadFileOK,
CCS_ReadFileFail,
CCS_WriteFileOK,
CCS_WriteFileFail,
CCS_FormatCardOK,
CCS_FormatCardFail,
CCS_DeleteFileOK,
CCS_DeleteFileFail,
CCS_GeneralFailure,
} CALLBACKSTATUS;
MemCard() {;}
~MemCard() {;}
static bool Start( void );
static bool Stop( void );
static void InvalidateCard( int Channel );
static void Handler( void );
static CARDSTATUS GetCardStatus( int Channel );
static SLOTSTATUS GetSlotStatus( int Channel );
static int GetFileCountOnCard( int Channel );
static int GetFreeBlocksOnCard( int Channel );
static const char *GetFileName( int Channel, int File );
static int GetFileSizeInBlocks( int Channel, int File );
static void FillHeaderDetails( unsigned char *HeaderBase, int FileLength, char *Filename );
static bool ReadFile( int Channel, int File, void *Dest, FileCallbackDef Callback );
static bool WriteFile( int Channel, int File, u8 *FName, void *Source, int FileLength, FileCallbackDef Callback );
static bool FormatCard( int Channel, FileCallbackDef Callback );
static bool DeleteFile( int Channel, int File, FileCallbackDef Callback );
static void SetActiveCardSlot( int Channel );
static void GiveCheckSum(unsigned char *_result,unsigned char *_data,u32 _size);
static int TestCheckSum(unsigned char *_result,unsigned char *_data,u32 _size);
static bool IsValidSavename(int _slot,char *_name);
static int FindFilenumberFromFilename(int _slot,char *_name);
enum {
BLOCKSIZE =8192, // 8k per file block
};
private:
enum
{
MAXBLOCKS =15, // Max of 15 blocks per card
MAXFILES =15, // Max of 15 files per card
COMPRESSEDNAMESIZE =64, // Length of Shift-JIS filename
CARDSLOTSTOCHECK =2, // Number of card slots available
};
// Available command types
typedef enum
{
CmdNone, // No command
CmdExist, // Check that card exists
CmdAccept, // Accept card after cheking that it exists
CmdReadDir, // Read directory of card
CmdReadFileInfo, // Reading info of each file
CmdReadFile, // Reading a file from card to memory
CmdWriteFile, // Writing data to a file
CmdFormatCard, // Formatting card
CmdDeleteFile, // Delete a file
} CMDTYPE;
// Definition of a card slot
typedef struct _pmccarddef
{
CARDSTATUS m_cardStatus; // Status of the crad ( 'in'/'out'/'maybe' sort of thing )
SLOTSTATUS m_slotStatus; // Status of the slot ( 'Idle'/'Scan'/'Read'/'Write'/'Format' )
// General data on all files on card
int m_totalFileCount; // Number of files on this card
int m_totalFreeBlocks; // Number of free blocks on this card
struct DIRENTRY m_totalDirEntry[ MAXFILES ]; // Basic file info ( internal use mainly )
// Data on app specific files
int m_nativeFileCount; // Number of files on this card that belong to this app
struct _fileinfo // File info on files that belong to this app
{
unsigned short m_sjisName[ 64 ]; // Shift-JIS name of file
int m_blocks; // Number of blocks this file uses
int m_dirEntry; // Number of file in TotalDirEntry array
} m_nativeFileInfo[ MAXFILES ];
} CARDDEF;
// Command handler functions
static void HandleCmd_None( void );
static void HandleCmd_Exist( void );
static void HandleCmd_Accept( void );
static void HandleCmd_ReadDir( void );
static void HandleCmd_ReadFileInfo( void );
static void HandleCmd_ReadFile( void );
static void HandleCmd_WriteFile( void );
static void HandleCmd_FormatCard( void );
static void HandleCmd_DeleteFile( void );
static void CreateFName(char *fname);
static int s_active;
static int s_currentChannel,m_nextChannel;
static CMDTYPE s_currentCommand,m_nextCommand;
static int s_activeSlot;
static CARDDEF s_cardData[CARDSLOTSTOCHECK];
static int s_file;
static int s_blockCount;
static char s_tempFileInfoBuffer[128];
static long int s_syncStatus,s_syncCmds,s_syncResults;
static void *s_bufPtr;
static char s_userFileName[8+1];
static char s_fname[20+1];
static char s_fnameBase[40];
static FileCallbackDef s_callbackFunction;
};
/*---------------------------------------------------------------------- */
#endif /* __MEMCARD_H__ */
/*===========================================================================
end */

537
source/memcard/saveload.cpp Normal file
View File

@ -0,0 +1,537 @@
/*=========================================================================
saveload.cpp
Author: PKG
Created:
Project: SBSP
Purpose:
Copyright (c) 2000 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "memcard\saveload.h"
#ifndef __MEMORY_HEADER__
#include "mem\memory.h"
#endif
#ifndef __MEMCARD_MEMCARD_H__
#include "memcard\memcard.h"
#endif
#ifndef _FILEIO_HEADER_
#include "fileio\fileio.h"
#endif
#ifndef __VID_HEADER_
#include "system\vid.h"
#endif
#ifndef __LOCALE_TEXTDBASE_H__
#include "locale\textdbase.h"
#endif
#ifndef __FILE_EQUATES_H__
#include <biglump.h>
#endif
/* Std Lib
------- */
/* Gfx
--- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Positional Vars
--------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
static void callback(int _status);
/*----------------------------------------------------------------------
Vars
---- */
static int s_callbackEnded=false;
static int s_callbackStatus=0;
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
SaveLoadDatabase::SaveLoadDatabase()
{
m_saving=false;
m_loading=false;
m_formatting=false;
m_loading=false;
m_autoloading=false;
m_tempBuffer=NULL;
gatherData();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
SaveLoadDatabase::~SaveLoadDatabase()
{
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::think()
{
MemCard::Handler();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::gatherData()
{
ASSERT(!m_saving);
ASSERT(!m_loading);
ASSERT(!m_formatting);
ASSERT(!m_autoloading);
createData();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool SaveLoadDatabase::startSave(char *_filename,int _fileNum=-1)
{
char nameBuf[9]="\0";
u8 *hdr;
ASSERT(!m_saving);
ASSERT(!m_loading);
ASSERT(!m_formatting);
ASSERT(!m_autoloading);
if(_fileNum!=-1)
{
strncat(nameBuf,MemCard::GetFileName(0,_fileNum),8);
_filename=nameBuf;
}
// Alloc a buffer and copy everything to it
allocateBuffer();
hdr=CFileIO::loadFile(MEMCARD_MEMHEAD_BIN);
memcpy((char*)&m_tempBuffer[0],hdr,256); // Memcard header
MemCard::FillHeaderDetails(m_tempBuffer,m_bufferSize,_filename); // Setup header
memcpy((char*)&m_tempBuffer[256],(char*)&m_dataBuffer,sizeof(m_dataBuffer)); // Data
MemCard::GiveCheckSum(&m_tempBuffer[m_bufferSize-MD5_CHECKSUM_SIZE], // Chksum
m_tempBuffer,m_bufferSize-MD5_CHECKSUM_SIZE);
// Start write to memcard
if(!MemCard::WriteFile(0,_fileNum,(u8*)_filename,(void*)m_tempBuffer,m_bufferSize,&callback))
{
MEMCARD_DBGMSG("write error");
freeBuffer();
return false;
}
s_callbackEnded=false;
m_saving=true;
return true;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int SaveLoadDatabase::getSaveStatus()
{
int ret=INACTIVE;
if(m_saving)
{
if(MemCard::GetCardStatus(0)==MemCard::CS_NoCard)
{
MEMCARD_DBGMSG("======= weird card removal - bonus 50 points");
// Card removed at weird time..
ret=FAILED;
s_callbackEnded=false;
m_saving=false;
freeBuffer();
}
else if(s_callbackEnded)
{
ASSERT(m_tempBuffer);
if(s_callbackStatus==MemCard::CCS_WriteFileOK) ret=FINISHED_OK;
else ret=FAILED;
freeBuffer();
s_callbackEnded=false;
m_saving=false;
}
else
{
ret=IN_PROGRESS;
}
}
return ret;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool SaveLoadDatabase::startLoad(int _file)
{
ASSERT(!m_saving);
ASSERT(!m_loading);
ASSERT(!m_formatting);
// Alloc a buffer to load to
allocateBuffer();
// Start read from memcard
if(!MemCard::ReadFile(0,_file,(void*)m_tempBuffer,&callback))
{
MEMCARD_DBGMSG("read error");
freeBuffer();
return false;
}
s_callbackEnded=false;
m_loading=true;
return true;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int SaveLoadDatabase::getLoadStatus()
{
int ret=INACTIVE;
if(m_loading)
{
if(MemCard::GetCardStatus(0)==MemCard::CS_NoCard)
{
MEMCARD_DBGMSG("======= weird card removal - bonus 50 points");
// Card removed at weird time..
freeBuffer();
m_loading=false;
m_autoloading=false;
s_callbackEnded=false;
ret=FAILED;
}
else if(s_callbackEnded)
{
ASSERT(m_tempBuffer);
// Load ok?
if(s_callbackStatus==MemCard::CCS_ReadFileOK&&
MemCard::TestCheckSum(&m_tempBuffer[m_bufferSize-MD5_CHECKSUM_SIZE],m_tempBuffer,m_bufferSize-MD5_CHECKSUM_SIZE))
{
memcpy(&m_dataBuffer,&m_tempBuffer[256],sizeof(m_dataBuffer));
if(m_dataBuffer.m_headerId!=SAVELOAD_HEADERID)
{
ASSERT(!"YOUR MEMCARD SAVE IS OUT OF DATE! PLEASE DELETE IT!");
}
// Loaded ok - Copy the data in
restoreData();
ret=FINISHED_OK;
MEMCARD_DBGMSG("load ok :)");
}
else
{
MEMCARD_DBGMSG("load failed!!!");
ret=FAILED;
}
freeBuffer();
m_loading=false;
m_autoloading=false;
s_callbackEnded=false;
}
else
{
ret=IN_PROGRESS;
}
}
return ret;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool SaveLoadDatabase::startFormat()
{
ASSERT(!m_saving);
ASSERT(!m_loading);
ASSERT(!m_formatting);
ASSERT(!m_autoloading);
if(!MemCard::FormatCard(0,&callback))
{
MEMCARD_DBGMSG("format error");
return false;
}
MEMCARD_DBGMSG("======= m_formatting=true");
s_callbackEnded=false;
m_formatting=true;
return true;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int SaveLoadDatabase::getFormatStatus()
{
int ret=INACTIVE;
if(m_formatting)
{
if(MemCard::GetCardStatus(0)==MemCard::CS_NoCard)
{
MEMCARD_DBGMSG("======= weird card removal - bonus 50 points");
// Card removed at weird time..
ret=FAILED;
s_callbackEnded=false;
m_formatting=false;
}
else if(s_callbackEnded)
{
if(s_callbackStatus==MemCard::CCS_FormatCardOK) ret=FINISHED_OK;
else ret=FAILED;
MEMCARD_DBGMSG("======= m_formatting=false");
s_callbackEnded=false;
m_formatting=false;
}
else
{
MEMCARD_DBGMSG("======= still formatting...");
ret=IN_PROGRESS;
}
}
return ret;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::startAutoload()
{
MEMCARD_DBGMSG("Trying autoload..");
m_autoloadFrameCounter=0;
m_autoloading=true;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool SaveLoadDatabase::monitorAutoload()
{
if(m_autoloading)
{
if(m_loading)
{
getLoadStatus();
}
else if(m_autoloading&&
m_autoloadFrameCounter>(60*2)&&
MemCard::GetCardStatus(0)!=MemCard::CS_CardInserted)
{
if(MemCard::GetFileCountOnCard(0))
{
startLoad(0);
}
else
{
m_autoloading=false;
}
}
m_autoloadFrameCounter++;
}
else
{
return false;
}
return true;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::createData()
{
int i;
// Header
m_dataBuffer.m_headerId=SAVELOAD_HEADERID;
// System details
m_dataBuffer.m_systemDetails.m_screenOffX=VidGetXOfs();
m_dataBuffer.m_systemDetails.m_screenOffY=VidGetYOfs();
for(i=0;i<CSoundMediator::NUM_VOLUMETYPES;i++)
{
m_dataBuffer.m_systemDetails.m_volumes[i]=CSoundMediator::getVolume((CSoundMediator::VOLUMETYPE)i);
}
m_dataBuffer.m_systemDetails.m_language=(char)TranslationDatabase::getLanguage();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::restoreData()
{
int i;
// System details
VidSetXYOfs(m_dataBuffer.m_systemDetails.m_screenOffX,m_dataBuffer.m_systemDetails.m_screenOffY);
for(i=0;i<CSoundMediator::NUM_VOLUMETYPES;i++)
{
CSoundMediator::setVolume((CSoundMediator::VOLUMETYPE)i,m_dataBuffer.m_systemDetails.m_volumes[i]);
}
if(!TranslationDatabase::isLoaded())
{
TranslationDatabase::loadLanguage(m_dataBuffer.m_systemDetails.m_language);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::allocateBuffer()
{
ASSERT(!m_tempBuffer);
m_bufferSize=MC_HEADER_SIZE+sizeof(m_dataBuffer)+MD5_CHECKSUM_SIZE;
m_bufferSize=((m_bufferSize/MemCard::BLOCKSIZE)+1)*MemCard::BLOCKSIZE;
m_tempBuffer=(unsigned char*)MemAlloc(m_bufferSize,"MEMCARD");
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void SaveLoadDatabase::freeBuffer()
{
ASSERT(m_tempBuffer);
MemFree(m_tempBuffer);
m_tempBuffer=NULL;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
static void callback(int _status)
{
ASSERT(!s_callbackEnded);
s_callbackEnded=true;
s_callbackStatus=_status;
}
/*===========================================================================
end */

131
source/memcard/saveload.h Normal file
View File

@ -0,0 +1,131 @@
/*=========================================================================
saveload.h
Author: PKG
Created:
Project: SBSP
Purpose:
Copyright (c) 2000 Climax Development Ltd
===========================================================================*/
#ifndef __MEMCARD_SAVELOAD_H__
#define __MEMCARD_SAVELOAD_H__
/*----------------------------------------------------------------------
Includes
-------- */
#ifndef __SOUND_SOUND_H__
#include "sound\sound.h"
#endif
/* Std Lib
------- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
struct SaveLoad_SystemDetails
{
char m_screenOffX,m_screenOffY;
unsigned char m_volumes[CSoundMediator::NUM_VOLUMETYPES];
unsigned char m_language;
};
struct SaveLoad_DataBuffer
{
unsigned char m_headerId;
SaveLoad_SystemDetails m_systemDetails;
};
class SaveLoadDatabase
{
public:
enum
{
INACTIVE,
IN_PROGRESS,
FINISHED_OK,
FAILED,
} STATUS;
SaveLoadDatabase();
~SaveLoadDatabase();
void think();
void gatherData();
bool startSave(char *_filename,int _fileNum=-1);
int getSaveStatus();
bool startLoad(int _file);
int getLoadStatus();
bool startFormat();
int getFormatStatus();
void startAutoload();
bool monitorAutoload();
private:
enum
{
MC_HEADER_SIZE=256,
};
enum
{
SAVELOAD_HEADERID=0,
};
void createData();
void restoreData();
void allocateBuffer();
void freeBuffer();
SaveLoad_DataBuffer m_dataBuffer;
int m_saving,m_loading,m_formatting,m_autoloading;
unsigned char *m_tempBuffer;
int m_bufferSize;
unsigned char *m_memcardHeader;
int m_autoloadFrameCounter;
};
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
/*---------------------------------------------------------------------- */
#endif /* __MEMCARD_SAVELOAD_H__ */
/*===========================================================================
end */