diff --git a/Makefile.common b/Makefile.common
index e8567377ab..a32e4819a0 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -93,6 +93,7 @@ OBJ += frontend/frontend.o \
file_path.o \
hash.o \
driver.o \
+ general.o \
settings.o \
settings_data.o \
dynamic.o \
@@ -254,7 +255,9 @@ ifeq ($(HAVE_GLUI), 1)
DEFINES += -DHAVE_GLUI
endif
ifeq ($(HAVE_LAKKA), 1)
- OBJ += frontend/menu/backend/menu_lakka_backend.o frontend/menu/disp/lakka.o
+ OBJ += frontend/menu/backend/menu_lakka_backend.o \
+ frontend/menu/disp/lakka.o \
+ frontend/menu/disp/tween.o
DEFINES += -DHAVE_LAKKA
endif
endif
diff --git a/apple/common/RAGameView.m b/apple/common/RAGameView.m
index 6b24f09cb3..4e1e1824b8 100644
--- a/apple/common/RAGameView.m
+++ b/apple/common/RAGameView.m
@@ -14,6 +14,7 @@
* If not, see .
*/
+#import
#import "RetroArch_Apple.h"
#include "../../general.h"
@@ -198,6 +199,11 @@ static GLContextClass* g_context;
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskLandscapeLeft);
case UIInterfaceOrientationLandscapeRight:
return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskLandscapeRight);
+
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
+ case UIInterfaceOrientationUnknown:
+ return (apple_frontend_settings.orientation_flags & UIInterfaceOrientationMaskAll);
+#endif
}
return YES;
diff --git a/apple/common/contentview_camera_ios.m.inl b/apple/common/contentview_camera_ios.m.inl
index 7429189483..068afe2cb8 100644
--- a/apple/common/contentview_camera_ios.m.inl
+++ b/apple/common/contentview_camera_ios.m.inl
@@ -4,6 +4,10 @@ CVOpenGLESTextureCacheRef textureCache;
GLuint outputTexture;
static bool newFrame = false;
+#ifndef GL_BGRA
+#define GL_BGRA 0x80E1
+#endif
+
void event_process_camera_frame(void* pixelBufferPtr)
{
CVOpenGLESTextureRef renderTexture;
diff --git a/apple/common/utility.m b/apple/common/utility.m
index 2ca230d4ee..15003e2612 100644
--- a/apple/common/utility.m
+++ b/apple/common/utility.m
@@ -64,7 +64,7 @@ void apple_display_alert(const char *message, const char *title)
- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error
{
- int i;
+ NSUInteger i;
bool hasDot = false;
if (partialString.length)
diff --git a/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj b/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj
index 7ad77e0196..fda405fa99 100644
--- a/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj
+++ b/apple/iOS/RetroArch_iOS.xcodeproj/project.pbxproj
@@ -505,6 +505,8 @@
"-DRARCH_INTERNAL",
"-DHAVE_THREADS",
"-DHAVE_FILTERS_BUILTIN",
+ "-DHAVE_LAKKA",
+ "-DHAVE_GLUI",
);
PRODUCT_NAME = "$(TARGET_NAME)";
VALID_ARCHS = "armv7 armv7s";
@@ -558,6 +560,8 @@
"-DHAVE_THREADS",
"-DHAVE_FILTERS_BUILTIN",
"-DHAVE_7ZIP",
+ "-DHAVE_LAKKA",
+ "-DHAVE_GLUI",
);
"OTHER_CFLAGS[arch=*]" = (
"-DNS_BLOCK_ASSERTIONS=1",
@@ -580,14 +584,16 @@
"-DRARCH_MOBILE",
"-DHAVE_COREAUDIO",
"-DHAVE_DYNAMIC",
+ "-DRARCH_INTERNAL",
"-DHAVE_OVERLAY",
"-DHAVE_ZLIB",
"-DWANT_MINIZ",
"-DSINC_LOWER_QUALITY",
- "-DRARCH_INTERNAL",
"-DHAVE_THREADS",
"-DHAVE_FILTERS_BUILTIN",
"-DHAVE_7ZIP",
+ "-DHAVE_LAKKA",
+ "-DHAVE_GLUI",
);
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
diff --git a/apple/iOS/RetroArch_iOS.xcodeproj/project.xcworkspace/xcshareddata/RetroArch_iOS.xccheckout b/apple/iOS/RetroArch_iOS.xcodeproj/project.xcworkspace/xcshareddata/RetroArch_iOS.xccheckout
index 2bc51df130..96f4777dbe 100644
--- a/apple/iOS/RetroArch_iOS.xcodeproj/project.xcworkspace/xcshareddata/RetroArch_iOS.xccheckout
+++ b/apple/iOS/RetroArch_iOS.xcodeproj/project.xcworkspace/xcshareddata/RetroArch_iOS.xccheckout
@@ -12,7 +12,9 @@
49FCA0A2-0FE0-4A7A-9C54-642C68ED726A
git://github.com/libretro/common-overlays.git
- A5B07A9E-AFED-41CB-BE4B-7C0CDBC26E8C
+ 76200F0D6584D865E96F58DE862E738E88B23A3C
+ https://github.com/libretro/libretro-super.git
+ C7C12374C7051F8843B3EFA1ACCAF2907102CCF7
https://github.com/libretro/RetroArch.git
IDESourceControlProjectPath
@@ -21,17 +23,27 @@
49FCA0A2-0FE0-4A7A-9C54-642C68ED726A
../../../media/overlays
- A5B07A9E-AFED-41CB-BE4B-7C0CDBC26E8C
+ 76200F0D6584D865E96F58DE862E738E88B23A3C
+ ../../../..
+ C7C12374C7051F8843B3EFA1ACCAF2907102CCF7
../../..
IDESourceControlProjectURL
https://github.com/libretro/RetroArch.git
IDESourceControlProjectVersion
- 110
+ 111
IDESourceControlProjectWCCIdentifier
- A5B07A9E-AFED-41CB-BE4B-7C0CDBC26E8C
+ C7C12374C7051F8843B3EFA1ACCAF2907102CCF7
IDESourceControlProjectWCConfigurations
+
+ IDESourceControlRepositoryExtensionIdentifierKey
+ public.vcs.git
+ IDESourceControlWCCIdentifierKey
+ 76200F0D6584D865E96F58DE862E738E88B23A3C
+ IDESourceControlWCCName
+
+
IDESourceControlRepositoryExtensionIdentifierKey
public.vcs.git
@@ -44,7 +56,7 @@
IDESourceControlRepositoryExtensionIdentifierKey
public.vcs.git
IDESourceControlWCCIdentifierKey
- A5B07A9E-AFED-41CB-BE4B-7C0CDBC26E8C
+ C7C12374C7051F8843B3EFA1ACCAF2907102CCF7
IDESourceControlWCCName
retroarch
diff --git a/apple/iOS/browser.m b/apple/iOS/browser.m
index 94c3034e61..bde80cea4c 100644
--- a/apple/iOS/browser.m
+++ b/apple/iOS/browser.m
@@ -46,9 +46,9 @@ static bool zlib_extract_callback(const char *name,
// Ignore directories
if (name[strlen(name) - 1] == '/')
return true;
-
+
fill_pathname_join(path, (const char*)userdata, name, sizeof(path));
-
+
switch (cmode)
{
case 0: // Uncompressed
@@ -80,7 +80,7 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
NSError* error = nil;
bool result = false;
NSFileManager* manager = [NSFileManager defaultManager];
-
+
switch (action)
{
case FA_DELETE:
@@ -123,16 +123,16 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
{
static NSString* const cell_id = @"path_item";
static NSString* const icon_types[2] = { @"ic_file", @"ic_dir" };
-
+
uint32_t type_id = self.isDirectory ? 1 : 0;
-
+
UITableViewCell* result = [tableView dequeueReusableCellWithIdentifier:cell_id];
if (!result)
result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_id];
result.textLabel.text = [self.path lastPathComponent];
result.imageView.image = [UIImage imageNamed:icon_types[type_id]];
-
+
return result;
}
@@ -152,21 +152,17 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
{
if ((self = [super initWithStyle:UITableViewStylePlain]))
{
- _path = path ? path : NSHomeDirectory();
- _chooseAction = action;
- _extensions = extensions ? BOXSTRING(extensions) : 0;
-
- self = [super initWithStyle:UITableViewStylePlain];
+ self.path = path ? path : NSHomeDirectory();
+ self.chooseAction = action;
+ self.extensions = extensions ? BOXSTRING(extensions) : 0;
self.hidesHeaders = YES;
-
+
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Up" style:UIBarButtonItemStyleBordered target:self
action:@selector(gotoParent)];
-
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self
action:@selector(cancelBrowser)];
-
// NOTE: The "App" and "Root" buttons aren't really needed for non-jailbreak devices.
NSMutableArray* toolbarButtons = [NSMutableArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStyleBordered target:self
@@ -183,12 +179,11 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
action:@selector(createNewFolder)],
nil
];
-
+
self.toolbarItems = toolbarButtons;
[self.tableView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(fileAction:)]];
-
}
return self;
@@ -201,7 +196,7 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
- (void)gotoParent
{
- [self browseTo:[_path stringByDeletingLastPathComponent]];
+ [self browseTo:[self.path stringByDeletingLastPathComponent]];
}
- (void)gotoHomeDir
@@ -221,27 +216,27 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
- (void)refresh
{
- [self browseTo:_path];
+ [self browseTo: self.path];
}
- (void)browseTo:(NSString*)path
{
- _path = path;
- self.title = _path.lastPathComponent;
+ self.path = path;
+ self.title = self.path.lastPathComponent;
// Need one array per section
self.sections = [NSMutableArray array];
-
+
for (NSString* i in [self sectionIndexTitlesForTableView:self.tableView])
[self.sections addObject:[NSMutableArray arrayWithObject:i]];
-
+
// List contents
- struct string_list* contents = dir_list_new(_path.UTF8String, _extensions.UTF8String, true);
-
+ struct string_list* contents = dir_list_new(self.path.UTF8String, self.extensions.UTF8String, true);
+
if (contents)
{
RADirectoryList __weak* weakSelf = self;
-
+
if (self.allowBlank)
[self.sections[0] addObject:[RAMenuItemBasic itemWithDescription:@"[ Use Empty Path ]"
action:^{ weakSelf.chooseAction(weakSelf, nil); }]];
@@ -250,17 +245,17 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
action:^{ weakSelf.chooseAction(weakSelf, [RADirectoryItem directoryItemFromPath:path]); }]];
dir_list_sort(contents, true);
-
- for (int i = 0; i < contents->size; i ++)
+
+ for (size_t i = 0; i < contents->size; i ++)
{
const char* basename = path_basename(contents->elems[i].data);
-
+
uint32_t section = isalpha(basename[0]) ? (toupper(basename[0]) - 'A') + 2 : 1;
section = (contents->elems[i].attr.i == RARCH_DIRECTORY) ? 0 : section;
[self.sections[section] addObject:[RADirectoryItem directoryItemFromElement:&contents->elems[i]]];
}
-
+
dir_list_free(contents);
}
else
@@ -280,7 +275,7 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
- [self browseTo:_path];
+ [self browseTo: self.path];
}
- (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView
@@ -312,7 +307,7 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
{
CGPoint point = [gesture locationInView:self.tableView];
NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:point];
-
+
if (indexPath)
{
self.selectedItem = [self itemForIndexPath:indexPath];
@@ -320,7 +315,7 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
NSString* button4_name = (IOS_IS_VERSION_7_OR_HIGHER()) ? @"AirDrop" : @"Delete";
NSString* button5_name = (IOS_IS_VERSION_7_OR_HIGHER()) ? @"Delete" : nil;
-
+
UIActionSheet* menu = [[UIActionSheet alloc] initWithTitle:self.selectedItem.path.lastPathComponent delegate:self
cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil
otherButtonTitles:is_zip ? @"Unzip" : @"Zip", @"Move", @"Rename", button4_name, button5_name, nil];
@@ -335,7 +330,7 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
{
NSString* target = self.selectedItem.path;
NSString* action = [actionSheet buttonTitleAtIndex:buttonIndex];
-
+
if ([action isEqualToString:@"Unzip"])
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Enter target directory" message:@"" delegate:self
@@ -360,11 +355,11 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
else if ([action isEqualToString:@"AirDrop"] && IOS_IS_VERSION_7_OR_HIGHER())
{
// TODO: Zip if not already zipped
-
+
NSURL* url = [NSURL fileURLWithPath:self.selectedItem.path isDirectory:self.selectedItem.isDirectory];
NSArray* items = [NSArray arrayWithObject:url];
UIActivityViewController* avc = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
-
+
[self presentViewController:avc animated:YES completion:nil];
}
#endif
@@ -392,10 +387,10 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
NSString* text = [alertView textFieldAtIndex:0].text;
if (text.length)
- file_action((enum file_action)alertView.tag, self.selectedItem.path, [_path stringByAppendingPathComponent:text]);
+ file_action((enum file_action)alertView.tag, self.selectedItem.path, [self.path stringByAppendingPathComponent:text]);
}
- [self browseTo:_path];
+ [self browseTo: self.path];
}
@end
@@ -411,23 +406,23 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
if ((self = [super initWithStyle:UITableViewStyleGrouped]))
{
RAFoldersList* __weak weakSelf = self;
- _path = path;
+ self.path = path;
// Parent item
- NSString* sourceItem = _path.stringByDeletingLastPathComponent;
-
+ NSString* sourceItem = self.path.stringByDeletingLastPathComponent;
+
RAMenuItemBasic* parentItem = [RAMenuItemBasic itemWithDescription:BOXSTRING("") association:sourceItem.stringByDeletingLastPathComponent
action:^(id userdata){ [weakSelf moveInto:userdata]; } detail:NULL];
[self.sections addObject:@[BOXSTRING(""), parentItem]];
// List contents
- struct string_list* contents = dir_list_new([_path stringByDeletingLastPathComponent].UTF8String, 0, true);
+ struct string_list* contents = dir_list_new([self.path stringByDeletingLastPathComponent].UTF8String, 0, true);
NSMutableArray* items = [NSMutableArray arrayWithObject:BOXSTRING("")];
-
+
if (contents)
{
- int i;
+ size_t i;
dir_list_sort(contents, true);
for (i = 0; i < contents->size; i ++)
@@ -435,18 +430,18 @@ static void file_action(enum file_action action, NSString* source, NSString* tar
if (contents->elems[i].attr.i == RARCH_DIRECTORY)
{
const char* basename = path_basename(contents->elems[i].data);
-
+
RAMenuItemBasic* item = [RAMenuItemBasic itemWithDescription:BOXSTRING(basename) association:BOXSTRING(contents->elems[i].data)
action:^(id userdata){ [weakSelf moveInto:userdata]; } detail:NULL];
[items addObject:item];
}
}
-
+
dir_list_free(contents);
}
- [self setTitle:[BOXSTRING("Move ") stringByAppendingString:_path.lastPathComponent]];
-
+ [self setTitle:[BOXSTRING("Move ") stringByAppendingString: self.path.lastPathComponent]];
+
[self.sections addObject:items];
}
diff --git a/apple/iOS/menu.m b/apple/iOS/menu.m
index 3baff5d374..3f2e8cf09d 100644
--- a/apple/iOS/menu.m
+++ b/apple/iOS/menu.m
@@ -52,7 +52,7 @@ typedef void (^RAActionSheetCallback)(UIActionSheet*, NSInteger);
static void RunActionSheet(const char* title, const struct string_list* items, UIView* parent, RAActionSheetCallback callback)
{
- int i;
+ size_t i;
RARunActionSheetDelegate* delegate = [[RARunActionSheetDelegate alloc] initWithCallbackBlock:callback];
UIActionSheet* actionSheet = [UIActionSheet new];
@@ -134,6 +134,10 @@ static void RunActionSheet(const char* title, const struct string_list* items, U
/* selected. */
/*********************************************/
@implementation RAMenuItemBasic
+@synthesize description;
+@synthesize userdata;
+@synthesize action;
+@synthesize detail;
+ (RAMenuItemBasic*)itemWithDescription:(NSString*)description action:(void (^)())action
{
@@ -653,15 +657,15 @@ static void RunActionSheet(const char* title, const struct string_list* items, U
- (void)dealloc
{
- if (_history)
- content_playlist_free(_history);
+ if (self.history)
+ content_playlist_free(self.history);
}
- (id)initWithHistoryPath:(const char*)historyPath
{
if ((self = [super initWithStyle:UITableViewStylePlain]))
{
- _history = content_playlist_init(historyPath, 100);
+ self.history = content_playlist_init(historyPath, 100);
[self reloadData];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:BOXSTRING("Clear History")
style:UIBarButtonItemStyleBordered target:self action:@selector(clearHistory)];
@@ -672,18 +676,18 @@ static void RunActionSheet(const char* title, const struct string_list* items, U
- (void)clearHistory
{
- if (_history)
- content_playlist_clear(_history);
+ if (self.history)
+ content_playlist_clear(self.history);
[self reloadData];
}
- (void)willReloadData
{
- int i;
+ size_t i;
RAHistoryMenu* __weak weakSelf = self;
NSMutableArray *section = [NSMutableArray arrayWithObject:BOXSTRING("")];
- for (i = 0; _history && i < content_playlist_size(_history); i ++)
+ for (i = 0; self.history && i < content_playlist_size(self.history); i ++)
{
RAMenuItemBasic *item;
const char *path = NULL;
@@ -903,7 +907,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U
- (void)willReloadData
{
- int i;
+ size_t i;
const core_info_list_t* core_list;
RAFrontendSettingsMenu* __weak weakSelf = self;
NSMutableArray* cores = (NSMutableArray*)self.coreConfigOptions;
@@ -1151,7 +1155,7 @@ static bool copy_config(const char *src_path, const char *dst_path)
self.actionRan = true;
if (self.action)
- _action(coreID);
+ self.action(coreID);
}
- (void)load:(uint32_t)count coresFromList:(const core_info_t*)list toSection:(NSMutableArray*)array
diff --git a/apple/iOS/platform.h b/apple/iOS/platform.h
index 0bf7845ef6..7479e3c2b4 100644
--- a/apple/iOS/platform.h
+++ b/apple/iOS/platform.h
@@ -37,6 +37,9 @@ const void* apple_get_frontend_settings(void);
@interface RetroArch_iOS : UINavigationController
+@property (nonatomic) UIWindow* window;
+@property (nonatomic) NSString* documentsDirectory; // e.g. /var/mobile/Documents
+
+ (RetroArch_iOS*)get;
- (void)showGameView;
@@ -45,9 +48,6 @@ const void* apple_get_frontend_settings(void);
- (void)unloadingCore;
- (void)refreshSystemConfig;
-
-@property (nonatomic) NSString* documentsDirectory; // e.g. /var/mobile/Documents
-
@end
// modes are: keyboard, icade and btstack
diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m
index b94a801cfb..1d0cd4dd28 100644
--- a/apple/iOS/platform.m
+++ b/apple/iOS/platform.m
@@ -73,7 +73,7 @@ const void* apple_get_frontend_settings(void)
// Input helpers: This is kept here because it needs objective-c
static void handle_touch_event(NSArray* touches)
{
- int i;
+ NSUInteger i;
const float scale = [[UIScreen mainScreen] scale];
g_current_input_data.touch_count = 0;
@@ -105,7 +105,7 @@ static void handle_touch_event(NSArray* touches)
@end
@interface UIApplication(iOS7Keyboard)
-- (id)_keyCommandForEvent:(id)event;
+- (id)_keyCommandForEvent:(UIEvent*)event;
@end
@interface RApplication : UIApplication
@@ -116,7 +116,7 @@ static void handle_touch_event(NSArray* touches)
// Keyboard handler for iOS 7
- (id)_keyCommandForEvent:(UIEvent*)event
{
- int i;
+ NSUInteger i;
// This gets called twice with the same timestamp for each keypress, that's fine for polling
// but is bad for business with events.
static double last_time_stamp;
@@ -165,10 +165,6 @@ static void handle_touch_event(NSArray* touches)
@end
@implementation RetroArch_iOS
-{
- UIWindow* _window;
- NSString* _path;
-}
+ (RetroArch_iOS*)get
{
@@ -185,9 +181,9 @@ static void handle_touch_event(NSArray* touches)
[self setDelegate:self];
// Setup window
- _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self showPauseMenu:self];
- [_window makeKeyAndVisible];
+ [self.window makeKeyAndVisible];
// Build system paths and test permissions
self.documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
@@ -278,7 +274,7 @@ static void handle_touch_event(NSArray* touches)
[self setToolbarHidden:true animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:true withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setIdleTimerDisabled:true];
- [_window setRootViewController:[RAGameView get]];
+ [self.window setRootViewController:[RAGameView get]];
g_extern.is_paused = false;
}
@@ -287,7 +283,7 @@ static void handle_touch_event(NSArray* touches)
g_extern.is_paused = true;
[[UIApplication sharedApplication] setStatusBarHidden:false withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setIdleTimerDisabled:false];
- [_window setRootViewController:self];
+ [self.window setRootViewController:self];
}
- (void)loadingCore:(NSString*)core withFile:(const char*)file
diff --git a/conf/config_file.c b/conf/config_file.c
index 232938510b..323f619250 100644
--- a/conf/config_file.c
+++ b/conf/config_file.c
@@ -84,15 +84,13 @@ static char *getaline(FILE *file)
cur_size *= 2;
newline_tmp = (char*)realloc(newline, cur_size + 1);
- if (newline_tmp)
- {
- newline = newline_tmp;
- }
- else
+ if (!newline_tmp)
{
free(newline);
return NULL;
}
+
+ newline = newline_tmp;
}
newline[index++] = in;
@@ -174,7 +172,9 @@ static void add_child_list(config_file_t *parent, config_file_t *child)
/* Rebase tail. */
if (parent->entries)
{
- struct config_entry_list *head = parent->entries;
+ struct config_entry_list *head =
+ (struct config_entry_list*)parent->entries;
+
while (head->next)
head = head->next;
parent->tail = head;
@@ -329,15 +329,13 @@ static bool parse_line(config_file_t *conf,
cur_size *= 2;
key_tmp = (char*)realloc(key, cur_size + 1);
- if (key_tmp)
- {
- key = key_tmp;
- }
- else
+ if (!key_tmp)
{
free(key);
return false;
}
+
+ key = key_tmp;
}
key[index++] = *line++;
diff --git a/driver.c b/driver.c
index b2d73fd4fb..c69246c8d8 100644
--- a/driver.c
+++ b/driver.c
@@ -638,7 +638,8 @@ static void find_video_driver(void)
}
#endif
- if (driver.frontend_ctx->get_video_driver)
+ if (driver.frontend_ctx &&
+ driver.frontend_ctx->get_video_driver)
{
driver.video = driver.frontend_ctx->get_video_driver();
diff --git a/driver.h b/driver.h
index e27cbae24a..db451704d2 100644
--- a/driver.h
+++ b/driver.h
@@ -624,9 +624,9 @@ extern video_driver_t video_xdk_d3d;
extern video_driver_t video_sdl;
extern video_driver_t video_sdl2;
extern video_driver_t video_vg;
-extern video_driver_t video_null;
extern video_driver_t video_omap;
extern video_driver_t video_exynos;
+extern video_driver_t video_null;
extern input_driver_t input_android;
extern input_driver_t input_sdl;
@@ -672,14 +672,14 @@ extern menu_ctx_driver_backend_t menu_ctx_backend_lakka;
#define check_oneshot_func(trigger_input) check_oneshot(BIND_PRESSED(trigger_input, RARCH_FRAMEADVANCE), BIND_PRESSED(trigger_input, RARCH_REWIND))
#define check_slowmotion_func(input) check_slowmotion(BIND_PRESSED(input, RARCH_SLOWMOTION))
#define check_shader_dir_func(trigger_input) check_shader_dir(BIND_PRESSED(trigger_input, RARCH_SHADER_NEXT), BIND_PRESSED(trigger_input, RARCH_SHADER_PREV))
-#define check_enter_menu_func(input, old_input) check_enter_menu(BIND_PRESSED(input, RARCH_MENU_TOGGLE), BIND_PRESSED(old_input, RARCH_MENU_TOGGLE))
+#define check_enter_menu_func(input) BIND_PRESSED(input, RARCH_MENU_TOGGLE)
#define check_mute_func(input, old_input) check_mute(BIND_PRESSED(input, RARCH_MUTE), BIND_PRESSED(old_input, RARCH_MUTE))
#define check_volume_func(input, old_input) check_volume(BIND_PRESSED(input, RARCH_VOLUME_UP), BIND_PRESSED(old_input, RARCH_VOLUME_DOWN))
#define check_fullscreen_func(trigger_input) rarch_check_fullscreen(BIND_PRESSED(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY))
#define check_fast_forward_button_func(input, old_input, trigger_input) check_fast_forward_button(BIND_PRESSED(trigger_input, RARCH_FAST_FORWARD_KEY), BIND_PRESSED(input, RARCH_FAST_FORWARD_HOLD_KEY), BIND_PRESSED(old_input, RARCH_FAST_FORWARD_HOLD_KEY))
#define check_rewind_func(input) check_rewind(BIND_PRESSED(input, RARCH_REWIND))
#define check_stateslots_func(trigger_input) check_stateslots(BIND_PRESSED(trigger_input, RARCH_STATE_SLOT_PLUS), BIND_PRESSED(trigger_input, RARCH_STATE_SLOT_MINUS))
-#define check_pause_func(input, old_input) check_pause(BIND_PRESSED(input, RARCH_PAUSE_TOGGLE), BIND_PRESSED(old_input, RARCH_PAUSE_TOGGLE), BIND_PRESSED(input, RARCH_FRAMEADVANCE))
+#define check_pause_func(input) check_pause(BIND_PRESSED(input, RARCH_PAUSE_TOGGLE), BIND_PRESSED(input, RARCH_FRAMEADVANCE))
#define check_quit_key_func(input) BIND_PRESSED(input, RARCH_QUIT_KEY)
#ifdef __cplusplus
diff --git a/dynamic.c b/dynamic.c
index 7d44990284..e36814298f 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -102,6 +102,7 @@ size_t (*pretro_get_memory_size)(unsigned);
#endif
static bool *load_no_content_hook;
+static bool ignore_environment_cb;
static bool environ_cb_get_system_info(unsigned cmd, void *data)
{
@@ -125,6 +126,13 @@ void libretro_get_environment_info(void (*func)(retro_environment_t),
/* load_no_content gets set in this callback. */
func(environ_cb_get_system_info);
+
+ /* It's possible that we just set get_system_info callback to the currently running core.
+ * Make sure we reset it to the actual environment callback.
+ * Ignore any environment callbacks here in case we're running on the non-current core. */
+ ignore_environment_cb = true;
+ func(rarch_environment_cb);
+ ignore_environment_cb = false;
}
static dylib_t libretro_get_system_info_lib(const char *path,
@@ -499,6 +507,9 @@ bool rarch_environment_cb(unsigned cmd, void *data)
{
unsigned p, id;
+ if (ignore_environment_cb)
+ return false;
+
switch (cmd)
{
case RETRO_ENVIRONMENT_GET_OVERSCAN:
@@ -591,6 +602,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
case RETRO_ENVIRONMENT_SHUTDOWN:
RARCH_LOG("Environ SHUTDOWN.\n");
g_extern.system.shutdown = true;
+ g_extern.core_shutdown_initiated = true;
break;
case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
diff --git a/frontend/frontend.c b/frontend/frontend.c
index e2a00b6398..465bff0dd6 100644
--- a/frontend/frontend.c
+++ b/frontend/frontend.c
@@ -55,50 +55,28 @@
#define MAX_ARGS 32
-static retro_keyboard_event_t key_event;
-
-static int main_entry_iterate_shutdown(signature(), args_type() args)
+static int main_entry_iterate_shutdown(signature(),
+ args_type() args)
{
(void)args;
- if (!g_settings.load_dummy_on_core_shutdown)
- return 1;
+ if (g_extern.core_shutdown_initiated
+ && g_settings.load_dummy_on_core_shutdown)
+ {
+ /* Load dummy core instead of exiting RetroArch completely. */
+ rarch_main_command(RARCH_CMD_PREPARE_DUMMY);
+ g_extern.core_shutdown_initiated = false;
+ return 0;
+ }
- /* Load dummy core instead of exiting RetroArch completely. */
- rarch_main_command(RARCH_CMD_PREPARE_DUMMY);
-
- return 0;
+ return 1;
}
int main_entry_decide(signature(), args_type() args)
{
-#ifdef HAVE_MENU
- if (g_extern.system.shutdown)
- return main_entry_iterate_shutdown(signature_expand(), args);
- if (g_extern.lifecycle_state & (1ULL << MODE_CLEAR_INPUT))
- return main_entry_iterate_clear_input(signature_expand(), args);
- if (g_extern.lifecycle_state & (1ULL << MODE_LOAD_GAME))
- return main_entry_iterate_load_content(signature_expand(), args);
- if (g_extern.lifecycle_state & (1ULL << MODE_GAME))
- return main_entry_iterate_content(signature_expand(), args);
- if (g_extern.lifecycle_state & (1ULL << MODE_MENU_PREINIT))
- return main_entry_iterate_menu_preinit(signature_expand(), args);
- if (g_extern.lifecycle_state & (1ULL << MODE_MENU))
- return main_entry_iterate_menu(signature_expand(), args);
-
- return 1;
-#else
- return main_entry_iterate_content_nomenu(signature_expand(), args);
-#endif
-}
-
-int main_entry_iterate_content(signature(), args_type() args)
-{
+ int ret = 0;
if (!rarch_main_iterate())
- {
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING_FINISHED);
- return 0;
- }
+ return main_entry_iterate_shutdown(signature_expand(), args);
if (driver.frontend_ctx && driver.frontend_ctx->process_events)
driver.frontend_ctx->process_events(args);
@@ -106,113 +84,6 @@ int main_entry_iterate_content(signature(), args_type() args)
return 0;
}
-#ifndef HAVE_MENU
-static int main_entry_iterate_content_nomenu(signature(), args_type() args)
-{
- if (!rarch_main_iterate())
- return 1;
-
- return 0;
-}
-#endif
-
-int main_entry_iterate_clear_input(signature(), args_type() args)
-{
- (void)args;
-
- rarch_input_poll();
-#ifdef HAVE_MENU
- if (menu_input())
- return 0;
-#endif
-
- /* Restore libretro keyboard callback. */
- g_extern.system.key_event = key_event;
- rarch_main_set_state(RARCH_ACTION_STATE_FLUSH_INPUT_FINISHED);
-
- return 0;
-}
-
-int main_entry_iterate_load_content(signature(), args_type() args)
-{
-#ifdef HAVE_MENU
- if (!load_menu_content())
- {
- /* If content loading fails, we go back to menu. */
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING_FINISHED);
- if (driver.menu)
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_PREINIT);
- }
-#endif
-
- rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_FINISHED);
-
- return 0;
-}
-
-#ifdef HAVE_MENU
-int main_entry_iterate_menu_preinit(signature(), args_type() args)
-{
- int i;
-
- /* Menu should always run with vsync on. */
- rarch_main_command(RARCH_CMD_VIDEO_SET_BLOCKING_STATE);
-
- /* Stop all rumbling before entering the menu. */
- for (i = 0; i < MAX_PLAYERS; i++)
- {
- driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0);
- driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0);
- }
-
- rarch_main_command(RARCH_CMD_AUDIO_STOP);
-
- if (driver.menu)
- {
- /* Override keyboard callback to redirect to menu instead.
- * We'll use this later for something ...
- * FIXME: This should probably be moved to menu_common somehow. */
- key_event = g_extern.system.key_event;
- g_extern.system.key_event = menu_key_event;
-
- driver.menu->need_refresh = true;
- driver.menu->old_input_state |= 1ULL << RARCH_MENU_TOGGLE;
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_PREINIT_FINISHED);
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING);
- }
-
- return 0;
-}
-
-int main_entry_iterate_menu(signature(), args_type() args)
-{
- retro_input_t input, old_state = 0;
-
- if (menu_iterate())
- {
- if (driver.frontend_ctx && driver.frontend_ctx->process_events)
- driver.frontend_ctx->process_events(args);
- return 0;
- }
-
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
- driver_set_nonblock_state(driver.nonblock_state);
-
- rarch_main_command(RARCH_CMD_AUDIO_START);
- rarch_main_set_state(RARCH_ACTION_STATE_FLUSH_INPUT);
-
- input = input_keys_pressed_func(RARCH_QUIT_KEY, RARCH_QUIT_KEY + 1,
- &old_state);
-
- if (BIND_PRESSED(input, RARCH_QUIT_KEY) ||
- !driver.video->alive(driver.video_data))
- return 1;
-
- return 0;
-}
-#endif
-
-
void main_exit(args_type() args)
{
g_extern.system.shutdown = false;
diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c
index 947202feaf..f9d4386268 100644
--- a/frontend/menu/backend/menu_common_backend.c
+++ b/frontend/menu/backend/menu_common_backend.c
@@ -1970,13 +1970,6 @@ static int menu_common_iterate(unsigned action)
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->set_texture)
driver.menu_ctx->set_texture(driver.menu);
- if (action == MENU_ACTION_TOGGLE &&
- g_extern.main_is_init && !g_extern.libretro_dummy)
- {
- rarch_main_command(RARCH_CMD_RESUME);
- return -1;
- }
-
if (!strcmp(menu_label, "help"))
return menu_start_screen_iterate(action);
else if (!strcmp(menu_label, "message"))
diff --git a/frontend/menu/backend/menu_lakka_backend.c b/frontend/menu/backend/menu_lakka_backend.c
index 1192ef8706..5ff95b972a 100644
--- a/frontend/menu/backend/menu_lakka_backend.c
+++ b/frontend/menu/backend/menu_lakka_backend.c
@@ -35,6 +35,7 @@
#include "../../../settings_data.h"
#include "../disp/lakka.h"
+#include "../disp/tween.h"
#ifdef HAVE_CONFIG_H
#include "../../../config.h"
@@ -514,7 +515,7 @@ static int menu_lakka_iterate(unsigned action)
(active_category->num_items - 1))))
{
add_tween(LAKKA_DELAY, 1.0, &global_alpha, &inOutQuad, NULL);
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING_FINISHED);
+ rarch_main_command(RARCH_CMD_QUIT_RETROARCH);
return -1;
}
break;
diff --git a/frontend/menu/disp/glui.c b/frontend/menu/disp/glui.c
index 6f67405e0a..6de08e7257 100644
--- a/frontend/menu/disp/glui.c
+++ b/frontend/menu/disp/glui.c
@@ -162,9 +162,6 @@ static void glui_frame(void)
if (!driver.menu || !gl)
return;
- if (g_extern.lifecycle_state & (1ULL << MODE_GAME))
- return;
-
line_height = g_settings.video.font_size * 4 / 3;
glyph_width = line_height / 2;
glui_margin = gl->win_width / 20 ;
diff --git a/frontend/menu/disp/lakka.c b/frontend/menu/disp/lakka.c
index be13e34009..6ace776ec7 100644
--- a/frontend/menu/disp/lakka.c
+++ b/frontend/menu/disp/lakka.c
@@ -43,6 +43,7 @@
#include "../../../gfx/fonts/bitmap.h"
#include "lakka.h"
+#include "tween.h"
// Category variables
menu_category_t *categories;
@@ -71,6 +72,7 @@ float above_subitem_offset;
float above_item_offset;
float active_item_factor;
float under_item_offset;
+float setting_margin_left;
// Font variables
static void *font;
@@ -117,9 +119,6 @@ struct lakka_texture_item
struct lakka_texture_item textures[TEXTURE_LAST];
-static tween_t* tweens = NULL;
-static int numtweens = 0;
-
static void lakka_responsive(void)
{
gl_t *gl = (gl_t*)driver_video_resolve(NULL);
@@ -149,6 +148,7 @@ static void lakka_responsive(void)
title_margin_top = 50.0;
label_margin_left = 192;
label_margin_top = 15;
+ setting_margin_left = 1200;
strcpy(icon_dir, "256");
return;
}
@@ -166,6 +166,7 @@ static void lakka_responsive(void)
label_margin_left = 144;
label_margin_top = 11.0;
strcpy(icon_dir, "192");
+ setting_margin_left = 800;
return;
}
@@ -181,6 +182,7 @@ static void lakka_responsive(void)
title_margin_top = 35.0;
label_margin_left = 85;
label_margin_top = 8.0;
+ setting_margin_left = 600;
strcpy(icon_dir, "128");
return;
}
@@ -198,6 +200,7 @@ static void lakka_responsive(void)
label_margin_left = 48;
label_margin_top = 6.0;
strcpy(icon_dir, "64");
+ setting_margin_left = 250;
return;
}
@@ -211,6 +214,7 @@ static void lakka_responsive(void)
title_margin_top = 30.0;
label_margin_left = 64;
label_margin_top = 6.0;
+ setting_margin_left = 400;
strcpy(icon_dir, "96");
}
@@ -249,104 +253,6 @@ static char *str_replace (const char *string, const char *substr, const char *re
return newstr;
}
-float inOutQuad(float t, float b, float c, float d)
-{
- t = t / d * 2;
- if (t < 1)
- return c / 2 * pow(t, 2) + b;
- return -c / 2 * ((t - 1) * (t - 3) - 1) + b;
-}
-
-void add_tween(float duration, float target_value, float* subject,
- easingFunc easing, tweenCallback callback)
-{
- tween_t *tween;
- tween_t *tweens_tmp;
-
- numtweens++;
-
- tweens_tmp = (tween_t*)realloc(tweens, numtweens * sizeof(tween_t));
- if (tweens_tmp != NULL)
- {
- tweens = tweens_tmp;
- }
- else // realloc failed
- {
- if (tweens != NULL)
- {
- free(tweens);
- tweens = NULL;
- }
-
- return;
- }
-
- tween = (tween_t*)&tweens[numtweens-1];
-
- if (!tween)
- return;
-
- tween->alive = 1;
- tween->duration = duration;
- tween->running_since = 0;
- tween->initial_value = *subject;
- tween->target_value = target_value;
- tween->subject = subject;
- tween->easing = easing;
- tween->callback = callback;
-}
-
-static void update_tween(void *data, float dt)
-{
- tween_t *tween = (tween_t*)data;
-
- if (!tween)
- return;
-
-#if 0
- RARCH_LOG("delta: %f\n", dt);
- RARCH_LOG("tween running since: %f\n", tween->running_since);
- RARCH_LOG("tween duration: %f\n", tween->duration);
-#endif
-
- if (tween->running_since < tween->duration)
- {
- tween->running_since += dt;
-
- if (tween->easing)
- *tween->subject = tween->easing(
- tween->running_since,
- tween->initial_value,
- tween->target_value - tween->initial_value,
- tween->duration);
-
- if (tween->running_since >= tween->duration)
- {
- *tween->subject = tween->target_value;
-
- if (tween->callback)
- tween->callback();
- }
- }
-}
-
-static void update_tweens(float dt)
-{
- int i, active_tweens;
-
- active_tweens = 0;
-
- for(i = 0; i < numtweens; i++)
- {
- update_tween(&tweens[i], dt);
- active_tweens += tweens[i].running_since <
- tweens[i].duration ? 1 : 0;
- }
-
- if (numtweens && !active_tweens)
- numtweens = 0;
-}
-
static void lakka_draw_text(const char *str, float x,
float y, float scale, float alpha)
{
@@ -545,7 +451,7 @@ static void lakka_draw_subitems(int i, int j)
snprintf(slot, sizeof(slot), "%d", g_settings.state_slot);
lakka_draw_text(slot,
margin_left + hspacing * (i+2.25) +
- all_categories_x + label_margin_left + 400,
+ all_categories_x + label_margin_left + setting_margin_left,
margin_top + subitem->y + label_margin_top,
1,
subitem->alpha);
@@ -559,7 +465,7 @@ static void lakka_draw_subitems(int i, int j)
sizeof(val));
lakka_draw_text(val,
margin_left + hspacing * (i+2.25) +
- all_categories_x + label_margin_left + 400,
+ all_categories_x + label_margin_left + setting_margin_left,
margin_top + subitem->y + label_margin_top,
1,
subitem->alpha);
@@ -739,9 +645,6 @@ static void lakka_context_destroy(void *data)
font_driver->free(font);
font_driver = NULL;
}
-
- //if (numtweens)
- // free(tweens);
}
void lakka_init_settings(void)
diff --git a/frontend/menu/disp/lakka.h b/frontend/menu/disp/lakka.h
index 5f8e0b42ed..5edb870b39 100644
--- a/frontend/menu/disp/lakka.h
+++ b/frontend/menu/disp/lakka.h
@@ -79,24 +79,6 @@ typedef struct
menu_item_t *items;
} menu_category_t;
-typedef float (*easingFunc)(float, float, float, float);
-typedef void (*tweenCallback) (void);
-
-typedef struct
-{
- int alive;
- float duration;
- float running_since;
- float initial_value;
- float target_value;
- float* subject;
- easingFunc easing;
- tweenCallback callback;
-} tween_t;
-
extern menu_category_t *categories;
-void add_tween(float duration, float target_value, float* subject, easingFunc easing, tweenCallback callback);
-float inOutQuad(float t, float b, float c, float d);
-
#endif /* MENU_DISP_LAKKA_H */
diff --git a/frontend/menu/disp/tween.c b/frontend/menu/disp/tween.c
new file mode 100644
index 0000000000..ccf999ade8
--- /dev/null
+++ b/frontend/menu/disp/tween.c
@@ -0,0 +1,332 @@
+#include "tween.h"
+#include
+
+tween_t* tweens = NULL;
+int numtweens = 0;
+
+void add_tween(float duration, float target_value, float* subject,
+ easingFunc easing, tweenCallback callback)
+{
+ tween_t *tween;
+ tween_t *tweens_tmp;
+
+ numtweens++;
+
+ tweens_tmp = (tween_t*)realloc(tweens, numtweens * sizeof(tween_t));
+ if (tweens_tmp != NULL)
+ {
+ tweens = tweens_tmp;
+ }
+ else // realloc failed
+ {
+ if (tweens != NULL)
+ {
+ free(tweens);
+ tweens = NULL;
+ }
+
+ return;
+ }
+
+ tween = (tween_t*)&tweens[numtweens-1];
+
+ if (!tween)
+ return;
+
+ tween->alive = 1;
+ tween->duration = duration;
+ tween->running_since = 0;
+ tween->initial_value = *subject;
+ tween->target_value = target_value;
+ tween->subject = subject;
+ tween->easing = easing;
+ tween->callback = callback;
+}
+
+void update_tween(void *data, float dt)
+{
+ tween_t *tween = (tween_t*)data;
+
+ if (!tween)
+ return;
+
+ if (tween->running_since < tween->duration)
+ {
+ tween->running_since += dt;
+
+ if (tween->easing)
+ *tween->subject = tween->easing(
+ tween->running_since,
+ tween->initial_value,
+ tween->target_value - tween->initial_value,
+ tween->duration);
+
+ if (tween->running_since >= tween->duration)
+ {
+ *tween->subject = tween->target_value;
+
+ if (tween->callback)
+ tween->callback();
+ }
+ }
+}
+
+void update_tweens(float dt)
+{
+ int i, active_tweens;
+
+ active_tweens = 0;
+
+ for(i = 0; i < numtweens; i++)
+ {
+ update_tween(&tweens[i], dt);
+ active_tweens += tweens[i].running_since < tweens[i].duration ? 1 : 0;
+ }
+
+ if (numtweens && !active_tweens)
+ numtweens = 0;
+}
+
+// linear
+
+float linear(float t, float b, float c, float d)
+{
+ return c * t / d + b;
+}
+
+// quad
+
+float inQuad(float t, float b, float c, float d)
+{
+ return c * pow(t / d, 2) + b;
+}
+
+float outQuad(float t, float b, float c, float d)
+{
+ t = t / d;
+ return -c * t * (t - 2) + b;
+}
+
+float inOutQuad(float t, float b, float c, float d)
+{
+ t = t / d * 2;
+ if (t < 1)
+ return c / 2 * pow(t, 2) + b;
+ return -c / 2 * ((t - 1) * (t - 3) - 1) + b;
+}
+
+float outInQuad(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outQuad(t * 2, b, c / 2, d);
+ return inQuad((t * 2) - d, b + c / 2, c / 2, d);
+}
+
+// cubic
+
+float inCubic(float t, float b, float c, float d)
+{
+ return c * pow(t / d, 3) + b;
+}
+
+float outCubic(float t, float b, float c, float d)
+{
+ return c * (pow(t / d - 1, 3) + 1) + b;
+}
+
+float inOutCubic(float t, float b, float c, float d)
+{
+ t = t / d * 2;
+ if (t < 1)
+ return c / 2 * t * t * t + b;
+ t = t - 2;
+ return c / 2 * (t * t * t + 2) + b;
+}
+
+float outInCubic(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outCubic(t * 2, b, c / 2, d);
+ return inCubic((t * 2) - d, b + c / 2, c / 2, d);
+}
+
+// quart
+
+float inQuart(float t, float b, float c, float d)
+{
+ return c * pow(t / d, 4) + b;
+}
+
+float outQuart(float t, float b, float c, float d)
+{
+ return -c * (pow(t / d - 1, 4) - 1) + b;
+}
+
+float inOutQuart(float t, float b, float c, float d)
+{
+ t = t / d * 2;
+ if (t < 1)
+ return c / 2 * pow(t, 4) + b;
+ return -c / 2 * (pow(t - 2, 4) - 2) + b;
+}
+
+float outInQuart(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outQuart(t * 2, b, c / 2, d);
+ return inQuart((t * 2) - d, b + c / 2, c / 2, d);
+}
+
+// quint
+
+float inQuint(float t, float b, float c, float d)
+{
+ return c * pow(t / d, 5) + b;
+}
+
+float outQuint(float t, float b, float c, float d)
+{
+ return c * (pow(t / d - 1, 5) + 1) + b;
+}
+
+float inOutQuint(float t, float b, float c, float d)
+{
+ t = t / d * 2;
+ if (t < 1)
+ return c / 2 * pow(t, 5) + b;
+ return c / 2 * (pow(t - 2, 5) + 2) + b;
+}
+
+float outInQuint(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outQuint(t * 2, b, c / 2, d);
+ return inQuint((t * 2) - d, b + c / 2, c / 2, d);
+}
+
+// sine
+
+float inSine(float t, float b, float c, float d)
+{
+ return -c * cos(t / d * (M_PI / 2)) + c + b;
+}
+
+float outSine(float t, float b, float c, float d)
+{
+ return c * sin(t / d * (M_PI / 2)) + b;
+}
+
+float inOutSine(float t, float b, float c, float d)
+{
+ return -c / 2 * (cos(M_PI * t / d) - 1) + b;
+}
+
+float outInSine(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outSine(t * 2, b, c / 2, d);
+ return inSine((t * 2) -d, b + c / 2, c / 2, d);
+}
+
+// expo
+
+float inExpo(float t, float b, float c, float d)
+{
+ if (t == 0)
+ return b;
+ return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001;
+}
+
+float outExpo(float t, float b, float c, float d)
+{
+ if (t == d)
+ return b + c;
+ return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b;
+}
+
+float inOutExpo(float t, float b, float c, float d)
+{
+ if (t == 0)
+ return b;
+ if (t == d)
+ return b + c;
+ t = t / d * 2;
+ if (t < 1)
+ return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005;
+ return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b;
+}
+
+float outInExpo(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outExpo(t * 2, b, c / 2, d);
+ return inExpo((t * 2) - d, b + c / 2, c / 2, d);
+}
+
+// circ
+
+float inCirc(float t, float b, float c, float d)
+{
+ return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b);
+}
+
+float outCirc(float t, float b, float c, float d)
+{
+ return(c * sqrt(1 - pow(t / d - 1, 2)) + b);
+}
+
+float inOutCirc(float t, float b, float c, float d)
+{
+ t = t / d * 2;
+ if (t < 1)
+ return -c / 2 * (sqrt(1 - t * t) - 1) + b;
+ t = t - 2;
+ return c / 2 * (sqrt(1 - t * t) + 1) + b;
+}
+
+float outInCirc(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outCirc(t * 2, b, c / 2, d);
+ return inCirc((t * 2) - d, b + c / 2, c / 2, d);
+}
+
+// bounce
+
+float outBounce(float t, float b, float c, float d)
+{
+ t = t / d;
+ if (t < 1 / 2.75)
+ return c * (7.5625 * t * t) + b;
+ if (t < 2 / 2.75)
+ {
+ t = t - (1.5 / 2.75);
+ return c * (7.5625 * t * t + 0.75) + b;
+ }
+ else if (t < 2.5 / 2.75)
+ {
+ t = t - (2.25 / 2.75);
+ return c * (7.5625 * t * t + 0.9375) + b;
+ }
+ t = t - (2.625 / 2.75);
+ return c * (7.5625 * t * t + 0.984375) + b;
+}
+
+float inBounce(float t, float b, float c, float d)
+{
+ return c - outBounce(d - t, 0, c, d) + b;
+}
+
+float inOutBounce(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return inBounce(t * 2, 0, c, d) * 0.5 + b;
+ return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b;
+}
+
+float outInBounce(float t, float b, float c, float d)
+{
+ if (t < d / 2)
+ return outBounce(t * 2, b, c / 2, d);
+ return inBounce((t * 2) - d, b + c / 2, c / 2, d);
+}
diff --git a/frontend/menu/disp/tween.h b/frontend/menu/disp/tween.h
new file mode 100644
index 0000000000..f4bfaeaf24
--- /dev/null
+++ b/frontend/menu/disp/tween.h
@@ -0,0 +1,78 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2014 - Daniel De Matteis
+ * Copyright (C) 2014 - Jean-André Santoni
+ *
+ * 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 .
+ */
+
+#ifndef _TWEEN_H
+#define _TWEEN_H
+
+#include
+
+typedef float (*easingFunc)(float, float, float, float);
+typedef void (*tweenCallback) (void);
+
+typedef struct
+{
+ int alive;
+ float duration;
+ float running_since;
+ float initial_value;
+ float target_value;
+ float* subject;
+ easingFunc easing;
+ tweenCallback callback;
+} tween_t;
+
+void add_tween(float duration, float target_value, float* subject, easingFunc easing, tweenCallback callback);
+void update_tween(void *data, float dt);
+void update_tweens(float dt);
+
+// from https://github.com/kikito/tween.lua/blob/master/tween.lua
+
+float linear(float t, float b, float c, float d);
+float inQuad(float t, float b, float c, float d);
+float outQuad(float t, float b, float c, float d);
+float inOutQuad(float t, float b, float c, float d);
+float outInQuad(float t, float b, float c, float d);
+float inCubic(float t, float b, float c, float d);
+float outCubic(float t, float b, float c, float d);
+float inOutCubic(float t, float b, float c, float d);
+float outInCubic(float t, float b, float c, float d);
+float inQuart(float t, float b, float c, float d);
+float outQuart(float t, float b, float c, float d);
+float inOutQuart(float t, float b, float c, float d);
+float outInQuart(float t, float b, float c, float d);
+float inQuint(float t, float b, float c, float d);
+float outQuint(float t, float b, float c, float d);
+float inOutQuint(float t, float b, float c, float d);
+float outInQuint(float t, float b, float c, float d);
+float inSine(float t, float b, float c, float d);
+float outSine(float t, float b, float c, float d);
+float inOutSine(float t, float b, float c, float d);
+float outInSine(float t, float b, float c, float d);
+float inExpo(float t, float b, float c, float d);
+float outExpo(float t, float b, float c, float d);
+float inOutExpo(float t, float b, float c, float d);
+float outInExpo(float t, float b, float c, float d);
+float inCirc(float t, float b, float c, float d);
+float outCirc(float t, float b, float c, float d);
+float inOutCirc(float t, float b, float c, float d);
+float outInCirc(float t, float b, float c, float d);
+float inBounce(float t, float b, float c, float d);
+float outBounce(float t, float b, float c, float d);
+float inOutBounce(float t, float b, float c, float d);
+float outInBounce(float t, float b, float c, float d);
+
+#endif /* TWEEN_H */
diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c
index 25e2a57ee1..06c0a15115 100644
--- a/frontend/menu/menu_common.c
+++ b/frontend/menu/menu_common.c
@@ -301,9 +301,10 @@ static unsigned input_frame(uint64_t trigger_state)
return MENU_ACTION_NOOP;
}
-bool menu_iterate(void)
+bool menu_iterate(retro_input_t input,
+ retro_input_t old_input, retro_input_t trigger_input)
{
- retro_input_t old_state = 0, trigger_input = 0;
+ retro_input_t old_state = 0;
unsigned action = MENU_ACTION_NOOP;
static bool initial_held = true;
static bool first_held = false;
@@ -313,31 +314,20 @@ bool menu_iterate(void)
if (!driver.menu)
return false;
-
- if (g_extern.lifecycle_state & (1ULL << MODE_MENU_PREINIT))
- {
- driver.menu->need_refresh = true;
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_PREINIT_FINISHED);
- }
-
- rarch_input_poll();
-
- retro_input_t input = input_keys_pressed_func(RARCH_FIRST_META_KEY,
- RARCH_BIND_LIST_END, &old_state);
-
- trigger_input = input & ~old_state;
#ifdef HAVE_OVERLAY
if (BIND_PRESSED(trigger_input, RARCH_OVERLAY_NEXT))
input_overlay_next(driver.overlay);
#endif
check_fullscreen_func(trigger_input);
- if (check_quit_key_func(input) || !driver.video->alive(driver.video_data))
+ if (check_enter_menu_func(trigger_input) &&
+ g_extern.main_is_init && !g_extern.libretro_dummy)
{
rarch_main_command(RARCH_CMD_RESUME);
return false;
}
+ rarch_input_poll();
input_state = menu_input();
if (driver.menu->do_held)
diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h
index 8f699d0d99..76ac35e6b3 100644
--- a/frontend/menu/menu_common.h
+++ b/frontend/menu/menu_common.h
@@ -132,7 +132,7 @@ typedef enum
void *menu_init(const void *data);
-bool menu_iterate(void);
+bool menu_iterate(retro_input_t input, retro_input_t old_input, retro_input_t trigger_input);
void menu_free(void *data);
diff --git a/general.c b/general.c
new file mode 100644
index 0000000000..6bf19b5f7c
--- /dev/null
+++ b/general.c
@@ -0,0 +1,210 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2014 - Daniel De Matteis
+ * Copyright (C) 2012-2014 - Michael Lelli
+ *
+ * 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 .
+ */
+
+#include "general.h"
+
+void rarch_playlist_push(content_playlist_t *playlist,
+ const char *path)
+{
+ char tmp[PATH_MAX];
+
+ if (!playlist || !g_extern.libretro_dummy)
+ return;
+
+ /* path can be relative here.
+ * Ensure we're pushing absolute path. */
+
+ strlcpy(tmp, path, sizeof(tmp));
+
+ if (*tmp)
+ path_resolve_realpath(tmp, sizeof(tmp));
+
+ if (g_extern.system.no_content || *tmp)
+ content_playlist_push(playlist,
+ *tmp ? tmp : NULL,
+ g_settings.libretro,
+ g_extern.system.info.library_name);
+}
+
+void rarch_playlist_load_content(content_playlist_t *playlist,
+ unsigned index)
+{
+ const char *path = NULL;
+ const char *core_path = NULL;
+
+ content_playlist_get_index(playlist,
+ index, &path, &core_path, NULL);
+
+ strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro));
+ rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)path);
+
+ rarch_main_command(RARCH_CMD_LOAD_CORE);
+}
+
+void rarch_main_init_wrap(const struct rarch_main_wrap *args,
+ int *argc, char **argv)
+{
+ *argc = 0;
+ argv[(*argc)++] = strdup("retroarch");
+
+ if (!args->no_content)
+ {
+ if (args->content_path)
+ {
+ RARCH_LOG("Using content: %s.\n", args->content_path);
+ argv[(*argc)++] = strdup(args->content_path);
+ }
+ else
+ {
+ RARCH_LOG("No content, starting dummy core.\n");
+ argv[(*argc)++] = strdup("--menu");
+ }
+ }
+
+ if (args->sram_path)
+ {
+ argv[(*argc)++] = strdup("-s");
+ argv[(*argc)++] = strdup(args->sram_path);
+ }
+
+ if (args->state_path)
+ {
+ argv[(*argc)++] = strdup("-S");
+ argv[(*argc)++] = strdup(args->state_path);
+ }
+
+ if (args->config_path)
+ {
+ argv[(*argc)++] = strdup("-c");
+ argv[(*argc)++] = strdup(args->config_path);
+ }
+
+#ifdef HAVE_DYNAMIC
+ if (args->libretro_path)
+ {
+ argv[(*argc)++] = strdup("-L");
+ argv[(*argc)++] = strdup(args->libretro_path);
+ }
+#endif
+
+ if (args->verbose)
+ argv[(*argc)++] = strdup("-v");
+
+#ifdef HAVE_FILE_LOGGER
+ for (i = 0; i < *argc; i++)
+ RARCH_LOG("arg #%d: %s\n", i, argv[i]);
+#endif
+}
+
+/* When selection is presented back, returns 0.
+ * If it can make a decision right now, returns -1. */
+
+int rarch_defer_core(core_info_list_t *core_info, const char *dir,
+ const char *path, char *deferred_path, size_t sizeof_deferred_path)
+{
+ const core_info_t *info = NULL;
+ size_t supported = 0;
+
+ fill_pathname_join(deferred_path, dir, path, sizeof_deferred_path);
+
+ if (path_is_compressed_file(dir))
+ {
+ /* In case of a compressed archive, we have to join with a hash */
+ /* We are going to write at the position of dir: */
+ rarch_assert(strlen(dir) < strlen(deferred_path));
+ deferred_path[strlen(dir)] = '#';
+ }
+
+ if (core_info)
+ core_info_list_get_supported_cores(core_info, deferred_path, &info,
+ &supported);
+
+ /* Can make a decision right now. */
+ if (supported == 1)
+ {
+ strlcpy(g_extern.fullpath, deferred_path,
+ sizeof(g_extern.fullpath));
+ if (path_file_exists(info->path))
+ strlcpy(g_settings.libretro, info->path,
+ sizeof(g_settings.libretro));
+ return -1;
+ }
+ return 0;
+}
+
+/* Quite intrusive and error prone.
+ * Likely to have lots of small bugs.
+ * Cleanly exit the main loop to ensure that all the tiny details
+ * get set properly.
+ *
+ * This should mitigate most of the smaller bugs. */
+
+bool rarch_replace_config(const char *path)
+{
+ /* If config file to be replaced is the same as the
+ * current config file, exit. */
+ if (!strcmp(path, g_extern.config_path))
+ return false;
+
+ if (g_settings.config_save_on_exit && *g_extern.config_path)
+ config_save_file(g_extern.config_path);
+
+ strlcpy(g_extern.config_path, path, sizeof(g_extern.config_path));
+ g_extern.block_config_read = false;
+ *g_settings.libretro = '\0'; /* Load core in new config. */
+
+ rarch_main_command(RARCH_CMD_PREPARE_DUMMY);
+
+ return true;
+}
+
+void rarch_update_system_info(struct retro_system_info *_info,
+ bool *load_no_content)
+{
+ const core_info_t *info = NULL;
+#if defined(HAVE_DYNAMIC)
+ libretro_free_system_info(_info);
+ if (!(*g_settings.libretro))
+ return;
+
+ libretro_get_system_info(g_settings.libretro, _info,
+ load_no_content);
+#endif
+ if (!g_extern.core_info)
+ return;
+
+ if (!core_info_list_get_info(g_extern.core_info,
+ g_extern.core_info_current, g_settings.libretro))
+ return;
+
+ /* Keep track of info for the currently selected core. */
+ info = (const core_info_t*)g_extern.core_info_current;
+
+ if (!g_extern.verbosity)
+ return;
+
+ RARCH_LOG("[Core Info]:\n");
+ if (info->display_name)
+ RARCH_LOG("Display Name = %s\n", info->display_name);
+ if (info->supported_extensions)
+ RARCH_LOG("Supported Extensions = %s\n",
+ info->supported_extensions);
+ if (info->authors)
+ RARCH_LOG("Authors = %s\n", info->authors);
+ if (info->permissions)
+ RARCH_LOG("Permissions = %s\n", info->permissions);
+}
diff --git a/general.h b/general.h
index 89bc64f6f8..af94efd87a 100644
--- a/general.h
+++ b/general.h
@@ -137,35 +137,27 @@ enum action_state
{
RARCH_ACTION_STATE_NONE = 0,
RARCH_ACTION_STATE_MENU_PREINIT,
- RARCH_ACTION_STATE_MENU_PREINIT_FINISHED,
RARCH_ACTION_STATE_LOAD_CONTENT,
- RARCH_ACTION_STATE_LOAD_CONTENT_FINISHED,
- RARCH_ACTION_STATE_RUNNING,
- RARCH_ACTION_STATE_RUNNING_FINISHED,
RARCH_ACTION_STATE_MENU_RUNNING,
RARCH_ACTION_STATE_MENU_RUNNING_FINISHED,
RARCH_ACTION_STATE_EXITSPAWN,
RARCH_ACTION_STATE_FLUSH_INPUT,
- RARCH_ACTION_STATE_FLUSH_INPUT_FINISHED,
RARCH_ACTION_STATE_QUIT,
RARCH_ACTION_STATE_FORCE_QUIT,
};
enum menu_enums
{
- MODE_GAME = 0,
- MODE_LOAD_GAME,
+ MODE_NONE = 0,
MODE_MENU,
MODE_MENU_WIDESCREEN,
MODE_MENU_HD,
- MODE_MENU_PREINIT,
MODE_EXTLAUNCH_MULTIMAN,
MODE_EXITSPAWN,
MODE_EXITSPAWN_START_GAME,
MODE_EXITSPAWN_MULTIMAN,
MODE_OSK_ENTRY_SUCCESS,
MODE_OSK_ENTRY_FAIL,
- MODE_CLEAR_INPUT,
};
enum sound_mode_enums
@@ -266,6 +258,7 @@ struct settings
bool allow_rotate;
bool shared_context;
+ bool force_srgb_disable;
} video;
#ifdef HAVE_MENU
@@ -436,6 +429,7 @@ struct global
bool location_active;
bool osk_active;
bool force_fullscreen;
+ bool core_shutdown_initiated;
struct string_list *temporary_content;
@@ -761,6 +755,8 @@ struct global
/* Config file associated with per-core configs. */
char core_specific_config_path[PATH_MAX];
+
+ retro_keyboard_event_t frontend_key_event;
};
struct rarch_main_wrap
diff --git a/gfx/gl.c b/gfx/gl.c
index fe85f30775..51f64f03d4 100644
--- a/gfx/gl.c
+++ b/gfx/gl.c
@@ -516,6 +516,9 @@ static void gl_create_fbo_textures(gl_t *gl)
RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n");
}
+ if (g_settings.video.force_srgb_disable)
+ srgb_fbo = false;
+
#ifndef HAVE_OPENGLES2
if (fp_fbo && gl->has_fp_fbo)
{
@@ -1874,6 +1877,9 @@ static bool resolve_extensions(gl_t *gl)
#endif
#endif
+ if (g_settings.video.force_srgb_disable)
+ gl->has_srgb_fbo = false;
+
#ifdef GL_DEBUG
// Useful for debugging, but kinda obnoxious otherwise.
RARCH_LOG("[GL]: Supported extensions:\n");
diff --git a/gfx/shader_parse.c b/gfx/shader_parse.c
index fee5c2825b..765d7ba833 100644
--- a/gfx/shader_parse.c
+++ b/gfx/shader_parse.c
@@ -608,7 +608,7 @@ static void shader_write_variable(config_file_t *conf,
config_set_hex(conf, wram_buf, info->addr);
break;
- default:
+ case RARCH_STATE_NONE:
break;
}
}
diff --git a/griffin/griffin.c b/griffin/griffin.c
index c7951012b6..8c3cfe37b8 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -590,6 +590,7 @@ MAIN
/*============================================================
RETROARCH
============================================================ */
+#include "../general.c"
#include "../retroarch.c"
/*============================================================
@@ -662,6 +663,7 @@ MENU
#ifdef HAVE_LAKKA
#include "../frontend/menu/backend/menu_lakka_backend.c"
#include "../frontend/menu/disp/lakka.c"
+#include "../frontend/menu/disp/tween.c"
#endif
#ifdef HAVE_GLUI
diff --git a/retroarch.c b/retroarch.c
index 421d75ce24..e69144058f 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -43,6 +43,7 @@
#ifdef HAVE_MENU
#include "frontend/menu/menu_common.h"
+#include "frontend/menu/menu_input_line_cb.h"
#endif
#ifdef _WIN32
@@ -2319,51 +2320,64 @@ static void check_slowmotion(bool pressed)
"Slow motion rewind." : "Slow motion.", 0, 30);
}
-static void check_movie_record(bool pressed)
+static bool check_movie_init(void)
{
+ char path[PATH_MAX], msg[PATH_MAX];
+ bool ret = true;
+
if (g_extern.bsv.movie)
+ return false;
+
+ g_settings.rewind_granularity = 1;
+
+ if (g_settings.state_slot > 0)
{
- msg_queue_clear(g_extern.msg_queue);
- msg_queue_push(g_extern.msg_queue,
- RETRO_MSG_MOVIE_RECORD_STOPPING, 2, 180);
- RARCH_LOG(RETRO_LOG_MOVIE_RECORD_STOPPING);
- deinit_movie();
+ snprintf(path, sizeof(path), "%s%d.bsv",
+ g_extern.bsv.movie_path, g_settings.state_slot);
}
else
{
- char path[PATH_MAX], msg[PATH_MAX];
-
- g_settings.rewind_granularity = 1;
-
- if (g_settings.state_slot > 0)
- {
- snprintf(path, sizeof(path), "%s%d.bsv",
- g_extern.bsv.movie_path, g_settings.state_slot);
- }
- else
- {
- snprintf(path, sizeof(path), "%s.bsv",
- g_extern.bsv.movie_path);
- }
-
- snprintf(msg, sizeof(msg), "Starting movie record to \"%s\".", path);
-
- g_extern.bsv.movie = bsv_movie_init(path, RARCH_MOVIE_RECORD);
- msg_queue_clear(g_extern.msg_queue);
- msg_queue_push(g_extern.msg_queue, g_extern.bsv.movie ?
- msg : "Failed to start movie record.", 1, 180);
-
- if (g_extern.bsv.movie)
- RARCH_LOG("Starting movie record to \"%s\".\n", path);
- else
- RARCH_ERR("Failed to start movie record.\n");
+ snprintf(path, sizeof(path), "%s.bsv",
+ g_extern.bsv.movie_path);
}
+
+ snprintf(msg, sizeof(msg), "Starting movie record to \"%s\".", path);
+
+ g_extern.bsv.movie = bsv_movie_init(path, RARCH_MOVIE_RECORD);
+
+ if (!g_extern.bsv.movie)
+ ret = false;
+
+ msg_queue_clear(g_extern.msg_queue);
+ msg_queue_push(g_extern.msg_queue, g_extern.bsv.movie ?
+ msg : "Failed to start movie record.", 1, 180);
+
+ if (g_extern.bsv.movie)
+ RARCH_LOG("Starting movie record to \"%s\".\n", path);
+ else
+ RARCH_ERR("Failed to start movie record.\n");
+
+ return ret;
}
-static void check_movie_playback(bool pressed)
+static bool check_movie_record(void)
+{
+ if (!g_extern.bsv.movie)
+ return false;
+
+ msg_queue_clear(g_extern.msg_queue);
+ msg_queue_push(g_extern.msg_queue,
+ RETRO_MSG_MOVIE_RECORD_STOPPING, 2, 180);
+ RARCH_LOG(RETRO_LOG_MOVIE_RECORD_STOPPING);
+ deinit_movie();
+
+ return true;
+}
+
+static bool check_movie_playback(void)
{
if (!g_extern.bsv.movie_end)
- return;
+ return false;
msg_queue_push(g_extern.msg_queue,
RETRO_MSG_MOVIE_PLAYBACK_ENDED, 1, 180);
@@ -2372,19 +2386,20 @@ static void check_movie_playback(bool pressed)
deinit_movie();
g_extern.bsv.movie_end = false;
g_extern.bsv.movie_playback = false;
+
+ return true;
}
-static void check_movie(void)
+static bool check_movie(void)
{
if (g_extern.bsv.movie_playback)
- check_movie_playback(true);
- else
- check_movie_record(true);
+ return check_movie_playback();
+ if (!g_extern.bsv.movie)
+ return check_movie_init();
+ return check_movie_record();
}
-static void check_pause(
- bool new_state, bool old_state,
- bool frameadvance_pressed)
+static void check_pause(bool pressed, bool frameadvance_pressed)
{
static bool old_focus = true;
bool focus = true;
@@ -2392,12 +2407,12 @@ static void check_pause(
bool has_set_audio_start = false;
/* FRAMEADVANCE will set us into pause mode. */
- new_state |= !g_extern.is_paused && frameadvance_pressed;
+ pressed |= !g_extern.is_paused && frameadvance_pressed;
if (g_settings.pause_nonactive)
focus = driver.video->focus(driver.video_data);
- if (focus && new_state && !old_state)
+ if (focus && pressed)
{
g_extern.is_paused = !g_extern.is_paused;
@@ -2486,6 +2501,9 @@ static void check_turbo(void)
static void check_shader_dir(bool pressed_next, bool pressed_prev)
{
+ char msg[PATH_MAX];
+ const char *shader = NULL, *ext = NULL;
+ enum rarch_shader_type type = RARCH_SHADER_NONE;
bool should_apply = false;
if (!g_extern.shader_dir.list || !driver.video->set_shader)
@@ -2506,13 +2524,12 @@ static void check_shader_dir(bool pressed_next, bool pressed_prev)
g_extern.shader_dir.ptr--;
}
- if (should_apply)
+ if (!should_apply)
+ return;
+
{
- char msg[512];
- const char *shader =
- g_extern.shader_dir.list->elems[g_extern.shader_dir.ptr].data;
- enum rarch_shader_type type = RARCH_SHADER_NONE;
- const char *ext = path_get_extension(shader);
+ shader = g_extern.shader_dir.list->elems[g_extern.shader_dir.ptr].data;
+ ext = path_get_extension(shader);
if (strcmp(ext, "glsl") == 0 || strcmp(ext, "glslp") == 0)
type = RARCH_SHADER_GLSL;
@@ -2536,7 +2553,7 @@ static void check_shader_dir(bool pressed_next, bool pressed_prev)
void rarch_disk_control_append_image(const char *path)
{
- char msg[512];
+ char msg[PATH_MAX];
unsigned new_index;
const struct retro_disk_control_callback *control =
(const struct retro_disk_control_callback*)&g_extern.system.disk_control;
@@ -2583,7 +2600,7 @@ void rarch_disk_control_append_image(const char *path)
void rarch_disk_control_set_eject(bool new_state, bool log)
{
- char msg[256];
+ char msg[PATH_MAX];
const struct retro_disk_control_callback *control =
(const struct retro_disk_control_callback*)&g_extern.system.disk_control;
bool error = false;
@@ -2621,7 +2638,7 @@ void rarch_disk_control_set_eject(bool new_state, bool log)
void rarch_disk_control_set_index(unsigned next_index)
{
- char msg[256];
+ char msg[PATH_MAX];
unsigned num_disks;
const struct retro_disk_control_callback *control =
(const struct retro_disk_control_callback*)&g_extern.system.disk_control;
@@ -2779,7 +2796,10 @@ static void check_disk_next(
RARCH_ERR("Got invalid disk index from libretro.\n");
}
-static void do_state_checks(
+/* Checks for stuff like fullscreen, save states, etc.
+ * Return false when RetroArch is paused. */
+
+static bool do_state_checks(
retro_input_t input, retro_input_t old_input,
retro_input_t trigger_input)
{
@@ -2814,10 +2834,10 @@ static void do_state_checks(
if (g_extern.netplay)
{
check_netplay_flip_func(trigger_input);
- return;
+ return true;
}
#endif
- check_pause_func(input, old_input);
+ check_pause_func(trigger_input);
check_oneshot_func(trigger_input);
@@ -2825,7 +2845,7 @@ static void do_state_checks(
rarch_render_cached_frame();
if (g_extern.is_paused && !g_extern.is_oneshot)
- return;
+ return false;
check_fast_forward_button_func(input, old_input, trigger_input);
@@ -2872,6 +2892,8 @@ static void do_state_checks(
if (BIND_PRESSED(trigger_input, RARCH_RESET))
rarch_main_command(RARCH_CMD_RESET);
+
+ return true;
}
static void init_state(void)
@@ -2951,7 +2973,8 @@ static void verify_api_version(void)
}
/* Make sure we haven't compiled for something we cannot run.
- * Ideally, code would get swapped out depending on CPU support, but this will do for now.
+ * Ideally, code would get swapped out depending on CPU support,
+ * but this will do for now.
*/
static void validate_cpu_features(void)
{
@@ -3096,21 +3119,6 @@ error:
return 1;
}
-static bool check_enter_menu(bool pressed, bool old_pressed)
-{
- bool rmenu_toggle = pressed || (g_extern.libretro_dummy && !old_pressed);
-
- if (rmenu_toggle && !old_pressed)
- {
- /* Always go into menu if dummy core is loaded. */
- rarch_main_set_state(RARCH_ACTION_STATE_MENU_PREINIT);
- g_extern.system.frame_time_last = 0;
- return true;
- }
-
- return false;
-}
-
static inline void update_frame_time(void)
{
retro_time_t time = 0;
@@ -3169,22 +3177,47 @@ void rarch_main_set_state(unsigned cmd)
switch (cmd)
{
case RARCH_ACTION_STATE_MENU_PREINIT:
- g_extern.lifecycle_state |= (1ULL << MODE_MENU_PREINIT);
- break;
- case RARCH_ACTION_STATE_MENU_PREINIT_FINISHED:
- g_extern.lifecycle_state &= ~(1ULL << MODE_MENU_PREINIT);
+ {
+ int i;
+
+ /* Menu should always run with vsync on. */
+ rarch_main_command(RARCH_CMD_VIDEO_SET_BLOCKING_STATE);
+
+ /* Stop all rumbling before entering the menu. */
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0);
+ driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0);
+ }
+
+ rarch_main_command(RARCH_CMD_AUDIO_STOP);
+
+#ifdef HAVE_MENU
+ if (driver.menu)
+ {
+ /* Override keyboard callback to redirect to menu instead.
+ * We'll use this later for something ...
+ * FIXME: This should probably be moved to menu_common somehow. */
+ g_extern.frontend_key_event = g_extern.system.key_event;
+ g_extern.system.key_event = menu_key_event;
+
+ driver.menu->need_refresh = true;
+ driver.menu->old_input_state |= 1ULL << RARCH_MENU_TOGGLE;
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING);
+ }
+#endif
+ g_extern.system.frame_time_last = 0;
+ }
break;
case RARCH_ACTION_STATE_LOAD_CONTENT:
- g_extern.lifecycle_state |= (1ULL << MODE_LOAD_GAME);
- break;
- case RARCH_ACTION_STATE_LOAD_CONTENT_FINISHED:
- g_extern.lifecycle_state &= ~(1ULL << MODE_LOAD_GAME);
- break;
- case RARCH_ACTION_STATE_RUNNING:
- g_extern.lifecycle_state |= (1ULL << MODE_GAME);
- break;
- case RARCH_ACTION_STATE_RUNNING_FINISHED:
- g_extern.lifecycle_state &= ~(1ULL << MODE_GAME);
+#ifdef HAVE_MENU
+ if (!load_menu_content())
+ {
+ /* If content loading fails, we go back to menu. */
+ if (driver.menu)
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_PREINIT);
+ }
+#endif
break;
case RARCH_ACTION_STATE_MENU_RUNNING:
g_extern.lifecycle_state |= (1ULL << MODE_MENU);
@@ -3196,18 +3229,20 @@ void rarch_main_set_state(unsigned cmd)
g_extern.lifecycle_state |= (1ULL << MODE_EXITSPAWN);
break;
case RARCH_ACTION_STATE_QUIT:
+ g_extern.system.shutdown = true;
rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING_FINISHED);
break;
case RARCH_ACTION_STATE_FORCE_QUIT:
g_extern.lifecycle_state = 0;
rarch_main_set_state(RARCH_ACTION_STATE_QUIT);
break;
case RARCH_ACTION_STATE_FLUSH_INPUT:
- g_extern.lifecycle_state |= (1ULL << MODE_CLEAR_INPUT);
- break;
- case RARCH_ACTION_STATE_FLUSH_INPUT_FINISHED:
- g_extern.lifecycle_state &= ~(1ULL << MODE_CLEAR_INPUT);
+ rarch_input_poll();
+#ifdef HAVE_MENU
+ menu_input();
+#endif
+ /* Restore libretro keyboard callback. */
+ g_extern.system.key_event = g_extern.frontend_key_event;
break;
case RARCH_ACTION_STATE_NONE:
default:
@@ -3238,11 +3273,13 @@ void rarch_main_command(unsigned cmd)
case RARCH_CMD_LOAD_CORE:
#ifdef HAVE_MENU
if (driver.menu)
- rarch_update_system_info(&g_extern.menu.info, &driver.menu->load_no_content);
+ rarch_update_system_info(&g_extern.menu.info,
+ &driver.menu->load_no_content);
#endif
break;
case RARCH_CMD_LOAD_STATE:
- /* Disallow savestate load when we absolutely cannot change game state. */
+ /* Disallow savestate load when we absolutely
+ * cannot change game state. */
if (g_extern.bsv.movie)
return;
@@ -3251,7 +3288,6 @@ void rarch_main_command(unsigned cmd)
return;
#endif
main_state(cmd);
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING);
break;
case RARCH_CMD_RESET:
RARCH_LOG(RETRO_LOG_RESETTING_CONTENT);
@@ -3261,14 +3297,12 @@ void rarch_main_command(unsigned cmd)
/* bSNES since v073r01 resets controllers to JOYPAD
* after a reset, so just enforce it here. */
init_controllers();
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING);
break;
case RARCH_CMD_SAVE_STATE:
if (g_settings.savestate_auto_index)
g_settings.state_slot++;
main_state(cmd);
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING);
break;
case RARCH_CMD_TAKE_SCREENSHOT:
take_screenshot();
@@ -3436,7 +3470,6 @@ void rarch_main_command(unsigned cmd)
#ifdef HAVE_MENU
rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
#endif
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING);
break;
case RARCH_CMD_RESTART_RETROARCH:
#if defined(GEKKO) && defined(HW_RVL)
@@ -3444,7 +3477,6 @@ void rarch_main_command(unsigned cmd)
SALAMANDER_FILE,
sizeof(g_extern.fullpath));
#endif
- rarch_main_set_state(RARCH_ACTION_STATE_RUNNING_FINISHED);
rarch_main_set_state(RARCH_ACTION_STATE_EXITSPAWN);
break;
case RARCH_CMD_MENU_SAVE_CONFIG:
@@ -3581,16 +3613,32 @@ bool rarch_main_iterate(void)
trigger_input = input & ~old_input;
- /* SHUTDOWN on consoles should exit RetroArch completely. */
- if (g_extern.system.shutdown)
- return false;
-
/* Time to drop? */
- if (check_quit_key_func(input) || !driver.video->alive(driver.video_data))
+ if (
+ g_extern.system.shutdown ||
+ check_quit_key_func(input) ||
+ !driver.video->alive(driver.video_data))
return false;
- if (check_enter_menu_func(input, old_input))
- return false; /* Enter menu, don't exit. */
+ if (g_extern.lifecycle_state & (1ULL << MODE_MENU))
+ {
+ if (!menu_iterate(input, old_input, trigger_input))
+ {
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED);
+ driver_set_nonblock_state(driver.nonblock_state);
+
+ rarch_main_command(RARCH_CMD_AUDIO_START);
+ rarch_main_set_state(RARCH_ACTION_STATE_FLUSH_INPUT);
+ }
+ return true;
+ }
+
+ if (check_enter_menu_func(trigger_input) || (g_extern.libretro_dummy))
+ {
+ /* Always go into menu if dummy core is loaded. */
+ rarch_main_set_state(RARCH_ACTION_STATE_MENU_PREINIT);
+ return true; /* Enter menu on next run. */
+ }
if (g_extern.exec)
{
@@ -3598,10 +3646,7 @@ bool rarch_main_iterate(void)
return false;
}
- /* Checks for stuff like fullscreen, save states, etc. */
- do_state_checks(input, old_input, trigger_input);
-
- if (g_extern.is_paused && !g_extern.is_oneshot)
+ if (!do_state_checks(input, old_input, trigger_input))
{
rarch_input_poll();
rarch_sleep(10);
@@ -3723,195 +3768,3 @@ void rarch_main_deinit(void)
g_extern.main_is_init = false;
}
-
-void rarch_playlist_push(content_playlist_t *playlist,
- const char *path)
-{
- char tmp[PATH_MAX];
-
- if (!playlist || !g_extern.libretro_dummy)
- return;
-
- /* path can be relative here.
- * Ensure we're pushing absolute path. */
-
- strlcpy(tmp, path, sizeof(tmp));
-
- if (*tmp)
- path_resolve_realpath(tmp, sizeof(tmp));
-
- if (g_extern.system.no_content || *tmp)
- content_playlist_push(playlist,
- *tmp ? tmp : NULL,
- g_settings.libretro,
- g_extern.system.info.library_name);
-}
-
-void rarch_playlist_load_content(content_playlist_t *playlist,
- unsigned index)
-{
- const char *path = NULL;
- const char *core_path = NULL;
-
- content_playlist_get_index(playlist,
- index, &path, &core_path, NULL);
-
- strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro));
- rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)path);
-
- rarch_main_command(RARCH_CMD_LOAD_CORE);
-}
-
-void rarch_main_init_wrap(const struct rarch_main_wrap *args,
- int *argc, char **argv)
-{
- *argc = 0;
- argv[(*argc)++] = strdup("retroarch");
-
- if (!args->no_content)
- {
- if (args->content_path)
- {
- RARCH_LOG("Using content: %s.\n", args->content_path);
- argv[(*argc)++] = strdup(args->content_path);
- }
- else
- {
- RARCH_LOG("No content, starting dummy core.\n");
- argv[(*argc)++] = strdup("--menu");
- }
- }
-
- if (args->sram_path)
- {
- argv[(*argc)++] = strdup("-s");
- argv[(*argc)++] = strdup(args->sram_path);
- }
-
- if (args->state_path)
- {
- argv[(*argc)++] = strdup("-S");
- argv[(*argc)++] = strdup(args->state_path);
- }
-
- if (args->config_path)
- {
- argv[(*argc)++] = strdup("-c");
- argv[(*argc)++] = strdup(args->config_path);
- }
-
-#ifdef HAVE_DYNAMIC
- if (args->libretro_path)
- {
- argv[(*argc)++] = strdup("-L");
- argv[(*argc)++] = strdup(args->libretro_path);
- }
-#endif
-
- if (args->verbose)
- argv[(*argc)++] = strdup("-v");
-
-#ifdef HAVE_FILE_LOGGER
- for (i = 0; i < *argc; i++)
- RARCH_LOG("arg #%d: %s\n", i, argv[i]);
-#endif
-}
-
-/* When selection is presented back, returns 0.
- * If it can make a decision right now, returns -1. */
-
-int rarch_defer_core(core_info_list_t *core_info, const char *dir,
- const char *path, char *deferred_path, size_t sizeof_deferred_path)
-{
- const core_info_t *info = NULL;
- size_t supported = 0;
-
- fill_pathname_join(deferred_path, dir, path, sizeof_deferred_path);
-
- if (path_is_compressed_file(dir))
- {
- /* In case of a compressed archive, we have to join with a hash */
- /* We are going to write at the position of dir: */
- rarch_assert(strlen(dir) < strlen(deferred_path));
- deferred_path[strlen(dir)] = '#';
- }
-
- if (core_info)
- core_info_list_get_supported_cores(core_info, deferred_path, &info,
- &supported);
-
- /* Can make a decision right now. */
- if (supported == 1)
- {
- strlcpy(g_extern.fullpath, deferred_path,
- sizeof(g_extern.fullpath));
-
- if (path_file_exists(info->path))
- strlcpy(g_settings.libretro, info->path,
- sizeof(g_settings.libretro));
- return -1;
- }
- return 0;
-}
-
-/* Quite intrusive and error prone.
- * Likely to have lots of small bugs.
- * Cleanly exit the main loop to ensure that all the tiny details
- * get set properly.
- *
- * This should mitigate most of the smaller bugs. */
-
-bool rarch_replace_config(const char *path)
-{
- /* If config file to be replaced is the same as the
- * current config file, exit. */
- if (!strcmp(path, g_extern.config_path))
- return false;
-
- if (g_settings.config_save_on_exit && *g_extern.config_path)
- config_save_file(g_extern.config_path);
-
- strlcpy(g_extern.config_path, path, sizeof(g_extern.config_path));
- g_extern.block_config_read = false;
- *g_settings.libretro = '\0'; /* Load core in new config. */
-
- rarch_main_command(RARCH_CMD_PREPARE_DUMMY);
-
- return true;
-}
-
-void rarch_update_system_info(struct retro_system_info *_info, bool *load_no_content)
-{
- const core_info_t *info = NULL;
-#if defined(HAVE_DYNAMIC)
- libretro_free_system_info(_info);
- if (!(*g_settings.libretro))
- return;
-
- libretro_get_system_info(g_settings.libretro, _info,
- load_no_content);
-#endif
- if (!g_extern.core_info)
- return;
-
- if (!core_info_list_get_info(g_extern.core_info,
- g_extern.core_info_current, g_settings.libretro))
- return;
-
- /* Keep track of info for the currently selected core. */
- info = (const core_info_t*)g_extern.core_info_current;
-
- if (!g_extern.verbosity)
- return;
-
- RARCH_LOG("[Core Info]:\n");
- if (info->display_name)
- RARCH_LOG("Display Name = %s\n", info->display_name);
- if (info->supported_extensions)
- RARCH_LOG("Supported Extensions = %s\n",
- info->supported_extensions);
- if (info->authors)
- RARCH_LOG("Authors = %s\n", info->authors);
- if (info->permissions)
- RARCH_LOG("Permissions = %s\n", info->permissions);
-}
diff --git a/retroarch.cfg b/retroarch.cfg
index a8019d5269..dc772521e3 100644
--- a/retroarch.cfg
+++ b/retroarch.cfg
@@ -124,6 +124,10 @@
# Video vsync.
# video_vsync = true
+# Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows
+# have video problems with sRGB FBO support enabled.
+# video_force_srgb_disable = false
+
# Attempts to hard-synchronize CPU and GPU. Can reduce latency at cost of performance.
# video_hard_sync = false
diff --git a/settings.c b/settings.c
index e1f7f00b12..cfa1ecb5b3 100644
--- a/settings.c
+++ b/settings.c
@@ -306,6 +306,7 @@ void config_set_defaults(void)
g_settings.video.threaded = g_defaults.settings.video_threaded_enable;
g_settings.video.shared_context = video_shared_context;
+ g_settings.video.force_srgb_disable = false;
#ifdef GEKKO
g_settings.video.viwidth = video_viwidth;
#endif
@@ -430,6 +431,7 @@ void config_set_defaults(void)
g_extern.console.screen.viewports.custom_vp.x = 0;
g_extern.console.screen.viewports.custom_vp.y = 0;
+
/* Make sure settings from other configs carry over into defaults
* for another config. */
if (!g_extern.has_set_save_path)
@@ -930,6 +932,8 @@ bool config_load_file(const char *path, bool set_defaults)
CONFIG_GET_FLOAT(video.msg_pos_y, "video_message_pos_y");
CONFIG_GET_INT(video.rotation, "video_rotation");
+ CONFIG_GET_BOOL(video.force_srgb_disable, "video_force_srgb_disable");
+
#ifdef RARCH_CONSOLE
/* TODO - will be refactored later to make it more clean - it's more
* important that it works for consoles right now */
@@ -1451,6 +1455,8 @@ bool config_save_file(const char *path)
config_set_bool(conf, "video_threaded", g_settings.video.threaded);
config_set_bool(conf, "video_shared_context",
g_settings.video.shared_context);
+ config_set_bool(conf, "video_force_srgb_disable",
+ g_settings.video.force_srgb_disable);
config_set_bool(conf, "video_fullscreen", g_settings.video.fullscreen);
config_set_float(conf, "video_refresh_rate", g_settings.video.refresh_rate);
config_set_int(conf, "video_monitor_index",
diff --git a/settings_data.c b/settings_data.c
index 4660a472f8..0300806e0a 100644
--- a/settings_data.c
+++ b/settings_data.c
@@ -2413,6 +2413,7 @@ rarch_setting_t *setting_data_get_list(void)
CONFIG_UINT(g_settings.video.fullscreen_y, "video_fullscreen_y", "Fullscreen Height", fullscreen_y, GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate", "Refresh Rate", refresh_rate, "%.3f Hz", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_RANGE(0, 0, 0.001, true, false)
CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate_auto", "Estimated Monitor FPS", refresh_rate, "%.3f Hz", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler)
+ CONFIG_BOOL(g_settings.video.force_srgb_disable, "video_force_srgb_disable", "Force-disable sRGB FBO", false, "OFF", "ON", GROUP_NAME, SUBGROUP_NAME, general_write_handler, general_read_handler) WITH_CMD(RARCH_CMD_REINIT) WITH_FLAGS(SD_FLAG_CMD_APPLY_AUTO)
END_SUB_GROUP()
START_SUB_GROUP("Aspect", GROUP_NAME)