rearrange vfat code to be reusable by multiple devices, make slot1-R4 use it, add slot1-fat-dir=/path/to/dir for setting up a fat image for slot-1 devices, rename "compact flash" addon to MPCF, make DLDI-autopatcher not touch roms unless "Default (No interface)" is the current driver (otherwise, your roms intentionally patched with other things will get overwritten)

This commit is contained in:
zeromus 2011-01-14 03:19:05 +00:00
parent b14e6f01df
commit 575d87fc98
25 changed files with 800 additions and 1215 deletions

View File

@ -944,7 +944,7 @@ void MMU_Reset()
rtcInit();
partie = 1;
addonsReset();
slot1Close();
slot1Reset();
Mic_Reset();
MMU.gfx3dCycles = 0;

View File

@ -19,8 +19,9 @@ libdesmume_a_SOURCES = \
common.cpp common.h \
debug.cpp debug.h \
Disassembler.cpp Disassembler.h \
emufat.h emufat.cpp emufat_types.h emufile.h emufile.cpp emufile_types.h fat.h FIFO.cpp FIFO.h \
emufile.h emufile.cpp emufile_types.h fat.h FIFO.cpp FIFO.h \
firmware.cpp firmware.h GPU.cpp GPU.h \
fs.h \
GPU_osd.h \
mem.h mc.cpp mc.h \
path.cpp path.h \
@ -44,10 +45,12 @@ libdesmume_a_SOURCES = \
PACKED.h PACKED_END.h \
utils/datetime.cpp utils/datetime.h \
utils/ConvertUTF.c utils/ConvertUTF.h utils/guid.cpp utils/guid.h \
utils/emufat.cpp utils/emufat.h utils/emufat_types.h \
utils/md5.cpp utils/md5.h utils/valuearray.h utils/xstring.cpp utils/xstring.h \
utils/decrypt/crc.cpp utils/decrypt/crc.h utils/decrypt/decrypt.cpp \
utils/decrypt/decrypt.h utils/decrypt/header.cpp utils/decrypt/header.h \
utils/task.cpp utils/task.h \
utils/vfat.h utils/vfat.cpp \
utils/dlditool.cpp \
utils/libfat/bit_ops.h \
utils/libfat/cache.cpp \
@ -77,7 +80,7 @@ libdesmume_a_SOURCES = \
utils/libfat/partition.cpp \
utils/libfat/partition.h \
addons.cpp addons.h \
addons/compactFlash.cpp addons/gbagame.cpp addons/none.cpp addons/rumblepak.cpp addons/guitarGrip.cpp addons/expMemory.cpp addons/piano.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail.cpp fs.h \
addons/slot2_mpcf.cpp addons/gbagame.cpp addons/none.cpp addons/rumblepak.cpp addons/guitarGrip.cpp addons/expMemory.cpp addons/piano.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail.cpp \
cheatSystem.cpp cheatSystem.h \
texcache.cpp texcache.h rasterize.cpp rasterize.h \
metaspu/metaspu.cpp metaspu/metaspu.h \

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010 DeSmuME team
/* Copyright (C) 2010-2011 DeSmuME team
This file is part of DeSmuME
@ -17,13 +17,15 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <time.h>
#include "../slot1.h"
#include "../registers.h"
#include "../MMU.h"
#include "../NDSSystem.h"
#include <time.h>
#include "../emufile.h"
static FILE *img = NULL;
static EMUFILE *img = NULL;
static u32 write_count = 0;
static u32 write_enabled = 0;
static void init_r4_flash()
@ -31,11 +33,11 @@ static void init_r4_flash()
srand(time(NULL));
if (!img)
img = fopen("DLDI_R4DS.img", "r+b");
img = slot1GetFatImage();
if(!img)
{
INFO("DLDI_R4DS.img not found\n");
INFO("slot1 fat not successfully mounted\n");
}
}
@ -48,9 +50,13 @@ static BOOL init()
return TRUE;
}
static void reset() {}
static void reset() {
init_r4_flash();
}
static void close() {}
static void close() {
img = NULL;
}
static void write08(u8 PROCNUM, u32 adr, u8 val) {}
@ -67,14 +73,14 @@ static void write32_GCROMCTRL(u32 val)
case 0xB9:
case 0xBA:
card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4];
fseek(img,card.address,SEEK_SET);
img->fseek(card.address,SEEK_SET);
break;
case 0xBB:
write_enabled = 1;
write_count = 0x80;
case 0xBC:
card.address = (card.command[1] << 24) | (card.command[2] << 16) | (card.command[3] << 8) | card.command[4];
fseek(img,card.address,SEEK_SET);
img->fseek(card.address,SEEK_SET);
break;
}
}
@ -105,8 +111,8 @@ static void write32_GCDATAIN(u32 val)
{
if(write_count && write_enabled)
{
fwrite(&val, 1, 4, img);
fflush(img);
img->fwrite(&val, 4);
img->fflush();
write_count--;
}
break;
@ -186,7 +192,7 @@ static u32 read32_GCDATAIN()
break;
case 0xBA:
//INFO("Read from sd at sector %08X at adr %08X ",card.address/512,ftell(img));
fread(&val, 1, 4, img);
img->fread(&val, 4);
//INFO("val %08X\n",val);
break;

View File

@ -0,0 +1,344 @@
/* Copyright (C) 2006 yopyop
Copyright (C) 2006 Mic
Copyright (C) 2009-2011 DeSmuME team
This file is part of DeSmuME
DeSmuME 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../addons.h"
#include <string>
#include <string.h>
#include "debug.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "../utils/vfat.h"
#include "../path.h"
#include "MMU.h"
#include "NDSSystem.h"
// Set up addresses for GBAMP
#define CF_REG_DATA 0x9000000
#define CF_REG_ERR 0x9020000
#define CF_REG_SEC 0x9040000
#define CF_REG_LBA1 0x9060000
#define CF_REG_LBA2 0x9080000
#define CF_REG_LBA3 0x90A0000
#define CF_REG_LBA4 0x90C0000
#define CF_REG_CMD 0x90E0000
#define CF_REG_STS 0x98C0000
// CF Card commands
#define CF_CMD_LBA 0xE0
#define CF_CMD_READ 0x20
#define CF_CMD_WRITE 0x30
static u16 cf_reg_sts,
cf_reg_lba1,
cf_reg_lba2,
cf_reg_lba3,
cf_reg_lba4,
cf_reg_cmd;
static off_t currLBA;
static const int lfnPos[13] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
static u32 fileStartLBA,fileEndLBA;
static std::string sFlashPath;
static BOOL cflashDeviceEnabled = FALSE;
static EMUFILE* file;
// ===========================
BOOL inited;
enum EListCallbackArg {
EListCallbackArg_Item, EListCallbackArg_Pop
};
static BOOL cflash_init()
{
if (inited) return FALSE;
BOOL init_good = FALSE;
CFLASHLOG("CFlash_Mode: %d\n",CFlash_Mode);
if (CFlash_Mode == ADDON_CFLASH_MODE_RomPath)
{
sFlashPath = path.pathToRoms;
INFO("Using CFlash directory of rom: %s\n", sFlashPath.c_str());
}
else if(CFlash_Mode == ADDON_CFLASH_MODE_Path)
{
sFlashPath = CFlash_Path;
INFO("Using CFlash directory: %s\n", sFlashPath.c_str());
}
if(CFlash_IsUsingPath())
{
cflashDeviceEnabled = FALSE;
currLBA = 0;
fileStartLBA = fileEndLBA = 0xFFFFFFFF;
VFAT vfat;
bool ret = vfat.build(sFlashPath.c_str(),16); //allocate 16MB extra for writing. this is probably enough for anyone, but maybe it should be configurable.
//we could always suggest to users to add a big file to their directory to overwrite (that would cause the image to get padded)
if(!ret)
{
CFLASHLOG("FAILED cflash_build_fat\n");
return FALSE;
}
file = vfat.detach();
cf_reg_sts = 0x58; // READY
cflashDeviceEnabled = TRUE;
init_good = TRUE;
}
else
{
sFlashPath = CFlash_Path;
INFO("Using CFlash disk image file %s\n", sFlashPath.c_str());
file = new EMUFILE_FILE(sFlashPath.c_str(),"rb+");
if(file->fail())
{
INFO("Failed to open file %s\n", sFlashPath.c_str());
delete file;
file = NULL;
}
}
// READY
cf_reg_sts = 0x58;
currLBA = 0;
cf_reg_lba1 = cf_reg_lba2 =
cf_reg_lba3 = cf_reg_lba4 = 0;
inited = TRUE;
return init_good;
}
static unsigned int cflash_read(unsigned int address)
{
unsigned int ret_value = 0;
size_t elems_read = 0;
switch (address)
{
case CF_REG_STS:
ret_value = cf_reg_sts;
break;
case CF_REG_DATA:
if (cf_reg_cmd == CF_CMD_READ)
{
if(file)
{
u8 data[2];
file->fseek(currLBA, SEEK_SET);
elems_read += file->fread(data,2);
ret_value = data[1] << 8 | data[0];
}
currLBA += 2;
}
break;
case CF_REG_CMD:
break;
case CF_REG_LBA1:
ret_value = cf_reg_lba1;
break;
}
return ret_value;
}
static void cflash_write(unsigned int address,unsigned int data)
{
static u8 sector_data[512];
static u32 sector_write_index = 0;
switch (address)
{
case CF_REG_STS:
cf_reg_sts = data&0xFFFF;
break;
case CF_REG_DATA:
if (cf_reg_cmd == CF_CMD_WRITE)
{
{
sector_data[sector_write_index] = (data >> 0) & 0xff;
sector_data[sector_write_index + 1] = (data >> 8) & 0xff;
sector_write_index += 2;
if (sector_write_index == 512)
{
CFLASHLOG( "Write sector to %ld\n", currLBA);
size_t written = 0;
if(file)
if(currLBA + 512 < file->size())
{
file->fseek(currLBA,SEEK_SET);
while(written < 512)
{
size_t todo = 512-written;
file->fwrite(&sector_data[written], todo);
size_t cur_write = todo;
written += cur_write;
if ( cur_write == (size_t)-1) break;
}
}
CFLASHLOG("Wrote %u bytes\n", written);
currLBA += 512;
sector_write_index = 0;
}
}
}
break;
case CF_REG_CMD:
cf_reg_cmd = data&0xFF;
cf_reg_sts = 0x58; // READY
break;
case CF_REG_LBA1:
cf_reg_lba1 = data&0xFF;
currLBA = (currLBA&0xFFFFFF00)| cf_reg_lba1;
break;
case CF_REG_LBA2:
cf_reg_lba2 = data&0xFF;
currLBA = (currLBA&0xFFFF00FF)|(cf_reg_lba2<<8);
break;
case CF_REG_LBA3:
cf_reg_lba3 = data&0xFF;
currLBA = (currLBA&0xFF00FFFF)|(cf_reg_lba3<<16);
break;
case CF_REG_LBA4:
cf_reg_lba4 = data&0xFF;
if ((cf_reg_lba4 & 0xf0) == CF_CMD_LBA)
{
currLBA = (currLBA&0x00FFFFFF)|((cf_reg_lba4&0x0F)<<24);
currLBA *= 512;
sector_write_index = 0;
}
break;
}
}
static void cflash_close( void)
{
if (!inited) return;
if (!CFlash_IsUsingPath())
{
delete file;
file = NULL;
}
else
{
int i;
cflashDeviceEnabled = FALSE;
}
inited = FALSE;
}
static BOOL init(void)
{
return TRUE;
}
static void reset(void)
{
cflash_close();
cflash_init();
}
static void close(void)
{
cflash_close();
}
static void config(void)
{
}
static void write08(u32 adr, u8 val)
{
cflash_write(adr, val);
}
static void write16(u32 adr, u16 val)
{
cflash_write(adr, val);
}
static void write32(u32 adr, u32 val)
{
cflash_write(adr, val);
}
static u8 read08(u32 adr)
{
return (cflash_read(adr));
}
static u16 read16(u32 adr)
{
return (cflash_read(adr));
}
static u32 read32(u32 adr)
{
return (cflash_read(adr));
}
static void info(char *info)
{
strcpy(info, "MPCF Flash Card Device");
}
ADDONINTERFACE addonCFlash = {
"MPCF Flash Card Device",
init,
reset,
close,
config,
write08,
write16,
write32,
read08,
read16,
read32,
info};
#undef CFLASHDEBUG

View File

@ -1,6 +1,4 @@
/* commandline.cpp
Copyright (C) 2009-2010 DeSmuME team
/* Copyright (C) 2009-2011 DeSmuME team
This file is part of DeSmuME
@ -52,6 +50,7 @@ CommandLine::CommandLine()
, _rigorous_timing(0)
, _advanced_timing(-1)
, _slot1(NULL)
, _slot1_fat_dir(NULL)
, depth_threshold(-1)
, load_slot(-1)
, arm9_gdb_port(0)
@ -94,6 +93,7 @@ void CommandLine::loadCommonOptions()
{ "rigorous-timing", 0, 0, G_OPTION_ARG_INT, &_rigorous_timing, "Use some rigorous timings instead of unrealistically generous (default 0)", "RIGOROUS_TIMING"},
{ "advanced-timing", 0, 0, G_OPTION_ARG_INT, &_advanced_timing, "Use advanced BUS-level timing (default 1)", "ADVANCED_TIMING"},
{ "slot1", 0, 0, G_OPTION_ARG_STRING, &_slot1, "Device to load in slot 1 (default retail)", "SLOT1"},
{ "slot1-fat-dir", 0, 0, G_OPTION_ARG_STRING, &_slot1_fat_dir, "Directory to scan for slot 1", "SLOT1_DIR"},
{ "depth-threshold", 0, 0, G_OPTION_ARG_INT, &depth_threshold, "Depth comparison threshold (default 0)", "DEPTHTHRESHOLD"},
#ifndef _MSC_VER
{ "disable-sound", 0, 0, G_OPTION_ARG_NONE, &disable_sound, "Disables the sound emulation", NULL},
@ -119,6 +119,7 @@ bool CommandLine::parse(int argc,char **argv)
return false;
}
if(_slot1_fat_dir) slot1_fat_dir = _slot1_fat_dir;
if(_slot1) slot1 = _slot1;
if(slot1.size() != 0) str_lcase((char*)&slot1[0]);
if(_play_movie_file) play_movie_file = _play_movie_file;
@ -227,10 +228,12 @@ void CommandLine::process_addonCommands()
is_cflash_configured = true;
}
if(slot1_fat_dir != "")
slot1SetFatDir(slot1_fat_dir);
if(slot1 == "retail")
slot1Change(NDS_SLOT1_RETAIL);
else if(slot1 == "r4")
slot1Change(NDS_SLOT1_R4);
}

View File

@ -1,6 +1,4 @@
/* commandline.h
Copyright (C) 2009-2010 DeSmuME team
/* Copyright (C) 2009-2011 DeSmuME team
This file is part of DeSmuME
@ -50,6 +48,7 @@ public:
std::string cflash_path;
std::string gbaslot_rom;
std::string slot1;
std::string slot1_fat_dir;
#ifndef _MSC_VER
int disable_sound;
int disable_limiter;
@ -91,6 +90,7 @@ private:
int _rigorous_timing;
int _advanced_timing;
char* _slot1;
char *_slot1_fat_dir;
};
#endif

View File

@ -61,7 +61,7 @@ size_t EMUFILE_MEMORY::_fread(const void *ptr, size_t bytes){
void EMUFILE_FILE::truncate(s32 length)
{
fflush(fp);
::fflush(fp);
#ifdef _MSC_VER
_chsize(_fileno(fp),length);
#else

View File

@ -113,6 +113,7 @@ public:
virtual int ftell() = 0;
virtual int size() = 0;
virtual void fflush() = 0;
virtual void truncate(s32 length) = 0;
};
@ -244,6 +245,8 @@ public:
return pos;
}
virtual void fflush() {}
void trim()
{
vec->resize(len);
@ -319,7 +322,7 @@ public:
failbit = true;
}
virtual int fseek(int offset, int origin){
virtual int fseek(int offset, int origin) {
return ::fseek(fp, offset, origin);
}
@ -335,6 +338,10 @@ public:
return len;
}
virtual void fflush() {
::fflush(fp);
}
};
#endif

View File

@ -1,87 +0,0 @@
/*
FAT.H
Mic, 2006
Structures taken from Michael Chisholm's FAT library
*/
#ifndef __FAT_H__
#define __FAT_H__
#include "types.h"
#include "PACKED.h"
#include "PACKED_END.h"
#define ATTRIB_DIR 0x10
#define ATTRIB_LFN 0x0F
#define FILE_FREE 0xE5
/* Name and extension maximum length */
#define NAME_LEN 8
#define EXT_LEN 3
// Boot Sector - must be packed
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define DIR_SEP "\\"
#else
#define DIR_SEP "/"
#endif
#include "PACKED.h"
struct boot_record
{
u8 jmpBoot[3];
u8 OEMName[8];
// BIOS Parameter Block
u16 bytesPerSector;
u8 sectorsPerCluster;
u16 reservedSectors;
u8 numFATs;
u16 rootEntries;
u16 numSectorsSmall;
u8 mediaDesc;
u16 sectorsPerFAT;
u16 sectorsPerTrk;
u16 numHeads;
u32 numHiddenSectors;
u32 numSectors;
struct
{
// Ext BIOS Parameter Block for FAT16
u8 driveNumber;
u8 reserved1;
u8 extBootSig;
u32 volumeID;
u8 volumeLabel[11];
u8 fileSysType[8];
// Bootcode
u8 bootCode[448];
u16 signature;
} __PACKED fat16;
} __PACKED;
typedef struct boot_record BOOT_RECORD;
#include "PACKED_END.h"
// Directory entry - must be packed
#include "PACKED.h"
struct dir_ent
{
u8 name[NAME_LEN];
u8 ext[EXT_LEN];
u8 attrib;
u8 reserved;
u8 cTime_ms;
u16 cTime;
u16 cDate;
u16 aDate;
u16 startClusterHigh;
u16 mTime;
u16 mDate;
u16 startCluster;
u32 fileSize;
} __PACKED;
typedef struct dir_ent DIR_ENT;
#include "PACKED_END.h"
#endif //

