diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index c120b37d1a..c3cef6924c 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -10,6 +10,8 @@ 9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 9629797616C3CD2400E6DCE0 /* dirlist.m */; }; 962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */ = {isa = PBXBuildFile; fileRef = 962979EB16C3E86F00E6DCE0 /* gameview.m */; }; 962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; }; + 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; }; + 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -82,6 +84,8 @@ 962979EB16C3E86F00E6DCE0 /* gameview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = gameview.m; sourceTree = ""; }; 962979EC16C3E86F00E6DCE0 /* gameview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameview.h; sourceTree = ""; }; 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = ""; }; + 962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = ""; }; + 962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = ""; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -291,6 +295,8 @@ 96AFAE1A16C1D4EA009DE44C = { isa = PBXGroup; children = ( + 962979F416C43B9500E6DCE0 /* ic_dir.png */, + 962979F516C43B9500E6DCE0 /* ic_file.png */, 96CF014A16C2BA1900ABF9C9 /* libretro.dylib */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, @@ -716,6 +722,8 @@ 96AFAE4E16C1D4EA009DE44C /* ViewController_iPhone.xib in Resources */, 96AFAE5116C1D4EA009DE44C /* ViewController_iPad.xib in Resources */, 96CF014F16C2BB9E00ABF9C9 /* libretro.dylib in Resources */, + 962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */, + 962979F716C43B9500E6DCE0 /* ic_file.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/RetroArch/dirlist.m b/ios/RetroArch/dirlist.m index 024bda1ebe..759df1eee5 100644 --- a/ios/RetroArch/dirlist.m +++ b/ios/RetroArch/dirlist.m @@ -12,74 +12,74 @@ struct dirent_list { - struct dirent_list* next; - struct dirent entry; + size_t count; + struct dirent* entries; }; const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index) { - while (list && index) - { - list = list->next; - index --; - } - - return list ? &list->entry : 0; + if (!list) return 0; + return (index < list->count) ? &list->entries[index] : 0; } unsigned get_dirent_list_count(struct dirent_list* list) { - unsigned result = 0; - - while (list) - { - result ++; - list = list->next; - } - - return result; + return list ? list->count : 0; } void free_dirent_list(struct dirent_list* list) { - struct dirent_list* next = list ? list : 0; + if (list) free(list->entries); + free(list); +} + +static int compare_dirent(const void *left, const void *right) +{ + const struct dirent* l = (const struct dirent*) left; + const struct dirent* r = (const struct dirent*) right; - while (next) + // Directories first + if ((l->d_type & DT_DIR) != (r->d_type & DT_DIR)) { - struct dirent_list* me = next; - next = next->next; - free(me); + return (l->d_type & DT_DIR) ? -1 : 1; } + + // Name + return strcmp(l->d_name, r->d_name); } struct dirent_list* build_dirent_list(const char* path) { struct dirent_list* result = 0; - struct dirent_list* iterate = 0; DIR* dir = opendir(path); if (dir) - { + { struct dirent* ent = 0; + + // Count the number of items + size_t count = 0; while ((ent = readdir(dir))) { - if (!iterate) - { - iterate = malloc(sizeof(struct dirent_list)); - iterate->next = 0; - result = iterate; - } - else - { - iterate->next = malloc(sizeof(struct dirent_list)); - iterate = iterate->next; - iterate->next = 0; - } - - memcpy(&iterate->entry, ent, sizeof(struct dirent)); + count += (strcmp(ent->d_name, ".") ? 1 : 0); } + rewinddir(dir); + + // Build and fill the result + result = malloc(sizeof(struct dirent_list)); + result->count = count; + result->entries = malloc(sizeof(struct dirent) * count); + size_t index = 0; + while ((ent = readdir(dir))) + { + if (strcmp(ent->d_name, ".") == 0) continue; + memcpy(&result->entries[index ++], ent, sizeof(struct dirent)); + } + closedir(dir); + + qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent); } return result; @@ -90,6 +90,9 @@ struct dirent_list* build_dirent_list(const char* path) char path[4096]; UITableView* table; struct dirent_list* files; + + UIImage* file_icon; + UIImage* folder_icon; }; -(void)dealloc @@ -100,6 +103,9 @@ struct dirent_list* build_dirent_list(const char* path) - (void)viewDidLoad { + file_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_file" ofType:@"png"]]; + folder_icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"ic_dir" ofType:@"png"]]; + [super viewDidLoad]; strcpy(path, "/"); @@ -158,7 +164,19 @@ struct dirent_list* build_dirent_list(const char* path) if (item) { cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name]; - cell.accessoryType = (item->d_type & DT_DIR) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; + + if (item->d_type & DT_DIR) + { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + cell.imageView.image = folder_icon; + } + else + { + cell.accessoryType = UITableViewCellAccessoryNone; + cell.imageView.image = file_icon; + } + + [cell.imageView sizeToFit]; } return cell;