mirror of
https://github.com/suloku/gcmm.git
synced 2026-04-24 23:08:10 -05:00
Increased lenght of filenames in selector
Added raw backup and restore modes, as well as format mode. Raw write still has the same issues as in ctr-gcs with official cards. Flash ID is checked before raw restoring (can be bypassed if memory card is changed after selecting the image, however size check can't be bypassed). This behavior is intentional. Changed STATUSOGC definition to gci.h (defining STATUSOGC makes GCMM use the normal CARD_GetStatus and CARD_SetStatus functions instead of the EX versions)
This commit is contained in:
parent
3033611a67
commit
166ded3cf5
|
|
@ -181,10 +181,10 @@ static void __erase_callback(s32 chn,s32 result);
|
|||
static void __dsp_donecallback(u32 chn);
|
||||
static s32 __dounlock(s32 chn,u32 *key);
|
||||
static s32 __card_readsegment(s32 chn,cardcallback callback);
|
||||
static s32 __card_read(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback);
|
||||
s32 __card_read(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback);
|
||||
static s32 __card_updatefat(s32 chn,struct card_bat *fatblock,cardcallback callback);
|
||||
static s32 __card_updatedir(s32 chn,cardcallback callback);
|
||||
static s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback);
|
||||
s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback);
|
||||
static s32 __card_writepage(s32 chn,cardcallback callback);
|
||||
static s32 __card_sectorerase(s32 chn,u32 sector,cardcallback callback);
|
||||
static s32 __card_onreset(s32 final);
|
||||
|
|
@ -278,7 +278,7 @@ static __inline__ struct card_bat* __card_getbatblock(card_block *card)
|
|||
return card->curr_fat;
|
||||
}
|
||||
|
||||
static s32 __card_sync(s32 chn)
|
||||
s32 __card_sync(s32 chn)
|
||||
{
|
||||
s32 ret;
|
||||
u32 level;
|
||||
|
|
@ -1553,7 +1553,7 @@ static void __card_dirwritecallback(s32 chn,s32 result)
|
|||
}
|
||||
}
|
||||
|
||||
static s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback)
|
||||
s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback)
|
||||
{
|
||||
s32 ret;
|
||||
card_block *card = NULL;
|
||||
|
|
@ -1574,7 +1574,7 @@ static s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallb
|
|||
return ret;
|
||||
}
|
||||
|
||||
static s32 __card_read(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback)
|
||||
s32 __card_read(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback)
|
||||
{
|
||||
s32 ret;
|
||||
card_block *card = NULL;
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ s32 CARD_SetGamecode(const char *gamecode);
|
|||
|
||||
\return \ref card_errors "card error codes"
|
||||
*/
|
||||
s32 __card_getstatusex(s32 chn,s32 fileno,struct card_direntry *entry)
|
||||
s32 __card_getstatusex(s32 chn,s32 fileno,struct card_direntry *entry);
|
||||
|
||||
|
||||
/*! \fn s32 __card_setstatusex(s32 chn,s32 fileno,struct card_direntry *entry)
|
||||
|
|
@ -618,7 +618,12 @@ s32 __card_getstatusex(s32 chn,s32 fileno,struct card_direntry *entry)
|
|||
|
||||
\return \ref card_errors "card error codes"
|
||||
*/
|
||||
s32 __card_setstatusex(s32 chn,s32 fileno,struct card_direntry *entry)
|
||||
s32 __card_setstatusex(s32 chn,s32 fileno,struct card_direntry *entry);
|
||||
|
||||
// Raw read and write functions
|
||||
s32 __card_read(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback);
|
||||
s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback);
|
||||
s32 __card_sync(s32 chn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* routines.
|
||||
****************************************************************************/
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
#include "mcard.h"
|
||||
#include "sdsupp.h"
|
||||
#include "bitmap.h"
|
||||
#include "raw.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <wiiuse/wpad.h>
|
||||
|
|
@ -34,13 +36,17 @@ FT_UInt glyph_index;
|
|||
extern card_stat CardStatus;
|
||||
extern int cancel;
|
||||
extern int mode;
|
||||
extern int MEM_CARD;
|
||||
extern s32 MEM_CARD;
|
||||
extern u16 bannerdata[CARD_BANNER_W*CARD_BANNER_H] ATTRIBUTE_ALIGN (32);
|
||||
extern u8 bannerdataCI[CARD_BANNER_W*CARD_BANNER_H] ATTRIBUTE_ALIGN (32);
|
||||
extern u8 icondata[1024] ATTRIBUTE_ALIGN (32);
|
||||
extern u16 icondataRGB[1024] ATTRIBUTE_ALIGN (32);
|
||||
extern u16 tlut[256] ATTRIBUTE_ALIGN (32);
|
||||
extern u16 tlutbanner[256] ATTRIBUTE_ALIGN (32);
|
||||
extern Header cardheader;
|
||||
extern s32 memsize, sectsize;
|
||||
extern syssramex *sramex;
|
||||
extern u8 imageserial[12];
|
||||
|
||||
static int fonthi, fontlo;
|
||||
|
||||
|
|
@ -343,7 +349,7 @@ int SelectMode ()
|
|||
}
|
||||
return 100;
|
||||
}
|
||||
if (PAD_ButtonsHeld (0) & PAD_TRIGGER_Z)
|
||||
if (PAD_ButtonsHeld (0) & PAD_TRIGGER_Z)//Delete mode
|
||||
{
|
||||
while ((PAD_ButtonsDown (0) & PAD_BUTTON_B))
|
||||
{
|
||||
|
|
@ -351,7 +357,7 @@ int SelectMode ()
|
|||
}
|
||||
return 200;
|
||||
}
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_Y)
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_Y)//Backup mode
|
||||
{
|
||||
while ((PAD_ButtonsDown (0) & PAD_BUTTON_Y))
|
||||
{
|
||||
|
|
@ -359,7 +365,7 @@ int SelectMode ()
|
|||
}
|
||||
return 300;
|
||||
}
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_X)
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_X)//Restore mode
|
||||
{
|
||||
while ((PAD_ButtonsDown (0) & PAD_BUTTON_X))
|
||||
{
|
||||
|
|
@ -367,7 +373,7 @@ int SelectMode ()
|
|||
}
|
||||
return 400;
|
||||
}
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_START)
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_START)//Exit
|
||||
{
|
||||
while ((PAD_ButtonsDown (0) & PAD_BUTTON_START))
|
||||
{
|
||||
|
|
@ -375,7 +381,7 @@ int SelectMode ()
|
|||
}
|
||||
return 500;
|
||||
}
|
||||
if (PAD_ButtonsHeld (0) & PAD_TRIGGER_R)
|
||||
if (PAD_ButtonsHeld (0) & PAD_TRIGGER_R)//Backup all mode
|
||||
{
|
||||
while ((PAD_ButtonsDown (0) & PAD_TRIGGER_R))
|
||||
{
|
||||
|
|
@ -383,7 +389,32 @@ int SelectMode ()
|
|||
}
|
||||
return 600;
|
||||
}
|
||||
while (PAD_ButtonsHeld (0) & PAD_TRIGGER_L)
|
||||
{
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_Y){//Raw backup mode
|
||||
while ((PAD_ButtonsDown (0) & PAD_TRIGGER_L) || (PAD_ButtonsDown (0) & PAD_BUTTON_Y))
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 700;
|
||||
}
|
||||
|
||||
if (PAD_ButtonsHeld (0) & PAD_BUTTON_X){//Raw restore mode
|
||||
while ((PAD_ButtonsDown (0) & PAD_TRIGGER_L) || (PAD_ButtonsDown (0) & PAD_BUTTON_X))
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 800;
|
||||
}
|
||||
|
||||
if (PAD_ButtonsHeld (0) & PAD_TRIGGER_Z){//Format card mode
|
||||
while ((PAD_ButtonsDown (0) & PAD_TRIGGER_L) || (PAD_ButtonsDown (0) & PAD_TRIGGER_Z))
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 900;
|
||||
}
|
||||
}
|
||||
#ifdef HW_RVL
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_A)
|
||||
{
|
||||
|
|
@ -395,13 +426,13 @@ int SelectMode ()
|
|||
}
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_2)
|
||||
{
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_2))
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_2))//Delete mode
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 200;
|
||||
}
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_MINUS)
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_MINUS)//Backup mode
|
||||
{
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_MINUS))
|
||||
{
|
||||
|
|
@ -409,7 +440,7 @@ int SelectMode ()
|
|||
}
|
||||
return 300;
|
||||
}
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_PLUS)
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_PLUS)//Restore mode
|
||||
{
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_PLUS))
|
||||
{
|
||||
|
|
@ -417,7 +448,7 @@ int SelectMode ()
|
|||
}
|
||||
return 400;
|
||||
}
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_HOME)
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_HOME)//Exit
|
||||
{
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_HOME))
|
||||
{
|
||||
|
|
@ -425,7 +456,7 @@ int SelectMode ()
|
|||
}
|
||||
return 500;
|
||||
}
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_1)
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_1)//Backup all mode
|
||||
{
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_1))
|
||||
{
|
||||
|
|
@ -433,6 +464,32 @@ int SelectMode ()
|
|||
}
|
||||
return 600;
|
||||
}
|
||||
while (WPAD_ButtonsHeld (0) & WPAD_BUTTON_B)
|
||||
{
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_MINUS){//Raw backup mode
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_B) || (WPAD_ButtonsDown (0) & WPAD_BUTTON_MINUS))
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 700;
|
||||
}
|
||||
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_PLUS){//Raw restore mode
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_B) || (WPAD_ButtonsDown (0) & WPAD_BUTTON_PLUS))
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 800;
|
||||
}
|
||||
|
||||
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_2){//Format card mode
|
||||
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_B) || (WPAD_ButtonsDown (0) & WPAD_BUTTON_2))
|
||||
{
|
||||
VIDEO_WaitVSync ();
|
||||
}
|
||||
return 900;
|
||||
}
|
||||
}
|
||||
if (power)
|
||||
{
|
||||
PowerOff();
|
||||
|
|
@ -515,6 +572,43 @@ int WaitButtonAB ()
|
|||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Wait for user to press A or B. Returns 0 = Z/2; 1 = A
|
||||
****************************************************************************/
|
||||
|
||||
int WaitButtonAZ ()
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
u32 gc_btns, wm_btns;
|
||||
|
||||
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_TRIGGER_Z))
|
||||
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_A | WPAD_CLASSIC_BUTTON_ZR | WPAD_CLASSIC_BUTTON_ZL))
|
||||
) VIDEO_WaitVSync();
|
||||
|
||||
while (1)
|
||||
{
|
||||
gc_btns = PAD_ButtonsDown (0);
|
||||
wm_btns = WPAD_ButtonsDown (0);
|
||||
if ( (gc_btns & PAD_BUTTON_A) || (wm_btns & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
|
||||
return 1;
|
||||
else if ( (gc_btns & PAD_TRIGGER_Z) || (wm_btns & (WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_ZR | WPAD_CLASSIC_BUTTON_ZL)) )
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
u32 gc_btns;
|
||||
|
||||
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_TRIGGER_Z)) ) VIDEO_WaitVSync();
|
||||
|
||||
while (1)
|
||||
{
|
||||
gc_btns = PAD_ButtonsDown (0);
|
||||
if ( gc_btns & PAD_BUTTON_A )
|
||||
return 1;
|
||||
else if ( gc_btns & PAD_TRIGGER_Z )
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -551,7 +645,26 @@ int WaitPromptChoice ( char *msg, char *bmsg, char *amsg)
|
|||
|
||||
return ret;
|
||||
}
|
||||
/****************************************************************************
|
||||
* Show a prompt with choice of two options. Returns 1 if A button was pressed
|
||||
and 0 if Z/2 button was pressed.
|
||||
****************************************************************************/
|
||||
int WaitPromptChoiceAZ ( char *msg, char *bmsg, char *amsg)
|
||||
{
|
||||
char txt[80];
|
||||
int ret;
|
||||
#ifdef HW_RVL
|
||||
sprintf (txt, "Z/2 = %s : A = %s", bmsg, amsg);
|
||||
#else
|
||||
sprintf (txt, "Z = %s : A = %s", bmsg, amsg);
|
||||
#endif
|
||||
writeStatusBar(msg, txt);
|
||||
ret = WaitButtonAZ ();
|
||||
//Clear the text
|
||||
writeStatusBar("","");
|
||||
|
||||
return ret;
|
||||
}
|
||||
void DrawLineFast (int startx, int endx, int y, u8 r, u8 g, u8 b)
|
||||
{
|
||||
int width;
|
||||
|
|
@ -567,6 +680,73 @@ void DrawLineFast (int startx, int endx, int y, u8 r, u8 g, u8 b)
|
|||
xfb[whichfb][offset++] = colour;
|
||||
}
|
||||
|
||||
void showCardInfo(int sel){
|
||||
//clear right pane, but just the card info
|
||||
int bgcolor = getcolour(84,174,211);
|
||||
DrawBoxFilled(375, 165, 605, 390, bgcolor);
|
||||
int y = 190, x = 375;
|
||||
int err;
|
||||
char txt[1024];
|
||||
int i;
|
||||
char temp[5];
|
||||
|
||||
//START card image info START
|
||||
//put block 1 in cardheader
|
||||
SDLoadCardImageHeader((char*)filelist[sel]);
|
||||
//get the serial
|
||||
getserial(imageserial);
|
||||
|
||||
sprintf(txt, "Card image flash ID");
|
||||
DrawText(x, y, txt);
|
||||
y += 20;
|
||||
|
||||
sprintf(txt, "%02X", imageserial[0]);
|
||||
for (i=1; i<11; i++){
|
||||
sprintf(temp, "%02X", imageserial[i]);
|
||||
strcat(txt, temp);
|
||||
}
|
||||
DrawText(x,y,txt);
|
||||
y+=20;
|
||||
|
||||
sprintf(txt, "Size: %d blocks", (cardheader.SizeMb[1]*16)-5);
|
||||
DrawText(x, y, txt);
|
||||
y+=40;
|
||||
//END card image info END
|
||||
|
||||
//START real card info START
|
||||
err = MountCard(MEM_CARD);
|
||||
if (err < 0)
|
||||
{
|
||||
WaitCardError("CardMount", err);
|
||||
return; /*** Unable to mount the card ***/
|
||||
}
|
||||
|
||||
sramex = __SYS_LockSramEx();
|
||||
__SYS_UnlockSramEx(0);
|
||||
|
||||
if (!MEM_CARD)
|
||||
{
|
||||
sprintf(txt, "Slot A card flash ID:");
|
||||
}else
|
||||
{
|
||||
sprintf(txt, "Slot B card flash ID:");
|
||||
}
|
||||
DrawText(x,y,txt);
|
||||
y+=20;
|
||||
|
||||
sprintf(txt, "%02X", sramex->flash_id[MEM_CARD][0]);
|
||||
for (i=1; i<sizeof(sramex->flash_id[MEM_CARD])-1; i++){
|
||||
sprintf(temp, "%02X", sramex->flash_id[MEM_CARD][i]);
|
||||
strcat(txt, temp);
|
||||
}
|
||||
DrawText(x,y,txt);
|
||||
y+=20;
|
||||
|
||||
sprintf(txt, "Size: %d blocks", (memsize*16)-5);
|
||||
DrawText(x,y,txt);
|
||||
//END real card info END
|
||||
}
|
||||
|
||||
void showSaveInfo(int sel)
|
||||
{
|
||||
int y = 160, x = 375, j;
|
||||
|
|
@ -714,12 +894,15 @@ void showSaveInfo(int sel)
|
|||
|
||||
}
|
||||
|
||||
|
||||
static void ShowFiles (int offset, int selection, int upordown) {
|
||||
// saveinfo 1: shows saveinfo (for gci/sav/gcs backup/restore)
|
||||
// saveinfo 0: retrieves .raw, .gcp and .mci
|
||||
static void ShowFiles (int offset, int selection, int upordown, int saveinfo) {
|
||||
int i, j; //j helps us determine which entry to highlight
|
||||
char text[23];
|
||||
int ypos;
|
||||
int w;
|
||||
//int textlen = 22;
|
||||
int textlen = 32;
|
||||
//If the filelist offset changed, we have to redraw every entry
|
||||
//This tracks switching "pages" of files in the list
|
||||
if (offsetchanged) {
|
||||
|
|
@ -738,8 +921,8 @@ static void ShowFiles (int offset, int selection, int upordown) {
|
|||
for (i = offset; i < (offset + PAGESIZE) && (i < maxfile); i++){
|
||||
//changed this to limit characters shown in filename since display gets weird
|
||||
//if we let the entire filename appear
|
||||
strncpy (text, (char*)filelist[i], 22);
|
||||
text[22] = 0;
|
||||
strncpy (text, (char*)filelist[i], textlen);
|
||||
text[textlen] = 0;
|
||||
if (j == (selection - offset)){
|
||||
/*** Highlighted text entry ***/
|
||||
for (w = 0; w < 20; w++){
|
||||
|
|
@ -763,7 +946,11 @@ static void ShowFiles (int offset, int selection, int upordown) {
|
|||
}
|
||||
//set black font - info on right side of screen is printed in showSaveInfo
|
||||
setfontcolour (28, 28, 28);
|
||||
showSaveInfo(selection);
|
||||
if (saveinfo){
|
||||
showSaveInfo(selection);
|
||||
}else if (!saveinfo){
|
||||
showCardInfo(selection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Filelist offset didn't change yet; Only redraw what matters
|
||||
|
|
@ -773,8 +960,8 @@ static void ShowFiles (int offset, int selection, int upordown) {
|
|||
setfontcolour (0xff, 0xff, 0xff);
|
||||
//user just pressed up
|
||||
if (upordown == 1) {
|
||||
strncpy (text, (char*)filelist[selection+1], 22);
|
||||
text[22] = 0;
|
||||
strncpy (text, (char*)filelist[selection+1], textlen);
|
||||
text[textlen] = 0;
|
||||
for (w = 0; w < 20; w++){
|
||||
DrawLineFast (35, 330, (((selection-offset)+1) * 20) + (ypos - 14) + w, 84, 174,211);
|
||||
}
|
||||
|
|
@ -782,8 +969,8 @@ static void ShowFiles (int offset, int selection, int upordown) {
|
|||
}
|
||||
//user just pressed down
|
||||
else if (upordown == 2) {
|
||||
strncpy (text, (char*)filelist[selection-1], 22);
|
||||
text[22] = 0;
|
||||
strncpy (text, (char*)filelist[selection-1], textlen);
|
||||
text[textlen] = 0;
|
||||
for (w = 0; w < 20; w++){
|
||||
DrawLineFast (35, 330, (((selection-offset)-1) * 20) + (ypos - 14) + w, 84, 174,211);
|
||||
}
|
||||
|
|
@ -793,14 +980,18 @@ static void ShowFiles (int offset, int selection, int upordown) {
|
|||
//appear faster - without it the highlight box glides too much
|
||||
ShowScreen();
|
||||
setfontcolour (28, 28, 28);
|
||||
strncpy (text, (char*)filelist[selection], 22);
|
||||
text[22] = 0;
|
||||
strncpy (text, (char*)filelist[selection], textlen);
|
||||
text[textlen] = 0;
|
||||
//the current spot is always highlighted
|
||||
for (w = 0; w < 20; w++){
|
||||
DrawLineFast (35, 330, ((selection-offset) * 20) + (ypos - 14) + w, 0xff, 0xff, 0xff);
|
||||
}
|
||||
DrawText (35, ((selection-offset) * 20) + ypos, text);
|
||||
showSaveInfo(selection);
|
||||
if (saveinfo){
|
||||
showSaveInfo(selection);
|
||||
}else if (!saveinfo){
|
||||
showCardInfo(selection);
|
||||
}
|
||||
}
|
||||
//Need this to show info update from showSaveInfo
|
||||
ShowScreen();
|
||||
|
|
@ -841,8 +1032,10 @@ static void ShowFiles (int offset, int selection, int upordown) {
|
|||
*
|
||||
* Let's the user select a file to backup or restore.
|
||||
* Returns index of file chosen.
|
||||
* saveinfo 1: enables getting and displaying saveinformation
|
||||
* saveinfo 0: disables save information (for raw mode)
|
||||
****************************************************************************/
|
||||
int ShowSelector ()
|
||||
int ShowSelector (int saveinfo)
|
||||
{
|
||||
u32 p;
|
||||
#ifdef HW_RVL
|
||||
|
|
@ -858,7 +1051,7 @@ int ShowSelector ()
|
|||
{
|
||||
if (redraw)
|
||||
{
|
||||
ShowFiles (offset, selection, upordown);
|
||||
ShowFiles (offset, selection, upordown, saveinfo);
|
||||
redraw = 0;
|
||||
}
|
||||
p = PAD_ButtonsDown (0);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ void ShowScreen ();
|
|||
void ShowAction (char *msg);
|
||||
void WaitPrompt (char *msg);
|
||||
int WaitPromptChoice ( char *msg, char *bmsg, char *amsg);
|
||||
int ShowSelector ();
|
||||
int WaitPromptChoiceAZ ( char *msg, char *bmsg, char *amsg);
|
||||
int ShowSelector (int saveinfo);
|
||||
int SelectMode ();
|
||||
void writeStatusBar(char *line1, char *line2);
|
||||
void clearLeftPane();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@
|
|||
|
||||
#include <gccore.h>
|
||||
|
||||
// If STATUSOGC defined uses CARD_GetStatus and CARD_SetStatus
|
||||
// Default (undefined) uses __card_getstatusex and __card_setstatusex
|
||||
// Diference: when restoring a savegame with the ex functions original time, copy counter, etc are preserved
|
||||
// Also, libogc creates card entries with time since 1970 and gamecube uses time since 2000... thus libogc adds 30 years!
|
||||
|
||||
//#define STATUSOGC
|
||||
|
||||
typedef struct {
|
||||
u8 gamecode[4];
|
||||
u8 company[2];
|
||||
|
|
|
|||
173
source/main.c
173
source/main.c
|
|
@ -28,6 +28,8 @@
|
|||
#endif
|
||||
|
||||
#include "mcard.h"
|
||||
#include "card.h"
|
||||
#include "raw.h"
|
||||
#include "sdsupp.h"
|
||||
#include "freetype.h"
|
||||
#include "bitmap.h"
|
||||
|
|
@ -45,7 +47,9 @@ static int vmode_60hz = 0;
|
|||
extern u8 filelist[1024][1024];
|
||||
extern bool offsetchanged;
|
||||
|
||||
int MEM_CARD = CARD_SLOTB;
|
||||
s32 MEM_CARD = CARD_SLOTB;
|
||||
extern syssramex *sramex;
|
||||
extern u8 imageserial[12];
|
||||
|
||||
static void updatePAD()
|
||||
{
|
||||
|
|
@ -281,7 +285,7 @@ void SD_BackupMode ()
|
|||
}
|
||||
else
|
||||
{
|
||||
selected = ShowSelector ();
|
||||
selected = ShowSelector (1);
|
||||
if (cancel)
|
||||
{
|
||||
WaitPrompt ("Backup action cancelled!");
|
||||
|
|
@ -378,7 +382,7 @@ void SD_RestoreMode ()
|
|||
clearRightPane();
|
||||
DrawText(390,130,"R e s t o r e M o d e");
|
||||
writeStatusBar("Pick a file using UP or DOWN", "Press A to restore to Memory Card ") ;
|
||||
files = SDGetFileList ();
|
||||
files = SDGetFileList (1);
|
||||
if (!files)
|
||||
{
|
||||
WaitPrompt ("No saved games in SD Card to restore !");
|
||||
|
|
@ -386,7 +390,7 @@ void SD_RestoreMode ()
|
|||
|
||||
else
|
||||
{
|
||||
selected = ShowSelector ();
|
||||
selected = ShowSelector (1);
|
||||
|
||||
if (cancel)
|
||||
{
|
||||
|
|
@ -413,56 +417,87 @@ void SD_RestoreMode ()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* TestMode
|
||||
*
|
||||
* RawBackupMode -SD Mode
|
||||
*
|
||||
* Perform backup of full memory card (in raw format) to a SD Card.
|
||||
****************************************************************************/
|
||||
/*void testMode (){
|
||||
void SD_RawBackupMode ()
|
||||
{
|
||||
s32 writen = 0;
|
||||
char msg[64];
|
||||
clearRightPane();
|
||||
DrawText(50, 230, "R A W B a c k u p M o d e");
|
||||
writeStatusBar("Reading memory card... ", "");
|
||||
|
||||
clearRightPane();
|
||||
DrawText(390,130,"T e s t M o d e");
|
||||
if (BackupRawImage(MEM_CARD, &writen) == 1)
|
||||
{
|
||||
sprintf(msg, "Backup complete! Wrote %d bytes to SD",writen);
|
||||
WaitPrompt(msg);
|
||||
}else{
|
||||
|
||||
WaitPrompt("Backup failed!");
|
||||
}
|
||||
|
||||
int bytestodo;
|
||||
|
||||
clearRightPane();
|
||||
|
||||
|
||||
ShowAction ("Reading From MC SLOT B");
|
||||
bytestodo = testreadimage (MEM_CARD);
|
||||
if (bytestodo){
|
||||
ShowAction ("Saving to SD CARD");
|
||||
if (SDSaveraw ()){
|
||||
WaitPrompt ("Backup complete");
|
||||
}
|
||||
else{
|
||||
WaitPrompt ("Backup failed");
|
||||
}
|
||||
}
|
||||
else{
|
||||
WaitPrompt ("Error reading MC file");
|
||||
}
|
||||
|
||||
// writeStatusBar("Pick a file using UP or DOWN", "Press A to restore to Memory Card ") ;
|
||||
|
||||
|
||||
//WaitPrompt ("No saved games in SD Card to restore !");
|
||||
//ShowAction ("Reading from SD Card");
|
||||
|
||||
|
||||
}*/
|
||||
|
||||
/* Reboot the system */
|
||||
/*void Reboot() {
|
||||
*((volatile u32*)0xCC003024) = 0x00000000;
|
||||
}
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* RawRestoreMode
|
||||
*
|
||||
* Restore a full raw backup to Memory Card from SD Card
|
||||
****************************************************************************/
|
||||
void SD_RawRestoreMode ()
|
||||
{
|
||||
int files;
|
||||
int selected;
|
||||
char msg[64];
|
||||
s32 writen = 0;
|
||||
int i;
|
||||
|
||||
clearRightPane();
|
||||
DrawText(400,130,"R A W R e s t o r e");
|
||||
DrawText(450,150,"M o d e");
|
||||
writeStatusBar("Pick a file using UP or DOWN", "Press A to restore to Memory Card ");
|
||||
|
||||
files = SDGetFileList (0);
|
||||
if (!files)
|
||||
{
|
||||
WaitPrompt ("No raw backups in SD Card to restore !");
|
||||
}else
|
||||
{
|
||||
selected = ShowSelector (0);
|
||||
|
||||
if (cancel)
|
||||
{
|
||||
WaitPrompt ("Restore action cancelled !");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Now imageserial and sramex.flash_id[MEM_CARD] variables should hold the proper information
|
||||
for (i=0;i<12;i++){
|
||||
if (imageserial[i] != sramex->flash_id[MEM_CARD][i]){
|
||||
WaitPrompt ("Card and image flash ID don't match !");
|
||||
return;
|
||||
}
|
||||
}
|
||||
ShowAction ("Reading from SD Card...");
|
||||
if (RestoreRawImage(MEM_CARD, (char*)filelist[selected], &writen) == 1)
|
||||
{
|
||||
sprintf(msg, "Restore complete! Wrote %d bytes to card",writen);
|
||||
WaitPrompt(msg);
|
||||
}else
|
||||
{
|
||||
WaitPrompt("Restore failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Main
|
||||
****************************************************************************/
|
||||
|
|
@ -492,10 +527,11 @@ int main ()
|
|||
{
|
||||
/*** Select Mode ***/
|
||||
ClearScreen();
|
||||
setfontsize (FONT_SIZE);
|
||||
cancel = 0;/******a global value to track action aborted by user pressing button B********/
|
||||
mode = SelectMode ();
|
||||
#ifdef HW_RVL
|
||||
if (mode != 100 && mode != 500){
|
||||
if ((mode != 500 ) && (mode != 100)){
|
||||
if (WaitPromptChoice ("Please select a memory card slot", "Slot B", "Slot A") == 1)
|
||||
{
|
||||
MEM_CARD = CARD_SLOTA;
|
||||
|
|
@ -540,8 +576,53 @@ int main ()
|
|||
if (have_sd) SD_BackupModeAllFiles();
|
||||
else WaitPrompt("Reboot aplication with an SD card");
|
||||
break;
|
||||
case 700 : //Raw backup mode
|
||||
if (have_sd)
|
||||
{
|
||||
DrawText(50, 230, "R A W B a c k u p M o d e");
|
||||
SD_RawBackupMode();
|
||||
}else
|
||||
{
|
||||
WaitPrompt("Reboot aplication with an SD card");
|
||||
}
|
||||
break;
|
||||
case 800 : //Raw restore mode
|
||||
//These two lines are a work around for the second call of CARD_Probe to detect a newly inserted memory card
|
||||
CARD_Probe(MEM_CARD);
|
||||
VIDEO_WaitVSync ();
|
||||
if (CARD_Probe(MEM_CARD) > 0)
|
||||
{
|
||||
if (have_sd) SD_RawRestoreMode();
|
||||
else WaitPrompt("Reboot aplication with an SD card");
|
||||
|
||||
}else if (MEM_CARD)
|
||||
{
|
||||
WaitPrompt("Please insert a memory card in slot B");
|
||||
}else
|
||||
{
|
||||
WaitPrompt("Please insert a memory card in slot A");
|
||||
}
|
||||
break;
|
||||
case 900 : //Format card mode
|
||||
//These two lines are a work around for the second call of CARD_Probe to detect a newly inserted memory card
|
||||
CARD_Probe(MEM_CARD);
|
||||
VIDEO_WaitVSync ();
|
||||
if (CARD_Probe(MEM_CARD) > 0)
|
||||
{
|
||||
DrawText(50, 230, "F o r m a t C a r d M o d e");
|
||||
clearRightPane();
|
||||
MC_FormatMode(MEM_CARD);
|
||||
|
||||
}else if (MEM_CARD)
|
||||
{
|
||||
WaitPrompt("Please insert a memory card in slot B");
|
||||
}else
|
||||
{
|
||||
WaitPrompt("Please insert a memory card in slot A");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
offsetchanged = true;
|
||||
}
|
||||
while (1);
|
||||
|
|
|
|||
|
|
@ -22,13 +22,6 @@
|
|||
#include "gci.h"
|
||||
#include "freetype.h"
|
||||
|
||||
// If STATUSOGC defined uses CARD_GetStatus and CARD_SetStatus
|
||||
// Default (undefined) uses __card_getstatusex and __card_setstatusex
|
||||
// Diference: when restoring a savegame with the ex functions original time, copy counter, etc are preserved
|
||||
// Also, libogc creates card entries with time since 1970 and gamecube uses time since 2000... thus libogc adds 30 years!
|
||||
|
||||
//#define STATUSOGC
|
||||
|
||||
/*** Memory Card Work Area ***/
|
||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
|
||||
|
||||
|
|
@ -61,20 +54,21 @@ static card_file CardFile;
|
|||
static card_stat CardStatus;
|
||||
static int cardcount = 0;
|
||||
static u8 permission;
|
||||
|
||||
s32 memsize, sectsize;
|
||||
|
||||
GCI gci;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------
|
||||
This function is called if a card is physically removed
|
||||
---------------------------------------------------------------------------------*/
|
||||
void card_removed(s32 chn,s32 result)
|
||||
{
|
||||
if (chn == CARD_SLOTA)
|
||||
printf("Card was removed from slot A");
|
||||
else
|
||||
printf("Card was removed from slot B");
|
||||
if (chn == CARD_SLOTA){
|
||||
//printf("Card was removed from slot A");
|
||||
}
|
||||
else{
|
||||
//printf("Card was removed from slot B");
|
||||
}
|
||||
CARD_Unmount(chn);
|
||||
}
|
||||
|
||||
|
|
@ -89,8 +83,7 @@ int MountCard(int cslot)
|
|||
{
|
||||
s32 ret = -1;
|
||||
int tries = 0;
|
||||
int isMounted, memsize, sectsize;
|
||||
char msg[64];
|
||||
int isMounted;
|
||||
|
||||
// Mount the card, try several times as they are tricky
|
||||
while ( (tries < 10) && (ret < 0))
|
||||
|
|
@ -684,7 +677,7 @@ void MC_DeleteMode(int slot)
|
|||
while(1)
|
||||
{
|
||||
// TODO: implement showselector
|
||||
selected = ShowSelector();
|
||||
selected = ShowSelector(1);
|
||||
if (cancel)
|
||||
{
|
||||
WaitPrompt ("Delete action cancelled !");
|
||||
|
|
@ -728,4 +721,58 @@ void MC_DeleteMode(int slot)
|
|||
offsetchanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MC_FormatMode(s32 slot)
|
||||
{
|
||||
int erase = 1;
|
||||
int err;
|
||||
|
||||
//0 = B wass pressed -> ask again
|
||||
if (!slot){
|
||||
erase = WaitPromptChoice("Are you sure you want to format memory card in slot A?", "Format", "Cancel");
|
||||
}else{
|
||||
erase = WaitPromptChoice("Are you sure you want to format memory card in slot B?", "Format", "Cancel");
|
||||
}
|
||||
|
||||
if (!erase){
|
||||
if (!slot){
|
||||
erase = WaitPromptChoiceAZ("All contents of memory card in slot A will be erased, continue?", "Format", "Cancel");
|
||||
}else{
|
||||
erase = WaitPromptChoiceAZ("All contents of memory card in slot B will be erased, continue?", "Format", "Cancel");
|
||||
}
|
||||
|
||||
if (!erase)
|
||||
{
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
err = MountCard(slot);
|
||||
if (err < 0)
|
||||
{
|
||||
WaitCardError("MCFormat Mount", err);
|
||||
return; /*** Unable to mount the card ***/
|
||||
}
|
||||
ShowAction("Formatting card...");
|
||||
/*** Format the card ***/
|
||||
CARD_Format(slot);
|
||||
usleep(1000*1000);
|
||||
|
||||
/*** Try to mount the card ***/
|
||||
err = MountCard(slot);
|
||||
if (err < 0)
|
||||
{
|
||||
WaitCardError("MCFormat Mount", err);
|
||||
return; /*** Unable to mount the card ***/
|
||||
}else
|
||||
{
|
||||
WaitPrompt("Format completed successfully");
|
||||
}
|
||||
|
||||
CARD_Unmount(slot);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WaitPrompt("Format operation cancelled");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ void CardListFiles ();
|
|||
int CardReadFileHeader (int slot, int id);
|
||||
int CardReadFile (int slot, int id);
|
||||
int CardWriteFile (int slot);
|
||||
void MC_DeleteMode(int slot);
|
||||
void MC_DeleteMode(int slot);
|
||||
void MC_FormatMode(s32 slot);
|
||||
void WaitCardError(char *src, int error);
|
||||
static int OFFSET = 0;
|
||||
#endif
|
||||
|
|
|
|||
368
source/raw.c
Normal file
368
source/raw.c
Normal file
|
|
@ -0,0 +1,368 @@
|
|||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/dir.h>
|
||||
#include <dirent.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "sdsupp.h"
|
||||
#include "card.h"
|
||||
#include "mcard.h"
|
||||
#include "gci.h"
|
||||
#include "freetype.h"
|
||||
#include "raw.h"
|
||||
|
||||
u8 *CardBuffer = 0;
|
||||
s8 read_data = 0;
|
||||
Header cardheader;
|
||||
|
||||
extern syssram* __SYS_LockSram();
|
||||
extern syssramex* __SYS_LockSramEx();
|
||||
extern u32 __SYS_UnlockSram(u32 write);
|
||||
extern u32 __SYS_UnlockSramEx(u32 write);
|
||||
|
||||
syssramex *sramex;
|
||||
u8 imageserial[12];
|
||||
|
||||
//code from tueidj's Devolution
|
||||
void getserial(u8 *serial)
|
||||
{
|
||||
int i;
|
||||
uint64_t rand;
|
||||
// rand() taken from K&R, lol
|
||||
rand = cardheader.formatTime; // seed
|
||||
|
||||
for (i=0; i < 12; i++)
|
||||
{
|
||||
rand = (rand * 1103515245 + 12345) >> 16;
|
||||
cardheader.serial[i] -= rand;
|
||||
rand = ((uint32_t)rand * 1103515245 + 12345) >> 16;
|
||||
rand &= 0x7FFF;
|
||||
|
||||
serial[i] = cardheader.serial[i];
|
||||
}
|
||||
serial[13]="\0";
|
||||
|
||||
}
|
||||
|
||||
void ClearFlashID(s32 chn){
|
||||
int i;
|
||||
|
||||
sramex = __SYS_LockSramEx();
|
||||
for (i=0; i<12; i++){
|
||||
sramex->flash_id[chn][i] = 0x00;
|
||||
}
|
||||
__SYS_UnlockSramEx(1);
|
||||
}
|
||||
|
||||
void _read_callback(s32 chn,s32 result)
|
||||
{
|
||||
read_data =1;
|
||||
}
|
||||
void _write_callback(s32 chn,s32 result)
|
||||
{
|
||||
read_data =1;
|
||||
}
|
||||
|
||||
//output is 29 char long
|
||||
void time2name(char *name)
|
||||
{
|
||||
int month, day, year, hour, min, sec;
|
||||
month = day = year = hour = min = sec = 0;
|
||||
char monthstr[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
|
||||
"Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
// Taken from void SecondsToDate(int seconds, int *pYear, int *pMonth, int *pDay)
|
||||
// Calculates year month and day since jan 1, 1970 from (t) seconds
|
||||
// Reference: Fliegel, H. F. and van Flandern, T. C. (1968).
|
||||
// Communications of the ACM, Vol. 11, No. 10 (October, 1968).
|
||||
// Original code in Fortran
|
||||
int I, J, K, L, N;
|
||||
|
||||
u32 t = time(NULL);
|
||||
|
||||
L = t / 86400 + 2509157;
|
||||
N = 4 * L / 146097;
|
||||
L = L - (146097 * N + 3) / 4;
|
||||
I = 4000 * (L + 1) / 1461001;
|
||||
L = L - 1461 * I / 4 + 31;
|
||||
J = 80 * L / 2447;
|
||||
K = L - 2447 * J / 80;
|
||||
L = J / 11;
|
||||
J = J + 2 - 12 * L;
|
||||
I = 100 * (N - 49) + I + L;
|
||||
year = I;
|
||||
month = J;
|
||||
day = K;
|
||||
|
||||
sec = t % 60;
|
||||
t /= 60;
|
||||
min = t % 60;
|
||||
t /= 60;
|
||||
hour = t % 24;
|
||||
|
||||
sprintf(name, "%04d_%02d%s_%02d_%02d-%02d-%02d", year, month, monthstr[month-1], day, hour, min, sec);
|
||||
}
|
||||
|
||||
s8 BackupRawImage(s32 slot, s32 *bytes_writen )
|
||||
{
|
||||
int err;
|
||||
char filename[1024];
|
||||
char msg[1024];
|
||||
FILE* dumpFd = 0;
|
||||
u32 SectorSize = 0;
|
||||
s32 BlockCount = 0;
|
||||
|
||||
CARD_Init(NULL,NULL);
|
||||
EXI_ProbeReset();
|
||||
|
||||
err = MountCard(slot);
|
||||
if (err < 0)
|
||||
{
|
||||
WaitCardError("BakRaw", err);
|
||||
return -1; /*** Unable to mount the card ***/
|
||||
}
|
||||
|
||||
usleep(10*1000);
|
||||
|
||||
err = CARD_GetSectorSize(slot,&SectorSize);
|
||||
if(err < 0 )
|
||||
{
|
||||
WaitCardError("BakRaw Sectsize", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = CARD_GetBlockCount(slot,(u32*)&BlockCount);
|
||||
if(err < 0 )
|
||||
{
|
||||
WaitCardError("BakRaw Blockcount", err);
|
||||
return -1;
|
||||
}
|
||||
CardBuffer = (u8*)memalign(32,SectorSize*BlockCount);
|
||||
if(CardBuffer == NULL)
|
||||
{
|
||||
//printf("failed to malloc memory. fail\n");
|
||||
WaitPrompt("BackRaw: Failed to malloc memory.");
|
||||
return -1;
|
||||
}
|
||||
s32 current_block = 0;
|
||||
int read = 0;
|
||||
s32 writen = 0;
|
||||
char name[64];
|
||||
int filenumber = 1;
|
||||
time2name(name);
|
||||
sprintf (filename, "fat:/%s/Backup_%s.raw", MCSAVES, name);
|
||||
//not really needed because the filename has seconds in it and the same filename will "never" happen
|
||||
while (file_exists(filename)){
|
||||
sprintf (filename, "fat:/%s/Backup_%s_%02d.raw", MCSAVES, name, filenumber);
|
||||
filenumber++;
|
||||
}
|
||||
dumpFd = fopen(filename,"wb");
|
||||
if (dumpFd == NULL)
|
||||
{
|
||||
//printf("can not create file on SD\n");
|
||||
WaitPrompt("BackRaw: cannot create file on SD.");
|
||||
return -1;
|
||||
}
|
||||
//printf("dumping...\n");
|
||||
while( 1 )
|
||||
{
|
||||
read_data = 0;
|
||||
//printf("\rReading : %u bytes of %u (block %d)...",read,BlockCount*SectorSize,current_block);
|
||||
sprintf(msg, "Reading : %u bytes of %u (block %d)...",read,BlockCount*SectorSize,current_block);
|
||||
writeStatusBar(msg, "");
|
||||
if( (err != 0) || current_block >= BlockCount)
|
||||
break;
|
||||
err = __card_read(slot,SectorSize*current_block,SectorSize,CardBuffer+SectorSize*current_block,_read_callback);
|
||||
if(err == 0)
|
||||
{
|
||||
while(read_data == 0)
|
||||
usleep(1*1000); //sleep untill the read is done
|
||||
read = read + SectorSize;
|
||||
current_block++;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("\nerror reading data : %d...\n",err);
|
||||
fclose(dumpFd);
|
||||
WaitCardError("BakRaw __read", err);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//printf("\n");
|
||||
u8* ptr = (u8*)CardBuffer;
|
||||
for(writen = 0;writen < read;writen=writen+16384)
|
||||
{
|
||||
fwrite((u8*)ptr+writen,16384,1,dumpFd);
|
||||
//printf("\rWriting : %u bytes of %u",writen+16384,read);
|
||||
sprintf(msg, "Writing : %u bytes of %u",writen+16384,read);
|
||||
writeStatusBar(msg, "");
|
||||
}
|
||||
fclose(dumpFd);
|
||||
if(bytes_writen != NULL)
|
||||
*bytes_writen = writen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
s8 RestoreRawImage( s32 slot, char *sdfilename, s32 *bytes_writen )
|
||||
{
|
||||
FILE *dumpFd = 0;
|
||||
char filename[1024];
|
||||
char msg[256];
|
||||
int err;
|
||||
u32 SectorSize = 0;
|
||||
s32 BlockCount = 0;
|
||||
s32 current_block = 0;
|
||||
s32 writen = 0;
|
||||
|
||||
CARD_Init(NULL,NULL);
|
||||
EXI_ProbeReset();
|
||||
|
||||
err = MountCard(slot);
|
||||
if (err < 0)
|
||||
{
|
||||
WaitCardError("RestRaw", err);
|
||||
return -1; /*** Unable to mount the card ***/
|
||||
}
|
||||
|
||||
usleep(10*1000);
|
||||
|
||||
err = CARD_GetSectorSize(slot,&SectorSize);
|
||||
if(err < 0 )
|
||||
{
|
||||
WaitCardError("RestRaw Sectsize", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = CARD_GetBlockCount(slot,(u32*)&BlockCount);
|
||||
if(err < 0 )
|
||||
{
|
||||
WaitCardError("RestRaw Blockcount", err);
|
||||
return -1;
|
||||
}
|
||||
CardBuffer = (u8*)memalign(32,SectorSize*BlockCount);
|
||||
if(CardBuffer == NULL)
|
||||
{
|
||||
//printf("failed to malloc memory. fail\n");
|
||||
WaitPrompt("RestRaw: Failed to malloc memory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*** Make fullpath filename ***/
|
||||
sprintf (filename, "fat:/%s/%s", MCSAVES, sdfilename);
|
||||
|
||||
/*** Open the SD Card file ***/
|
||||
dumpFd = fopen ( filename , "rb" );
|
||||
if (dumpFd <= 0)
|
||||
{
|
||||
free(CardBuffer);
|
||||
sprintf(msg, "Couldn't open %s", filename);
|
||||
WaitPrompt (msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//first read the content of the SD dump into the buffer.
|
||||
u32 lSize;
|
||||
fseek (dumpFd , 0 , SEEK_END);
|
||||
lSize = ftell (dumpFd);
|
||||
rewind (dumpFd);
|
||||
if(lSize != BlockCount*SectorSize)
|
||||
{
|
||||
//check for mci raw image
|
||||
if((lSize-64) != BlockCount*SectorSize){
|
||||
//incorrect dump size D:<
|
||||
fclose(dumpFd);
|
||||
free(CardBuffer);
|
||||
WaitPrompt ("Card and image sizes differ");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//printf("are you -SURE- you want to recover? a faulty backup or even a program\nfailure will corrupt the memory card!\n");
|
||||
|
||||
int erase = 1;
|
||||
//0 = B wass pressed -> ask again
|
||||
if (!slot){
|
||||
erase = WaitPromptChoice("Are you -SURE- you want to restore to memory card in slot A?", "Restore", "Cancel");
|
||||
}else{
|
||||
erase = WaitPromptChoice("Are you -SURE- you want to restore to memory card in slot B?", "Restore", "Cancel");
|
||||
}
|
||||
|
||||
if (!erase)
|
||||
{
|
||||
if (!slot){
|
||||
erase = WaitPromptChoiceAZ("All contents of memory card in slot A will be overwritten, continue?", "Restore", "Cancel");
|
||||
}else{
|
||||
erase = WaitPromptChoiceAZ("All contents of memory card in slot B will be erased, continue?", "Restore", "Cancel");
|
||||
}
|
||||
|
||||
if (!erase)
|
||||
{
|
||||
if ((lSize-64) == BlockCount*SectorSize) fseek(dumpFd, 64, SEEK_SET);
|
||||
fread(CardBuffer,BlockCount*0x2000,1,dumpFd);
|
||||
fclose(dumpFd);
|
||||
|
||||
// Test code to see if raw image is correctly read
|
||||
FILE *test = 0;
|
||||
test = fopen ( "fat:/test.bin" , "wb" );
|
||||
fwrite (CardBuffer , 1 , BlockCount*0x2000 , test );
|
||||
fclose (test);
|
||||
|
||||
|
||||
//printf("writing data to memory card...\n");
|
||||
ShowAction ("Writing data to memory card...");
|
||||
s32 upblock = 0;
|
||||
s32 write_len = SectorSize;
|
||||
//s32 write_len = 0x80;//pagesize o memory card
|
||||
while( 1 )
|
||||
{
|
||||
//printf("\rWriting... : %d of %d (block %d)",writen,BlockCount*SectorSize,current_block);
|
||||
sprintf(msg, "Writing... : Block %d (%d of %d)",current_block, writen,BlockCount*SectorSize);
|
||||
ShowAction (msg);
|
||||
//gprintf("\rWriting... : %d of %d (block %d of %d)",writen,BlockCount*SectorSize,current_block,BlockCount);
|
||||
read_data = 0;
|
||||
if( (err != 0) || current_block >= BlockCount || writen == BlockCount*SectorSize)
|
||||
break;
|
||||
//s32 __card_write(s32 chn,u32 address,u32 block_len,void *buffer,cardcallback callback)
|
||||
err = __card_write(slot,writen,write_len,CardBuffer+writen,_read_callback);
|
||||
if(err == 0)
|
||||
{
|
||||
while(read_data == 0)
|
||||
usleep(1*1000); //sleep untill the write is done which sadly takes alot longer then read
|
||||
__card_sync(slot);
|
||||
|
||||
writen = writen + write_len;
|
||||
upblock=upblock+write_len;
|
||||
if(upblock == SectorSize)
|
||||
{
|
||||
current_block++;
|
||||
upblock = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(dumpFd);
|
||||
free(CardBuffer);
|
||||
//printf("\nerror writing data(%d) Memory card could be corrupt now!!!\n",err);
|
||||
sprintf(msg, "error writing data(%d) Memory card could be corrupt now!!!",err);
|
||||
WaitPrompt (msg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//printf("\n");
|
||||
//gprintf("\n");
|
||||
if(bytes_writen != NULL)
|
||||
*bytes_writen = writen;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
22
source/raw.h
Normal file
22
source/raw.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
typedef struct {
|
||||
//Offset Size Description
|
||||
// Serial in libogc
|
||||
u8 serial[12]; //0x0000 12 ?
|
||||
u64 formatTime; //0x000c 8 time of format (OSTime value)
|
||||
u32 SramBias; //0x0014 4 sram bias at time of format
|
||||
u32 SramLang; //0x0018 4 sram language
|
||||
u8 Unk2[4]; //0x001c 4 ? almost always 0
|
||||
// end Serial in libogc
|
||||
u8 deviceID[2]; //0x0020 2 0 if formated in slot A 1 if formated in slot B
|
||||
u8 SizeMb[2]; //0x0022 2 size of memcard in Mbits
|
||||
u16 Encoding; //0x0024 2 encoding (ASCII or japanese)
|
||||
u8 Unused1[468]; //0x0026 468 unused (0xff)
|
||||
u16 UpdateCounter; //0x01fa 2 update Counter (?, probably unused)
|
||||
u16 Checksum; //0x01fc 2 Additive Checksum
|
||||
u16 Checksum_Inv; //0x01fe 2 Inverse Checksum
|
||||
u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff)
|
||||
} __attribute__((__packed__)) Header;
|
||||
|
||||
void getserial(u8 *serial);
|
||||
s8 BackupRawImage(s32 slot, s32 *bytes_writen);
|
||||
s8 RestoreRawImage(s32 slot, char *sdfilename, s32 *bytes_writen);
|
||||
117
source/sdsupp.c
117
source/sdsupp.c
|
|
@ -15,6 +15,8 @@
|
|||
#include "freetype.h"
|
||||
#include "gci.h"
|
||||
#include "mcard.h"
|
||||
#include "card.h"
|
||||
#include "raw.h"
|
||||
|
||||
#define PAGESIZE 20
|
||||
#define PADCAL 80
|
||||
|
|
@ -25,6 +27,7 @@
|
|||
/*** Memory Card FileBuffer ***/
|
||||
#define MAXFILEBUFFER (1024 * 2048) /*** 2MB Buffer ***/
|
||||
extern u8 FileBuffer[MAXFILEBUFFER] ATTRIBUTE_ALIGN (32);
|
||||
extern Header cardheader;
|
||||
extern u8 CommentBuffer[64] ATTRIBUTE_ALIGN (32);
|
||||
extern u16 bannerdata[CARD_BANNER_W*CARD_BANNER_H] ATTRIBUTE_ALIGN (32);
|
||||
extern u8 bannerdataCI[CARD_BANNER_W*CARD_BANNER_H] ATTRIBUTE_ALIGN (32);
|
||||
|
|
@ -377,10 +380,13 @@ int SDLoadMCImageHeader(char *sdfilename)
|
|||
}
|
||||
|
||||
ExtractGCIHeader();
|
||||
// GCIMakeHeader();
|
||||
#ifdef STATUSOGC
|
||||
GCIMakeHeader();
|
||||
#else
|
||||
//Let's get the full header as is, instead of populating it...
|
||||
memset(&gci, 0xff, sizeof(GCI)); /*** Clear out the cgi header ***/
|
||||
memcpy (&gci, FileBuffer, sizeof (GCI));
|
||||
#endif
|
||||
|
||||
//Find how many icons are present
|
||||
numicons = 8;
|
||||
|
|
@ -464,6 +470,62 @@ int SDLoadMCImageHeader(char *sdfilename)
|
|||
return bytesToRead;
|
||||
}
|
||||
|
||||
int SDLoadCardImageHeader(char *sdfilename)
|
||||
{
|
||||
|
||||
FILE *handle;
|
||||
char filename[1024];
|
||||
char msg[256];
|
||||
long bytesToRead = 0;
|
||||
|
||||
/*** Clear the work buffers ***/
|
||||
memset (&cardheader, 0, sizeof(Header));
|
||||
|
||||
/*** Make fullpath filename ***/
|
||||
sprintf (filename, "fat:/%s/%s", MCSAVES, sdfilename);
|
||||
|
||||
/*** Open the SD Card file ***/
|
||||
handle = fopen ( filename , "rb" );
|
||||
if (handle <= 0)
|
||||
{
|
||||
sprintf(msg, "Couldn't open %s", filename);
|
||||
WaitPrompt (msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// obtain file size:
|
||||
fseek (handle , 0 , SEEK_END);
|
||||
bytesToRead = ftell (handle);
|
||||
rewind (handle);
|
||||
if (bytesToRead < 8192) //We don't want to read something smaller than the card header
|
||||
{
|
||||
sprintf(msg, "Incorrect file size %ld . Not raw image file or header", bytesToRead);
|
||||
WaitPrompt (msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char fileType[1024];
|
||||
char * dot;
|
||||
int pos = 4;
|
||||
dot = strrchr(filename,'.');
|
||||
strncpy(fileType, dot+1,pos);
|
||||
fileType[pos]='\0';
|
||||
|
||||
if(!strcasecmp(fileType, "mci"))
|
||||
{
|
||||
//MCI files have a 64 byte header
|
||||
fseek(handle, 64, SEEK_SET);
|
||||
}
|
||||
memset(&cardheader, 0, sizeof(cardheader));
|
||||
/*** Read the file header ***/
|
||||
fread (&cardheader,1,sizeof(cardheader),handle);
|
||||
|
||||
/*** Close the file ***/
|
||||
fclose (handle);
|
||||
|
||||
return bytesToRead;
|
||||
}
|
||||
|
||||
int isdir_sd(char *path)
|
||||
{
|
||||
DIR* dir = opendir(path);
|
||||
|
|
@ -475,12 +537,43 @@ int isdir_sd(char *path)
|
|||
return 1;
|
||||
}
|
||||
|
||||
//Code from Kobie. Returns true if extension matches (also works with paths), should check only the last '.' in the string.
|
||||
bool compare_extension(char *filename, char *extension)
|
||||
{
|
||||
/* Sanity checks */
|
||||
|
||||
if(filename == NULL || extension == NULL)
|
||||
return false;
|
||||
|
||||
if(strlen(filename) == 0 || strlen(extension) == 0)
|
||||
return false;
|
||||
|
||||
if(strchr(filename, '.') == NULL || strchr(extension, '.') == NULL)
|
||||
return false;
|
||||
|
||||
/* Iterate backwards through respective strings and compare each char one at a time */
|
||||
int i;
|
||||
for(i = 0; i < strlen(filename); i++)
|
||||
{
|
||||
if(tolower(filename[strlen(filename) - i - 1]) == tolower(extension[strlen(extension) - i - 1]))
|
||||
{
|
||||
if(i == strlen(extension) - 1)
|
||||
return true;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* SDGetFileList
|
||||
*
|
||||
* Get the directory listing from SD Card
|
||||
* Mode 1: retrieves .gci, .sav and .gcs
|
||||
* Mode 0: retrieves .raw, .gcp and .mci
|
||||
****************************************************************************/
|
||||
int SDGetFileList()
|
||||
int SDGetFileList(int mode)
|
||||
{
|
||||
int filecount = 0;
|
||||
DIR *dir;
|
||||
|
|
@ -501,11 +594,23 @@ int SDGetFileList()
|
|||
{
|
||||
if(strncmp(dit->d_name, ".", 1) != 0 && strncmp(dit->d_name, "..", 2) != 0)
|
||||
{
|
||||
strcpy((char *)filelist[filecount], dit->d_name);
|
||||
sprintf(namefile, "%s%s", filename, dit->d_name);
|
||||
dirtype = ((isdir_sd(namefile) == 1) ? DIRENT_T_DIR : DIRENT_T_FILE);
|
||||
if (mode){
|
||||
if (compare_extension(dit->d_name, ".gci") || compare_extension(dit->d_name, ".sav") || compare_extension(dit->d_name, ".gcs")){
|
||||
strcpy((char *)filelist[filecount], dit->d_name);
|
||||
sprintf(namefile, "%s%s", filename, dit->d_name);
|
||||
dirtype = ((isdir_sd(namefile) == 1) ? DIRENT_T_DIR : DIRENT_T_FILE);
|
||||
|
||||
filecount++;
|
||||
filecount++;
|
||||
}
|
||||
}else if (!mode){
|
||||
if (compare_extension(dit->d_name, ".raw") || compare_extension(dit->d_name, ".gcp") || compare_extension(dit->d_name, ".mci")){
|
||||
strcpy((char *)filelist[filecount], dit->d_name);
|
||||
sprintf(namefile, "%s%s", filename, dit->d_name);
|
||||
dirtype = ((isdir_sd(namefile) == 1) ? DIRENT_T_DIR : DIRENT_T_FILE);
|
||||
|
||||
filecount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
int SDSaveMCImage();
|
||||
int SDLoadMCImage(char *sdfilename);
|
||||
int SDLoadMCImageHeader(char *sdfilename);
|
||||
int SDLoadCardImageHeader(char *sdfilename);
|
||||
int isdir_sd(char *path);
|
||||
int SDGetFileList();
|
||||
int SDGetFileList(int mode);
|
||||
bool file_exists(const char * filename);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user