Added returning to the last dir a ROM was launched from on next boot. Fixes #21.

This commit is contained in:
profi200 2020-10-25 22:00:44 +01:00
parent ffb32cca9c
commit c87769a06e
No known key found for this signature in database
GPG Key ID: 17B42AE5911139F3
8 changed files with 127 additions and 31 deletions

View File

@ -25,3 +25,4 @@
Result fsQuickRead(const char *const path, void *const buf, u32 size);
Result fsQuickWrite(const char *const path, const void *const buf, u32 size);
Result fsMakePath(const char *const path);

View File

@ -26,7 +26,26 @@
NAKED void wait(u32 cycles);
/**
* @brief Waits at least the specified amount of CPU cycles.
*
* @param[in] cycles The cycles to wait.
*/
NAKED void wait_cycles(u32 cycles);
/**
* @brief Safer strcpy with checks.
* The dst string always gets terminated except when num is 0.
* If the src string is too long nothing is copied and dst will be terminated.
* This function is not safe against race conditions!
*
* @param dst The destination pointer.
* @param[in] src The source pointer.
* @param[in] num Maximum number of chars to copy including null terminator.
*
* @return The length of the copied string in bytes including null terminator.
*/
size_t safeStrcpy(char *const dst, const char *const src, size_t num);
// case insensitive string compare function
int strnicmp(const char *str1, const char *str2, u32 len);

View File

@ -3,6 +3,7 @@
#include "types.h"
#include "error_codes.h"
#include "fs.h"
#include "util.h"
#include "arm11/hardware/hid.h"
#include "arm11/fmt.h"
#include "hardware/gfx.h"
@ -17,7 +18,7 @@
typedef struct
{
u8 type; // 0 = file, 1 = dir
char str[255];
char str[256];
} DirListEnt;
typedef struct
@ -29,22 +30,6 @@ typedef struct
// num including null terminator.
static size_t safeStrcpy(char *const dst, const char *const src, size_t num)
{
if(num == 0) return 0;
const size_t len = strlen(src) + 1;
if(len > num)
{
*dst = '\0';
return 1;
}
strcpy(dst, src);
return len;
}
int dlistCompare(const void *a, const void *b)
{
const DirListEnt *const entA = *(DirListEnt**)a;
@ -90,7 +75,7 @@ static Result scanDir(const char *const path, DirList *const dList, const char *
}
dList->entries[dListPos].type = isDir;
safeStrcpy(dList->entries[dListPos].str, fi[i].fname, 255);
safeStrcpy(dList->entries[dListPos].str, fi[i].fname, 256);
dList->ptrs[dListPos] = &dList->entries[dListPos];
dListPos++;
}
@ -196,7 +181,7 @@ Result browseFiles(const char *const basePath, char selected[512])
{
// TODO: !!! Insecure !!!
if(curDir[pathLen - 1] != '/') curDir[pathLen++] = '/';
safeStrcpy(curDir + pathLen, dList->ptrs[cursorPos]->str, 255);
safeStrcpy(curDir + pathLen, dList->ptrs[cursorPos]->str, 256);
if(dList->ptrs[cursorPos]->type == 0)
{

View File

@ -74,7 +74,7 @@ void GFX_init(GfxFbFmt fmtTop, GfxFbFmt fmtBot)
// Reset
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E;
wait(12);
wait_cycles(12);
REG_PDN_GPU_CNT = PDN_GPU_CNT_CLK_E | PDN_GPU_CNT_RST_ALL;
REG_GX_GPU_CLK = 0x100;
REG_GX_PSC_VRAM = 0;
@ -452,7 +452,7 @@ void GX_textureCopy(const u32 *const in, u32 indim, u32 *out, u32 outdim, u32 si
void GX_processCommandList(u32 size, const u32 *const cmdList)
{
REG_GX_P3D(GPUREG_IRQ_ACK) = 0; // Acknowledge last P3D.
while(REG_GX_PSC_STAT & 1u<<31) wait(0x30);
while(REG_GX_PSC_STAT & 1u<<31) wait_cycles(0x30);
REG_GX_P3D(GPUREG_CMDBUF_SIZE0) = size>>3;
REG_GX_P3D(GPUREG_CMDBUF_ADDR0) = (u32)cmdList>>3;

View File

@ -33,6 +33,7 @@
#include "arm11/power.h"
#include "hardware/gfx.h"
#include "fs.h"
#include "fsutil.h"
#include "arm11/filebrowser.h"
#include "arm.h"
#include "arm11/hardware/lcd.h"
@ -41,6 +42,9 @@
#include "kevent.h"
#define OAF_WORK_DIR "sdmc:/3ds/open_agb_firm"
static u32 padRomArea(u32 romFileSize)
{
@ -265,7 +269,7 @@ saveTypeFound:
return saveType;
}
u16 saveDbDebug(const char *const savePath, u32 romSize)
static u16 saveDbDebug(const char *const savePath, u32 romSize)
{
FILINFO fi;
const bool saveExists = fStat(savePath, &fi) == RES_OK;
@ -470,7 +474,7 @@ static void gbaGfxHandler(void *args)
}
#ifndef NDEBUG
void debugTests(void)
static void debugTests(void)
{
const u32 kDown = hidKeysDown();
@ -500,6 +504,52 @@ void debugTests(void)
}
#endif
static Result handleFsStuff(char romPath[512])
{
// Mount SD card.
Result res;
if((res = fMount(FS_DRIVE_SDMC)) == RES_OK)
{
char *lastDir = (char*)calloc(512, 1);
if(lastDir != NULL)
{
do
{
// Create working dir.
if((res = fsMakePath(OAF_WORK_DIR)) != RES_OK && res != RES_FR_EXIST) break;
// Get last ROM launch path.
if((res = fsQuickRead(OAF_WORK_DIR "/lastdir.bin", lastDir, 511)) != RES_OK)
{
if(res == RES_FR_NO_FILE) strcpy(lastDir, "sdmc:/");
else break;
}
// Show file browser.
*romPath = '\0';
if((res = browseFiles(lastDir, romPath)) != RES_OK) break;
size_t cmpLen = strrchr(romPath, '/') - romPath;
if((size_t)(strchr(romPath, '/') - romPath) == cmpLen) cmpLen++; // Keep the first '/'.
if(cmpLen < 512)
{
if(cmpLen < strlen(lastDir) || strncmp(lastDir, romPath, cmpLen) != 0)
{
strncpy(lastDir, romPath, cmpLen);
lastDir[cmpLen] = '\0';
res = fsQuickWrite(OAF_WORK_DIR "/lastdir.bin", lastDir, cmpLen + 1);
}
}
} while(0);
free(lastDir);
}
else res = RES_OUT_OF_MEM;
}
return res;
}
int main(void)
{
GFX_init(GFX_BGR8, GFX_RGB565);
@ -507,12 +557,9 @@ int main(void)
consoleInit(SCREEN_BOT, NULL);
//CODEC_init();
// Show file browser.
Result res;
char *romPath = (char*)malloc(512);
*romPath = '\0';
if((res = fMount(FS_DRIVE_SDMC)) != RES_OK || (res = browseFiles("sdmc:/", romPath)) != RES_OK || *romPath == '\0')
goto end;
Result res = handleFsStuff(romPath);
if(res != RES_OK || *romPath == '\0') goto end;
ee_puts("Reading ROM and save...");
u32 romSize;

View File

@ -470,7 +470,7 @@ int SD_Init()
set_target(&handleSD);
// TMIO base clock is half of the CPU clock so 2 CPU cycles = 1 base clock pulse.
// cycles = 2 * [TMIO clock divider] * 74
wait(2 * 128 * 74);
wait_cycles(2 * 128 * 74);
sdmmc_send_command(&handleSD,0,0);
sdmmc_send_command(&handleSD,0x10408,0x1AA);

View File

@ -19,6 +19,7 @@
#include <string.h>
#include "fsutil.h"
#include "fs.h"
#include "util.h"
@ -54,3 +55,30 @@ Result fsQuickWrite(const char *const path, const void *const buf, u32 size)
return res;
}
Result fsMakePath(const char *const path)
{
char tmpPath[512];
safeStrcpy(tmpPath, path, 512);
char *str;
if((str = strchr(tmpPath, ':')) == NULL) str = tmpPath;
else str++;
// Path without any dir.
if(*str == '\0') return RES_INVALID_ARG;
Result res = RES_OK;
while((str = strchr(str + 1, '/')) != NULL)
{
*str = '\0';
if((res = fMkdir(tmpPath)) != RES_OK && res != RES_FR_EXIST) break;
*str = '/';
}
// Only create the last dir in the path if the
// previous error code is not an unexpected one.
if(res == RES_OK || res == RES_FR_EXIST) res = fMkdir(tmpPath);
return res;
}

View File

@ -23,7 +23,7 @@
NAKED void wait(u32 cycles)
NAKED void wait_cycles(u32 cycles)
{
#ifdef ARM9
__asm__("1: subs %0, %0, #4\n\t"
@ -35,6 +35,22 @@ NAKED void wait(u32 cycles)
"bx lr\n\t" : : "r" (cycles) : "cc");
}
size_t safeStrcpy(char *const dst, const char *const src, size_t num)
{
if(num == 0) return 0;
const size_t len = strlen(src) + 1;
if(len > num)
{
*dst = '\0';
return 1;
}
strcpy(dst, src);
return len;
}
// case insensitive string compare function
int strnicmp(const char *str1, const char *str2, u32 len)
{