View File

@ -484,6 +484,7 @@ void BackupDevice::reset_command()
default:
//the archaic case: write the address and then some modulo-4 number of bytes
//why modulo 4? who knows.
//SM64 (KOR) makes it here with autodetect_size=11 and nothing interesting in the buffer
addr_size = autodetect_size & 3;
break;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010 DeSmuME team
/* Copyright (C) 2010-2011 DeSmuME team
This file is part of DeSmuME
@ -17,30 +17,57 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "slot1.h"
#include <string>
#include "types.h"
#include "slot1.h"
#include "emufile.h"
#include "utils/vfat.h"
extern SLOT1INTERFACE slot1None;
extern SLOT1INTERFACE slot1Retail;
extern SLOT1INTERFACE slot1R4;
static EMUFILE* fatImage = NULL;
static std::string fatDir;
SLOT1INTERFACE slot1List[NDS_SLOT1_COUNT] = {
slot1None,
slot1Retail,
slot1R4
};
SLOT1INTERFACE slot1_device = slot1Retail; //default for frontends that dont even configure this
u8 slot1_device_type = NDS_SLOT1_RETAIL;
SLOT1INTERFACE slot1_device = slot1Retail; //default for frontends that dont even configure this
u8 slot1_device_type = NDS_SLOT1_RETAIL;
static void scanDir()
{
if(fatDir == "") return;
delete fatImage;
fatImage = NULL;
VFAT vfat;
if(vfat.build(fatDir.c_str(),16))
{
fatImage = vfat.detach();
}
}
BOOL slot1Init()
{
scanDir();
return slot1_device.init();
}
void slot1Close()
{
slot1_device.close();
//be careful to do this second, maybe the device will write something more
delete fatImage;
fatImage = NULL;
}
void slot1Reset()
@ -57,3 +84,13 @@ BOOL slot1Change(NDS_SLOT1_TYPE changeToType)
slot1_device = slot1List[slot1_device_type];
return slot1_device.init();
}
void slot1SetFatDir(const std::string& dir)
{
fatDir = dir;
}
EMUFILE* slot1GetFatImage()
{
return fatImage;
}

View File

@ -20,10 +20,13 @@
#ifndef __SLOT1_H__
#define __SLOT1_H__
#include <string>
#include "common.h"
#include "types.h"
#include "debug.h"
class EMUFILE;
struct SLOT1INTERFACE
{
// The name of the plugin, this name will appear in the plugins list
@ -65,10 +68,11 @@ enum NDS_SLOT1_TYPE
NDS_SLOT1_COUNT // use for counter addons - MUST TO BE LAST!!!
};
extern BOOL slot1Init();
extern void slot1Close();
extern void slot1Reset();
extern BOOL slot1Change(NDS_SLOT1_TYPE type); // change current adddon
BOOL slot1Init();
void slot1Close();
void slot1Reset();
BOOL slot1Change(NDS_SLOT1_TYPE type); // change current adddon
void slot1SetFatDir(const std::string& dir);
EMUFILE* slot1GetFatImage();
#endif //__ADDONS_H__

View File

@ -649,6 +649,12 @@ bool tryPatch(void* data, size_t size)
return false;
}
if(memcmp(&pAH[DO_friendlyName],"Default (No interface)",22))
{
printf("Would have been a candidate for auto-patch DLDI, but there was already a patch installed.");
return false;
}
//----should be able to patch OK-----
addr_t memOffset; // Offset of DLDI after the file is loaded into memory

234
desmume/src/utils/vfat.cpp Normal file
View File

@ -0,0 +1,234 @@
/* Copyright (C) 2006 yopyop
Copyright (C) 2006 Mic
Copyright (C) 2010-2011 DeSmuME team
This file is part of DeSmuME
DeSmuME 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include "../types.h"
#include "../debug.h"
#include "../fs.h"
#include "emufat.h"
#include "vfat.h"
#include "libfat/libfat_public_api.h"
enum EListCallbackArg {
EListCallbackArg_Item, EListCallbackArg_Pop
};
typedef void (*ListCallback)(FsEntry* fs, EListCallbackArg);
// List all files and subdirectories recursively
static void list_files(const char *filepath, ListCallback list_callback)
{
char DirSpec[255+1], SubDir[255+1];
FsEntry entry;
void * hFind;
char *fname;
u32 dwError;
strncpy(DirSpec, filepath, ARRAY_SIZE(DirSpec));
DirSpec[255] = 0 ; // hard limit the string here
hFind = FsReadFirst(DirSpec, &entry);
if (hFind == NULL) return;
fname = (strlen(entry.cAlternateFileName)>0) ? entry.cAlternateFileName : entry.cFileName;
list_callback(&entry,EListCallbackArg_Item);
while (FsReadNext(hFind, &entry) != 0)
{
fname = (strlen(entry.cAlternateFileName)>0) ? entry.cAlternateFileName : entry.cFileName;
list_callback(&entry,EListCallbackArg_Item);
printf("cflash added %s\n",entry.cFileName);
if ((entry.flags & FS_IS_DIR) && (strcmp(fname, ".")) && (strcmp(fname, "..")))
{
if (strlen(fname)+strlen(filepath)+2 < 256)
{
sprintf(SubDir, "%s%c%s", filepath, FS_SEPARATOR, fname);
list_files(SubDir, list_callback);
list_callback(&entry, EListCallbackArg_Pop);
}
}
}
dwError = FsError();
FsClose(hFind);
if (dwError != FS_ERR_NO_MORE_FILES) return;
}
static u64 dataSectors = 0;
void count_ListCallback(FsEntry* fs, EListCallbackArg arg)
{
if(arg == EListCallbackArg_Pop) return;
u32 sectors = 1;
if(fs->flags & FS_IS_DIR)
{
}
else
sectors += (fs->fileSize+511)/512 + 1;
dataSectors += sectors;
}
static std::string currPath;
static std::stack<std::string> pathStack;
static std::stack<std::string> virtPathStack;
static std::string currVirtPath;
void build_ListCallback(FsEntry* fs, EListCallbackArg arg)
{
char* fname = (strlen(fs->cAlternateFileName)>0) ? fs->cAlternateFileName : fs->cFileName;
//we use cFileName always because it is a LFN and we are making sure that we always make a fat32 image
fname = fs->cFileName;
if(arg == EListCallbackArg_Pop)
{
currPath = pathStack.top();
pathStack.pop();
currVirtPath = virtPathStack.top();
virtPathStack.pop();
return;
}
if(fs->flags & FS_IS_DIR)
{
if(!strcmp(fname,".")) return;
if(!strcmp(fname,"..")) return;
pathStack.push(currPath);
virtPathStack.push(currVirtPath);
currVirtPath = currVirtPath + "/" + fname;
bool ok = LIBFAT::MkDir(currVirtPath.c_str());
if(!ok)
printf("ERROR adding dir %s via libfat\n",currVirtPath.c_str());
currPath = currPath + std::string(1,FS_SEPARATOR) + fname;
return;
}
else
{
std::string path = currPath + std::string(1,FS_SEPARATOR) + fname;
FILE* inf = fopen(path.c_str(),"rb");
if(inf)
{
fseek(inf,0,SEEK_END);
long len = ftell(inf);
fseek(inf,0,SEEK_SET);
u8 *buf = new u8[len];
fread(buf,1,len,inf);
fclose(inf);
std::string path = currVirtPath + "/" + fname;
bool ok = LIBFAT::WriteFile(path.c_str(),buf,len);
if(!ok)
printf("ERROR adding file %s via libfat\n",path.c_str());
delete[] buf;
}
}
}
bool VFAT::build(const char* path, int extra_MB)
{
dataSectors = 0;
currVirtPath = "";
currPath = path;
list_files(path, count_ListCallback);
dataSectors += 8; //a few for reserved sectors, etc.
dataSectors += extra_MB*1024*1024/512; //add extra write space
//dataSectors += 16*1024*1024/512; //add 16MB worth of write space. this is probably enough for anyone, but maybe it should be configurable.
//we could always suggest to users to add a big file to their directory to overwrite (that would cause the image to get padded)
//this seems to be the minimum size that will turn into a solid fat32
if(dataSectors<36*1024*1024/512)
dataSectors = 36*1024*1024/512;
if(dataSectors>=(0x80000000>>9))
{
printf("error allocating memory for fat (%d KBytes)\n",(dataSectors*512)/1024);
printf("total fat sizes > 2GB are never going to work\n");
}
delete file;
try
{
file = new EMUFILE_MEMORY(dataSectors*512);
}
catch(std::bad_alloc)
{
printf("error allocating memory for fat (%d KBytes)\n",(dataSectors*512)/1024);
printf("(out of memory)\n");
return false;
}
//debug..
//file = new EMUFILE_FILE("c:\\temp.ima","rb+");
//format the disk
{
EmuFat fat(file);
EmuFatVolume vol;
u8 ok = vol.init(&fat);
vol.formatNew(dataSectors);
//ensure we are working in memory, just in case we were testing with a disk file.
//libfat will need to go straight to memory (for now; we could easily change it to work with the disk)
file = file->memwrap();
}
EMUFILE_MEMORY* memf = (EMUFILE_MEMORY*)file;
//setup libfat and write all the files through it
LIBFAT::Init(memf->buf(),memf->size());
list_files(path, build_ListCallback);
LIBFAT::Shutdown();
return true;
}
VFAT::VFAT()
: file(NULL)
{
}
VFAT::~VFAT()
{
delete file;
}
EMUFILE* VFAT::detach()
{
EMUFILE* ret = file;
file = NULL;
return ret;
}

39
desmume/src/utils/vfat.h Normal file
View File

@ -0,0 +1,39 @@
/* Copyright (C) 2011 DeSmuME team
This file is part of DeSmuME
DeSmuME 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VFAT_H
class EMUFILE;
//THIS CLASS IS NOT THREAD SAFE!! SORRY SO SLOPPY
class VFAT
{
public:
VFAT();
~VFAT();
bool build(const char* path, int extra_MB=0);
EMUFILE* detach();
private:
EMUFILE* file;
};
#endif //_VFAT_H

View File

@ -454,7 +454,7 @@
StructMemberAlignment="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="false"
EnableEnhancedInstructionSet="2"
EnableEnhancedInstructionSet="0"
FloatingPointModel="2"
RuntimeTypeInfo="false"
WarningLevel="3"
@ -1232,7 +1232,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -1242,7 +1242,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -1252,7 +1252,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -1262,7 +1262,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -1272,7 +1272,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -1282,7 +1282,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -1377,6 +1377,18 @@
RelativePath="..\utils\dlditool.cpp"
>
</File>
<File
RelativePath="..\utils\emufat.cpp"
>
</File>
<File
RelativePath="..\utils\emufat.h"
>
</File>
<File
RelativePath="..\utils\emufat_types.h"
>
</File>
<File
RelativePath="..\utils\guid.cpp"
>
@ -1405,6 +1417,14 @@
RelativePath="..\utils\valuearray.h"
>
</File>
<File
RelativePath="..\utils\vfat.cpp"
>
</File>
<File
RelativePath="..\utils\vfat.h"
>
</File>
<File
RelativePath="..\utils\xstring.cpp"
>
@ -1611,10 +1631,6 @@
<Filter
Name="addons"
>
<File
RelativePath="..\addons\compactFlash.cpp"
>
</File>
<File
RelativePath="..\addons\expMemory.cpp"
>
@ -1651,6 +1667,10 @@
RelativePath="..\addons\slot1_retail.cpp"
>
</File>
<File
RelativePath="..\addons\slot2_mpcf.cpp"
>
</File>
</Filter>
<Filter
Name="metaspu"
@ -1960,18 +1980,6 @@
RelativePath="..\driver.h"
>
</File>
<File
RelativePath="..\emufat.cpp"
>
</File>
<File
RelativePath="..\emufat.h"
>
</File>
<File
RelativePath="..\emufat_types.h"
>
</File>
<File
RelativePath="..\emufile.cpp"
>

View File

@ -718,18 +718,6 @@
RelativePath="..\driver.h"
>
</File>
<File
RelativePath="..\emufat.cpp"
>
</File>
<File
RelativePath="..\emufat.h"
>
</File>
<File
RelativePath="..\emufat_types.h"
>
</File>
<File
RelativePath="..\emufile.cpp"
>
@ -1005,10 +993,6 @@
<Filter
Name="addons"
>
<File
RelativePath="..\addons\compactFlash.cpp"
>
</File>
<File
RelativePath="..\addons\expMemory.cpp"
>
@ -1045,6 +1029,10 @@
RelativePath="..\addons\slot1_retail.cpp"
>
</File>
<File
RelativePath="..\addons\slot2_mpcf.cpp"
>
</File>
</Filter>
<Filter
Name="gdbstub"
@ -1081,6 +1069,14 @@
RelativePath="..\utils\dlditool.cpp"
>
</File>
<File
RelativePath="..\utils\emufat.cpp"
>
</File>
<File
RelativePath="..\utils\emufat.h"
>
</File>
<File
RelativePath="..\utils\guid.cpp"
>
@ -1109,6 +1105,14 @@
RelativePath="..\utils\valuearray.h"
>
</File>
<File
RelativePath="..\utils\vfat.cpp"
>
</File>
<File
RelativePath="..\utils\vfat.h"
>
</File>
<File
RelativePath="..\utils\xstring.cpp"
>
@ -2005,7 +2009,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -2015,7 +2019,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -2025,7 +2029,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -2035,7 +2039,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -2045,7 +2049,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
AdditionalDependencies="7z.exe;un7z_and_touch.bat"
Outputs=".libs\lua.tag"
/>
@ -2055,7 +2059,7 @@
>
<Tool
Name="VCCustomBuildTool"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag"
CommandLine="un7z_and_touch.bat lua\lua.7z .libs\win32\lua* .libs\x64\lua* .libs\lua.tag&#x0D;&#x0A;"
Outputs=".libs\lua.tag"
/>
</FileConfiguration>

View File

@ -432,6 +432,7 @@
<ClCompile Include="..\addons\slot1_none.cpp" />
<ClCompile Include="..\addons\slot1_r4.cpp" />
<ClCompile Include="..\addons\slot1_retail.cpp" />
<ClCompile Include="..\addons\slot2_mpcf.cpp" />
<ClCompile Include="..\aggdraw.cpp" />
<ClCompile Include="..\arm_instructions.cpp" />
<ClCompile Include="..\armcpu.cpp" />
@ -447,7 +448,6 @@
<ClCompile Include="..\debug.cpp" />
<ClCompile Include="..\Disassembler.cpp" />
<ClCompile Include="..\driver.cpp" />
<ClCompile Include="..\emufat.cpp" />
<ClCompile Include="..\emufile.cpp" />
<ClCompile Include="..\FIFO.cpp" />
<ClCompile Include="..\firmware.cpp" />
@ -475,6 +475,7 @@
<ClCompile Include="..\thumb_instructions.cpp" />
<ClCompile Include="..\utils\datetime.cpp" />
<ClCompile Include="..\utils\dlditool.cpp" />
<ClCompile Include="..\utils\emufat.cpp" />
<ClCompile Include="..\utils\libfat\cache.cpp" />
<ClCompile Include="..\utils\libfat\directory.cpp" />
<ClCompile Include="..\utils\libfat\disc.cpp" />
@ -486,9 +487,9 @@
<ClCompile Include="..\utils\libfat\libfat_public_api.cpp" />
<ClCompile Include="..\utils\libfat\lock.cpp" />
<ClCompile Include="..\utils\libfat\partition.cpp" />
<ClCompile Include="..\utils\vfat.cpp" />
<ClCompile Include="..\version.cpp" />
<ClCompile Include="..\wifi.cpp" />
<ClCompile Include="..\addons\compactFlash.cpp" />
<ClCompile Include="..\addons\expMemory.cpp" />
<ClCompile Include="..\addons\gbagame.cpp" />
<ClCompile Include="..\addons\guitarGrip.cpp" />
@ -574,7 +575,6 @@
<ClInclude Include="..\debug.h" />
<ClInclude Include="..\Disassembler.h" />
<ClInclude Include="..\driver.h" />
<ClInclude Include="..\emufat.h" />
<ClInclude Include="..\emufat_types.h" />
<ClInclude Include="..\emufile.h" />
<ClInclude Include="..\fat.h" />
@ -609,6 +609,8 @@
<ClInclude Include="..\thumb_instructions.h" />
<ClInclude Include="..\types.h" />
<ClInclude Include="..\utils\datetime.h" />
<ClInclude Include="..\utils\emufat.h" />
<ClInclude Include="..\utils\emufat_types.h" />
<ClInclude Include="..\utils\libfat\bit_ops.h" />
<ClInclude Include="..\utils\libfat\cache.h" />
<ClInclude Include="..\utils\libfat\common.h" />
@ -625,6 +627,7 @@
<ClInclude Include="..\utils\libfat\lock.h" />
<ClInclude Include="..\utils\libfat\mem_allocate.h" />
<ClInclude Include="..\utils\libfat\partition.h" />
<ClInclude Include="..\utils\vfat.h" />
<ClInclude Include="..\version.h" />
<ClInclude Include="..\wifi.h" />
<ClInclude Include="..\utils\xstring.h" />

View File

@ -165,9 +165,6 @@
<ClCompile Include="..\wifi.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\addons\compactFlash.cpp">
<Filter>Core\addons</Filter>
</ClCompile>
<ClCompile Include="..\addons\expMemory.cpp">
<Filter>Core\addons</Filter>
</ClCompile>
@ -396,9 +393,6 @@
<ClCompile Include="..\addons\slot1_retail.cpp">
<Filter>Core\addons</Filter>
</ClCompile>
<ClCompile Include="..\emufat.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\utils\datetime.cpp">
<Filter>Core\utils</Filter>
</ClCompile>
@ -438,6 +432,15 @@
<ClCompile Include="..\path.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\addons\slot2_mpcf.cpp">
<Filter>Core\addons</Filter>
</ClCompile>
<ClCompile Include="..\utils\vfat.cpp">
<Filter>Core\utils</Filter>
</ClCompile>
<ClCompile Include="..\utils\emufat.cpp">
<Filter>Core\utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\addons.h">
@ -767,9 +770,6 @@
<ClInclude Include="filter\hq2x.h" />
<ClInclude Include="filter\interp.h" />
<ClInclude Include="filter\lq2x.h" />
<ClInclude Include="..\emufat.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="..\emufat_types.h" />
<ClInclude Include="..\utils\datetime.h">
<Filter>Core\utils</Filter>
@ -822,6 +822,15 @@
<ClInclude Include="..\utils\libfat\mem_allocate.h">
<Filter>Core\utils\libfat</Filter>
</ClInclude>
<ClInclude Include="..\utils\vfat.h">
<Filter>Core\utils</Filter>
</ClInclude>
<ClInclude Include="..\utils\emufat.h">
<Filter>Core\utils</Filter>
</ClInclude>
<ClInclude Include="..\utils\emufat_types.h">
<Filter>Core\utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\instruction_tabdef.inc">

View File

@ -117,7 +117,7 @@ INT_PTR CALLBACK GbaSlotCFlash(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = dialog;
const char *fileFilter = "Compact Flash image (*.img)\0*.img\0Any file (*.*)\0*.*\0";
const char *fileFilter = "FAT image (*.img)\0*.img\0Any file (*.*)\0*.*\0";
ofn.lpstrFilter = fileFilter;
ofn.nFilterIndex = 1;
@ -144,7 +144,7 @@ INT_PTR CALLBACK GbaSlotCFlash(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam
bp.hwndOwner=dialog;
bp.pidlRoot=NULL;
bp.pszDisplayName=NULL;
bp.lpszTitle="Select directory for Compact Flash";
bp.lpszTitle="Select directory for FAT image building";
bp.ulFlags=BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_USENEWUI;
bp.lpfn=NULL;

Binary file not shown.