mirror of
https://github.com/ApacheThunder/akmenu-next.git
synced 2025-06-18 19:25:37 -04:00
TopToyLauncher: use 8.3 filename for TTMENU.SYS
Fixes an issue on some SD card
This commit is contained in:
parent
30836cdae3
commit
7ebc6abf53
@ -20,6 +20,7 @@
|
||||
#include "../ui/progresswnd.h"
|
||||
#include "ILauncher.h"
|
||||
#include "TopToyLauncher.h"
|
||||
#include "libfat_ext/fat_ext.h"
|
||||
|
||||
static void resetAndLoop() {
|
||||
DC_FlushAll();
|
||||
@ -117,6 +118,7 @@ typedef struct {
|
||||
|
||||
// TTMENU.SYS file creation. Sets up parameters for ttpatch.dat
|
||||
bool TopToyLauncher::prepareTTSYS(void) {
|
||||
char fname[0x1004] = {};
|
||||
TTSYSHeader* ttsys_header = (TTSYSHeader*)malloc(sizeof(TTSYSHeader));
|
||||
ttsys_header->TTSYSMagic[0] = 't';
|
||||
ttsys_header->TTSYSMagic[1] = 't';
|
||||
@ -132,10 +134,12 @@ bool TopToyLauncher::prepareTTSYS(void) {
|
||||
fseek(TTSYSFile, 0, SEEK_SET);
|
||||
fwrite(ttsys_header, sizeof(TTSYSHeader), 1, TTSYSFile);
|
||||
free(ttsys_header);
|
||||
fatGetAliasPath("fat:/", mRomPath.c_str(), fname);
|
||||
fseek(TTSYSFile, 0x100, SEEK_SET);
|
||||
fwrite(mRomPath.c_str() + 4, 1, 0x1000, TTSYSFile);
|
||||
fwrite(fname + 4, 1, 0x1000, TTSYSFile);
|
||||
fatGetAliasPath("fat:/", mSavePath.c_str(), fname);
|
||||
fseek(TTSYSFile, 0x1100, SEEK_SET);
|
||||
fwrite(mSavePath.c_str() + 4, 1, 0x1000, TTSYSFile);
|
||||
fwrite(fname + 4, 1, 0x1000, TTSYSFile);
|
||||
if (mFlags & PATCH_CHEATS) {
|
||||
fseek(TTSYSFile, 0x2100, SEEK_SET);
|
||||
fwrite("/YSMENU.ARP", 1, 0x12, TTSYSFile);
|
||||
|
129
arm9/source/launcher/libfat_ext/cache.h
Normal file
129
arm9/source/launcher/libfat_ext/cache.h
Normal file
@ -0,0 +1,129 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
cache.h
|
||||
The cache is not visible to the user. It should be flushed
|
||||
when any file is closed or changes are made to the filesystem.
|
||||
|
||||
This cache implements a least-used-page replacement policy. This will
|
||||
distribute sectors evenly over the pages, so if less than the maximum
|
||||
pages are used at once, they should all eventually remain in the cache.
|
||||
This also has the benefit of throwing out old sectors, so as not to keep
|
||||
too many stale pages around.
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
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 _CACHE_H
|
||||
#define _CACHE_H
|
||||
|
||||
#include "fatcommon.h"
|
||||
|
||||
typedef struct {
|
||||
sec_t sector;
|
||||
unsigned int count;
|
||||
unsigned int last_access;
|
||||
bool dirty;
|
||||
uint8_t* cache;
|
||||
} CACHE_ENTRY;
|
||||
|
||||
typedef struct {
|
||||
const DISC_INTERFACE* disc;
|
||||
sec_t endOfPartition;
|
||||
unsigned int numberOfPages;
|
||||
unsigned int sectorsPerPage;
|
||||
unsigned int bytesPerSector;
|
||||
CACHE_ENTRY* cacheEntries;
|
||||
} CACHE;
|
||||
|
||||
/*
|
||||
Read data from a sector in the cache
|
||||
If the sector is not in the cache, it will be swapped in
|
||||
offset is the position to start reading from
|
||||
size is the amount of data to read
|
||||
Precondition: offset + size <= BYTES_PER_READ
|
||||
*/
|
||||
bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, unsigned int offset, size_t size);
|
||||
|
||||
bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes);
|
||||
|
||||
/*
|
||||
Write data to a sector in the cache
|
||||
If the sector is not in the cache, it will be swapped in.
|
||||
When the sector is swapped out, the data will be written to the disc
|
||||
offset is the position to start writing to
|
||||
size is the amount of data to write
|
||||
Precondition: offset + size <= BYTES_PER_READ
|
||||
*/
|
||||
bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size);
|
||||
|
||||
bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int num_bytes);
|
||||
|
||||
/*
|
||||
Write data to a sector in the cache, zeroing the sector first
|
||||
If the sector is not in the cache, it will be swapped in.
|
||||
When the sector is swapped out, the data will be written to the disc
|
||||
offset is the position to start writing to
|
||||
size is the amount of data to write
|
||||
Precondition: offset + size <= BYTES_PER_READ
|
||||
*/
|
||||
bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size);
|
||||
|
||||
/*
|
||||
Read several sectors from the cache
|
||||
*/
|
||||
bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void* buffer);
|
||||
|
||||
/*
|
||||
Read a full sector from the cache
|
||||
*/
|
||||
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
|
||||
return _FAT_cache_readPartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
|
||||
}
|
||||
|
||||
/*
|
||||
Write a full sector to the cache
|
||||
*/
|
||||
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
|
||||
return _FAT_cache_writePartialSector (cache, buffer, sector, 0, cache->bytesPerSector);
|
||||
}
|
||||
|
||||
bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, const void* buffer);
|
||||
|
||||
/*
|
||||
Write any dirty sectors back to disc and clear out the contents of the cache
|
||||
*/
|
||||
bool _FAT_cache_flush (CACHE* cache);
|
||||
|
||||
/*
|
||||
Clear out the contents of the cache without writing any dirty sectors first
|
||||
*/
|
||||
void _FAT_cache_invalidate (CACHE* cache);
|
||||
|
||||
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, unsigned int bytesPerSector);
|
||||
|
||||
void _FAT_cache_destructor (CACHE* cache);
|
||||
|
||||
#endif // _CACHE_H
|
||||
|
182
arm9/source/launcher/libfat_ext/directory.h
Normal file
182
arm9/source/launcher/libfat_ext/directory.h
Normal file
@ -0,0 +1,182 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
directory.h
|
||||
Reading, writing and manipulation of the directory structure on
|
||||
a FAT partition
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
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 _DIRECTORY_H
|
||||
#define _DIRECTORY_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
||||
#include "partition.h"
|
||||
|
||||
#define DIR_ENTRY_DATA_SIZE 0x20
|
||||
#define MAX_LFN_LENGTH 256
|
||||
#define MAX_ALIAS_LENGTH 13
|
||||
#define LFN_ENTRY_LENGTH 13
|
||||
#define ALIAS_ENTRY_LENGTH 11
|
||||
#define MAX_ALIAS_EXT_LENGTH 3
|
||||
#define MAX_ALIAS_PRI_LENGTH 8
|
||||
#define MAX_NUMERIC_TAIL 999999
|
||||
#define FAT16_ROOT_DIR_CLUSTER 0
|
||||
|
||||
#define DIR_SEPARATOR '/'
|
||||
|
||||
// File attributes
|
||||
#define ATTRIB_ARCH 0x20 // Archive
|
||||
#define ATTRIB_DIR 0x10 // Directory
|
||||
#define ATTRIB_LFN 0x0F // Long file name
|
||||
#define ATTRIB_VOL 0x08 // Volume
|
||||
#define ATTRIB_SYS 0x04 // System
|
||||
#define ATTRIB_HID 0x02 // Hidden
|
||||
#define ATTRIB_RO 0x01 // Read only
|
||||
|
||||
#define CASE_LOWER_EXT 0x10 // WinNT lowercase extension
|
||||
#define CASE_LOWER_BASE 0x08 // WinNT lowercase basename
|
||||
|
||||
typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cluster;
|
||||
sec_t sector;
|
||||
int32_t offset;
|
||||
} DIR_ENTRY_POSITION;
|
||||
|
||||
typedef struct {
|
||||
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
|
||||
DIR_ENTRY_POSITION dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN
|
||||
DIR_ENTRY_POSITION dataEnd; // Always points to the file/directory's alias entry
|
||||
char filename[NAME_MAX];
|
||||
} DIR_ENTRY;
|
||||
|
||||
// Directory entry offsets
|
||||
enum DIR_ENTRY_offset {
|
||||
DIR_ENTRY_name = 0x00,
|
||||
DIR_ENTRY_extension = 0x08,
|
||||
DIR_ENTRY_attributes = 0x0B,
|
||||
DIR_ENTRY_caseInfo = 0x0C,
|
||||
DIR_ENTRY_cTime_ms = 0x0D,
|
||||
DIR_ENTRY_cTime = 0x0E,
|
||||
DIR_ENTRY_cDate = 0x10,
|
||||
DIR_ENTRY_aDate = 0x12,
|
||||
DIR_ENTRY_clusterHigh = 0x14,
|
||||
DIR_ENTRY_mTime = 0x16,
|
||||
DIR_ENTRY_mDate = 0x18,
|
||||
DIR_ENTRY_cluster = 0x1A,
|
||||
DIR_ENTRY_fileSize = 0x1C
|
||||
};
|
||||
|
||||
/*
|
||||
Returns true if the file specified by entry is a directory
|
||||
*/
|
||||
static inline bool _FAT_directory_isDirectory (DIR_ENTRY* entry) {
|
||||
return ((entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR) != 0);
|
||||
}
|
||||
|
||||
static inline bool _FAT_directory_isWritable (DIR_ENTRY* entry) {
|
||||
return ((entry->entryData[DIR_ENTRY_attributes] & ATTRIB_RO) == 0);
|
||||
}
|
||||
|
||||
static inline bool _FAT_directory_isDot (DIR_ENTRY* entry) {
|
||||
return ((entry->filename[0] == '.') && ((entry->filename[1] == '\0') ||
|
||||
((entry->filename[1] == '.') && entry->filename[2] == '\0')));
|
||||
}
|
||||
|
||||
/*
|
||||
Reads the first directory entry from the directory starting at dirCluster
|
||||
Places result in entry
|
||||
entry will be destroyed even if no directory entry is found
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_getFirstEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster);
|
||||
|
||||
/*
|
||||
Reads the next directory entry after the one already pointed to by entry
|
||||
Places result in entry
|
||||
entry will be destroyed even if no directory entry is found
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_getNextEntry (PARTITION* partition, DIR_ENTRY* entry);
|
||||
|
||||
/*
|
||||
Gets the directory entry corrsponding to the supplied path
|
||||
entry will be destroyed even if no directory entry is found
|
||||
pathEnd specifies the end of the path string, for cutting strings short if needed
|
||||
specify NULL to use the full length of path
|
||||
pathEnd is only a suggestion, and the path string will be searched up until the next PATH_SEPARATOR
|
||||
after pathEND.
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_entryFromPath (PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd);
|
||||
|
||||
/*
|
||||
Changes the current directory to the one specified by path
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_chdir (PARTITION* partition, const char* path);
|
||||
|
||||
/*
|
||||
Removes the directory entry specified by entry
|
||||
Assumes that entry is valid
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_removeEntry (PARTITION* partition, DIR_ENTRY* entry);
|
||||
|
||||
/*
|
||||
Add a directory entry to the directory specified by dirCluster
|
||||
The fileData, dataStart and dataEnd elements of the DIR_ENTRY struct are
|
||||
updated with the new directory entry position and alias.
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_addEntry (PARTITION* partition, DIR_ENTRY* entry, uint32_t dirCluster);
|
||||
|
||||
/*
|
||||
Get the start cluster of a file from it's entry data
|
||||
*/
|
||||
uint32_t _FAT_directory_entryGetCluster (PARTITION* partition, const uint8_t* entryData);
|
||||
|
||||
/*
|
||||
Fill in the file name and entry data of DIR_ENTRY* entry.
|
||||
Assumes that the entry's dataStart and dataEnd are correct
|
||||
Returns true on success, false on failure
|
||||
*/
|
||||
bool _FAT_directory_entryFromPosition (PARTITION* partition, DIR_ENTRY* entry);
|
||||
|
||||
/*
|
||||
Fill in a stat struct based on a file entry
|
||||
*/
|
||||
void _FAT_directory_entryStat (PARTITION* partition, DIR_ENTRY* entry, struct stat *st);
|
||||
|
||||
/*
|
||||
Get volume label
|
||||
*/
|
||||
bool _FAT_directory_getVolumeLabel (PARTITION* partition, char *label);
|
||||
|
||||
#endif // _DIRECTORY_H
|
28
arm9/source/launcher/libfat_ext/fat_ext.h
Normal file
28
arm9/source/launcher/libfat_ext/fat_ext.h
Normal file
@ -0,0 +1,28 @@
|
||||
// clang-format off
|
||||
|
||||
#ifndef _LIBFAT_EXT_H
|
||||
#define _LIBFAT_EXT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nds/disc_io.h>
|
||||
|
||||
/*
|
||||
Get Alias Name
|
||||
*/
|
||||
extern void fatGetAliasName (const char* drive, const char* name, char *alias);
|
||||
|
||||
/*
|
||||
Get Alias Path
|
||||
*/
|
||||
extern void fatGetAliasPath (const char* drive, const char* path, char *alias);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _LIBFAT_EXT_H
|
48
arm9/source/launcher/libfat_ext/fatcommon.h
Normal file
48
arm9/source/launcher/libfat_ext/fatcommon.h
Normal file
@ -0,0 +1,48 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
common.h
|
||||
Common definitions and included files for the FATlib
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
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 _FAT_COMMON_H
|
||||
#define _FAT_COMMON_H
|
||||
|
||||
#include <fat.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Platform specific includes
|
||||
#include <nds/ndstypes.h>
|
||||
#include <nds/system.h>
|
||||
#include <nds/disc_io.h>
|
||||
|
||||
// Platform specific options
|
||||
#define DEFAULT_CACHE_PAGES 16
|
||||
#define DEFAULT_SECTORS_PAGE 8
|
||||
#define USE_RTC_TIME
|
||||
|
||||
#endif // _FAT_COMMON_H
|
141
arm9/source/launcher/libfat_ext/libfat_ext.c
Normal file
141
arm9/source/launcher/libfat_ext/libfat_ext.c
Normal file
@ -0,0 +1,141 @@
|
||||
// clang-format off
|
||||
|
||||
#include <sys/iosupport.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <malloc.h>
|
||||
|
||||
static inline void* _FAT_mem_allocate (size_t size) {
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
static inline void* _FAT_mem_align (size_t size) {
|
||||
return malloc (size);
|
||||
}
|
||||
|
||||
static inline void _FAT_mem_free (void* mem) {
|
||||
free (mem);
|
||||
}
|
||||
|
||||
#include "directory.h"
|
||||
#include "partition.h"
|
||||
#include "tonccpy.h"
|
||||
|
||||
//static int timesRan = 0;
|
||||
|
||||
static int fatGetAlias (const char* drive, const char* name, const char* nameEnd, char *alias) {
|
||||
devoptab_t *devops;
|
||||
PARTITION* partition;
|
||||
DIR_ENTRY entry;
|
||||
char *buf;
|
||||
int drivelen/*,namelen*/,i;
|
||||
|
||||
if (!drive || !name)
|
||||
return -1;
|
||||
|
||||
drivelen = strlen(drive);
|
||||
//namelen = strlen(name);
|
||||
buf=(char*)_FAT_mem_allocate(sizeof(char)*drivelen+2);
|
||||
strcpy(buf,drive);
|
||||
|
||||
if (drive[drivelen-1] == '/') {
|
||||
buf[drivelen-1]='\0';
|
||||
drivelen--;
|
||||
}
|
||||
|
||||
if (drive[drivelen-1] != ':') {
|
||||
buf[drivelen]=':';
|
||||
buf[drivelen+1]='\0';
|
||||
}
|
||||
|
||||
/*if (name[namelen-1] == '/') {
|
||||
name[namelen-1]='\0';
|
||||
namelen--;
|
||||
}*/
|
||||
|
||||
devops = (devoptab_t*)GetDeviceOpTab(buf);
|
||||
|
||||
for (i=0;buf[i]!='\0' && buf[i]!=':';i++);
|
||||
if (!devops || strncasecmp(buf,devops->name,i)) {
|
||||
_FAT_mem_free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_FAT_mem_free(buf);
|
||||
|
||||
partition = (PARTITION*)devops->deviceData;
|
||||
|
||||
int resultLen = 0;
|
||||
|
||||
if (_FAT_directory_entryFromPath(partition, &entry, name, nameEnd)) {
|
||||
tonccpy(alias,&entry.entryData,8);
|
||||
int i = 0;
|
||||
if (strncmp((char*)entry.entryData+8, " ", 3) != 0) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (entry.entryData[i] == ' ') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
alias[i] = '.';
|
||||
alias[i+1] = entry.entryData[8];
|
||||
alias[i+2] = entry.entryData[9];
|
||||
alias[i+3] = entry.entryData[10];
|
||||
alias[i+4] = '\0';
|
||||
resultLen = i+4;
|
||||
} else {
|
||||
for (i = 0; i <= 8; i++) {
|
||||
if (entry.entryData[i] == ' ') {
|
||||
alias[i] = _FAT_directory_isDirectory(&entry) ? '\x2F' : '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
resultLen = i+1;
|
||||
}
|
||||
/*tonccpy((char*)0x02800000+(timesRan*0x20), entry.entryData, 0x20);
|
||||
tonccpy((char*)0x02800100+(timesRan*0x10), alias, 12);
|
||||
timesRan++;*/
|
||||
}
|
||||
|
||||
return resultLen;
|
||||
}
|
||||
|
||||
void fatGetAliasName (const char* drive, const char* name, char *alias) {
|
||||
fatGetAlias (drive, name, NULL, alias);
|
||||
}
|
||||
|
||||
void fatGetAliasPath (const char* drive, const char* path, char *alias) {
|
||||
char dirBak[PATH_MAX];
|
||||
getcwd(dirBak, PATH_MAX);
|
||||
chdir(drive);
|
||||
|
||||
char name[128];
|
||||
int len = (int)strlen(drive);
|
||||
int lfnLen = len;
|
||||
if (path[0] == '\x2F') {
|
||||
len = 1;
|
||||
lfnLen = len;
|
||||
}
|
||||
int nameEnd = 0;
|
||||
tonccpy(alias, drive, len);
|
||||
|
||||
for (int i = len; i < 256; i++) {
|
||||
for (nameEnd = 0; nameEnd < 128; nameEnd++) {
|
||||
name[nameEnd] = path[i+nameEnd];
|
||||
if (path[i+nameEnd] == '\0' || path[i+nameEnd] == '\x2F' /*|| path[i+nameEnd] == '\x5C'*/) {
|
||||
name[nameEnd] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
//tonccpy((char*)0x02800040+(timesRan*0x10), name, nameEnd);
|
||||
len += fatGetAlias (drive, path+lfnLen, path+lfnLen+nameEnd, alias+len);
|
||||
lfnLen += nameEnd+1;
|
||||
i += nameEnd;
|
||||
//timesRan++;
|
||||
if (path[i] == '\0') break;
|
||||
chdir(name);
|
||||
}
|
||||
|
||||
chdir(dirBak);
|
||||
}
|
74
arm9/source/launcher/libfat_ext/lock.h
Normal file
74
arm9/source/launcher/libfat_ext/lock.h
Normal file
@ -0,0 +1,74 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
lock.h
|
||||
|
||||
Copyright (c) 2008 Sven Peter <svpe@gmx.net>
|
||||
|
||||
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 _LOCK_H
|
||||
#define _LOCK_H
|
||||
|
||||
#include "fatcommon.h"
|
||||
|
||||
#ifdef USE_LWP_LOCK
|
||||
|
||||
static inline void _FAT_lock_init(mutex_t *mutex)
|
||||
{
|
||||
LWP_MutexInit(mutex, false);
|
||||
}
|
||||
|
||||
static inline void _FAT_lock_deinit(mutex_t *mutex)
|
||||
{
|
||||
LWP_MutexDestroy(*mutex);
|
||||
}
|
||||
|
||||
static inline void _FAT_lock(mutex_t *mutex)
|
||||
{
|
||||
LWP_MutexLock(*mutex);
|
||||
}
|
||||
|
||||
static inline void _FAT_unlock(mutex_t *mutex)
|
||||
{
|
||||
LWP_MutexUnlock(*mutex);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// We still need a blank lock type
|
||||
#ifndef mutex_t
|
||||
typedef int mutex_t;
|
||||
#endif
|
||||
|
||||
void _FAT_lock_init(mutex_t *mutex);
|
||||
void _FAT_lock_deinit(mutex_t *mutex);
|
||||
void _FAT_lock(mutex_t *mutex);
|
||||
void _FAT_unlock(mutex_t *mutex);
|
||||
|
||||
#endif // USE_LWP_LOCK
|
||||
|
||||
|
||||
#endif // _LOCK_H
|
||||
|
108
arm9/source/launcher/libfat_ext/partition.h
Normal file
108
arm9/source/launcher/libfat_ext/partition.h
Normal file
@ -0,0 +1,108 @@
|
||||
// clang-format off
|
||||
|
||||
/*
|
||||
partition.h
|
||||
Functions for mounting and dismounting partitions
|
||||
on various block devices.
|
||||
|
||||
Copyright (c) 2006 Michael "Chishm" Chisholm
|
||||
|
||||
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 _PARTITION_H
|
||||
#define _PARTITION_H
|
||||
|
||||
#include "cache.h"
|
||||
#include "lock.h"
|
||||
|
||||
#define MIN_SECTOR_SIZE 512
|
||||
#define MAX_SECTOR_SIZE 4096
|
||||
|
||||
// Filesystem type
|
||||
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
|
||||
|
||||
typedef struct {
|
||||
sec_t fatStart;
|
||||
uint32_t sectorsPerFat;
|
||||
uint32_t lastCluster;
|
||||
uint32_t firstFree;
|
||||
uint32_t numberFreeCluster;
|
||||
uint32_t numberLastAllocCluster;
|
||||
} FAT;
|
||||
|
||||
typedef struct {
|
||||
const DISC_INTERFACE* disc;
|
||||
CACHE* cache;
|
||||
// Info about the partition
|
||||
FS_TYPE filesysType;
|
||||
uint64_t totalSize;
|
||||
sec_t rootDirStart;
|
||||
uint32_t rootDirCluster;
|
||||
uint32_t numberOfSectors;
|
||||
sec_t dataStart;
|
||||
uint32_t bytesPerSector;
|
||||
uint32_t sectorsPerCluster;
|
||||
uint32_t bytesPerCluster;
|
||||
uint32_t fsInfoSector;
|
||||
FAT fat;
|
||||
// Values that may change after construction
|
||||
uint32_t cwdCluster; // Current working directory cluster
|
||||
int openFileCount;
|
||||
struct _FILE_STRUCT* firstOpenFile; // The start of a linked list of files
|
||||
mutex_t lock; // A lock for partition operations
|
||||
bool readOnly; // If this is set, then do not try writing to the disc
|
||||
char label[12]; // Volume label
|
||||
} PARTITION;
|
||||
|
||||
/*
|
||||
Mount the supplied device and return a pointer to the struct necessary to use it
|
||||
*/
|
||||
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t SectorsPerPage, sec_t startSector);
|
||||
|
||||
/*
|
||||
Dismount the device and free all structures used.
|
||||
Will also attempt to synchronise all open files to disc.
|
||||
*/
|
||||
void _FAT_partition_destructor (PARTITION* partition);
|
||||
|
||||
/*
|
||||
Return the partition specified in a path, as taken from the devoptab.
|
||||
*/
|
||||
PARTITION* _FAT_partition_getPartitionFromPath (const char* path);
|
||||
|
||||
/*
|
||||
Create the fs info sector.
|
||||
*/
|
||||
void _FAT_partition_createFSinfo(PARTITION * partition);
|
||||
|
||||
/*
|
||||
Read the fs info sector data.
|
||||
*/
|
||||
void _FAT_partition_readFSinfo(PARTITION * partition);
|
||||
|
||||
/*
|
||||
Write the fs info sector data.
|
||||
*/
|
||||
void _FAT_partition_writeFSinfo(PARTITION * partition);
|
||||
|
||||
#endif // _PARTITION_H
|
134
arm9/source/launcher/libfat_ext/tonccpy.c
Normal file
134
arm9/source/launcher/libfat_ext/tonccpy.c
Normal file
@ -0,0 +1,134 @@
|
||||
// clang-format off
|
||||
|
||||
#include "tonccpy.h"
|
||||
#include <stddef.h>
|
||||
|
||||
//# tonccpy.c
|
||||
|
||||
//! VRAM-safe cpy.
|
||||
/*! This version mimics memcpy in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memcpy, but faster
|
||||
implementations can be made.
|
||||
\param dst Destination pointer.
|
||||
\param src Source pointer.
|
||||
\param size Fill-length in bytes.
|
||||
\note The pointers and size need not be word-aligned.
|
||||
*/
|
||||
void tonccpy(void *dst, const void *src, uint size)
|
||||
{
|
||||
if (size == 0 || dst == NULL || src == NULL)
|
||||
return;
|
||||
|
||||
uint count;
|
||||
u16 *dst16; // hword destination
|
||||
u8 *src8; // byte source
|
||||
|
||||
// Ideal case: copy by 4x words. Leaves tail for later.
|
||||
if (((u32)src|(u32)dst) %4 == 0 && size >= 4) {
|
||||
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
||||
|
||||
count = size/4;
|
||||
uint tmp = count&3;
|
||||
count /= 4;
|
||||
|
||||
// Duff's Device, good friend!
|
||||
switch(tmp) {
|
||||
do { *dst32++ = *src32++;
|
||||
case 3: *dst32++ = *src32++;
|
||||
case 2: *dst32++ = *src32++;
|
||||
case 1: *dst32++ = *src32++;
|
||||
case 0: ; } while (count--);
|
||||
}
|
||||
|
||||
// Check for tail
|
||||
size &= 3;
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
src8 = (u8*)src32;
|
||||
dst16 = (u16*)dst32;
|
||||
} else {
|
||||
// Unaligned
|
||||
|
||||
uint dstOfs = (u32)dst&1;
|
||||
src8 = (u8*)src;
|
||||
dst16 = (u16*)(dst-dstOfs);
|
||||
|
||||
// Head: 1 byte.
|
||||
if (dstOfs != 0) {
|
||||
*dst16 = (*dst16 & 0xFF) | *src8++<<8;
|
||||
dst16++;
|
||||
if (--size == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unaligned main: copy by 2x byte.
|
||||
count = size/2;
|
||||
while (count--) {
|
||||
*dst16++ = src8[0] | src8[1]<<8;
|
||||
src8 += 2;
|
||||
}
|
||||
|
||||
// Tail: 1 byte.
|
||||
if (size & 1)
|
||||
*dst16 = (*dst16 &~ 0xFF) | *src8;
|
||||
}
|
||||
//# toncset.c
|
||||
|
||||
//! VRAM-safe memset, internal routine.
|
||||
/*! This version mimics memset in functionality, with
|
||||
the benefit of working for VRAM as well. It is also
|
||||
slightly faster than the original memset.
|
||||
\param dst Destination pointer.
|
||||
\param fill Word to fill with.
|
||||
\param size Fill-length in bytes.
|
||||
\note The \a dst pointer and \a size need not be
|
||||
word-aligned. In the case of unaligned fills, \a fill
|
||||
will be masked off to match the situation.
|
||||
*/
|
||||
void __toncset(void *dst, u32 fill, uint size)
|
||||
{
|
||||
if (size == 0 || dst == NULL)
|
||||
return;
|
||||
|
||||
uint left = (u32)dst&3;
|
||||
u32 *dst32 = (u32*)(dst-left);
|
||||
u32 count, mask;
|
||||
|
||||
// Unaligned head.
|
||||
if (left != 0) {
|
||||
// Adjust for very small stint.
|
||||
if (left + size < 4) {
|
||||
mask = BIT_MASK(size*8)<<(left*8);
|
||||
*dst32 = (*dst32 &~ mask) | (fill & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
mask = BIT_MASK(left*8);
|
||||
*dst32 = (*dst32 & mask) | (fill&~mask);
|
||||
dst32++;
|
||||
size -= 4 - left;
|
||||
}
|
||||
|
||||
// Main stint.
|
||||
count = size/4;
|
||||
uint tmp = count&3;
|
||||
count /= 4;
|
||||
|
||||
switch(tmp) {
|
||||
do { *dst32++ = fill;
|
||||
case 3: *dst32++ = fill;
|
||||
case 2: *dst32++ = fill;
|
||||
case 1: *dst32++ = fill;
|
||||
case 0: ; } while (count--);
|
||||
}
|
||||
|
||||
// Tail
|
||||
size &= 3;
|
||||
if (size) {
|
||||
mask= BIT_MASK(size*8);
|
||||
*dst32= (*dst32 &~ mask) | (fill & mask);
|
||||
}
|
||||
}
|
45
arm9/source/launcher/libfat_ext/tonccpy.h
Normal file
45
arm9/source/launcher/libfat_ext/tonccpy.h
Normal file
@ -0,0 +1,45 @@
|
||||
// clang-format off
|
||||
|
||||
//# Stuff you may not have yet.
|
||||
|
||||
#ifndef TONCCPY_H
|
||||
#define TONCCPY_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
#define BIT_MASK(len) ( (1<<(len))-1 )
|
||||
static inline u32 quad8(u16 x) { x |= x<<8; return x | x<<16; }
|
||||
|
||||
|
||||
//# Declarations and inlines.
|
||||
|
||||
void tonccpy(void *dst, const void *src, uint size);
|
||||
|
||||
void __toncset(void *dst, u32 fill, uint size);
|
||||
static inline void toncset(void *dst, u8 src, uint size);
|
||||
static inline void toncset16(void *dst, u16 src, uint size);
|
||||
static inline void toncset32(void *dst, u32 src, uint size);
|
||||
|
||||
|
||||
//! VRAM-safe memset, byte version. Size in bytes.
|
||||
static inline void toncset(void *dst, u8 src, uint size)
|
||||
{ __toncset(dst, quad8(src), size); }
|
||||
|
||||
//! VRAM-safe memset, halfword version. Size in hwords.
|
||||
static inline void toncset16(void *dst, u16 src, uint size)
|
||||
{ __toncset(dst, src|src<<16, size*2); }
|
||||
|
||||
//! VRAM-safe memset, word version. Size in words.
|
||||
static inline void toncset32(void *dst, u32 src, uint size)
|
||||
{ __toncset(dst, src, size*4); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -17,7 +17,7 @@ SOURCE_PATH := ../arm9
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
BUILD := build
|
||||
SOURCES := $(SOURCE_PATH)/source $(SOURCE_PATH)/source/ui $(SOURCE_PATH)/source/font $(SOURCE_PATH)/source/launcher $(SOURCE_PATH)/source/saves
|
||||
SOURCES := $(SOURCE_PATH)/source $(SOURCE_PATH)/source/ui $(SOURCE_PATH)/source/font $(SOURCE_PATH)/source/launcher $(SOURCE_PATH)/source/launcher/libfat_ext $(SOURCE_PATH)/source/saves
|
||||
INCLUDES := $(SOURCE_PATH)/include ../share $(SOURCES)
|
||||
DATA := $(SOURCE_PATH)/data ../data
|
||||
GRAPHICS :=
|
||||
|
Loading…
Reference in New Issue
Block a user