diff --git a/360/main.c b/360/main.c
index 05b8c8fa47..0525981e24 100644
--- a/360/main.c
+++ b/360/main.c
@@ -320,7 +320,7 @@ begin_shutdown:
if(path_file_exists(SYS_CONFIG_FILE))
rarch_config_save(SYS_CONFIG_FILE);
- menu_deinit();
+ menu_free();
video_xdk360.stop();
input_xdk360.free(NULL);
rarch_exec();
diff --git a/360/menu.cpp b/360/menu.cpp
index 657b344653..312b7ec123 100644
--- a/360/menu.cpp
+++ b/360/menu.cpp
@@ -70,10 +70,12 @@ static void filebrowser_fetch_directory_entries(const char *path, filebrowser_t
rompath_title->SetText(strw_buffer);
romlist->DeleteItems(0, romlist->GetItemCount());
- romlist->InsertItems(0, browser->file_count);
- for(unsigned i = 0; i < browser->file_count; i++)
+ romlist->InsertItems(0, browser->current_dir.size);
+ for(unsigned i = 0; i < browser->current_dir.size; i++)
{
- rarch_convert_char_to_wchar(strw_buffer, browser->cur[i].d_name, sizeof(strw_buffer));
+ char fname_tmp[256];
+ fill_pathname_base(fname_tmp, browser->current_dir.elems[i], sizeof(fname_tmp));
+ rarch_convert_char_to_wchar(strw_buffer, fname_tmp, sizeof(strw_buffer));
romlist->SetText(i, strw_buffer);
}
}
@@ -524,13 +526,12 @@ HRESULT CRetroArchFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle
if(hObjPressed == m_romlist)
{
int index = m_romlist.GetCurSel();
- if(browser.cur[index].d_type != FILE_ATTRIBUTE_DIRECTORY)
+ if(path_file_exists(browser.current_dir.elems[index]))
{
struct retro_system_info info;
retro_get_system_info(&info);
bool block_zip_extract = info.block_extract;
-
- const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t*)m_romlist.GetText(index));
+ const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t*)m_romlist.GetText(index));
if((strstr(strbuffer, ".zip") || strstr(strbuffer, ".ZIP")) && !block_zip_extract)
{
@@ -545,7 +546,7 @@ HRESULT CRetroArchFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle
rarch_settings_change(S_START_RARCH);
}
}
- else if(browser.cur[index].d_type == FILE_ATTRIBUTE_DIRECTORY)
+ else if(path_is_directory(browser.current_dir.elems[index]))
{
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index));
@@ -578,7 +579,7 @@ HRESULT CRetroArchShaderBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHand
if(hObjPressed == m_shaderlist)
{
int index = m_shaderlist.GetCurSel();
- if(tmp_browser.cur[index].d_type != FILE_ATTRIBUTE_DIRECTORY)
+ if(path_file_exists(tmp_browser.current_dir.elems[index]))
{
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_shaderlist.GetText(index));
@@ -599,7 +600,7 @@ HRESULT CRetroArchShaderBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHand
if (g_console.info_msg_enable)
rarch_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
}
- else if(tmp_browser.cur[index].d_type == FILE_ATTRIBUTE_DIRECTORY)
+ else if(path_is_directory(tmp_browser.current_dir.elems[index]))
{
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_shaderlist.GetText(index));
snprintf(path, sizeof(path), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
@@ -619,13 +620,13 @@ HRESULT CRetroArchCoreBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle
if(hObjPressed == m_romlist)
{
int index = m_romlist.GetCurSel();
- if(tmp_browser.cur[index].d_type != FILE_ATTRIBUTE_DIRECTORY)
+ if(path_file_exists(tmp_browser.current_dir.elems[index]))
{
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index));
snprintf(g_console.launch_app_on_exit, sizeof(g_console.launch_app_on_exit), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
rarch_settings_change(S_RETURN_TO_LAUNCHER);
}
- else if(tmp_browser.cur[index].d_type == FILE_ATTRIBUTE_DIRECTORY)
+ else if(path_is_directory(tmp_browser.current_dir.elems[index]))
{
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index));
snprintf(path, sizeof(path), "%s%s\\", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
@@ -838,8 +839,10 @@ int menu_init (void)
return 0;
}
-void menu_deinit (void)
+void menu_free (void)
{
+ filebrowser_free(&browser);
+ filebrowser_free(&tmp_browser);
app.Uninit();
}
diff --git a/360/menu.h b/360/menu.h
index fbb3978eea..b7041b6d8e 100644
--- a/360/menu.h
+++ b/360/menu.h
@@ -215,7 +215,7 @@ class CRetroArchControls: public CXuiSceneImpl
};
int menu_init (void);
-void menu_deinit (void);
+void menu_free (void);
void menu_loop (void);
extern CRetroArch app;
diff --git a/Makefile b/Makefile
index 93238a1a9d..863a2f607f 100644
--- a/Makefile
+++ b/Makefile
@@ -164,6 +164,11 @@ ifeq ($(HAVE_SDL_IMAGE), 1)
DEFINES += $(SDL_IMAGE_CFLAGS)
endif
+ifeq ($(HAVE_LIBPNG), 1)
+ LIBS += $(LIBPNG_LIBS)
+ DEFINES += $(LIBPNG_CFLAGS)
+endif
+
ifeq ($(HAVE_FFMPEG), 1)
OBJ += record/ffemu.o
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS)
diff --git a/Makefile.win b/Makefile.win
index 9f282a6e90..b20ab47429 100644
--- a/Makefile.win
+++ b/Makefile.win
@@ -32,7 +32,6 @@ libretro ?= -lretro
LIBS = -lm
DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.6\"
LDFLAGS = -L. -static-libgcc
-LDCXXFLAGS = -s
ifeq ($(TDM_GCC),)
LDCXXFLAGS += -static-libstdc++
@@ -153,7 +152,14 @@ ifneq ($(V), 1)
Q := @
endif
-CFLAGS += -Wall -Wno-unused-result -O3 -I.
+ifeq ($(DEBUG), 1)
+ CFLAGS += -O0 -g
+else
+ CFLAGS += -O3
+ LDCXXFLAGS += -s
+endif
+
+CFLAGS += -Wall -Wno-unused-result -I.
ifeq ($(CXX_BUILD), 1)
CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS
else
diff --git a/android/.classpath b/android/.classpath
new file mode 100644
index 0000000000..a4763d1eec
--- /dev/null
+++ b/android/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/android/.project b/android/.project
new file mode 100644
index 0000000000..4af1961cac
--- /dev/null
+++ b/android/.project
@@ -0,0 +1,33 @@
+
+
+ RetroArch
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/android/.settings/org.eclipse.jdt.core.prefs b/android/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..f77b31c2d2
--- /dev/null
+++ b/android/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 0000000000..7e450a1267
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/bin/classes/com/retroarch/BuildConfig.class b/android/bin/classes/com/retroarch/BuildConfig.class
new file mode 100644
index 0000000000..2ecbee69f1
Binary files /dev/null and b/android/bin/classes/com/retroarch/BuildConfig.class differ
diff --git a/android/bin/classes/com/retroarch/MainActivity.class b/android/bin/classes/com/retroarch/MainActivity.class
new file mode 100644
index 0000000000..d5fba4e868
Binary files /dev/null and b/android/bin/classes/com/retroarch/MainActivity.class differ
diff --git a/android/bin/classes/com/retroarch/R$attr.class b/android/bin/classes/com/retroarch/R$attr.class
new file mode 100644
index 0000000000..f85362c78b
Binary files /dev/null and b/android/bin/classes/com/retroarch/R$attr.class differ
diff --git a/android/bin/classes/com/retroarch/R$drawable.class b/android/bin/classes/com/retroarch/R$drawable.class
new file mode 100644
index 0000000000..62036ee00a
Binary files /dev/null and b/android/bin/classes/com/retroarch/R$drawable.class differ
diff --git a/android/bin/classes/com/retroarch/R$layout.class b/android/bin/classes/com/retroarch/R$layout.class
new file mode 100644
index 0000000000..78c6034104
Binary files /dev/null and b/android/bin/classes/com/retroarch/R$layout.class differ
diff --git a/android/bin/classes/com/retroarch/R$string.class b/android/bin/classes/com/retroarch/R$string.class
new file mode 100644
index 0000000000..e0ffa75cf2
Binary files /dev/null and b/android/bin/classes/com/retroarch/R$string.class differ
diff --git a/android/bin/classes/com/retroarch/R.class b/android/bin/classes/com/retroarch/R.class
new file mode 100644
index 0000000000..5f0f1bbb20
Binary files /dev/null and b/android/bin/classes/com/retroarch/R.class differ
diff --git a/android/bin/jarlist.cache b/android/bin/jarlist.cache
new file mode 100644
index 0000000000..1b5ec3f9c5
--- /dev/null
+++ b/android/bin/jarlist.cache
@@ -0,0 +1,3 @@
+# cache for current jar dependecy. DO NOT EDIT.
+# format is
+# Encoding is UTF-8
diff --git a/android/gen/com/retroarch/BuildConfig.java b/android/gen/com/retroarch/BuildConfig.java
new file mode 100644
index 0000000000..f7b068bd97
--- /dev/null
+++ b/android/gen/com/retroarch/BuildConfig.java
@@ -0,0 +1,6 @@
+/** Automatically generated file. DO NOT MODIFY */
+package com.retroarch;
+
+public final class BuildConfig {
+ public final static boolean DEBUG = true;
+}
\ No newline at end of file
diff --git a/android/gen/com/retroarch/R.java b/android/gen/com/retroarch/R.java
new file mode 100644
index 0000000000..083d090c3b
--- /dev/null
+++ b/android/gen/com/retroarch/R.java
@@ -0,0 +1,42 @@
+/* AUTO-GENERATED FILE. DO NOT MODIFY.
+ *
+ * This class was automatically generated by the
+ * aapt tool from the resource data it found. It
+ * should not be modified by hand.
+ */
+
+package com.retroarch;
+
+public final class R {
+ public static final class attr {
+ }
+ public static final class drawable {
+ public static final int ic_action_close=0x7f020000;
+ public static final int ic_action_history=0x7f020001;
+ public static final int ic_action_load=0x7f020002;
+ public static final int ic_action_open=0x7f020003;
+ public static final int ic_action_quit=0x7f020004;
+ public static final int ic_action_save=0x7f020005;
+ public static final int ic_action_settings=0x7f020006;
+ public static final int ic_launcher=0x7f020007;
+ }
+ public static final class id {
+ public static final int close=0x7f060001;
+ public static final int history=0x7f060004;
+ public static final int load=0x7f060002;
+ public static final int open=0x7f060000;
+ public static final int quit=0x7f060006;
+ public static final int save=0x7f060003;
+ public static final int settings=0x7f060005;
+ }
+ public static final class layout {
+ public static final int main=0x7f030000;
+ }
+ public static final class menu {
+ public static final int main_menu=0x7f050000;
+ }
+ public static final class string {
+ public static final int app_name=0x7f040001;
+ public static final int hello=0x7f040000;
+ }
+}
diff --git a/android/proguard-project.txt b/android/proguard-project.txt
new file mode 100644
index 0000000000..f2fe1559a2
--- /dev/null
+++ b/android/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/android/project.properties b/android/project.properties
new file mode 100644
index 0000000000..0840b4a059
--- /dev/null
+++ b/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-15
diff --git a/android/res/drawable-hdpi/ic_action_close.png b/android/res/drawable-hdpi/ic_action_close.png
new file mode 100644
index 0000000000..1c74f6df01
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_close.png differ
diff --git a/android/res/drawable-hdpi/ic_action_history.png b/android/res/drawable-hdpi/ic_action_history.png
new file mode 100644
index 0000000000..0d324e3cd0
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_history.png differ
diff --git a/android/res/drawable-hdpi/ic_action_load.png b/android/res/drawable-hdpi/ic_action_load.png
new file mode 100644
index 0000000000..3ef03ab59a
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_load.png differ
diff --git a/android/res/drawable-hdpi/ic_action_open.png b/android/res/drawable-hdpi/ic_action_open.png
new file mode 100644
index 0000000000..41233c5e00
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_open.png differ
diff --git a/android/res/drawable-hdpi/ic_action_quit.png b/android/res/drawable-hdpi/ic_action_quit.png
new file mode 100644
index 0000000000..10dc28fcbb
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_quit.png differ
diff --git a/android/res/drawable-hdpi/ic_action_save.png b/android/res/drawable-hdpi/ic_action_save.png
new file mode 100644
index 0000000000..dbc044c9d8
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_save.png differ
diff --git a/android/res/drawable-hdpi/ic_action_settings.png b/android/res/drawable-hdpi/ic_action_settings.png
new file mode 100644
index 0000000000..c73c92ec96
Binary files /dev/null and b/android/res/drawable-hdpi/ic_action_settings.png differ
diff --git a/android/res/drawable-hdpi/ic_launcher.png b/android/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..ea7613b8c4
Binary files /dev/null and b/android/res/drawable-hdpi/ic_launcher.png differ
diff --git a/android/res/drawable-ldpi/ic_action_close.png b/android/res/drawable-ldpi/ic_action_close.png
new file mode 100644
index 0000000000..65bf37c1d7
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_close.png differ
diff --git a/android/res/drawable-ldpi/ic_action_history.png b/android/res/drawable-ldpi/ic_action_history.png
new file mode 100644
index 0000000000..85f2127777
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_history.png differ
diff --git a/android/res/drawable-ldpi/ic_action_load.png b/android/res/drawable-ldpi/ic_action_load.png
new file mode 100644
index 0000000000..92ae2f321e
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_load.png differ
diff --git a/android/res/drawable-ldpi/ic_action_open.png b/android/res/drawable-ldpi/ic_action_open.png
new file mode 100644
index 0000000000..a291177360
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_open.png differ
diff --git a/android/res/drawable-ldpi/ic_action_quit.png b/android/res/drawable-ldpi/ic_action_quit.png
new file mode 100644
index 0000000000..203696e713
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_quit.png differ
diff --git a/android/res/drawable-ldpi/ic_action_save.png b/android/res/drawable-ldpi/ic_action_save.png
new file mode 100644
index 0000000000..929966cacb
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_save.png differ
diff --git a/android/res/drawable-ldpi/ic_action_settings.png b/android/res/drawable-ldpi/ic_action_settings.png
new file mode 100644
index 0000000000..7a3dc396bc
Binary files /dev/null and b/android/res/drawable-ldpi/ic_action_settings.png differ
diff --git a/android/res/drawable-ldpi/ic_launcher.png b/android/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000000..f969b747a2
Binary files /dev/null and b/android/res/drawable-ldpi/ic_launcher.png differ
diff --git a/android/res/drawable-mdpi/ic_action_close.png b/android/res/drawable-mdpi/ic_action_close.png
new file mode 100644
index 0000000000..af5a18a5fa
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_close.png differ
diff --git a/android/res/drawable-mdpi/ic_action_history.png b/android/res/drawable-mdpi/ic_action_history.png
new file mode 100644
index 0000000000..e75db82cb5
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_history.png differ
diff --git a/android/res/drawable-mdpi/ic_action_load.png b/android/res/drawable-mdpi/ic_action_load.png
new file mode 100644
index 0000000000..659c27fc84
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_load.png differ
diff --git a/android/res/drawable-mdpi/ic_action_open.png b/android/res/drawable-mdpi/ic_action_open.png
new file mode 100644
index 0000000000..9d0c7c070b
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_open.png differ
diff --git a/android/res/drawable-mdpi/ic_action_quit.png b/android/res/drawable-mdpi/ic_action_quit.png
new file mode 100644
index 0000000000..369120e38c
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_quit.png differ
diff --git a/android/res/drawable-mdpi/ic_action_save.png b/android/res/drawable-mdpi/ic_action_save.png
new file mode 100644
index 0000000000..45c25de467
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_save.png differ
diff --git a/android/res/drawable-mdpi/ic_action_settings.png b/android/res/drawable-mdpi/ic_action_settings.png
new file mode 100644
index 0000000000..522c8a9cf5
Binary files /dev/null and b/android/res/drawable-mdpi/ic_action_settings.png differ
diff --git a/android/res/drawable-mdpi/ic_launcher.png b/android/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..84f2bca830
Binary files /dev/null and b/android/res/drawable-mdpi/ic_launcher.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_close.png b/android/res/drawable-xhdpi/ic_action_close.png
new file mode 100644
index 0000000000..1c74f6df01
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_close.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_history.png b/android/res/drawable-xhdpi/ic_action_history.png
new file mode 100644
index 0000000000..0d324e3cd0
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_history.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_load.png b/android/res/drawable-xhdpi/ic_action_load.png
new file mode 100644
index 0000000000..3ef03ab59a
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_load.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_open.png b/android/res/drawable-xhdpi/ic_action_open.png
new file mode 100644
index 0000000000..41233c5e00
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_open.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_quit.png b/android/res/drawable-xhdpi/ic_action_quit.png
new file mode 100644
index 0000000000..041de185be
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_quit.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_save.png b/android/res/drawable-xhdpi/ic_action_save.png
new file mode 100644
index 0000000000..dbc044c9d8
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_save.png differ
diff --git a/android/res/drawable-xhdpi/ic_action_settings.png b/android/res/drawable-xhdpi/ic_action_settings.png
new file mode 100644
index 0000000000..c73c92ec96
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_action_settings.png differ
diff --git a/android/res/drawable-xhdpi/ic_launcher.png b/android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..a113106a99
Binary files /dev/null and b/android/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/android/res/layout/main.xml b/android/res/layout/main.xml
new file mode 100644
index 0000000000..bc12cd8231
--- /dev/null
+++ b/android/res/layout/main.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/res/menu/main_menu.xml b/android/res/menu/main_menu.xml
new file mode 100644
index 0000000000..bdf9374246
--- /dev/null
+++ b/android/res/menu/main_menu.xml
@@ -0,0 +1,13 @@
+
+
diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml
new file mode 100644
index 0000000000..1e2ffa990e
--- /dev/null
+++ b/android/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+
+
+ Hello World, MainActivity!
+ RetroArch
+
+
\ No newline at end of file
diff --git a/android/src/com/retroarch/MainActivity.java b/android/src/com/retroarch/MainActivity.java
new file mode 100644
index 0000000000..957f352602
--- /dev/null
+++ b/android/src/com/retroarch/MainActivity.java
@@ -0,0 +1,69 @@
+package com.retroarch;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.Toast;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class MainActivity extends Activity
+{
+ private GLSurfaceView ctx_gl;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ ctx_gl = new rgl_context(this);
+ setContentView(ctx_gl);
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.main_menu, menu);
+ return true;
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch (item.getItemId())
+ {
+ case R.id.quit:
+ android.os.Process.killProcess(android.os.Process.myPid());
+ return true;
+ default:
+ Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show();
+ return true;
+ }
+ }
+
+ @Override
+ protected void onPause()
+ {
+ super.onPause();
+ ctx_gl.onPause();
+ }
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+ ctx_gl.onResume();
+ }
+}
+
+class rgl_context extends GLSurfaceView
+{
+ public rgl_context(Context context)
+ {
+ super(context);
+ setEGLContextClientVersion(2);
+ setRenderer(new rgl());
+ }
+}
\ No newline at end of file
diff --git a/android/src/com/retroarch/audio_android.java b/android/src/com/retroarch/audio_android.java
new file mode 100644
index 0000000000..c12d649fd4
--- /dev/null
+++ b/android/src/com/retroarch/audio_android.java
@@ -0,0 +1,130 @@
+package com.retroarch;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+
+public class audio_android
+{
+ private static AudioTrack _track;
+ private static int _minSamples;
+ private static float _volume = AudioTrack.getMaxVolume();
+
+ private static int _rate;
+ private static int _bits;
+ private static int _channels;
+
+
+ private audio_android()
+ {
+
+ }
+
+
+ public static void pause()
+ {
+ if (_track != null && _track.getPlayState() != AudioTrack.PLAYSTATE_PAUSED)
+ _track.pause();
+ }
+
+
+ public static void resume()
+ {
+ if (_track != null && _track.getPlayState() != AudioTrack.PLAYSTATE_PLAYING)
+ _track.play();
+ }
+
+ public int getMinSamples()
+ {
+ return _minSamples;
+ }
+
+
+ public static int write(short[] data, int size)
+ {
+ int retVal = 0;
+ if (_track == null)
+ return retVal;
+
+ retVal = _track.write(data, 0, size);
+
+ return retVal;
+ }
+
+
+ void set_volume(int vol)
+ {
+ final float min = AudioTrack.getMinVolume();
+ final float max = AudioTrack.getMaxVolume();
+ _volume = min + (max - min) * vol / 100;
+
+ if (_track != null)
+ _track.setStereoVolume(_volume, _volume);
+ }
+
+
+ public static void free()
+ {
+ if (_track != null)
+ {
+ _track.pause();
+ _track.release();
+ _track = null;
+ }
+ }
+
+
+ public static boolean init(int rate, int bits, int channels)
+ {
+ _track = null;
+ _rate = rate;
+ _bits = bits;
+ _channels = channels;
+
+ // generate format
+ int format = (_bits == 16
+ ? AudioFormat.ENCODING_PCM_16BIT
+ : AudioFormat.ENCODING_PCM_8BIT);
+
+ // determine channel config
+ int channelConfig = (_channels == 2
+ ? AudioFormat.CHANNEL_OUT_STEREO
+ : AudioFormat.CHANNEL_OUT_MONO);
+
+ int bufferSize = AudioTrack.getMinBufferSize(_rate, channelConfig,
+ format);
+
+ _minSamples = bufferSize;
+
+ try
+ {
+ _track = new AudioTrack(
+ AudioManager.STREAM_MUSIC,
+ _rate,
+ channelConfig,
+ format,
+ bufferSize,
+ AudioTrack.MODE_STREAM);
+
+ if (_track.getState() == AudioTrack.STATE_UNINITIALIZED)
+ _track = null;
+
+ }
+ catch (IllegalArgumentException e)
+ {
+ _track = null;
+ return false;
+ }
+
+ // set max volume
+ _track.setStereoVolume(_volume, _volume);
+
+ return true;
+ }
+
+
+ public static int getMaxBufferSize()
+ {
+ return _minSamples;
+ }
+}
diff --git a/android/src/com/retroarch/rgl.java b/android/src/com/retroarch/rgl.java
new file mode 100644
index 0000000000..7c71ca21fb
--- /dev/null
+++ b/android/src/com/retroarch/rgl.java
@@ -0,0 +1,95 @@
+package com.retroarch;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.ByteOrder;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+
+public class rgl implements GLSurfaceView.Renderer
+{
+ private int cprg;
+ private int v_position_handle;
+ private FloatBuffer triangle_vbo;
+
+ private void triangles_init()
+ {
+ float triangle_coords[] = {
+ // X, Y, Z
+ -0.5f, -0.25f, 0,
+ 0.5f, -0.25f, 0,
+ 0.0f, 0.559016994f, 0
+ };
+
+ ByteBuffer vbb = ByteBuffer.allocateDirect(triangle_coords.length * 4);
+ vbb.order(ByteOrder.nativeOrder());
+ triangle_vbo = vbb.asFloatBuffer();
+ triangle_vbo.put(triangle_coords);
+ triangle_vbo.position(0);
+ }
+
+ private void shader_init()
+ {
+ final String vprg =
+ "attribute vec4 vPosition; \n" +
+ "void main(){ \n" +
+ " gl_Position = vPosition; \n" +
+ "} \n";
+ final String fprg =
+ "precision mediump float; \n" +
+ "void main(){ \n" +
+ " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" +
+ "} \n";
+
+ int vertex_shader, fragment_shader;
+
+ vertex_shader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
+
+ GLES20.glShaderSource(vertex_shader, vprg);
+ GLES20.glCompileShader(vertex_shader);
+
+ fragment_shader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
+
+ GLES20.glShaderSource(fragment_shader, fprg);
+ GLES20.glCompileShader(fragment_shader);
+
+ cprg = GLES20.glCreateProgram();
+ GLES20.glAttachShader(cprg, vertex_shader);
+ GLES20.glAttachShader(cprg, fragment_shader);
+ GLES20.glLinkProgram(cprg);
+
+ //get handle to the vertex shader's vPosition member
+ v_position_handle = GLES20.glGetAttribLocation(cprg, "vPosition");
+; }
+
+ public void onSurfaceCreated(GL10 unused, EGLConfig config)
+ {
+ //background color
+ GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+
+ triangles_init();
+ shader_init();
+ }
+
+ public void onDrawFrame(GL10 unused)
+ {
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+
+ GLES20.glUseProgram(cprg);
+
+ // Triangle
+ GLES20.glVertexAttribPointer(v_position_handle, 3, GLES20.GL_FLOAT, false, 12, triangle_vbo);
+ GLES20.glEnableVertexAttribArray(v_position_handle);
+
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
+ }
+
+ public void onSurfaceChanged(GL10 unused, int width, int height)
+ {
+ GLES20.glViewport(0, 0, width, height);
+ }
+}
diff --git a/config.features.h b/config.features.h
index 6060a4ab73..d05067885d 100644
--- a/config.features.h
+++ b/config.features.h
@@ -110,6 +110,12 @@ static const bool _sdl_image_supp = true;
static const bool _sdl_image_supp = false;
#endif
+#ifdef HAVE_LIBPNG
+static const bool _libpng_supp = true;
+#else
+static const bool _libpng_supp = false;
+#endif
+
#ifdef HAVE_FBO
static const bool _fbo_supp = true;
#else
diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c
index b5fc50b23f..039f0f792c 100644
--- a/console/fileio/file_browser.c
+++ b/console/fileio/file_browser.c
@@ -14,216 +14,37 @@
* If not, see .
*/
-#ifdef _XBOX
-#include
-#endif
#include "file_browser.h"
-static int less_than_key(const void * a, const void * b)
-{
- DirectoryEntry * a_dir = (DirectoryEntry*)a;
- DirectoryEntry * b_dir = (DirectoryEntry*)b;
-
- /* compare a directory to a file directory is always lesser than*/
- if ((a_dir->d_type == FS_TYPES_DIRECTORY && b_dir->d_type == FS_TYPES_FILE))
- return -1;
- else if (a_dir->d_type == FS_TYPES_FILE && b_dir->d_type == FS_TYPES_DIRECTORY)
- return 1;
-
- return strcasecmp(a_dir->d_name, b_dir->d_name);
-}
-
-static const char * filebrowser_get_extension(const char * filename)
-{
- const char * ext = strrchr(filename, '.');
-
- if (ext)
- return ext+1;
- else
- return "";
-}
-
-static void filebrowser_clear_current_entries(filebrowser_t * filebrowser)
-{
- for(uint32_t i = 0; i < MAX_FILE_LIMIT; i++)
- {
- filebrowser->cur[filebrowser->file_count].d_type = 0;
- filebrowser->cur[filebrowser->file_count].d_namlen = 0;
- strlcpy(filebrowser->cur[filebrowser->file_count].d_name, "\0", sizeof(filebrowser->cur[filebrowser->file_count].d_name));
- }
-}
-
static void filebrowser_parse_directory(filebrowser_t * filebrowser,
const char * path, const char * extensions)
{
- int error = 0;
-#if defined(_XBOX)
- filebrowser->file_count = 0;
+ strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path,
+ sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
- WIN32_FIND_DATA ffd;
- HANDLE hFind = INVALID_HANDLE_VALUE;
+ filebrowser->current_dir.elems = dir_list_new(path, extensions, true);
+ filebrowser->current_dir.size = dir_list_size(filebrowser->current_dir.elems);
+ filebrowser->current_dir.ptr = 0;
- char path_buf[PATH_MAX];
-
- if (strlcpy(path_buf, path, sizeof(path_buf)) >= sizeof(path_buf))
- {
- error = 1;
- goto error;
- }
- if (strlcat(path_buf, "\\*", sizeof(path_buf)) >= sizeof(path_buf))
- {
- error = 1;
- goto error;
- }
-
- hFind = FindFirstFile(path_buf, &ffd);
- if (hFind == INVALID_HANDLE_VALUE)
- {
- error = 1;
- goto error;
- }
-
- do
- {
- strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
- bool found_dir = false;
-
- if(!(ffd.dwFileAttributes & FS_TYPES_DIRECTORY))
- {
- char tmp_extensions[512];
- strlcpy(tmp_extensions, extensions, sizeof(tmp_extensions));
- const char * current_extension = filebrowser_get_extension(ffd.cFileName);
- bool found_rom = false;
-
- if(current_extension)
- {
- char * pch = strtok(tmp_extensions, "|");
- while (pch != NULL)
- {
- if(strcmp(current_extension, pch) == 0)
- {
- found_rom = true;
- break;
- }
- pch = strtok(NULL, "|");
- }
- }
-
- if(!found_rom)
- continue;
- }
- else if (ffd.dwFileAttributes & FS_TYPES_DIRECTORY)
- found_dir = true;
-
- filebrowser->cur[filebrowser->file_count].d_type = found_dir ? FS_TYPES_DIRECTORY : FS_TYPES_FILE;
- snprintf(filebrowser->cur[filebrowser->file_count].d_name, sizeof(filebrowser->cur[filebrowser->file_count].d_name), ffd.cFileName);
-
- filebrowser->file_count++;
- }while (FindNextFile(hFind, &ffd) != 0 && (filebrowser->file_count + 1) < MAX_FILE_LIMIT);
-#elif defined(__CELLOS_LV2__)
- int fd;
-
- /* bad path*/
- if (strcmp(path,"") == 0)
- {
- error = 1;
- goto error;
- }
-
- /* delete old path*/
- filebrowser_clear_current_entries(filebrowser);
-
- if (cellFsOpendir(path, &fd) == CELL_FS_SUCCEEDED)
- {
- uint64_t nread = 0;
-
- strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
-
- filebrowser->file_count = 0;
- filebrowser->currently_selected = 0;
-
- CellFsDirent dirent;
-
- while (cellFsReaddir(fd, &dirent, &nread) == CELL_FS_SUCCEEDED)
- {
- if (nread == 0)
- break;
-
- if ((dirent.d_type != FS_TYPES_FILE) && (dirent.d_type != FS_TYPES_DIRECTORY))
- continue;
-
- if (dirent.d_type == FS_TYPES_DIRECTORY && !(strcmp(dirent.d_name, ".")))
- continue;
-
- if (dirent.d_type == FS_TYPES_FILE)
- {
- char tmp_extensions[512];
- strlcpy(tmp_extensions, extensions, sizeof(tmp_extensions));
- const char * current_extension = filebrowser_get_extension(dirent.d_name);
- bool found_rom = false;
-
- if(current_extension)
- {
- char * pch = strtok(tmp_extensions, "|");
- while (pch != NULL)
- {
- if(strcmp(current_extension, pch) == 0)
- {
- found_rom = true;
- break;
- }
- pch = strtok(NULL, "|");
- }
- }
-
- if(!found_rom)
- continue;
- }
-
- filebrowser->cur[filebrowser->file_count].d_type = dirent.d_type;
- filebrowser->cur[filebrowser->file_count].d_namlen = dirent.d_namlen;
- strlcpy(filebrowser->cur[filebrowser->file_count].d_name, dirent.d_name, sizeof(filebrowser->cur[filebrowser->file_count].d_name));
-
- ++filebrowser->file_count;
- }
-
- cellFsClosedir(fd);
- }
- else
- {
- error = 1;
- goto error;
- }
-#endif
- qsort(filebrowser->cur, filebrowser->file_count, sizeof(DirectoryEntry), less_than_key);
- error:
- if(error)
- {
- RARCH_ERR("Failed to open directory: \"%s\"\n", path);
- }
-#ifdef _XBOX
- FindClose(hFind);
-#endif
+ dir_list_sort(filebrowser->current_dir.elems, true);
}
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir,
const char * extensions)
{
- filebrowser_clear_current_entries(filebrowser);
filebrowser->directory_stack_size = 0;
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
- filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
+ filebrowser_parse_directory(filebrowser, start_dir, extensions);
}
-
-void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir,
-const char * extensions)
+void filebrowser_free(filebrowser_t * filebrowser)
{
- filebrowser->directory_stack_size = 0;
- strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
+ dir_list_free(filebrowser->current_dir.elems);
- filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
+ filebrowser->current_dir.elems = NULL;
+ filebrowser->current_dir.size = 0;
+ filebrowser->current_dir.ptr = 0;
}
void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path,
@@ -244,3 +65,8 @@ void filebrowser_pop_directory (filebrowser_t * filebrowser)
filebrowser_parse_directory(filebrowser, filebrowser->dir[filebrowser->directory_stack_size],
filebrowser->extensions);
}
+
+const char * filebrowser_get_current_path (filebrowser_t *filebrowser)
+{
+ return filebrowser->current_dir.elems[filebrowser->current_dir.ptr];
+}
diff --git a/console/fileio/file_browser.h b/console/fileio/file_browser.h
index 6fb77f70e1..6759876403 100644
--- a/console/fileio/file_browser.h
+++ b/console/fileio/file_browser.h
@@ -17,89 +17,63 @@
#ifndef FILEBROWSER_H_
#define FILEBROWSER_H_
-#define MAXJOLIET 255
#define MAX_DIR_STACK 25
#include
#include
-#ifdef __CELLOS_LV2__
-#include
-#include
-#include
-#define FS_MAX_PATH 256
-#define FS_MAX_FS_PATH_LENGTH 255
-#define MAX_FILE_LIMIT 8192
-#elif defined(_XBOX)
-#define FS_MAX_PATH MAX_PATH
-#define FS_MAX_FS_PATH_LENGTH 2048
-#define MAX_FILE_LIMIT 4096
-#endif
-
-#if defined(_XBOX)
-#define FS_TYPES_DIRECTORY (FILE_ATTRIBUTE_DIRECTORY)
-#define FS_TYPES_FILE (FILE_ATTRIBUTE_NORMAL)
-#elif defined(__CELLOS_LV2__)
-#define FS_TYPES_DIRECTORY (CELL_FS_TYPE_DIRECTORY)
-#define FS_TYPES_FILE (CELL_FS_TYPE_REGULAR)
-#endif
-
-typedef struct {
- uint8_t d_type;
- uint8_t d_namlen;
- char d_name[FS_MAX_PATH];
-} DirectoryEntry;
-
typedef struct
{
- uint32_t file_count; /* amount of files in current dir*/
- uint32_t currently_selected; /* currently select browser entry*/
uint32_t directory_stack_size;
- char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; /* info of the current directory*/
- DirectoryEntry cur[MAX_FILE_LIMIT]; /* current file listing*/
- char extensions[FS_MAX_PATH]; /* allowed extensions*/
+ char dir[MAX_DIR_STACK][512];
+ struct {
+ char **elems;
+ size_t size;
+ size_t ptr;
+ } current_dir;
+ char extensions[PATH_MAX];
} filebrowser_t;
-void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
-void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
+void filebrowser_new(filebrowser_t *filebrowser, const char * start_dir, const char * extensions);
+void filebrowser_free(filebrowser_t *filebrowser);
void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension);
void filebrowser_pop_directory (filebrowser_t * filebrowser);
#define FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(filebrowser) (filebrowser.dir[filebrowser.directory_stack_size])
-#define FILEBROWSER_GET_CURRENT_DIRECTORY_FILE_COUNT(filebrowser) (filebrowser.file_count)
-#define FILEBROWSER_GOTO_ENTRY(filebrowser, i) filebrowser.currently_selected = i;
+#define FILEBROWSER_GET_CURRENT_DIRECTORY_FILE_COUNT(filebrowser) (filebrowser.current_dir.size)
+#define FILEBROWSER_GOTO_ENTRY(filebrowser, i) filebrowser.current_dir.ptr = i;
#define FILEBROWSER_INCREMENT_ENTRY(filebrowser) \
{ \
- filebrowser.currently_selected++; \
- if (filebrowser.currently_selected >= filebrowser.file_count) \
- filebrowser.currently_selected = 0; \
+ filebrowser.current_dir.ptr++; \
+ if (filebrowser.current_dir.ptr >= filebrowser.current_dir.size) \
+ filebrowser.current_dir.ptr = 0; \
}
#define FILEBROWSER_INCREMENT_ENTRY_POINTER(filebrowser) \
{ \
- filebrowser->currently_selected++; \
- if (filebrowser->currently_selected >= filebrowser->file_count) \
- filebrowser->currently_selected = 0; \
+ filebrowser->current_dir.ptr++; \
+ if (filebrowser->current_dir.ptr >= filebrowser->current_dir.size) \
+ filebrowser->current_dir.ptr = 0; \
}
#define FILEBROWSER_DECREMENT_ENTRY(filebrowser) \
{ \
- filebrowser.currently_selected--; \
- if (filebrowser.currently_selected >= filebrowser.file_count) \
- filebrowser.currently_selected = filebrowser.file_count - 1; \
+ filebrowser.current_dir.ptr--; \
+ if (filebrowser.current_dir.ptr >= filebrowser.current_dir.size) \
+ filebrowser.current_dir.ptr = filebrowser.current_dir.size - 1; \
}
#define FILEBROWSER_DECREMENT_ENTRY_POINTER(filebrowser) \
{ \
- filebrowser->currently_selected--; \
- if (filebrowser->currently_selected >= filebrowser->file_count) \
- filebrowser->currently_selected = filebrowser->file_count - 1; \
+ filebrowser->current_dir.ptr--; \
+ if (filebrowser->current_dir.ptr >= filebrowser->current_dir.size) \
+ filebrowser->current_dir.ptr = filebrowser->current_dir.size - 1; \
}
-#define FILEBROWSER_GET_CURRENT_FILENAME(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_name)
-#define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.currently_selected)
-#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_type == CELL_FS_TYPE_REGULAR)
-#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_type == CELL_FS_TYPE_DIRECTORY)
+#define FILEBROWSER_GET_CURRENT_FILENAME(filebrowser) (filebrowser.current_dir.elems[filebrowser.current_dir.ptr])
+#define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.current_dir.ptr)
+#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (path_file_exists(filebrowser.current_dir.elems[filebrowser.current_dir.ptr]))
+#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (path_is_directory(filebrowser.current_dir.elems[filebrowser.current_dir.ptr]))
#endif /* FILEBROWSER_H_ */
diff --git a/console/libretro_mgmt.c b/console/libretro_mgmt.c
index 48ed9a6dca..f023339ebf 100644
--- a/console/libretro_mgmt.c
+++ b/console/libretro_mgmt.c
@@ -43,13 +43,10 @@ const char *rarch_manage_libretro_install(const char *full_path, const char *pat
// file first.
RARCH_LOG("Upgrading emulator core...\n");
-#if defined(__CELLOS_LV2__)
- ret = cellFsUnlink(tmp_pathnewfile);
- if (ret == CELL_FS_SUCCEEDED)
-#elif defined(_XBOX)
- ret = DeleteFile(tmp_pathnewfile);
- if (ret != 0)
-#endif
+
+ ret = remove(tmp_pathnewfile);
+
+ if (ret == 0)
{
RARCH_LOG("Succeeded in removing pre-existing libretro core: [%s].\n", tmp_pathnewfile);
}
@@ -58,26 +55,21 @@ const char *rarch_manage_libretro_install(const char *full_path, const char *pat
}
//now attempt the renaming.
-#if defined(__CELLOS_LV2__)
- ret = cellFsRename(full_path, tmp_pathnewfile);
+ ret = rename(full_path, tmp_pathnewfile);
- if (ret != CELL_FS_SUCCEEDED)
-#elif defined(_XBOX)
- ret = MoveFileExA(full_path, tmp_pathnewfile, NULL);
if (ret == 0)
-#endif
- {
- RARCH_ERR("Failed to rename CORE executable.\n");
- }
- else
{
RARCH_LOG("Libsnes core [%s] renamed to: [%s].\n", full_path, tmp_pathnewfile);
retstr = tmp_pathnewfile;
goto done;
}
+ else
+ {
+ RARCH_ERR("Failed to rename CORE executable.\n");
+ RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n");
+ }
}
- RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n");
done:
return retstr;
}
diff --git a/console/salamander/main.c b/console/salamander/main.c
index 8fb038e22e..9b26aaaaac 100644
--- a/console/salamander/main.c
+++ b/console/salamander/main.c
@@ -87,9 +87,9 @@ static void find_and_set_first_file(void)
// we can find in the RetroArch cores directory
#if defined(_XBOX)
- char ** dir_list = dir_list_new("game:\\", ".xex", false);
+ char ** dir_list = dir_list_new("game:\\", "xex", false);
#elif defined(__CELLOS_LV2__)
- char ** dir_list = dir_list_new(LIBRETRO_DIR_PATH, ".SELF", false);
+ char ** dir_list = dir_list_new(LIBRETRO_DIR_PATH, "SELF", false);
#endif
if (!dir_list)
diff --git a/driver.c b/driver.c
index 9f4fb80cdf..3cbf5f2d18 100644
--- a/driver.c
+++ b/driver.c
@@ -403,6 +403,12 @@ static void init_filter(void)
if (*g_settings.video.filter_path == '\0')
return;
+ if (g_extern.system.rgb32)
+ {
+ RARCH_WARN("libretro implementation uses XRGB8888 format. CPU filters only support 0RGB1555.\n");
+ return;
+ }
+
RARCH_LOG("Loading bSNES filter from \"%s\"\n", g_settings.video.filter_path);
g_extern.filter.lib = dylib_load(g_settings.video.filter_path);
if (!g_extern.filter.lib)
@@ -417,6 +423,7 @@ static void init_filter(void)
(void (*)(uint32_t*, uint32_t*,
unsigned, const uint16_t*,
unsigned, unsigned, unsigned))dylib_proc(g_extern.filter.lib, "filter_render");
+
if (!g_extern.filter.psize || !g_extern.filter.prender)
{
RARCH_ERR("Failed to find functions in filter...\n");
@@ -428,28 +435,30 @@ static void init_filter(void)
g_extern.filter.active = true;
struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
- unsigned width = geom->max_width;
+ unsigned width = geom->max_width;
unsigned height = geom->max_height;
g_extern.filter.psize(&width, &height);
- unsigned pow2_x = next_pow2(width);
- unsigned pow2_y = next_pow2(height);
+ unsigned pow2_x = next_pow2(width);
+ unsigned pow2_y = next_pow2(height);
unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
g_extern.filter.scale = maxsize / RARCH_SCALE_BASE;
- g_extern.filter.buffer = (uint32_t*)malloc(RARCH_SCALE_BASE * RARCH_SCALE_BASE * g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
- g_extern.filter.pitch = RARCH_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t);
+ g_extern.filter.buffer = (uint32_t*)malloc(RARCH_SCALE_BASE * RARCH_SCALE_BASE *
+ g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
rarch_assert(g_extern.filter.buffer);
- g_extern.filter.colormap = (uint32_t*)malloc(32768 * sizeof(uint32_t));
+ g_extern.filter.pitch = RARCH_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t);
+
+ g_extern.filter.colormap = (uint32_t*)malloc(0x10000 * sizeof(uint32_t));
rarch_assert(g_extern.filter.colormap);
// Set up conversion map from 16-bit XRGB1555 to 32-bit ARGB.
- for (unsigned i = 0; i < 32768; i++)
+ for (unsigned i = 0; i < 0x10000; i++)
{
- unsigned r = (i >> 10) & 31;
- unsigned g = (i >> 5) & 31;
- unsigned b = (i >> 0) & 31;
+ unsigned r = (i >> 10) & 0x1f;
+ unsigned g = (i >> 5) & 0x1f;
+ unsigned b = (i >> 0) & 0x1f;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
@@ -477,17 +486,14 @@ static void init_shader_dir(void)
if (!*g_settings.video.shader_dir)
return;
- g_extern.shader_dir.elems = dir_list_new(g_settings.video.shader_dir, ".shader", false);
- g_extern.shader_dir.size = 0;
- g_extern.shader_dir.ptr = 0;
- if (g_extern.shader_dir.elems)
- {
- while (g_extern.shader_dir.elems[g_extern.shader_dir.size])
- {
- RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.elems[g_extern.shader_dir.size]);
- g_extern.shader_dir.size++;
- }
- }
+ g_extern.shader_dir.elems = dir_list_new(g_settings.video.shader_dir, "shader", false);
+ g_extern.shader_dir.size = dir_list_size(g_extern.shader_dir.elems);
+ g_extern.shader_dir.ptr = 0;
+
+ dir_list_sort(g_extern.shader_dir.elems, false);
+
+ for (unsigned i = 0; i < g_extern.shader_dir.size; i++)
+ RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.elems[i]);
}
static void deinit_shader_dir(void)
@@ -495,8 +501,8 @@ static void deinit_shader_dir(void)
// It handles NULL, no worries :D
dir_list_free(g_extern.shader_dir.elems);
g_extern.shader_dir.elems = NULL;
- g_extern.shader_dir.size = 0;
- g_extern.shader_dir.ptr = 0;
+ g_extern.shader_dir.size = 0;
+ g_extern.shader_dir.ptr = 0;
}
#endif
@@ -559,7 +565,7 @@ void init_video_input(void)
video.force_aspect = g_settings.video.force_aspect;
video.smooth = g_settings.video.smooth;
video.input_scale = scale;
- video.rgb32 = g_extern.filter.active;
+ video.rgb32 = g_extern.filter.active || g_extern.system.rgb32;
const input_driver_t *tmp = driver.input;
driver.video_data = video_init_func(&video, &driver.input, &driver.input_data);
diff --git a/dynamic.c b/dynamic.c
index 61120b5818..6b24ab2322 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -331,6 +331,31 @@ static bool environment_cb(unsigned cmd, void *data)
RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n", g_settings.system_directory);
break;
+ case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT:
+ {
+ enum retro_pixel_format pix_fmt = *(const enum retro_pixel_format*)data;
+ bool rgb32 = false;
+ switch (pix_fmt)
+ {
+ case RETRO_PIXEL_FORMAT_0RGB1555:
+ rgb32 = false;
+ RARCH_LOG("Environ SET_PIXEL_FORMAT: 0RGB1555.\n");
+ break;
+
+#ifndef RARCH_CONSOLE
+ case RETRO_PIXEL_FORMAT_XRGB8888:
+ rgb32 = true;
+ RARCH_LOG("Environ SET_PIXEL_FORMAT: XRGB8888.\n");
+ break;
+#endif
+ default:
+ return false;
+ }
+
+ g_extern.system.rgb32 = rgb32;
+ break;
+ }
+
default:
RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
return false;
diff --git a/file.h b/file.h
index 2ad5972181..b4f4179bb0 100644
--- a/file.h
+++ b/file.h
@@ -24,10 +24,6 @@
#include
#include "general.h"
-#ifdef __CELLOS_LV2__
-#include
-#endif
-
// Generic file, path and directory handling.
ssize_t read_file(const char *path, void **buf);
@@ -44,6 +40,8 @@ bool init_rom_file(enum rarch_game_type type);
// If ext is NULL, any file will be picked.
// If non-NULL, only files with extension ext are added.
char **dir_list_new(const char *dir, const char *ext, bool include_dirs);
+size_t dir_list_size(char * const *dir_list);
+void dir_list_sort(char **dir_list, bool dir_first);
void dir_list_free(char **dir_list);
bool path_is_directory(const char *path);
diff --git a/file_path.c b/file_path.c
index 009c56106c..860f3cf69e 100644
--- a/file_path.c
+++ b/file_path.c
@@ -20,9 +20,10 @@
#include
#include
#include "compat/strl.h"
+#include "compat/posix_string.h"
#ifdef __CELLOS_LV2__
-#include
+#define S_ISDIR(x) (x & CELL_FS_S_IFDIR)
#endif
#if defined(_WIN32) && !defined(_XBOX)
@@ -43,141 +44,273 @@
#endif
// Yep, this is C alright ;)
-char **dir_list_new(const char *dir, const char *ext, bool include_dirs)
+struct string_list
{
- size_t cur_ptr = 0;
- size_t cur_size = 32;
- char **dir_list = NULL;
+ char **data;
+ size_t size;
+ size_t cap;
+};
-#ifdef _WIN32
- WIN32_FIND_DATA ffd;
- HANDLE hFind = INVALID_HANDLE_VALUE;
+static bool string_list_capacity(struct string_list *list, size_t cap)
+{
+ rarch_assert(cap > list->size);
- char path_buf[PATH_MAX];
+ char **new_data = (char**)realloc(list->data, cap * sizeof(char*));
+ if (!new_data)
+ return false;
- if (strlcpy(path_buf, dir, sizeof(path_buf)) >= sizeof(path_buf))
- goto error;
-#ifdef _XBOX
- if (strlcat(path_buf, "*", sizeof(path_buf)) >= sizeof(path_buf))
-#else
- if (strlcat(path_buf, "/*", sizeof(path_buf)) >= sizeof(path_buf))
-#endif
+ list->data = new_data;
+ list->cap = cap;
+ return true;
+}
+
+static bool string_list_init(struct string_list *list)
+{
+ memset(list, 0, sizeof(*list));
+ return string_list_capacity(list, 32);
+}
+
+static bool string_list_append(struct string_list *list, const char *elem)
+{
+ if (list->size + 1 >= list->cap && !string_list_capacity(list, list->cap * 2))
+ return false;
+
+ if (!(list->data[list->size] = strdup(elem)))
+ return false;
+
+ list->size++;
+ return true;
+}
+
+static char **string_list_finalize(struct string_list *list)
+{
+ rarch_assert(list->cap > list->size);
+
+ list->data[list->size] = NULL;
+ return list->data;
+}
+
+static void string_list_cleanup(struct string_list *list)
+{
+ for (size_t i = 0; i < list->size; i++)
+ free(list->data[i]);
+ free(list->data);
+ memset(list, 0, sizeof(*list));
+}
+
+static void string_list_free(char **list)
+{
+ if (!list)
+ return;
+
+ char **orig = list;
+ while (*list)
+ free(*list++);
+ free(orig);
+}
+
+static char **string_split(const char *str, const char *delim)
+{
+ char *copy = NULL;
+ const char *tmp = NULL;
+ struct string_list list;
+
+ if (!string_list_init(&list))
goto error;
- if (ext)
+ copy = strdup(str);
+ if (!copy)
+ return NULL;
+
+ tmp = strtok(copy, delim);
+ while (tmp)
{
- if (strlcat(path_buf, ext, sizeof(path_buf)) >= sizeof(path_buf))
- goto error;
- }
-
- hFind = FindFirstFile(path_buf, &ffd);
- if (hFind == INVALID_HANDLE_VALUE)
- goto error;
-#else
- DIR *directory = NULL;
- const struct dirent *entry = NULL;
-
- directory = opendir(dir);
- if (!directory)
- goto error;
-#endif
-
- dir_list = (char**)calloc(cur_size, sizeof(char*));
- if (!dir_list)
- goto error;
-
-#ifdef _WIN32 // Hard to read? Blame non-POSIX heathens!
- do
-#else
- while ((entry = readdir(directory)))
-#endif
- {
- // Not a perfect search of course, but hopefully good enough in practice.
-#ifdef _WIN32
- if (include_dirs)
- {
- if (ext && !strstr(ffd.cFileName, ext) && !path_is_directory(ffd.cFileName))
- continue;
- }
- else
- {
- if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- continue;
- if (ext && !strstr(ffd.cFileName, ext))
- continue;
- }
-#else
- if (include_dirs)
- {
- if (ext && !strstr(entry->d_name, ext) && !path_is_directory(entry->d_name))
- continue;
- }
- else
- {
- if (ext && !strstr(entry->d_name, ext))
- continue;
- }
-#endif
-
- dir_list[cur_ptr] = (char*)malloc(PATH_MAX);
- if (!dir_list[cur_ptr])
+ if (!string_list_append(&list, tmp))
goto error;
- strlcpy(dir_list[cur_ptr], dir, PATH_MAX);
-#ifndef _XBOX
- strlcat(dir_list[cur_ptr], "/", PATH_MAX);
-#endif
-#ifdef _WIN32
- strlcat(dir_list[cur_ptr], ffd.cFileName, PATH_MAX);
-#else
- strlcat(dir_list[cur_ptr], entry->d_name, PATH_MAX);
-#endif
-
- cur_ptr++;
- if (cur_ptr + 1 == cur_size) // Need to reserve for NULL.
- {
- cur_size *= 2;
- dir_list = (char**)realloc(dir_list, cur_size * sizeof(char*));
- if (!dir_list)
- goto error;
-
- // Make sure it's all NULL'd out since we cannot rely on realloc to do this.
- memset(dir_list + cur_ptr, 0, (cur_size - cur_ptr) * sizeof(char*));
- }
+ tmp = strtok(NULL, delim);
}
-#if defined(_WIN32)
- while (FindNextFile(hFind, &ffd) != 0);
-#endif
-#ifdef _WIN32
- FindClose(hFind);
-#else
- closedir(directory);
-#endif
- return dir_list;
+ free(copy);
+ return string_list_finalize(&list);
error:
- RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
-#ifdef _WIN32
- if (hFind != INVALID_HANDLE_VALUE)
- FindClose(hFind);
-#else
- if (directory)
- closedir(directory);
-#endif
- dir_list_free(dir_list);
+ string_list_cleanup(&list);
+ free(copy);
return NULL;
}
-void dir_list_free(char **dir_list)
+static bool string_list_find_elem(char * const *list, const char *elem)
+{
+ if (!list)
+ return false;
+
+ for (; *list; list++)
+ if (strcmp(*list, elem) == 0)
+ return true;
+
+ return false;
+}
+
+static const char *path_get_extension(const char *path)
+{
+ const char *ext = strrchr(path, '.');
+ if (ext)
+ return ext + 1;
+ else
+ return "";
+}
+
+size_t dir_list_size(char * const *dir_list)
+{
+ if (!dir_list)
+ return 0;
+
+ size_t size = 0;
+ while (*dir_list++)
+ size++;
+
+ return size;
+}
+
+static int qstrcmp_plain(const void *a, const void *b)
+{
+ return strcasecmp(*(const char * const*)a, *(const char * const*)b);
+}
+
+static int qstrcmp_dir(const void *a_, const void *b_)
+{
+ const char *a = *(const char * const*)a_;
+ const char *b = *(const char * const*)b_;
+
+ // Sort directories before files.
+ int a_dir = path_is_directory(a);
+ int b_dir = path_is_directory(b);
+ if (a_dir != b_dir)
+ return b_dir - a_dir;
+
+ return strcasecmp(a, b);
+}
+
+void dir_list_sort(char **dir_list, bool dir_first)
{
if (!dir_list)
return;
- char **orig = dir_list;
- while (*dir_list)
- free(*dir_list++);
- free(orig);
+ qsort(dir_list, dir_list_size(dir_list), sizeof(char*), dir_first ? qstrcmp_dir : qstrcmp_plain);
+}
+
+#ifdef _WIN32 // Because the API is just fucked up ...
+char **dir_list_new(const char *dir, const char *ext, bool include_dirs)
+{
+ struct string_list list;
+ if (!string_list_init(&list))
+ return NULL;
+
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATA ffd;
+
+ char path_buf[PATH_MAX];
+ snprintf(path_buf, sizeof(path_buf), "%s\\*", dir);
+
+ char **ext_list = NULL;
+ if (ext)
+ ext_list = string_split(ext, "|");
+
+ hFind = FindFirstFile(path_buf, &ffd);
+ if (hFind == INVALID_HANDLE_VALUE)
+ goto error;
+
+ do
+ {
+ const char *name = ffd.cFileName;
+ const char *file_ext = path_get_extension(name);
+ bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+
+ if (!include_dirs && is_dir)
+ continue;
+
+ if (!is_dir && ext_list && !string_list_find_elem(ext_list, file_ext))
+ continue;
+
+ char file_path[PATH_MAX];
+ snprintf(file_path, sizeof(file_path), "%s\\%s", dir, name);
+
+ if (!string_list_append(&list, file_path))
+ goto error;
+ }
+ while (FindNextFile(hFind, &ffd) != 0);
+
+ FindClose(hFind);
+ string_list_free(ext_list);
+ return string_list_finalize(&list);
+
+error:
+ RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
+ if (hFind != INVALID_HANDLE_VALUE)
+ FindClose(hFind);
+
+ string_list_cleanup(&list);
+ string_list_free(ext_list);
+ return NULL;
+}
+#else
+char **dir_list_new(const char *dir, const char *ext, bool include_dirs)
+{
+ struct string_list list;
+ if (!string_list_init(&list))
+ return NULL;
+
+ DIR *directory = NULL;
+ const struct dirent *entry = NULL;
+
+ char **ext_list = NULL;
+ if (ext)
+ ext_list = string_split(ext, "|");
+
+ directory = opendir(dir);
+ if (!directory)
+ goto error;
+
+ while ((entry = readdir(directory)))
+ {
+ const char *name = entry->d_name;
+ const char *file_ext = path_get_extension(name);
+ bool is_dir = entry->d_type == DT_DIR;
+
+ if (!include_dirs && is_dir)
+ continue;
+
+ if (!is_dir && ext_list && !string_list_find_elem(ext_list, file_ext))
+ continue;
+
+ char file_path[PATH_MAX];
+ snprintf(file_path, sizeof(file_path), "%s/%s", dir, name);
+
+ if (!string_list_append(&list, file_path))
+ goto error;
+ }
+
+ closedir(directory);
+
+ string_list_free(ext_list);
+ return string_list_finalize(&list);
+
+error:
+ RARCH_ERR("Failed to open directory: \"%s\"\n", dir);
+
+ if (directory)
+ closedir(directory);
+
+ string_list_cleanup(&list);
+ string_list_free(ext_list);
+ return NULL;
+}
+#endif
+
+void dir_list_free(char **dir_list)
+{
+ string_list_free(dir_list);
}
bool path_is_directory(const char *path)
@@ -185,12 +318,6 @@ bool path_is_directory(const char *path)
#ifdef _WIN32
DWORD ret = GetFileAttributes(path);
return (ret & FILE_ATTRIBUTE_DIRECTORY) && (ret != INVALID_FILE_ATTRIBUTES);
-#elif defined(__CELLOS_LV2__)
- CellFsStat buf;
- if (cellFsStat(path, &buf) < 0)
- return false;
-
- return buf.st_mode & CELL_FS_S_IFDIR;
#else
struct stat buf;
if (stat(path, &buf) < 0)
diff --git a/general.h b/general.h
index fc59c3a0f2..8a4f022c4e 100644
--- a/general.h
+++ b/general.h
@@ -332,6 +332,7 @@ struct global
unsigned rotation;
bool shutdown;
unsigned performance_level;
+ bool rgb32;
} system;
struct
diff --git a/libretro.h b/libretro.h
index 28ea262041..8aa579e863 100755
--- a/libretro.h
+++ b/libretro.h
@@ -150,7 +150,19 @@ extern "C" {
// The returned value can be NULL.
// If so, no such directory is defined,
// and it's up to the implementation to find a suitable directory.
+ //
+#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10
+ // const enum retro_pixel_format * --
+ // Sets the internal pixel format used by the implementation.
+ // The default pixel format is RETRO_PIXEL_FORMAT_XRGB1555.
+ // If the call returns false, the frontend does not support this pixel format.
+ // This function should be called inside retro_load_game() or retro_get_system_av_info().
+enum retro_pixel_format
+{
+ RETRO_PIXEL_FORMAT_0RGB1555 = 0, // 0RGB1555, native endian. 0 bit must be set to 0.
+ RETRO_PIXEL_FORMAT_XRGB8888 // XRGB8888, native endian. X bits are ignored.
+};
struct retro_message
{
@@ -225,7 +237,7 @@ struct retro_game_info
// Environment callback. Gives implementations a way of performing uncommon tasks. Extensible.
typedef bool (*retro_environment_t)(unsigned cmd, void *data);
-// Render a frame. Pixel format is 15-bit XRGB1555 native endian.
+// Render a frame. Pixel format is 15-bit 0RGB1555 native endian unless changed (see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT).
// Width and height specify dimensions of buffer.
// Pitch specifices length in bytes between two lines in buffer.
typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch);
diff --git a/ps3/main.c b/ps3/main.c
index 1ae53780b1..9fc59bc64d 100644
--- a/ps3/main.c
+++ b/ps3/main.c
@@ -78,7 +78,7 @@ char MULTIMAN_EXECUTABLE[PATH_MAX];
int rarch_main(int argc, char *argv[]);
-SYS_PROCESS_PARAM(1001, 0x100000)
+SYS_PROCESS_PARAM(1001, 0x200000)
#undef main
@@ -418,8 +418,8 @@ begin_shutdown:
rarch_main_deinit();
input_ps3.free(NULL);
-
video_gl.stop();
+ menu_free();
if(g_console.oskutil_handle.is_running)
oskutil_unload(&g_console.oskutil_handle);
diff --git a/ps3/menu.c b/ps3/menu.c
index 27b513d51f..03ce0c48ad 100644
--- a/ps3/menu.c
+++ b/ps3/menu.c
@@ -220,7 +220,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_LSTICK_DOWN(state))
{
- if(b->currently_selected < b->file_count-1)
+ if(b->current_dir.ptr < b->current_dir.size-1)
{
FILEBROWSER_INCREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST;
@@ -229,7 +229,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_DOWN(state))
{
- if(b->currently_selected < b->file_count-1)
+ if(b->current_dir.ptr < b->current_dir.size-1)
{
FILEBROWSER_INCREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST;
@@ -238,7 +238,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_LSTICK_UP(state))
{
- if(b->currently_selected > 0)
+ if(b->current_dir.ptr > 0)
{
FILEBROWSER_DECREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST;
@@ -247,7 +247,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_UP(state))
{
- if(b->currently_selected > 0)
+ if(b->current_dir.ptr > 0)
{
FILEBROWSER_DECREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST;
@@ -256,66 +256,66 @@ static void browser_update(filebrowser_t * b)
if (CTRL_RIGHT(state))
{
- b->currently_selected = (MIN(b->currently_selected + 5, b->file_count-1));
+ b->current_dir.ptr = (MIN(b->current_dir.ptr + 5, b->current_dir.size-1));
set_delay = DELAY_SMALL;
}
if (CTRL_LSTICK_RIGHT(state))
{
- b->currently_selected = (MIN(b->currently_selected + 5, b->file_count-1));
+ b->current_dir.ptr = (MIN(b->current_dir.ptr + 5, b->current_dir.size-1));
set_delay = DELAY_SMALLEST;
}
if (CTRL_LEFT(state))
{
- if (b->currently_selected <= 5)
- b->currently_selected = 0;
+ if (b->current_dir.ptr <= 5)
+ b->current_dir.ptr = 0;
else
- b->currently_selected -= 5;
+ b->current_dir.ptr -= 5;
set_delay = DELAY_SMALL;
}
if (CTRL_LSTICK_LEFT(state))
{
- if (b->currently_selected <= 5)
- b->currently_selected = 0;
+ if (b->current_dir.ptr <= 5)
+ b->current_dir.ptr = 0;
else
- b->currently_selected -= 5;
+ b->current_dir.ptr -= 5;
set_delay = DELAY_SMALLEST;
}
if (CTRL_R1(state))
{
- b->currently_selected = (MIN(b->currently_selected + NUM_ENTRY_PER_PAGE, b->file_count-1));
+ b->current_dir.ptr = (MIN(b->current_dir.ptr + NUM_ENTRY_PER_PAGE, b->current_dir.size-1));
set_delay = DELAY_MEDIUM;
}
if (CTRL_R2(state))
{
- b->currently_selected = (MIN(b->currently_selected + 50, b->file_count-1));
- if(!b->currently_selected)
- b->currently_selected = 0;
+ b->current_dir.ptr = (MIN(b->current_dir.ptr + 50, b->current_dir.size-1));
+ if(!b->current_dir.ptr)
+ b->current_dir.ptr = 0;
set_delay = DELAY_SMALL;
}
if (CTRL_L2(state))
{
- if (b->currently_selected <= 50)
- b->currently_selected= 0;
+ if (b->current_dir.ptr <= 50)
+ b->current_dir.ptr= 0;
else
- b->currently_selected -= 50;
+ b->current_dir.ptr -= 50;
set_delay = DELAY_SMALL;
}
if (CTRL_L1(state))
{
- if (b->currently_selected <= NUM_ENTRY_PER_PAGE)
- b->currently_selected= 0;
+ if (b->current_dir.ptr <= NUM_ENTRY_PER_PAGE)
+ b->current_dir.ptr= 0;
else
- b->currently_selected -= NUM_ENTRY_PER_PAGE;
+ b->current_dir.ptr -= NUM_ENTRY_PER_PAGE;
set_delay = DELAY_MEDIUM;
}
@@ -330,11 +330,11 @@ static void browser_update(filebrowser_t * b)
static void browser_render(filebrowser_t * b)
{
gl_t *gl = driver.video_data;
- uint32_t file_count = b->file_count;
+ uint32_t file_count = b->current_dir.size;
int current_index, page_number, page_base, i;
float currentX, currentY, ySpacing;
- current_index = b->currently_selected;
+ current_index = b->current_dir.ptr;
page_number = current_index / NUM_ENTRY_PER_PAGE;
page_base = page_number * NUM_ENTRY_PER_PAGE;
@@ -344,8 +344,10 @@ static void browser_render(filebrowser_t * b)
for ( i = page_base; i < file_count && i < page_base + NUM_ENTRY_PER_PAGE; ++i)
{
+ char fname_tmp[256];
+ fill_pathname_base(fname_tmp, b->current_dir.elems[i], sizeof(fname_tmp));
currentY = currentY + ySpacing;
- cellDbgFontPuts(currentX, currentY, FONT_SIZE, i == current_index ? RED : b->cur[i].d_type == CELL_FS_TYPE_DIRECTORY ? GREEN : WHITE, b->cur[i].d_name);
+ cellDbgFontPuts(currentX, currentY, FONT_SIZE, i == current_index ? RED : WHITE, fname_tmp);
gl_render_msg_post(gl);
}
gl_render_msg_post(gl);
@@ -818,8 +820,7 @@ static void apply_scaling (unsigned init_mode)
static void select_file(uint32_t menu_id)
{
- char extensions[256], title[256], object[256], comment[256], dir_path[PATH_MAX],
- path[PATH_MAX], *separatorslash;
+ char extensions[256], title[256], object[256], comment[256], dir_path[PATH_MAX], path[PATH_MAX];
uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data;
@@ -881,7 +882,7 @@ static void select_file(uint32_t menu_id)
if(IS_TIMER_EXPIRED(gl))
{
if (CTRL_START(button_was_pressed))
- filebrowser_reset_start_directory(&tmpBrowser, "/", extensions);
+ filebrowser_new(&tmpBrowser, "/", extensions);
if (CTRL_CROSS(button_was_pressed))
{
@@ -889,19 +890,17 @@ static void select_file(uint32_t menu_id)
{
/*if 'filename' is in fact '..' - then pop back directory instead of
adding '..' to filename path */
- if(tmpBrowser.currently_selected == 0)
+ if(tmpBrowser.current_dir.ptr == 0)
filebrowser_pop_directory(&tmpBrowser);
else
{
- separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser),"/") == 0) ? "" : "/";
- snprintf(path, sizeof(path), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
+ snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
filebrowser_push_directory(&tmpBrowser, path, true);
}
}
else if (FILEBROWSER_IS_CURRENT_A_FILE(tmpBrowser))
{
- snprintf(path, sizeof(path), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
- printf("path: %s\n", path);
+ snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
switch(menu_id)
{
@@ -962,7 +961,7 @@ static void select_file(uint32_t menu_id)
static void select_directory(uint32_t menu_id)
{
- char path[1024], newpath[1024], *separatorslash;
+ char path[1024], newpath[1024];
uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data;
@@ -981,13 +980,13 @@ static void select_directory(uint32_t menu_id)
if(IS_TIMER_EXPIRED(gl))
{
if (CTRL_START(button_was_pressed))
- filebrowser_reset_start_directory(&tmpBrowser, "/","empty");
+ filebrowser_new(&tmpBrowser, "/","empty");
if (CTRL_SQUARE(button_was_pressed))
{
if(FILEBROWSER_IS_CURRENT_A_DIRECTORY(tmpBrowser))
{
- snprintf(path, sizeof(path), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
+ snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
switch(menu_id)
{
case PATH_SAVESTATES_DIR_CHOICE:
@@ -1035,12 +1034,11 @@ static void select_directory(uint32_t menu_id)
/* if 'filename' is in fact '..' - then pop back directory instead of
* adding '..' to filename path */
- if(tmpBrowser.currently_selected == 0)
+ if(tmpBrowser.current_dir.ptr == 0)
filebrowser_pop_directory(&tmpBrowser);
else
{
- separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser),"/") == 0) ? "" : "/";
- snprintf(newpath, sizeof(newpath), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
+ snprintf(newpath, sizeof(newpath), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
filebrowser_push_directory(&tmpBrowser, newpath, false);
}
}
@@ -1895,7 +1893,7 @@ static void select_setting(menu * menu_obj)
static void select_rom(void)
{
- char newpath[1024], *separatorslash;
+ char newpath[1024];
uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data;
@@ -1914,7 +1912,7 @@ static void select_rom(void)
}
if (CTRL_START(button_was_pressed))
- filebrowser_reset_start_directory(&browser, "/", rarch_console_get_rom_ext());
+ filebrowser_new(&browser, "/", rarch_console_get_rom_ext());
if (CTRL_CROSS(button_was_pressed))
{
@@ -1922,14 +1920,13 @@ static void select_rom(void)
{
/*if 'filename' is in fact '..' - then pop back directory instead of adding '..' to filename path */
- if(browser.currently_selected == 0)
+ if(browser.current_dir.ptr == 0)
{
filebrowser_pop_directory(&browser);
}
else
{
- separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser),"/") == 0) ? "" : "/";
- snprintf(newpath, sizeof(newpath), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(browser));
+ snprintf(newpath, sizeof(newpath), FILEBROWSER_GET_CURRENT_FILENAME(browser));
filebrowser_push_directory(&browser, newpath, true);
}
}
@@ -1940,13 +1937,13 @@ static void select_rom(void)
retro_get_system_info(&info);
bool block_zip_extract = info.block_extract;
- snprintf(rom_path_temp, sizeof(rom_path_temp), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), FILEBROWSER_GET_CURRENT_FILENAME(browser));
+ snprintf(rom_path_temp, sizeof(rom_path_temp), FILEBROWSER_GET_CURRENT_FILENAME(browser));
if((strstr(rom_path_temp, ".zip") || strstr(rom_path_temp, ".ZIP")) && !block_zip_extract)
rarch_extract_zipfile(rom_path_temp);
else
{
- snprintf(g_console.rom_path, sizeof(g_console.rom_path), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), FILEBROWSER_GET_CURRENT_FILENAME(browser));
+ snprintf(g_console.rom_path, sizeof(g_console.rom_path), FILEBROWSER_GET_CURRENT_FILENAME(browser));
rarch_settings_change(S_START_RARCH);
}
}
@@ -2462,6 +2459,12 @@ void menu_init (void)
filebrowser_new(&browser, g_console.default_rom_startup_dir, rarch_console_get_rom_ext());
}
+void menu_free (void)
+{
+ filebrowser_free(&browser);
+ filebrowser_free(&tmpBrowser);
+}
+
void menu_loop(void)
{
gl_t * gl = driver.video_data;
diff --git a/ps3/menu.h b/ps3/menu.h
index 5034605575..ebf7b3e02d 100644
--- a/ps3/menu.h
+++ b/ps3/menu.h
@@ -157,5 +157,6 @@ enum
void menu_init (void);
void menu_loop (void);
+void menu_free (void);
#endif /* MENU_H_ */
diff --git a/qb/config.libs.sh b/qb/config.libs.sh
index 9300e8e183..dfc724f720 100644
--- a/qb/config.libs.sh
+++ b/qb/config.libs.sh
@@ -21,7 +21,6 @@ else
HAVE_RPI=no
fi
-
if [ "$LIBRETRO" ]; then
echo "Explicit libsnes used, disabling dynamic libsnes loading ..."
HAVE_DYNAMIC='no'
@@ -93,6 +92,7 @@ fi
check_pkgconf XML libxml-2.0
check_pkgconf SDL_IMAGE SDL_image
+check_pkgconf LIBPNG libpng
if [ "$HAVE_THREADS" != 'no' ]; then
if [ "$HAVE_FFMPEG" != 'no' ]; then
@@ -140,6 +140,6 @@ check_pkgconf PYTHON python3
add_define_make OS "$OS"
# Creates config.mk and config.h.
-VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 X264RGB SINC BSV_MOVIE RPI"
+VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE CONFIGFILE FREETYPE XVIDEO X11 XEXT NETPLAY NETWORK_CMD SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 X264RGB SINC BSV_MOVIE RPI"
create_config_make config.mk $VARS
-create_config_header config.h $VARS
\ No newline at end of file
+create_config_header config.h $VARS
diff --git a/qb/config.params.sh b/qb/config.params.sh
index 3a2f311363..676e53b7e8 100644
--- a/qb/config.params.sh
+++ b/qb/config.params.sh
@@ -21,6 +21,7 @@ HAVE_PULSE=auto # Enable PulseAudio support
HAVE_FREETYPE=auto # Enable FreeType support
HAVE_XVIDEO=auto # Enable XVideo support
HAVE_SDL_IMAGE=auto # Enable SDL_image support
+HAVE_LIBPNG=auto # Enable libpng support
HAVE_PYTHON=auto # Enable Python 3 support for shaders
HAVE_SINC=yes # Disable SINC resampler
HAVE_BSV_MOVIE=yes # Disable BSV movie support
diff --git a/retroarch.c b/retroarch.c
index 10045a9533..b3cb31915c 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -499,6 +499,7 @@ static void print_features(void)
_PSUPP(cg, "Cg", "Cg pixel shaders");
_PSUPP(xml, "XML", "bSNES XML pixel shaders");
_PSUPP(sdl_image, "SDL_image", "SDL_image image loading");
+ _PSUPP(libpng, "libpng", "libpng screenshot support");
_PSUPP(fbo, "FBO", "OpenGL render-to-texture (multi-pass shaders)");
_PSUPP(dynamic, "Dynamic", "Dynamic run-time loading of libretro library");
_PSUPP(ffmpeg, "FFmpeg", "On-the-fly recording of gameplay with libavcodec");
@@ -1175,7 +1176,7 @@ static void init_recording(void)
params.filename = g_extern.record_path;
params.fps = fps;
params.samplerate = samplerate;
- params.rgb32 = false;
+ params.rgb32 = g_extern.system.rgb32;
if (g_extern.record_width || g_extern.record_height)
{
diff --git a/screenshot.c b/screenshot.c
index 5be6b7d8df..b111453838 100644
--- a/screenshot.c
+++ b/screenshot.c
@@ -22,9 +22,80 @@
#include
#include "general.h"
-// Simple 24bpp .BMP writer.
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
-static void write_header(FILE *file, unsigned width, unsigned height)
+#ifdef HAVE_LIBPNG
+#include
+#endif
+
+#ifdef HAVE_LIBPNG
+static png_structp png_ptr;
+static png_infop png_info_ptr;
+
+static void destroy_png(void)
+{
+ if (png_ptr)
+ png_destroy_write_struct(&png_ptr, &png_info_ptr);
+}
+
+static bool write_header_png(FILE *file, unsigned width, unsigned height)
+{
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr)
+ return false;
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ goto error;
+
+ png_info_ptr = png_create_info_struct(png_ptr);
+ if (!png_info_ptr)
+ goto error;
+
+ png_init_io(png_ptr, file);
+
+ png_set_IHDR(png_ptr, png_info_ptr, width, height, 8,
+ PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ png_write_info(png_ptr, png_info_ptr);
+ png_set_compression_level(png_ptr, 9);
+
+ return true;
+
+error:
+ destroy_png();
+ return false;
+}
+
+static void dump_lines_png(uint8_t **lines, int height)
+{
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ RARCH_ERR("PNG: dump_lines_png() failed!\n");
+ goto end;
+ }
+
+ // PNG is top-down, BMP is bottom-up.
+ for (int i = 0, j = height - 1; i < j; i++, j--)
+ {
+ uint8_t *tmp = lines[i];
+ lines[i] = lines[j];
+ lines[j] = tmp;
+ }
+
+ png_set_rows(png_ptr, png_info_ptr, lines);
+ png_write_png(png_ptr, png_info_ptr, PNG_TRANSFORM_BGR, NULL);
+ png_write_end(png_ptr, NULL);
+
+end:
+ destroy_png();
+}
+
+#else
+
+static bool write_header_bmp(FILE *file, unsigned width, unsigned height)
{
unsigned line_size = (width * 3 + 3) & ~3;
unsigned size = line_size * height + 54;
@@ -49,9 +120,17 @@ static void write_header(FILE *file, unsigned width, unsigned height)
0, 0, 0, 0
};
- fwrite(header, 1, sizeof(header), file);
+ return fwrite(header, 1, sizeof(header), file) == sizeof(header);
}
+static void dump_lines_file(FILE *file, uint8_t **lines, size_t line_size, unsigned height)
+{
+ for (unsigned i = 0; i < height; i++)
+ fwrite(lines[i], 1, line_size, file);
+}
+
+#endif
+
static void dump_line_bgr(uint8_t *line, const uint8_t *src, unsigned width)
{
memcpy(line, src, width * 3);
@@ -78,31 +157,42 @@ static void dump_content(FILE *file, const void *frame,
const uint16_t *frame16 = (const uint16_t*)frame;
if (!bgr24)
- pitch /= 2;
+ pitch /= sizeof(uint16_t);
- unsigned line_size = (width * 3 + 3) & ~3;
- uint8_t *line = (uint8_t*)calloc(1, line_size);
- if (!line)
+ uint8_t **lines = (uint8_t**)calloc(height, sizeof(uint8_t*));
+ if (!lines)
return;
+ size_t line_size = (width * 3 + 3) & ~3;
+
+ for (int i = 0; i < height; i++)
+ {
+ lines[i] = (uint8_t*)calloc(1, line_size);
+ if (!lines[i])
+ goto end;
+ }
+
if (bgr24) // BGR24 byte order. Can directly copy.
{
for (int j = 0; j < height; j++, frame_bgr += pitch)
- {
- dump_line_bgr(line, frame_bgr, width);
- fwrite(line, 1, line_size, file);
- }
+ dump_line_bgr(lines[j], frame_bgr, width);
}
else // ARGB1555
{
for (int j = 0; j < height; j++, frame16 += pitch)
- {
- dump_line_16(line, frame16, width);
- fwrite(line, 1, line_size, file);
- }
+ dump_line_16(lines[j], frame16, width);
}
- free(line);
+#ifdef HAVE_LIBPNG
+ dump_lines_png(lines, height);
+#else
+ dump_lines_file(file, lines, line_size, height);
+#endif
+
+end:
+ for (int i = 0; i < height; i++)
+ free(lines[i]);
+ free(lines);
}
bool screenshot_dump(const char *folder, const void *frame,
@@ -111,8 +201,14 @@ bool screenshot_dump(const char *folder, const void *frame,
time_t cur_time;
time(&cur_time);
+#ifdef HAVE_LIBPNG
+#define IMG_EXT "png"
+#else
+#define IMG_EXT "bmp"
+#endif
+
char timefmt[128];
- strftime(timefmt, sizeof(timefmt), "RetroArch-%m%d-%H%M%S.bmp", localtime(&cur_time));
+ strftime(timefmt, sizeof(timefmt), "RetroArch-%m%d-%H%M%S." IMG_EXT, localtime(&cur_time));
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s/%s", folder, timefmt);
@@ -124,11 +220,18 @@ bool screenshot_dump(const char *folder, const void *frame,
return false;
}
- write_header(file, width, height);
- dump_content(file, frame, width, height, pitch, bgr24);
+#ifdef HAVE_LIBPNG
+ bool ret = write_header_png(file, width, height);
+#else
+ bool ret = write_header_bmp(file, width, height);
+#endif
+
+ if (ret)
+ dump_content(file, frame, width, height, pitch, bgr24);
+ else
+ RARCH_ERR("Failed to write image header.\n");
fclose(file);
-
- return true;
+ return ret;
}
| | |