diff --git a/nds/Makefile b/nds/Makefile index cc7afe9..511d023 100644 --- a/nds/Makefile +++ b/nds/Makefile @@ -104,7 +104,7 @@ dist-bin: install: cp lib/libfat.a $(DEVKITPRO)/libnds/lib - cp include/fat.h include/nitrofs.h $(DEVKITPRO)/libnds/include + cp include/fat.h $(DEVKITPRO)/libnds/include #--------------------------------------------------------------------------------- else diff --git a/nds/include/nitrofs.h b/nds/include/nitrofs.h deleted file mode 100644 index 209e75f..0000000 --- a/nds/include/nitrofs.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - nitrofs.h - Simple functionality for initialising nitrofs filesystem. - - Copyright (c) 2008 - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - - -#ifndef _NITROFS_H -#define _NITROFS_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -bool nitroFSInit(); - -#ifdef __cplusplus -} -#endif - -#endif // _NITROFS_H diff --git a/nds/source/nitrofs.c b/nds/source/nitrofs.c deleted file mode 100644 index 1eb2ef2..0000000 --- a/nds/source/nitrofs.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - nitrofs.c - eris's wai ossum nitro filesystem device driver - Based on information found at http://frangoassado.org/ds/rom_spec.txt and from the #dsdev ppls - Kallisti (K) 2008-01-26 All rights reversed. -*/ -#include -#include -#include - -#include -#include -#include - -DIR_ITER* nitroFSDirOpen(struct _reent *r, DIR_ITER *dirState, const char *path); -int nitroDirReset(struct _reent *r, DIR_ITER *dirState); -int nitroFSDirNext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st); -int nitroFSDirClose(struct _reent *r, DIR_ITER *dirState); -int nitroFSOpen(struct _reent *r, void *fileStruct, const char *path,int flags,int mode); -int nitroFSClose(struct _reent *r,int fd); -ssize_t nitroFSRead(struct _reent *r,int fd,char *ptr,size_t len); -off_t nitroFSSeek(struct _reent *r,int fd,off_t pos,int dir); -int nitroFSFstat(struct _reent *r,int fd,struct stat *st); - -#define LOADERSTR "PASS" //look for this -#define LOADERSTROFFSET 0xac -#define FNTOFFSET 0x40 -#define FATOFFSET 0x48 - -#define NITRONAMELENMAX 0x80 //max file name is 127 +1 for zero byte :D -#define NITROMAXPATHLEN 0x100 //256 bytes enuff? - -#define NITROROOT 0xf000 //root entry_file_id -#define NITRODIRMASK 0x0fff //remove leading 0xf - -#define NITROISDIR 0x80 //mask to indicate this name entry is a dir, other 7 bits = name length - -//Directory filename subtable entry structure -struct ROM_FNTDir { - u32 entry_start; - u16 entry_file_id; - u16 parent_id; -}; - -//Yo, dis table is fat (describes the structures -struct ROM_FAT { - u32 top; //start of file in rom image - u32 bottom; //end of file in rom image -}; - -//used (mostly by the 'sub' functions) for the raw reading of rom image either via gba rom or dldi -struct nitroRawStruct { - FILE *ndsFile; //used if going thru dldi >_> (if set to null we assume GBA with loader) - unsigned int pos; //where in the file am i? -}; - -struct nitroFSStruct { - struct nitroRawStruct nrs; - unsigned int start; //where in the rom this file starts - unsigned int end; //where in the rom this file ends -// unsigned int pos; //where in current file are we? -}; - -struct nitroDIRStruct { - struct nitroRawStruct nrs; - unsigned int namepos; //ptr to next name to lookup in list - struct ROM_FAT romfat; - u16 entry_id; //which entry this is (for files only) incremented with each new file in dir? - u16 dir_id; //which directory entry this is.. used ofc for dirs only - u16 cur_dir_id; //which directory entry we are using - u16 parent_id; //who is the parent of the current directory (this can be used to easily ../ ) -}; - -//Globals! -u32 fntOffset; //offset to start of filename table -u32 fatOffset; //offset to start of file alloc table -bool isNdsFile; //is it a nds file? -const char *ndsfilename; //what nds file to use - -devoptab_t nitroFSdevoptab={ - "nitro", // const char *name; - sizeof(struct nitroFSStruct), // int structSize; - &nitroFSOpen, // int (*open_r)(struct _reent *r, void *fileStruct, const char *path,int flags,int mode); - &nitroFSClose, // int (*close_r)(struct _reent *r,int fd); - NULL, // ssize_t (*write_r)(struct _reent *r,int fd,const char *ptr,size_t len); - &nitroFSRead, // ssize_t (*read_r)(struct _reent *r,int fd,char *ptr,size_t len); - &nitroFSSeek, // off_t (*seek_r)(struct _reent *r,int fd,off_t pos,int dir); - &nitroFSFstat, // int (*fstat_r)(struct _reent *r,int fd,struct stat *st); - NULL, // int (*stat_r)(struct _reent *r,const char *file,struct stat *st); - NULL, // int (*link_r)(struct _reent *r,const char *existing, const char *newLink); - NULL, // int (*unlink_r)(struct _reent *r,const char *name); - NULL, // int (*chdir_r)(struct _reent *r,const char *name); - - NULL, // int (*rename_r) (struct _reent *r, const char *oldName, const char *newName); - NULL, // int (*mkdir_r) (struct _reent *r, const char *path, int mode); - - sizeof(struct nitroDIRStruct), // int dirStateSize; - &nitroFSDirOpen, // DIR_ITER* (*diropen_r)(struct _reent *r, DIR_ITER *dirState, const char *path); - &nitroDirReset, // int (*dirreset_r)(struct _reent *r, DIR_ITER *dirState); - &nitroFSDirNext, // int (*dirnext_r)(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat); - &nitroFSDirClose, // int (*dirclose_r)(struct _reent *r, DIR_ITER *dirState); - NULL, // int (*statvfs_r)(struct _reent *r, const char *path, struct statvfs *buf); - NULL, // int (*ftruncate_r)(struct _reent *r, int fd, off_t len); - NULL, // int (*fsync_r)(struct _reent *r, int fd); - NULL, // void *deviceData; -}; - -//inline these mebbe? these 4 'sub' functions deal with actually reading from either gba rom or .nds file :) -//what i rly rly rly wanna know is how an actual nds cart reads from itself, but it seems no one can tell me ~_~ -//so, instead we have this weird weird haxy try gbaslot then try dldi method. If i (or you!!) ever do figure out -//how to read the proper way can replace these 4 functions and everything should work normally :) -int nitroSubOpen(struct nitroRawStruct *nrs) { - if(isNdsFile) { - if((nrs->ndsFile = fopen(ndsfilename,"rb+"))) { - nrs->pos=0; - return 1; - } - } else { - nrs->ndsFile=(FILE*)NULL; - nrs->pos=0; - return 1; - } - return(0); -} - -int nitroSubClose(struct nitroRawStruct *nrs) { - if(isNdsFile) - return(fclose(nrs->ndsFile)); - return(0); -} - - -//reads from rom image either gba rom or dldi -int nitroSubRead(struct nitroRawStruct *nrs, void *ptr, int len) { - if(isNdsFile) { //read from ndsfile - len=fread(ptr,1,len,nrs->ndsFile); - } else { //reading from gbarom - memcpy(ptr, nrs->pos+(void*)GBAROM,len); //len isnt checked here because other checks exist in the callers (hopefully) - } - nrs->pos+=len; - return(len); -} - -int nitroSubSeek(struct nitroRawStruct *nrs, int pos, int dir) { - if(dir==SEEK_SET) //otherwise just set the pos :) - nrs->pos=pos; - else if(dir==SEEK_CUR) - nrs->pos+=pos; //see ez! - if(isNdsFile) { //read from ndsfile actually do a seek - return(fseek(nrs->ndsFile,pos,dir)); - } else { - return(nrs->pos); - } -} - -//Figure out if its gba or ds, setup stuff -bool nitroFSInit() { - struct nitroRawStruct nrs; - char romstr[0x10]; - - sysSetCartOwner(BUS_OWNER_ARM9 ); - - if(strncmp(((const char *)GBAROM)+LOADERSTROFFSET,LOADERSTR,strlen(LOADERSTR))==0) { // found standard nds file in gba cart - fntOffset=((u32)*(u32*)(((const char *)GBAROM)+FNTOFFSET)); - fatOffset=((u32)*(u32*)(((const char *)GBAROM)+FATOFFSET)); - isNdsFile=false; - AddDevice(&nitroFSdevoptab); - return true; - - } else { //okay then try something else ~_~ - - isNdsFile=true; - - if ( __system_argv->argvMagic == ARGV_MAGIC && __system_argv->argc >= 1 ) { - ndsfilename=__system_argv->argv[0]; //set global for what file.nds to use - if (!fatInitDefault()) return false; - if(nitroSubOpen(&nrs)) { - nitroSubSeek(&nrs,LOADERSTROFFSET,SEEK_SET); - nitroSubRead(&nrs,romstr,strlen(LOADERSTR)); - - if(strncmp(romstr,LOADERSTR,strlen(LOADERSTR))!=0) return false; - - nitroSubSeek(&nrs,FNTOFFSET,SEEK_SET); - nitroSubRead(&nrs,&fntOffset,sizeof(fntOffset)); - nitroSubSeek(&nrs,FATOFFSET,SEEK_SET); - nitroSubRead(&nrs,&fatOffset,sizeof(fatOffset)); - nitroSubClose(&nrs); - - AddDevice(&nitroFSdevoptab); - return true; - } - } - } - return false; -} - - - -//Directory functs -DIR_ITER* nitroFSDirOpen(struct _reent *r, DIR_ITER *dirState, const char *path) { - struct nitroDIRStruct *dirStruct=(struct nitroDIRStruct*)dirState->dirStruct; //this makes it lots easier! - struct stat st; - char dirname[NITRONAMELENMAX]; - char *cptr; - char mydirpath[NITROMAXPATHLEN]; //to hold copy of path string - char *dirpath=mydirpath; -//NOTE: might add prepending of chdir path? seems like lotta work for something silly that shoulda been handled in newlib anyways ~_~ - bool pathfound; - if((cptr=strchr(path,':'))) - path=cptr+1; //move path past any device names (if it was nixy style wouldnt need this step >_>) - strncpy(dirpath,path,sizeof(mydirpath)-1); //copy the string (as im gonna mutalate it) - nitroSubOpen(&dirStruct->nrs); //open a file for me to use - dirStruct->cur_dir_id=NITROROOT; //first root dir - nitroDirReset(r,dirState); //set dir to current path - do { - while((cptr=strchr(dirpath,'/'))==dirpath) { - dirpath++; //move past any leading / or // together - } - if(cptr) - *cptr=0; //erase / - //here is prolly where you should handle .. and . filenames if desired - if(*dirpath==0) {//are we at the end of the path string?? if so there is nothing to search for we're already here ! - pathfound=true; //mostly this handles searches for root or / or no path specified cases - break; - } - pathfound=false; - while(nitroFSDirNext(r,dirState,dirname,&st)==0) { - if((st.st_mode==S_IFDIR) && !(strcmp(dirname,dirpath))) { //if its a directory and name matches dirpath - dirStruct->cur_dir_id=dirStruct->dir_id; //move us to the next dir in tree - nitroDirReset(r,dirState); //set dir to current path we just found... - pathfound=true; - break; - } - }; - if(!pathfound) - break; - dirpath=cptr+1; //move to right after last / we found - } while(cptr); // go till after the last / - if(pathfound) { - return(dirState); - } else { - nitroSubClose(&dirStruct->nrs); //oops almost forgot to close the file we opened <_< - return(NULL); - } -} - - -int nitroFSDirClose(struct _reent *r, DIR_ITER *dirState) { - return(nitroSubClose(&((struct nitroDIRStruct*)dirState->dirStruct)->nrs)); - -} - -//reset dir to start of entry selected by dirStruct->cur_dir_id which should be set in dirOpen -int nitroDirReset(struct _reent *r, DIR_ITER *dirState) { - struct nitroDIRStruct *dirStruct=(struct nitroDIRStruct*)dirState->dirStruct; //this makes it lots easier! - struct ROM_FNTDir dirsubtable; - nitroSubSeek(&dirStruct->nrs,fntOffset+((dirStruct->cur_dir_id&NITRODIRMASK)*sizeof(struct ROM_FNTDir)),SEEK_SET); - nitroSubRead(&dirStruct->nrs, &dirsubtable, sizeof(dirsubtable)); - dirStruct->namepos=dirsubtable.entry_start; //set namepos to first entry in this dir's table - dirStruct->entry_id=dirsubtable.entry_file_id; //get number of first file ID in this branch - dirStruct->parent_id=dirsubtable.parent_id; //save parent ID in case we wanna add ../ functionality - return(0); -} - -int nitroFSDirNext(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { - unsigned char next; - struct nitroDIRStruct *dirStruct=(struct nitroDIRStruct*)dirState->dirStruct; //this makes it lots easier! - nitroSubSeek(&dirStruct->nrs,fntOffset+dirStruct->namepos,SEEK_SET); - nitroSubRead(&dirStruct->nrs, &next , sizeof(next)); - // next: high bit 0x80 = entry isdir.. other 7 bits r size, the 16 bits following name are dir's entryid (starts with f000) - // 00 = endoftable // - if(next) { - if(next&NITROISDIR) { - if(st) st->st_mode=S_IFDIR; - next&=NITROISDIR^0xff; //invert bits and mask off 0x80 - nitroSubRead(&dirStruct->nrs,filename,next); -// nitroSubRead(&dirStruct->nrs,&dirStruct->dir_id,sizeof(struct nitroDIRStruct.dir_id)); //read the dir_id -//grr cant get the struct member size?, just wanna test it so moving on... - nitroSubRead(&dirStruct->nrs,&dirStruct->dir_id,sizeof(u16)); //read the dir_id - dirStruct->namepos+=next+sizeof(u16)+1; //now we points to next one plus dir_id size:D - } else { - if(st) st->st_mode=0; - nitroSubRead(&dirStruct->nrs,filename,next); - dirStruct->namepos+=next+1; //now we points to next one :D - //read file info to get filesize (and for fileopen) - nitroSubSeek(&dirStruct->nrs,fatOffset+(dirStruct->entry_id*sizeof(struct ROM_FAT)),SEEK_SET); - nitroSubRead(&dirStruct->nrs, &dirStruct->romfat, sizeof(dirStruct->romfat)); //retrieve romfat entry (contains filestart and end positions) - dirStruct->entry_id++; //advance ROM_FNTStrFile ptr - if(st) st->st_size=dirStruct->romfat.bottom-dirStruct->romfat.top; //calculate filesize - } - filename[(int)next]=0; //zero last char - return(0); - } else { - return(-1); - } -} - -//fs functs -int nitroFSOpen(struct _reent *r, void *fileStruct, const char *path,int flags,int mode) { - struct nitroFSStruct *fatStruct=(struct nitroFSStruct *)fileStruct; - struct nitroDIRStruct dirStruct; - DIR_ITER dirState; - dirState.dirStruct=&dirStruct; //create a temp dirstruct - struct _reent dre; - struct stat st; //all these are just used for reading the dir ~_~ - char dirfilename[NITROMAXPATHLEN]; // to hold a full path (i tried to avoid using so much stack but blah :/) - char *filename; // to hold filename - char *cptr; //used to string searching and manipulation - cptr=(char*)path+strlen(path); //find the end... - filename=NULL; - do { - if((*cptr=='/') || (*cptr==':')) { // split at either / or : (whichever comes first from the end!) - cptr++; - strncpy(dirfilename,path,cptr-path); //copy string up till and including/ or : zero rest - dirfilename[cptr-path]=0; //it seems strncpy doesnt always zero?! - filename=cptr; //filename = now remainder of string - break; - } - } while(cptr--!=dirfilename); //search till start - if(!filename) { //we didnt find a / or : ? shouldnt realyl happen but if it does... - filename=(char*)path; //filename = complete path - dirfilename[0]=0; //make directory path "" - } - if(nitroFSDirOpen(&dre,&dirState,dirfilename)) { - fatStruct->start=0; - while(nitroFSDirNext(&dre,&dirState, dirfilename, &st)==0) { - if(!(st.st_mode & S_IFDIR) && (strcmp(dirfilename,filename)==0)) { //Found the *file* your looking for!! - fatStruct->start=dirStruct.romfat.top; - fatStruct->end=dirStruct.romfat.bottom; - break; - } - } - if(fatStruct->start) { - fatStruct->nrs.ndsFile=dirStruct.nrs.ndsFile; //reuse already open'd filehandle - nitroSubSeek(&fatStruct->nrs,fatStruct->start,SEEK_SET); //seek to start of file - return(0); //woot! - } - nitroFSDirClose(&dre,&dirState); - } - return(-1); -} - -int nitroFSClose(struct _reent *r,int fd) { - return(nitroSubClose(&((struct nitroFSStruct *)fd)->nrs)); -} - -ssize_t nitroFSRead(struct _reent *r,int fd,char *ptr,size_t len) { - struct nitroFSStruct *fatStruct=(struct nitroFSStruct *)fd; - struct nitroRawStruct *nrs=&((struct nitroFSStruct *)fd)->nrs; - if(nrs->pos+len > fatStruct->end) - len=fatStruct->end-nrs->pos; //dont let us read past the end plz! - if(nrs->pos > fatStruct->end) - return(0); //hit eof - return(nitroSubRead(nrs,ptr,len)); -} - -off_t nitroFSSeek(struct _reent *r,int fd ,off_t pos,int dir) { - //need check for eof here... - struct nitroFSStruct *fatStruct=(struct nitroFSStruct *)fd; - struct nitroRawStruct *nrs=&((struct nitroFSStruct *)fd)->nrs; - if(dir==SEEK_SET) - pos+=fatStruct->start; //add start from .nds file offset - if(pos > fatStruct->end) - return(0); //dont let us read past the end plz! - return(nitroSubSeek(nrs,pos,dir)); - -} - -int nitroFSFstat(struct _reent *r,int fd,struct stat *st) { - struct nitroFSStruct *fatStruct=(struct nitroFSStruct *)fd; - //cant think of what else to do here besides report the size atm - st->st_size=fatStruct->end-fatStruct->start; - return(0); -}