From 53f645ed0b103cdfb1d24b287b52046710a6eb7c Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 16 Jun 2012 15:07:31 +0200 Subject: [PATCH 01/33] Add SET_PIXEL_FORMAT environ. --- driver.c | 8 +++++++- dynamic.c | 25 +++++++++++++++++++++++++ general.h | 1 + libretro.h | 14 +++++++++++++- retroarch.c | 2 +- 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/driver.c b/driver.c index 9e93197236..e65fd93fe4 100644 --- a/driver.c +++ b/driver.c @@ -397,6 +397,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) @@ -553,7 +559,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/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/retroarch.c b/retroarch.c index d4b683a5e5..80346d3dcd 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1171,7 +1171,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) { From b3e74aa1890a3575588c3a458acae4e64f80f30c Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 16 Jun 2012 22:03:08 +0200 Subject: [PATCH 02/33] (Android) Start skeleton app dir --- android/.classpath | 8 +++++ android/.project | 33 ++++++++++++++++++ android/.settings/org.eclipse.jdt.core.prefs | 4 +++ android/AndroidManifest.xml | 23 ++++++++++++ .../classes/com/retroarch/BuildConfig.class | Bin 0 -> 335 bytes .../classes/com/retroarch/MainActivity.class | Bin 0 -> 507 bytes .../bin/classes/com/retroarch/R$attr.class | Bin 0 -> 325 bytes .../classes/com/retroarch/R$drawable.class | Bin 0 -> 392 bytes .../bin/classes/com/retroarch/R$layout.class | Bin 0 -> 379 bytes .../bin/classes/com/retroarch/R$string.class | Bin 0 -> 412 bytes android/bin/classes/com/retroarch/R.class | Bin 0 -> 459 bytes android/bin/jarlist.cache | 3 ++ android/gen/com/retroarch/BuildConfig.java | 6 ++++ android/gen/com/retroarch/R.java | 23 ++++++++++++ android/proguard-project.txt | 20 +++++++++++ android/project.properties | 14 ++++++++ android/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 9397 bytes android/res/drawable-ldpi/ic_launcher.png | Bin 0 -> 2729 bytes android/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 5237 bytes android/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 14383 bytes android/res/layout/main.xml | 12 +++++++ android/res/values/strings.xml | 7 ++++ android/src/com/retroarch/MainActivity.java | 13 +++++++ ps3/main.c | 2 +- 24 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 android/.classpath create mode 100644 android/.project create mode 100644 android/.settings/org.eclipse.jdt.core.prefs create mode 100644 android/AndroidManifest.xml create mode 100644 android/bin/classes/com/retroarch/BuildConfig.class create mode 100644 android/bin/classes/com/retroarch/MainActivity.class create mode 100644 android/bin/classes/com/retroarch/R$attr.class create mode 100644 android/bin/classes/com/retroarch/R$drawable.class create mode 100644 android/bin/classes/com/retroarch/R$layout.class create mode 100644 android/bin/classes/com/retroarch/R$string.class create mode 100644 android/bin/classes/com/retroarch/R.class create mode 100644 android/bin/jarlist.cache create mode 100644 android/gen/com/retroarch/BuildConfig.java create mode 100644 android/gen/com/retroarch/R.java create mode 100644 android/proguard-project.txt create mode 100644 android/project.properties create mode 100644 android/res/drawable-hdpi/ic_launcher.png create mode 100644 android/res/drawable-ldpi/ic_launcher.png create mode 100644 android/res/drawable-mdpi/ic_launcher.png create mode 100644 android/res/drawable-xhdpi/ic_launcher.png create mode 100644 android/res/layout/main.xml create mode 100644 android/res/values/strings.xml create mode 100644 android/src/com/retroarch/MainActivity.java 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..b8c7093233 --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/bin/classes/com/retroarch/BuildConfig.class b/android/bin/classes/com/retroarch/BuildConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..2ecbee69f13ad92bd9b3fa8a38f48afd2984c17b GIT binary patch literal 335 zcmZ{fy-tHr7>1v(Kv8ThR+q*bPzOn8O^4#oLUd3W+z#~Eo`!M~3f`BKiGvs5MHvHe zaB+O!Jl~h+{rdj+1g0GM^n^)nH&LbQ%Bm_~Mf1iKi`bSgX6fS!;aa__s8HoHy3f`+ zuLbYwdj51P$g?nvZMm&gS*NOKv;&CHzci((XM%HbnhI`g7dpUUIAE7R7$v6Ecg-f# z)uYM^EsPVJt0GmEY4dOC)+@6Wj+1{4FNEO1HdU@~O#3GMV}IU?GezjEnBdVz@PQsX l2-4ah>;X}i!8?0r@YW&w&>euw2pAwOK*&KmlW|8K{s63lMKJ&X literal 0 HcmV?d00001 diff --git a/android/bin/classes/com/retroarch/MainActivity.class b/android/bin/classes/com/retroarch/MainActivity.class new file mode 100644 index 0000000000000000000000000000000000000000..45b23bfee91f67844495aec97b596278d6aa51a2 GIT binary patch literal 507 zcmZ{gPfH^)7{-5Zr?onrty;C~pS|p@R&em_B4|Mrsu!2u<4nLTHIbRL;%PtAUKBj| z0ro?QWUS~xa|k5Qo8R+1`TzX*1njZZq$X@;?m8{BFPti}tMp76dzg7MHU6$iU078% zFPzC!b#s%xDZ<<@V~sx$qTcpMs1IDOV3$jJ_4>z0(l6Q>v-XPi^Uy&Gdz@@GGCth4{ivicBAy&|~@I7w!I0Q^ik& zh_Gr%=#S6@QUn1S{Rig%RdNiK9QGEFybh4?4Uo`a_V|PvwJ_1&d0?sE>D;sO&S+PL ZF%4R@NGewMb$-SQ?C-2s5jHCC%@=@sX1f3Y literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f85362c78b0a9aeb245c8352760dfbd93e6bf4c8 GIT binary patch literal 325 zcmZvW!AiqG5Qe{L(nQl}YAu3y59-0tv&Bn65Q0LL-ZycvThatJTi?r*;K2v*p+q)# z66Y}R&p-dn_x1hp3Cx(r41{UbZgZ=hZI!Lo`SMITXJbNPyiui5QV>K+NQRtsr9dQ?Lu7`x>np2ghElM(yiR47n_paz)hk{pUIWr!Uyo7 zL~hWH;AY^=oH_H&=hyoOFk;|S69#d%iL5Scrfj^5X2(mbp4B4NK6RnDR!=HQm3fSA z7i%3CLMMqIQdOFGrL7czpzt1v4@NnQm8Z;4nphgQp95F%%h$;<@vp0g*%CZgB0(1$10C5I- S>{Ro9Rd?BgDn{7nkl{BT;Zhp_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fae0fa84b3dfd7e2703278445d1f0bb1aa24858b GIT binary patch literal 379 zcmZvXF-yZx6otRrq>0wl)~dDL9n`_lS#b#ng`!ZU`)hpIl=KB&UIZt9lat`!5Aa8c zBsz)9g>&z@hwprTy?+1`Mjm=>GZYG(^&(^Wh_&ed~Kxe#CIuho-^b7dam+vQrP zPVhG>GlEQoZc>=iDdQF@ueA5#fe>6~CUaMUcXGNA{G@o$9Xz@b+jNB9EHnD1+AOub zSIb-rgISTPe4%Vs>))mCR#_>GX8+S&2%Wp4vZ=n#>WpB1UZV=p)EI4(T$QCRLxw`{ zPl6EqG-QI{QA3Yu6Ci{@i!B7HX%TjSxY5u)dn0;nEW6M=K%X8EA+>=%d(C~&%zX}^ Ki4hJtV*Cv}*iB9V literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..2b74c5aebc496723e4b281c87e17ccb61cefc0fe GIT binary patch literal 412 zcmZvXF;Bu!6otP_TZ#yRph%q^)WL>X<3eIWLNr0cY993kO3EvFEw271Cld#MfIrHZ zRt95SZt~r8&&j!;U+*8lfMcJE(2LSlXmxH=WurwnImvPxo4JoGw3q5xg^4or@NTx$ zQ7+Wfdi`kBN((X)n#0s&xia}wB^&L$xQO5_bdsb6AXKkn6X(~0b9y!v++q5p>o~L; z?9vcgraAE{dt)If&)|t@TemACDjPn`NeevDcU16fv{xo&fnO3EiG** Z4bWvD%2V*@&@J_YavsuyZQKz7!8iGDQQrUn literal 0 HcmV?d00001 diff --git a/android/bin/classes/com/retroarch/R.class b/android/bin/classes/com/retroarch/R.class new file mode 100644 index 0000000000000000000000000000000000000000..83ec258ebb5e858646e43b2325ce38d798533aa1 GIT binary patch literal 459 zcmZvY%Syvg5Qe{L)27B~FV@<4*@z2uVdz?MQxJrrP^J6R^w6fn1Wr=L$8sgO@Bw@% zk)*l_&SK`Dng3@lU*8{}zn=lvG#~1kyf_ods+6*I=raHCh2;GwOL}i%~tUTE43jH!+X4K1ir^X+& z=?lFwF;cI|DnE7&Y!3b*rI`uixlmsN1_)Jh6C{5If(`gZ4z=@l8gD=a2Z}a0YyvKl h6L8ro`rCzX(gKdLXd~?4(M9Otv4`N{v5# +# 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..2b02953f09 --- /dev/null +++ b/android/gen/com/retroarch/R.java @@ -0,0 +1,23 @@ +/* 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_launcher=0x7f020000; + } + public static final class layout { + public static final int main=0x7f030000; + } + 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_launcher.png b/android/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..96a442e5b8e9394ccf50bab9988cb2316026245d GIT binary patch literal 9397 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 literal 0 HcmV?d00001 diff --git a/android/res/drawable-mdpi/ic_launcher.png b/android/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..359047dfa4ed206e41e2354f9c6b307e713efe32 GIT binary patch literal 5237 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 literal 0 HcmV?d00001 diff --git a/android/res/drawable-xhdpi/ic_launcher.png b/android/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..71c6d760f05183ef8a47c614d8d13380c8528499 GIT binary patch literal 14383 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 literal 0 HcmV?d00001 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/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..c9364e2ea9 --- /dev/null +++ b/android/src/com/retroarch/MainActivity.java @@ -0,0 +1,13 @@ +package com.retroarch; + +import android.app.Activity; +import android.os.Bundle; + +public class MainActivity extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +} \ No newline at end of file diff --git a/ps3/main.c b/ps3/main.c index 1ae53780b1..dc7b0b0c17 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 From f432463aed93a60bf78e48db3c8d07ed586afbc6 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 16 Jun 2012 22:07:29 +0200 Subject: [PATCH 03/33] (Android) Replace icons --- android/res/drawable-hdpi/ic_launcher.png | Bin 9397 -> 2525 bytes android/res/drawable-ldpi/ic_launcher.png | Bin 2729 -> 925 bytes android/res/drawable-mdpi/ic_launcher.png | Bin 5237 -> 1642 bytes android/res/drawable-xhdpi/ic_launcher.png | Bin 14383 -> 2971 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/android/res/drawable-hdpi/ic_launcher.png b/android/res/drawable-hdpi/ic_launcher.png index 96a442e5b8e9394ccf50bab9988cb2316026245d..16db30ee1035a096af0fffb9f0e2219585b38de8 100644 GIT binary patch delta 2515 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 literal 9397 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 W9n+@7XBw6O0000v?%Diqs_lhQIONz`Zn zBT5hn;Sn&2B!mRxO~^a<`Fot_K6~|#bMJ+eOXVuvGkebOw|~#xXMNXqeb?IOY?wrQ z=HNAd`k&98cl>15yfAX@S>J#0qWN!izM0I!pWnJ`v8ScA_is3-I5wubraN)>ouayW zk?Q(6ub;n1Z=Cn?u6;jx^3i>bw`xO}WV`E!=RQ!M;=lBt$-fXY5bY=1F-er4QFQ3dT!ova}n|J zDdN$^2!|M8H?hVLNt8|NbG{mR>gwrs?kdg2uIq16lt+7Uq~0bAwd>6bFYTr8=La8{OIvvh6^;H!WA^5jFdYV(J=><`xf@W}3u z4mk;WoW>YeM_dsph8WLB5Y!3IIjnWq)RLwtNq?Mztut_RSk+i*52x(kGko*Cx4m-5 zq(%K7j&U%nHeYsnvpLe!Zg&VfnTAo5AQ>bKVmj?G@12049TEl+VHgvI2}x|}g#8#l z5t~>t>#&KtbRv8A{P^8(1oWHibK`@bd>u?1md^@12~m)099qdWk`e|9Q4kY$Mtc|& zg?}+gl#;}jB*{qA44Y+GYc)+%TqX<0o_j>UaK>-+rUd}CDIT|f>r4QAfXxFpG0(db z)qg7wF?d&p)&+Y9`hGcZL_T+L`>gLB>Fm6`SoA+s@6D*xJ&Gj|10o72>I784PhAIa?cbkttcHHF z=ZgDOlWSCc`VaTB=hp)doVH}{g9J0z{OG}rx?{_LG>2kT!Sf8oqKD@j#DD_oG}lq0 z#F53O8AgO^qo8w6oGP^*|D}1SXUk7Kb?V*KdY9iC3G_f;Tb_CB@TqH89N00=(0^Ea zdCQ^G!ejvOh&qk~dpgsLUgw=tX1&0LSN6&!S5HOou!$j!9cc_URcz+4X@=7b#K9O_ zD9$;O$jQincrJ_&NKIY{fZnxxm0Fo@c~mYE<(?$O(9D!|;!-k|w|JMzcrN z2ohy>)Vs{#vH~)48W+6pZxA8pTx67cp}RJdvlm^((Y-}pX}^RiTGT1NS5>72np3P! z)j7mvN*E;JgoRO+NS%^*Kz~gUBzMj!s=}<^GdSzCOStu`m-76U#|fg&xSo90TczND9&ll5IX8;yB|C8UZ&E?Q&Gh^#W`yXUe1_~h3!}uO2sNC z9JiPmGp19oc8`Mrh=1Y$T%IkOY5voV0#S0oI{`>01SBG1uKawFQ$>s!ufpm^bMb$* ze2sg(7V~{DvnYb9$&03eqn5n=m9uq%Jo;3QC-_>6orm6?Eb^7CpwX{8}s( zb0?foDl|}sVo=R9cr^oiAcd+nE5_tZVqd%^b&f>BQzGBTL-|M&8(H=O;xQ=e^A=e^iz z^4+6@yKlSf%8Tv#hqkcmS4VRN-hS^#_`+wt2f#&FoaoiN8`U^;=?_+H4ewj^5AQhK z+SC`?KJ^PeVnke)?{!I}B<(sU&3He<>2?MWWu%2Z{C`r0U+{9>siIkdBD4AR&Q~8@ z`R|)QI8n$yecO3_-A}y>{v8j5J%U`q#cUwdwy~fPcooyytRwW+hCWSxO@7(;NyJ+!+vu z2e7gE+Oz8q-U`TjFPZ(5PBij?N~KJxt3bgoq zell%lnOa?G4mm~!ElFUCQ@iKO$8UI7W#{haU7=j2QZG|1dMfymc4Sfq8vbM^7fQwy zOMim#JT(SUCo~-tix$s^a?N*TuSl&?#P^M4X@Pb!L1}-x&WA*#CC1=+BE_;txmKWD zDTfD-_Gz_Ib&Z~KTI()QX%w`p;#2A}c%F3r-vD)*@$xL`N{seU@}^QO)(>T_xfWpd zaeovRE7^CZPMr}#|!d*|R6{H=+M{9o6koSw|&b3an%jMEp+^}O==zSk8+LHxvq zjT;WX_*j1b`Y+8lJ&hCopwv}c;+fLWz>&jSzxMejhyVQgGcbP4xBunk-)iH30EM0u U4!@C?rvLx|07*qoM6N<$f_6Px# diff --git a/android/res/drawable-mdpi/ic_launcher.png b/android/res/drawable-mdpi/ic_launcher.png index 359047dfa4ed206e41e2354f9c6b307e713efe32..b311ce1fd446b9de3092b2f595960f6bd90ac2a9 100644 GIT binary patch delta 1625 zcmV-f2B!J-DC!K5B!2;OQb$4nuFf3k00006VoOIv0RI600RN!9r;`8x010qNS#tmY z7ZLyf7ZL$ypVCqQ000McNliru+y)R72LK`;NuU4#1?oveK~!ko?O0z-Q)d+aefM9B zEg+q!NQ_}prl?6@BwO~NkeC>=>}9yUnJm!ZbUJb1z<~}S#0P~MK=SC+)YOeoC{!Xz5)8wD&*yuh zs%nEQ%aKj-a({SuI1YeTYHe*L$#)CY9gRl&?7Ax}D@n2~7kMccroO&D#s1s)_&5N> z3UweH4kzrtEiEkp!27w#E0$0S0M2x736VB#-@bjz)^7mdcDpm=Hww4gouxz5GywR< zVw(&=``bC52-4Fn_D6YD6Lt#^Z4&5($H(H&>%| zUB42K$EoW&FI>1lyY5}Pc9G;~rfp5pXq5Nw-)CQ6AD=yYMv`A=D2&BozXLEVN{qvY z50m5MRW<9Bva&J& zm;wMop|*NJVW8c!R;rY`c5+E&%*Q@{!pYe-lEq3L!|+5JJe- zD40cVxsqhE(_TnTO--~IKfZVGUTT^~r_-5LbSd(9JoI=x+`fG~%gf6%sG_2RJ9g}# zB!5Y(%B!kMNs^4#)>iA;aeEE4wY8DtTj>bMvi!5AY4643@w8L6sFY4lP9m91u6eby zv$F-Y)I=fy0K)J0ugO|rr$APrfT@v^Xc_wLN97h}Gx^*irS)b2GE9&d(H|)TM-!ejo ztO1jcY{rXHk~W-f8d5 z*#S+{RMY#shtgJ{s;X+$9hO+7#eb;)#)841UR70vmX?<4wzjqm-lnD|T)TGdF95+@ z7i25IarNreqbE^(w(&aK+0@Bog1{Tm!LK_Re;4auNU< zgb=Z;-DIIV{{OagF#uv=VPUm(WX?srR8v!v^@a?am!CSoz9gOS#&rYL;1{s z=HA}k_R-N%D2f7?%Y{>?PR*B;lJgF09cEJvMkGujg3At#Bxth&z}I?FXOcgAaUZviFZ;q_Vo1J1mHpuMHErQD~Epp X`tbgV%hMbK00000NkvXXu0mjfWa|de delta 5228 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 LNkvXXu0mjff)~BH literal 14383 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 From 3ad9c7ba847aa3d2d20f2b3183f95792981867ed Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 16 Jun 2012 22:47:16 +0200 Subject: [PATCH 04/33] (Android) OpenGL ES 2.0 skeleton driver - shows a triangle right now --- android/AndroidManifest.xml | 5 +- .../classes/com/retroarch/MainActivity.class | Bin 507 -> 907 bytes android/src/com/retroarch/MainActivity.java | 39 ++++++- android/src/com/retroarch/rgl.java | 95 ++++++++++++++++++ 4 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 android/src/com/retroarch/rgl.java diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index b8c7093233..7e450a1267 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -19,5 +19,6 @@ - - \ No newline at end of file + + + diff --git a/android/bin/classes/com/retroarch/MainActivity.class b/android/bin/classes/com/retroarch/MainActivity.class index 45b23bfee91f67844495aec97b596278d6aa51a2..377b626eae8132a695bb6877f9e398d2c31935dc 100644 GIT binary patch literal 907 zcmaKqT~8B16o#KumbR1?XhEd4@*#fEMcsH^L!u-alWL45P4tEg+Y#23S+YAV__IvZ zCYtyI{87g2wxnRt%b7XnnfE+1zkYxJ2|VUuft*kaqGLbSHjY#r9Qm(QXr2Z(9EA2$ z0Y_L;rW;3L*HSbJf*xL^xWA&LWvBZruGk%h1{KsEqCrKeLz{*B9;0{vQM8t@t3lN3iN^BG?T!32=L|znZ zrkR;Db11x&^L*bQz?gpOOwx5bU((p*)6+JrX*?=wufRcQYFhY$w~3PJDo&y}SuCTS zkQ>g=M;V=K)^HCNVgLvQV1yum9o#5hFt!7kZPW$yH-M%Lh}ry=XINM!5rj9YLA`#Z d@n?7_%rhGo7oD*N{ Date: Sun, 17 Jun 2012 00:18:23 +0200 Subject: [PATCH 05/33] Add DEBUG=1 to Makefile.win. --- Makefile.win | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile.win b/Makefile.win index 9f282a6e90..d64ee4a462 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,6 +152,13 @@ ifneq ($(V), 1) Q := @ endif +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 + LDCXXFLAGS += -s +endif + CFLAGS += -Wall -Wno-unused-result -O3 -I. ifeq ($(CXX_BUILD), 1) CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS From 042eb51d74ec448861584a29767a0b36098249ad Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 17 Jun 2012 00:20:12 +0200 Subject: [PATCH 06/33] Don't automatically add -O3 to Makefile.win. --- Makefile.win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.win b/Makefile.win index d64ee4a462..b20ab47429 100644 --- a/Makefile.win +++ b/Makefile.win @@ -159,7 +159,7 @@ else LDCXXFLAGS += -s endif -CFLAGS += -Wall -Wno-unused-result -O3 -I. +CFLAGS += -Wall -Wno-unused-result -I. ifeq ($(CXX_BUILD), 1) CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS else From 13839bc511179e37827cc5cd1fd768aee3bc7b72 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 17 Jun 2012 00:47:23 +0200 Subject: [PATCH 07/33] (Android) Add initial audio driver --- android/src/com/retroarch/audio_android.java | 130 +++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 android/src/com/retroarch/audio_android.java 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; + } +} From d843dacfd404f56797282e28863a3ee18827d85e Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 17 Jun 2012 03:36:59 +0200 Subject: [PATCH 08/33] (Android) Added placeholder ActionBar --- .../classes/com/retroarch/MainActivity.class | Bin 907 -> 1937 bytes .../classes/com/retroarch/R$drawable.class | Bin 392 -> 628 bytes .../bin/classes/com/retroarch/R$layout.class | Bin 379 -> 379 bytes .../bin/classes/com/retroarch/R$string.class | Bin 412 -> 412 bytes android/bin/classes/com/retroarch/R.class | Bin 459 -> 537 bytes android/gen/com/retroarch/R.java | 19 +++++++++++++++++- android/res/drawable-hdpi/ic_action_close.png | Bin 0 -> 729 bytes .../res/drawable-hdpi/ic_action_history.png | Bin 0 -> 312 bytes android/res/drawable-hdpi/ic_action_load.png | Bin 0 -> 725 bytes android/res/drawable-hdpi/ic_action_open.png | Bin 0 -> 578 bytes android/res/drawable-hdpi/ic_action_save.png | Bin 0 -> 614 bytes .../res/drawable-hdpi/ic_action_settings.png | Bin 0 -> 608 bytes android/res/drawable-ldpi/ic_action_close.png | Bin 0 -> 349 bytes .../res/drawable-ldpi/ic_action_history.png | Bin 0 -> 188 bytes android/res/drawable-ldpi/ic_action_load.png | Bin 0 -> 406 bytes android/res/drawable-ldpi/ic_action_open.png | Bin 0 -> 281 bytes android/res/drawable-ldpi/ic_action_save.png | Bin 0 -> 306 bytes .../res/drawable-ldpi/ic_action_settings.png | Bin 0 -> 304 bytes android/res/drawable-mdpi/ic_action_close.png | Bin 0 -> 472 bytes .../res/drawable-mdpi/ic_action_history.png | Bin 0 -> 234 bytes android/res/drawable-mdpi/ic_action_load.png | Bin 0 -> 506 bytes android/res/drawable-mdpi/ic_action_open.png | Bin 0 -> 407 bytes android/res/drawable-mdpi/ic_action_save.png | Bin 0 -> 418 bytes .../res/drawable-mdpi/ic_action_settings.png | Bin 0 -> 395 bytes android/res/menu/main_menu.xml | 12 +++++++++++ android/src/com/retroarch/MainActivity.java | 18 +++++++++++++++++ 26 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 android/res/drawable-hdpi/ic_action_close.png create mode 100644 android/res/drawable-hdpi/ic_action_history.png create mode 100644 android/res/drawable-hdpi/ic_action_load.png create mode 100644 android/res/drawable-hdpi/ic_action_open.png create mode 100644 android/res/drawable-hdpi/ic_action_save.png create mode 100644 android/res/drawable-hdpi/ic_action_settings.png create mode 100644 android/res/drawable-ldpi/ic_action_close.png create mode 100644 android/res/drawable-ldpi/ic_action_history.png create mode 100644 android/res/drawable-ldpi/ic_action_load.png create mode 100644 android/res/drawable-ldpi/ic_action_open.png create mode 100644 android/res/drawable-ldpi/ic_action_save.png create mode 100644 android/res/drawable-ldpi/ic_action_settings.png create mode 100644 android/res/drawable-mdpi/ic_action_close.png create mode 100644 android/res/drawable-mdpi/ic_action_history.png create mode 100644 android/res/drawable-mdpi/ic_action_load.png create mode 100644 android/res/drawable-mdpi/ic_action_open.png create mode 100644 android/res/drawable-mdpi/ic_action_save.png create mode 100644 android/res/drawable-mdpi/ic_action_settings.png create mode 100644 android/res/menu/main_menu.xml diff --git a/android/bin/classes/com/retroarch/MainActivity.class b/android/bin/classes/com/retroarch/MainActivity.class index 377b626eae8132a695bb6877f9e398d2c31935dc..33f0134ca22eb8783c6bbb47ac0f7ddeaaac0069 100644 GIT binary patch literal 1937 zcmaKsYj+b>6o#MOPMb6x3r%nK0v4>Aq(Cg-b+8Imu$Tgp8l|8(ogC7^WTs9|+WN^q ziXo?A8`Y0}{)t`D{pw*tv zFwT_G_^L41WyQCFF0OQnVa8^F!3@Hj%{k5sBTc2_m_QpNj_BF()owAi$2gL0 zx;v`68Z@;Vc&e;p^<$@q7sd|SyT7gdFler+pmmaLPM!RQQL|w425$;yYD$~q)!qkjaY5BvqP8} zTmp!M*^~JPvK?U}43g$owQ7`AU3pqng_-V%4!I`6$#0~1N0@rwI9Q{-H3DD;-aA@|9t3u$vRUC%VbI;)RzX#`+*|kl=5ys~rD9)Q0r<>3wOKoIsO-VnK`T77uw5?Yky@^G26pxZiTyouj^NM*m zTtMgtgg&z#fI-A;J%k~kh#G33XA(> z3ojUdRM=0v@6o#LZn~$0%O&h;@>$i5HU3lqQaT5>9+hdEawh&b&W=eg6R*bJ(LL>}!8f1XBgCf?gG;hs&Tot3_#gw1wSs zb*YL{xwGQ^;@s#;7+F16y0YHQb?KuKd*YWl~$$RR77iq-NLDs4na1wlLl#L{nAPoy9cY5w@+Kmul_w%7i3!h3;$XZ1qOS zp1+t0?TKHSJ{kFd+uRXGQ|rvT^~J)3kLl~ecc!w{ua+MLI(86>Ci>!0WG%3xzXT0Iok~$ zkTY!X4mqO+?~=3E;4wKj8+;2vQX>d=fud&U99^;htv=xZ>IE2b4;Ub6fcreC{fG7Y Nh{r&`UVp+f^52slef9tV delta 161 zcmW-ZI|{;36hzNe6ZPdqjlU$Mx3Cc#*WnICf}kQ60e4_w`^ZYH0v0a7?U-65w;4Fh znW;OEw)y;CZ(vR0%*F<%e0SO3uKDp$xNYXXi62_}m@<+==H*=$XCcMIN9Y1AdI-`u k2m!EC25(tmpQ;Q%2M{s@EYb*!h_oMTPMCt;2s2{RKT1jyJOBUy diff --git a/android/bin/classes/com/retroarch/R$layout.class b/android/bin/classes/com/retroarch/R$layout.class index fae0fa84b3dfd7e2703278445d1f0bb1aa24858b..9feb438dea38a7c86453e42305bae200b199e627 100644 GIT binary patch delta 13 Ucmey(^qXmeA0wmOWPe5-03>S!C;$Ke delta 13 Ucmey(^qXmeA0wl{WPe5-03;;@8UO$Q diff --git a/android/bin/classes/com/retroarch/R$string.class b/android/bin/classes/com/retroarch/R$string.class index 2b74c5aebc496723e4b281c87e17ccb61cefc0fe..9838af76c9e6f00ed3cacc1b992a0d11fe980dde 100644 GIT binary patch delta 13 UcmbQkJcoHhJ|m;ba-V`LCPSCX5WSIWr10;1R%6esI3RxukfuuWdgs35=~%fQGW&mhU5z`)3$#2^U( DP6->b delta 37 tcmbQqa+;az)W2Q(7#J7~8DuwdF)~ipU{qq1o}9y2#jM1@GWjK=0sz&*3Hty5 diff --git a/android/gen/com/retroarch/R.java b/android/gen/com/retroarch/R.java index 2b02953f09..4b7bc1bc03 100644 --- a/android/gen/com/retroarch/R.java +++ b/android/gen/com/retroarch/R.java @@ -11,11 +11,28 @@ public final class R { public static final class attr { } public static final class drawable { - public static final int ic_launcher=0x7f020000; + 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_save=0x7f020004; + public static final int ic_action_settings=0x7f020005; + public static final int ic_launcher=0x7f020006; + } + public static final class id { + public static final int close=0x7f060003; + public static final int history=0x7f060004; + public static final int load=0x7f060001; + public static final int open=0x7f060000; + public static final int save=0x7f060002; + 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/res/drawable-hdpi/ic_action_close.png b/android/res/drawable-hdpi/ic_action_close.png new file mode 100644 index 0000000000000000000000000000000000000000..1c74f6df01d05ee37092477c3dba8f4bdd254c40 GIT binary patch literal 729 zcmV;~0w(>5P)9r+DI2-4N@xzO8>z@kIKrc??wRBD33^rm;r(jk#pL(_$!J65Ce1tuC*8!N8rm!FL z>cT9*#SVhB>oU6Qzzlvsn3n#ILdnPUdkxcRJi^W9^-w;RR1FG^54#hMMz9S_OFWjy z|MEkLUI(gRR!9r*J8ViE|7zTg_)X!f_Js|3&{8#y?-HRF;AF(_n&Li%bv0m$P^q2j z!mkm(Z;K0lnE?>_PQ0;3r$Xa9+bZnFtH_VWpi(>46Y*J+VRNA9ru-fDA_7$>Q=vWX zhYW`T1^rEvb%{{XPT~82$Ilu5sJQtapBIdJg-1(5rmz^373;5NxKnX+ti)_>B2=(b z@-tMKMl(FFxOuz6Y}T2Q?>l9BUK^-sIIB$IdI%_aWF?)NQKsZa-7<|Phq?l)cBbSn z->MVAl?(?1X8j?cLZ^~5g&zZT$1-dR6#NqdYW_%arf@Y-)0bf(UIvPK6QNQv^)_&C zLhG{$#{-3j%&kYxR8bJas}>@JY(}TTtgeAk3f1Fm2=8B_8xTn#5kQF-5?>#H9|v3}e-dLE4}i z_y#A`+lj|mGz1+|R*u55hj47ht*t z;TUf}V7de044=PXRu94kE-_jH121^|Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyh` z0S!95t$tL_t(o!_AmYYZFlvhTk(LMbxOYw7L-2DhN{Wqjn?IintfimEgZ9 zs320;g4=GY*owLftu!WSD~i;wT?Kd2EJV?bwS{!?xS7ZplgyouWPD*ZckZ0?aL&2s z-npiT0tO_FNjfd*h@=CO3jXV#lGY@xN_r)!Y-T@{wg3ahfk(hE+_etO0A~S93+5zH zA-SFd$CH5Mfa^e=^i&5XfLv6V-M}2(QxPacfvM1al|rHXG|kgH6+5O6xIynV(GF$= z*vbH?4xDIkc#S?IX;M;7y;ok+WTQ`c{@^)DXA&4)mh>XQ_hbI^CtZ&dg!}=}=RdOv z?94V`27!$PFx#3|X6eo3WRR-c zX7;+>zLN(QdKjJg(7#x}i7oX2rW$OvE>PW!)H7$8ru5xPxzM+On~^UYTCBb_TEZeQ zlGYuO2V4N20-F&aHi0L=dDjaoivc$zY25KjuViN5qS*fpV%!oYo(e+x00000NkvXX Hu0mjfe&Im( literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..41233c5e00e8df7745ad10128d9e990638ae14d9 GIT binary patch literal 578 zcmV-I0=@l-P)jwCW{jQW9C}!X+R| zLM1;J(r^3g{!C(B{PN30TP|~hztKCGK7a{6d=>0f%_N=l{txOfg(xPa3VzJQy*no)H0>S z!_?1zCdnHNb`yGVgfcA_JIPE5e}T8~B~jaf84XM(Wd`J%+A}E+c0ETmRkX%!nT8c3H`=!B;Ew`Qlt>vio`o}9{yr1MQ9ucIWr$e;^RU$ zwlIT-c8lNw8DKZ~7=zN!(vWi%_)`L*U7Tu#yexsx zi}sK!B@mi!52=U`NugXz5t_@9vo3j&#ChRI*d1&nDr;&d*~huVi$^TA7#LOr3#l?q zp+WK0UAGwR(qC74BtKROIH;8SdcYL8DbN%H{f1a z$JyK>38@M$VOe}T=#^bO$F!n8Sf$7f<0h8GA13Pf-mE&_;t}Sx_ND;-0c-U}X-5cg QvH$=807*qoM6N<$f_2yT$^ZZW literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..dbc044c9d8097dbc098636cc3b6cd9fee512be0d GIT binary patch literal 614 zcmV-s0-61ZP)x*s&zNyMb3Jo7e=^;kz5lGWX6?NviYkIpT*rN^VG}=F&n8xJ57#hKb^fvv`)~=1 z*jAoxJi$fuH6=5Fw-qF^c#ZK+LbUwi$mI-wM`Rj!F!AkHL)IHH=RwnIjov2l26BtuK*quqxsK1~L{J z6YA@gHjzolJS?%!kFr9sRNF}9Q9dNq?| zJ{jf<9ZW>nt2#YTO(uop5Z0-=UqQ5 zW(&Uhmnrnk6=oa0`9FWqUo>V1ek5SxsG~(;cH>tSOer%MECMr;0u%34b5Pie-x)CR zP7URa*;6Mbe-wH|$2pG-=YeUYGv%4VFk0)u9FSjU%5x?Y3cXFllyWu|3VovET0~Bz z!8E%w@r+l)98+9pN*S$$>7N74Bdkcm42X_nk-3j$Nth1B?wJy1d8J!5P%!2WmR8%y zSMeR)_|jy|-Kv-XdVz=Gbr(K233D5ZYGKxhPS!~5y)Jxg0%l27Ojvwpm~gP{{f+pL z6Xu3morx`cB24N`xV9k&)XmhGu;?g$VsVA*9e7_S<{B2H#)Ji*<8h5K9e7s(wFYl zziT($S(XqQIK?}L#ri-CO_WmSLO>NA|LXy@X^>6y=75aVM?HqD;X5+^;2itdLmPtx ztQLaq5;t~Hi7s5kRie#OhWd>7&nQQ*5-ua(PKM)PV}z#!ER`&5vz_53*tkL&k8>nz z1@+HN{$OJr7N(^suu1^h4QjthP+^>zECP)tT8rXOO@_0$wWE-Xl?awf)|LOWv053n zBhw8Q=13N*IX2!#g=;J)lEq&G?nBcmz9Pd={_zfqby4hv>SH~gw+)l?HcLHhWhoWO v;x<$2pqhk4z`A^NUge`Oz#C4`NS*luXXB$@T26hQ00000NkvXXu0mjf*@}>> literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..85f21277779bd3a801a27890c90434c2b4d5c465 GIT binary patch literal 188 zcmV;t07L(YP)_Ci6Y{4EZ!#XU)CM-iRFuKShF1%bpo`HdTDB|7>ez56-{h2N0A7PFo z77=8Hi)YKJ$Qr#@?GQE?jBA6i#npQq&R^E4Ms~P=Kz`{~FvET#FoF(2Bp=GzTH0Z! qUw`U@tg!fqR9JjyD=hwvwDtg3S&VU}Z12JV0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyh` z0S**PRv>Bs009uM$d~+EB_WCB&l6N{Eb%jicOX!7812naR)I9 z78a>RcVIfBWC7x_nZWRp_g-Q?7#J>>GvA$iXA&kz-2+-c1K0@R51gU@ba$1z1okz%6hb;;GsKeu3qT z*?tsi?u3EUlVXr=Y79%z(XiD2f*%ez9uu zPKWJx0GgPj)RB+@D{Z?SqeKqRqdfPvx&u9X6T_CUJ1}sq)dLO6m4^zHpWTP|A!>e3+hSa z4DnHjPvTzAAgIUMuz`>rf- zm`~(nN7(|$ZGV6YZ(B%4E0weeFEGFi%ebbvks6!v3-_`AIuugV_5c6?07*qoM6N<$ Ef(Si?2mk;8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..7a3dc396bc416455323b0f957dd66babfd6d6831 GIT binary patch literal 304 zcmV-00nh%4P)eFdP^ZgVE+65Ck!4vDw9DFd2+Cn{c32ZQ3;$L{Nj_1O==AKoQ{{ z!_MNex3lc-y=iB5zGrqnzE-P3(7`Pp(XCPwLmvF6UmL?To(<<6v!f!_G0fnl1WEIO zxlxfUHlIhjl4jOTKaadNK;SGzrtsDfImJW@tw{Rv+W;BQ{?sO}@Zl zc;2Xh4I`oWDf@|7$9DudMmsh)HwF7eSTPa`)^Hwqw~DWT97U0E_y7a!gmoJW*hUYZ zI4ng%;dQuifIG=#Uttf+m@EY{&^<1(izVrB)yyC7hT!APrx(Eh00006P)NklcgyTqtFS3Zh(L7zYnGz&wNoy&iBUlW?~%icOGDnRkl;)A*U`;z9w^G+lKK9bOlBoC(A-J(j~K_xFaiNyUyxzI$!Z<>q5 k&4VNoH_?(v+)Vy!uIRFHITwkKIsgCw07*qoM6N<$f+PWCwg3PC literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..659c27fc845848d3e2e3f31eebffe26defa95861 GIT binary patch literal 506 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyh` z0S+k>K5Tmc00DYQL_t(Y$E}vnE(1{%#=mQ$*jn_@vMXMKtu&g7!~@X8j_@#*Ml8gN z1Z5$%o@r=KEaoB@>-EgeLv;Y7A07*qoM6N<$g5tK+l>h($ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9d0c7c070bfe82ddd4d0d099cccb93b882f57bb4 GIT binary patch literal 407 zcmV;I0cie-P)me;#5{5aCP7PrvI$y@?uohj^98~dz*>Q)wmyyVLHr*-E5|-kx1>XEz7s7p> z!eS(_oRNPJ53D6zP)&HnZ5ed~jd72usw-B7t9DWhurkccn-hu*u#sArRpApy#of@# zYec4TC^#X7Hyo(;d<3Cgoa0LP>-Ed$Gwh^@zX1`|iOjF+qsRaN002ovPDHLkV1fy= BxKscD literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..45c25de467d46708d318dd03fc7d22d40de9883c GIT binary patch literal 418 zcmV;T0bTxyP)yBeVr#5zyu2ES|Kx7nJM z_JY_jRXW2Q7I9q>zrq6Mah_oGgV>d2{l#42jLIfgSSZBj@vnk&7sS>t>kaFrN?XJw zE{gChwt@Ew&Qr>Oct~pvji19)MKTEZlL+P}KWgABHE^;NUDPaqmnxGCK5Y26AH zp$IL`rl5qbPIV~7k3-(!ak)z_cbD&W?|7f@EbxHx@JAWtHT{U+R5asRgl;k1_mL zE<9{r37h)nH^8s-{;K=oAU`mj3lGRn>||Z6VG{?T^e?{S6W-u)ZafrxP2BAbj`Sw$ pHJ*+HrWCZp6urj+9+d(Uxd%VG)(dF-S2O?s002ovPDHLkV1mwvtC0Wz literal 0 HcmV?d00001 diff --git a/android/res/menu/main_menu.xml b/android/res/menu/main_menu.xml new file mode 100644 index 0000000000..e6d0cc623f --- /dev/null +++ b/android/res/menu/main_menu.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/android/src/com/retroarch/MainActivity.java b/android/src/com/retroarch/MainActivity.java index aae2172216..2a1f77b482 100644 --- a/android/src/com/retroarch/MainActivity.java +++ b/android/src/com/retroarch/MainActivity.java @@ -2,6 +2,10 @@ package com.retroarch; 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; @@ -18,6 +22,20 @@ public class MainActivity extends Activity 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) + { + Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show(); + + return true; + } + @Override protected void onPause() { From 93d2e69773f1aefd9b6433091ac97af22fbaeee7 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 17 Jun 2012 04:41:00 +0200 Subject: [PATCH 09/33] (Android) Upload drawable-xhdpi --- android/res/drawable-xhdpi/ic_action_close.png | Bin 0 -> 729 bytes android/res/drawable-xhdpi/ic_action_history.png | Bin 0 -> 312 bytes android/res/drawable-xhdpi/ic_action_load.png | Bin 0 -> 725 bytes android/res/drawable-xhdpi/ic_action_open.png | Bin 0 -> 578 bytes android/res/drawable-xhdpi/ic_action_save.png | Bin 0 -> 614 bytes android/res/drawable-xhdpi/ic_action_settings.png | Bin 0 -> 608 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 android/res/drawable-xhdpi/ic_action_close.png create mode 100644 android/res/drawable-xhdpi/ic_action_history.png create mode 100644 android/res/drawable-xhdpi/ic_action_load.png create mode 100644 android/res/drawable-xhdpi/ic_action_open.png create mode 100644 android/res/drawable-xhdpi/ic_action_save.png create mode 100644 android/res/drawable-xhdpi/ic_action_settings.png 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 0000000000000000000000000000000000000000..1c74f6df01d05ee37092477c3dba8f4bdd254c40 GIT binary patch literal 729 zcmV;~0w(>5P)9r+DI2-4N@xzO8>z@kIKrc??wRBD33^rm;r(jk#pL(_$!J65Ce1tuC*8!N8rm!FL z>cT9*#SVhB>oU6Qzzlvsn3n#ILdnPUdkxcRJi^W9^-w;RR1FG^54#hMMz9S_OFWjy z|MEkLUI(gRR!9r*J8ViE|7zTg_)X!f_Js|3&{8#y?-HRF;AF(_n&Li%bv0m$P^q2j z!mkm(Z;K0lnE?>_PQ0;3r$Xa9+bZnFtH_VWpi(>46Y*J+VRNA9ru-fDA_7$>Q=vWX zhYW`T1^rEvb%{{XPT~82$Ilu5sJQtapBIdJg-1(5rmz^373;5NxKnX+ti)_>B2=(b z@-tMKMl(FFxOuz6Y}T2Q?>l9BUK^-sIIB$IdI%_aWF?)NQKsZa-7<|Phq?l)cBbSn z->MVAl?(?1X8j?cLZ^~5g&zZT$1-dR6#NqdYW_%arf@Y-)0bf(UIvPK6QNQv^)_&C zLhG{$#{-3j%&kYxR8bJas}>@JY(}TTtgeAk3f1Fm2=8B_8xTn#5kQF-5?>#H9|v3}e-dLE4}i z_y#A`+lj|mGz1+|R*u55hj47ht*t z;TUf}V7de044=PXRu94kE-_jH121^|Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyh` z0S!95t$tL_t(o!_AmYYZFlvhTk(LMbxOYw7L-2DhN{Wqjn?IintfimEgZ9 zs320;g4=GY*owLftu!WSD~i;wT?Kd2EJV?bwS{!?xS7ZplgyouWPD*ZckZ0?aL&2s z-npiT0tO_FNjfd*h@=CO3jXV#lGY@xN_r)!Y-T@{wg3ahfk(hE+_etO0A~S93+5zH zA-SFd$CH5Mfa^e=^i&5XfLv6V-M}2(QxPacfvM1al|rHXG|kgH6+5O6xIynV(GF$= z*vbH?4xDIkc#S?IX;M;7y;ok+WTQ`c{@^)DXA&4)mh>XQ_hbI^CtZ&dg!}=}=RdOv z?94V`27!$PFx#3|X6eo3WRR-c zX7;+>zLN(QdKjJg(7#x}i7oX2rW$OvE>PW!)H7$8ru5xPxzM+On~^UYTCBb_TEZeQ zlGYuO2V4N20-F&aHi0L=dDjaoivc$zY25KjuViN5qS*fpV%!oYo(e+x00000NkvXX Hu0mjfe&Im( literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..41233c5e00e8df7745ad10128d9e990638ae14d9 GIT binary patch literal 578 zcmV-I0=@l-P)jwCW{jQW9C}!X+R| zLM1;J(r^3g{!C(B{PN30TP|~hztKCGK7a{6d=>0f%_N=l{txOfg(xPa3VzJQy*no)H0>S z!_?1zCdnHNb`yGVgfcA_JIPE5e}T8~B~jaf84XM(Wd`J%+A}E+c0ETmRkX%!nT8c3H`=!B;Ew`Qlt>vio`o}9{yr1MQ9ucIWr$e;^RU$ zwlIT-c8lNw8DKZ~7=zN!(vWi%_)`L*U7Tu#yexsx zi}sK!B@mi!52=U`NugXz5t_@9vo3j&#ChRI*d1&nDr;&d*~huVi$^TA7#LOr3#l?q zp+WK0UAGwR(qC74BtKROIH;8SdcYL8DbN%H{f1a z$JyK>38@M$VOe}T=#^bO$F!n8Sf$7f<0h8GA13Pf-mE&_;t}Sx_ND;-0c-U}X-5cg QvH$=807*qoM6N<$f_2yT$^ZZW literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..dbc044c9d8097dbc098636cc3b6cd9fee512be0d GIT binary patch literal 614 zcmV-s0-61ZP)x*s&zNyMb3Jo7e=^;kz5lGWX6?NviYkIpT*rN^VG}=F&n8xJ57#hKb^fvv`)~=1 z*jAoxJi$fuH6=5Fw-qF^c#ZK+LbUwi$mI-wM`Rj!F!AkHL)IHH=RwnIjov2l26BtuK*quqxsK1~L{J z6YA@gHjzolJS?%!kFr9sRNF}9Q9dNq?| zJ{jf<9ZW>nt2#YTO(uop5Z0-=UqQ5 zW(&Uhmnrnk6=oa0`9FWqUo>V1ek5SxsG~(;cH>tSOer%MECMr;0u%34b5Pie-x)CR zP7URa*;6Mbe-wH|$2pG-=YeUYGv%4VFk0)u9FSjU%5x?Y3cXFllyWu|3VovET0~Bz z!8E%w@r+l)98+9pN*S$$>7N74Bdkcm42X_nk-3j$Nth1B?wJy1d8J!5P%!2WmR8%y zSMeR)_|jy|-Kv-XdVz=Gbr(K233D5ZYGKxhPS!~5y)Jxg0%l27Ojvwpm~gP{{f+pL z6Xu3morx`cB24N`xV9k&)XmhGu;?g$VsVA*9e7_S<{B2H#)Ji*<8h5K9e7s Date: Sun, 17 Jun 2012 05:53:59 +0200 Subject: [PATCH 10/33] (Android) Most Action Bar actions now part of popup menu --- .../classes/com/retroarch/MainActivity.class | Bin 1937 -> 2082 bytes .../classes/com/retroarch/R$drawable.class | Bin 628 -> 666 bytes .../bin/classes/com/retroarch/R$layout.class | Bin 379 -> 379 bytes .../bin/classes/com/retroarch/R$string.class | Bin 412 -> 412 bytes android/gen/com/retroarch/R.java | 14 ++++++++------ android/res/drawable-hdpi/ic_action_quit.png | Bin 0 -> 797 bytes android/res/drawable-hdpi/ic_launcher.png | Bin 2525 -> 2520 bytes android/res/drawable-ldpi/ic_action_quit.png | Bin 0 -> 411 bytes android/res/drawable-mdpi/ic_action_quit.png | Bin 0 -> 536 bytes android/res/drawable-mdpi/ic_launcher.png | Bin 1642 -> 1629 bytes android/res/drawable-xhdpi/ic_action_quit.png | Bin 0 -> 797 bytes android/res/drawable-xhdpi/ic_launcher.png | Bin 2971 -> 2941 bytes android/res/menu/main_menu.xml | 11 ++++++----- android/src/com/retroarch/MainActivity.java | 13 ++++++++++--- 14 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 android/res/drawable-hdpi/ic_action_quit.png create mode 100644 android/res/drawable-ldpi/ic_action_quit.png create mode 100644 android/res/drawable-mdpi/ic_action_quit.png create mode 100644 android/res/drawable-xhdpi/ic_action_quit.png diff --git a/android/bin/classes/com/retroarch/MainActivity.class b/android/bin/classes/com/retroarch/MainActivity.class index 33f0134ca22eb8783c6bbb47ac0f7ddeaaac0069..d5fba4e8682cc5870ac66c2e42c06a61007c2000 100644 GIT binary patch delta 629 zcmZ9HOHUI~6vuzJ^D6Ca!A4$235i78VrYB=710(SqdY~cAc~b4%D~WSTQIKJx;1y< z-kpXGiK#^sKLDS^_#up$A}(B<#rZ$adEfrABXaQj+YjJ8)xF5i&`y-gT(!6&=q#3< zYQ=Lh+n)O-Gv$`I?7F)t8D>P#R&wjXYC8fgnX)5f8MC-1NF3QJwajd_vf|cilIwxT z*nB(dIf3$qmbi?!gzaoL2v{MTOiwQyZdU3m$@r&hBX1-qa%B9?v=R0mS%xyv2 z(JlQE^4yhJ*n-aFEQ^@>WX#2mW6;Ghy6L4yS>{aJNeoUQ=~K(*#hrKPgn)^`eJ%+;1Dx0~ zF@pgTO-7rH>$~aiD^(}@QS9yWNaHF?^gsP6(HB+!KcoTi5}^l_Gc zQshVzYjLeU;M{e|8Jo?5cbX*zxYj%^--mA!u*aWr5Uoe`pp Rwz4GxkcZg_UbWP({{W#cd=>xz delta 480 zcmX}k%}x_h7>DuabWUfc!=VUTDp(TIbfJYfQLBLU`x6wb1w;#I9hpf}Q>Fn|&*!heDT00HXTr2NE6C~znVqwl z5u}!aaCadJwkI7*%qc9+3o^$SpL;Jnx8;QmcO}|shK=%xwE-@0$>O5^l^8cJb44E* zMZ3f`#dU7z-$wc9ErB!H30lEc6!<5*;(T{p&=q;wE^$|}$dY~~3;7CFi~E8jUg+<% zo4)(9={JJNU2S`vNU_X{{w~+e3J(-(+D*<5ZzyWm4v*Qecp}K{RdeG4yB#hEo!#xg z!N610`#+w3m#hn=(`I$>FiA2DGs+lQ-7+hwVW_peB@rts(cG1P=M2G^5iKn2#od((hSkP0uOnFKvL5`tjx@M@jYWP ooBRKTGzL&aGQ|MXJw+h^^-q!1yRH4S-#*i?t?86tt4H{M0m_P5MgRZ+ diff --git a/android/bin/classes/com/retroarch/R$drawable.class b/android/bin/classes/com/retroarch/R$drawable.class index 9cf4ba1bc2596a99ae576dabc483467b7e445ccb..62036ee00abf0bbf776024be96dcb922fbf8a8ab 100644 GIT binary patch delta 226 zcmYj|O-jR17)8%l^CK}86sjh+T5Zk1NpTf+XP2AR(YD`TD??ho4po>y29x{T4=4R zr`9ZqhRRQ~$_nCWzq(7r-;7ga5SU evIQJ^Kwx2)Dmx(} diff --git a/android/bin/classes/com/retroarch/R$layout.class b/android/bin/classes/com/retroarch/R$layout.class index 9feb438dea38a7c86453e42305bae200b199e627..78c6034104e9cef605aab513ca6850c8c46bcdbf 100644 GIT binary patch delta 13 Ucmey(^qXmeA0wl}WPe5-03>w;DgXcg delta 13 Ucmey(^qXmeA0wmOWPe5-03>S!C;$Ke diff --git a/android/bin/classes/com/retroarch/R$string.class b/android/bin/classes/com/retroarch/R$string.class index 9838af76c9e6f00ed3cacc1b992a0d11fe980dde..e0ffa75cf22584f18adb20b71e069789d6250a5b 100644 GIT binary patch delta 13 UcmbQkJcoHhJ|m;rPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyh` z10pp&ijVXF00Ny!L_t(o!_8Q~YZOrs{=S!kC>;JkjYTSBr(y^g!NNkD6lty%1uX(L zK|}=o11tmuNg-GXHb%6OU=S4q1%H&rV4*22Y&^)xorxrPx%n)d#m9l>Zf~>ez~k+E z>IHaNl8s*CqE@!N#!9k+fMQu00E#R zkWBkwiEd)6976cfseTCnNS=-Wej)k3J)B*LNjgk&mm~nV3E)h(Uo|7iB-OGYrlg%w z=&If52A>DrBlDS@6mk(j)xnh_phKMkD!D>4!xP+aa0!^>0A5JC)QOAd+`Z4TLL=#u z+pPKeV-iC%8(7andC21gD}c8}0P2hB0N`?x3P|oTvs-xsngMVRzys&fs-%4m3M9`; z8p(}Ae@#+m*Ue03W|C@>`U?f*pcbP%^{6OP$FkoGFaV63S*1`wA%v==i6lTIrzH)< zCm^d(Oaa*3K_-VJ1F+)nZvrq2V6>DWm`Rf7x+pL0TZbf#X9kGmV3KFjwk-hmX33%3 zk_e#L$?&?Vh({oKKT8iScuv{T+3Va5;5C4L_v!@6uZ83x=iIwLwbmY@tXjs(cayJG-g&e zv%Wmrj}@Pnox~#mPWTZgfTJOVR*@a!c~5?nbRmQ=UuX+U^0{+oA%t+_pBKdqlC?HK zcg(Er$#7i)zH$Q2Wk~9VUq0*I=p`On0B{7rK}nMUKKD>0MRFLx7GJNXN#m91&Ll~# zUPjV0`+POk{~<|B0LmHj=sU@+Y3}v_aKH)I1YkXmmh-XF>mRf-$!*@(^u%cZOCf|t bw~D_2x%qgDWIp0I00000NkvXXu0mjf4%%0Q literal 0 HcmV?d00001 diff --git a/android/res/drawable-hdpi/ic_launcher.png b/android/res/drawable-hdpi/ic_launcher.png index 16db30ee1035a096af0fffb9f0e2219585b38de8..ea7613b8c41d6f58090fa5218c720d4fe44ddce9 100644 GIT binary patch delta 2450 zcmV;D32pY>6W9}wV1E$^OZ0u&S@yD(=`!Ta~`h#7w*fTb3dw+<7=15Prc4pqa@4Wl& zyZ62aIB?*=fddB)95`^`z<~n?OAKP69i&nzpUdUi51sxNk_7i}rhPMtbMk~?jZ zy`rb5XV6Oa@#Duy^4W#Tkrw#9XJBB!ZS`cqXlTf=df3s?!OXJ1p#**8 z@p$^I9+sAt0)TFp0S5vBT0LB~YLx)cvQQz)9A^BzjDG{nVnhhhocl^iNr~kw4h{|i zz+C|TVgo_$k&%(m9Fucx+Ia2&@Eri@tbqt2{*X68(P&h7Jf4Fc9UZ^Ec<~~H5Kt5a ze!m}MV`C?ai;K4iAzA^5Kph4(&;qP=`=#25XQ#F zb`=*FZxlid=cCMzGHckF=KPFx>(-HE56Pm;yZ?Odx#t)Pg^aSYvaH#Erg^P<$wB&3|W>L30q*}IYnP_Ne zxC~&O5F&266MX_$JTvWg&Rwjapujw`6auBCr7-}BS;q74Kp>De@v}jeWnnfDMNyzA zO0N|;0O0j{2bL{cW~t9?1X)^;s;Z{Hmw%U+1Hga~B9dbrN*CtiR3b<^+L z+uPMGTedt#vMV2gUVH7e^{G^9#_yAplj!T~t0j2|z{i>FAUC-&cI_I?QkllaM(Le*-r2EoimIxreX=YgnM`8awr$XLy-rb-yR!4G zD2nBHBuNtaI_cF{u3Ry7YO7bTCdsy(cTZPWR~uFi{YErZRgLlSapvf_uD-tB^xcOZ zdWeQ${46gYB!uWGDJg-OV>9thx_`^%vMnK<4^&kZ7M4E)D^{$45Tb2fsfL+D_4$0r zu%8?9FR2=i$K#nkx#>AvhBU8K!wh|WeE?8Naw~v1fEAgfbjctRi9iSel0O8X0=Vz$ z)vJr2i!2xzyl8~$oZC+mveY{n8{?4$z+nfy}c|fEL>2ZPe1)MNe1mIcUU422w=m84Nz4T zilV^h^WpZ}Z(mTK)z#HlzJGi%cZNA6`lq9G6H48Eqb)xO+czAdi=g*(Vnl)=c5{6;m{Q2_>>hs-q-^Ha% zmynH$Q>hf*e*5j4lOSE!QCC+tm4)lNj%YNxpgzOlFluUQrj}JAk$*7V#cm3MvLua< zk1uMU@pv5Zc>D{CsiZk_GJM%F*BGVG<7mIk&~<%&1PLJ^g!s~%&|G1Hn1$KPjg5`p zcMob#8^J- zQe^)AHdBy4Me?s*U4LB(kH@oQ>OT3lJ$v?~NxqpgroWL~wP-WY-`{_(q@?7gC8(vP zWs>9?+ahUA(~>vy&X!0djA^y3#U&_}O3mr@mog?MChQFqZ@cZb)SY+UiL+aI1_1mq91eTkZZ|w0kE^w{b=|%9-fMbBbm-6_?Ay2R zKLDBlq!u$52JrneXU=S{t*tekjb za&#TeoB-Rp3v_SazMX!*pXKG{^!xp@9^PHPe3>LS+J8h)aXOvu4TVCp9$J=`meT9> zva+($c>n$PNpgc-)>GNq+G={o2AP{?$BrH2E3dr5rluyo_uhNdb^Wl-7X9N7Km3qQ zO-*cWZf0|HGb<}AEy>!raU)3{uuGYz8XFreg}?B^3nY1xFn% zGBN_&o#5P-R2qxLgcUg?^Dgq|L(u;+H%HB48)ohkg>P^+p-7S>Tjg6mpAUtFh2yqK zk4B>(Z`!nJ#^uSnx;n<=@i8m`kbLv`=bvXmL4ScUeG}>I>`asViJhs&3IIm{ROjS0 z3V?qBcuEK{utZ2|0Pq6!bnEPlR}7|#Uw}u;0B-pC;*TIkPHTcQ}t>|l8VCN zumK>7B?Q0Uzg(8(asWO6y%Q4?A19N^1ROYU;J|?c2M!!KaNxkflE?o6=|0fBWn!xH Q01E&B07*qoM6N<$f-@b##{d8T delta 2455 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 Vybx^#2jBnz002ovPDHLkV1n#&yTSkf 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 0000000000000000000000000000000000000000..203696e713f8fa6783a388110638789d02fbf673 GIT binary patch literal 411 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 bw~D_2x%qgDWIp0I00000NkvXXu0mjf9EVru literal 0 HcmV?d00001 diff --git a/android/res/drawable-xhdpi/ic_launcher.png b/android/res/drawable-xhdpi/ic_launcher.png index 97e0bd975604eade68961b03bc3b0c2ebd28a7bf..a113106a99940f98c368dd477e702d7527565924 100644 GIT binary patch delta 2874 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 Y15q^~Q&Eg*-~a#s07*qoM6N<$f)?zOK>z>% delta 2904 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 - - - - - + + + + + + diff --git a/android/src/com/retroarch/MainActivity.java b/android/src/com/retroarch/MainActivity.java index 2a1f77b482..957f352602 100644 --- a/android/src/com/retroarch/MainActivity.java +++ b/android/src/com/retroarch/MainActivity.java @@ -1,5 +1,6 @@ package com.retroarch; +import android.app.ActionBar; import android.app.Activity; import android.content.Context; import android.view.Menu; @@ -31,9 +32,15 @@ public class MainActivity extends Activity public boolean onOptionsItemSelected(MenuItem item) { - Toast.makeText(this, "MenuItem " + item.getTitle() + " selected.", Toast.LENGTH_SHORT).show(); - - return true; + 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 From e71115151b65262e86d392ed9fba2064b043980d Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 17 Jun 2012 13:11:12 +0200 Subject: [PATCH 11/33] Add libpng screenshot support. --- Makefile | 5 ++ config.features.h | 6 ++ qb/config.libs.sh | 5 +- qb/config.params.sh | 1 + retroarch.c | 1 + screenshot.c | 145 +++++++++++++++++++++++++++++++++++++------- 6 files changed, 140 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index b14ee92025..1510406c89 100644 --- a/Makefile +++ b/Makefile @@ -157,6 +157,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/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/qb/config.libs.sh b/qb/config.libs.sh index b5cefda93b..8c352df57e 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -81,6 +81,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 @@ -128,6 +129,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" +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" 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 80346d3dcd..2062d2803c 100644 --- a/retroarch.c +++ b/retroarch.c @@ -495,6 +495,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"); 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; } From e455e52e063f64e0bc935b44f2d311c9363e1ed5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 18 Jun 2012 00:34:47 +0200 Subject: [PATCH 12/33] MAJOR refactor of dir_list_new. --- console/salamander/main.c | 4 +- driver.c | 34 +++-- file_path.c | 286 +++++++++++++++++++++++++------------- 3 files changed, 209 insertions(+), 115 deletions(-) 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 e65fd93fe4..e0435a1bd0 100644 --- a/driver.c +++ b/driver.c @@ -417,6 +417,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 +429,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,9 +480,10 @@ 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; + 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]) @@ -495,8 +499,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 diff --git a/file_path.c b/file_path.c index 009c56106c..deea3b2411 100644 --- a/file_path.c +++ b/file_path.c @@ -43,141 +43,231 @@ #endif // Yep, this is C alright ;) +struct string_list +{ + char **data; + size_t size; + size_t cap; +}; + +static bool string_list_capacity(struct string_list *list, size_t cap) +{ + rarch_assert(cap > list->size); + + char **new_data = (char**)realloc(list->data, cap * sizeof(char*)); + if (!new_data) + return false; + + 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; + struct string_list list; + + if (!string_list_init(&list)) + goto error; + + copy = strdup(str); + if (!copy) + return NULL; + + const char *tmp = strtok(copy, delim); + while (tmp) + { + if (!string_list_append(&list, tmp)) + goto error; + + tmp = strtok(NULL, delim); + } + + free(copy); + return string_list_finalize(&list); + +error: + string_list_cleanup(&list); + free(copy); + return NULL; +} + +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 ""; +} + +#ifdef _WIN32 // Because the API is just fucked up ... char **dir_list_new(const char *dir, const char *ext, bool include_dirs) { - size_t cur_ptr = 0; - size_t cur_size = 32; - char **dir_list = NULL; + struct string_list list; + if (!string_list_init(&list)) + return NULL; -#ifdef _WIN32 - WIN32_FIND_DATA ffd; HANDLE hFind = INVALID_HANDLE_VALUE; + WIN32_FIND_DATA ffd; char path_buf[PATH_MAX]; + snprintf(path_buf, sizeof(path_buf), "%s\\*", dir); - 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 - goto error; - + char **ext_list = NULL; if (ext) - { - if (strlcat(path_buf, ext, sizeof(path_buf)) >= sizeof(path_buf)) - goto error; - } + 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); + + if (!include_dirs && path_is_directory(name)) + continue; + + if (!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; -#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 + const char *name = entry->d_name; + const char *file_ext = path_get_extension(name); - dir_list[cur_ptr] = (char*)malloc(PATH_MAX); - if (!dir_list[cur_ptr]) + if (!include_dirs && path_is_directory(name)) + continue; + + if (!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; - - 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*)); - } } -#if defined(_WIN32) - while (FindNextFile(hFind, &ffd) != 0); -#endif -#ifdef _WIN32 - FindClose(hFind); -#else closedir(directory); -#endif - return dir_list; + + string_list_free(ext_list); + 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); + string_list_free(ext_list); return NULL; } +#endif void dir_list_free(char **dir_list) { - if (!dir_list) - return; - - char **orig = dir_list; - while (*dir_list) - free(*dir_list++); - free(orig); + string_list_free(dir_list); } bool path_is_directory(const char *path) From a1f5715431036b1ed4902fbbd617a49780582d14 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 18 Jun 2012 01:11:03 +0200 Subject: [PATCH 13/33] Add sorting and size query to dir_list_new. --- driver.c | 14 +++++--------- file.h | 2 ++ file_path.c | 34 ++++++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/driver.c b/driver.c index e0435a1bd0..5ca1a4184c 100644 --- a/driver.c +++ b/driver.c @@ -481,17 +481,13 @@ static void init_shader_dir(void) 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.size = dir_list_size(g_extern.shader_dir.elems); 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++; - } - } + dir_list_sort(g_extern.shader_dir.elems); + + 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) diff --git a/file.h b/file.h index 2ad5972181..acee1679a9 100644 --- a/file.h +++ b/file.h @@ -44,6 +44,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); 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 deea3b2411..a2faa5e12d 100644 --- a/file_path.c +++ b/file_path.c @@ -110,7 +110,8 @@ static void string_list_free(char **list) static char **string_split(const char *str, const char *delim) { - char *copy = NULL; + char *copy = NULL; + const char *tmp = NULL; struct string_list list; if (!string_list_init(&list)) @@ -120,7 +121,7 @@ static char **string_split(const char *str, const char *delim) if (!copy) return NULL; - const char *tmp = strtok(copy, delim); + tmp = strtok(copy, delim); while (tmp) { if (!string_list_append(&list, tmp)) @@ -159,6 +160,31 @@ static const char *path_get_extension(const char *path) 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(const void *a, const void *b) +{ + return strcmp(*(char * const*)a, *(char * const*)b); +} + +void dir_list_sort(char **dir_list) +{ + if (!dir_list) + return; + + qsort(dir_list, dir_list_size(dir_list), sizeof(char*), qstrcmp); +} + #ifdef _WIN32 // Because the API is just fucked up ... char **dir_list_new(const char *dir, const char *ext, bool include_dirs) { @@ -188,7 +214,7 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) if (!include_dirs && path_is_directory(name)) continue; - if (!string_list_find_elem(ext_list, file_ext)) + if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext)) continue; char file_path[PATH_MAX]; @@ -238,7 +264,7 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) if (!include_dirs && path_is_directory(name)) continue; - if (!string_list_find_elem(ext_list, file_ext)) + if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext)) continue; char file_path[PATH_MAX]; From 49535b3a54961692718b0d5c04864fc958a4e6ba Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 02:07:19 +0200 Subject: [PATCH 14/33] (PS3) Refactor of filebrowser --- console/fileio/file_browser.c | 33 +++++++++++---------- console/fileio/file_browser.h | 46 ++++++++++++++-------------- ps3/menu.c | 56 +++++++++++++++++------------------ 3 files changed, 70 insertions(+), 65 deletions(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index b5fc50b23f..f36c9cc383 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -47,9 +47,9 @@ 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)); + filebrowser->current_dir.files[i].d_type = 0; + filebrowser->current_dir.files[i].d_namlen = 0; + strlcpy(filebrowser->current_dir.files[i].d_name, "\0", sizeof(filebrowser->current_dir.files[i].d_name)); } } @@ -58,7 +58,7 @@ const char * path, const char * extensions) { int error = 0; #if defined(_XBOX) - filebrowser->file_count = 0; + filebrowser->current_dir.size = 0; WIN32_FIND_DATA ffd; HANDLE hFind = INVALID_HANDLE_VALUE; @@ -115,11 +115,12 @@ const char * path, const char * extensions) 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->current_dir.files[filebrowser->current_dir.ptr].d_type = found_dir ? FS_TYPES_DIRECTORY : FS_TYPES_FILE; + snprintf(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name, sizeof(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name), ffd.cFileName); - filebrowser->file_count++; - }while (FindNextFile(hFind, &ffd) != 0 && (filebrowser->file_count + 1) < MAX_FILE_LIMIT); + filebrowser->current_dir.ptr++; + filebrowser->current_dir.size++; + }while (FindNextFile(hFind, &ffd) != 0 && (filebrowser->current_dir.ptr + 1) < MAX_FILE_LIMIT); #elif defined(__CELLOS_LV2__) int fd; @@ -139,8 +140,8 @@ const char * path, const char * extensions) strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size])); - filebrowser->file_count = 0; - filebrowser->currently_selected = 0; + filebrowser->current_dir.size = 0; + filebrowser->current_dir.ptr = 0; CellFsDirent dirent; @@ -180,11 +181,12 @@ const char * path, const char * extensions) 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->current_dir.files[filebrowser->current_dir.ptr].d_type = dirent.d_type; + filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_namlen = dirent.d_namlen; + strlcpy(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name, dirent.d_name, sizeof(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name)); - ++filebrowser->file_count; + ++filebrowser->current_dir.ptr; + ++filebrowser->current_dir.size; } cellFsClosedir(fd); @@ -195,7 +197,8 @@ const char * path, const char * extensions) goto error; } #endif - qsort(filebrowser->cur, filebrowser->file_count, sizeof(DirectoryEntry), less_than_key); + qsort(filebrowser->current_dir.files, filebrowser->current_dir.size, sizeof(DirectoryEntry), less_than_key); + filebrowser->current_dir.ptr = 0; error: if(error) { diff --git a/console/fileio/file_browser.h b/console/fileio/file_browser.h index 6fb77f70e1..a091d312f0 100644 --- a/console/fileio/file_browser.h +++ b/console/fileio/file_browser.h @@ -52,11 +52,13 @@ 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; - char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; /* info of the current directory*/ - DirectoryEntry cur[MAX_FILE_LIMIT]; /* current file listing*/ + char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; + struct { + DirectoryEntry files[MAX_FILE_LIMIT]; + size_t size; + size_t ptr; + } current_dir; char extensions[FS_MAX_PATH]; /* allowed extensions*/ } filebrowser_t; @@ -66,40 +68,40 @@ void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, 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.files[filebrowser.current_dir.ptr].d_name) +#define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.current_dir.ptr) +#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_type == CELL_FS_TYPE_REGULAR) +#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_type == CELL_FS_TYPE_DIRECTORY) #endif /* FILEBROWSER_H_ */ diff --git a/ps3/menu.c b/ps3/menu.c index 27b513d51f..70b7a6a940 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; @@ -345,7 +345,7 @@ static void browser_render(filebrowser_t * b) for ( i = page_base; i < file_count && i < page_base + NUM_ENTRY_PER_PAGE; ++i) { 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 : b->current_dir.files[i].d_type == CELL_FS_TYPE_DIRECTORY ? GREEN : WHITE, b->current_dir.files[i].d_name); gl_render_msg_post(gl); } gl_render_msg_post(gl); @@ -889,7 +889,7 @@ 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 { @@ -1035,7 +1035,7 @@ 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 { @@ -1922,7 +1922,7 @@ 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); } From 0b84f1744ef18c142f491964ace85e6addcab3f1 Mon Sep 17 00:00:00 2001 From: TwinAphex51224 Date: Mon, 18 Jun 2012 02:27:54 +0200 Subject: [PATCH 15/33] (360) Updated for filebrowser changes --- 360/menu.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/360/menu.cpp b/360/menu.cpp index 657b344653..860b0ad061 100644 --- a/360/menu.cpp +++ b/360/menu.cpp @@ -70,10 +70,10 @@ 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)); + rarch_convert_char_to_wchar(strw_buffer, browser->current_dir.files[i].d_name, sizeof(strw_buffer)); romlist->SetText(i, strw_buffer); } } @@ -524,7 +524,7 @@ 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(browser.current_dir.files[index].d_type != FILE_ATTRIBUTE_DIRECTORY) { struct retro_system_info info; retro_get_system_info(&info); @@ -545,7 +545,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(browser.current_dir.files[index].d_type == FILE_ATTRIBUTE_DIRECTORY) { const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index)); @@ -578,7 +578,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(tmp_browser.current_dir.files[index].d_type != FILE_ATTRIBUTE_DIRECTORY) { const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_shaderlist.GetText(index)); @@ -599,7 +599,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(tmp_browser.current_dir.files[index].d_type == FILE_ATTRIBUTE_DIRECTORY) { 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 +619,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(tmp_browser.current_dir.files[index].d_type != FILE_ATTRIBUTE_DIRECTORY) { 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(tmp_browser.current_dir.files[index].d_type == FILE_ATTRIBUTE_DIRECTORY) { 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); From 805ca7e027b308fdf934905cec07fd2f4d9e13bb Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 05:31:43 +0200 Subject: [PATCH 16/33] (PS3) More refactoring of filebrowser - should be mostly platform- agnostic now --- console/fileio/file_browser.c | 206 ++++------------------------------ console/fileio/file_browser.h | 30 ++--- file_path.c | 2 + ps3/menu.c | 29 +++-- 4 files changed, 43 insertions(+), 224 deletions(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index f36c9cc383..7010f43b35 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -19,204 +19,35 @@ #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->current_dir.files[i].d_type = 0; - filebrowser->current_dir.files[i].d_namlen = 0; - strlcpy(filebrowser->current_dir.files[i].d_name, "\0", sizeof(filebrowser->current_dir.files[i].d_name)); - } -} static void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path, const char * extensions) { - int error = 0; -#if defined(_XBOX) - filebrowser->current_dir.size = 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->current_dir.files[filebrowser->current_dir.ptr].d_type = found_dir ? FS_TYPES_DIRECTORY : FS_TYPES_FILE; - snprintf(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name, sizeof(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name), ffd.cFileName); - - filebrowser->current_dir.ptr++; - filebrowser->current_dir.size++; - }while (FindNextFile(hFind, &ffd) != 0 && (filebrowser->current_dir.ptr + 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->current_dir.size = 0; - filebrowser->current_dir.ptr = 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->current_dir.files[filebrowser->current_dir.ptr].d_type = dirent.d_type; - filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_namlen = dirent.d_namlen; - strlcpy(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name, dirent.d_name, sizeof(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name)); - - ++filebrowser->current_dir.ptr; - ++filebrowser->current_dir.size; - } - - cellFsClosedir(fd); - } - else - { - error = 1; - goto error; - } -#endif - qsort(filebrowser->current_dir.files, filebrowser->current_dir.size, sizeof(DirectoryEntry), less_than_key); - filebrowser->current_dir.ptr = 0; - error: - if(error) - { - RARCH_ERR("Failed to open directory: \"%s\"\n", path); - } -#ifdef _XBOX - FindClose(hFind); -#endif + dir_list_sort(filebrowser->current_dir.elems); } 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_free(filebrowser_t * filebrowser) +{ + dir_list_free(filebrowser->current_dir.elems); + + filebrowser->current_dir.elems = NULL; + filebrowser->current_dir.size = 0; + filebrowser->current_dir.ptr = 0; } @@ -226,7 +57,7 @@ const char * extensions) 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_push_directory(filebrowser_t * filebrowser, const char * path, @@ -247,3 +78,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 a091d312f0..96e8f3e97f 100644 --- a/console/fileio/file_browser.h +++ b/console/fileio/file_browser.h @@ -25,44 +25,28 @@ #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 directory_stack_size; char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; struct { - DirectoryEntry files[MAX_FILE_LIMIT]; + char **elems; size_t size; size_t ptr; } current_dir; - char extensions[FS_MAX_PATH]; /* allowed extensions*/ + char extensions[FS_MAX_PATH]; } 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_free(filebrowser_t *filebrowser); void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir, const char * extensions); void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension); void filebrowser_pop_directory (filebrowser_t * filebrowser); @@ -99,9 +83,9 @@ void filebrowser_pop_directory (filebrowser_t * filebrowser); filebrowser->current_dir.ptr = filebrowser->current_dir.size - 1; \ } -#define FILEBROWSER_GET_CURRENT_FILENAME(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_name) +#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) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_type == CELL_FS_TYPE_REGULAR) -#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_type == CELL_FS_TYPE_DIRECTORY) +#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/file_path.c b/file_path.c index a2faa5e12d..8b840c5239 100644 --- a/file_path.c +++ b/file_path.c @@ -264,8 +264,10 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) if (!include_dirs && path_is_directory(name)) continue; +#ifndef __CELLOS_LV2__ if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext)) continue; +#endif char file_path[PATH_MAX]; snprintf(file_path, sizeof(file_path), "%s/%s", dir, name); diff --git a/ps3/menu.c b/ps3/menu.c index 70b7a6a940..b239f81c88 100644 --- a/ps3/menu.c +++ b/ps3/menu.c @@ -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->current_dir.files[i].d_type == CELL_FS_TYPE_DIRECTORY ? GREEN : WHITE, b->current_dir.files[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; @@ -893,15 +894,13 @@ static void select_file(uint32_t menu_id) 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; @@ -987,7 +986,7 @@ static void select_directory(uint32_t menu_id) { 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: @@ -1039,8 +1038,7 @@ static void select_directory(uint32_t menu_id) 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; @@ -1928,8 +1926,7 @@ static void select_rom(void) } 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); } } From 21a344e61bd51eb2a599fb13d10674d86ac78213 Mon Sep 17 00:00:00 2001 From: TwinAphex51224 Date: Mon, 18 Jun 2012 06:12:37 +0200 Subject: [PATCH 17/33] (360) Works now too with refactored filebrowser code --- 360/menu.cpp | 19 ++++++++++--------- file_path.c | 2 ++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/360/menu.cpp b/360/menu.cpp index 860b0ad061..0aa0bbee01 100644 --- a/360/menu.cpp +++ b/360/menu.cpp @@ -73,7 +73,9 @@ static void filebrowser_fetch_directory_entries(const char *path, filebrowser_t 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->current_dir.files[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.current_dir.files[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.current_dir.files[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.current_dir.files[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.current_dir.files[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.current_dir.files[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.current_dir.files[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); diff --git a/file_path.c b/file_path.c index 8b840c5239..9da20bd3e0 100644 --- a/file_path.c +++ b/file_path.c @@ -214,8 +214,10 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) if (!include_dirs && path_is_directory(name)) continue; +#ifndef _XBOX if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext)) continue; +#endif char file_path[PATH_MAX]; snprintf(file_path, sizeof(file_path), "%s\\%s", dir, name); From 54273d94b1b1d98488ce6d7b431e07797d9ea758 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 06:06:49 +0200 Subject: [PATCH 18/33] (PS3) Deallocate filebrowser code at shutdown --- ps3/main.c | 2 +- ps3/menu.c | 6 ++++++ ps3/menu.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ps3/main.c b/ps3/main.c index dc7b0b0c17..9fc59bc64d 100644 --- a/ps3/main.c +++ b/ps3/main.c @@ -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 b239f81c88..327bb47741 100644 --- a/ps3/menu.c +++ b/ps3/menu.c @@ -2459,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_ */ From e760807d4768cdbed0e4d934609e47d5a3d11328 Mon Sep 17 00:00:00 2001 From: TwinAphex51224 Date: Mon, 18 Jun 2012 06:22:26 +0200 Subject: [PATCH 19/33] (360) Add filebrowser free to menu_deinit (now renamed menu_free) --- 360/main.c | 2 +- 360/menu.cpp | 4 +++- 360/menu.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) 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 0aa0bbee01..312b7ec123 100644 --- a/360/menu.cpp +++ b/360/menu.cpp @@ -839,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; From 214f8563c4c4b9ebb041ead7c3948a47c4f57677 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 18 Jun 2012 10:02:00 +0200 Subject: [PATCH 20/33] Fix bug when ext is NULL in dir_list_new. --- file_path.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/file_path.c b/file_path.c index 9da20bd3e0..8180d32d38 100644 --- a/file_path.c +++ b/file_path.c @@ -215,7 +215,7 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) continue; #ifndef _XBOX - if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext)) + if (!path_is_directory(name) && ext_list && !string_list_find_elem(ext_list, file_ext)) continue; #endif @@ -267,7 +267,7 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) continue; #ifndef __CELLOS_LV2__ - if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext)) + if (!path_is_directory(name) && ext_list && !string_list_find_elem(ext_list, file_ext)) continue; #endif From 84cf67525a335865193c44c51906ad6dc8fabf80 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 18 Jun 2012 20:37:35 +0200 Subject: [PATCH 21/33] Use strcasecmp() for sorting. --- file_path.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/file_path.c b/file_path.c index 8180d32d38..f71e438696 100644 --- a/file_path.c +++ b/file_path.c @@ -20,6 +20,7 @@ #include #include #include "compat/strl.h" +#include "compat/posix_string.h" #ifdef __CELLOS_LV2__ #include @@ -174,7 +175,7 @@ size_t dir_list_size(char * const *dir_list) static int qstrcmp(const void *a, const void *b) { - return strcmp(*(char * const*)a, *(char * const*)b); + return strcasecmp(*(char * const*)a, *(char * const*)b); } void dir_list_sort(char **dir_list) From f335ee2dab338e4dc22e10be18e8ef038143252b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 20:37:17 +0200 Subject: [PATCH 22/33] (Filebrowser) Remove duplicate code --- console/fileio/file_browser.c | 10 ---------- console/fileio/file_browser.h | 1 - ps3/menu.c | 6 +++--- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index 7010f43b35..9d299882b2 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -50,16 +50,6 @@ void filebrowser_free(filebrowser_t * filebrowser) filebrowser->current_dir.ptr = 0; } - -void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir, -const char * extensions) -{ - filebrowser->directory_stack_size = 0; - strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions)); - - filebrowser_parse_directory(filebrowser, start_dir, extensions); -} - void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension) { diff --git a/console/fileio/file_browser.h b/console/fileio/file_browser.h index 96e8f3e97f..ab3a4b943d 100644 --- a/console/fileio/file_browser.h +++ b/console/fileio/file_browser.h @@ -47,7 +47,6 @@ typedef struct void filebrowser_new(filebrowser_t *filebrowser, const char * start_dir, const char * extensions); void filebrowser_free(filebrowser_t *filebrowser); -void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir, const char * extensions); void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension); void filebrowser_pop_directory (filebrowser_t * filebrowser); diff --git a/ps3/menu.c b/ps3/menu.c index 327bb47741..03ce0c48ad 100644 --- a/ps3/menu.c +++ b/ps3/menu.c @@ -882,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)) { @@ -980,7 +980,7 @@ 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)) { @@ -1912,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)) { From 72985dd4d69311ed57aa0a9f93d2f8c304cb01d9 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 20:44:21 +0200 Subject: [PATCH 23/33] (Filebrowser) Get rid of platform-specific ifdefs --- console/fileio/file_browser.h | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/console/fileio/file_browser.h b/console/fileio/file_browser.h index ab3a4b943d..6759876403 100644 --- a/console/fileio/file_browser.h +++ b/console/fileio/file_browser.h @@ -17,32 +17,21 @@ #ifndef FILEBROWSER_H_ #define FILEBROWSER_H_ -#define MAXJOLIET 255 #define MAX_DIR_STACK 25 #include #include -#ifdef __CELLOS_LV2__ -#include -#include -#define FS_MAX_PATH 256 -#define FS_MAX_FS_PATH_LENGTH 255 -#elif defined(_XBOX) -#define FS_MAX_PATH MAX_PATH -#define FS_MAX_FS_PATH_LENGTH 2048 -#endif - typedef struct { uint32_t directory_stack_size; - char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH]; + char dir[MAX_DIR_STACK][512]; struct { char **elems; size_t size; size_t ptr; } current_dir; - char extensions[FS_MAX_PATH]; + char extensions[PATH_MAX]; } filebrowser_t; void filebrowser_new(filebrowser_t *filebrowser, const char * start_dir, const char * extensions); From d3006569907d6871dc3b339be84b7eff9b881b12 Mon Sep 17 00:00:00 2001 From: TwinAphex51224 Date: Mon, 18 Jun 2012 21:06:01 +0200 Subject: [PATCH 24/33] (Filebrowser) nit --- console/fileio/file_browser.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index 9d299882b2..303143a235 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -14,12 +14,8 @@ * If not, see . */ -#ifdef _XBOX -#include -#endif #include "file_browser.h" - static void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path, const char * extensions) { From f81c9c31666c1bc751ee41bc2ae88709dbe266d9 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 22:59:33 +0200 Subject: [PATCH 25/33] (PS3) use stat for PS3 - get rid of cellFsStat --- file_path.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/file_path.c b/file_path.c index f71e438696..7a88119db3 100644 --- a/file_path.c +++ b/file_path.c @@ -24,6 +24,8 @@ #ifdef __CELLOS_LV2__ #include + +#define S_ISDIR(x) (x & CELL_FS_S_IFDIR) #endif #if defined(_WIN32) && !defined(_XBOX) @@ -306,12 +308,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) From e252ab8f6154c570adac6af950af7c05644c1c0a Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 18 Jun 2012 23:27:49 +0200 Subject: [PATCH 26/33] Optimize dir reading on Unix. --- file_path.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/file_path.c b/file_path.c index 7a88119db3..6219942a70 100644 --- a/file_path.c +++ b/file_path.c @@ -265,12 +265,13 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) { 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 && path_is_directory(name)) + if (!include_dirs && is_dir) continue; #ifndef __CELLOS_LV2__ - if (!path_is_directory(name) && ext_list && !string_list_find_elem(ext_list, file_ext)) + if (!is_dir && ext_list && !string_list_find_elem(ext_list, file_ext)) continue; #endif From 2e94fdca368b6a3ecbaf4c484aaca6e690214c87 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 23:26:52 +0200 Subject: [PATCH 27/33] (PS3/360) Made libretro_mgmt.c portable --- console/libretro_mgmt.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) 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; } From 75f1cef3039fe6b8f8e875b9007a1e718b2349be Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 23:29:43 +0200 Subject: [PATCH 28/33] (PS3) Directory / extension filtering works on PS3 now --- file_path.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/file_path.c b/file_path.c index 6219942a70..b5ecda7e64 100644 --- a/file_path.c +++ b/file_path.c @@ -270,10 +270,8 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) if (!include_dirs && is_dir) continue; -#ifndef __CELLOS_LV2__ if (!is_dir && ext_list && !string_list_find_elem(ext_list, file_ext)) continue; -#endif char file_path[PATH_MAX]; snprintf(file_path, sizeof(file_path), "%s/%s", dir, name); From bebc4462a641e4402dfc0ba20056c01f432b9f8a Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 18 Jun 2012 23:43:24 +0200 Subject: [PATCH 29/33] Should fix dir_list_new on 360. --- file_path.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/file_path.c b/file_path.c index b5ecda7e64..16d177552e 100644 --- a/file_path.c +++ b/file_path.c @@ -213,14 +213,13 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs) { const char *name = ffd.cFileName; const char *file_ext = path_get_extension(name); + bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - if (!include_dirs && path_is_directory(name)) + if (!include_dirs && is_dir) continue; -#ifndef _XBOX - if (!path_is_directory(name) && ext_list && !string_list_find_elem(ext_list, file_ext)) + if (!is_dir && ext_list && !string_list_find_elem(ext_list, file_ext)) continue; -#endif char file_path[PATH_MAX]; snprintf(file_path, sizeof(file_path), "%s\\%s", dir, name); From d8b9d4b4f6f3ae0ac587c1bd0dedfa4fe8bc22d5 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 18 Jun 2012 23:43:21 +0200 Subject: [PATCH 30/33] (PS3) Got rid of cell_fs includes --- console/fileio/file_browser.c | 3 ++- file.h | 4 ---- file_path.c | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index 303143a235..ab7c5c4302 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -19,7 +19,8 @@ static void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path, const char * extensions) { - strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size])); + strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, + sizeof(filebrowser->dir[filebrowser->directory_stack_size])); filebrowser->current_dir.elems = dir_list_new(path, extensions, true); filebrowser->current_dir.size = dir_list_size(filebrowser->current_dir.elems); diff --git a/file.h b/file.h index acee1679a9..33e06b223f 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); diff --git a/file_path.c b/file_path.c index 16d177552e..58c7a1f1e8 100644 --- a/file_path.c +++ b/file_path.c @@ -23,8 +23,6 @@ #include "compat/posix_string.h" #ifdef __CELLOS_LV2__ -#include - #define S_ISDIR(x) (x & CELL_FS_S_IFDIR) #endif From 7d05d051b47db5dc6660f83a10b0c9f59f2c5ebd Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 19 Jun 2012 00:00:20 +0200 Subject: [PATCH 31/33] Sort directories before files. --- file_path.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/file_path.c b/file_path.c index 58c7a1f1e8..ad92bbed80 100644 --- a/file_path.c +++ b/file_path.c @@ -173,9 +173,35 @@ size_t dir_list_size(char * const *dir_list) return size; } -static int qstrcmp(const void *a, const void *b) +static size_t strcountelem(const char *str, const char *valid) { - return strcasecmp(*(char * const*)a, *(char * const*)b); + size_t count = 0; + + while (*str) + { + if (strchr(valid, *str++)) + count++; + } + + return count; +} + +static int qstrcmp(const void *a_, const void *b_) +{ + const char *a = *(const char * const*)a_; + const char *b = *(const char * const*)b_; + + ssize_t a_cnt = strcountelem(a, "/\\"); + ssize_t b_cnt = strcountelem(b, "/\\"); + + // Place directories on top. + // It is assumed that number of '/' or '\\' in path can determine + // if one path is a directory and the other is not. + + if (a_cnt != b_cnt) + return a_cnt - b_cnt; + else + return strcasecmp(a, b); } void dir_list_sort(char **dir_list) From f0fab577e7b13c1e49d3c001e36284120bde83e8 Mon Sep 17 00:00:00 2001 From: Themaister Date: Tue, 19 Jun 2012 00:16:59 +0200 Subject: [PATCH 32/33] Take the slow but more correct path for directory sorting. --- driver.c | 2 +- file.h | 2 +- file_path.c | 34 +++++++++++----------------------- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/driver.c b/driver.c index 5ca1a4184c..31e419fc7d 100644 --- a/driver.c +++ b/driver.c @@ -484,7 +484,7 @@ static void init_shader_dir(void) 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); + 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]); diff --git a/file.h b/file.h index 33e06b223f..b4f4179bb0 100644 --- a/file.h +++ b/file.h @@ -41,7 +41,7 @@ bool init_rom_file(enum rarch_game_type type); // 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); +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 ad92bbed80..860f3cf69e 100644 --- a/file_path.c +++ b/file_path.c @@ -173,43 +173,31 @@ size_t dir_list_size(char * const *dir_list) return size; } -static size_t strcountelem(const char *str, const char *valid) +static int qstrcmp_plain(const void *a, const void *b) { - size_t count = 0; - - while (*str) - { - if (strchr(valid, *str++)) - count++; - } - - return count; + return strcasecmp(*(const char * const*)a, *(const char * const*)b); } -static int qstrcmp(const void *a_, const void *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_; - ssize_t a_cnt = strcountelem(a, "/\\"); - ssize_t b_cnt = strcountelem(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; - // Place directories on top. - // It is assumed that number of '/' or '\\' in path can determine - // if one path is a directory and the other is not. - - if (a_cnt != b_cnt) - return a_cnt - b_cnt; - else - return strcasecmp(a, b); + return strcasecmp(a, b); } -void dir_list_sort(char **dir_list) +void dir_list_sort(char **dir_list, bool dir_first) { if (!dir_list) return; - qsort(dir_list, dir_list_size(dir_list), sizeof(char*), qstrcmp); + 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 ... From 958b869c8158aa38aa82caf594bfa3477cd48b80 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 19 Jun 2012 00:11:51 +0200 Subject: [PATCH 33/33] (PS3/360) Directories are now correctly placed before files --- console/fileio/file_browser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/fileio/file_browser.c b/console/fileio/file_browser.c index ab7c5c4302..039f0f792c 100644 --- a/console/fileio/file_browser.c +++ b/console/fileio/file_browser.c @@ -26,7 +26,7 @@ const char * path, const char * extensions) filebrowser->current_dir.size = dir_list_size(filebrowser->current_dir.elems); filebrowser->current_dir.ptr = 0; - dir_list_sort(filebrowser->current_dir.elems); + dir_list_sort(filebrowser->current_dir.elems, true); } void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir,