void string_base::fix_dir_separator(char c) {
#ifdef _WIN32
    end_with(c);
#else
    end_with_slash();
#endif
}
Example #2
0
void CdllsDlg::OnBnClickedSave()
{
	TCHAR app_path_buf[PATH_LEN];
	memset(app_path_buf,0,sizeof(app_path_buf));
	GetModuleFileName(NULL, app_path_buf,sizeof(app_path_buf)/sizeof(app_path_buf[0]));
	int pathlen = _tcslen(app_path_buf);
	int i = pathlen-1;
	while(i>0)
	{
		if(app_path_buf[i]==_T('\\') )
		{
			app_path_buf[i+1] = 0;
			break;
		}
		i--;
	}

	TCHAR szFilters[] =_T("Text Files (*.txt)\0*.txt\0")
		_T("All Files (*.*)\0*.*\0");
	CFileDialog fdlg (FALSE, NULL, NULL,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | 
		OFN_PATHMUSTEXIST |OFN_EXPLORER, szFilters, AfxGetMainWnd());
	//CFileDialog ofdlg(FALSE);
	fdlg.m_ofn.lpstrFilter = szFilters;
	//CFileDialog fdlg(FALSE,_T(".txt"),_T("dlllist.txt"));
	fdlg.m_ofn.lpstrInitialDir =app_path_buf;
	if(IDOK!=fdlg.DoModal())
		return;	
	std::basic_string<TCHAR> savepathname = fdlg.m_ofn.lpstrFile;
	if(1==fdlg.m_ofn.nFilterIndex && !end_with(savepathname,_T(".txt"),true) )
	{
		savepathname += _T(".txt");
	}
	std::basic_fstream<TCHAR> ofile;
	ofile.open( (LPCSTR)_bstr_t(savepathname.c_str()),std::ios_base::out|std::ios_base::trunc);
	HWND hwndListView =GetDlgItem(IDC_LVW)->m_hWnd;
	int rows = 0;
	rows = ListView_GetItemCount(hwndListView);
	int cols = 0;
	HWND headerwnd = ListView_GetHeader(hwndListView);
	cols = Header_GetItemCount(headerwnd);
	for(int i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		{
			app_path_buf[0] = 0;
			ListView_GetItemText(hwndListView,i,j,app_path_buf,ARRAY_SIZE(app_path_buf));
			if(j<cols-1)
				ofile<<app_path_buf<<_T("    ");
			else
			{
				ofile<<app_path_buf<<(char)0xd<<(char)0xa;
			}
		}
	}
	ofile.close();
}
Example #3
0
void get_dir(const char *path) {
    DIR *fd;
    struct dirent *file;
    char new_path[512];
    strncpy(new_path, path, 512);

    if (NULL == (fd = opendir(new_path))) {
        printf("\xb[3;1HDirectory empty...");
        return;
    }

    memset(picker, 0, sizeof(picker_s));
    strncpy(picker->now_path, new_path, 512);

    while ((file = readdir(fd))) {
        if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, ".."))
            continue;
        if (file->d_type != DT_DIR) {
            const char *ext = get_filename_ext(file->d_name);
            if (strcasecmp(ext, "bin") != 0
                && strcasecmp(ext, "dat") != 0
                && strcasecmp(ext, "3dsx") != 0)
                continue;
        }

        // file name
        strncpy(picker->files[picker->file_count].name, file->d_name, 512);

        //  build absolute path
        if (end_with(new_path, '/')) {
            snprintf(picker->files[picker->file_count].path,
                     512, "%s%s", new_path, file->d_name);
        } else {
            snprintf(picker->files[picker->file_count].path,
                     512, "%s/%s", new_path, file->d_name);
        }

        // dir vs file
        if (file->d_type != DT_DIR) {
            picker->files[picker->file_count].isDir = false;
            // file size
            struct stat st;
            stat(picker->files[picker->file_count].path, &st);
            picker->files[picker->file_count].size = (u64) st.st_size;
        } else {
            picker->files[picker->file_count].isDir = true;
        }
        picker->file_count++;
    }

    if (picker->file_count > 1) {
        qsort(picker->files, (size_t) picker->file_count,
              sizeof(*picker->files), alphasort);
    }

    closedir(fd);
}
void string_base::end_with_slash() {
	end_with( io::path::getDefaultSeparator() );
}
Example #5
0
int main (int argc, char **argv)
{
    // Optimize allocation for Tornado (2GB hash allocated after 1GB dictionary)
    AllocTopDown = FALSE;

    // Operation mode
    OPMODE global_mode=AUTO;

    // Record that stores all the info required for ReadWriteCallback
    static Results r;
    r.use_cpu_time = r.quiet_title = r.quiet_header = r.quiet_progress = r.quiet_result = FALSE;

    // Default compression parameters are equivalent to option -5
    r.method = std_Tornado_method [default_Tornado_method];

    // Delete successfully (de)compressed input files
    bool delete_input_files = FALSE;

    // Count of files to process
    int fcount=0;

    // Output path/filename
    const char *output_filename = NULL;

    // Process options until "--"
    // 1. First, process -1..-16 option if any
    for (char **argv_ptr = argv; *++argv_ptr!=NULL; ) {
        char *param = *argv_ptr;
        if (*param == '-') {
            param++;
                 if (strcasecmp(param,"-")==0)   break;   // "--" is a "stop processing" option
            else if (isdigit(*param))            r.method = std_Tornado_method[check_parse_int (param, 1, elements(std_Tornado_method)-1, param-1)];
        }
    }
    // 2. Second, process rest of options
    for (char **argv_ptr = argv; *++argv_ptr!=NULL; ) {
        char *param = *argv_ptr;
        if (param[0] != '-' || param[1]=='\0') {
            fcount++;
        } else { param++;  int error=0;
                 if (strcasecmp(param,"-")==0)      break;
            else if (strcasecmp(param,"") ==0)      continue;
            else if (strcasecmp(param,"z")==0)      global_mode=_COMPRESS;
            else if (strcasecmp(param,"d")==0)      global_mode=_DECOMPRESS;
            else if (strcasecmp(param,"delete")==0) delete_input_files=TRUE;
            else if (strcasecmp(param,"t")==0)      output_filename="";
            else if (strcasecmp(param,"q")==0)      r.quiet_title = r.quiet_header = r.quiet_progress = r.quiet_result = TRUE;
#ifndef FREEARC_NO_TIMING
            else if (strcasecmp(param,"cpu")==0)    r.use_cpu_time=TRUE;
#endif
            else if (strcasecmp(param,"h")==0)      global_mode=HELP;
            else if (strcasecmp(param,"b")==0)      r.method.buffer = MAX_BUFFER_SIZE;         // set buffer size to the maximum supported by LZ coders
            else if (strcasecmp(param,"x")==0)      r.method.caching_finder = CACHING_MF4;
            else if (strcasecmp(param,"xx")==0)     r.method.caching_finder = CYCLED_MF4;
            else if (strcasecmp(param,"x+")==0)     r.method.caching_finder = CACHING_MF4;
            else if (strcasecmp(param,"x-")==0)     r.method.caching_finder = NON_CACHING_MF;
            else if (strcasecmp(param,"t+")==0)     r.method.find_tables = TRUE;
            else if (strcasecmp(param,"t-")==0)     r.method.find_tables = FALSE;
            else if (strcasecmp(param,"t1")==0)     r.method.find_tables = TRUE;
            else if (strcasecmp(param,"t0")==0)     r.method.find_tables = FALSE;
            else if (strcasecmp(param,"s")==0)      r.method.hash3 = 1;
            else if (strcasecmp(param,"ss")==0)     r.method.hash3 = 2;
            else if (strcasecmp(param,"s+")==0)     r.method.hash3 = 1;
            else if (strcasecmp(param,"s-")==0)     r.method.hash3 = 0;
            else if (start_with(param,"fb"))        r.method.fast_bytes = check_parse_int (param+2, MIN_FAST_BYTES, MAX_FAST_BYTES, *argv_ptr);
#ifdef FREEARC_WIN
            else if (strcasecmp(param,"slp-")==0)   DefaultLargePageMode = DISABLE;
            else if (strcasecmp(param,"slp" )==0)   DefaultLargePageMode = TRY;
            else if (strcasecmp(param,"slp+")==0)   DefaultLargePageMode = FORCE;
#endif
            else if (start_with(param,"rem"))       /* ignore option */;
            else if (isdigit(*param))            ; // -1..-16 option is already processed :)
            else switch( tolower(*param++) ) {
                case 'b': r.method.buffer          = check_parse_mem (param, MIN_BUFFER_SIZE, MAX_BUFFER_SIZE,    *argv_ptr);  break;
                case 'h': r.method.hashsize        = check_parse_mem (param, MIN_HASH_SIZE,   MAX_HASH_SIZE,      *argv_ptr);  break;
                case 'l': r.method.hash_row_width  = check_parse_int (param, 1,               MAX_HASH_ROW_WIDTH, *argv_ptr);  break;
                case 'u': r.method.update_step     = check_parse_int (param, 1,               MAX_UPDATE_STEP,    *argv_ptr);  break;
                case 'c': r.method.encoding_method = check_parse_int (param, BYTECODER,       ARICODER,           *argv_ptr);  break;
                case 's': r.method.hash3           = check_parse_int (param, 0,               2,                  *argv_ptr);  break;
                case 'p': r.method.match_parser    = parseInt (param, &error);  break;
                case 'x': r.method.caching_finder  = parseInt (param, &error);  break;
                case 'o': output_filename          = param;                     break;
                case 'q':
#ifndef FREEARC_NO_TIMING
                          r.quiet_title            = strchr (param, 't');
                          r.quiet_progress         = strchr (param, 'p');
#endif
                          r.quiet_header           = strchr (param, 'h');
                          r.quiet_result           = strchr (param, 'r');
                          break;
                case 'a': switch( tolower(*param++) ) {
                            case 'h': r.method.auxhash_size      = check_parse_mem (param, MIN_HASH_SIZE, MAX_HASH_SIZE, *argv_ptr);  goto check_for_errors;
                            case 'l': r.method.auxhash_row_width = check_parse_int (param, 1,        MAX_HASH_ROW_WIDTH, *argv_ptr);  goto check_for_errors;
                          }
                          // 'a' should be the last case!
                default : fprintf (stderr, "ERROR: unknown option '%s'\n", *argv_ptr);
                          exit(FREEARC_EXIT_ERROR);
            }
check_for_errors:
            if (error) {
                fprintf (stderr, "ERROR: bad option format: '%s'\n", *argv_ptr);
                exit(FREEARC_EXIT_ERROR);
            }
            if (!(r.method.match_parser==GREEDY || r.method.match_parser==LAZY  || r.method.match_parser==OPTIMAL)) {
                fprintf (stderr, "ERROR: bad option value: '%s'\n", *argv_ptr);
                exit(FREEARC_EXIT_ERROR);
            }
            int mf = r.method.caching_finder;
            r.method.caching_finder = mf = (mf==CACHING_MF4_DUB? CACHING_MF4 : (mf==CYCLED_MF4_DUB? CYCLED_MF4 : mf));
            if (!(mf==NON_CACHING_MF || (CYCLED_MF4<=mf && mf<=CYCLED_MF7) || (CACHING_MF4<=mf && mf<=CACHING_MF7) || (BT_MF4<=mf && mf<=BT_MF7))) {
                fprintf (stderr, "ERROR: non-existing match finder: '%s'\n", *argv_ptr);
                exit(FREEARC_EXIT_ERROR);
            }
        }
    }

    // No files to compress: read from stdin and write to stdout
    if (global_mode!=HELP && fcount==0 &&
       (global_mode!=AUTO  ||  !isatty(0) && !isatty(1)) ) {

        static char *_argv[] = {argv[0], (char*)"-", NULL};
        argv = _argv;
        fcount = 1;

    } else if (global_mode==HELP || fcount==0) {
        char h[100], ah[100], b[100], MinHashSizeStr[100], MaxHashSizeStr[100], MinBufSizeStr[100], MaxBufSizeStr[100];
        showMem64 (r.method.hashsize, h);
        showMem64 (r.method.auxhash_size, ah);
        showMem64 (r.method.buffer, b);
        showMem64 (MIN_HASH_SIZE, MinHashSizeStr);
        showMem64 (MAX_HASH_SIZE+1, MaxHashSizeStr);
        showMem64 (MIN_BUFFER_SIZE, MinBufSizeStr);
        showMem64 (MAX_BUFFER_SIZE, MaxBufSizeStr);
        printf( "Tornado compressor v0.6  (c) [email protected]  http://freearc.org  2014-03-08\n"
                "\n"
                " Usage: tor [options and files in any order]\n"
                "   -#      -- compression level (1..%d), default %d\n", int(elements(std_Tornado_method))-1, default_Tornado_method);
        printf( "   -z      -- force compression\n"
                "   -d      -- force decompression\n"
                "   -oNAME  -- output filename/directory (default %s/%s)\n", COMPRESS_EXT, DECOMPRESS_EXT);
        printf( "   -t      -- test (de)compression (redirect output to nul)\n"
                "   -delete -- delete successfully (de)compressed input files\n"
#ifdef FREEARC_NO_TIMING
                "   -q      -- be quiet; -q[hr]* disables header/results individually\n"
#else
                "   -q      -- be quiet; -q[thpr]* disables title/header/progress/results individually\n"
                "   -cpu    -- compute raw CPU time (for benchmarking)\n"
#endif
#ifdef FREEARC_WIN
                "   -slp[+/-/]   -- force/disable/try(default) large pages support (2mb/4mb)\n"
#endif
                "   -rem... -- command-line remark\n"
                "   -h      -- display this help\n"
                "   --      -- stop flags processing\n"
                " \"-\" used as filename means stdin/stdout\n"
                "\n"
                " Advanced compression parameters:\n"
                "   -b#     -- buffer size (%s..%s), default %s\n", MinBufSizeStr, MaxBufSizeStr, b);
        printf( "   -h#     -- hash size (%s..%s-1), default %s\n", MinHashSizeStr, MaxHashSizeStr, h);
        printf( "   -l#     -- length of hash row (1..%d), default %d\n", int(MAX_HASH_ROW_WIDTH), r.method.hash_row_width);
        printf( "   -ah#    -- auxiliary hash size (%s..%s-1), default %s\n", MinHashSizeStr, MaxHashSizeStr, ah);
        printf( "   -al#    -- auxiliary hash row length (1..%d), default %d\n", int(MAX_HASH_ROW_WIDTH), r.method.auxhash_row_width);
        printf( "   -u#     -- update step (1..%d), default %d\n", int(MAX_UPDATE_STEP), r.method.update_step);
        printf( "   -c#     -- coder (1-bytes, 2-bits, 3-huf, 4-arith), default %d\n", r.method.encoding_method);
        printf( "   -p#     -- parser (1-greedy, 2-lazy, 4-optimal), default %d\n", r.method.match_parser);
        printf( "   -x#     -- match finder (0: non-caching ht4, 4-7: cycling cached ht4..ht7,\n"
                "                            14-17: shifting cached ht4..ht7, 24-27: bt4..bt7), default %d\n", r.method.caching_finder);
        printf( "   -s#     -- 2/3-byte hash (0-disabled, 1-fast, 2-max), default %d\n", r.method.hash3);
        printf( "   -t#     -- table diffing (0-disabled, 1-enabled), default %d\n", r.method.find_tables);
        printf( "   -fb#    -- fast bytes in the optimal parser (%d..%d), default %d\n", int(MIN_FAST_BYTES), int(MAX_FAST_BYTES), r.method.fast_bytes);
        printf( "\n"
                " Predefined methods:\n");
        for (int i=1; i<elements(std_Tornado_method); i++)
        {
            printf("   %-8d-- %s\n", -i, name(std_Tornado_method[i]));
        }
        exit(EXIT_SUCCESS);
    }



    // (De)compress all files given on cmdline
    bool parse_options=TRUE;  // options will be parsed until "--"
    Install_signal_handler(signal_handler);

    for (char **parameters = argv; *++parameters!=NULL; )
    {
        // If options are still parsed and this argument starts with "-" - it's an option
        if (parse_options && parameters[0][0]=='-' && parameters[0][1]) {
            if (strequ(*parameters,"--"))  parse_options=FALSE;
            continue;
        }

        // Save input filename
        r.filename = *parameters;

        // Select operation mode if it was not specified on cmdline
        r.mode = global_mode != AUTO?                  global_mode :
                 end_with (r.filename, COMPRESS_EXT)?  _DECOMPRESS  :
                                                       _COMPRESS;
        // Extension that should be added to output filenames
        const char *MODE_EXT  =  r.mode==_COMPRESS? COMPRESS_EXT : DECOMPRESS_EXT;

        // Construct output filename
        if (r.mode==BENCHMARK  ||  output_filename && strequ (output_filename, "")) {  // Redirect output to nul
            strcpy (r.outname, "");
        } else if (output_filename) {
            if (strequ(output_filename,"-"))
                strcpy (r.outname, output_filename);
            else if (is_path_char (last_char (output_filename)))
                {sprintf(r.outname, "%s%s", output_filename, drop_dirname(r.filename));  goto add_remove_ext;}
            else if (dir_exists (output_filename))
                {sprintf(r.outname, "%s%c%s", output_filename, PATH_DELIMITER, drop_dirname(r.filename));  goto add_remove_ext;}
            else
                strcpy (r.outname, output_filename);
        } else if (strequ(r.filename,"-")) {
            strcpy (r.outname, r.filename);
        } else {
            // No output filename was given on cmdline:
            //    on compression   - add COMPRESS_EXT
            //    on decompression - remove COMPRESS_EXT (and add DECOMPRESS_EXT if file already exists)
            strcpy (r.outname, r.filename);
add_remove_ext: // Remove COMPRESS_EXT on the end of name or add DECOMPRESS_EXT (unless we are in _COMPRESS mode)
            if (r.mode!=_COMPRESS && end_with (r.outname, COMPRESS_EXT)) {
                r.outname [strlen(r.outname) - strlen(COMPRESS_EXT)] = '\0';
                if (file_exists (r.outname))
                    strcat(r.outname, MODE_EXT);
            } else {
                strcat(r.outname, MODE_EXT);
            }
        }

        // Open input file
        r.fin = strequ (r.filename, "-")? stdin : file_open_read_binary(r.filename);
        if (r.fin == NULL) {
            fprintf (stderr, "\n Can't open %s for read\n", r.filename);
            exit(FREEARC_EXIT_ERROR);
        }
        set_binary_mode (r.fin);

        // Open output file
        if (*r.outname) {
          r.fout = strequ (r.outname, "-")? stdout : file_open_write_binary(r.outname);
          if (r.fout == NULL) {
              fprintf (stderr, "\n Can't open %s for write\n", r.outname);
              exit(FREEARC_EXIT_ERROR);
          }
          set_binary_mode (r.fout);
        } else {
          r.fout = NULL;
        }

        // Prepare to (de)compression
        int result;  char filesize_str[100];
        start_print_stats(r);

        // Perform actual (de)compression
        switch (r.mode) {
        case _COMPRESS: {
            if (!r.quiet_header && r.filesize >= 0)
                fprintf (stderr, "Compressing %s bytes with %s\n", show3(r.filesize,filesize_str), name(r.method));
            PackMethod m = r.method;
            if (r.filesize >= 0)
                m.buffer = mymin (m.buffer, r.filesize+LOOKAHEAD*2);
            result = tor_compress (m, ReadWriteCallback, &r, NULL, -1);
            break; }

        case _DECOMPRESS: {
            //if (!r.quiet_header && !strequ (r.outname, "-"))   fprintf (stderr, "Unpacking %.3lf mb\n", double(r.filesize)/1000/1000);
            result = tor_decompress (ReadWriteCallback, &r, NULL, -1);
            break; }
        }

        // Finish (de)compression
        print_final_stats(r);
        fclose (r.fin);
        if (r.fout)  fclose (r.fout);

        if (result == FREEARC_OK)  {
            if (delete_input_files && !strequ(r.filename,"-"))    delete_file(r.filename);
        } else {
            if (!strequ(r.outname,"-") && !strequ(r.outname,""))  delete_file(r.outname);
            switch (result) {
            case FREEARC_ERRCODE_INVALID_COMPRESSOR:
                fprintf (stderr, "\nThis compression mode isn't supported by small Tornado version, use full version instead!");
                break;
            case FREEARC_ERRCODE_NOT_ENOUGH_MEMORY:
                fprintf (stderr, "\nNot enough memory for (de)compression!");
                break;
            case FREEARC_ERRCODE_READ:
                fprintf (stderr, "\nRead error! Bad media?");
                break;
            case FREEARC_ERRCODE_WRITE:
                fprintf (stderr, "\nWrite error! Disk full?");
                break;
            case FREEARC_ERRCODE_BAD_COMPRESSED_DATA:
                fprintf (stderr, "\nData can't be decompressed!");
                break;
            default:
                fprintf (stderr, "\n(De)compression failed with error code %d!", result);
                break;
            }
            exit(FREEARC_EXIT_ERROR);
        }

        // going to next file...
    }

    return EXIT_SUCCESS;
}
Example #6
0
void pick_file(file_s *picked, const char *path) {

    picker = malloc(sizeof(picker_s));
    get_dir(path);

    // key repeat timer
    static time_t t_start = 0, t_end = 0, t_elapsed = 0;

    while (aptMainLoop()) {

        hidScanInput();
        u32 kHeld = hidKeysHeld();
        u32 kDown = hidKeysDown();

        if (hidKeysUp()) {
            time(&t_start); // reset held timer
        }

        if (kDown & KEY_DOWN) {
            picker->file_index++;
            if (picker->file_index >= picker->file_count)
                picker->file_index = 0;
            time(&t_start);
        } else if (kHeld & KEY_DOWN) {
            time(&t_end);
            t_elapsed = t_end - t_start;
            if (t_elapsed > 0) {
                picker->file_index++;
                if (picker->file_index >= picker->file_count)
                    picker->file_index = 0;
                svcSleep(100);
            }
        }

        if (kDown & KEY_UP) {
            picker->file_index--;
            if (picker->file_index < 0)
                picker->file_index = picker->file_count - 1;
            time(&t_start);
        } else if (kHeld & KEY_UP) {
            time(&t_end);
            t_elapsed = t_end - t_start;
            if (t_elapsed > 0) {
                picker->file_index--;
                if (picker->file_index < 0)
                    picker->file_index = picker->file_count - 1;
                svcSleep(100);
            }
        }

        if (kDown & KEY_A) {
            int index = picker->file_index;
            if (!picker->files[index].isDir) {
                if (confirm(0, "Launch \"%s\" ?", picker->files[index].name)) {
                    strncpy(picked->name, picker->files[index].name, 512);
                    strncpy(picked->path, picker->files[index].path, 512);
                    picked->isDir = picker->files[index].isDir;
                    picked->size = picker->files[index].size;
                    break;
                }
            }
            else {
                get_dir(picker->files[index].path);
            }
        } else if (kDown & KEY_X) {
            int index = picker->file_index;
            if (!picker->files[index].isDir) {
                const char *ext = get_filename_ext(picker->files[index].name);
                if (strcasecmp(ext, "3dsx") == 0) {
                    if (confirm(3, "Add entry to boot menu: \"%s\" ?", picker->files[index].name)) {
                        if (config->count > CONFIG_MAX_ENTRIES - 1) {
                            debug("Maximum entries reached (%i)\n", CONFIG_MAX_ENTRIES);
                        } else if (configAddEntry(picker->files[index].name, picker->files[index].path, 0) == 0) {
                            debug("Added entry: %s\n", picker->files[index].name);
                        } else {
                            debug("Error adding entry: %s\n", picker->files[index].name);
                        }
                    }
                }
            }
        }
        else if (kDown & KEY_B) {
            // exit if we can't go back
            if (strlen(picker->now_path) <= 1)
                break;

            // remove slash if needed
            if (end_with(picker->now_path, '/'))
                picker->now_path[strlen(picker->now_path) - 1] = '\0';

            // build path
            char *slash = strrchr(picker->now_path, '/');
            if (slash == NULL)
                break;
            int len = (int) (slash - picker->now_path);
            picker->now_path[len] = '\0';

            // enter new dir
            get_dir(picker->now_path);
        }

        gfxClear();
        gfxDrawText(GFX_TOP, GFX_LEFT, &fontTitle, "*** Select a file ***", 130, 20);

        int minX = 16;
        int maxX = 400 - 16;
        int minY = 32;
        int maxY = 240 - 16;
        drawRect(GFX_TOP, GFX_LEFT, minX, minY, maxX, maxY, (u8) 0xFF, (u8) 0xFF, (u8) 0xFF);
        minY += 20;

        int i, y = 0;
        int page = picker->file_index / MAX_LINE;
        for (i = page * MAX_LINE; i < page * MAX_LINE + MAX_LINE; i++) {
            if (i >= picker->file_count)
                break;

            if (i == picker->file_index) {
                gfxDrawRectangle(GFX_TOP, GFX_LEFT, (u8[]) {0xDC, 0xDC, 0xDC}, minX + 4, minY + 16 * y, maxX - 23, 15);
                gfxDrawTextN(GFX_TOP, GFX_LEFT, &fontSelected, picker->files[i].name, 47, minX + 6, minY + 16 * y);
                if (!picker->files[i].isDir) {
                    gfxDrawText(GFX_BOTTOM, GFX_LEFT, &fontTitle, "Informations", minX + 6, 20);
                    gfxDrawText(GFX_BOTTOM, GFX_LEFT, &fontDefault,
                                "Press (A) to launch\nPress (X) to add to boot menu", minX + 12, 40);
                }
            } else {
                gfxDrawTextN(GFX_TOP, GFX_LEFT, &fontDefault, picker->files[i].name, 47, minX + 6, minY + 16 * y);
            }
            y++;
        }
Example #7
0
void pick_file(file_s *picked, const char *path) {

    picker = malloc(sizeof(picker_s));
    get_dir(path);

    // key repeat timer
    static time_t t_start = 0, t_end = 0, t_elapsed = 0;

    while (aptMainLoop()) {

        hidScanInput();
        u32 kHeld = hidKeysHeld();
        u32 kDown = hidKeysDown();

        if (hidKeysUp()) {
            time(&t_start); // reset held timer
        }

        if (kDown & KEY_DOWN) {
            picker->file_index++;
            if (picker->file_index >= picker->file_count)
                picker->file_index = 0;
            time(&t_start);
        } else if (kHeld & KEY_DOWN) {
            time(&t_end);
            t_elapsed = t_end - t_start;
            if (t_elapsed > 0) {
                picker->file_index++;
                if (picker->file_index >= picker->file_count)
                    picker->file_index = 0;
                svcSleep(100);
            }
        }

        if (kDown & KEY_UP) {
            picker->file_index--;
            if (picker->file_index < 0)
                picker->file_index = picker->file_count - 1;
            time(&t_start);
        } else if (kHeld & KEY_UP) {
            time(&t_end);
            t_elapsed = t_end - t_start;
            if (t_elapsed > 0) {
                picker->file_index--;
                if (picker->file_index < 0)
                    picker->file_index = picker->file_count - 1;
                svcSleep(100);
            }
        }

        if (kDown & KEY_A) {
            if (picker->file_count > 0) {
                int index = picker->file_index;
                if (!picker->files[index].isDir) {
                    if (confirm(0, "Launch \"%s\" ?", picker->files[index].name)) {
                        strncpy(picked->name, picker->files[index].name, 512);
                        strncpy(picked->path, picker->files[index].path, 512);
                        picked->isDir = picker->files[index].isDir;
                        picked->size = picker->files[index].size;
                        break;
                    }
                }
                else {
                    get_dir(picker->files[index].path);
                }
            }
        } else if (kDown & KEY_X) {
            int index = picker->file_index;
            if (!picker->files[index].isDir) {
                const char *ext = get_filename_ext(picker->files[index].name);
                if (strcasecmp(ext, "3dsx") == 0) {
                    if (confirm(3, "Add entry to boot menu: \"%s\" ?", picker->files[index].name)) {
                        if (config->count > CONFIG_MAX_ENTRIES - 1) {
                            debug("Maximum entries reached (%i)\n", CONFIG_MAX_ENTRIES);
                        } else if (configAddEntry(picker->files[index].name, picker->files[index].path, 0) == 0) {
                            debug("Added entry: %s\n", picker->files[index].name);
                        } else {
                            debug("Error adding entry: %s\n", picker->files[index].name);
                        }
                    }
                }
            }
        }
        else if (kDown & KEY_B) {
            // exit if we can't go back
            if (strlen(picker->now_path) <= 1)
                break;

            // remove slash if needed
            if (end_with(picker->now_path, '/'))
                picker->now_path[strlen(picker->now_path) - 1] = '\0';

            // build path
            char *slash = strrchr(picker->now_path, '/');
            if (slash == NULL)
                break;
            int len = (int) (slash - picker->now_path);
            picker->now_path[len] = '\0';

            // enter new dir
            get_dir(picker->now_path);
        }

        drawBg();
        drawTitle("*** Select a file ***");

        int i, y = 0;
        int page = picker->file_index / MAX_LINE;
        for (i = page * MAX_LINE; i < page * MAX_LINE + MAX_LINE; i++) {
            if (i >= picker->file_count)
                break;

            drawItemN(i == picker->file_index, 47, 16 * i, picker->files[i].name);
            if (i == picker->file_index && !picker->files[i].isDir) {
                drawInfo("Press (A) to launch\nPress (X) to add to boot menu");

            }
            y++;
        }
        gfxSwap();
    }
    free(picker);
}