Conflicts:
	qb/config.libs.sh
This commit is contained in:
Toad King 2012-06-18 18:50:22 -04:00
commit 4f3e54529b
77 changed files with 1074 additions and 504 deletions

View File

@ -320,7 +320,7 @@ begin_shutdown:
if(path_file_exists(SYS_CONFIG_FILE)) if(path_file_exists(SYS_CONFIG_FILE))
rarch_config_save(SYS_CONFIG_FILE); rarch_config_save(SYS_CONFIG_FILE);
menu_deinit(); menu_free();
video_xdk360.stop(); video_xdk360.stop();
input_xdk360.free(NULL); input_xdk360.free(NULL);
rarch_exec(); rarch_exec();

View File

@ -70,10 +70,12 @@ static void filebrowser_fetch_directory_entries(const char *path, filebrowser_t
rompath_title->SetText(strw_buffer); rompath_title->SetText(strw_buffer);
romlist->DeleteItems(0, romlist->GetItemCount()); romlist->DeleteItems(0, romlist->GetItemCount());
romlist->InsertItems(0, browser->file_count); romlist->InsertItems(0, browser->current_dir.size);
for(unsigned i = 0; i < browser->file_count; i++) 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); romlist->SetText(i, strw_buffer);
} }
} }
@ -524,13 +526,12 @@ HRESULT CRetroArchFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle
if(hObjPressed == m_romlist) if(hObjPressed == m_romlist)
{ {
int index = m_romlist.GetCurSel(); 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; struct retro_system_info info;
retro_get_system_info(&info); retro_get_system_info(&info);
bool block_zip_extract = info.block_extract; 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) 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); 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)); 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) if(hObjPressed == m_shaderlist)
{ {
int index = m_shaderlist.GetCurSel(); 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)); 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) if (g_console.info_msg_enable)
rarch_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180); 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)); 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); 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) if(hObjPressed == m_romlist)
{ {
int index = m_romlist.GetCurSel(); 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)); 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); 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); 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)); 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); snprintf(path, sizeof(path), "%s%s\\", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
@ -838,8 +839,10 @@ int menu_init (void)
return 0; return 0;
} }
void menu_deinit (void) void menu_free (void)
{ {
filebrowser_free(&browser);
filebrowser_free(&tmp_browser);
app.Uninit(); app.Uninit();
} }

View File

@ -215,7 +215,7 @@ class CRetroArchControls: public CXuiSceneImpl
}; };
int menu_init (void); int menu_init (void);
void menu_deinit (void); void menu_free (void);
void menu_loop (void); void menu_loop (void);
extern CRetroArch app; extern CRetroArch app;

View File

@ -164,6 +164,11 @@ ifeq ($(HAVE_SDL_IMAGE), 1)
DEFINES += $(SDL_IMAGE_CFLAGS) DEFINES += $(SDL_IMAGE_CFLAGS)
endif endif
ifeq ($(HAVE_LIBPNG), 1)
LIBS += $(LIBPNG_LIBS)
DEFINES += $(LIBPNG_CFLAGS)
endif
ifeq ($(HAVE_FFMPEG), 1) ifeq ($(HAVE_FFMPEG), 1)
OBJ += record/ffemu.o OBJ += record/ffemu.o
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS)

View File

@ -32,7 +32,6 @@ libretro ?= -lretro
LIBS = -lm LIBS = -lm
DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.6\" DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.6\"
LDFLAGS = -L. -static-libgcc LDFLAGS = -L. -static-libgcc
LDCXXFLAGS = -s
ifeq ($(TDM_GCC),) ifeq ($(TDM_GCC),)
LDCXXFLAGS += -static-libstdc++ LDCXXFLAGS += -static-libstdc++
@ -153,7 +152,14 @@ ifneq ($(V), 1)
Q := @ Q := @
endif 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) ifeq ($(CXX_BUILD), 1)
CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS
else else

8
android/.classpath Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

33
android/.project Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>RetroArch</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -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

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.retroarch"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- Tell the system this app requires OpenGL ES 2.0. -->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
</manifest>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
# cache for current jar dependecy. DO NOT EDIT.
# format is <lastModified> <length> <SHA-1> <path>
# Encoding is UTF-8

View File

@ -0,0 +1,6 @@
/** Automatically generated file. DO NOT MODIFY */
package com.retroarch;
public final class BuildConfig {
public final static boolean DEBUG = true;
}

View File

@ -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;
}
}

View File

