Esempio n. 1
0
extern u32 fs_chm_to_menu(const char *chmfile, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor)
{
	int fid;
	struct chmFile *chm;
	t_fs_chm_enum cenum;

	if (menu_renew(&g_menu) == NULL) {
		return 0;
	}

	fid = freq_enter_hotzone();
	chm = chm_open(chmfile);

	if (chm == NULL) {
		freq_leave(fid);
		return 0;
	}

	add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor);

	cenum.icolor = icolor;
	cenum.selicolor = selicolor;
	cenum.selrcolor = selrcolor;
	cenum.selbcolor = selbcolor;
	chm_enumerate(chm, CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES, chmEnum, (void *) &cenum);
	chm_close(chm);
	freq_leave(fid);

	return g_menu->size;
}
Esempio n. 2
0
int music_list_save(const char *path)
{
	FILE *fp;
	int i;
	int fid;

	if (path == NULL)
		return -EINVAL;

	fp = fopen(path, "wt");
	if (fp == NULL)
		return -EBADFD;

	fid = freq_enter_hotzone();
	for (i = 0; i < music_maxindex(); i++) {
		struct music_file *file;

		file = music_get(i);
		if (file == NULL)
			continue;
		fprintf(fp, "%s\n", file->shortpath->ptr);
		fprintf(fp, "%s\n", file->longpath->ptr);
	}
	fclose(fp);
	freq_leave(fid);

	return true;
}
Esempio n. 3
0
int music_list_save(const char *path)
{
	FILE *fp;
	int i;
	int fid;

	if (path == NULL)
		return -EINVAL;

	fp = fopen(path, "wt");
	if (fp == NULL)
		return -EBADFD;

	fid = freq_enter_hotzone();
	for (i = 0; i < music_maxindex(); i++) {
		MusicListEntry *file;

		file = musiclist_get(&g_music_list, i);
		if (file == NULL)
			continue;
		fprintf(fp, "%s\n", file->spath);
		fprintf(fp, "%s\n", file->lpath);
	}
	fclose(fp);
	freq_leave(fid);

	return true;
}
Esempio n. 4
0
int music_list_load(const char *path)
{
	int ret = 0;
	FILE *fp;
	char fname[PATH_MAX];
	char lfname[PATH_MAX];
	int fid;

	if (path == NULL) {
		ret = -EINVAL;
		goto end;
	}

	fp = fopen(path, "rt");

	if (fp == NULL) {
		ret = -EBADFD;
		goto end;
	}

	fid = freq_enter_hotzone();

	while (fgets(fname, PATH_MAX, fp) != NULL) {
		dword len1, len2;

		if (fgets(lfname, PATH_MAX, fp) == NULL)
			break;

		len1 = strlen(fname);
		len2 = strlen(lfname);

		if (len1 > 1 && len2 > 1) {
			if (fname[len1 - 1] == '\n')
				fname[len1 - 1] = 0;
			if (lfname[len2 - 1] == '\n')
				lfname[len2 - 1] = 0;
		} else
			continue;
		if (!music_is_file_exist(fname))
			continue;
		music_add(fname, lfname);
	}

	fclose(fp);
	freq_leave(fid);

end:
	music_list_refresh();

	return ret;
}
Esempio n. 5
0
int musicdrv_load(const char *spath, const char *lpath)
{
	if (spath == NULL || lpath == NULL)
		return -EINVAL;
	if (cur_musicdrv == NULL)
		return -EBUSY;
	if (cur_musicdrv->load) {
		int ret, fid;

		fid = freq_enter_hotzone();
		ret = cur_musicdrv->load(spath, lpath);
		freq_leave(fid);

		need_stop = true;

		return ret;
	} else
		return -ENOSYS;
}
Esempio n. 6
0
void generic_set_playback(bool playing)
{
	if (playing) {
		if (g_fid < 0) {
			struct music_info info = { 0 };

			info.type = MD_GET_CPUFREQ;

			if (musicdrv_get_info(&info) == 0) {
				g_fid = freq_enter(info.psp_freq[0], info.psp_freq[1]);
			}
		}
	} else {
		if (g_fid >= 0) {
			freq_leave(g_fid);
			g_fid = -1;
		}
	}
}
Esempio n. 7
0
dword scene_readimage(dword selidx)
{
	u64 timer_start, timer_end;
	u64 slide_start, slide_end;

	width_rotated = 0, height_rotated = 0, thumb_width = 0, thumb_height =
		0, paintleft = 0, painttop = 0;
	imgdata = NULL, imgshow = NULL;
	oldangle = 0;
	curtop = 0, curleft = 0, xpos = 0, ypos = 0;
	img_needrf = true, img_needrc = true, img_needrp = true, showinfo =
		false, thumb = false;
	slideshow = false;
	now = 0, lasttime = 0;
	imgreading = true;

	if (config.imginfobar)
		imgh = PSP_SCREEN_HEIGHT - DISP_FONTSIZE;
	else
		imgh = PSP_SCREEN_HEIGHT;

	if (config.use_image_queue) {
		cache_setup(config.max_cache_img, &selidx);
		cache_set_forward(true);
		cache_on(true);
	}

	xrRtcGetCurrentTick(&timer_start);

	while (1) {
		u64 dbgnow, dbglasttick;
		dword key = 0;
		int ret;

		if (img_needrf) {
			int fid;
			dword ret;

			fid = freq_enter_hotzone();
			xrRtcGetCurrentTick(&dbglasttick);
			ret = scene_reloadimage(selidx);

			if (ret == -1) {
				freq_leave(fid);
				break;
			}

			img_needrf = false;
			xrRtcGetCurrentTick(&dbgnow);
			dbg_printf(d, _("装载图像时间: %.2f秒"),
					   pspDiffTime(&dbgnow, &dbglasttick));
			freq_leave(fid);
		}

		if (img_needrc) {
			int fid;

			fid = freq_enter_hotzone();
			xrRtcGetCurrentTick(&dbglasttick);
			scene_rotateimage();
			img_needrc = false;
			xrRtcGetCurrentTick(&dbgnow);
			dbg_printf(d, _("旋转图像时间: %.2f秒"),
					   pspDiffTime(&dbgnow, &dbglasttick));
			freq_leave(fid);
		}

		if (img_needrp) {
			scene_printimage(selidx);
			img_needrp = false;
		}

		now = time(NULL);

		if (config.thumb == conf_thumb_scroll && thumb) {
			thumb = false;
			img_needrp = true;
		}

		key = ctrl_read_cont();
		ret = image_handle_input(&selidx, key);

		if (ret == -1 && slideshow && !slideshow_move) {
			if (key == PSP_CTRL_CIRCLE) {
			} else if (key != 0
					   && (key == config.imgkey[1] || key == config.imgkey2[1]
						   || key == CTRL_FORWARD)) {
				bool should_exit = false;

				next_image(&selidx, &should_exit);

				if (should_exit) {
					break;
				}
			} else if (key != 0
					   && (key == config.imgkey[0] || key == config.imgkey2[0]
						   || key == CTRL_BACK)) {
				prev_image(&selidx);
			} else {
				xrPowerTick(0);
				if (config.imgpaging == conf_imgpaging_direct ||
					config.imgpaging == conf_imgpaging_updown ||
					config.imgpaging == conf_imgpaging_leftright) {
					if (now - lasttime >= config.slideinterval) {
						lasttime = now;
						ret = scene_slideshow_forward(&selidx);
					}
				} else {
					xrRtcGetCurrentTick(&slide_end);
					if (pspDiffTime(&slide_end, &slide_start) >= 0.1) {
						xrRtcGetCurrentTick(&slide_start);
					} else {
						lasttime = now;
						ret = scene_slideshow_forward(&selidx);
					}
				}
			}
		}

		if (showinfo && (key & PSP_CTRL_CIRCLE) == 0) {
			img_needrp = true;
			showinfo = false;
		}

		xrRtcGetCurrentTick(&timer_end);

		if (pspDiffTime(&timer_end, &timer_start) >= 1.0) {
			xrRtcGetCurrentTick(&timer_start);
			secticks++;
		}

		if (config.autosleep != 0 && secticks > 60 * config.autosleep) {
			power_down();
			xrPowerRequestSuspend();
			secticks = 0;
		}

		if (ret != -1) {
			selidx = ret;
			break;
		}

		scene_image_delay_action();
	}

	reset_image_show_ptr();

	if (config.use_image_queue) {
		cache_on(false);
	}

	imgreading = false;

	if (config.use_image_queue) {
	} else {
		if (imgdata != NULL) {
			free(imgdata);
			imgdata = NULL;
		}
	}

	if (config.use_image_queue) {
		// let cacher delete exif data
		exif_array = NULL;
	} else {
		if (exif_array) {
			buffer_array_free(exif_array);
			exif_array = NULL;
		}
	}

	return selidx;
}
Esempio n. 8
0
int start_cache_next_image(void)
{
	cache_image_t *p = NULL;
	cache_image_t tmp;
	t_fs_filetype ft;
	dword free_memory;
	int fid;

	if (avoid_times && curr_times++ < avoid_times) {
//      dbg_printf(d, "%s: curr_times %d avoid time %d", __func__, curr_times, avoid_times);
		return -1;
	}

	free_memory = get_free_mem();

	if (config.scale >= 100) {
		if (free_memory < 8 * 1024 * 1024) {
			return -1;
		}
	} else if (free_memory < 1024 * 1024) {
		return -1;
	}

	cache_lock();

	for (p = ccacher.caches; p != ccacher.caches + ccacher.caches_size; ++p) {
		if (p->status == CACHE_INIT || p->status == CACHE_FAILED) {
			break;
		}
	}

	// if we ecounter FAILED cache, abort the caching, because user will quit when the image shows up
	if (p == ccacher.caches + ccacher.caches_size || p->status == CACHE_FAILED) {
		cache_unlock();
		return 0;
	}

	copy_cache_image(&tmp, p);
	cache_unlock();
	ft = fs_file_get_type(tmp.filename);
	fid = freq_enter_hotzone();

	if (tmp.where == scene_in_dir) {
		char fullpath[PATH_MAX];

		STRCPY_S(fullpath, tmp.archname);
		STRCAT_S(fullpath, tmp.filename);
		tmp.result =
			image_open_archive(fullpath, tmp.archname, ft, &tmp.width,
							   &tmp.height, &tmp.data, &tmp.bgc, tmp.where,
							   &tmp.exif_array);
	} else {
		tmp.result =
			image_open_archive(tmp.filename, tmp.archname, ft, &tmp.width,
							   &tmp.height, &tmp.data, &tmp.bgc, tmp.where,
							   &tmp.exif_array);
	}

	if (tmp.result == 0 && tmp.data != NULL && config.imgbrightness != 100) {
		pixel *t = tmp.data;
		short b = 100 - config.imgbrightness;
		dword i;

		for (i = 0; i < tmp.height * tmp.width; i++) {
			*t = disp_grayscale(*t, 0, 0, 0, b);
			t++;
		}
	}

	freq_leave(fid);

	cache_lock();

	for (p = ccacher.caches; p != ccacher.caches + ccacher.caches_size; ++p) {
		if (p->status == CACHE_INIT || p->status == CACHE_FAILED) {
			break;
		}
	}

	// recheck the first unloaded (and not failed) image, for we haven't locked cache for a while
	if (p == ccacher.caches + ccacher.caches_size || p->status == CACHE_FAILED) {
		free_cache_image(&tmp);
		cache_unlock();
		return 0;
	}

	if (tmp.result == 0) {
		dword memory_used;

		memory_used = tmp.width * tmp.height * sizeof(pixel);

//      dbg_printf(d, "SERVER: Image %u finished loading", (unsigned)tmp.selidx);
//      dbg_printf(d, "%s: Memory usage %uKB", __func__, (unsigned) ccacher.memory_usage / 1024);
		ccacher.memory_usage += memory_used;
		cacher_cleared = false;
		tmp.status = CACHE_OK;
		copy_cache_image(p, &tmp);
		tmp.data = NULL;
		tmp.exif_array = NULL;
		free_cache_image(&tmp);
		curr_times = avoid_times = 0;
	} else if ((tmp.result == 4 || tmp.result == 5)
			   || (tmp.where == scene_in_rar && tmp.result == 6)) {
		// out of memory
		// if unrar throwed a bad_cast exception when run out of memory, result can be 6 also.

		// is memory completely out of memory?
		if (ccacher.memory_usage == 0) {
//          dbg_printf(d, "SERVER: Image %u finished failed(%u), giving up", (unsigned)tmp.selidx, tmp.result);
			tmp.status = CACHE_FAILED;
			copy_cache_image(p, &tmp);
			p->data = NULL;
			p->exif_array = NULL;
		} else {
			// retry later
//          dbg_printf(d, "SERVER: Image %u finished failed(%u), retring", (unsigned)tmp.selidx, tmp.result);
//          dbg_printf(d, "%s: Memory usage %uKB", __func__, (unsigned) ccacher.memory_usage / 1024);
			if (avoid_times) {
				avoid_times *= 2;
			} else {
				avoid_times = 1;
			}

			avoid_times = min(avoid_times, 32767);
			curr_times = 0;
		}

		free_cache_image(&tmp);
	} else {
//      dbg_printf(d, "SERVER: Image %u finished failed(%u)", (unsigned)tmp.selidx, tmp.result);
		tmp.status = CACHE_FAILED;
		copy_cache_image(p, &tmp);
		p->data = NULL;
		p->exif_array = NULL;
		free_cache_image(&tmp);
	}

	cache_unlock();

	return 0;
}
Esempio n. 9
0
extern u32 fs_umd_to_menu(const char *umdfile, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor)
{
	buffer *pbuf = NULL;
	u32 cur_count = 1;
	int fid;
	t_win_menuitem item;

	if (menu_renew(&g_menu) == NULL) {
		return 0;
	}

	fid = freq_enter_hotzone();

	add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor);

	do {
		size_t stlen = 0;
		u_int i = 1;
		struct t_chapter *p;
		char pos[20] = { 0 };

		if (!p_umdchapter || (p_umdchapter->umdfile->ptr && strcmp(p_umdchapter->umdfile->ptr, umdfile))) {
			if (p_umdchapter)
				umd_chapter_reset(p_umdchapter);
			p_umdchapter = umd_chapter_init();
			if (!p_umdchapter)
				break;
			buffer_copy_string(p_umdchapter->umdfile, umdfile);
			cur_count = parse_umd_chapters(umdfile, &p_umdchapter);
		} else
			cur_count = p_umdchapter->chapter_count + 1;

		if (cur_count > 1) {
			p = p_umdchapter->pchapters;
			pbuf = buffer_init();

			if (!pbuf || buffer_prepare_copy(pbuf, 256) < 0)
				break;

			for (i = 1; i < cur_count; i++) {
				stlen = p[i - 1].name->used - 1;
				stlen = charsets_ucs_conv((const u8 *) p[i - 1].name->ptr, stlen, (u8 *) pbuf->ptr, pbuf->size);
				SPRINTF_S(pos, "%d", p[i - 1].length);
				win_menuitem_new(&item);
				buffer_copy_string_len(item.shortname, pos, 20);
				buffer_copy_string_len(item.compname, pbuf->ptr, (stlen > 256) ? 256 : stlen);
				filename_to_itemname(&item, item.compname->ptr);
				if (1 != p_umdchapter->umd_type) {
					if (0 == p_umdchapter->umd_mode)
						item.data = (void *) fs_filetype_bmp;
					else if (1 == p_umdchapter->umd_mode)
						item.data = (void *) fs_filetype_jpg;
					else
						item.data = (void *) fs_filetype_gif;
				} else
					item.data = (void *) fs_filetype_txt;
				item.data2[0] = p[i - 1].chunk_pos & 0xFFFF;
				item.data2[1] = (p[i - 1].chunk_pos >> 16) & 0xFFFF;
				item.data2[2] = p[i - 1].chunk_offset & 0xFFFF;
				item.data2[3] = (p[i - 1].chunk_offset >> 16) & 0xFFFF;
				item.data3 = p[i - 1].length;
#if 0
				printf("%d pos:%d,%d,%d-%d,%d\n", i, p[i - 1].chunk_pos, item.data2[0], item.data2[1], item.data2[2], item.data2[3]);
#endif
				item.selected = false;
				item.icolor = icolor;
				item.selicolor = selicolor;
				item.selrcolor = selrcolor;
				item.selbcolor = selbcolor;
				//buffer_free(p[i - 1].name);
				win_menu_add(g_menu, &item);
			}
#if 0
			printf("%s umd file:%s type:%d,mode:%d,chapter count:%ld\n", __func__, umdfile, p_umdchapter->umd_type, p_umdchapter->umd_mode, cur_count);
#endif
		}
	} while (false);

	if (pbuf)
		buffer_free(pbuf);

	freq_leave(fid);

	return g_menu->size;
}
Esempio n. 10
0
extern u32 fs_rar_to_menu(const char *rarfile, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor)
{
	int fid;
	struct RAROpenArchiveData arcdata;
	struct RARHeaderDataEx header;
	int ret;
	HANDLE hrar;
	t_fs_filetype ft;
	t_win_menuitem item;

	if (menu_renew(&g_menu) == NULL) {
		return 0;
	}

	fid = freq_enter_hotzone();

	arcdata.ArcName = (char *) rarfile;
	arcdata.OpenMode = RAR_OM_LIST;
	arcdata.CmtBuf = NULL;
	arcdata.CmtBufSize = 0;

	hrar = RAROpenArchive(&arcdata);

	if (hrar == 0) {
		freq_leave(fid);
		return 0;
	}

	add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor);

	do {
		char t[20];

		if ((ret = RARReadHeaderEx(hrar, &header)) != 0) {
			if (ret != ERAR_UNKNOWN)
				break;
			RARCloseArchive(hrar);
			if ((hrar = reopen_rar_with_passwords(&arcdata)) == 0)
				break;
			if (RARReadHeaderEx(hrar, &header) != 0)
				break;
		}
		if (header.UnpSize == 0)
			continue;

		ft = fs_file_get_type(header.FileName);

		if (ft == fs_filetype_chm || ft == fs_filetype_zip || ft == fs_filetype_rar)
			continue;

		win_menuitem_new(&item);
		item.data = (void *) ft;

		if (header.Flags & 0x200) {
			char str[1024];
			const u8 *uni;

			memset(str, 0, 1024);
			uni = (u8 *) header.FileNameW;
			charsets_utf32_conv(uni, sizeof(header.FileNameW), (u8 *) str, sizeof(str));
			buffer_copy_string_len(item.compname, header.FileName, 256);
			filename_to_itemname(&item, str);
		} else {
			buffer_copy_string_len(item.compname, header.FileName, 256);
			filename_to_itemname(&item, header.FileName);
		}

		SPRINTF_S(t, "%u", (unsigned int) header.UnpSize);
		buffer_copy_string(item.shortname, t);
		item.selected = false;
		item.icolor = icolor;
		item.selicolor = selicolor;
		item.selrcolor = selrcolor;
		item.selbcolor = selbcolor;
		item.data3 = header.UnpSize;
		win_menu_add(g_menu, &item);
	} while (RARProcessFile(hrar, RAR_SKIP, NULL, NULL) == 0);

	RARCloseArchive(hrar);
	freq_leave(fid);

	return g_menu->size;
}
Esempio n. 11
0
extern u32 fs_zip_to_menu(const char *zipfile, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor)
{
	int fid;
	unzFile unzf;
	t_win_menuitem item;

	if (menu_renew(&g_menu) == NULL) {
		return 0;
	}

	fid = freq_enter_hotzone();
	unzf = unzOpen(zipfile);

	if (unzf == NULL) {
		freq_leave(fid);
		return 0;
	}

	add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor);

	if (unzGoToFirstFile(unzf) != UNZ_OK) {
		unzClose(unzf);
		freq_leave(fid);

		return g_menu->size;
	}

	do {
		char fname[PATH_MAX];
		unz_file_info file_info;
		t_fs_filetype ft;
		char t[20];

		if (unzGetCurrentFileInfo(unzf, &file_info, fname, PATH_MAX, NULL, 0, NULL, 0) != UNZ_OK)
			break;

		if (file_info.uncompressed_size == 0)
			continue;

		ft = fs_file_get_type(fname);

		if (ft == fs_filetype_chm || ft == fs_filetype_zip || ft == fs_filetype_rar)
			continue;

		win_menuitem_new(&item);

		item.data = (void *) ft;
		buffer_copy_string(item.compname, fname);

		SPRINTF_S(t, "%u", (unsigned int) file_info.uncompressed_size);
		buffer_copy_string(item.shortname, t);
		filename_to_itemname(&item, fname);
		item.selected = false;
		item.icolor = icolor;
		item.selicolor = selicolor;
		item.selrcolor = selrcolor;
		item.selbcolor = selbcolor;
		item.data3 = file_info.uncompressed_size;
		win_menu_add(g_menu, &item);
	} while (unzGoToNextFile(unzf) == UNZ_OK);

	unzClose(unzf);
	freq_leave(fid);

	return g_menu->size;
}
Esempio n. 12
0
// New style fat system custom reading
extern u32 fs_dir_to_menu(const char *dir, char *sdir, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor, bool showhidden, bool showunknown)
{
	int fid;
	p_fat_info info;
	u32 count;
	u32 i;
	t_win_menuitem item;

	if (menu_renew(&g_menu) == NULL) {
		return 0;
	}

	fid = freq_enter_hotzone();
	count = fat_readdir(dir, sdir, &info);

	if (count == INVALID) {
		freq_leave(fid);
		return 0;
	}

	add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor);

	for (i = 0; i < count; i++) {
		win_menuitem_new(&item);

		if (!showhidden && (info[i].attr & FAT_FILEATTR_HIDDEN) > 0) {
			win_menuitem_free(&item);
			continue;
		}

		if (info[i].attr & FAT_FILEATTR_DIRECTORY) {
			item.data = (void *) fs_filetype_dir;
			buffer_copy_string(item.shortname, info[i].filename);
			buffer_copy_string(item.compname, info[i].longname);
			item.name[0] = '<';
			if ((item.width = strlen(info[i].longname) + 2) > MAX_ITEM_NAME_LEN) {
				strncpy_s(&item.name[1], NELEMS(item.name) - 1, info[i].longname, MAX_ITEM_NAME_LEN - 5);
				item.name[MAX_ITEM_NAME_LEN - 4] = item.name[MAX_ITEM_NAME_LEN - 3] = item.name[MAX_ITEM_NAME_LEN - 2] = '.';
				item.name[MAX_ITEM_NAME_LEN - 1] = '>';
				item.name[MAX_ITEM_NAME_LEN] = 0;
				item.width = MAX_ITEM_NAME_LEN;
			} else {
				strncpy_s(&item.name[1], NELEMS(item.name) - 1, info[i].longname, MAX_ITEM_NAME_LEN);
				item.name[item.width - 1] = '>';
				item.name[item.width] = 0;
			}
		} else {
			t_fs_filetype ft;

			if (info[i].filesize == 0) {
				win_menuitem_free(&item);
				continue;
			}

			ft = fs_file_get_type(info[i].longname);

			if (!showunknown && ft == fs_filetype_unknown) {
				win_menuitem_free(&item);
				continue;
			}

			item.data = (void *) ft;
			buffer_copy_string(item.shortname, info[i].filename);
			buffer_copy_string(item.compname, info[i].longname);
			filename_to_itemname(&item, info[i].longname);
		}
		item.icolor = icolor;
		item.selicolor = selicolor;
		item.selrcolor = selrcolor;
		item.selbcolor = selbcolor;
		item.selected = false;
		item.data2[0] = info[i].cdate;
		item.data2[1] = info[i].ctime;
		item.data2[2] = info[i].mdate;
		item.data2[3] = info[i].mtime;
		item.data3 = info[i].filesize;
		win_menu_add(g_menu, &item);
	}

	free(info);
	freq_leave(fid);

	return g_menu->size;
}
Esempio n. 13
0
extern u32 fs_flashdir_to_menu(const char *dir, const char *sdir, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor)
{
	int fid;
	SceIoDirent info;
	int fd;
	t_win_menuitem item;

	if (menu_renew(&g_menu) == NULL) {
		return 0;
	}

	fid = freq_enter_hotzone();
	strcpy_s((char *) sdir, 256, dir);
	fd = sceIoDopen(dir);

	if (fd < 0) {
		freq_leave(fid);
		return 0;
	}

	add_parent_to_menu(g_menu, icolor, selicolor, selrcolor, selbcolor);

	memset(&info, 0, sizeof(SceIoDirent));

	while (sceIoDread(fd, &info) > 0) {
		win_menuitem_new(&item);

		if ((info.d_stat.st_mode & FIO_S_IFMT) == FIO_S_IFDIR) {
			if (info.d_name[0] == '.' && info.d_name[1] == 0) {
				win_menuitem_free(&item);
				continue;
			}

			if (strcmp(info.d_name, "..") == 0) {
				win_menuitem_free(&item);
				continue;
			}

			item.data = (void *) fs_filetype_dir;
			buffer_copy_string(item.compname, info.d_name);
			item.name[0] = '<';

			if ((item.width = strlen(info.d_name) + 2) > MAX_ITEM_NAME_LEN) {
				mbcsncpy_s((unsigned char *) &item.name[1], MAX_ITEM_NAME_LEN - 4, (const unsigned char *) info.d_name, -1);
				STRCAT_S(item.name, "...>");
				item.width = MAX_ITEM_NAME_LEN;
			} else {
				mbcsncpy_s((unsigned char *) &item.name[1], MAX_ITEM_NAME_LEN - 1, (const unsigned char *) info.d_name, -1);
				STRCAT_S(item.name, ">");
			}
		} else {
			t_fs_filetype ft = fs_file_get_type(info.d_name);

			item.data = (void *) ft;
			buffer_copy_string(item.compname, info.d_name);
			buffer_copy_string(item.shortname, info.d_name);
			filename_to_itemname(&item, info.d_name);
		}

		item.icolor = icolor;
		item.selicolor = selicolor;
		item.selrcolor = selrcolor;
		item.selbcolor = selbcolor;
		item.selected = false;
		item.data2[0] = ((info.d_stat.st_ctime.year - 1980) << 9) + (info.d_stat.st_ctime.month << 5) + info.d_stat.st_ctime.day;
		item.data2[1] = (info.d_stat.st_ctime.hour << 11) + (info.d_stat.st_ctime.minute << 5) + info.d_stat.st_ctime.second / 2;
		item.data2[2] = ((info.d_stat.st_mtime.year - 1980) << 9) + (info.d_stat.st_mtime.month << 5) + info.d_stat.st_mtime.day;
		item.data2[3] = (info.d_stat.st_mtime.hour << 11) + (info.d_stat.st_mtime.minute << 5) + info.d_stat.st_mtime.second / 2;
		item.data3 = info.d_stat.st_size;

		win_menu_add(g_menu, &item);
	}

	sceIoDclose(fd);
	freq_leave(fid);

	return g_menu->size;
}