mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 22:13:51 +00:00
ios: Don't use performSelector to schedule every frame, the rarch_iterate method runs the UI loop internally; Split dirent_list code out of dirlist.m.
This commit is contained in:
parent
80c0d35f58
commit
33d57ee3a0
@ -12,6 +12,7 @@
|
||||
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 */; };
|
||||
96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; };
|
||||
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 */; };
|
||||
@ -86,6 +87,8 @@
|
||||
962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = "<group>"; };
|
||||
962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = "<group>"; };
|
||||
962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = "<group>"; };
|
||||
962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = "<group>"; };
|
||||
96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = "<group>"; };
|
||||
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; };
|
||||
@ -330,6 +333,8 @@
|
||||
96AFAE3316C1D4EA009DE44C /* RetroArch */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
962979FF16C4767F00E6DCE0 /* dirent_list.c */,
|
||||
96297A0016C4767F00E6DCE0 /* dirent_list.h */,
|
||||
962979EB16C3E86F00E6DCE0 /* gameview.m */,
|
||||
962979EC16C3E86F00E6DCE0 /* gameview.h */,
|
||||
96AFAE3C16C1D4EA009DE44C /* AppDelegate.h */,
|
||||
@ -787,6 +792,7 @@
|
||||
9629797716C3CD2400E6DCE0 /* dirlist.m in Sources */,
|
||||
962979ED16C3E86F00E6DCE0 /* gameview.m in Sources */,
|
||||
962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */,
|
||||
96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
97
ios/RetroArch/dirent_list.c
Normal file
97
ios/RetroArch/dirent_list.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "general.h"
|
||||
#include "dirent_list.h"
|
||||
|
||||
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;
|
||||
|
||||
// Directories first
|
||||
if (l->d_type != r->d_type)
|
||||
return (l->d_type) ? -1 : 1;
|
||||
|
||||
// Name
|
||||
return strcmp(l->d_name, r->d_name);
|
||||
}
|
||||
|
||||
static bool is_dirent_verboten(const struct dirent* entry)
|
||||
{
|
||||
if (!entry) return true;
|
||||
if (strcmp(entry->d_name, ".") == 0) return true;
|
||||
//if (strcmp(entry->d_name, "..") == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dirent_list* build_dirent_list(const char* path)
|
||||
{
|
||||
struct dirent_list* result = 0;
|
||||
|
||||
DIR* dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent* ent = 0;
|
||||
|
||||
// Count the number of items
|
||||
size_t count = 0;
|
||||
while ((ent = readdir(dir)))
|
||||
{
|
||||
count += is_dirent_verboten(ent) ? 0 : 1;
|
||||
}
|
||||
rewinddir(dir);
|
||||
|
||||
// String buffer for 'stat'ing
|
||||
char* stat_path = malloc(strlen(path) + sizeof(ent->d_name));
|
||||
strcpy(stat_path, path);
|
||||
uint32_t last_index = strlen(stat_path);
|
||||
|
||||
// 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 (is_dirent_verboten(ent)) continue;
|
||||
memcpy(&result->entries[index], ent, sizeof(struct dirent));
|
||||
|
||||
// Chage dirent.d_type to a boolean indication if it is a directory
|
||||
struct stat stat_buf;
|
||||
strcat(strcat(stat_path, "/"), ent->d_name);
|
||||
stat(stat_path, &stat_buf);
|
||||
result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0;
|
||||
stat_path[last_index] = 0;
|
||||
|
||||
index ++;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
free(stat_path);
|
||||
|
||||
qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void free_dirent_list(struct dirent_list* list)
|
||||
{
|
||||
if (list) free(list->entries);
|
||||
free(list);
|
||||
}
|
||||
|
||||
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index)
|
||||
{
|
||||
if (!list) return 0;
|
||||
return (index < list->count) ? &list->entries[index] : 0;
|
||||
}
|
||||
|
||||
unsigned get_dirent_list_count(struct dirent_list* list)
|
||||
{
|
||||
return list ? list->count : 0;
|
||||
}
|
||||
|
33
ios/RetroArch/dirent_list.h
Normal file
33
ios/RetroArch/dirent_list.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_IOS_DIRENT_LIST_H
|
||||
#define __RARCH_IOS_DIRENT_LIST_H
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
struct dirent_list
|
||||
{
|
||||
size_t count;
|
||||
struct dirent* entries;
|
||||
};
|
||||
|
||||
struct dirent_list* build_dirent_list(const char* path);
|
||||
void free_dirent_list(struct dirent_list* list);
|
||||
|
||||
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index);
|
||||
unsigned get_dirent_list_count(struct dirent_list* list);
|
||||
|
||||
#endif
|
@ -6,100 +6,10 @@
|
||||
// Copyright (c) 2013 RetroArch. All rights reserved.
|
||||
//
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include "dirent_list.h"
|
||||
#import "dirlist.h"
|
||||
#import "gameview.h"
|
||||
|
||||
struct dirent_list
|
||||
{
|
||||
size_t count;
|
||||
struct dirent* entries;
|
||||
};
|
||||
|
||||
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index)
|
||||
{
|
||||
if (!list) return 0;
|
||||
return (index < list->count) ? &list->entries[index] : 0;
|
||||
}
|
||||
|
||||
unsigned get_dirent_list_count(struct dirent_list* list)
|
||||
{
|
||||
return list ? list->count : 0;
|
||||
}
|
||||
|
||||
void free_dirent_list(struct dirent_list* list)
|
||||
{
|
||||
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;
|
||||
|
||||
// Directories first
|
||||
if (l->d_type != r->d_type)
|
||||
return (l->d_type) ? -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;
|
||||
|
||||
DIR* dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent* ent = 0;
|
||||
|
||||
// Count the number of items
|
||||
size_t count = 0;
|
||||
while ((ent = readdir(dir)))
|
||||
{
|
||||
count += (strcmp(ent->d_name, ".") ? 1 : 0);
|
||||
}
|
||||
rewinddir(dir);
|
||||
|
||||
// String buffer for 'stat'ing
|
||||
char* stat_path = malloc(strlen(path) + sizeof(ent->d_name));
|
||||
strcpy(stat_path, path);
|
||||
uint32_t last_index = strlen(stat_path);
|
||||
|
||||
// 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));
|
||||
|
||||
// Chage dirent.d_type to a boolean indication if it is a directory
|
||||
struct stat stat_buf;
|
||||
strcat(stat_path, "/");
|
||||
strcat(stat_path, ent->d_name);
|
||||
stat(stat_path, &stat_buf);
|
||||
result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0;
|
||||
stat_path[last_index] = 0;
|
||||
|
||||
index ++;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
free(stat_path);
|
||||
|
||||
qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@implementation dirlist_view
|
||||
{
|
||||
char path[4096];
|
||||
@ -146,7 +56,6 @@ struct dirent_list* build_dirent_list(const char* path)
|
||||
char* last_slash = strrchr(path, '/');
|
||||
if (last_slash) *last_slash = 0;
|
||||
path[0] = (path[0] == 0) ? '/' : path[0];
|
||||
printf("%s\n", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -170,7 +79,7 @@ struct dirent_list* build_dirent_list(const char* path)
|
||||
strcat(path, "/");
|
||||
strcat(path, item->d_name);
|
||||
|
||||
extern void ios_load_game(const char*);
|
||||
extern void ios_run_game(const char*);
|
||||
ios_load_game(path);
|
||||
}
|
||||
}
|
||||
|
@ -23,23 +23,63 @@ static float screen_scale;
|
||||
static bool ra_initialized = false;
|
||||
static bool ra_done = false;
|
||||
|
||||
void ios_load_game(const char* file_name)
|
||||
{
|
||||
if(!ra_initialized && file_name)
|
||||
{
|
||||
const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String];
|
||||
const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String];
|
||||
|
||||
strcpy(g_settings.input.overlay, overlay ? overlay : "");
|
||||
|
||||
const char* argv[] = {"retroarch", "-L", libretro, file_name, 0};
|
||||
if (rarch_main_init(6, (char**)argv) == 0)
|
||||
{
|
||||
rarch_init_msg_queue();
|
||||
ra_initialized = TRUE;
|
||||
|
||||
[current_view performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.2f];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ios_close_game()
|
||||
{
|
||||
if (ra_initialized)
|
||||
{
|
||||
rarch_main_deinit();
|
||||
rarch_deinit_msg_queue();
|
||||
|
||||
#ifdef PERF_TEST
|
||||
rarch_perf_log();
|
||||
#endif
|
||||
|
||||
rarch_main_clear_state();
|
||||
|
||||
ra_done = true;
|
||||
}
|
||||
|
||||
ra_initialized = false;
|
||||
}
|
||||
|
||||
@implementation game_view
|
||||
{
|
||||
EAGLContext *gl_context;
|
||||
}
|
||||
|
||||
- (void)schedule_iterate
|
||||
{
|
||||
if (ra_initialized && !ra_done)
|
||||
[self performSelector:@selector(rarch_iterate:) withObject:nil afterDelay:0.002f];
|
||||
}
|
||||
|
||||
- (void)rarch_iterate:(id)sender
|
||||
{
|
||||
if (ra_initialized && !ra_done)
|
||||
ra_done = !rarch_main_iterate();
|
||||
|
||||
[self schedule_iterate];
|
||||
{
|
||||
while (!ra_done && rarch_main_iterate())
|
||||
{
|
||||
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource);
|
||||
}
|
||||
|
||||
ios_close_game();
|
||||
|
||||
ra_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
@ -83,42 +123,3 @@ void get_game_view_size(unsigned *width, unsigned *height)
|
||||
*height = gl_view.bounds.size.height * screen_scale;
|
||||
}
|
||||
}
|
||||
|
||||
void ios_close_game()
|
||||
{
|
||||
if (ra_initialized)
|
||||
{
|
||||
rarch_main_deinit();
|
||||
rarch_deinit_msg_queue();
|
||||
|
||||
#ifdef PERF_TEST
|
||||
rarch_perf_log();
|
||||
#endif
|
||||
|
||||
rarch_main_clear_state();
|
||||
|
||||
ra_done = true;
|
||||
}
|
||||
|
||||
ra_initialized = false;
|
||||
}
|
||||
|
||||
void ios_load_game(const char* file_name)
|
||||
{
|
||||
if(!ra_initialized && file_name)
|
||||
{
|
||||
const char* libretro = [[[NSBundle mainBundle] pathForResource:@"libretro" ofType:@"dylib"] UTF8String];
|
||||
const char* overlay = [[[NSBundle mainBundle] pathForResource:@"overlay" ofType:@"cfg"] UTF8String];
|
||||
|
||||
strcpy(g_settings.input.overlay, overlay ? overlay : "");
|
||||
|
||||
const char* argv[] = {"retroarch", "-L", libretro, file_name, 0};
|
||||
if (rarch_main_init(6, (char**)argv) == 0)
|
||||
{
|
||||
rarch_init_msg_queue();
|
||||
ra_initialized = TRUE;
|
||||
|
||||
if (current_view) [current_view schedule_iterate];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user