@ -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 *;
#}

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
</LinearLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/open" android:showAsAction="ifRoom|withText" android:title="Open ROM" android:icon="@drawable/ic_action_open"></item>
<item android:id="@+id/close" android:showAsAction="collapseActionView" android:title="Close ROM" android:icon="@drawable/ic_action_close"></item>
<item android:id="@+id/load" android:showAsAction="collapseActionView" android:title="Load" android:icon="@drawable/ic_action_load"></item>
<item android:id="@+id/save" android:showAsAction="collapseActionView" android:title="Save" android:icon="@drawable/ic_action_save"></item>
<item android:id="@+id/history" android:showAsAction="collapseActionView" android:title="History" android:icon="@drawable/ic_action_history"></item>
<item android:id="@+id/settings" android:showAsAction="collapseActionView" android:title="Settings" android:icon="@drawable/ic_action_settings"></item>
<item android:id="@+id/quit" android:showAsAction="collapseActionView" android:title="Quit" android:icon="@drawable/ic_action_quit"></item>
</menu>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MainActivity!</string>
<string name="app_name">RetroArch</string>
</resources>

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -110,6 +110,12 @@ static const bool _sdl_image_supp = true;
static const bool _sdl_image_supp = false; static const bool _sdl_image_supp = false;
#endif #endif
#ifdef HAVE_LIBPNG
static const bool _libpng_supp = true;
#else
static const bool _libpng_supp = false;
#endif
#ifdef HAVE_FBO #ifdef HAVE_FBO
static const bool _fbo_supp = true; static const bool _fbo_supp = true;
#else #else

View File

@ -14,216 +14,37 @@
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifdef _XBOX
#include <xtl.h>
#endif
#include "file_browser.h" #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, static void filebrowser_parse_directory(filebrowser_t * filebrowser,
const char * path, const char * extensions) const char * path, const char * extensions)
{ {
int error = 0; strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path,
#if defined(_XBOX) sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
filebrowser->file_count = 0;
WIN32_FIND_DATA ffd; filebrowser->current_dir.elems = dir_list_new(path, extensions, true);
HANDLE hFind = INVALID_HANDLE_VALUE; filebrowser->current_dir.size = dir_list_size(filebrowser->current_dir.elems);
filebrowser->current_dir.ptr = 0;
char path_buf[PATH_MAX]; dir_list_sort(filebrowser->current_dir.elems, true);
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
} }
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir,
const char * extensions) const char * extensions)
{ {
filebrowser_clear_current_entries(filebrowser);
filebrowser->directory_stack_size = 0; filebrowser->directory_stack_size = 0;
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions)); strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions); filebrowser_parse_directory(filebrowser, start_dir, extensions);
} }
void filebrowser_free(filebrowser_t * filebrowser)
void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir,
const char * extensions)
{ {
filebrowser->directory_stack_size = 0; dir_list_free(filebrowser->current_dir.elems);
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
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, 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_parse_directory(filebrowser, filebrowser->dir[filebrowser->directory_stack_size],
filebrowser->extensions); filebrowser->extensions);
} }
const char * filebrowser_get_current_path (filebrowser_t *filebrowser)
{
return filebrowser->current_dir.elems[filebrowser->current_dir.ptr];
}

View File

