diff --git a/source/common.h b/source/common.h index 00abf0f..5d9f08d 100644 --- a/source/common.h +++ b/source/common.h @@ -38,7 +38,7 @@ (((v) % (a)) ? ((v) + (a) - ((v) % (a))) : (v)) // GodMode9 version -#define VERSION "0.8.1" +#define VERSION "0.8.2" // buffer area defines (in use by godmode.c) #define DIR_BUFFER (0x21000000) diff --git a/source/fs.c b/source/fs.c index eac751c..f91159f 100644 --- a/source/fs.c +++ b/source/fs.c @@ -10,7 +10,7 @@ #define NORM_FS 10 #define IMGN_FS 3 // image normal filesystems -#define VIRT_FS 8 +#define VIRT_FS 9 #define SKIP_CUR (1<<3) #define OVERWRITE_CUR (1<<4) @@ -190,6 +190,8 @@ int DriveType(const char* path) { type = DRV_VIRTUAL | DRV_EMUNAND; } else if (vsrc == VRT_IMGNAND) { type = DRV_VIRTUAL | DRV_IMAGE; + } else if (vsrc == VRT_XORPAD) { + type = DRV_VIRTUAL | DRV_XORPAD; } else if (vsrc == VRT_MEMORY) { type = DRV_VIRTUAL | DRV_MEMORY; } else if (vsrc == VRT_GAME) { @@ -286,6 +288,9 @@ bool CheckWritePermissions(const char* path) { } else if (drvtype & DRV_GAME) { perm = PERM_GAME; snprintf(area_name, 16, "game images"); + } else if (drvtype & DRV_XORPAD) { + perm = PERM_XORPAD; + snprintf(area_name, 16, "XORpads"); } else if (drvtype & DRV_IMAGE) { perm = PERM_IMAGE; snprintf(area_name, 16, "images"); @@ -346,6 +351,10 @@ bool SetWritePermissions(u32 perm, bool add_perm) { ShowPrompt(false, "Unlock write permission for\ngame images is not allowed."); return false; break; + case PERM_XORPAD: + ShowPrompt(false, "Unlock write permission for\nXORpad drive is not allowed."); + return false; + break; #ifndef SAFEMODE case PERM_SYSNAND: if (!ShowUnlockSequence(3, "!Better be careful!\n \nYou want to enable SysNAND\nwriting permissions.\nThis enables you to do some\nreally dangerous stuff!")) @@ -1147,11 +1156,12 @@ bool GetRootDirContentsWorker(DirStruct* contents) { "GAME IMAGE", "SYSNAND SD", "EMUNAND SD", "SYSNAND VIRTUAL", "EMUNAND VIRTUAL", "IMGNAND VIRTUAL", + "NAND XORPADS", "MEMORY VIRTUAL", "LAST SEARCH" }; static const char* drvnum[] = { - "0:", "1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "G:", "A:", "B:", "S:", "E:", "I:", "M:", "Z:" + "0:", "1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "G:", "A:", "B:", "S:", "E:", "I:", "X:", "M:", "Z:" }; u32 n_entries = 0; diff --git a/source/fs.h b/source/fs.h index 824a4d4..e04df08 100644 --- a/source/fs.h +++ b/source/fs.h @@ -8,10 +8,11 @@ #define DRV_FAT (1<<0) #define DRV_VIRTUAL (1<<1) // secondary drive types -#define DRV_SDCARD (1<<3) -#define DRV_SYSNAND (1<<4) -#define DRV_EMUNAND (1<<5) -#define DRV_IMAGE (1<<6) +#define DRV_SDCARD (1<<2) +#define DRV_SYSNAND (1<<3) +#define DRV_EMUNAND (1<<4) +#define DRV_IMAGE (1<<5) +#define DRV_XORPAD (1<<6) #define DRV_RAMDRIVE (1<<7) #define DRV_MEMORY (1<<8) #define DRV_GAME (1<<9) @@ -27,8 +28,9 @@ #define PERM_IMAGE (1<<4) #define PERM_MEMORY (1<<5) #define PERM_GAME (1<<6) // can't be enabled, placeholder -#define PERM_A9LH ((1<<7) | PERM_SYSNAND) -#define PERM_SDDATA ((1<<8) | PERM_SDCARD) +#define PERM_XORPAD (1<<7) // can't be enabled, placeholder +#define PERM_A9LH ((1<<8) | PERM_SYSNAND) +#define PERM_SDDATA ((1<<9) | PERM_SDCARD) #define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE) #define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY | PERM_SDDATA) diff --git a/source/godmode.c b/source/godmode.c index cd8f329..a1de388 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -84,9 +84,10 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c int drvtype = DriveType(curr_entry->path); char drvstr[32]; snprintf(drvstr, 31, "(%s%s)", - ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMDrive" : (drvtype & DRV_GAME) ? "Game" : + ((drvtype & DRV_SDCARD) ? "SD" : (drvtype & DRV_RAMDRIVE) ? "RAMdrive" : (drvtype & DRV_GAME) ? "Game" : (drvtype & DRV_SYSNAND) ? "SysNAND" : (drvtype & DRV_EMUNAND) ? "EmuNAND" : (drvtype & DRV_IMAGE) ? "Image" : - (drvtype & DRV_MEMORY) ? "Memory" : (drvtype & DRV_ALIAS) ? "Alias" : (drvtype & DRV_SEARCH) ? "Search" : ""), + (drvtype & DRV_XORPAD) ? "XORpad" : (drvtype & DRV_MEMORY) ? "Memory" : (drvtype & DRV_ALIAS) ? "Alias" : + (drvtype & DRV_SEARCH) ? "Search" : ""), ((drvtype & DRV_FAT) ? " FAT" : (drvtype & DRV_VIRTUAL) ? " Virtual" : "")); ResizeString(tempstr, drvstr, 160 / FONT_WIDTH_EXT, 8, false); }else { @@ -851,6 +852,8 @@ u32 GodMode() { ShowPrompt(false, "Not allowed in search drive"); } else if ((curr_drvtype & DRV_GAME) && (pad_state & BUTTON_Y)) { ShowPrompt(false, "Not allowed in virtual game path"); + } else if ((curr_drvtype & DRV_XORPAD) && (pad_state & BUTTON_Y)) { + ShowPrompt(false, "Not allowed in XORpad drive"); } else if (pad_state & BUTTON_Y) { // paste files const char* optionstr[2] = { "Copy path(s)", "Move path(s)" }; char promptstr[64]; diff --git a/source/nand/nand.c b/source/nand/nand.c index 8e4b79e..3575d90 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -362,6 +362,8 @@ int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, u32 nand_src } else if (nand_src == NAND_SYSNAND) { // SysNAND int errorcode = sdmmc_nand_readsectors(sector, count, buffer); if (errorcode) return errorcode; + } else if (nand_src == NAND_ZERONAND) { // zero NAND (good for XORpads) + memset(buffer, 0, count * 0x200); } else { return -1; } @@ -425,10 +427,14 @@ u64 GetNandSizeSectors(u32 nand_src) u32 emunand_min_sectors = (emunand_base_sector % 0x200000 == 0) ? sysnand_sectors : NAND_MIN_SECTORS; if (emunand_max_sectors >= sysnand_sectors) return sysnand_sectors; else return (emunand_min_sectors > emunand_max_sectors) ? 0 : emunand_min_sectors; - } else if (nand_src == NAND_IMGNAND) { + } else if (nand_src == NAND_IMGNAND) { // for images u32 img_sectors = (GetMountState() == IMG_NAND) ? GetMountSize() / 0x200 : 0; return (img_sectors >= sysnand_sectors) ? sysnand_sectors : (img_sectors >= NAND_MIN_SECTORS) ? NAND_MIN_SECTORS : 0; - } else return sysnand_sectors; // for SysNAND + } else if (nand_src == NAND_SYSNAND) { // for SysNAND + return sysnand_sectors; + } + + return 0; } bool InitEmuNandBase(void) diff --git a/source/virtual/virtual.c b/source/virtual/virtual.c index 586ed09..3ea2946 100644 --- a/source/virtual/virtual.c +++ b/source/virtual/virtual.c @@ -9,7 +9,7 @@ typedef struct { } __attribute__((packed)) VirtualDrive; static const VirtualDrive virtualDrives[] = - { {'S', VRT_SYSNAND}, {'E', VRT_EMUNAND}, {'I', VRT_IMGNAND}, {'M', VRT_MEMORY}, {'G', VRT_GAME} }; + { {'S', VRT_SYSNAND}, {'E', VRT_EMUNAND}, {'I', VRT_IMGNAND}, {'X', VRT_XORPAD }, {'M', VRT_MEMORY}, {'G', VRT_GAME} }; u32 GetVirtualSource(const char* path) { // check path validity @@ -33,7 +33,7 @@ bool CheckVirtualDrive(const char* path) { bool ReadVirtualDir(VirtualFile* vfile, VirtualDir* vdir) { u32 virtual_src = vdir->virtual_src; bool ret = false; - if (virtual_src & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND)) { + if (virtual_src & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD)) { ret = ReadVNandDir(vfile, vdir); } else if (virtual_src & VRT_MEMORY) { ret = ReadVMemDir(vfile, vdir); @@ -150,7 +150,7 @@ int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count, count = vfile->size - offset; if (bytes_read) *bytes_read = count; - if (vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND)) { + if (vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD)) { return ReadVNandFile(vfile, buffer, offset, count); } else if (vfile->flags & VRT_MEMORY) { return ReadVMemFile(vfile, buffer, offset, count); diff --git a/source/virtual/virtual.h b/source/virtual/virtual.h index 31ce8dd..0f4c8b9 100644 --- a/source/virtual/virtual.h +++ b/source/virtual/virtual.h @@ -7,10 +7,11 @@ #define VRT_SYSNAND NAND_SYSNAND #define VRT_EMUNAND NAND_EMUNAND #define VRT_IMGNAND NAND_IMGNAND +#define VRT_XORPAD NAND_ZERONAND #define VRT_MEMORY (1<<10) #define VRT_GAME (1<<11) -#define VRT_SOURCE (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_MEMORY|VRT_GAME) +#define VRT_SOURCE (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD|VRT_MEMORY|VRT_GAME) #define VFLAG_DIR (1<<16) #define VFLAG_ROOT (1<<17) diff --git a/source/virtual/vnand.c b/source/virtual/vnand.c index 7fc9b0c..5dcfb09 100644 --- a/source/virtual/vnand.c +++ b/source/virtual/vnand.c @@ -47,6 +47,12 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir // copy current template to vfile memcpy(vfile, templates + vdir->index, sizeof(VirtualFile)); + // XORpad drive handling + if (nand_src == VRT_XORPAD) { + snprintf(vfile->name, 32, "%s.xorpad", templates[vdir->index].name); + if ((vfile->keyslot == 0x11) || (vfile->keyslot >= 0x40)) continue; + } + // process / check special flags if (!(vfile->flags & nand_type)) continue; // virtual file has wrong NAND type @@ -57,7 +63,7 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir if (!(nand_src & VRT_SYSNAND) || !CheckA9lh()) vfile->flags &= ~VFLAG_A9LH_AREA; // flag is meaningless outside of A9LH / SysNAND if (vfile->flags & VFLAG_NAND_SIZE) { - if ((nand_src != NAND_SYSNAND) && (GetNandSizeSectors(NAND_SYSNAND) != GetNandSizeSectors(nand_src))) + if ((nand_src != VRT_SYSNAND) && (GetNandSizeSectors(NAND_SYSNAND) != GetNandSizeSectors(nand_src))) continue; // EmuNAND/ImgNAND is too small vfile->size = GetNandSizeSectors(NAND_SYSNAND) * 0x200; } @@ -71,11 +77,11 @@ bool ReadVNandDir(VirtualFile* vfile, VirtualDir* vdir) { // uses a generic vdir } int ReadVNandFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count) { - u32 nand_src = vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND); + u32 nand_src = vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD); return ReadNandBytes(buffer, vfile->offset + offset, count, vfile->keyslot, nand_src); } int WriteVNandFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count) { - u32 nand_dst = vfile->flags & (VRT_SYSNAND | VRT_EMUNAND | VRT_IMGNAND); + u32 nand_dst = vfile->flags & (VRT_SYSNAND|VRT_EMUNAND|VRT_IMGNAND|VRT_XORPAD); return WriteNandBytes(buffer, vfile->offset + offset, count, vfile->keyslot, nand_dst); }