@ -17,89 +17,63 @@
#ifndef FILEBROWSER_H_ #ifndef FILEBROWSER_H_
#define FILEBROWSER_H_ #define FILEBROWSER_H_
#define MAXJOLIET 255
#define MAX_DIR_STACK 25 #define MAX_DIR_STACK 25
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __CELLOS_LV2__
#include <stdbool.h>
#include <cell/cell_fs.h>
#include <sys/types.h>
#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 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; uint32_t directory_stack_size;
char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; /* info of the current directory*/ char dir[MAX_DIR_STACK][512];
DirectoryEntry cur[MAX_FILE_LIMIT]; /* current file listing*/ struct {
char extensions[FS_MAX_PATH]; /* allowed extensions*/ char **elems;
size_t size;
size_t ptr;
} current_dir;
char extensions[PATH_MAX];
} filebrowser_t; } filebrowser_t;
void filebrowser_new(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_reset_start_directory(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_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension);
void filebrowser_pop_directory (filebrowser_t * filebrowser); 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_NAME(filebrowser) (filebrowser.dir[filebrowser.directory_stack_size])
#define FILEBROWSER_GET_CURRENT_DIRECTORY_FILE_COUNT(filebrowser) (filebrowser.file_count) #define FILEBROWSER_GET_CURRENT_DIRECTORY_FILE_COUNT(filebrowser) (filebrowser.current_dir.size)
#define FILEBROWSER_GOTO_ENTRY(filebrowser, i) filebrowser.currently_selected = i; #define FILEBROWSER_GOTO_ENTRY(filebrowser, i) filebrowser.current_dir.ptr = i;
#define FILEBROWSER_INCREMENT_ENTRY(filebrowser) \ #define FILEBROWSER_INCREMENT_ENTRY(filebrowser) \
{ \ { \
filebrowser.currently_selected++; \ filebrowser.current_dir.ptr++; \
if (filebrowser.currently_selected >= filebrowser.file_count) \ if (filebrowser.current_dir.ptr >= filebrowser.current_dir.size) \
filebrowser.currently_selected = 0; \ filebrowser.current_dir.ptr = 0; \
} }
#define FILEBROWSER_INCREMENT_ENTRY_POINTER(filebrowser) \ #define FILEBROWSER_INCREMENT_ENTRY_POINTER(filebrowser) \
{ \ { \
filebrowser->currently_selected++; \ filebrowser->current_dir.ptr++; \
if (filebrowser->currently_selected >= filebrowser->file_count) \ if (filebrowser->current_dir.ptr >= filebrowser->current_dir.size) \
filebrowser->currently_selected = 0; \ filebrowser->current_dir.ptr = 0; \
} }
#define FILEBROWSER_DECREMENT_ENTRY(filebrowser) \ #define FILEBROWSER_DECREMENT_ENTRY(filebrowser) \
{ \ { \
filebrowser.currently_selected--; \ filebrowser.current_dir.ptr--; \
if (filebrowser.currently_selected >= filebrowser.file_count) \ if (filebrowser.current_dir.ptr >= filebrowser.current_dir.size) \
filebrowser.currently_selected = filebrowser.file_count - 1; \ filebrowser.current_dir.ptr = filebrowser.current_dir.size - 1; \
} }
#define FILEBROWSER_DECREMENT_ENTRY_POINTER(filebrowser) \ #define FILEBROWSER_DECREMENT_ENTRY_POINTER(filebrowser) \
{ \ { \
filebrowser->currently_selected--; \ filebrowser->current_dir.ptr--; \
if (filebrowser->currently_selected >= filebrowser->file_count) \ if (filebrowser->current_dir.ptr >= filebrowser->current_dir.size) \
filebrowser->currently_selected = filebrowser->file_count - 1; \ 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_FILENAME(filebrowser) (filebrowser.current_dir.elems[filebrowser.current_dir.ptr])
#define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.currently_selected) #define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.current_dir.ptr)
#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_type == CELL_FS_TYPE_REGULAR) #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) (filebrowser.cur[filebrowser.currently_selected].d_type == CELL_FS_TYPE_DIRECTORY) #define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (path_is_directory(filebrowser.current_dir.elems[filebrowser.current_dir.ptr]))
#endif /* FILEBROWSER_H_ */ #endif /* FILEBROWSER_H_ */

View File

@ -43,13 +43,10 @@ const char *rarch_manage_libretro_install(const char *full_path, const char *pat
// file first. // file first.
RARCH_LOG("Upgrading emulator core...\n"); RARCH_LOG("Upgrading emulator core...\n");
#if defined(__CELLOS_LV2__)
ret = cellFsUnlink(tmp_pathnewfile); ret = remove(tmp_pathnewfile);
if (ret == CELL_FS_SUCCEEDED)
#elif defined(_XBOX) if (ret == 0)
ret = DeleteFile(tmp_pathnewfile);
if (ret != 0)
#endif
{ {
RARCH_LOG("Succeeded in removing pre-existing libretro core: [%s].\n", tmp_pathnewfile); 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. //now attempt the renaming.
#if defined(__CELLOS_LV2__) ret = rename(full_path, tmp_pathnewfile);
ret = cellFsRename(full_path, tmp_pathnewfile);
if (ret != CELL_FS_SUCCEEDED)
#elif defined(_XBOX)
ret = MoveFileExA(full_path, tmp_pathnewfile, NULL);
if (ret == 0) 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); RARCH_LOG("Libsnes core [%s] renamed to: [%s].\n", full_path, tmp_pathnewfile);
retstr = tmp_pathnewfile; retstr = tmp_pathnewfile;
goto done; 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: done:
return retstr; return retstr;
} }

View File

@ -87,9 +87,9 @@ static void find_and_set_first_file(void)
// we can find in the RetroArch cores directory // we can find in the RetroArch cores directory
#if defined(_XBOX) #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__) #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 #endif
if (!dir_list) if (!dir_list)

View File

@ -403,6 +403,12 @@ static void init_filter(void)
if (*g_settings.video.filter_path == '\0') if (*g_settings.video.filter_path == '\0')
return; 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); RARCH_LOG("Loading bSNES filter from \"%s\"\n", g_settings.video.filter_path);
g_extern.filter.lib = dylib_load(g_settings.video.filter_path); g_extern.filter.lib = dylib_load(g_settings.video.filter_path);
if (!g_extern.filter.lib) if (!g_extern.filter.lib)
@ -417,6 +423,7 @@ static void init_filter(void)
(void (*)(uint32_t*, uint32_t*, (void (*)(uint32_t*, uint32_t*,
unsigned, const uint16_t*, unsigned, const uint16_t*,
unsigned, unsigned, unsigned))dylib_proc(g_extern.filter.lib, "filter_render"); unsigned, unsigned, unsigned))dylib_proc(g_extern.filter.lib, "filter_render");
if (!g_extern.filter.psize || !g_extern.filter.prender) if (!g_extern.filter.psize || !g_extern.filter.prender)
{ {
RARCH_ERR("Failed to find functions in filter...\n"); RARCH_ERR("Failed to find functions in filter...\n");
@ -428,28 +435,30 @@ static void init_filter(void)
g_extern.filter.active = true; g_extern.filter.active = true;
struct retro_game_geometry *geom = &g_extern.system.av_info.geometry; 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; unsigned height = geom->max_height;
g_extern.filter.psize(&width, &height); g_extern.filter.psize(&width, &height);
unsigned pow2_x = next_pow2(width); unsigned pow2_x = next_pow2(width);
unsigned pow2_y = next_pow2(height); unsigned pow2_y = next_pow2(height);
unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y; unsigned maxsize = pow2_x > pow2_y ? pow2_x : pow2_y;
g_extern.filter.scale = maxsize / RARCH_SCALE_BASE; 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.buffer = (uint32_t*)malloc(RARCH_SCALE_BASE * RARCH_SCALE_BASE *
g_extern.filter.pitch = RARCH_SCALE_BASE * g_extern.filter.scale * sizeof(uint32_t); g_extern.filter.scale * g_extern.filter.scale * sizeof(uint32_t));
rarch_assert(g_extern.filter.buffer); 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); rarch_assert(g_extern.filter.colormap);
// Set up conversion map from 16-bit XRGB1555 to 32-bit ARGB. // 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 r = (i >> 10) & 0x1f;
unsigned g = (i >> 5) & 31; unsigned g = (i >> 5) & 0x1f;
unsigned b = (i >> 0) & 31; unsigned b = (i >> 0) & 0x1f;
r = (r << 3) | (r >> 2); r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2); g = (g << 3) | (g >> 2);
@ -477,17 +486,14 @@ static void init_shader_dir(void)
if (!*g_settings.video.shader_dir) if (!*g_settings.video.shader_dir)
return; return;
g_extern.shader_dir.elems = dir_list_new(g_settings.video.shader_dir, ".shader", false); 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.size = dir_list_size(g_extern.shader_dir.elems);
g_extern.shader_dir.ptr = 0; g_extern.shader_dir.ptr = 0;
if (g_extern.shader_dir.elems)
{ dir_list_sort(g_extern.shader_dir.elems, false);
while (g_extern.shader_dir.elems[g_extern.shader_dir.size])
{ for (unsigned i = 0; i < g_extern.shader_dir.size; i++)
RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.elems[g_extern.shader_dir.size]); RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.elems[i]);
g_extern.shader_dir.size++;
}
}
} }
static void deinit_shader_dir(void) static void deinit_shader_dir(void)
@ -495,8 +501,8 @@ static void deinit_shader_dir(void)
// It handles NULL, no worries :D // It handles NULL, no worries :D
dir_list_free(g_extern.shader_dir.elems); dir_list_free(g_extern.shader_dir.elems);
g_extern.shader_dir.elems = NULL; g_extern.shader_dir.elems = NULL;
g_extern.shader_dir.size = 0; g_extern.shader_dir.size = 0;
g_extern.shader_dir.ptr = 0; g_extern.shader_dir.ptr = 0;
} }
#endif #endif
@ -559,7 +565,7 @@ void init_video_input(void)
video.force_aspect = g_settings.video.force_aspect; video.force_aspect = g_settings.video.force_aspect;
video.smooth = g_settings.video.smooth; video.smooth = g_settings.video.smooth;
video.input_scale = scale; 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; const input_driver_t *tmp = driver.input;
driver.video_data = video_init_func(&video, &driver.input, &driver.input_data); driver.video_data = video_init_func(&video, &driver.input, &driver.input_data);

View File

@ -331,6 +331,31 @@ static bool environment_cb(unsigned cmd, void *data)
RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n", g_settings.system_directory); RARCH_LOG("Environ SYSTEM_DIRECTORY: \"%s\".\n", g_settings.system_directory);
break; 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: default:
RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd); RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
return false; return false;

6
file.h
View File

@ -24,10 +24,6 @@
#include <sys/types.h> #include <sys/types.h>
#include "general.h" #include "general.h"
#ifdef __CELLOS_LV2__
#include <cell/cell_fs.h>
#endif
// Generic file, path and directory handling. // Generic file, path and directory handling.
ssize_t read_file(const char *path, void **buf); 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 ext is NULL, any file will be picked.
// If non-NULL, only files with extension ext are added. // If non-NULL, only files with extension ext are added.
char **dir_list_new(const char *dir, const char *ext, bool include_dirs); 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); void dir_list_free(char **dir_list);
bool path_is_directory(const char *path); bool path_is_directory(const char *path);

View File

@ -20,9 +20,10 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "compat/strl.h" #include "compat/strl.h"
#include "compat/posix_string.h"
#ifdef __CELLOS_LV2__ #ifdef __CELLOS_LV2__
#include <cell/cell_fs.h> #define S_ISDIR(x) (x & CELL_FS_S_IFDIR)
#endif #endif
#if defined(_WIN32) && !defined(_XBOX) #if defined(_WIN32) && !defined(_XBOX)
@ -43,141 +44,273 @@
#endif #endif
// Yep, this is C alright ;) // 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; char **data;
size_t cur_size = 32; size_t size;
char **dir_list = NULL; size_t cap;
};
#ifdef _WIN32 static bool string_list_capacity(struct string_list *list, size_t cap)
WIN32_FIND_DATA ffd; {
HANDLE hFind = INVALID_HANDLE_VALUE; 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)) list->data = new_data;
goto error; list->cap = cap;
#ifdef _XBOX return true;
if (strlcat(path_buf, "*", sizeof(path_buf)) >= sizeof(path_buf)) }
#else
if (strlcat(path_buf, "/*", sizeof(path_buf)) >= sizeof(path_buf)) static bool string_list_init(struct string_list *list)
#endif {
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; 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)) if (!string_list_append(&list, tmp))
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])
goto error; goto error;
strlcpy(dir_list[cur_ptr], dir, PATH_MAX); tmp = strtok(NULL, delim);
#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*));
}
} }
#if defined(_WIN32)
while (FindNextFile(hFind, &ffd) != 0);
#endif
#ifdef _WIN32 free(copy);
FindClose(hFind); return string_list_finalize(&list);
#else
closedir(directory);
#endif
return dir_list;
error: error:
RARCH_ERR("Failed to open directory: \"%s\"\n", dir); string_list_cleanup(&list);
#ifdef _WIN32 free(copy);
if (hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
#else
if (directory)
closedir(directory);
#endif
dir_list_free(dir_list);
return NULL; 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) if (!dir_list)
return; return;
char **orig = dir_list; qsort(dir_list, dir_list_size(dir_list), sizeof(char*), dir_first ? qstrcmp_dir : qstrcmp_plain);
while (*dir_list) }
free(*dir_list++);
free(orig); #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) bool path_is_directory(const char *path)
@ -185,12 +318,6 @@ bool path_is_directory(const char *path)
#ifdef _WIN32 #ifdef _WIN32
DWORD ret = GetFileAttributes(path); DWORD ret = GetFileAttributes(path);
return (ret & FILE_ATTRIBUTE_DIRECTORY) && (ret != INVALID_FILE_ATTRIBUTES); 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 #else
struct stat buf; struct stat buf;
if (stat(path, &buf) < 0) if (stat(path, &buf) < 0)

View File

@ -332,6 +332,7 @@ struct global
unsigned rotation; unsigned rotation;
bool shutdown; bool shutdown;
unsigned performance_level; unsigned performance_level;
bool rgb32;
} system; } system;
struct struct

View File

@ -150,7 +150,19 @@ extern "C" {
// The returned value can be NULL. // The returned value can be NULL.
// If so, no such directory is defined, // If so, no such directory is defined,
// and it's up to the implementation to find a suitable directory. // 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 struct retro_message
{ {
@ -225,7 +237,7 @@ struct retro_game_info
// Environment callback. Gives implementations a way of performing uncommon tasks. Extensible. // Environment callback. Gives implementations a way of performing uncommon tasks. Extensible.
typedef bool (*retro_environment_t)(unsigned cmd, void *data); 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. // Width and height specify dimensions of buffer.
// Pitch specifices length in bytes between two lines in 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); typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch);

View File

@ -78,7 +78,7 @@ char MULTIMAN_EXECUTABLE[PATH_MAX];
int rarch_main(int argc, char *argv[]); int rarch_main(int argc, char *argv[]);
SYS_PROCESS_PARAM(1001, 0x100000) SYS_PROCESS_PARAM(1001, 0x200000)
#undef main #undef main
@ -418,8 +418,8 @@ begin_shutdown:
rarch_main_deinit(); rarch_main_deinit();
input_ps3.free(NULL); input_ps3.free(NULL);
video_gl.stop(); video_gl.stop();
menu_free();
if(g_console.oskutil_handle.is_running) if(g_console.oskutil_handle.is_running)
oskutil_unload(&g_console.oskutil_handle); oskutil_unload(&g_console.oskutil_handle);

View File

@ -220,7 +220,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_LSTICK_DOWN(state)) 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); FILEBROWSER_INCREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST; set_delay = DELAY_SMALLEST;
@ -229,7 +229,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_DOWN(state)) 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); FILEBROWSER_INCREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST; set_delay = DELAY_SMALLEST;
@ -238,7 +238,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_LSTICK_UP(state)) if (CTRL_LSTICK_UP(state))
{ {
if(b->currently_selected > 0) if(b->current_dir.ptr > 0)
{ {
FILEBROWSER_DECREMENT_ENTRY_POINTER(b); FILEBROWSER_DECREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST; set_delay = DELAY_SMALLEST;
@ -247,7 +247,7 @@ static void browser_update(filebrowser_t * b)
if (CTRL_UP(state)) if (CTRL_UP(state))
{ {
if(b->currently_selected > 0) if(b->current_dir.ptr > 0)
{ {
FILEBROWSER_DECREMENT_ENTRY_POINTER(b); FILEBROWSER_DECREMENT_ENTRY_POINTER(b);
set_delay = DELAY_SMALLEST; set_delay = DELAY_SMALLEST;
@ -256,66 +256,66 @@ static void browser_update(filebrowser_t * b)
if (CTRL_RIGHT(state)) 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; set_delay = DELAY_SMALL;
} }
if (CTRL_LSTICK_RIGHT(state)) 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; set_delay = DELAY_SMALLEST;
} }
if (CTRL_LEFT(state)) if (CTRL_LEFT(state))
{ {
if (b->currently_selected <= 5) if (b->current_dir.ptr <= 5)
b->currently_selected = 0; b->current_dir.ptr = 0;
else else
b->currently_selected -= 5; b->current_dir.ptr -= 5;
set_delay = DELAY_SMALL; set_delay = DELAY_SMALL;
} }
if (CTRL_LSTICK_LEFT(state)) if (CTRL_LSTICK_LEFT(state))
{ {
if (b->currently_selected <= 5) if (b->current_dir.ptr <= 5)
b->currently_selected = 0; b->current_dir.ptr = 0;
else else
b->currently_selected -= 5; b->current_dir.ptr -= 5;
set_delay = DELAY_SMALLEST; set_delay = DELAY_SMALLEST;
} }
if (CTRL_R1(state)) 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; set_delay = DELAY_MEDIUM;
} }
if (CTRL_R2(state)) if (CTRL_R2(state))
{ {
b->currently_selected = (MIN(b->currently_selected + 50, b->file_count-1)); b->current_dir.ptr = (MIN(b->current_dir.ptr + 50, b->current_dir.size-1));
if(!b->currently_selected) if(!b->current_dir.ptr)
b->currently_selected = 0; b->current_dir.ptr = 0;
set_delay = DELAY_SMALL; set_delay = DELAY_SMALL;
} }
if (CTRL_L2(state)) if (CTRL_L2(state))
{ {
if (b->currently_selected <= 50) if (b->current_dir.ptr <= 50)
b->currently_selected= 0; b->current_dir.ptr= 0;
else else
b->currently_selected -= 50; b->current_dir.ptr -= 50;
set_delay = DELAY_SMALL; set_delay = DELAY_SMALL;
} }
if (CTRL_L1(state)) if (CTRL_L1(state))
{ {
if (b->currently_selected <= NUM_ENTRY_PER_PAGE) if (b->current_dir.ptr <= NUM_ENTRY_PER_PAGE)
b->currently_selected= 0; b->current_dir.ptr= 0;
else else
b->currently_selected -= NUM_ENTRY_PER_PAGE; b->current_dir.ptr -= NUM_ENTRY_PER_PAGE;
set_delay = DELAY_MEDIUM; set_delay = DELAY_MEDIUM;
} }
@ -330,11 +330,11 @@ static void browser_update(filebrowser_t * b)
static void browser_render(filebrowser_t * b) static void browser_render(filebrowser_t * b)
{ {
gl_t *gl = driver.video_data; 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; int current_index, page_number, page_base, i;
float currentX, currentY, ySpacing; float currentX, currentY, ySpacing;
current_index = b->currently_selected; current_index = b->current_dir.ptr;
page_number = current_index / NUM_ENTRY_PER_PAGE; page_number = current_index / NUM_ENTRY_PER_PAGE;
page_base = page_number * 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) 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; 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);
} }
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) static void select_file(uint32_t menu_id)
{ {
char extensions[256], title[256], object[256], comment[256], dir_path[PATH_MAX], char extensions[256], title[256], object[256], comment[256], dir_path[PATH_MAX], path[PATH_MAX];
path[PATH_MAX], *separatorslash;
uint64_t state, diff_state, button_was_pressed; uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data; gl_t * gl = driver.video_data;
@ -881,7 +882,7 @@ static void select_file(uint32_t menu_id)
if(IS_TIMER_EXPIRED(gl)) if(IS_TIMER_EXPIRED(gl))
{ {
if (CTRL_START(button_was_pressed)) if (CTRL_START(button_was_pressed))
filebrowser_reset_start_directory(&tmpBrowser, "/", extensions); filebrowser_new(&tmpBrowser, "/", extensions);
if (CTRL_CROSS(button_was_pressed)) 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 /*if 'filename' is in fact '..' - then pop back directory instead of
adding '..' to filename path */ adding '..' to filename path */
if(tmpBrowser.currently_selected == 0) if(tmpBrowser.current_dir.ptr == 0)
filebrowser_pop_directory(&tmpBrowser); filebrowser_pop_directory(&tmpBrowser);
else else
{ {
separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser),"/") == 0) ? "" : "/"; snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
snprintf(path, sizeof(path), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
filebrowser_push_directory(&tmpBrowser, path, true); filebrowser_push_directory(&tmpBrowser, path, true);
} }
} }
else if (FILEBROWSER_IS_CURRENT_A_FILE(tmpBrowser)) 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)); snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
printf("path: %s\n", path);
switch(menu_id) switch(menu_id)
{ {
@ -962,7 +961,7 @@ static void select_file(uint32_t menu_id)
static void select_directory(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; uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data; gl_t * gl = driver.video_data;
@ -981,13 +980,13 @@ static void select_directory(uint32_t menu_id)
if(IS_TIMER_EXPIRED(gl)) if(IS_TIMER_EXPIRED(gl))
{ {
if (CTRL_START(button_was_pressed)) if (CTRL_START(button_was_pressed))
filebrowser_reset_start_directory(&tmpBrowser, "/","empty"); filebrowser_new(&tmpBrowser, "/","empty");
if (CTRL_SQUARE(button_was_pressed)) if (CTRL_SQUARE(button_was_pressed))
{ {
if(FILEBROWSER_IS_CURRENT_A_DIRECTORY(tmpBrowser)) 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) switch(menu_id)
{ {
case PATH_SAVESTATES_DIR_CHOICE: 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 /* if 'filename' is in fact '..' - then pop back directory instead of
* adding '..' to filename path */ * adding '..' to filename path */
if(tmpBrowser.currently_selected == 0) if(tmpBrowser.current_dir.ptr == 0)
filebrowser_pop_directory(&tmpBrowser); filebrowser_pop_directory(&tmpBrowser);
else else
{ {
separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser),"/") == 0) ? "" : "/"; snprintf(newpath, sizeof(newpath), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
snprintf(newpath, sizeof(newpath), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
filebrowser_push_directory(&tmpBrowser, newpath, false); filebrowser_push_directory(&tmpBrowser, newpath, false);
} }
} }
@ -1895,7 +1893,7 @@ static void select_setting(menu * menu_obj)
static void select_rom(void) static void select_rom(void)
{ {
char newpath[1024], *separatorslash; char newpath[1024];
uint64_t state, diff_state, button_was_pressed; uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data; gl_t * gl = driver.video_data;
@ -1914,7 +1912,7 @@ static void select_rom(void)
} }
if (CTRL_START(button_was_pressed)) 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)) 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 '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); filebrowser_pop_directory(&browser);
} }
else else
{ {
separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser),"/") == 0) ? "" : "/"; snprintf(newpath, sizeof(newpath), FILEBROWSER_GET_CURRENT_FILENAME(browser));
snprintf(newpath, sizeof(newpath), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(browser));
filebrowser_push_directory(&browser, newpath, true); filebrowser_push_directory(&browser, newpath, true);
} }
} }
@ -1940,13 +1937,13 @@ static void select_rom(void)
retro_get_system_info(&info); retro_get_system_info(&info);
bool block_zip_extract = info.block_extract; 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) if((strstr(rom_path_temp, ".zip") || strstr(rom_path_temp, ".ZIP")) && !block_zip_extract)
rarch_extract_zipfile(rom_path_temp); rarch_extract_zipfile(rom_path_temp);
else 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); 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()); 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) void menu_loop(void)
{ {
gl_t * gl = driver.video_data; gl_t * gl = driver.video_data;

View File

@ -157,5 +157,6 @@ enum
void menu_init (void); void menu_init (void);
void menu_loop (void); void menu_loop (void);
void menu_free (void);
#endif /* MENU_H_ */ #endif /* MENU_H_ */

View File

@ -21,7 +21,6 @@ else
HAVE_RPI=no HAVE_RPI=no
fi fi
if [ "$LIBRETRO" ]; then if [ "$LIBRETRO" ]; then
echo "Explicit libsnes used, disabling dynamic libsnes loading ..." echo "Explicit libsnes used, disabling dynamic libsnes loading ..."
HAVE_DYNAMIC='no' HAVE_DYNAMIC='no'
@ -93,6 +92,7 @@ fi
check_pkgconf XML libxml-2.0 check_pkgconf XML libxml-2.0
check_pkgconf SDL_IMAGE SDL_image check_pkgconf SDL_IMAGE SDL_image
check_pkgconf LIBPNG libpng
if [ "$HAVE_THREADS" != 'no' ]; then if [ "$HAVE_THREADS" != 'no' ]; then
if [ "$HAVE_FFMPEG" != 'no' ]; then if [ "$HAVE_FFMPEG" != 'no' ]; then
@ -140,6 +140,6 @@ check_pkgconf PYTHON python3
add_define_make OS "$OS" add_define_make OS "$OS"
# Creates config.mk and config.h. # 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_make config.mk $VARS
create_config_header config.h $VARS create_config_header config.h $VARS

View File

@ -21,6 +21,7 @@ HAVE_PULSE=auto # Enable PulseAudio support
HAVE_FREETYPE=auto # Enable FreeType support HAVE_FREETYPE=auto # Enable FreeType support
HAVE_XVIDEO=auto # Enable XVideo support HAVE_XVIDEO=auto # Enable XVideo support
HAVE_SDL_IMAGE=auto # Enable SDL_image 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_PYTHON=auto # Enable Python 3 support for shaders
HAVE_SINC=yes # Disable SINC resampler HAVE_SINC=yes # Disable SINC resampler
HAVE_BSV_MOVIE=yes # Disable BSV movie support HAVE_BSV_MOVIE=yes # Disable BSV movie support

View File

@ -499,6 +499,7 @@ static void print_features(void)
_PSUPP(cg, "Cg", "Cg pixel shaders"); _PSUPP(cg, "Cg", "Cg pixel shaders");
_PSUPP(xml, "XML", "bSNES XML pixel shaders"); _PSUPP(xml, "XML", "bSNES XML pixel shaders");
_PSUPP(sdl_image, "SDL_image", "SDL_image image loading"); _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(fbo, "FBO", "OpenGL render-to-texture (multi-pass shaders)");
_PSUPP(dynamic, "Dynamic", "Dynamic run-time loading of libretro library"); _PSUPP(dynamic, "Dynamic", "Dynamic run-time loading of libretro library");
_PSUPP(ffmpeg, "FFmpeg", "On-the-fly recording of gameplay with libavcodec"); _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.filename = g_extern.record_path;
params.fps = fps; params.fps = fps;
params.samplerate = samplerate; params.samplerate = samplerate;
params.rgb32 = false; params.rgb32 = g_extern.system.rgb32;
if (g_extern.record_width || g_extern.record_height) if (g_extern.record_width || g_extern.record_height)
{ {

View File

@ -22,9 +22,80 @@
#include <string.h> #include <string.h>
#include "general.h" #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 <png.h>
#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 line_size = (width * 3 + 3) & ~3;
unsigned size = line_size * height + 54; unsigned size = line_size * height + 54;
@ -49,9 +120,17 @@ static void write_header(FILE *file, unsigned width, unsigned height)
0, 0, 0, 0 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) static void dump_line_bgr(uint8_t *line, const uint8_t *src, unsigned width)
{ {
memcpy(line, src, width * 3); 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; const uint16_t *frame16 = (const uint16_t*)frame;
if (!bgr24) if (!bgr24)
pitch /= 2; pitch /= sizeof(uint16_t);
unsigned line_size = (width * 3 + 3) & ~3; uint8_t **lines = (uint8_t**)calloc(height, sizeof(uint8_t*));
uint8_t *line = (uint8_t*)calloc(1, line_size); if (!lines)
if (!line)
return; 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. if (bgr24) // BGR24 byte order. Can directly copy.
{ {
for (int j = 0; j < height; j++, frame_bgr += pitch) for (int j = 0; j < height; j++, frame_bgr += pitch)
{ dump_line_bgr(lines[j], frame_bgr, width);
dump_line_bgr(line, frame_bgr, width);
fwrite(line, 1, line_size, file);
}
} }
else // ARGB1555 else // ARGB1555
{ {
for (int j = 0; j < height; j++, frame16 += pitch) for (int j = 0; j < height; j++, frame16 += pitch)
{ dump_line_16(lines[j], frame16, width);
dump_line_16(line, frame16, width);
fwrite(line, 1, line_size, file);
}
} }
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, 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_t cur_time;
time(&cur_time); time(&cur_time);
#ifdef HAVE_LIBPNG
#define IMG_EXT "png"
#else
#define IMG_EXT "bmp"
#endif
char timefmt[128]; 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]; char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s/%s", folder, timefmt); snprintf(filename, sizeof(filename), "%s/%s", folder, timefmt);
@ -124,11 +220,18 @@ bool screenshot_dump(const char *folder, const void *frame,
return false; return false;
} }
write_header(file, width, height); #ifdef HAVE_LIBPNG
dump_content(file, frame, width, height, pitch, bgr24); 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); fclose(file);
return ret;
return true;
} }