Merge branch 'master' of git://github.com/libretro/RetroArch
This commit is contained in:
commit
00495aa9dd
|
@ -0,0 +1,159 @@
|
|||
TARGET = retroarch.js
|
||||
|
||||
OBJ = frontend/frontend_emscripten.o \
|
||||
retroarch.o \
|
||||
file.o \
|
||||
file_path.o \
|
||||
driver.o \
|
||||
conf/config_file.o \
|
||||
settings.o \
|
||||
hash.o \
|
||||
dynamic.o \
|
||||
dynamic_dummy.o \
|
||||
message.o \
|
||||
rewind.o \
|
||||
movie.o \
|
||||
gfx/gfx_common.o \
|
||||
input/input_common.o \
|
||||
input/rwebinput_input.o \
|
||||
core_options.o \
|
||||
patch.o \
|
||||
compat/compat.o \
|
||||
compat/rxml/rxml.o \
|
||||
screenshot.o \
|
||||
cheats.o \
|
||||
audio/utils.o \
|
||||
audio/rwebaudio.o \
|
||||
input/overlay.o \
|
||||
fifo_buffer.o \
|
||||
gfx/scaler/scaler.o \
|
||||
gfx/scaler/pixconv.o \
|
||||
gfx/scaler/scaler_int.o \
|
||||
gfx/scaler/filter.o \
|
||||
gfx/state_tracker.o \
|
||||
gfx/shader_parse.o \
|
||||
gfx/fonts/fonts.o \
|
||||
gfx/fonts/bitmapfont.o \
|
||||
gfx/image.o \
|
||||
audio/resampler.o \
|
||||
audio/sinc.o \
|
||||
audio/null.o \
|
||||
performance.o
|
||||
|
||||
HAVE_OPENGL = 1
|
||||
HAVE_RGUI = 1
|
||||
HAVE_SDL = 0
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_FBO = 1
|
||||
WANT_MINIZ = 1
|
||||
MEMORY = 67108864
|
||||
LTO = 0
|
||||
FAST_DOUBLES = 1
|
||||
|
||||
ifneq ($(NATIVE_ZLIB),)
|
||||
WANT_MINIZ = 0
|
||||
endif
|
||||
|
||||
libretro = libretro_emscripten.bc
|
||||
|
||||
LIBS = -lm
|
||||
DEFINES = -DHAVE_SCREENSHOTS -DHAVE_NULLAUDIO -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.9.3\"
|
||||
LDFLAGS = -L. -s TOTAL_MEMORY=$(MEMORY) --js-library emscripten/library_rwebaudio.js --js-library emscripten/library_rwebinput.js
|
||||
|
||||
ifeq ($(PERF_TEST), 1)
|
||||
DEFINES += -DPERF_TEST
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RGUI), 1)
|
||||
DEFINES += -DHAVE_RGUI
|
||||
OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += input/sdl_input.o
|
||||
LIBS += -lSDL
|
||||
DEFINES += -ISDL -DHAVE_SDL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/emscriptenegl_ctx.o gfx/shader_glsl.o gfx/glsym/rglgen.o gfx/glsym/glsym_es2.o
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_EGL -DHAVE_OVERLAY -DHAVE_GLSL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZLIB), 1)
|
||||
OBJ += gfx/rpng/rpng.o file_extract.o
|
||||
DEFINES += -DHAVE_ZLIB
|
||||
ifeq ($(WANT_MINIZ), 1)
|
||||
OBJ += deps/miniz/miniz.o
|
||||
DEFINES += -DWANT_MINIZ
|
||||
else
|
||||
LIBS += -lz
|
||||
DEFINES += -DHAVE_ZLIB_DEFLATE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FBO), 1)
|
||||
DEFINES += -DHAVE_FBO
|
||||
endif
|
||||
|
||||
ifneq ($(V), 1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
LDFLAGS += -O0 -g
|
||||
CFLAGS += -O0 -g
|
||||
else
|
||||
LDFLAGS += -O2
|
||||
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
|
||||
ifeq ($(FAST_DOUBLES), 1)
|
||||
LDFLAGS += -s DOUBLE_MODE=0
|
||||
endif
|
||||
ifeq ($(LTO), 1)
|
||||
LDFLAGS += --llvm-lto 3
|
||||
endif
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -Wno-unused-result -Wno-unused-variable -I. -std=gnu99
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
$(Q)$(LD) -o $@ $(OBJ) $(libretro) $(LIBS) $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
%.o: %.cpp
|
||||
@$(if $(Q), $(shell echo echo CXX $<),)
|
||||
$(Q)$(CXX) $(CXXFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f deps/miniz/*.o
|
||||
rm -f frontend/*.o
|
||||
rm -f frontend/menu/*.o
|
||||
rm -f audio/*.o
|
||||
rm -f audio/xaudio-c/*.o
|
||||
rm -f compat/*.o
|
||||
rm -f compat/rxml/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/scaler/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/d3d9/*.o
|
||||
rm -f gfx/context/*.o
|
||||
rm -f gfx/math/*.o
|
||||
rm -f gfx/fonts/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f gfx/rpng/*.o
|
||||
rm -f gfx/glsym/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
rm -f $(TARGET)
|
||||
|
||||
.PHONY: all clean
|
||||
|
18
Makefile.win
18
Makefile.win
|
@ -17,6 +17,7 @@ OBJ = frontend/frontend.o \
|
|||
movie.o \
|
||||
gfx/gfx_common.o \
|
||||
input/input_common.o \
|
||||
input/autoconf/builtin_win.o \
|
||||
core_options.o \
|
||||
patch.o \
|
||||
compat/compat.o \
|
||||
|
@ -44,7 +45,8 @@ JOBJ := conf/config_file.o \
|
|||
compat/compat.o \
|
||||
file_path.o \
|
||||
tools/input_common_joyconfig.o \
|
||||
input/dinput.o
|
||||
input/dinput.o \
|
||||
input/winxinput_joypad.o
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
|
@ -62,6 +64,9 @@ HAVE_STDIN_CMD = 1
|
|||
HAVE_THREADS = 1
|
||||
HAVE_RGUI = 1
|
||||
DYNAMIC = 1
|
||||
HAVE_WIN32GUI = 1
|
||||
|
||||
HAVE_WINXINPUT = 1
|
||||
|
||||
ifeq ($(SLIM),)
|
||||
HAVE_SDL = 1
|
||||
|
@ -78,7 +83,7 @@ endif
|
|||
libretro ?= -lretro
|
||||
|
||||
LIBS = -lm
|
||||
DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE
|
||||
DEFINES = -I. -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DHAVE_BUILTIN_AUTOCONFIG
|
||||
LDFLAGS = -L. -static-libgcc
|
||||
|
||||
ifeq ($(TDM_GCC),)
|
||||
|
@ -100,6 +105,10 @@ ifeq ($(HAVE_RGUI), 1)
|
|||
OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_WIN32GUI), 1)
|
||||
DEFINES += -DHAVE_WIN32GUI
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/sdl_gfx.o input/sdl_input.o input/sdl_joypad.o audio/sdl_audio.o
|
||||
JOBJ += input/sdl_joypad.o
|
||||
|
@ -212,6 +221,11 @@ ifeq ($(HAVE_PYTHON), 1)
|
|||
OBJ += gfx/py_state/py_state.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_WINXINPUT), 1)
|
||||
DEFINES += -DHAVE_WINXINPUT
|
||||
OBJ += input/winxinput_joypad.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DINPUT), 1)
|
||||
LIBS += -ldinput8 -ldxguid -lole32
|
||||
DEFINES += -DHAVE_DINPUT
|
||||
|
|
|
@ -48,7 +48,7 @@ ifeq ($(PERF_TEST), 1)
|
|||
LOCAL_CFLAGS += -DPERF_TEST
|
||||
endif
|
||||
|
||||
LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DRARCH_MOBILE -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DHAVE_RGUI -DHAVE_SCREENSHOTS -DWANT_MINIZ -DHAVE_ZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREADS -D__LIBRETRO__ -DRARCH_PERFORMANCE_MODE -std=gnu99 -I../../../deps/miniz
|
||||
LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DRARCH_MOBILE -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DHAVE_RGUI -DHAVE_SCREENSHOTS -DWANT_MINIZ -DHAVE_ZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREADS -D__LIBRETRO__ -std=gnu99 -I../../../deps/miniz
|
||||
|
||||
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL -lGLESv2 $(LOGGER_LDLIBS) -ldl
|
||||
|
||||
|
|
|
@ -1855,7 +1855,7 @@ static int16_t android_input_state(void *data, const struct retro_keybind **bind
|
|||
|
||||
static bool android_input_key_pressed(void *data, int key)
|
||||
{
|
||||
return ((g_extern.lifecycle_state | driver.overlay_state) & (1ULL << key));
|
||||
return ((g_extern.lifecycle_state | driver.overlay_state.buttons) & (1ULL << key));
|
||||
}
|
||||
|
||||
static void android_input_free_input(void *data)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.retroarch"
|
||||
android:versionCode="23"
|
||||
android:versionCode="24"
|
||||
android:versionName="0.9.9.6" >
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
@ -29,6 +29,7 @@
|
|||
<activity android:name=".browser.LazyPopupMenu"></activity>
|
||||
<activity android:name=".browser.PopupMenuAbstract"></activity>
|
||||
<activity android:name=".browser.ReportIME"></activity>
|
||||
<activity android:name=".browser.IMEActivity"></activity>
|
||||
<activity android:name=".browser.HelpActivity"></activity>
|
||||
<activity android:name=".browser.FileWrapper"></activity>
|
||||
<activity android:name=".browser.DirectoryActivity"></activity>
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<ListPreference
|
||||
android:entries="@array/aspect_ratios"
|
||||
android:entryValues="@array/aspect_values"
|
||||
android:defaultValue="auto"
|
||||
android:key="video_aspect_ratio"
|
||||
android:summary="Aspect ratio to enforce."
|
||||
android:title="Aspect ratio" />
|
||||
|
@ -123,17 +124,25 @@
|
|||
</PreferenceScreen>
|
||||
<PreferenceScreen android:title="Input Options" >
|
||||
<PreferenceCategory android:title="General" >
|
||||
<CheckBoxPreference android:title="Enable global configuration"
|
||||
android:summary="Enable global settings for all cores. Leave disabled if you want per-core settings."
|
||||
android:key="global_config_enable"
|
||||
android:defaultValue="true"/>
|
||||
<ListPreference
|
||||
android:entries="@array/back_options"
|
||||
android:entryValues="@array/back_options_values"
|
||||
android:defaultValue="0"
|
||||
android:key="input_back_behavior"
|
||||
android:summary="Select how you want the Back button to behave."
|
||||
android:title="Back behavior" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="IME" >
|
||||
<Preference
|
||||
android:summary="Sets IME to be used in-game."
|
||||
android:title="Set Input Method" >
|
||||
<intent
|
||||
android:targetClass="org.retroarch.browser.IMEActivity"
|
||||
android:targetPackage="org.retroarch" />
|
||||
</Preference>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="Configuration Autodetect" >
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
|
@ -468,6 +477,14 @@
|
|||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen android:title="Settings" >
|
||||
<PreferenceCategory android:title="Configuration style" >
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="global_config_enable"
|
||||
android:summary="Enable global settings for all cores. Leave disabled if you want per-core settings."
|
||||
android:title="Enable global configuration" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="General" >
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
|
|
|
@ -80,6 +80,10 @@ public class ConfigFile {
|
|||
public void setDouble(String key, double value) {
|
||||
map.put(key, Double.toString(value));
|
||||
}
|
||||
|
||||
public void setFloat(String key, float value) {
|
||||
map.put(key, Float.toString(value));
|
||||
}
|
||||
|
||||
public boolean keyExists(String key) {
|
||||
return map.containsKey(key);
|
||||
|
@ -108,6 +112,14 @@ public class ConfigFile {
|
|||
else
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
|
||||
public float getFloat(String key) throws NumberFormatException {
|
||||
String str = getString(key);
|
||||
if (str != null)
|
||||
return Float.parseFloat(str);
|
||||
else
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
|
||||
public boolean getBoolean(String key) {
|
||||
String str = getString(key);
|
||||
|
|
|
@ -9,7 +9,6 @@ import android.content.*;
|
|||
import android.app.*;
|
||||
import android.media.AudioManager;
|
||||
import android.os.*;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.widget.*;
|
||||
import android.view.*;
|
||||
|
||||
|
@ -107,7 +106,7 @@ public class DirectoryActivity extends Activity implements
|
|||
|
||||
private void finishWithPath(String path) {
|
||||
if (pathSettingKey != null && !pathSettingKey.isEmpty()) {
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences settings = MainMenuActivity.getPreferences();
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString(pathSettingKey, path);
|
||||
editor.commit();
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.content.SharedPreferences;
|
|||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
@ -36,7 +35,7 @@ public class DisplayRefreshRateTest extends Activity {
|
|||
}
|
||||
|
||||
private void setFPSSetting(double fps) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = MainMenuActivity.getPreferences();
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("video_refresh_rate", Double.valueOf(fps).toString());
|
||||
edit.commit();
|
||||
|
@ -117,7 +116,7 @@ public class DisplayRefreshRateTest extends Activity {
|
|||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = MainMenuActivity.getPreferences();
|
||||
String fps = prefs.getString("video_refresh_rate", "ERROR");
|
||||
Toast.makeText(this, "Refresh rate measured to: " + fps + " Hz.", Toast.LENGTH_LONG).show();
|
||||
super.onDestroy();
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.retroarch.browser;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
public class IMEActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showInputMethodPicker();
|
||||
finish();
|
||||
}
|
||||
}
|
|
@ -11,12 +11,15 @@ import android.content.Context;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
|
@ -31,20 +34,58 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
static private final String TAG = "MainMenu";
|
||||
static private String libretro_path;
|
||||
static private String libretro_name;
|
||||
|
||||
|
||||
private boolean globalConfigEnable = true;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void refreshPreferenceScreen() {
|
||||
readbackConfigFile();
|
||||
|
||||
setPreferenceScreen(null);
|
||||
addPreferencesFromResource(R.xml.prefs);
|
||||
|
||||
setCoreTitle(libretro_name);
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs, false);
|
||||
|
||||
final CheckBoxPreference param = (CheckBoxPreference) findPreference("global_config_enable");
|
||||
globalConfigEnable = param.isChecked();
|
||||
param.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
updateConfigFile();
|
||||
globalConfigEnable = param.isChecked();
|
||||
SharedPreferences prefs = MainMenuActivity.getPreferences();
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("global_config_enable", param.isChecked());
|
||||
edit.commit();
|
||||
|
||||
refreshPreferenceScreen();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean usePerCoreConfig() {
|
||||
boolean config_same_as_native_lib_dir = libretro_path
|
||||
.equals(getApplicationInfo().nativeLibraryDir);
|
||||
|
||||
return !globalConfigEnable && !config_same_as_native_lib_dir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
instance = this;
|
||||
|
||||
SharedPreferences prefs = getPreferences();
|
||||
|
||||
libretro_path = prefs.getString("libretro_path", getApplicationInfo().nativeLibraryDir);
|
||||
libretro_name = prefs.getString("libretro_name", "No core");
|
||||
|
||||
addPreferencesFromResource(R.xml.prefs);
|
||||
PreferenceManager.setDefaultValues(this, R.xml.prefs, false);
|
||||
refreshPreferenceScreen();
|
||||
|
||||
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
|
||||
extractAssets();
|
||||
|
||||
if (!prefs.getBoolean("first_time_refreshrate_calculate", false)) {
|
||||
|
@ -56,37 +97,11 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
.setTitle("Welcome to RetroArch")
|
||||
.setMessage(
|
||||
"This is your first time starting up RetroArch. RetroArch will now be preconfigured for the best possible gameplay experience.")
|
||||
.setPositiveButton("OK",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences.Editor edit = prefs
|
||||
.edit();
|
||||
edit.putBoolean("video_threaded", true);
|
||||
edit.commit();
|
||||
}
|
||||
});
|
||||
.setPositiveButton("OK", null);
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
|
||||
if (prefs.getString("libretro_path", "").isEmpty() == false) {
|
||||
libretro_path = prefs.getString("libretro_path", "");
|
||||
setCoreTitle("No core");
|
||||
|
||||
if (prefs.getString("libretro_name", "").isEmpty() == false) {
|
||||
libretro_name = prefs.getString("libretro_name", "No core");
|
||||
setCoreTitle(libretro_name);
|
||||
}
|
||||
} else {
|
||||
libretro_path = MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir;
|
||||
libretro_name = "No core";
|
||||
setCoreTitle("No core");
|
||||
}
|
||||
|
||||
Intent startedByIntent = getIntent();
|
||||
if (null != startedByIntent.getStringExtra("ROM")
|
||||
&& null != startedByIntent.getStringExtra("LIBRETRO")) {
|
||||
|
@ -119,19 +134,17 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
|
||||
public static final double getRefreshRate() {
|
||||
double rate = 0;
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(MainMenuActivity.getInstance()
|
||||
.getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
String refresh_rate = prefs.getString("video_refresh_rate", "");
|
||||
if (!refresh_rate.isEmpty()) {
|
||||
try {
|
||||
rate = Double.parseDouble(refresh_rate);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "Cannot parse: " + refresh_rate + " as a double!");
|
||||
rate = MainMenuActivity.getInstance().getDisplayRefreshRate();
|
||||
rate = getInstance().getDisplayRefreshRate();
|
||||
}
|
||||
} else {
|
||||
rate = MainMenuActivity.getInstance().getDisplayRefreshRate();
|
||||
rate = getInstance().getDisplayRefreshRate();
|
||||
}
|
||||
|
||||
Log.i(TAG, "Using refresh rate: " + rate + " Hz.");
|
||||
|
@ -157,12 +170,29 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
|
||||
@TargetApi(17)
|
||||
public static int getLowLatencyOptimalSamplingRate() {
|
||||
AudioManager manager = (AudioManager) MainMenuActivity.getInstance()
|
||||
AudioManager manager = (AudioManager) getInstance()
|
||||
.getApplicationContext()
|
||||
.getSystemService(Context.AUDIO_SERVICE);
|
||||
return Integer.parseInt(manager
|
||||
.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
|
||||
}
|
||||
|
||||
@TargetApi(17)
|
||||
public static int getLowLatencyBufferSize() {
|
||||
AudioManager manager = (AudioManager) getInstance()
|
||||
.getApplicationContext()
|
||||
.getSystemService(Context.AUDIO_SERVICE);
|
||||
int buffersize = Integer.parseInt(manager
|
||||
.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
|
||||
Log.i(TAG, "Queried ideal buffer size (frames): " + buffersize);
|
||||
return buffersize;
|
||||
}
|
||||
|
||||
@TargetApi(17)
|
||||
public static boolean hasLowLatencyAudio() {
|
||||
PackageManager pm = getInstance().getPackageManager();
|
||||
return pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY);
|
||||
}
|
||||
|
||||
public static int getOptimalSamplingRate() {
|
||||
int ret;
|
||||
|
@ -175,27 +205,24 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
Log.i(TAG, "Using sampling rate: " + ret + " Hz");
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String sanitizeLibretroPath(String path) {
|
||||
String sanitized_name = path.substring(
|
||||
path.lastIndexOf("/") + 1,
|
||||
path.lastIndexOf("."));
|
||||
sanitized_name = sanitized_name.replace("neon", "");
|
||||
sanitized_name = sanitized_name.replace("libretro_", "");
|
||||
return sanitized_name;
|
||||
}
|
||||
|
||||
public static String getDefaultConfigPath() {
|
||||
String internal = System.getenv("INTERNAL_STORAGE");
|
||||
String external = System.getenv("EXTERNAL_STORAGE");
|
||||
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(MainMenuActivity.getInstance()
|
||||
.getBaseContext());
|
||||
|
||||
boolean global_config_enable = prefs.getBoolean("global_config_enable",
|
||||
true);
|
||||
boolean config_same_as_native_lib_dir = libretro_path
|
||||
.equals(MainMenuActivity.getInstance().getApplicationInfo().nativeLibraryDir);
|
||||
String append_path;
|
||||
if (!global_config_enable && (config_same_as_native_lib_dir == false)) {
|
||||
String sanitized_name = libretro_path.substring(
|
||||
libretro_path.lastIndexOf("/") + 1,
|
||||
libretro_path.lastIndexOf("."));
|
||||
sanitized_name = sanitized_name.replace("neon", "");
|
||||
sanitized_name = sanitized_name.replace("libretro_", "");
|
||||
append_path = File.separator + sanitized_name + "retroarch.cfg";
|
||||
if (getInstance().usePerCoreConfig()) {
|
||||
String sanitized_name = sanitizeLibretroPath(libretro_path);
|
||||
append_path = File.separator + sanitized_name + ".cfg";
|
||||
} else {
|
||||
append_path = File.separator + "retroarch.cfg";
|
||||
}
|
||||
|
@ -219,40 +246,138 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
else if (external != null
|
||||
&& new File(internal + append_path).canWrite())
|
||||
return external + append_path;
|
||||
else if ((MainMenuActivity.getInstance().getApplicationInfo().dataDir) != null)
|
||||
return (MainMenuActivity.getInstance().getApplicationInfo().dataDir)
|
||||
else if ((getInstance().getApplicationInfo().dataDir) != null)
|
||||
return (getInstance().getApplicationInfo().dataDir)
|
||||
+ append_path;
|
||||
else
|
||||
// emergency fallback, all else failed
|
||||
return "/mnt/sd" + append_path;
|
||||
}
|
||||
|
||||
public void updateConfigFile() {
|
||||
|
||||
private void readbackString(ConfigFile cfg, SharedPreferences.Editor edit, String key) {
|
||||
if (cfg.keyExists(key))
|
||||
edit.putString(key, cfg.getString(key));
|
||||
else
|
||||
edit.remove(key);
|
||||
}
|
||||
|
||||
private void readbackBool(ConfigFile cfg, SharedPreferences.Editor edit, String key) {
|
||||
if (cfg.keyExists(key))
|
||||
edit.putBoolean(key, cfg.getBoolean(key));
|
||||
else
|
||||
edit.remove(key);
|
||||
}
|
||||
|
||||
private void readbackDouble(ConfigFile cfg, SharedPreferences.Editor edit, String key) {
|
||||
if (cfg.keyExists(key))
|
||||
edit.putFloat(key, (float)cfg.getDouble(key));
|
||||
else
|
||||
edit.remove(key);
|
||||
}
|
||||
|
||||
private void readbackFloat(ConfigFile cfg, SharedPreferences.Editor edit, String key) {
|
||||
if (cfg.keyExists(key))
|
||||
edit.putFloat(key, cfg.getFloat(key));
|
||||
else
|
||||
edit.remove(key);
|
||||
}
|
||||
|
||||
private void readbackInt(ConfigFile cfg, SharedPreferences.Editor edit, String key) {
|
||||
if (cfg.keyExists(key))
|
||||
edit.putInt(key, cfg.getInt(key));
|
||||
else
|
||||
edit.remove(key);
|
||||
}
|
||||
|
||||
public void readbackConfigFile() {
|
||||
String path = getDefaultConfigPath();
|
||||
ConfigFile config;
|
||||
try {
|
||||
config = new ConfigFile(new File(getDefaultConfigPath()));
|
||||
config = new ConfigFile(new File(path));
|
||||
} catch (IOException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(TAG, "Config readback from: " + path);
|
||||
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
|
||||
readbackString(config, edit, "rgui_browser_directory");
|
||||
readbackString(config, edit, "savefile_directory");
|
||||
readbackString(config, edit, "savestate_directory");
|
||||
readbackBool(config, edit, "savefile_directory_enable"); // Ignored by RetroArch
|
||||
readbackBool(config, edit, "savestate_directory_enable"); // Ignored by RetroArch
|
||||
|
||||
readbackString(config, edit, "input_overlay");
|
||||
readbackBool(config, edit, "input_overlay_enable");
|
||||
readbackBool(config, edit, "video_scale_integer");
|
||||
readbackBool(config, edit, "video_smooth");
|
||||
readbackBool(config, edit, "video_threaded");
|
||||
readbackBool(config, edit, "rewind_enable");
|
||||
readbackBool(config, edit, "savestate_auto_load");
|
||||
readbackBool(config, edit, "savestate_auto_save");
|
||||
//readbackDouble(config, edit, "video_refresh_rate");
|
||||
|
||||
readbackBool(config, edit, "audio_rate_control");
|
||||
readbackBool(config, edit, "audio_enable");
|
||||
// TODO: other audio settings
|
||||
|
||||
readbackDouble(config, edit, "input_overlay_opacity");
|
||||
readbackBool(config, edit, "input_autodetect_enable");
|
||||
//readbackInt(config, edit, "input_back_behavior");
|
||||
|
||||
readbackBool(config, edit, "video_allow_rotate");
|
||||
readbackBool(config, edit, "video_font_enable");
|
||||
|
||||
readbackBool(config, edit, "video_vsync");
|
||||
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public void updateConfigFile() {
|
||||
String path = getDefaultConfigPath();
|
||||
ConfigFile config;
|
||||
try {
|
||||
config = new ConfigFile(new File(path));
|
||||
} catch (IOException e) {
|
||||
config = new ConfigFile();
|
||||
}
|
||||
|
||||
Log.i(TAG, "Writing config to: " + path);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(MainMenuActivity.getInstance()
|
||||
.getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
|
||||
config.setString("libretro_path", libretro_path);
|
||||
config.setString("libretro_name", libretro_name);
|
||||
setCoreTitle(libretro_name);
|
||||
|
||||
config.setString("rgui_browser_directory",
|
||||
prefs.getString("rgui_browser_directory", ""));
|
||||
config.setBoolean("global_config_enable",
|
||||
prefs.getBoolean("global_config_enable", true));
|
||||
config.setBoolean("audio_rate_control",
|
||||
prefs.getBoolean("audio_rate_control", true));
|
||||
config.setInt("audio_out_rate",
|
||||
MainMenuActivity.getOptimalSamplingRate());
|
||||
config.setInt("audio_latency",
|
||||
prefs.getBoolean("audio_high_latency", false) ? 160 : 64);
|
||||
|
||||
int optimalRate = getOptimalSamplingRate();
|
||||
config.setInt("audio_out_rate", optimalRate);
|
||||
|
||||
// Refactor this entire mess and make this usable for per-core config
|
||||
if (android.os.Build.VERSION.SDK_INT >= 17) {
|
||||
int buffersize = getLowLatencyBufferSize();
|
||||
|
||||
boolean lowLatency = hasLowLatencyAudio();
|
||||
Log.i(TAG, "Audio is low latency: " + (lowLatency ? "yes" : "no"));
|
||||
|
||||
if (lowLatency && !prefs.getBoolean("audio_high_latency", false)) {
|
||||
config.setInt("audio_latency", 64);
|
||||
config.setInt("audio_block_frames", buffersize);
|
||||
} else {
|
||||
config.setInt("audio_latency", prefs.getBoolean(
|
||||
"audio_high_latency", false) ? 160 : 64);
|
||||
config.setInt("audio_block_frames", 0);
|
||||
}
|
||||
} else {
|
||||
config.setInt("audio_latency",
|
||||
prefs.getBoolean("audio_high_latency", false) ? 160 : 64);
|
||||
}
|
||||
|
||||
config.setBoolean("audio_enable",
|
||||
prefs.getBoolean("audio_enable", true));
|
||||
config.setBoolean("video_smooth",
|
||||
|
@ -286,10 +411,12 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
"0")));
|
||||
|
||||
config.setDouble("video_refresh_rate",
|
||||
MainMenuActivity.getRefreshRate());
|
||||
getRefreshRate());
|
||||
config.setBoolean("video_threaded",
|
||||
prefs.getBoolean("video_threaded", true));
|
||||
|
||||
// Refactor these weird values - 'full', 'auto', 'square', whatever -
|
||||
// go by what we have in RGUI - makes maintaining state easier too
|
||||
String aspect = prefs.getString("video_aspect_ratio", "auto");
|
||||
if (aspect.equals("full")) {
|
||||
config.setBoolean("video_force_aspect", false);
|
||||
|
@ -317,9 +444,10 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
&& new File(shaderPath).exists());
|
||||
|
||||
boolean useOverlay = prefs.getBoolean("input_overlay_enable", true);
|
||||
config.setBoolean("input_overlay_enable", useOverlay); // Not used by RetroArch directly.
|
||||
if (useOverlay) {
|
||||
String overlayPath = prefs
|
||||
.getString("input_overlay", (MainMenuActivity.getInstance()
|
||||
.getString("input_overlay", (getInstance()
|
||||
.getApplicationInfo().dataDir)
|
||||
+ "/overlays/snes-landscape.cfg");
|
||||
config.setString("input_overlay", overlayPath);
|
||||
|
@ -328,7 +456,6 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
} else {
|
||||
config.setString("input_overlay", "");
|
||||
}
|
||||
|
||||
config.setString(
|
||||
"savefile_directory",
|
||||
prefs.getBoolean("savefile_directory_enable", false) ? prefs
|
||||
|
@ -345,7 +472,7 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
config.setBoolean("video_font_enable",
|
||||
prefs.getBoolean("video_font_enable", true));
|
||||
|
||||
config.setString("game_history_path", MainMenuActivity.getInstance()
|
||||
config.setString("game_history_path", getInstance()
|
||||
.getApplicationInfo().dataDir + "/retroarch-history.txt");
|
||||
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
|
@ -359,11 +486,10 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
}
|
||||
}
|
||||
|
||||
String confPath = getDefaultConfigPath();
|
||||
try {
|
||||
config.write(new File(confPath));
|
||||
config.write(new File(path));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to save config file to: " + confPath);
|
||||
Log.e(TAG, "Failed to save config file to: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,20 +625,28 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static SharedPreferences getPreferences() {
|
||||
return PreferenceManager.getDefaultSharedPreferences(getInstance().getBaseContext());
|
||||
}
|
||||
|
||||
public void setModule(String core_path, String core_name) {
|
||||
updateConfigFile();
|
||||
|
||||
libretro_path = core_path;
|
||||
libretro_name = core_name;
|
||||
File libretro_path_file = new File(core_path);
|
||||
setCoreTitle((libretro_path_file.isDirectory() == true) ? "No core"
|
||||
: core_name);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("libretro_path", libretro_path);
|
||||
edit.putString("libretro_name", libretro_name);
|
||||
edit.commit();
|
||||
|
||||
if (usePerCoreConfig())
|
||||
refreshPreferenceScreen();
|
||||
else {
|
||||
setCoreTitle(libretro_name); // this still needs to be applied
|
||||
}
|
||||
}
|
||||
|
||||
public void setCoreTitle(String core_name) {
|
||||
|
@ -538,8 +672,7 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs
|
||||
.edit();
|
||||
edit.putString("video_refresh_rate", Double
|
||||
|
@ -562,8 +695,7 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs
|
||||
.edit();
|
||||
edit.putBoolean("input_overlay_enable",
|
||||
|
@ -585,8 +717,7 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs
|
||||
.edit();
|
||||
edit.putBoolean("input_overlay_enable",
|
||||
|
@ -598,6 +729,27 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
} else if (android.os.Build.MODEL.equals("R800x")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle("Xperia Play detected")
|
||||
.setMessage(message)
|
||||
.setPositiveButton("OK",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs
|
||||
.edit();
|
||||
edit.putBoolean("input_overlay_enable",
|
||||
false);
|
||||
edit.putBoolean("input_autodetect_enable",
|
||||
true);
|
||||
edit.commit();
|
||||
}
|
||||
});
|
||||
alert.show();
|
||||
retval = true;
|
||||
} else if (android.os.Build.ID.equals("JSS15J")) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this)
|
||||
.setTitle("Nexus 7 2013 detected")
|
||||
|
@ -607,8 +759,7 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
SharedPreferences prefs = PreferenceManager
|
||||
.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = getPreferences();
|
||||
SharedPreferences.Editor edit = prefs
|
||||
.edit();
|
||||
edit.putString("video_refresh_rate", Double
|
||||
|
@ -626,6 +777,8 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
"Device either not detected in list or doesn't have any optimal settings in our database.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
refreshPreferenceScreen();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -668,7 +821,7 @@ public class MainMenuActivity extends PreferenceActivity {
|
|||
myIntent.putExtra("ROM", data.getStringExtra("PATH"));
|
||||
myIntent.putExtra("LIBRETRO", libretro_path);
|
||||
myIntent.putExtra("CONFIGFILE",
|
||||
MainMenuActivity.getDefaultConfigPath());
|
||||
getDefaultConfigPath());
|
||||
myIntent.putExtra("IME", current_ime);
|
||||
startActivity(myIntent);
|
||||
}
|
||||
|
|
|
@ -4,13 +4,12 @@ import java.io.File;
|
|||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class ROMActivity extends DirectoryActivity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = MainMenuActivity.getPreferences();
|
||||
String startPath = prefs.getString("rgui_browser_directory", "");
|
||||
if (!startPath.isEmpty() && new File(startPath).exists())
|
||||
super.setStartDirectory(startPath);
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
@ -18,7 +17,7 @@ public class RefreshRateSetOS extends Activity {
|
|||
final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
|
||||
final Display display = wm.getDefaultDisplay();
|
||||
double rate = display.getRefreshRate();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||
SharedPreferences prefs = MainMenuActivity.getPreferences();
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("video_refresh_rate", Double.valueOf(rate).toString());
|
||||
edit.commit();
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.retroarch.browser;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
|
||||
|
@ -9,7 +10,27 @@ public class ReportIME extends Activity {
|
|||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
String current_ime = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
new AlertDialog.Builder(this).setMessage(current_ime).setNeutralButton("Close", null).show();
|
||||
String current_ime = Settings.Secure.getString(getContentResolver(),
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD);
|
||||
|
||||
final Activity ctx = this;
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this)
|
||||
.setMessage(current_ime)
|
||||
.setNeutralButton("Close",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
ctx.finish();
|
||||
}
|
||||
}).setCancelable(true)
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
ctx.finish();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,384 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1080</int>
|
||||
<string key="IBDocument.SystemVersion">12E55</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.39</string>
|
||||
<string key="IBDocument.HIToolboxVersion">626.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="NS.object.0">3084</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBNSLayoutConstraint</string>
|
||||
<string>NSButton</string>
|
||||
<string>NSButtonCell</string>
|
||||
<string>NSCustomObject</string>
|
||||
<string>NSTextField</string>
|
||||
<string>NSTextFieldCell</string>
|
||||
<string>NSView</string>
|
||||
<string>NSWindowTemplate</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="NSCustomObject" id="1001">
|
||||
<string key="NSClassName">NSWindowController</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1003">
|
||||
<string key="NSClassName">FirstResponder</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1004">
|
||||
<string key="NSClassName">NSApplication</string>
|
||||
</object>
|
||||
<object class="NSWindowTemplate" id="1005">
|
||||
<int key="NSWindowStyleMask">15</int>
|
||||
<int key="NSWindowBacking">2</int>
|
||||
<string key="NSWindowRect">{{196, 240}, {480, 109}}</string>
|
||||
<int key="NSWTFlags">544735232</int>
|
||||
<string key="NSWindowTitle">Window</string>
|
||||
<string key="NSWindowClass">RAInputBinder</string>
|
||||
<nil key="NSViewClass"/>
|
||||
<nil key="NSUserInterfaceItemIdentifier"/>
|
||||
<object class="NSView" key="NSWindowView" id="1006">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSTextField" id="693377980">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{17, 72}, {446, 17}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="606338068"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:1535</string>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSTextFieldCell" key="NSCell" id="270729776">
|
||||
<int key="NSCellFlags">68157504</int>
|
||||
<int key="NSCellFlags2">138413056</int>
|
||||
<string key="NSContents">Press a Key, Joystick Button, or move a Joystick Axis</string>
|
||||
<object class="NSFont" key="NSSupport" id="965449829">
|
||||
<string key="NSName">LucidaGrande</string>
|
||||
<double key="NSSize">13</double>
|
||||
<int key="NSfFlags">1044</int>
|
||||
</object>
|
||||
<string key="NSCellIdentifier">_NS:1535</string>
|
||||
<reference key="NSControlView" ref="693377980"/>
|
||||
<object class="NSColor" key="NSBackgroundColor">
|
||||
<int key="NSColorSpace">6</int>
|
||||
<string key="NSCatalogName">System</string>
|
||||
<string key="NSColorName">controlColor</string>
|
||||
<object class="NSColor" key="NSColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSColor" key="NSTextColor">
|
||||
<int key="NSColorSpace">6</int>
|
||||
<string key="NSCatalogName">System</string>
|
||||
<string key="NSColorName">controlTextColor</string>
|
||||
<object class="NSColor" key="NSColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MAA</bytes>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||
</object>
|
||||
<object class="NSButton" id="606338068">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{384, 13}, {82, 32}}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<reference key="NSWindow"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSButtonCell" key="NSCell" id="548104382">
|
||||
<int key="NSCellFlags">67108864</int>
|
||||
<int key="NSCellFlags2">134217728</int>
|
||||
<string key="NSContents">Cancel</string>
|
||||
<reference key="NSSupport" ref="965449829"/>
|
||||
<string key="NSCellIdentifier">_NS:9</string>
|
||||
<reference key="NSControlView" ref="606338068"/>
|
||||
<int key="NSButtonFlags">-2038284288</int>
|
||||
<int key="NSButtonFlags2">129</int>
|
||||
<reference key="NSAlternateImage" ref="965449829"/>
|
||||
<string key="NSAlternateContents"/>
|
||||
<string type="base64-UTF8" key="NSKeyEquivalent">Gw</string>
|
||||
<int key="NSPeriodicDelay">200</int>
|
||||
<int key="NSPeriodicInterval">25</int>
|
||||
</object>
|
||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSFrameSize">{480, 109}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="693377980"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
|
||||
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
|
||||
<bool key="NSWindowIsRestorable">YES</bool>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">window</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="1005"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">goAway:</string>
|
||||
<reference key="source" ref="1005"/>
|
||||
<reference key="destination" ref="606338068"/>
|
||||
</object>
|
||||
<int key="connectionID">20</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="1001"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="1003"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">First Responder</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-3</int>
|
||||
<reference key="object" ref="1004"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">Application</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">1</int>
|
||||
<reference key="object" ref="1005"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="1006"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="1006"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<object class="IBNSLayoutConstraint" id="952757161">
|
||||
<reference key="firstItem" ref="1006"/>
|
||||
<int key="firstAttribute">4</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="606338068"/>
|
||||
<int key="secondAttribute">4</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||
<double key="value">20</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="1006"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="1024300700">
|
||||
<reference key="firstItem" ref="1006"/>
|
||||
<int key="firstAttribute">6</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="606338068"/>
|
||||
<int key="secondAttribute">6</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||
<double key="value">20</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="1006"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="547048879">
|
||||
<reference key="firstItem" ref="693377980"/>
|
||||
<int key="firstAttribute">3</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="1006"/>
|
||||
<int key="secondAttribute">3</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||
<double key="value">20</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="1006"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="101981711">
|
||||
<reference key="firstItem" ref="1006"/>
|
||||
<int key="firstAttribute">6</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="693377980"/>
|
||||
<int key="secondAttribute">6</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||
<double key="value">20</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="1006"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="362753409">
|
||||
<reference key="firstItem" ref="693377980"/>
|
||||
<int key="firstAttribute">5</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="1006"/>
|
||||
<int key="secondAttribute">5</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBNSLayoutSymbolicConstant" key="constant">
|
||||
<double key="value">20</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="1006"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<reference ref="693377980"/>
|
||||
<reference ref="606338068"/>
|
||||
</array>
|
||||
<reference key="parent" ref="1005"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">4</int>
|
||||
<reference key="object" ref="693377980"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="270729776"/>
|
||||
</array>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">5</int>
|
||||
<reference key="object" ref="270729776"/>
|
||||
<reference key="parent" ref="693377980"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">9</int>
|
||||
<reference key="object" ref="362753409"/>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">10</int>
|
||||
<reference key="object" ref="101981711"/>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">11</int>
|
||||
<reference key="object" ref="547048879"/>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">12</int>
|
||||
<reference key="object" ref="606338068"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="548104382"/>
|
||||
</array>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">13</int>
|
||||
<reference key="object" ref="548104382"/>
|
||||
<reference key="parent" ref="606338068"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">14</int>
|
||||
<reference key="object" ref="1024300700"/>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">15</int>
|
||||
<reference key="object" ref="952757161"/>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="1.IBWindowTemplateEditedContentRect">{{357, 418}, {480, 270}}</string>
|
||||
<boolean value="NO" key="1.NSWindowTemplate.visibleAtLaunch"/>
|
||||
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="11.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<boolean value="NO" key="12.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||
<string key="12.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="13.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="15.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<array key="2.IBNSViewMetadataConstraints">
|
||||
<reference ref="362753409"/>
|
||||
<reference ref="101981711"/>
|
||||
<reference ref="547048879"/>
|
||||
<reference ref="1024300700"/>
|
||||
<reference ref="952757161"/>
|
||||
</array>
|
||||
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<boolean value="NO" key="4.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="9.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">20</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">NSLayoutConstraint</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">RAInputBinder</string>
|
||||
<string key="superclassName">NSWindow</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/RAInputBinder.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<bool key="IBDocument.UseAutolayout">YES</bool>
|
||||
</data>
|
||||
</archive>
|
|
@ -2,9 +2,9 @@
|
|||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1080</int>
|
||||
<string key="IBDocument.SystemVersion">12D78</string>
|
||||
<string key="IBDocument.SystemVersion">12E55</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.37</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.39</string>
|
||||
<string key="IBDocument.HIToolboxVersion">626.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
|
@ -297,6 +297,28 @@
|
|||
</array>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="1225315">
|
||||
<reference key="NSMenu" ref="649796088"/>
|
||||
<string key="NSTitle">Go</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="35465992"/>
|
||||
<reference key="NSMixedImage" ref="502551668"/>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<object class="NSMenu" key="NSSubmenu" id="715293634">
|
||||
<string key="NSTitle">Go</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="NSMenuItem" id="777071989">
|
||||
<reference key="NSMenu" ref="715293634"/>
|
||||
<string key="NSTitle">Cores Directory</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="35465992"/>
|
||||
<reference key="NSMixedImage" ref="502551668"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMenuItem" id="713487014">
|
||||
<reference key="NSMenu" ref="649796088"/>
|
||||
<string key="NSTitle">Window</string>
|
||||
|
@ -397,11 +419,9 @@
|
|||
<nil key="NSViewClass"/>
|
||||
<nil key="NSUserInterfaceItemIdentifier"/>
|
||||
<object class="NSView" key="NSWindowView" id="439893737">
|
||||
<reference key="NSNextResponder"/>
|
||||
<nil key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<string key="NSFrameSize">{480, 360}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
|
||||
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
|
||||
|
@ -420,7 +440,7 @@
|
|||
<nil key="NSViewClass"/>
|
||||
<nil key="NSUserInterfaceItemIdentifier"/>
|
||||
<object class="NSView" key="NSWindowView" id="327272550">
|
||||
<reference key="NSNextResponder"/>
|
||||
<nil key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSTextField" id="981013832">
|
||||
|
@ -428,7 +448,6 @@
|
|||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{17, 72}, {242, 17}}</string>
|
||||
<reference key="NSSuperview" ref="327272550"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="481701893"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:1535</string>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
|
@ -470,7 +489,6 @@
|
|||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{20, 45}, {239, 26}}</string>
|
||||
<reference key="NSSuperview" ref="327272550"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="59737118"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<int key="NSTag">1</int>
|
||||
|
@ -499,7 +517,7 @@
|
|||
<object class="NSComboTableView" key="NSTableView" id="845451530">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrameSize">{13, 0}</string>
|
||||
<string key="NSFrameSize">{15, 0}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:24</string>
|
||||
|
@ -508,7 +526,7 @@
|
|||
<bool key="NSControlAllowsExpansionToolTips">YES</bool>
|
||||
<array class="NSMutableArray" key="NSTableColumns">
|
||||
<object class="NSTableColumn">
|
||||
<double key="NSWidth">10</double>
|
||||
<double key="NSWidth">12</double>
|
||||
<double key="NSMinWidth">10</double>
|
||||
<double key="NSMaxWidth">1000</double>
|
||||
<object class="NSTableHeaderCell" key="NSHeaderCell">
|
||||
|
@ -559,7 +577,7 @@
|
|||
</object>
|
||||
<double key="NSRowHeight">19</double>
|
||||
<string key="NSAction">tableViewAction:</string>
|
||||
<int key="NSTvFlags">-765427712</int>
|
||||
<int key="NSTvFlags">-767524864</int>
|
||||
<reference key="NSDelegate" ref="50876060"/>
|
||||
<reference key="NSDataSource" ref="50876060"/>
|
||||
<reference key="NSTarget" ref="50876060"/>
|
||||
|
@ -578,7 +596,6 @@
|
|||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{180, 13}, {82, 32}}</string>
|
||||
<reference key="NSSuperview" ref="327272550"/>
|
||||
<reference key="NSWindow"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSButtonCell" key="NSCell" id="404714727">
|
||||
|
@ -599,8 +616,6 @@
|
|||
</object>
|
||||
</array>
|
||||
<string key="NSFrameSize">{276, 89}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="981013832"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:21</string>
|
||||
</object>
|
||||
|
@ -787,6 +802,14 @@
|
|||
</object>
|
||||
<int key="connectionID">584</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBActionConnection" key="connection">
|
||||
<string key="label">showCoresDirectory:</string>
|
||||
<reference key="source" ref="976324537"/>
|
||||
<reference key="destination" ref="777071989"/>
|
||||
</object>
|
||||
<int key="connectionID">588</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
|
@ -823,6 +846,7 @@
|
|||
<reference ref="379814623"/>
|
||||
<reference ref="448692316"/>
|
||||
<reference ref="265357942"/>
|
||||
<reference ref="1225315"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
|
@ -1339,6 +1363,27 @@
|
|||
<reference key="object" ref="257009827"/>
|
||||
<reference key="parent" ref="835318025"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">585</int>
|
||||
<reference key="object" ref="1225315"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="715293634"/>
|
||||
</array>
|
||||
<reference key="parent" ref="649796088"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">586</int>
|
||||
<reference key="object" ref="715293634"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="777071989"/>
|
||||
</array>
|
||||
<reference key="parent" ref="1225315"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">587</int>
|
||||
<reference key="object" ref="777071989"/>
|
||||
<reference key="parent" ref="715293634"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
|
@ -1417,6 +1462,9 @@
|
|||
<string key="579.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="582.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="585.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="586.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="587.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="73.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
|
@ -1428,7 +1476,7 @@
|
|||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">584</int>
|
||||
<int key="maxID">588</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
|
@ -1443,6 +1491,39 @@
|
|||
<object class="IBPartialClassDescription">
|
||||
<string key="className">RetroArch_OSX</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<dictionary class="NSMutableDictionary" key="actions">
|
||||
<string key="coreWasChosen:">id</string>
|
||||
<string key="showCoresDirectory:">id</string>
|
||||
<string key="showPreferences:">id</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="actionInfosByName">
|
||||
<object class="IBActionInfo" key="coreWasChosen:">
|
||||
<string key="name">coreWasChosen:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="showCoresDirectory:">
|
||||
<string key="name">showCoresDirectory:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="showPreferences:">
|
||||
<string key="name">showPreferences:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="_coreSelectSheet">NSWindow</string>
|
||||
<string key="window">NSWindow</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="_coreSelectSheet">
|
||||
<string key="name">_coreSelectSheet</string>
|
||||
<string key="candidateClassName">NSWindow</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="window">
|
||||
<string key="name">window</string>
|
||||
<string key="candidateClassName">NSWindow</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/RetroArch_OSX.h</string>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,14 +14,44 @@
|
|||
*/
|
||||
|
||||
#include <IOKit/hid/IOHIDManager.h>
|
||||
#include "../RetroArch/apple_input.h"
|
||||
#include "apple/common/apple_input.h"
|
||||
|
||||
// NOTE: I pieced this together through trial and error, any corrections are welcome
|
||||
|
||||
static IOHIDManagerRef g_hid_manager;
|
||||
static uint32_t g_num_pads;
|
||||
static uint32_t g_pad_slots;
|
||||
|
||||
static void hid_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef)
|
||||
#define HID_ISSET(t, x) (t & (1 << x))
|
||||
#define HID_SET(t, x) { t |= (1 << x); }
|
||||
#define HID_CLEAR(t, x) { t &= ~(1 << x); }
|
||||
|
||||
// Set the LEDs on PS3 controllers, if slot >= MAX_PADS the LEDs will be cleared
|
||||
static void osx_pad_set_leds(IOHIDDeviceRef device, uint32_t slot)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
CFStringRef device_name = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
||||
if (device_name)
|
||||
{
|
||||
CFStringGetCString(device_name, buffer, 1024, kCFStringEncodingUTF8);
|
||||
|
||||
if (strncmp(buffer, "PLAYSTATION(R)3 Controller", 1024) == 0)
|
||||
{
|
||||
static uint8_t report_buffer[] = {
|
||||
0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x27,
|
||||
0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00,
|
||||
0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
report_buffer[10] = (slot >= MAX_PADS) ? 0 : (1 << (slot + 1));
|
||||
|
||||
IOHIDDeviceSetReport(device, kIOHIDReportTypeOutput, 0x01, report_buffer, sizeof(report_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void hid_device_input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef inIOHIDValueRef)
|
||||
{
|
||||
IOHIDElementRef element = IOHIDValueGetElement(inIOHIDValueRef);
|
||||
IOHIDDeviceRef device = IOHIDElementGetDevice(element);
|
||||
|
@ -82,25 +112,49 @@ static void hid_input_callback(void* inContext, IOReturn inResult, void* inSende
|
|||
}
|
||||
}
|
||||
|
||||
static void hid_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice)
|
||||
static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender)
|
||||
{
|
||||
void* context = 0;
|
||||
IOHIDDeviceRef inDevice = (IOHIDDeviceRef)inSender;
|
||||
|
||||
if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
{
|
||||
if (g_num_pads > 4)
|
||||
return;
|
||||
context = (void*)(g_num_pads++);
|
||||
uint32_t pad_index = (uint32_t)inContext;
|
||||
|
||||
if (pad_index < MAX_PADS)
|
||||
{
|
||||
HID_CLEAR(g_pad_slots, pad_index);
|
||||
|
||||
g_current_input_data.pad_buttons[pad_index] = 0;
|
||||
memset(g_current_input_data.pad_axis[pad_index], 0, sizeof(g_current_input_data.pad_axis));
|
||||
}
|
||||
}
|
||||
|
||||
IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDDeviceRegisterInputValueCallback(inDevice, hid_input_callback, context);
|
||||
osx_pad_set_leds(inDevice, MAX_PADS);
|
||||
IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone);
|
||||
}
|
||||
|
||||
static void hid_device_removed(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice)
|
||||
static void hid_manager_device_attached(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inDevice)
|
||||
{
|
||||
IOHIDDeviceClose(inDevice, kIOHIDOptionsTypeNone);
|
||||
uint32_t pad_index = 0;
|
||||
if (IOHIDDeviceConformsTo(inDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
|
||||
{
|
||||
if ((g_pad_slots & 0xF) == 0xF)
|
||||
return;
|
||||
|
||||
for (pad_index = 0; pad_index != MAX_PADS; pad_index ++)
|
||||
if (!HID_ISSET(g_pad_slots, pad_index))
|
||||
{
|
||||
HID_SET(g_pad_slots, pad_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IOHIDDeviceOpen(inDevice, kIOHIDOptionsTypeNone);
|
||||
IOHIDDeviceScheduleWithRunLoop(inDevice, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
IOHIDDeviceRegisterInputValueCallback(inDevice, hid_device_input_callback, (void*)pad_index);
|
||||
IOHIDDeviceRegisterRemovalCallback(inDevice, hid_device_removed, (void*)pad_index);
|
||||
|
||||
osx_pad_set_leds(inDevice, pad_index);
|
||||
}
|
||||
|
||||
static CFMutableDictionaryRef build_matching_dictionary(uint32_t page, uint32_t use)
|
||||
|
@ -137,9 +191,8 @@ void osx_pad_init()
|
|||
IOHIDManagerSetDeviceMatchingMultiple(g_hid_manager, matcher);
|
||||
CFRelease(matcher);
|
||||
|
||||
IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_device_attached, 0);
|
||||
IOHIDManagerRegisterDeviceRemovalCallback(g_hid_manager, hid_device_removed, 0);
|
||||
IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDManagerRegisterDeviceMatchingCallback(g_hid_manager, hid_manager_device_attached, 0);
|
||||
IOHIDManagerScheduleWithRunLoop(g_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
|
||||
|
||||
IOHIDManagerOpen(g_hid_manager, kIOHIDOptionsTypeNone);
|
||||
}
|
||||
|
@ -150,7 +203,7 @@ void osx_pad_quit()
|
|||
if (g_hid_manager)
|
||||
{
|
||||
IOHIDManagerClose(g_hid_manager, kIOHIDOptionsTypeNone);
|
||||
IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDManagerUnscheduleFromRunLoop(g_hid_manager, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
|
||||
|
||||
CFRelease(g_hid_manager);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file;
|
||||
- (void)unloadingCore:(RAModuleInfo*)core;
|
||||
|
||||
@property (strong, nonatomic) NSString* configDirectory; // e.g. /var/mobile/Documents/.RetroArch
|
||||
@property (strong, nonatomic) NSString* globalConfigFile; // e.g. /var/mobile/Documents/.RetroArch/retroarch.cfg
|
||||
@property (strong, nonatomic) NSString* coreDirectory; // e.g. /Applications/RetroArch.app/modules
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,15 +18,7 @@
|
|||
|
||||
#import "RetroArch_Apple.h"
|
||||
#include "rarch_wrapper.h"
|
||||
#include "../RetroArch/apple_input.h"
|
||||
|
||||
// If USE_XATTR is defined any loaded file will get a com.RetroArch.Core extended attribute
|
||||
// specifying which core was used to load.
|
||||
//#define USE_XATTR
|
||||
|
||||
#if defined(USE_XATTR)
|
||||
#include "sys/xattr.h"
|
||||
#endif
|
||||
#include "apple/common/apple_input.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
|
@ -66,6 +58,11 @@
|
|||
apple_platform = self;
|
||||
_loaded = true;
|
||||
|
||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
self.configDirectory = [paths[0] stringByAppendingPathComponent:@"RetroArch"];
|
||||
self.globalConfigFile = [NSString stringWithFormat:@"%@/retroarch.cfg", self.configDirectory];
|
||||
self.coreDirectory = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Contents/Resources/modules"];
|
||||
|
||||
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
|
||||
RAGameView.get.frame = [window.contentView bounds];
|
||||
|
@ -76,16 +73,16 @@
|
|||
// Create core select list
|
||||
NSComboBox* cb = (NSComboBox*)[_coreSelectSheet.contentView viewWithTag:1];
|
||||
|
||||
for (RAModuleInfo* i in RAModuleInfo.getModules)
|
||||
for (RAModuleInfo* i in apple_get_modules())
|
||||
[cb addItemWithObjectValue:i];
|
||||
|
||||
if (cb.numberOfItems)
|
||||
[cb selectItemAtIndex:0];
|
||||
else
|
||||
apple_display_alert(@"No libretro cores were found.", @"RetroArch");
|
||||
apple_display_alert(@"No libretro cores were found.\nSelect \"Go->Cores Directory\" from the menu and place libretro dylib files there.", @"RetroArch");
|
||||
|
||||
// Run RGUI if needed
|
||||
if (!_wantReload)
|
||||
if (!_wantReload || apple_argv)
|
||||
apple_run_core(nil, 0);
|
||||
else
|
||||
[self chooseCore];
|
||||
|
@ -162,23 +159,6 @@
|
|||
|
||||
- (void)chooseCore
|
||||
{
|
||||
#ifdef USE_XATTR
|
||||
char stored_name[PATH_MAX];
|
||||
if (getxattr(_file.UTF8String, "com.RetroArch.Core", stored_name, PATH_MAX, 0, 0) > 0)
|
||||
{
|
||||
for (RAModuleInfo* i in RAModuleInfo.getModules)
|
||||
{
|
||||
const char* core_name = i.path.lastPathComponent.UTF8String;
|
||||
if (strcmp(core_name, stored_name) == 0)
|
||||
{
|
||||
_core = i;
|
||||
[self runCore];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[NSApplication.sharedApplication beginSheet:_coreSelectSheet modalForWindow:window modalDelegate:nil didEndSelector:nil contextInfo:nil];
|
||||
[NSApplication.sharedApplication runModalForWindow:_coreSelectSheet];
|
||||
}
|
||||
|
@ -202,14 +182,7 @@
|
|||
- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file
|
||||
{
|
||||
if (file)
|
||||
{
|
||||
[NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:file]]];
|
||||
|
||||
#ifdef USE_XATTR
|
||||
const char* core_name = core.path.lastPathComponent.UTF8String;
|
||||
setxattr(file, "com.RetroArch.Core", core_name, strlen(core_name) + 1, 0, 0);
|
||||
#endif
|
||||
}
|
||||
[NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:[NSURL fileURLWithPath:@(file)]];
|
||||
}
|
||||
|
||||
- (void)unloadingCore:(RAModuleInfo*)core
|
||||
|
@ -227,21 +200,16 @@
|
|||
_wantReload = false;
|
||||
}
|
||||
|
||||
- (NSString*)retroarchConfigPath
|
||||
{
|
||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
return [paths[0] stringByAppendingPathComponent:@"RetroArch"];
|
||||
}
|
||||
|
||||
- (NSString*)corePath
|
||||
{
|
||||
return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"Contents/Resources/modules"];
|
||||
}
|
||||
|
||||
#pragma mark Menus
|
||||
- (IBAction)showCoresDirectory:(id)sender
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] openFile:self.coreDirectory];
|
||||
}
|
||||
|
||||
- (IBAction)showPreferences:(id)sender
|
||||
{
|
||||
[[[NSWindowController alloc] initWithWindowNibName:@"Settings"] window];
|
||||
NSWindowController* wc = [[NSWindowController alloc] initWithWindowNibName:@"Settings"];
|
||||
[NSApp runModalForWindow:wc.window];
|
||||
}
|
||||
|
||||
- (IBAction)basicEvent:(id)sender
|
||||
|
@ -259,6 +227,23 @@
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t current_argc = 0;
|
||||
|
||||
for (int i = 0; i != argc; i ++)
|
||||
{
|
||||
if (strcmp(argv[i], "--") == 0)
|
||||
{
|
||||
current_argc = 1;
|
||||
apple_argv = malloc(sizeof(char*) * (argc + 1));
|
||||
memset(apple_argv, 0, sizeof(char*) * (argc + 1));
|
||||
apple_argv[0] = argv[0];
|
||||
}
|
||||
else if (current_argc)
|
||||
{
|
||||
apple_argv[current_argc ++] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NSApplicationMain(argc, (const char **) argv);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,272 @@
|
|||
*/
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import "../RetroArch/RetroArch_Apple.h"
|
||||
#include "../RetroArch/setting_data.h"
|
||||
#import "apple/common/RetroArch_Apple.h"
|
||||
#include "apple/common/setting_data.h"
|
||||
#include "apple/common/apple_input.h"
|
||||
|
||||
#include "driver.h"
|
||||
#include "input/input_common.h"
|
||||
|
||||
struct settings fake_settings;
|
||||
struct global fake_extern;
|
||||
|
||||
static const void* associated_name_tag = (void*)&associated_name_tag;
|
||||
|
||||
#define BINDFOR(s) (*(struct retro_keybind*)(&s)->value)
|
||||
|
||||
static const char* key_name_for_id(uint32_t hidkey)
|
||||
{
|
||||
for (int i = 0; apple_key_name_map[i].hid_id; i ++)
|
||||
if (apple_key_name_map[i].hid_id == hidkey)
|
||||
return apple_key_name_map[i].keyname;
|
||||
|
||||
return "nul";
|
||||
}
|
||||
|
||||
static uint32_t key_id_for_name(const char* name)
|
||||
{
|
||||
for (int i = 0; apple_key_name_map[i].hid_id; i ++)
|
||||
if (strcmp(name, apple_key_name_map[i].keyname) == 0)
|
||||
return apple_key_name_map[i].hid_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define key_name_for_rk(X) key_name_for_id(input_translate_rk_to_keysym(X))
|
||||
#define key_rk_for_name(X) input_translate_keysym_to_rk(key_id_for_name(X))
|
||||
|
||||
static const char* get_input_config_key(const rarch_setting_t* setting, const char* type)
|
||||
{
|
||||
static char buffer[32];
|
||||
if (setting->input_player)
|
||||
snprintf(buffer, 32, "input_player%d_%s%c%s", setting->input_player, setting->name, type ? '_' : '\0', type);
|
||||
else
|
||||
snprintf(buffer, 32, "input_%s%c%s", setting->name, type ? '_' : '\0', type);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char* get_button_name(const rarch_setting_t* setting)
|
||||
{
|
||||
static char buffer[32];
|
||||
|
||||
if (BINDFOR(*setting).joykey == NO_BTN)
|
||||
return "nul";
|
||||
|
||||
snprintf(buffer, 32, "%lld", BINDFOR(*setting).joykey);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char* get_axis_name(const rarch_setting_t* setting)
|
||||
{
|
||||
static char buffer[32];
|
||||
|
||||
uint32_t joyaxis = BINDFOR(*setting).joyaxis;
|
||||
|
||||
if (AXIS_NEG_GET(joyaxis) != AXIS_DIR_NONE)
|
||||
snprintf(buffer, 8, "-%d", AXIS_NEG_GET(joyaxis));
|
||||
else if (AXIS_POS_GET(joyaxis) != AXIS_DIR_NONE)
|
||||
snprintf(buffer, 8, "+%d", AXIS_POS_GET(joyaxis));
|
||||
else
|
||||
return "nul";
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@interface RANumberFormatter : NSNumberFormatter
|
||||
@end
|
||||
|
||||
@implementation RANumberFormatter
|
||||
- (id)initWithFloatSupport:(bool)allowFloat minimum:(double)min maximum:(double)max
|
||||
{
|
||||
self = [super init];
|
||||
self.allowsFloats = allowFloat;
|
||||
self.maximumFractionDigits = 10;
|
||||
|
||||
if (min || max)
|
||||
{
|
||||
self.minimum = @(min);
|
||||
self.maximum = @(max);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error
|
||||
{
|
||||
bool hasDot = false;
|
||||
|
||||
if (partialString.length)
|
||||
for (int i = 0; i != partialString.length; i ++)
|
||||
{
|
||||
unichar ch = [partialString characterAtIndex:i];
|
||||
|
||||
if (i == 0 && (!self.minimum || self.minimum.intValue < 0) && ch == '-')
|
||||
continue;
|
||||
else if (self.allowsFloats && !hasDot && ch == '.')
|
||||
hasDot = true;
|
||||
else if (!isdigit(ch))
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface RAInputBinder : NSWindow
|
||||
@end
|
||||
|
||||
@implementation RAInputBinder
|
||||
|
||||
- (IBAction)goAway:(id)sender
|
||||
{
|
||||
[NSApp endSheet:self];
|
||||
[self orderOut:nil];
|
||||
}
|
||||
|
||||
// Stop the annoying sound when pressing a key
|
||||
- (void)keyDown:(NSEvent*)theEvent
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RASettingCell : NSTableCellView
|
||||
@property (nonatomic) const rarch_setting_t* setting;
|
||||
|
||||
@property (nonatomic) NSString* stringValue;
|
||||
@property (nonatomic) IBOutlet NSNumber* numericValue;
|
||||
@property (nonatomic) bool booleanValue;
|
||||
|
||||
@property (nonatomic) NSTimer* bindTimer;
|
||||
@end
|
||||
|
||||
@implementation RASettingCell
|
||||
- (void)setSetting:(const rarch_setting_t *)aSetting
|
||||
{
|
||||
_setting = aSetting;
|
||||
|
||||
if (!_setting)
|
||||
return;
|
||||
|
||||
if (aSetting->type == ST_INT || aSetting->type == ST_FLOAT)
|
||||
{
|
||||
self.textField.formatter = [[RANumberFormatter alloc] initWithFloatSupport:aSetting->type == ST_FLOAT
|
||||
minimum:aSetting->min
|
||||
maximum:aSetting->max];
|
||||
}
|
||||
else
|
||||
self.textField.formatter = nil;
|
||||
|
||||
// Set value
|
||||
switch (aSetting->type)
|
||||
{
|
||||
case ST_INT: self.numericValue = @(*(int*)aSetting->value); break;
|
||||
case ST_FLOAT: self.numericValue = @(*(float*)aSetting->value); break;
|
||||
case ST_STRING: self.stringValue = @((const char*)aSetting->value); break;
|
||||
case ST_PATH: self.stringValue = @((const char*)aSetting->value); break;
|
||||
case ST_BOOL: self.booleanValue = *(bool*)aSetting->value; break;
|
||||
case ST_BIND: [self updateInputString]; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)doBrowse:(id)sender
|
||||
{
|
||||
NSOpenPanel* panel = [NSOpenPanel new];
|
||||
[panel runModal];
|
||||
|
||||
if (panel.URLs.count == 1)
|
||||
self.stringValue = panel.URL.path;
|
||||
}
|
||||
|
||||
- (void)setNumericValue:(NSNumber *)numericValue
|
||||
{
|
||||
_numericValue = numericValue;
|
||||
|
||||
if (_setting && _setting->type == ST_INT)
|
||||
*(int*)_setting->value = _numericValue.intValue;
|
||||
else if (_setting && _setting->type == ST_FLOAT)
|
||||
*(float*)_setting->value = _numericValue.floatValue;
|
||||
}
|
||||
|
||||
- (void)setBooleanValue:(bool)booleanValue
|
||||
{
|
||||
_booleanValue = booleanValue;
|
||||
|
||||
if (_setting && _setting->type == ST_BOOL)
|
||||
*(bool*)_setting->value = _booleanValue;
|
||||
}
|
||||
|
||||
- (void)setStringValue:(NSString *)stringValue
|
||||
{
|
||||
_stringValue = stringValue ? stringValue : @"";
|
||||
|
||||
if (_setting && (_setting->type == ST_STRING || _setting->type == ST_PATH))
|
||||
strlcpy(_setting->value, _stringValue.UTF8String, _setting->size);
|
||||
}
|
||||
|
||||
// Input Binding
|
||||
- (void)updateInputString
|
||||
{
|
||||
self.stringValue = [NSString stringWithFormat:@"[KB:%s] [JS:%s] [AX:%s]", key_name_for_rk(BINDFOR(*_setting).key),
|
||||
get_button_name(_setting),
|
||||
get_axis_name(_setting)];
|
||||
}
|
||||
|
||||
- (void)dismissBinder
|
||||
{
|
||||
[self.bindTimer invalidate];
|
||||
self.bindTimer = nil;
|
||||
|
||||
[self updateInputString];
|
||||
|
||||
[(id)self.window.attachedSheet goAway:nil];
|
||||
}
|
||||
|
||||
- (void)checkBind:(NSTimer*)send
|
||||
{
|
||||
int32_t value = 0;
|
||||
|
||||
if ((value = apple_input_find_any_key()))
|
||||
BINDFOR(*_setting).key = input_translate_keysym_to_rk(value);
|
||||
else if ((value = apple_input_find_any_button(0)) >= 0)
|
||||
BINDFOR(*_setting).joykey = value;
|
||||
else if ((value = apple_input_find_any_axis(0)))
|
||||
BINDFOR(*_setting).joyaxis = (value > 0) ? AXIS_POS(value - 1) : AXIS_NEG(value - 1);
|
||||
else
|
||||
return;
|
||||
|
||||
[self dismissBinder];
|
||||
}
|
||||
|
||||
- (IBAction)doGetBind:(id)sender
|
||||
{
|
||||
static NSWindowController* controller;
|
||||
if (!controller)
|
||||
controller = [[NSWindowController alloc] initWithWindowNibName:@"InputBinder"];
|
||||
|
||||
self.bindTimer = [NSTimer timerWithTimeInterval:.1f target:self selector:@selector(checkBind:) userInfo:nil repeats:YES];
|
||||
[[NSRunLoop currentRunLoop] addTimer:self.bindTimer forMode:NSModalPanelRunLoopMode];
|
||||
|
||||
[NSApp beginSheet:controller.window modalForWindow:self.window modalDelegate:nil didEndSelector:nil contextInfo:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@protocol RASettingView
|
||||
@property const rarch_setting_t* setting;
|
||||
@end
|
||||
|
||||
@interface RASettingsDelegate : NSObject<NSTableViewDataSource, NSTableViewDelegate,
|
||||
NSOutlineViewDataSource, NSOutlineViewDelegate>
|
||||
NSOutlineViewDataSource, NSOutlineViewDelegate,
|
||||
NSWindowDelegate>
|
||||
@end
|
||||
|
||||
@implementation RASettingsDelegate
|
||||
{
|
||||
NSWindow IBOutlet* _window;
|
||||
NSWindow IBOutlet* _inputWindow;
|
||||
NSTableView IBOutlet* _table;
|
||||
NSOutlineView IBOutlet* _outline;
|
||||
|
||||
|
@ -33,10 +289,15 @@
|
|||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
apple_enter_stasis();
|
||||
|
||||
NSMutableArray* thisGroup = nil;
|
||||
NSMutableArray* thisSubGroup = nil;
|
||||
_settings = [NSMutableArray array];
|
||||
|
||||
|
||||
memcpy(&fake_settings, &g_settings, sizeof(struct settings));
|
||||
memcpy(&fake_extern, &g_extern, sizeof(struct global));
|
||||
|
||||
for (int i = 0; setting_data[i].type; i ++)
|
||||
{
|
||||
switch (setting_data[i].type)
|
||||
|
@ -44,7 +305,7 @@
|
|||
case ST_GROUP:
|
||||
{
|
||||
thisGroup = [NSMutableArray array];
|
||||
objc_setAssociatedObject(thisGroup, "NAME", [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
objc_setAssociatedObject(thisGroup, associated_name_tag, [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -58,7 +319,7 @@
|
|||
case ST_SUB_GROUP:
|
||||
{
|
||||
thisSubGroup = [NSMutableArray array];
|
||||
objc_setAssociatedObject(thisSubGroup, "NAME", [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
objc_setAssociatedObject(thisSubGroup, associated_name_tag, [NSString stringWithFormat:@"%s", setting_data[i].name], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -77,49 +338,81 @@
|
|||
}
|
||||
}
|
||||
|
||||
[NSApplication.sharedApplication beginSheet:_window modalForWindow:RetroArch_OSX.get->window modalDelegate:nil didEndSelector:nil contextInfo:nil];
|
||||
[NSApplication.sharedApplication runModalForWindow:_window];
|
||||
[self load];
|
||||
}
|
||||
|
||||
- (IBAction)close:(id)sender
|
||||
- (void)load
|
||||
{
|
||||
[NSApplication.sharedApplication stopModal];
|
||||
[NSApplication.sharedApplication endSheet:_window returnCode:0];
|
||||
[_window orderOut:nil];
|
||||
config_file_t* conf = config_file_new(apple_platform.globalConfigFile.UTF8String);
|
||||
|
||||
for (int i = 0; setting_data[i].type; i ++)
|
||||
{
|
||||
switch (setting_data[i].type)
|
||||
{
|
||||
case ST_BOOL: config_get_bool (conf, setting_data[i].name, (bool*)setting_data[i].value); break;
|
||||
case ST_INT: config_get_int (conf, setting_data[i].name, (int*)setting_data[i].value); break;
|
||||
case ST_FLOAT: config_get_float (conf, setting_data[i].name, (float*)setting_data[i].value); break;
|
||||
case ST_PATH: config_get_array (conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break;
|
||||
case ST_STRING: config_get_array (conf, setting_data[i].name, (char*)setting_data[i].value, setting_data[i].size); break;
|
||||
|
||||
case ST_BIND:
|
||||
{
|
||||
input_config_parse_key (conf, "input_player1", setting_data[i].name, setting_data[i].value);
|
||||
input_config_parse_joy_button(conf, "input_player1", setting_data[i].name, setting_data[i].value);
|
||||
input_config_parse_joy_axis (conf, "input_player1", setting_data[i].name, setting_data[i].value);
|
||||
break;
|
||||
}
|
||||
|
||||
case ST_HEX: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
config_file_free(conf);
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
config_file_t* conf = config_file_new(apple_platform.globalConfigFile.UTF8String);
|
||||
conf = conf ? conf : config_file_new(0);
|
||||
|
||||
for (int i = 0; setting_data[i].type; i ++)
|
||||
{
|
||||
switch (setting_data[i].type)
|
||||
{
|
||||
case ST_BOOL: config_set_bool (conf, setting_data[i].name, * (bool*)setting_data[i].value); break;
|
||||
case ST_INT: config_set_int (conf, setting_data[i].name, * (int*)setting_data[i].value); break;
|
||||
case ST_FLOAT: config_set_float (conf, setting_data[i].name, *(float*)setting_data[i].value); break;
|
||||
case ST_PATH: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break;
|
||||
case ST_STRING: config_set_string(conf, setting_data[i].name, (char*)setting_data[i].value); break;
|
||||
|
||||
case ST_BIND:
|
||||
{
|
||||
config_set_string(conf, get_input_config_key(&setting_data[i], 0 ), key_name_for_rk(BINDFOR(setting_data[i]).key));
|
||||
config_set_string(conf, get_input_config_key(&setting_data[i], "btn" ), get_button_name(&setting_data[i]));
|
||||
config_set_string(conf, get_input_config_key(&setting_data[i], "axis"), get_axis_name(&setting_data[i]));
|
||||
break;
|
||||
}
|
||||
|
||||
case ST_HEX: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
config_file_write(conf, apple_platform.globalConfigFile.UTF8String);
|
||||
config_file_free(conf);
|
||||
|
||||
apple_exit_stasis(true);
|
||||
|
||||
[NSApp stopModal];
|
||||
}
|
||||
|
||||
#pragma mark View Builders
|
||||
- (NSView*)labelAccessoryFor:(NSString*)text onTable:(NSTableView*)table
|
||||
{
|
||||
NSTextField* result = [table makeViewWithIdentifier:@"label" owner:self];
|
||||
if (result == nil)
|
||||
{
|
||||
result = [NSTextField new];
|
||||
result.bordered = NO;
|
||||
result.drawsBackground = NO;
|
||||
result.identifier = @"label";
|
||||
}
|
||||
|
||||
RASettingCell* result = [table makeViewWithIdentifier:@"RALabelSetting" owner:nil];
|
||||
result.stringValue = text;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSView*)booleanAccessoryFor:(const rarch_setting_t*)setting onTable:(NSTableView*)table
|
||||
{
|
||||
NSButton* result = [table makeViewWithIdentifier:@"boolean" owner:self];
|
||||
|
||||
if (!result)
|
||||
{
|
||||
result = [NSButton new];
|
||||
result.buttonType = NSSwitchButton;
|
||||
result.title = @"";
|
||||
}
|
||||
|
||||
result.state = *(bool*)setting->value;
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma mark Section Table
|
||||
- (NSInteger)numberOfRowsInTableView:(NSTableView*)view
|
||||
{
|
||||
|
@ -128,7 +421,7 @@
|
|||
|
||||
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
||||
{
|
||||
return [self labelAccessoryFor:objc_getAssociatedObject(_settings[row], "NAME") onTable:tableView];
|
||||
return [self labelAccessoryFor:objc_getAssociatedObject(_settings[row], associated_name_tag) onTable:tableView];
|
||||
}
|
||||
|
||||
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
|
||||
|
@ -153,12 +446,16 @@
|
|||
return [item isKindOfClass:[NSArray class]];
|
||||
}
|
||||
|
||||
- (BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
|
||||
{
|
||||
if ([item isKindOfClass:[NSArray class]])
|
||||
{
|
||||
if ([tableColumn.identifier isEqualToString:@"title"])
|
||||
return [self labelAccessoryFor:objc_getAssociatedObject(item, "NAME") onTable:outlineView];
|
||||
return [self labelAccessoryFor:objc_getAssociatedObject(item, associated_name_tag) onTable:outlineView];
|
||||
else
|
||||
return [self labelAccessoryFor:[NSString stringWithFormat:@"%d items", (int)[item count]] onTable:outlineView];
|
||||
}
|
||||
|
@ -167,25 +464,22 @@
|
|||
const rarch_setting_t* setting = &setting_data[[item intValue]];
|
||||
|
||||
if ([tableColumn.identifier isEqualToString:@"title"])
|
||||
return [self labelAccessoryFor:[NSString stringWithFormat:@"%s", setting->short_description] onTable:outlineView]; // < The outlineView will fill the value
|
||||
return [self labelAccessoryFor:@(setting->short_description) onTable:outlineView];
|
||||
else if([tableColumn.identifier isEqualToString:@"accessory"])
|
||||
{
|
||||
RASettingCell* s = nil;
|
||||
switch (setting->type)
|
||||
{
|
||||
case ST_BOOL: return [self booleanAccessoryFor:setting onTable:outlineView];
|
||||
|
||||
case ST_PATH:
|
||||
case ST_STRING:
|
||||
return [self labelAccessoryFor:[NSString stringWithFormat:@"%s", (const char*)setting->value] onTable:outlineView];
|
||||
|
||||
case ST_INT:
|
||||
return [self labelAccessoryFor:[NSString stringWithFormat:@"%d", *(int*)setting->value] onTable:outlineView];
|
||||
|
||||
case ST_FLOAT:
|
||||
return [self labelAccessoryFor:[NSString stringWithFormat:@"%f", *(float*)setting->value] onTable:outlineView];
|
||||
|
||||
default: abort();
|
||||
case ST_BOOL: s = [outlineView makeViewWithIdentifier:@"RABooleanSetting" owner:nil]; break;
|
||||
case ST_INT: s = [outlineView makeViewWithIdentifier:@"RANumericSetting" owner:nil]; break;
|
||||
case ST_FLOAT: s = [outlineView makeViewWithIdentifier:@"RANumericSetting" owner:nil]; break;
|
||||
case ST_PATH: s = [outlineView makeViewWithIdentifier:@"RAPathSetting" owner:nil]; break;
|
||||
case ST_STRING: s = [outlineView makeViewWithIdentifier:@"RAStringSetting" owner:nil]; break;
|
||||
case ST_BIND: s = [outlineView makeViewWithIdentifier:@"RABindSetting" owner:nil]; break;
|
||||
default: break;
|
||||
}
|
||||
s.setting = setting;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
/* Begin PBXBuildFile section */
|
||||
9620F663178FD4D3001B3B81 /* settings.m in Sources */ = {isa = PBXBuildFile; fileRef = 9620F662178FD4D3001B3B81 /* settings.m */; };
|
||||
9620F6651790004F001B3B81 /* Settings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9620F6641790004F001B3B81 /* Settings.xib */; };
|
||||
962EE0E2178B3DF6004224FF /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 962EE0E1178B3DF6004224FF /* IOKit.framework */; };
|
||||
96355CE31788E72A0010DBFA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96355CE21788E72A0010DBFA /* Cocoa.framework */; };
|
||||
9646869817BBC14E00C5EA69 /* platform.m in Sources */ = {isa = PBXBuildFile; fileRef = 9646869617BBC14E00C5EA69 /* platform.m */; };
|
||||
964DE7C117D84B34001CBB6C /* InputBinder.xib in Resources */ = {isa = PBXBuildFile; fileRef = 964DE7C317D84B34001CBB6C /* InputBinder.xib */; };
|
||||
964DE7C417D84B57001CBB6C /* Settings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 964DE7C617D84B57001CBB6C /* Settings.xib */; };
|
||||
967894931788ECDB00D6CA69 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9678948F1788ECDB00D6CA69 /* InfoPlist.strings */; };
|
||||
967894941788ECDB00D6CA69 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 967894911788ECDB00D6CA69 /* MainMenu.xib */; };
|
||||
967894961788ED1100D6CA69 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 967894951788ED1100D6CA69 /* main.m */; };
|
||||
|
@ -29,7 +30,6 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
9620F662178FD4D3001B3B81 /* settings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = settings.m; path = OSX/settings.m; sourceTree = SOURCE_ROOT; };
|
||||
9620F6641790004F001B3B81 /* Settings.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = Settings.xib; path = OSX/Settings.xib; sourceTree = "<group>"; };
|
||||
962EE0E1178B3DF6004224FF /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = ../../../../../../../System/Library/Frameworks/IOKit.framework; sourceTree = "<group>"; };
|
||||
96355CDF1788E72A0010DBFA /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
96355CE21788E72A0010DBFA /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
|
@ -38,6 +38,8 @@
|
|||
96355CE71788E72A0010DBFA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
9646869617BBC14E00C5EA69 /* platform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = platform.m; path = OSX/platform.m; sourceTree = SOURCE_ROOT; };
|
||||
9646869717BBC14E00C5EA69 /* platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = platform.h; path = OSX/platform.h; sourceTree = SOURCE_ROOT; };
|
||||
964DE7C217D84B34001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file; name = en; path = en.lproj/InputBinder.xib; sourceTree = "<group>"; };
|
||||
964DE7C517D84B57001CBB6C /* en */ = {isa = PBXFileReference; lastKnownFileType = file; name = en; path = en.lproj/Settings.xib; sourceTree = "<group>"; };
|
||||
9678948D1788ECCA00D6CA69 /* RetroArch-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "RetroArch-Info.plist"; path = "OSX/RetroArch-Info.plist"; sourceTree = SOURCE_ROOT; };
|
||||
967894901788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; };
|
||||
967894921788ECDB00D6CA69 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = OSX/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -78,7 +80,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
962EE0E1178B3DF6004224FF /* IOKit.framework */,
|
||||
96355CE81788E72A0010DBFA /* RetroArch */,
|
||||
96355CE81788E72A0010DBFA /* common */,
|
||||
967894E7178A2E9B00D6CA69 /* Assets */,
|
||||
96355CE11788E72A0010DBFA /* Frameworks */,
|
||||
96355CE01788E72A0010DBFA /* Products */,
|
||||
|
@ -109,7 +111,7 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
96355CE81788E72A0010DBFA /* RetroArch */ = {
|
||||
96355CE81788E72A0010DBFA /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9646869617BBC14E00C5EA69 /* platform.m */,
|
||||
|
@ -124,7 +126,7 @@
|
|||
9678949C1788F02600D6CA69 /* utility.m */,
|
||||
967894951788ED1100D6CA69 /* main.m */,
|
||||
);
|
||||
path = RetroArch;
|
||||
path = common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
96355CE91788E72A0010DBFA /* Supporting Files */ = {
|
||||
|
@ -143,7 +145,8 @@
|
|||
967894E8178A2EB400D6CA69 /* modules */,
|
||||
967894911788ECDB00D6CA69 /* MainMenu.xib */,
|
||||
C15874EE178F2094001171D4 /* RetroArch.icns */,
|
||||
9620F6641790004F001B3B81 /* Settings.xib */,
|
||||
964DE7C617D84B57001CBB6C /* Settings.xib */,
|
||||
964DE7C317D84B34001CBB6C /* InputBinder.xib */,
|
||||
);
|
||||
name = Assets;
|
||||
sourceTree = "<group>";
|
||||
|
@ -202,7 +205,8 @@
|
|||
967894941788ECDB00D6CA69 /* MainMenu.xib in Resources */,
|
||||
967894E9178A2EB400D6CA69 /* modules in Resources */,
|
||||
C15874EF178F2094001171D4 /* RetroArch.icns in Resources */,
|
||||
9620F6651790004F001B3B81 /* Settings.xib in Resources */,
|
||||
964DE7C417D84B57001CBB6C /* Settings.xib in Resources */,
|
||||
964DE7C117D84B34001CBB6C /* InputBinder.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -226,6 +230,24 @@
|
|||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
964DE7C317D84B34001CBB6C /* InputBinder.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
964DE7C217D84B34001CBB6C /* en */,
|
||||
);
|
||||
name = InputBinder.xib;
|
||||
path = OSX;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
964DE7C617D84B57001CBB6C /* Settings.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
964DE7C517D84B57001CBB6C /* en */,
|
||||
);
|
||||
name = Settings.xib;
|
||||
path = OSX;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9678948F1788ECDB00D6CA69 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
|
@ -303,7 +325,6 @@
|
|||
"-DINLINE=inline",
|
||||
"-DLSB_FIRST",
|
||||
"-D__LIBRETRO__",
|
||||
"-DRARCH_PERFORMANCE_MODE",
|
||||
"-DWANT_RPNG",
|
||||
"-DHAVE_COREAUDIO",
|
||||
"-DHAVE_DYNAMIC",
|
||||
|
@ -349,23 +370,22 @@
|
|||
"-DHAVE_RARCH_MAIN_WRAP",
|
||||
"-DHAVE_GRIFFIN",
|
||||
"-DHAVE_RGUI",
|
||||
"-DIOS",
|
||||
"-DOSX",
|
||||
"-DHAVE_OPENGL",
|
||||
"-DHAVE_FBO",
|
||||
"-DHAVE_VID_CONTEXT",
|
||||
"-DHAVE_OPENGLES2",
|
||||
"-DHAVE_GLSL",
|
||||
"-DINLINE=inline",
|
||||
"-DLSB_FIRST",
|
||||
"-D__LIBRETRO__",
|
||||
"-DRARCH_PERFORMANCE_MODE",
|
||||
"-DRARCH_MOBILE",
|
||||
"-DWANT_RPNG",
|
||||
"-DHAVE_COREAUDIO",
|
||||
"-DHAVE_DYNAMIC",
|
||||
"-DHAVE_OVERLAY",
|
||||
"-DHAVE_ZLIB",
|
||||
"-DWANT_MINIZ",
|
||||
"-DSINC_LOWER_QUALITY",
|
||||
"-DHAVE_NETPLAY",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = "";
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
96AFAE1A16C1D4EA009DE44C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
96AFAE3316C1D4EA009DE44C /* RetroArch */,
|
||||
96AFAE3316C1D4EA009DE44C /* common */,
|
||||
96AFAE9C16C1D976009DE44C /* core */,
|
||||
966B9CB716E41E7A005B61E1 /* Assets */,
|
||||
96AFAE2816C1D4EA009DE44C /* Frameworks */,
|
||||
|
@ -151,7 +151,7 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
96AFAE3316C1D4EA009DE44C /* RetroArch */ = {
|
||||
96AFAE3316C1D4EA009DE44C /* common */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9646869417BBBEAE00C5EA69 /* platform.m */,
|
||||
|
@ -167,7 +167,7 @@
|
|||
96355CD11788CF190010DBFA /* RetroArch_Apple.h */,
|
||||
96337E81176AC6E5004685F3 /* utility.m */,
|
||||
);
|
||||
path = RetroArch;
|
||||
path = common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
96AFAE3416C1D4EA009DE44C /* Supporting Files */ = {
|
||||
|
@ -367,7 +367,6 @@
|
|||
"-DLSB_FIRST",
|
||||
"-DHAVE_THREAD",
|
||||
"-D__LIBRETRO__",
|
||||
"-DRARCH_PERFORMANCE_MODE",
|
||||
"-DRARCH_MOBILE",
|
||||
"-std=gnu99",
|
||||
"-DHAVE_COREAUDIO",
|
||||
|
@ -417,7 +416,6 @@
|
|||
"-DLSB_FIRST",
|
||||
"-DHAVE_THREAD",
|
||||
"-D__LIBRETRO__",
|
||||
"-DRARCH_PERFORMANCE_MODE",
|
||||
"-DRARCH_MOBILE",
|
||||
"-std=gnu99",
|
||||
"-DHAVE_COREAUDIO",
|
||||
|
@ -458,7 +456,6 @@
|
|||
"-DINLINE=inline",
|
||||
"-DLSB_FIRST",
|
||||
"-D__LIBRETRO__",
|
||||
"-DRARCH_PERFORMANCE_MODE",
|
||||
"-DRARCH_MOBILE",
|
||||
"-DHAVE_COREAUDIO",
|
||||
"-DHAVE_DYNAMIC",
|
||||
|
@ -501,7 +498,6 @@
|
|||
"-DINLINE=inline",
|
||||
"-DLSB_FIRST",
|
||||
"-D__LIBRETRO__",
|
||||
"-DRARCH_PERFORMANCE_MODE",
|
||||
"-DRARCH_MOBILE",
|
||||
"-DHAVE_COREAUDIO",
|
||||
"-DHAVE_DYNAMIC",
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "rarch_wrapper.h"
|
||||
|
||||
#include "general.h"
|
||||
#include "gfx/gfx_common.h"
|
||||
|
||||
#ifdef IOS
|
||||
|
||||
|
@ -33,6 +34,7 @@ static UIView* g_pause_indicator_view;
|
|||
|
||||
#include "apple_input.h"
|
||||
|
||||
static bool g_has_went_fullscreen;
|
||||
static RAGameView* g_instance;
|
||||
static NSOpenGLContext* g_context;
|
||||
static NSOpenGLPixelFormat* g_format;
|
||||
|
@ -312,6 +314,73 @@ void *apple_get_proc_address(const char *symbol_name)
|
|||
#endif
|
||||
}
|
||||
|
||||
void apple_update_window_title(void)
|
||||
{
|
||||
static char buf[128];
|
||||
bool got_text = gfx_get_fps(buf, sizeof(buf), false);
|
||||
#ifdef OSX
|
||||
static const char* const text = buf; // < Can't access buf directly in the block
|
||||
|
||||
if (got_text)
|
||||
{
|
||||
// NOTE: This could go bad if buf is updated again before this completes.
|
||||
// If it poses a problem it should be changed to dispatch_sync.
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
g_view.window.title = @(text);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool apple_game_view_has_focus(void)
|
||||
{
|
||||
#ifdef OSX
|
||||
return [NSApp isActive];
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen)
|
||||
{
|
||||
__block bool result = true;
|
||||
|
||||
#ifdef OSX
|
||||
dispatch_sync(dispatch_get_main_queue(),
|
||||
^{
|
||||
// TODO: Sceen mode support
|
||||
|
||||
if (fullscreen && !g_has_went_fullscreen)
|
||||
{
|
||||
if (g_settings.video.monitor_index >= [NSScreen screens].count)
|
||||
{
|
||||
apple_display_alert(@"Could not go fullscreen: Monitor index out of range.", nil);
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
[g_view enterFullScreenMode:[NSScreen screens][g_settings.video.monitor_index] withOptions:nil];
|
||||
[NSCursor hide];
|
||||
}
|
||||
else if (!fullscreen && g_has_went_fullscreen)
|
||||
{
|
||||
[g_view exitFullScreenModeWithOptions:nil];
|
||||
[g_view.window makeFirstResponder:g_view];
|
||||
[NSCursor unhide];
|
||||
}
|
||||
|
||||
g_has_went_fullscreen = fullscreen;
|
||||
if (!g_has_went_fullscreen)
|
||||
[g_view.window setContentSize:NSMakeSize(width, height)];
|
||||
});
|
||||
#endif
|
||||
|
||||
// TODO: Maybe iOS users should be apple to show/hide the status bar here?
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef IOS
|
||||
void apple_bind_game_view_fbo(void)
|
||||
{
|
|
@ -22,22 +22,22 @@
|
|||
#include "conf/config_file.h"
|
||||
#include "core_info.h"
|
||||
|
||||
extern NSArray* apple_get_modules();
|
||||
|
||||
@interface RAModuleInfo : NSObject
|
||||
@property (strong) NSString* path;
|
||||
@property NSString* path; // e.g. /path/to/corename_libretro.dylib
|
||||
@property NSString* baseName; // e.g. corename_libretro
|
||||
@property core_info_t* info;
|
||||
@property config_file_t* data;
|
||||
@property (strong) NSString* description;
|
||||
@property (strong) NSString* customConfigPath;
|
||||
@property NSString* description; // Friendly name from config file, else just the filename
|
||||
@property NSString* customConfigFile; // Path where custom config file would reside
|
||||
@property NSString* configFile; // Path to effective config file
|
||||
|
||||
+ (NSArray*)getModules;
|
||||
- (bool)supportsFileAtPath:(NSString*)path;
|
||||
|
||||
+ (NSString*)globalConfigPath;
|
||||
|
||||
- (void)createCustomConfig;
|
||||
- (void)deleteCustomConfig;
|
||||
- (bool)hasCustomConfig;
|
||||
- (NSString*)configPath;
|
||||
|
||||
@end
|
||||
|
|
@ -22,30 +22,29 @@
|
|||
static NSMutableArray* moduleList;
|
||||
static core_info_list_t* coreList;
|
||||
|
||||
@implementation RAModuleInfo
|
||||
+ (NSArray*)getModules
|
||||
NSArray* apple_get_modules()
|
||||
{
|
||||
if (!moduleList)
|
||||
{
|
||||
coreList = get_core_info_list(apple_platform.corePath.UTF8String);
|
||||
coreList = get_core_info_list(apple_platform.coreDirectory.UTF8String);
|
||||
|
||||
if (!coreList)
|
||||
return nil;
|
||||
|
||||
moduleList = [NSMutableArray arrayWithCapacity:coreList->count];
|
||||
|
||||
moduleList = [NSMutableArray arrayWithCapacity:coreList->count];
|
||||
|
||||
for (int i = 0; coreList && i < coreList->count; i ++)
|
||||
{
|
||||
core_info_t* core = &coreList->list[i];
|
||||
|
||||
RAModuleInfo* newInfo = [RAModuleInfo new];
|
||||
newInfo.path = [NSString stringWithUTF8String:core->path];
|
||||
newInfo.path = @(core->path);
|
||||
newInfo.baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension;
|
||||
newInfo.info = core;
|
||||
newInfo.data = core->data;
|
||||
newInfo.description = [NSString stringWithUTF8String:core->display_name];
|
||||
|
||||
NSString* baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension;
|
||||
newInfo.customConfigPath = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.retroarchConfigPath, baseName];
|
||||
newInfo.description = @(core->display_name);
|
||||
newInfo.customConfigFile = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.configDirectory, newInfo.baseName];
|
||||
newInfo.configFile = newInfo.hasCustomConfig ? newInfo.customConfigFile : apple_platform.globalConfigFile;
|
||||
|
||||
[moduleList addObject:newInfo];
|
||||
}
|
||||
|
@ -59,9 +58,7 @@ static core_info_list_t* coreList;
|
|||
return moduleList;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
}
|
||||
@implementation RAModuleInfo
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
|
@ -73,35 +70,21 @@ static core_info_list_t* coreList;
|
|||
return does_core_support_file(self.info, path.UTF8String);
|
||||
}
|
||||
|
||||
+ (NSString*)globalConfigPath
|
||||
{
|
||||
static NSString* path;
|
||||
if (!path)
|
||||
path = [NSString stringWithFormat:@"%@/retroarch.cfg", apple_platform.retroarchConfigPath];
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
- (void)createCustomConfig
|
||||
{
|
||||
if (!self.hasCustomConfig)
|
||||
[NSFileManager.defaultManager copyItemAtPath:RAModuleInfo.globalConfigPath toPath:self.customConfigPath error:nil];
|
||||
[NSFileManager.defaultManager copyItemAtPath:apple_platform.globalConfigFile toPath:self.customConfigFile error:nil];
|
||||
}
|
||||
|
||||
- (void)deleteCustomConfig
|
||||
{
|
||||
if (self.hasCustomConfig)
|
||||
[NSFileManager.defaultManager removeItemAtPath:self.customConfigPath error:nil];
|
||||
[NSFileManager.defaultManager removeItemAtPath:self.customConfigFile error:nil];
|
||||
}
|
||||
|
||||
- (bool)hasCustomConfig
|
||||
{
|
||||
return path_file_exists(self.customConfigPath.UTF8String);
|
||||
}
|
||||
|
||||
- (NSString*)configPath
|
||||
{
|
||||
return self.hasCustomConfig ? self.customConfigPath : RAModuleInfo.globalConfigPath;
|
||||
return path_file_exists(self.customConfigFile.UTF8String);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -148,7 +131,7 @@ static NSString* build_string_pair(NSString* stringA, NSString* stringB)
|
|||
for (int i = 0; i < firmwareCount; i ++)
|
||||
{
|
||||
NSString* path = objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_path", i + 1], @"Unspecified");
|
||||
path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:RetroArch_iOS.get.systemDirectory];
|
||||
path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:[RetroArch_iOS get].systemDirectory];
|
||||
[firmwareSection addObject:build_string_pair(objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_desc", i + 1], @"Unspecified"), path)];
|
||||
}
|
||||
|
|
@ -28,8 +28,9 @@
|
|||
- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file;
|
||||
- (void)unloadingCore:(RAModuleInfo*)core;
|
||||
|
||||
- (NSString*)retroarchConfigPath; // < This returns the directory that contains retroarch.cfg and other custom configs
|
||||
- (NSString*)corePath;
|
||||
- (NSString*)configDirectory; // < This returns the directory that contains retroarch.cfg and other custom configs
|
||||
- (NSString*)globalConfigFile; // < This is the full path to retroarch.cfg
|
||||
- (NSString*)coreDirectory; // < This is the default path to where libretro cores are installed
|
||||
@end
|
||||
|
||||
#ifdef IOS
|
||||
|
@ -38,6 +39,7 @@
|
|||
#import "../OSX/platform.h"
|
||||
#endif
|
||||
|
||||
extern char** apple_argv;
|
||||
extern bool apple_is_paused;
|
||||
extern bool apple_is_running;
|
||||
extern bool apple_use_tv_mode;
|
||||
|
@ -53,7 +55,7 @@ extern void apple_event_show_rgui(void* userdata);
|
|||
|
||||
extern void apple_refresh_config();
|
||||
extern void apple_enter_stasis();
|
||||
extern void apple_exit_stasis();
|
||||
extern void apple_exit_stasis(bool reload_config);
|
||||
extern void apple_run_core(RAModuleInfo* core, const char* file);
|
||||
|
||||
// utility.m
|
|
@ -22,14 +22,14 @@
|
|||
#include "general.h"
|
||||
#include "driver.h"
|
||||
|
||||
#include "keycode.inc"
|
||||
|
||||
extern const rarch_joypad_driver_t apple_joypad;
|
||||
static const rarch_joypad_driver_t* const g_joydriver = &apple_joypad;
|
||||
|
||||
apple_input_data_t g_current_input_data;
|
||||
apple_input_data_t g_polled_input_data;
|
||||
|
||||
static const struct rarch_key_map rarch_key_map_hidusage[];
|
||||
|
||||
#ifdef OSX // Taken from https://github.com/depp/keycode, check keycode.h for license
|
||||
const unsigned char MAC_NATIVE_TO_HID[128] = {
|
||||
4, 22, 7, 9, 11, 10, 29, 27, 6, 25,255, 5, 20, 26, 8, 21,
|
||||
|
@ -101,6 +101,42 @@ void apple_input_handle_key_event(unsigned keycode, bool down)
|
|||
g_current_input_data.keys[keycode] = down;
|
||||
}
|
||||
|
||||
|
||||
int32_t apple_input_find_any_key()
|
||||
{
|
||||
for (int i = 0; apple_key_name_map[i].hid_id; i++)
|
||||
if (g_current_input_data.keys[apple_key_name_map[i].hid_id])
|
||||
return apple_key_name_map[i].hid_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t apple_input_find_any_button(uint32_t port)
|
||||
{
|
||||
uint32_t buttons = g_current_input_data.pad_buttons[port] |
|
||||
((port == 0) ? apple_input_get_icade_buttons() : 0);
|
||||
|
||||
if (g_current_input_data.pad_buttons[port])
|
||||
for (int i = 0; i != 32; i ++)
|
||||
if (buttons & (1 << i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t apple_input_find_any_axis(uint32_t port)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value = g_current_input_data.pad_axis[port][i];
|
||||
|
||||
if (abs(value) > 0x4000)
|
||||
return (value < 0) ? -(i + 1) : i + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Game thread interface
|
||||
static bool apple_key_pressed(enum retro_key key)
|
||||
{
|
||||
|
@ -118,7 +154,7 @@ static bool apple_is_pressed(unsigned port_num, const struct retro_keybind *bind
|
|||
// Exported input driver
|
||||
static void *apple_input_init(void)
|
||||
{
|
||||
input_init_keyboard_lut(rarch_key_map_hidusage);
|
||||
input_init_keyboard_lut(apple_key_map_hidusage);
|
||||
memset(&g_polled_input_data, 0, sizeof(g_polled_input_data));
|
||||
return (void*)-1;
|
||||
}
|
||||
|
@ -273,150 +309,3 @@ const input_driver_t input_apple = {
|
|||
apple_input_set_keybinds,
|
||||
"apple_input",
|
||||
};
|
||||
|
||||
|
||||
// Key table
|
||||
#include "keycode.h"
|
||||
static const struct rarch_key_map rarch_key_map_hidusage[] = {
|
||||
{ KEY_Delete, RETROK_BACKSPACE },
|
||||
{ KEY_Tab, RETROK_TAB },
|
||||
// RETROK_CLEAR },
|
||||
{ KEY_Enter, RETROK_RETURN },
|
||||
{ KEY_Pause, RETROK_PAUSE },
|
||||
{ KEY_Escape, RETROK_ESCAPE },
|
||||
{ KEY_Space, RETROK_SPACE },
|
||||
// RETROK_EXCLAIM },
|
||||
// RETROK_QUOTEDBL },
|
||||
// RETROK_HASH },
|
||||
// RETROK_DOLLAR },
|
||||
// RETROK_AMPERSAND },
|
||||
{ KEY_Quote, RETROK_QUOTE },
|
||||
// RETROK_LEFTPAREN },
|
||||
// RETROK_RIGHTPAREN },
|
||||
// RETROK_ASTERISK },
|
||||
// RETROK_PLUS },
|
||||
{ KEY_Comma, RETROK_COMMA },
|
||||
{ KEY_Minus, RETROK_MINUS },
|
||||
{ KEY_Period, RETROK_PERIOD },
|
||||
{ KEY_Slash, RETROK_SLASH },
|
||||
{ KEY_0, RETROK_0 },
|
||||
{ KEY_1, RETROK_1 },
|
||||
{ KEY_2, RETROK_2 },
|
||||
{ KEY_3, RETROK_3 },
|
||||
{ KEY_4, RETROK_4 },
|
||||
{ KEY_5, RETROK_5 },
|
||||
{ KEY_6, RETROK_6 },
|
||||
{ KEY_7, RETROK_7 },
|
||||
{ KEY_8, RETROK_8 },
|
||||
{ KEY_9, RETROK_9 },
|
||||
// RETROK_COLON },
|
||||
{ KEY_Semicolon, RETROK_SEMICOLON },
|
||||
// RETROK_LESS },
|
||||
{ KEY_Equals, RETROK_EQUALS },
|
||||
// RETROK_GREATER },
|
||||
// RETROK_QUESTION },
|
||||
// RETROK_AT },
|
||||
{ KEY_LeftBracket, RETROK_LEFTBRACKET },
|
||||
{ KEY_Backslash, RETROK_BACKSLASH },
|
||||
{ KEY_RightBracket, RETROK_RIGHTBRACKET },
|
||||
// RETROK_CARET },
|
||||
// RETROK_UNDERSCORE },
|
||||
{ KEY_Grave, RETROK_BACKQUOTE },
|
||||
{ KEY_A, RETROK_a },
|
||||
{ KEY_B, RETROK_b },
|
||||
{ KEY_C, RETROK_c },
|
||||
{ KEY_D, RETROK_d },
|
||||
{ KEY_E, RETROK_e },
|
||||
{ KEY_F, RETROK_f },
|
||||
{ KEY_G, RETROK_g },
|
||||
{ KEY_H, RETROK_h },
|
||||
{ KEY_I, RETROK_i },
|
||||
{ KEY_J, RETROK_j },
|
||||
{ KEY_K, RETROK_k },
|
||||
{ KEY_L, RETROK_l },
|
||||
{ KEY_M, RETROK_m },
|
||||
{ KEY_N, RETROK_n },
|
||||
{ KEY_O, RETROK_o },
|
||||
{ KEY_P, RETROK_p },
|
||||
{ KEY_Q, RETROK_q },
|
||||
{ KEY_R, RETROK_r },
|
||||
{ KEY_S, RETROK_s },
|
||||
{ KEY_T, RETROK_t },
|
||||
{ KEY_U, RETROK_u },
|
||||
{ KEY_V, RETROK_v },
|
||||
{ KEY_W, RETROK_w },
|
||||
{ KEY_X, RETROK_x },
|
||||
{ KEY_Y, RETROK_y },
|
||||
{ KEY_Z, RETROK_z },
|
||||
{ KEY_DeleteForward, RETROK_DELETE },
|
||||
|
||||
{ KP_0, RETROK_KP0 },
|
||||
{ KP_1, RETROK_KP1 },
|
||||
{ KP_2, RETROK_KP2 },
|
||||
{ KP_3, RETROK_KP3 },
|
||||
{ KP_4, RETROK_KP4 },
|
||||
{ KP_5, RETROK_KP5 },
|
||||
{ KP_6, RETROK_KP6 },
|
||||
{ KP_7, RETROK_KP7 },
|
||||
{ KP_8, RETROK_KP8 },
|
||||
{ KP_9, RETROK_KP9 },
|
||||
{ KP_Point, RETROK_KP_PERIOD },
|
||||
{ KP_Divide, RETROK_KP_DIVIDE },
|
||||
{ KP_Multiply, RETROK_KP_MULTIPLY },
|
||||
{ KP_Subtract, RETROK_KP_MINUS },
|
||||
{ KP_Add, RETROK_KP_PLUS },
|
||||
{ KP_Enter, RETROK_KP_ENTER },
|
||||
{ KP_Equals, RETROK_KP_EQUALS },
|
||||
|
||||
{ KEY_Up, RETROK_UP },
|
||||
{ KEY_Down, RETROK_DOWN },
|
||||
{ KEY_Right, RETROK_RIGHT },
|
||||
{ KEY_Left, RETROK_LEFT },
|
||||
{ KEY_Insert, RETROK_INSERT },
|
||||
{ KEY_Home, RETROK_HOME },
|
||||
{ KEY_End, RETROK_END },
|
||||
{ KEY_PageUp, RETROK_PAGEUP },
|
||||
{ KEY_PageDown, RETROK_PAGEDOWN },
|
||||
|
||||
{ KEY_F1, RETROK_F1 },
|
||||
{ KEY_F2, RETROK_F2 },
|
||||
{ KEY_F3, RETROK_F3 },
|
||||
{ KEY_F4, RETROK_F4 },
|
||||
{ KEY_F5, RETROK_F5 },
|
||||
{ KEY_F6, RETROK_F6 },
|
||||
{ KEY_F7, RETROK_F7 },
|
||||
{ KEY_F8, RETROK_F8 },
|
||||
{ KEY_F9, RETROK_F9 },
|
||||
{ KEY_F10, RETROK_F10 },
|
||||
{ KEY_F11, RETROK_F11 },
|
||||
{ KEY_F12, RETROK_F12 },
|
||||
{ KEY_F13, RETROK_F13 },
|
||||
{ KEY_F14, RETROK_F14 },
|
||||
{ KEY_F15, RETROK_F15 },
|
||||
|
||||
// RETROK_NUMLOCK },
|
||||
{ KEY_CapsLock, RETROK_CAPSLOCK },
|
||||
// RETROK_SCROLLOCK },
|
||||
{ KEY_RightShift, RETROK_RSHIFT },
|
||||
{ KEY_LeftShift, RETROK_LSHIFT },
|
||||
{ KEY_RightControl, RETROK_RCTRL },
|
||||
{ KEY_LeftControl, RETROK_LCTRL },
|
||||
{ KEY_RightAlt, RETROK_RALT },
|
||||
{ KEY_LeftAlt, RETROK_LALT },
|
||||
{ KEY_RightGUI, RETROK_RMETA },
|
||||
{ KEY_LeftGUI, RETROK_RMETA },
|
||||
// RETROK_LSUPER },
|
||||
// RETROK_RSUPER },
|
||||
// RETROK_MODE },
|
||||
// RETROK_COMPOSE },
|
||||
|
||||
// RETROK_HELP },
|
||||
{ KEY_PrintScreen, RETROK_PRINT },
|
||||
// RETROK_SYSREQ },
|
||||
// RETROK_BREAK },
|
||||
{ KEY_Menu, RETROK_MENU },
|
||||
// RETROK_POWER },
|
||||
// RETROK_EURO },
|
||||
// RETROK_UNDO },
|
||||
{ 0, RETROK_UNKNOWN }
|
||||
};
|
|
@ -50,4 +50,8 @@ void apple_input_enable_icade(bool on);
|
|||
uint32_t apple_input_get_icade_buttons();
|
||||
void apple_input_handle_key_event(unsigned keycode, bool down);
|
||||
|
||||
extern int32_t apple_input_find_any_key();
|
||||
extern int32_t apple_input_find_any_button(uint32_t port);
|
||||
extern int32_t apple_input_find_any_axis(uint32_t port);
|
||||
|
||||
#endif
|
|
@ -17,12 +17,12 @@
|
|||
#include "general.h"
|
||||
|
||||
#ifdef IOS
|
||||
#include "../iOS/input/BTStack/btdynamic.c"
|
||||
#include "../iOS/input/BTStack/wiimote.c"
|
||||
#include "../iOS/input/BTStack/btpad.c"
|
||||
#include "../iOS/input/BTStack/btpad_ps3.c"
|
||||
#include "../iOS/input/BTStack/btpad_wii.c"
|
||||
#include "../iOS/input/BTStack/btpad_queue.c"
|
||||
#include "apple/iOS/bluetooth/btdynamic.c"
|
||||
#include "apple/iOS/bluetooth/wiimote.c"
|
||||
#include "apple/iOS/bluetooth/btpad.c"
|
||||
#include "apple/iOS/bluetooth/btpad_ps3.c"
|
||||
#include "apple/iOS/bluetooth/btpad_wii.c"
|
||||
#include "apple/iOS/bluetooth/btpad_queue.c"
|
||||
#elif defined(OSX)
|
||||
#include "../OSX/hid_pad.c"
|
||||
#endif
|
|
@ -153,4 +153,21 @@ enum {
|
|||
KEY_RightAlt = 230,
|
||||
KEY_RightGUI = 231
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
#include "input/input_common.h" // < For rarch_key_map
|
||||
|
||||
struct apple_key_name_map_entry
|
||||
{
|
||||
const char* const keyname;
|
||||
const uint32_t hid_id;
|
||||
};
|
||||
|
||||
extern const struct apple_key_name_map_entry apple_key_name_map[];
|
||||
extern const struct rarch_key_map apple_key_map_hidusage[];
|
||||
|
||||
|
||||
const char* apple_keycode_hidusage_to_name(uint32_t hid_usage);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,222 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - Jason Fetters
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "keycode.h"
|
||||
|
||||
const struct apple_key_name_map_entry apple_key_name_map[] =
|
||||
{
|
||||
{ "left", KEY_Left }, { "right", KEY_Right },
|
||||
{ "up", KEY_Up }, { "down", KEY_Down },
|
||||
{ "enter", KEY_Enter }, { "kp_enter", KP_Enter },
|
||||
{ "space", KEY_Space }, { "tab", KEY_Tab },
|
||||
{ "shift", KEY_LeftShift }, { "rshift", KEY_RightShift },
|
||||
{ "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt },
|
||||
{ "escape", KEY_Escape }, { "backspace", KEY_DeleteForward },
|
||||
{ "backquote", KEY_Grave }, { "pause", KEY_Pause },
|
||||
|
||||
{ "f1", KEY_F1 }, { "f2", KEY_F2 },
|
||||
{ "f3", KEY_F3 }, { "f4", KEY_F4 },
|
||||
{ "f5", KEY_F5 }, { "f6", KEY_F6 },
|
||||
{ "f7", KEY_F7 }, { "f8", KEY_F8 },
|
||||
{ "f9", KEY_F9 }, { "f10", KEY_F10 },
|
||||
{ "f11", KEY_F11 }, { "f12", KEY_F12 },
|
||||
|
||||
{ "num0", KEY_0 }, { "num1", KEY_1 },
|
||||
{ "num2", KEY_2 }, { "num3", KEY_3 },
|
||||
{ "num4", KEY_4 }, { "num5", KEY_5 },
|
||||
{ "num6", KEY_6 }, { "num7", KEY_7 },
|
||||
{ "num8", KEY_8 }, { "num9", KEY_9 },
|
||||
|
||||
{ "insert", KEY_Insert }, { "del", KEY_DeleteForward },
|
||||
{ "home", KEY_Home }, { "end", KEY_End },
|
||||
{ "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown },
|
||||
|
||||
{ "add", KP_Add }, { "subtract", KP_Subtract },
|
||||
{ "multiply", KP_Multiply }, { "divide", KP_Divide },
|
||||
{ "keypad0", KP_0 }, { "keypad1", KP_1 },
|
||||
{ "keypad2", KP_2 }, { "keypad3", KP_3 },
|
||||
{ "keypad4", KP_4 }, { "keypad5", KP_5 },
|
||||
{ "keypad6", KP_6 }, { "keypad7", KP_7 },
|
||||
{ "keypad8", KP_8 }, { "keypad9", KP_9 },
|
||||
|
||||
{ "period", KEY_Period }, { "capslock", KEY_CapsLock },
|
||||
{ "numlock", KP_NumLock }, { "print_screen", KEY_PrintScreen },
|
||||
{ "scroll_lock", KEY_ScrollLock },
|
||||
|
||||
{ "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D },
|
||||
{ "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H },
|
||||
{ "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L },
|
||||
{ "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P },
|
||||
{ "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T },
|
||||
{ "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X },
|
||||
{ "y", KEY_Y }, { "z", KEY_Z },
|
||||
|
||||
{ "nul", 0x00},
|
||||
};
|
||||
|
||||
const struct rarch_key_map apple_key_map_hidusage[] =
|
||||
{
|
||||
{ KEY_Delete, RETROK_BACKSPACE },
|
||||
{ KEY_Tab, RETROK_TAB },
|
||||
// RETROK_CLEAR },
|
||||
{ KEY_Enter, RETROK_RETURN },
|
||||
{ KEY_Pause, RETROK_PAUSE },
|
||||
{ KEY_Escape, RETROK_ESCAPE },
|
||||
{ KEY_Space, RETROK_SPACE },
|
||||
// RETROK_EXCLAIM },
|
||||
// RETROK_QUOTEDBL },
|
||||
// RETROK_HASH },
|
||||
// RETROK_DOLLAR },
|
||||
// RETROK_AMPERSAND },
|
||||
{ KEY_Quote, RETROK_QUOTE },
|
||||
// RETROK_LEFTPAREN },
|
||||
// RETROK_RIGHTPAREN },
|
||||
// RETROK_ASTERISK },
|
||||
// RETROK_PLUS },
|
||||
{ KEY_Comma, RETROK_COMMA },
|
||||
{ KEY_Minus, RETROK_MINUS },
|
||||
{ KEY_Period, RETROK_PERIOD },
|
||||
{ KEY_Slash, RETROK_SLASH },
|
||||
{ KEY_0, RETROK_0 },
|
||||
{ KEY_1, RETROK_1 },
|
||||
{ KEY_2, RETROK_2 },
|
||||
{ KEY_3, RETROK_3 },
|
||||
{ KEY_4, RETROK_4 },
|
||||
{ KEY_5, RETROK_5 },
|
||||
{ KEY_6, RETROK_6 },
|
||||
{ KEY_7, RETROK_7 },
|
||||
{ KEY_8, RETROK_8 },
|
||||
{ KEY_9, RETROK_9 },
|
||||
// RETROK_COLON },
|
||||
{ KEY_Semicolon, RETROK_SEMICOLON },
|
||||
// RETROK_LESS },
|
||||
{ KEY_Equals, RETROK_EQUALS },
|
||||
// RETROK_GREATER },
|
||||
// RETROK_QUESTION },
|
||||
// RETROK_AT },
|
||||
{ KEY_LeftBracket, RETROK_LEFTBRACKET },
|
||||
{ KEY_Backslash, RETROK_BACKSLASH },
|
||||
{ KEY_RightBracket, RETROK_RIGHTBRACKET },
|
||||
// RETROK_CARET },
|
||||
// RETROK_UNDERSCORE },
|
||||
{ KEY_Grave, RETROK_BACKQUOTE },
|
||||
{ KEY_A, RETROK_a },
|
||||
{ KEY_B, RETROK_b },
|
||||
{ KEY_C, RETROK_c },
|
||||
{ KEY_D, RETROK_d },
|
||||
{ KEY_E, RETROK_e },
|
||||
{ KEY_F, RETROK_f },
|
||||
{ KEY_G, RETROK_g },
|
||||
{ KEY_H, RETROK_h },
|
||||
{ KEY_I, RETROK_i },
|
||||
{ KEY_J, RETROK_j },
|
||||
{ KEY_K, RETROK_k },
|
||||
{ KEY_L, RETROK_l },
|
||||
{ KEY_M, RETROK_m },
|
||||
{ KEY_N, RETROK_n },
|
||||
{ KEY_O, RETROK_o },
|
||||
{ KEY_P, RETROK_p },
|
||||
{ KEY_Q, RETROK_q },
|
||||
{ KEY_R, RETROK_r },
|
||||
{ KEY_S, RETROK_s },
|
||||
{ KEY_T, RETROK_t },
|
||||
{ KEY_U, RETROK_u },
|
||||
{ KEY_V, RETROK_v },
|
||||
{ KEY_W, RETROK_w },
|
||||
{ KEY_X, RETROK_x },
|
||||
{ KEY_Y, RETROK_y },
|
||||
{ KEY_Z, RETROK_z },
|
||||
{ KEY_DeleteForward, RETROK_DELETE },
|
||||
|
||||
{ KP_0, RETROK_KP0 },
|
||||
{ KP_1, RETROK_KP1 },
|
||||
{ KP_2, RETROK_KP2 },
|
||||
{ KP_3, RETROK_KP3 },
|
||||
{ KP_4, RETROK_KP4 },
|
||||
{ KP_5, RETROK_KP5 },
|
||||
{ KP_6, RETROK_KP6 },
|
||||
{ KP_7, RETROK_KP7 },
|
||||
{ KP_8, RETROK_KP8 },
|
||||
{ KP_9, RETROK_KP9 },
|
||||
{ KP_Point, RETROK_KP_PERIOD },
|
||||
{ KP_Divide, RETROK_KP_DIVIDE },
|
||||
{ KP_Multiply, RETROK_KP_MULTIPLY },
|
||||
{ KP_Subtract, RETROK_KP_MINUS },
|
||||
{ KP_Add, RETROK_KP_PLUS },
|
||||
{ KP_Enter, RETROK_KP_ENTER },
|
||||
{ KP_Equals, RETROK_KP_EQUALS },
|
||||
|
||||
{ KEY_Up, RETROK_UP },
|
||||
{ KEY_Down, RETROK_DOWN },
|
||||
{ KEY_Right, RETROK_RIGHT },
|
||||
{ KEY_Left, RETROK_LEFT },
|
||||
{ KEY_Insert, RETROK_INSERT },
|
||||
{ KEY_Home, RETROK_HOME },
|
||||
{ KEY_End, RETROK_END },
|
||||
{ KEY_PageUp, RETROK_PAGEUP },
|
||||
{ KEY_PageDown, RETROK_PAGEDOWN },
|
||||
|
||||
{ KEY_F1, RETROK_F1 },
|
||||
{ KEY_F2, RETROK_F2 },
|
||||
{ KEY_F3, RETROK_F3 },
|
||||
{ KEY_F4, RETROK_F4 },
|
||||
{ KEY_F5, RETROK_F5 },
|
||||
{ KEY_F6, RETROK_F6 },
|
||||
{ KEY_F7, RETROK_F7 },
|
||||
{ KEY_F8, RETROK_F8 },
|
||||
{ KEY_F9, RETROK_F9 },
|
||||
{ KEY_F10, RETROK_F10 },
|
||||
{ KEY_F11, RETROK_F11 },
|
||||
{ KEY_F12, RETROK_F12 },
|
||||
{ KEY_F13, RETROK_F13 },
|
||||
{ KEY_F14, RETROK_F14 },
|
||||
{ KEY_F15, RETROK_F15 },
|
||||
|
||||
// RETROK_NUMLOCK },
|
||||
{ KEY_CapsLock, RETROK_CAPSLOCK },
|
||||
// RETROK_SCROLLOCK },
|
||||
{ KEY_RightShift, RETROK_RSHIFT },
|
||||
{ KEY_LeftShift, RETROK_LSHIFT },
|
||||
{ KEY_RightControl, RETROK_RCTRL },
|
||||
{ KEY_LeftControl, RETROK_LCTRL },
|
||||
{ KEY_RightAlt, RETROK_RALT },
|
||||
{ KEY_LeftAlt, RETROK_LALT },
|
||||
{ KEY_RightGUI, RETROK_RMETA },
|
||||
{ KEY_LeftGUI, RETROK_RMETA },
|
||||
// RETROK_LSUPER },
|
||||
// RETROK_RSUPER },
|
||||
// RETROK_MODE },
|
||||
// RETROK_COMPOSE },
|
||||
|
||||
// RETROK_HELP },
|
||||
{ KEY_PrintScreen, RETROK_PRINT },
|
||||
// RETROK_SYSREQ },
|
||||
// RETROK_BREAK },
|
||||
{ KEY_Menu, RETROK_MENU },
|
||||
// RETROK_POWER },
|
||||
// RETROK_EURO },
|
||||
// RETROK_UNDO },
|
||||
{ 0, RETROK_UNKNOWN }
|
||||
};
|
||||
|
||||
|
||||
const char* apple_keycode_hidusage_to_name(uint32_t hid_usage)
|
||||
{
|
||||
for (int i = 0; apple_key_name_map[i].hid_id; i ++)
|
||||
if (apple_key_name_map[i].hid_id == hid_usage)
|
||||
return apple_key_name_map[i].keyname;
|
||||
|
||||
return "nul";
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "file.h"
|
||||
|
||||
//#define HAVE_DEBUG_FILELOG
|
||||
char** apple_argv;
|
||||
|
||||
id<RetroArch_Platform> apple_platform;
|
||||
|
||||
|
@ -71,8 +71,6 @@ pthread_mutex_t stasis_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||
|
||||
static void event_stasis(void* userdata)
|
||||
{
|
||||
// HACK: uninit_drivers is the nuclear option; uninit_audio would be better but will
|
||||
// crash when resuming.
|
||||
uninit_drivers();
|
||||
pthread_mutex_lock(&stasis_mutex);
|
||||
pthread_mutex_unlock(&stasis_mutex);
|
||||
|
@ -88,8 +86,14 @@ void apple_enter_stasis()
|
|||
}
|
||||
}
|
||||
|
||||
void apple_exit_stasis()
|
||||
void apple_exit_stasis(bool reload_config)
|
||||
{
|
||||
if (reload_config)
|
||||
{
|
||||
objc_clear_config_hack();
|
||||
config_load();
|
||||
}
|
||||
|
||||
if (apple_is_running)
|
||||
pthread_mutex_unlock(&stasis_mutex);
|
||||
}
|
||||
|
@ -125,37 +129,38 @@ void apple_run_core(RAModuleInfo* core, const char* file)
|
|||
|
||||
apple_core = core;
|
||||
apple_is_running = true;
|
||||
|
||||
|
||||
static char config_path[PATH_MAX];
|
||||
static char core_path[PATH_MAX];
|
||||
static char file_path[PATH_MAX];
|
||||
|
||||
static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 };
|
||||
|
||||
if (apple_core)
|
||||
strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path));
|
||||
else
|
||||
strlcpy(config_path, RAModuleInfo.globalConfigPath.UTF8String, sizeof(config_path));
|
||||
if (!apple_argv)
|
||||
{
|
||||
NSString* config_to_use = apple_core ? apple_core.configFile : apple_platform.globalConfigFile;
|
||||
strlcpy(config_path, config_to_use.UTF8String, sizeof(config_path));
|
||||
|
||||
static const char* const argv_game[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 };
|
||||
static const char* const argv_menu[] = { "retroarch", "-c", config_path, "--menu", 0 };
|
||||
|
||||
if (file && core)
|
||||
{
|
||||
argv[3] = "-L";
|
||||
argv[4] = core_path;
|
||||
strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path));
|
||||
strlcpy(file_path, file, sizeof(file_path));
|
||||
}
|
||||
else
|
||||
{
|
||||
argv[3] = "--menu";
|
||||
argv[4] = 0;
|
||||
if (file && core)
|
||||
{
|
||||
strlcpy(core_path, apple_core.path.UTF8String, sizeof(core_path));
|
||||
strlcpy(file_path, file, sizeof(file_path));
|
||||
}
|
||||
|
||||
apple_argv = (char**)((file && core) ? argv_game : argv_menu);
|
||||
}
|
||||
|
||||
if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, argv))
|
||||
if (pthread_create(&apple_retro_thread, 0, rarch_main_spring, apple_argv))
|
||||
{
|
||||
apple_argv = 0;
|
||||
|
||||
apple_rarch_exited((void*)1);
|
||||
return;
|
||||
}
|
||||
|
||||
apple_argv = 0;
|
||||
|
||||
pthread_detach(apple_retro_thread);
|
||||
}
|
||||
}
|
|
@ -23,12 +23,15 @@ char* ios_get_rarch_system_directory();
|
|||
// These functions should only be called as arguments to dispatch_sync
|
||||
void apple_rarch_exited (void* result);
|
||||
|
||||
// These functions must only be called in gfx/context/ioseagl_ctx.c
|
||||
// These functions must only be called in gfx/context/apple_gl_context.c
|
||||
bool apple_init_game_view(void);
|
||||
void apple_destroy_game_view(void);
|
||||
bool apple_set_video_mode(unsigned width, unsigned height, bool fullscreen);
|
||||
void apple_flip_game_view(void);
|
||||
void apple_set_game_view_sync(unsigned interval);
|
||||
void apple_get_game_view_size(unsigned *width, unsigned *height);
|
||||
void apple_update_window_title(void);
|
||||
bool apple_game_view_has_focus(void);
|
||||
void *apple_get_proc_address(const char *symbol_name);
|
||||
|
||||
#ifdef IOS
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
#include "general.h"
|
||||
|
||||
enum setting_type { ST_NONE, ST_BOOL, ST_INT, ST_FLOAT, ST_PATH, ST_STRING, ST_HEX, ST_GROUP, ST_SUB_GROUP,
|
||||
ST_END_GROUP, ST_END_SUB_GROUP };
|
||||
enum setting_type { ST_NONE, ST_BOOL, ST_INT, ST_FLOAT, ST_PATH, ST_STRING, ST_HEX, ST_BIND,
|
||||
ST_GROUP, ST_SUB_GROUP, ST_END_GROUP, ST_END_SUB_GROUP };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -28,36 +28,43 @@ typedef struct
|
|||
const char* name;
|
||||
|
||||
void* value;
|
||||
uint32_t size;
|
||||
|
||||
const char* short_description;
|
||||
const char* long_description;
|
||||
|
||||
const char** values;
|
||||
|
||||
uint32_t input_player;
|
||||
|
||||
double min;
|
||||
double max;
|
||||
bool allow_blank;
|
||||
} rarch_setting_t;
|
||||
|
||||
#define START_GROUP(NAME) { ST_GROUP, NAME, 0, 0, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define END_GROUP() { ST_END_GROUP, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define START_SUB_GROUP(NAME) { ST_SUB_GROUP, NAME, 0, 0, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define END_SUB_GROUP() { ST_END_SUB_GROUP, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define START_GROUP(NAME) { ST_GROUP, NAME, 0, 0, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define END_GROUP() { ST_END_GROUP, 0, 0, 0, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false },
|
||||
#define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, SHORT, 0, 0, 0, 0.0, 0.0, false },
|
||||
extern struct settings fake_settings;
|
||||
extern struct global fake_extern;
|
||||
|
||||
// HACK
|
||||
#define g_settings fake_settings
|
||||
#define g_extern fake_extern
|
||||
|
||||
#define START_GROUP(NAME) { ST_GROUP, NAME },
|
||||
#define END_GROUP() { ST_END_GROUP },
|
||||
#define START_SUB_GROUP(NAME) { ST_SUB_GROUP, NAME },
|
||||
#define END_SUB_GROUP() { ST_END_SUB_GROUP },
|
||||
#define CONFIG_BOOL(TARGET, NAME, SHORT) { ST_BOOL, NAME, &TARGET, sizeof(TARGET), SHORT },
|
||||
#define CONFIG_INT(TARGET, NAME, SHORT) { ST_INT, NAME, &TARGET, sizeof(TARGET), SHORT },
|
||||
#define CONFIG_FLOAT(TARGET, NAME, SHORT) { ST_FLOAT, NAME, &TARGET, sizeof(TARGET), SHORT },
|
||||
#define CONFIG_PATH(TARGET, NAME, SHORT) { ST_PATH, NAME, &TARGET, sizeof(TARGET), SHORT },
|
||||
#define CONFIG_STRING(TARGET, NAME, SHORT) { ST_STRING, NAME, &TARGET, sizeof(TARGET), SHORT },
|
||||
#define CONFIG_HEX(TARGET, NAME, SHORT) { ST_HEX, NAME, &TARGET, sizeof(TARGET), SHORT },
|
||||
|
||||
#define CONFIG_BIND(TARGET, PLAYER, NAME, SHORT) { ST_BIND, NAME, &TARGET, sizeof(TARGET), SHORT, PLAYER },
|
||||
|
||||
const rarch_setting_t setting_data[] =
|
||||
{
|
||||
/***********/
|
||||
/* DRIVERS */
|
||||
/***********/
|
||||
#if 0
|
||||
START_GROUP("Drivers")
|
||||
START_SUB_GROUP("Drivers")
|
||||
CONFIG_STRING(g_settings.video.driver, "video_driver", "Video Driver")
|
||||
|
@ -67,6 +74,7 @@ const rarch_setting_t setting_data[] =
|
|||
CONFIG_STRING(g_settings.input.joypad_driver, "input_joypad_driver", "Joypad Driver")
|
||||
END_SUB_GROUP()
|
||||
END_GROUP()
|
||||
#endif
|
||||
|
||||
/*********/
|
||||
/* PATHS */
|
||||
|
@ -92,7 +100,6 @@ const rarch_setting_t setting_data[] =
|
|||
END_GROUP()
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* EMULATION */
|
||||
/*************/
|
||||
|
@ -113,6 +120,82 @@ const rarch_setting_t setting_data[] =
|
|||
END_SUB_GROUP()
|
||||
END_GROUP()
|
||||
|
||||
/*********/
|
||||
/* VIDEO */
|
||||
/*********/
|
||||
START_GROUP("Video")
|
||||
START_SUB_GROUP("Monitor")
|
||||
CONFIG_INT(g_settings.video.monitor_index, "video_monitor_index", "Monitor Index")
|
||||
CONFIG_BOOL(g_settings.video.fullscreen, "video_fullscreen", "Use Fullscreen mode") // if (!g_extern.force_fullscreen)
|
||||
CONFIG_BOOL(g_settings.video.windowed_fullscreen, "video_windowed_fullscreen", "Windowed Fullscreen Mode")
|
||||
CONFIG_INT(g_settings.video.fullscreen_x, "video_fullscreen_x", "Fullscreen Width")
|
||||
CONFIG_INT(g_settings.video.fullscreen_y, "video_fullscreen_y", "Fullscreen Height")
|
||||
CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate", "Refresh Rate")
|
||||
END_SUB_GROUP()
|
||||
|
||||
#if 0
|
||||
/* Video: Window Manager */
|
||||
START_SUB_GROUP("Window Manager")
|
||||
CONFIG_BOOL(g_settings.video.disable_composition, "video_disable_composition", "Disable WM Composition")
|
||||
END_SUB_GROUP()
|
||||
#endif
|
||||
|
||||
START_SUB_GROUP("Aspect")
|
||||
CONFIG_BOOL(g_settings.video.force_aspect, "video_force_aspect", "Force aspect ratio")
|
||||
CONFIG_FLOAT(g_settings.video.aspect_ratio, "video_aspect_ratio", "Aspect Ratio")
|
||||
CONFIG_BOOL(g_settings.video.aspect_ratio_auto, "video_aspect_ratio_auto", "Use Auto Aspect Ratio")
|
||||
CONFIG_INT(g_settings.video.aspect_ratio_idx, "aspect_ratio_index", "Aspect Ratio Index")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Scaling")
|
||||
CONFIG_FLOAT(g_settings.video.xscale, "video_xscale", "X Scale")
|
||||
CONFIG_FLOAT(g_settings.video.yscale, "video_yscale", "Y Scale")
|
||||
CONFIG_BOOL(g_settings.video.scale_integer, "video_scale_integer", "Force integer scaling")
|
||||
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.x, "custom_viewport_x", "Custom Viewport X")
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.y, "custom_viewport_y", "Custom Viewport Y")
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.width, "custom_viewport_width", "Custom Viewport Width")
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.height, "custom_viewport_height", "Custom Viewport Height")
|
||||
|
||||
CONFIG_BOOL(g_settings.video.smooth, "video_smooth", "Use bilinear filtering")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Shader")
|
||||
CONFIG_BOOL(g_settings.video.shader_enable, "video_shader_enable", "Enable Shaders")
|
||||
CONFIG_PATH(g_settings.video.shader_dir, "video_shader_dir", "Shader Directory")
|
||||
CONFIG_PATH(g_settings.video.shader_path, "video_shader", "Shader")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Sync")
|
||||
CONFIG_BOOL(g_settings.video.threaded, "video_threaded", "Use threaded video")
|
||||
CONFIG_BOOL(g_settings.video.vsync, "video_vsync", "Use VSync")
|
||||
CONFIG_BOOL(g_settings.video.hard_sync, "video_hard_sync", "Use OpenGL Hard Sync")
|
||||
CONFIG_INT(g_settings.video.hard_sync_frames, "video_hard_sync_frames", "Number of Hard Sync frames") // 0 - 3
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Misc")
|
||||
CONFIG_BOOL(g_settings.video.post_filter_record, "video_post_filter_record", "Post filter record")
|
||||
CONFIG_BOOL(g_settings.video.gpu_record, "video_gpu_record", "GPU Record")
|
||||
CONFIG_BOOL(g_settings.video.gpu_screenshot, "video_gpu_screenshot", "GPU Screenshot")
|
||||
CONFIG_BOOL(g_settings.video.allow_rotate, "video_allow_rotate", "Allow rotation")
|
||||
CONFIG_BOOL(g_settings.video.crop_overscan, "video_crop_overscan", "Crop Overscan")
|
||||
|
||||
#ifdef HAVE_DYLIB
|
||||
CONFIG_PATH(g_settings.video.filter_path, "video_filter", "Software filter"),
|
||||
#endif
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Messages")
|
||||
CONFIG_PATH(g_settings.video.font_path, "video_font_path", "Font Path")
|
||||
CONFIG_FLOAT(g_settings.video.font_size, "video_font_size", "Font Size")
|
||||
CONFIG_BOOL(g_settings.video.font_enable, "video_font_enable", "Font Enable")
|
||||
CONFIG_BOOL(g_settings.video.font_scale, "video_font_scale", "Font Scale")
|
||||
CONFIG_FLOAT(g_settings.video.msg_pos_x, "video_message_pos_x", "Message X Position")
|
||||
CONFIG_FLOAT(g_settings.video.msg_pos_y, "video_message_pos_y", "Message Y Position")
|
||||
/* message color */
|
||||
END_SUB_GROUP()
|
||||
END_GROUP()
|
||||
|
||||
/*********/
|
||||
/* AUDIO */
|
||||
/*********/
|
||||
|
@ -162,8 +245,8 @@ const rarch_setting_t setting_data[] =
|
|||
/* Input: Overlay */
|
||||
#ifdef HAVE_OVERLAY
|
||||
CONFIG_PATH(g_settings.input.overlay, "input_overlay", "Input Overlay")
|
||||
CONFIG_FLOAT(g_settings.input.overlay_opacity, "overlay_opacity", "Overlay Opacity")
|
||||
CONFIG_FLOAT(g_settings.input.overlay_scale, "overlay_scale", "Overlay Scale")
|
||||
CONFIG_FLOAT(g_settings.input.overlay_opacity, "input_overlay_opacity", "Overlay Opacity")
|
||||
CONFIG_FLOAT(g_settings.input.overlay_scale, "input_overlay_scale", "Overlay Scale")
|
||||
#endif
|
||||
|
||||
/* Input: Android */
|
||||
|
@ -175,79 +258,67 @@ const rarch_setting_t setting_data[] =
|
|||
CONFIG_INT(g_settings.input.icade_profile[3], "input_autodetect_icade_profile_pad4", "iCade 4")
|
||||
#endif
|
||||
END_SUB_GROUP()
|
||||
END_GROUP()
|
||||
|
||||
/*********/
|
||||
/* VIDEO */
|
||||
/*********/
|
||||
START_GROUP("Video")
|
||||
START_SUB_GROUP("Monitor")
|
||||
CONFIG_INT(g_settings.video.monitor_index, "video_monitor_index", "Monitor Index")
|
||||
CONFIG_BOOL(g_settings.video.fullscreen, "video_fullscreen", "Use Fullscreen mode") // if (!g_extern.force_fullscreen)
|
||||
CONFIG_BOOL(g_settings.video.windowed_fullscreen, "video_windowed_fullscreen", "Windowed Fullscreen Mode")
|
||||
CONFIG_INT(g_settings.video.fullscreen_x, "video_fullscreen_x", "Fullscreen Width")
|
||||
CONFIG_INT(g_settings.video.fullscreen_y, "video_fullscreen_y", "Fullscreen Height")
|
||||
CONFIG_FLOAT(g_settings.video.refresh_rate, "video_refresh_rate", "Refresh Rate")
|
||||
END_SUB_GROUP()
|
||||
|
||||
/* Video: Window Manager */
|
||||
START_SUB_GROUP("Window Manager")
|
||||
CONFIG_BOOL(g_settings.video.disable_composition, "video_disable_composition", "Disable WM Composition")
|
||||
START_SUB_GROUP("Meta Keys")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_FAST_FORWARD_KEY], 0, "toggle_fast_forward", "Fast forward toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_FAST_FORWARD_HOLD_KEY], 0, "hold_fast_forward", "Fast forward hold")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_LOAD_STATE_KEY], 0, "load_state", "Load state")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_SAVE_STATE_KEY], 0, "save_state", "Save state")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_FULLSCREEN_TOGGLE_KEY], 0, "toggle_fullscreen", "Fullscreen toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_QUIT_KEY], 0, "exit_emulator", "Quit RetroArch")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_STATE_SLOT_PLUS], 0, "state_slot_increase", "Savestate slot +")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_STATE_SLOT_MINUS], 0, "state_slot_decrease", "Savestate slot -")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_REWIND], 0, "rewind", "Rewind")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_MOVIE_RECORD_TOGGLE], 0, "movie_record_toggle", "Movie record toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_PAUSE_TOGGLE], 0, "pause_toggle", "Pause toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_FRAMEADVANCE], 0, "frame_advance", "Frameadvance")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_RESET], 0, "reset", "Reset game")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_SHADER_NEXT], 0, "shader_next", "Next shader")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_SHADER_PREV], 0, "shader_prev", "Previous shader")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_CHEAT_INDEX_PLUS], 0, "cheat_index_plus", "Cheat index +")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_CHEAT_INDEX_MINUS], 0, "cheat_index_minus", "Cheat index -")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_CHEAT_TOGGLE], 0, "cheat_toggle", "Cheat toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_SCREENSHOT], 0, "screenshot", "Take screenshot")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_DSP_CONFIG], 0, "dsp_config", "DSP config")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_MUTE], 0, "audio_mute", "Audio mute toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_NETPLAY_FLIP], 0, "netplay_flip_players", "Netplay flip players")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_SLOWMOTION], 0, "slowmotion", "Slow motion")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ENABLE_HOTKEY], 0, "enable_hotkey", "Enable hotkeys")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_VOLUME_UP], 0, "volume_up", "Volume +")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_VOLUME_DOWN], 0, "volume_down", "Volume -")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_OVERLAY_NEXT], 0, "overlay_next", "Overlay next")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_DISK_EJECT_TOGGLE], 0, "disk_eject_toggle", "Disk eject toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_DISK_NEXT], 0, "disk_next", "Disk next")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_GRAB_MOUSE_TOGGLE], 0, "grab_mouse_toggle", "Grab mouse toggle")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_MENU_TOGGLE], 0, "menu_toggle", "RGUI menu toggle")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Aspect")
|
||||
CONFIG_BOOL(g_settings.video.force_aspect, "video_force_aspect", "Force aspect ratio")
|
||||
CONFIG_FLOAT(g_settings.video.aspect_ratio, "video_aspect_ratio", "Aspect Ratio")
|
||||
CONFIG_INT(g_settings.video.aspect_ratio_idx, "aspect_ratio_index", "Aspect Ratio Index")
|
||||
CONFIG_BOOL(g_settings.video.aspect_ratio_auto, "video_aspect_ratio_auto", "Use Auto Aspect Ratio")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Scaling")
|
||||
CONFIG_FLOAT(g_settings.video.xscale, "video_xscale", "X Scale")
|
||||
CONFIG_FLOAT(g_settings.video.yscale, "video_yscale", "Y Scale")
|
||||
CONFIG_BOOL(g_settings.video.scale_integer, "video_scale_integer", "Force integer scaling")
|
||||
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.x, "custom_viewport_x", "Custom Viewport X")
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.y, "custom_viewport_y", "Custom Viewport Y")
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.width, "custom_viewport_width", "Custom Viewport Width")
|
||||
CONFIG_INT(g_extern.console.screen.viewports.custom_vp.height, "custom_viewport_height", "Custom Viewport Height")
|
||||
|
||||
CONFIG_BOOL(g_settings.video.smooth, "video_smooth", "Use bilinear filtering")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Shader")
|
||||
CONFIG_BOOL(g_settings.video.shader_enable, "video_shader_enable", "Enable Shaders")
|
||||
CONFIG_PATH(g_settings.video.shader_dir, "video_shader_dir", "Shader Directory")
|
||||
CONFIG_PATH(g_settings.video.shader_path, "video_shader", "Shader")
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Sync")
|
||||
CONFIG_BOOL(g_settings.video.threaded, "video_threaded", "Use threaded video")
|
||||
CONFIG_BOOL(g_settings.video.vsync, "video_vsync", "Use VSync")
|
||||
CONFIG_BOOL(g_settings.video.hard_sync, "video_hard_sync", "Use OpenGL Hard Sync")
|
||||
CONFIG_INT(g_settings.video.hard_sync_frames, "video_hard_sync_frames", "Number of Hard Sync frames") // 0 - 3
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Misc")
|
||||
CONFIG_BOOL(g_settings.video.post_filter_record, "video_post_filter_record", "Post filter record")
|
||||
CONFIG_BOOL(g_settings.video.gpu_record, "video_gpu_record", "GPU Record")
|
||||
CONFIG_BOOL(g_settings.video.gpu_screenshot, "video_gpu_screenshot", "GPU Screenshot")
|
||||
CONFIG_BOOL(g_settings.video.allow_rotate, "video_allow_rotate", "Allow rotation")
|
||||
CONFIG_BOOL(g_settings.video.crop_overscan, "video_crop_overscan", "Crop Overscan")
|
||||
|
||||
#ifdef HAVE_DYLIB
|
||||
CONFIG_PATH(g_settings.video.filter_path, "video_filter", "Software filter"),
|
||||
#endif
|
||||
END_SUB_GROUP()
|
||||
|
||||
START_SUB_GROUP("Messages")
|
||||
CONFIG_PATH(g_settings.video.font_path, "video_font_path", "Font Path")
|
||||
CONFIG_FLOAT(g_settings.video.font_size, "video_font_size", "Font Size")
|
||||
CONFIG_BOOL(g_settings.video.font_enable, "video_font_enable", "Font Enable")
|
||||
CONFIG_BOOL(g_settings.video.font_scale, "video_font_scale", "Font Scale")
|
||||
CONFIG_FLOAT(g_settings.video.msg_pos_x, "video_message_pos_x", "Message X Position")
|
||||
CONFIG_FLOAT(g_settings.video.msg_pos_y, "video_message_pos_y", "Message Y Position")
|
||||
/* message color */
|
||||
START_SUB_GROUP("Player 1")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_B], 1, "b", "B button (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_Y], 1, "y", "Y button (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_SELECT],1, "select", "Select button")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_START], 1, "start", "Start button")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_UP], 1, "up", "Up D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_DOWN], 1, "down", "Down D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_LEFT], 1, "left", "Left D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_RIGHT], 1, "right", "Right D-pad")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_A], 1, "a", "A button (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_X], 1, "x", "X button (top)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L], 1, "l", "L button (left shoulder)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R], 1, "r", "R button (right shoulder)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L2], 1, "l2", "L2 button (left shoulder #2)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R2], 1, "r2", "R2 button (right shoulder #2)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_L3], 1, "l3", "L3 button (left analog button)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RETRO_DEVICE_ID_JOYPAD_R3], 1, "r3", "R3 button (right analog button)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_TURBO_ENABLE], 1, "turbo", "Turbo enable")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_PLUS], 1, "l_x_plus", "Left analog X+ (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_X_MINUS], 1, "l_x_minus", "Left analog X- (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_PLUS], 1, "l_y_plus", "Left analog Y+ (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_LEFT_Y_MINUS], 1, "l_y_minus", "Left analog Y- (up)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_PLUS], 1, "r_x_plus", "Right analog X+ (right)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_X_MINUS], 1, "r_x_minus", "Right analog X- (left)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_PLUS], 1, "r_y_plus", "Right analog Y+ (down)")
|
||||
CONFIG_BIND(g_settings.input.binds[0][RARCH_ANALOG_RIGHT_Y_MINUS], 1, "r_y_minus", "Right analog Y- (up)")
|
||||
END_SUB_GROUP()
|
||||
END_GROUP()
|
||||
|
||||
|
@ -266,4 +337,11 @@ const rarch_setting_t setting_data[] =
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
// HACK
|
||||
#undef g_settings
|
||||
#undef g_extern
|
||||
|
||||
// Keyboard
|
||||
#include "keycode.h"
|
||||
|
||||
#endif
|
|
@ -57,7 +57,7 @@ NSString* objc_get_value_from_config(config_file_t* config, NSString* name, NSSt
|
|||
if (config)
|
||||
config_get_string(config, [name UTF8String], &data);
|
||||
|
||||
NSString* result = data ? [NSString stringWithUTF8String:data] : defaultValue;
|
||||
NSString* result = data ? @(data) : defaultValue;
|
||||
free(data);
|
||||
return result;
|
||||
}
|
||||
|
@ -110,6 +110,11 @@ char* ios_get_rarch_system_directory()
|
|||
return self.sections[indexPath.section][indexPath.row + 1];
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
self.sections = [NSMutableArray array];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
@end
|
||||
|
||||
#endif
|
|
@ -34,7 +34,7 @@ void ios_add_log_message(const char* format, ...)
|
|||
va_start(args, format);
|
||||
vsnprintf(buffer, 512, format, args);
|
||||
va_end(args);
|
||||
[g_messages addObject:[NSString stringWithUTF8String: buffer]];
|
||||
[g_messages addObject:@(buffer)];
|
||||
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
|
||||
#include "../../../RetroArch/rarch_wrapper.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
|
||||
#define BUILDING_BTDYNAMIC
|
||||
#include "btdynamic.h"
|
|
@ -20,7 +20,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../../RetroArch/rarch_wrapper.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
#include "btdynamic.h"
|
||||
#include "btpad.h"
|
||||
#include "btpad_queue.h"
|
|
@ -18,7 +18,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "boolean.h"
|
||||
#include "../../../RetroArch/rarch_wrapper.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
|
||||
#include "btdynamic.h"
|
||||
#include "btpad.h"
|
||||
|
@ -37,7 +37,7 @@ struct btpad_ps3_data
|
|||
|
||||
static void btpad_ps3_send_control(struct btpad_ps3_data* device)
|
||||
{
|
||||
// TODO: Can this be modified to turn of motion tracking?
|
||||
// TODO: Can this be modified to turn off motion tracking?
|
||||
static uint8_t report_buffer[] = {
|
||||
0x52, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
@ -18,7 +18,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "boolean.h"
|
||||
#include "../../../RetroArch/rarch_wrapper.h"
|
||||
#include "apple/common/rarch_wrapper.h"
|
||||
|
||||
#include "btdynamic.h"
|
||||
#include "btpad.h"
|
|
@ -16,7 +16,7 @@
|
|||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#import "../RetroArch/RetroArch_Apple.h"
|
||||
#import "apple/common/RetroArch_Apple.h"
|
||||
#import "views.h"
|
||||
|
||||
#include "conf/config_file.h"
|
||||
|
@ -29,50 +29,47 @@
|
|||
{
|
||||
NSString* _path;
|
||||
NSMutableArray* _sectionNames;
|
||||
id<RADirectoryListDelegate> _delegate;
|
||||
}
|
||||
|
||||
+ (id)directoryListAtBrowseRoot
|
||||
{
|
||||
NSString* rootPath = RetroArch_iOS.get.documentsDirectory;
|
||||
NSString* ragPath = [rootPath stringByAppendingPathComponent:@"RetroArchGames"];
|
||||
RADirectoryList* list = [RADirectoryList directoryListForPath:path_is_directory(ragPath.UTF8String) ? ragPath : rootPath];
|
||||
return list;
|
||||
}
|
||||
|
||||
+ (id)directoryListForPath:(NSString*)path
|
||||
{
|
||||
// NOTE: Don't remove or ignore this abstraction, this function will be expanded when cover art comes back.
|
||||
return [[RADirectoryList alloc] initWithPath:path];
|
||||
}
|
||||
|
||||
- (id)initWithPath:(NSString*)path
|
||||
- (id)initWithPath:(NSString*)path delegate:(id<RADirectoryListDelegate>)delegate
|
||||
{
|
||||
_path = path;
|
||||
_delegate = delegate;
|
||||
|
||||
self = [super initWithStyle:UITableViewStylePlain];
|
||||
self.title = path.lastPathComponent;
|
||||
self.hidesHeaders = YES;
|
||||
|
||||
NSMutableArray *toolbarButtons = [[NSMutableArray alloc] initWithCapacity:3];
|
||||
NSMutableArray *toolbarButtons = [[NSMutableArray alloc] initWithCapacity:3];
|
||||
|
||||
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)];
|
||||
refreshButton.style = UIBarButtonItemStyleBordered;
|
||||
[toolbarButtons addObject:refreshButton];
|
||||
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)];
|
||||
refreshButton.style = UIBarButtonItemStyleBordered;
|
||||
[toolbarButtons addObject:refreshButton];
|
||||
|
||||
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
|
||||
[toolbarButtons addObject:flexibleSpace];
|
||||
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
|
||||
[toolbarButtons addObject:flexibleSpace];
|
||||
|
||||
UIBarButtonItem *newFolderButton = [[UIBarButtonItem alloc] initWithTitle:@"New Folder" style:UIBarButtonItemStyleBordered target:self action:@selector(createNewFolder)];
|
||||
[toolbarButtons addObject:newFolderButton];
|
||||
UIBarButtonItem *newFolderButton = [[UIBarButtonItem alloc] initWithTitle:@"New Folder" style:UIBarButtonItemStyleBordered target:self action:@selector(createNewFolder)];
|
||||
[toolbarButtons addObject:newFolderButton];
|
||||
|
||||
[[[RetroArch_iOS get] toolbar] setItems:toolbarButtons];
|
||||
[self setToolbarItems:toolbarButtons];
|
||||
|
||||
[self refresh];
|
||||
[[[RetroArch_iOS get] toolbar] setItems:toolbarButtons];
|
||||
[self setToolbarItems:toolbarButtons];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[self refresh];
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated
|
||||
{
|
||||
[self reset];
|
||||
}
|
||||
|
||||
- (void)refresh
|
||||
{
|
||||
static const char sectionNames[28] = { '/', '#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||
|
@ -104,7 +101,7 @@
|
|||
section = contents->elems[i].attr.b ? 0 : section;
|
||||
|
||||
RADirectoryItem* item = RADirectoryItem.new;
|
||||
item.path = [NSString stringWithUTF8String:contents->elems[i].data];
|
||||
item.path = @(contents->elems[i].data);
|
||||
item.isDirectory = contents->elems[i].attr.b;
|
||||
[sectionLists[section] addObject:item];
|
||||
}
|
||||
|
@ -127,37 +124,27 @@
|
|||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = (RADirectoryItem*)[self itemForIndexPath:indexPath];
|
||||
|
||||
if(path.isDirectory)
|
||||
[[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListForPath:path.path] animated:YES];
|
||||
else
|
||||
{
|
||||
if (access(_path.UTF8String, R_OK | W_OK | X_OK))
|
||||
apple_display_alert(@"The directory containing the selected file has limited permissions. This may "
|
||||
"prevent zipped games from loading, and will cause some cores to not function.", 0);
|
||||
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES];
|
||||
}
|
||||
[_delegate directoryList:self itemWasSelected:[self itemForIndexPath:indexPath]];
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = (RADirectoryItem*)[self itemForIndexPath:indexPath];
|
||||
static NSString *CellIdentifier = @"path";
|
||||
static NSString* const cell_types[2] = { @"file", @"folder" };
|
||||
static NSString* const icon_types[2] = { @"ic_file", @"ic_dir" };
|
||||
static const UITableViewCellAccessoryType accessory_types[2] = { UITableViewCellAccessoryDetailDisclosureButton,
|
||||
UITableViewCellAccessoryDisclosureIndicator };
|
||||
RADirectoryItem* path = [self itemForIndexPath:indexPath];
|
||||
uint32_t type_id = path.isDirectory ? 1 : 0;
|
||||
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
cell.textLabel.text = [path.path lastPathComponent];
|
||||
cell.accessoryType = (path.isDirectory) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
|
||||
|
||||
if (path.isDirectory) {
|
||||
cell.imageView.image = [UIImage imageNamed:@"ic_dir"];
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
} else {
|
||||
cell.imageView.image = [UIImage imageNamed:@"ic_file"];
|
||||
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:cell_types[type_id]];
|
||||
if (!cell)
|
||||
{
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cell_types[type_id]];
|
||||
cell.imageView.image = [UIImage imageNamed:icon_types[type_id]];
|
||||
cell.accessoryType = accessory_types[type_id];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [path.path lastPathComponent];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
@ -224,26 +211,25 @@
|
|||
|
||||
@implementation RAModuleList
|
||||
{
|
||||
NSString* _game;
|
||||
id<RAModuleListDelegate> _delegate;
|
||||
}
|
||||
|
||||
- (id)initWithGame:(NSString*)path
|
||||
- (id)initWithGame:(NSString*)path delegate:(id<RAModuleListDelegate>)delegate
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStyleGrouped];
|
||||
[self setTitle:[path lastPathComponent]];
|
||||
|
||||
_game = path;
|
||||
[self setTitle:path ? [path lastPathComponent] : @"Cores"];
|
||||
_delegate = delegate;
|
||||
|
||||
// Load the modules with their data
|
||||
NSArray* moduleList = [RAModuleInfo getModules];
|
||||
NSArray* moduleList = apple_get_modules();
|
||||
|
||||
NSMutableArray* supported = [NSMutableArray arrayWithObject:@"Suggested Cores"];
|
||||
NSMutableArray* other = [NSMutableArray arrayWithObject:@"Other Cores"];
|
||||
|
||||
for (RAModuleInfo* i in moduleList)
|
||||
{
|
||||
if ([i supportsFileAtPath:_game]) [supported addObject:i];
|
||||
else [other addObject:i];
|
||||
if (path && [i supportsFileAtPath:path]) [supported addObject:i];
|
||||
else [other addObject:i];
|
||||
}
|
||||
|
||||
if (supported.count > 1)
|
||||
|
@ -257,7 +243,7 @@
|
|||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
apple_run_core((RAModuleInfo*)[self itemForIndexPath:indexPath], _game.UTF8String);
|
||||
[_delegate moduleList:self itemWasSelected:[self itemForIndexPath:indexPath]];
|
||||
}
|
||||
|
||||
- (void)infoButtonTapped:(id)sender
|
||||
|
@ -363,21 +349,8 @@
|
|||
NSString *directoryPath = [currentDirectoryPath stringByAppendingPathComponent:cell.textLabel.text];
|
||||
NSString *newPath = [directoryPath stringByAppendingPathComponent:fileName];
|
||||
|
||||
BOOL didMove = [[NSFileManager defaultManager] moveItemAtPath:selectedFilePath toPath:newPath error:nil];
|
||||
|
||||
if (didMove) {
|
||||
NSArray *viewsControllers = [[self presentingViewController] childViewControllers];
|
||||
|
||||
// Searches for RADirectoryList instance and call the refresh method
|
||||
for (int i = 0; i < viewsControllers.count; i++) {
|
||||
if ([viewsControllers[i] isKindOfClass:[RADirectoryList class]]) {
|
||||
[viewsControllers[i] refresh];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (![[NSFileManager defaultManager] moveItemAtPath:selectedFilePath toPath:newPath error:nil])
|
||||
apple_display_alert(@"It was not possible to move the file", 0);
|
||||
}
|
||||
|
||||
[self dismissViewController];
|
||||
}
|
||||
|
|
|
@ -17,22 +17,28 @@
|
|||
#ifndef __RARCH_IOS_PLATFORM_H
|
||||
#define __RARCH_IOS_PLATFORM_H
|
||||
|
||||
#include "views.h"
|
||||
|
||||
@interface RAGameView : UIViewController
|
||||
+ (RAGameView*)get;
|
||||
- (void)openPauseMenu;
|
||||
- (void)closePauseMenu;
|
||||
@end
|
||||
|
||||
@interface RetroArch_iOS : UINavigationController<UIApplicationDelegate, UINavigationControllerDelegate, RetroArch_Platform>
|
||||
@interface RetroArch_iOS : UINavigationController<UIApplicationDelegate, UINavigationControllerDelegate, RetroArch_Platform,
|
||||
RADirectoryListDelegate, RAModuleListDelegate>
|
||||
|
||||
+ (RetroArch_iOS*)get;
|
||||
|
||||
- (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file;
|
||||
- (void)unloadingCore:(RAModuleInfo*)core;
|
||||
- (NSString*)retroarchConfigPath;
|
||||
|
||||
- (void)refreshSystemConfig;
|
||||
|
||||
@property (strong, nonatomic) NSString* configDirectory; // e.g. /var/mobile/Documents/.RetroArch
|
||||
@property (strong, nonatomic) NSString* globalConfigFile; // e.g. /var/mobile/Documents/.RetroArch/retroarch.cfg
|
||||
@property (strong, nonatomic) NSString* coreDirectory; // e.g. /Applications/RetroArch.app/modules
|
||||
|
||||
@property (strong, nonatomic) NSString* documentsDirectory; // e.g. /var/mobile/Documents
|
||||
@property (strong, nonatomic) NSString* systemDirectory; // e.g. /var/mobile/Documents/.RetroArch
|
||||
@property (strong, nonatomic) NSString* systemConfigPath; // e.g. /var/mobile/Documents/.RetroArch/frontend.cfg
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
#import "RetroArch_Apple.h"
|
||||
#include "rarch_wrapper.h"
|
||||
|
||||
#include "../RetroArch/apple_input.h"
|
||||
#include "apple/common/apple_input.h"
|
||||
|
||||
#import "views.h"
|
||||
#include "input/BTStack/btpad.h"
|
||||
#include "input/BTStack/btdynamic.h"
|
||||
#include "input/BTStack/btpad.h"
|
||||
#include "bluetooth/btpad.h"
|
||||
#include "bluetooth/btdynamic.h"
|
||||
#include "bluetooth/btpad.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
|
@ -85,6 +85,7 @@ static void handle_touch_event(NSArray* touches)
|
|||
@implementation RetroArch_iOS
|
||||
{
|
||||
UIWindow* _window;
|
||||
NSString* _path;
|
||||
|
||||
bool _isGameTop, _isRomList;
|
||||
uint32_t _settingMenusInBackStack;
|
||||
|
@ -111,28 +112,27 @@ static void handle_touch_event(NSArray* touches)
|
|||
self.documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
||||
self.systemDirectory = [self.documentsDirectory stringByAppendingPathComponent:@".RetroArch"];
|
||||
self.systemConfigPath = [self.systemDirectory stringByAppendingPathComponent:@"frontend.cfg"];
|
||||
|
||||
self.configDirectory = self.systemDirectory;
|
||||
self.globalConfigFile = [NSString stringWithFormat:@"%@/retroarch.cfg", self.configDirectory];
|
||||
self.coreDirectory = [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"modules"];
|
||||
|
||||
if (!path_make_and_check_directory(self.documentsDirectory.UTF8String, 0755, R_OK | W_OK | X_OK))
|
||||
apple_display_alert([NSString stringWithFormat:@"Failed to create or access base directory: %@", self.documentsDirectory], 0);
|
||||
else if (!path_make_and_check_directory(self.systemDirectory.UTF8String, 0755, R_OK | W_OK | X_OK))
|
||||
apple_display_alert([NSString stringWithFormat:@"Failed to create or access system directory: %@", self.systemDirectory], 0);
|
||||
else
|
||||
{
|
||||
[self pushViewController:[RADirectoryList directoryListAtBrowseRoot] animated:YES];
|
||||
[self refreshSystemConfig];
|
||||
|
||||
if (apple_use_tv_mode)
|
||||
apple_run_core(nil, 0);
|
||||
}
|
||||
[self beginBrowsingForFile];
|
||||
|
||||
|
||||
// Warn if there are no cores present
|
||||
if ([RAModuleInfo getModules].count == 0)
|
||||
if (apple_get_modules().count == 0)
|
||||
apple_display_alert(@"No libretro cores were found. You will not be able to play any games.", 0);
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
apple_exit_stasis();
|
||||
apple_exit_stasis(false);
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
|
@ -140,6 +140,45 @@ static void handle_touch_event(NSArray* touches)
|
|||
apple_enter_stasis();
|
||||
}
|
||||
|
||||
#pragma mark Frontend Browsing Logic
|
||||
- (void)beginBrowsingForFile
|
||||
{
|
||||
NSString* rootPath = RetroArch_iOS.get.documentsDirectory;
|
||||
NSString* ragPath = [rootPath stringByAppendingPathComponent:@"RetroArchGames"];
|
||||
NSString* target = path_is_directory(ragPath.UTF8String) ? ragPath : rootPath;
|
||||
|
||||
[self pushViewController:[[RADirectoryList alloc] initWithPath:target delegate:self] animated:YES];
|
||||
|
||||
[self refreshSystemConfig];
|
||||
if (apple_use_tv_mode)
|
||||
apple_run_core(nil, 0);
|
||||
|
||||
}
|
||||
|
||||
- (bool)directoryList:(id)list itemWasSelected:(RADirectoryItem*)path
|
||||
{
|
||||
if(path.isDirectory)
|
||||
[[RetroArch_iOS get] pushViewController:[[RADirectoryList alloc] initWithPath:path.path delegate:self] animated:YES];
|
||||
else
|
||||
{
|
||||
_path = path.path;
|
||||
|
||||
if (access([path.path stringByDeletingLastPathComponent].UTF8String, R_OK | W_OK | X_OK))
|
||||
apple_display_alert(@"The directory containing the selected file has limited permissions. This may "
|
||||
"prevent zipped games from loading, and will cause some cores to not function.", 0);
|
||||
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path delegate:self] animated:YES];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (bool)moduleList:(id)list itemWasSelected:(RAModuleInfo*)module
|
||||
{
|
||||
apple_run_core(module, _path.UTF8String);
|
||||
return true;
|
||||
}
|
||||
|
||||
// UINavigationControllerDelegate
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
||||
{
|
||||
|
@ -217,16 +256,6 @@ static void handle_touch_event(NSArray* touches)
|
|||
btpad_set_inquiry_state(true);
|
||||
}
|
||||
|
||||
- (NSString*)retroarchConfigPath
|
||||
{
|
||||
return self.systemDirectory;
|
||||
}
|
||||
|
||||
- (NSString*)corePath
|
||||
{
|
||||
return [NSBundle.mainBundle.bundlePath stringByAppendingPathComponent:@"modules"];
|
||||
}
|
||||
|
||||
#pragma mark FRONTEND CONFIG
|
||||
- (void)refreshSystemConfig
|
||||
{
|
||||
|
@ -259,7 +288,7 @@ static void handle_touch_event(NSArray* touches)
|
|||
ios_set_bluetooth_mode(objc_get_value_from_config(conf, @"ios_btmode", @"keyboard"));
|
||||
|
||||
bool val;
|
||||
apple_use_tv_mode = config_get_bool(conf, "ios_tv_mode", & val) && val;
|
||||
apple_use_tv_mode = config_get_bool(conf, "ios_tv_mode", &val) && val;
|
||||
|
||||
config_file_free(conf);
|
||||
}
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import "../RetroArch/RetroArch_Apple.h"
|
||||
#import "apple/common/RetroArch_Apple.h"
|
||||
#import "views.h"
|
||||
|
||||
#include "../RetroArch/apple_input.h"
|
||||
#include "../RetroArch/keycode.h"
|
||||
#include "input/BTStack/btdynamic.h"
|
||||
#include "input/BTStack/btpad.h"
|
||||
#include "apple/common/apple_input.h"
|
||||
#include "apple/common/keycode.h"
|
||||
#include "bluetooth/btdynamic.h"
|
||||
#include "bluetooth/btpad.h"
|
||||
|
||||
enum SettingTypes
|
||||
{
|
||||
|
@ -275,7 +275,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player)
|
|||
- (id)initWithModule:(RAModuleInfo*)module
|
||||
{
|
||||
_module = module;
|
||||
_configPath = _module ? _module.configPath : RAModuleInfo.globalConfigPath;
|
||||
_configPath = _module ? _module.configFile : apple_platform.globalConfigFile;
|
||||
|
||||
config_file_t* config = config_file_new([_configPath UTF8String]);
|
||||
|
||||
|
@ -308,7 +308,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player)
|
|||
|
||||
[NSArray arrayWithObjects:@"Input",
|
||||
subpath_setting(config, @"input_overlay", @"Input Overlay", @"", overlay_path, @"cfg"),
|
||||
range_setting(config, @"overlay_opacity", @"Overlay Opacity", @"1.0", 0.0, 1.0),
|
||||
range_setting(config, @"input_overlay_opacity", @"Overlay Opacity", @"1.0", 0.0, 1.0),
|
||||
group_setting(@"System Keys", [NSArray arrayWithObjects:
|
||||
// TODO: Many of these strings will be cut off on an iPhone
|
||||
[NSArray arrayWithObjects:@"System Keys",
|
||||
|
@ -408,7 +408,7 @@ static void bluetooth_option_changed(RASettingData* setting)
|
|||
[modules addObject:@"Cores"];
|
||||
[modules addObject:custom_action(@"Global Core Config", nil, nil, 0)];
|
||||
|
||||
NSArray* moduleList = [RAModuleInfo getModules];
|
||||
NSArray* moduleList = apple_get_modules();
|
||||
for (RAModuleInfo* i in moduleList)
|
||||
{
|
||||
[modules addObject:custom_action(i.description, nil, i, reload_core_config_state)];
|
||||
|
@ -840,97 +840,18 @@ static void bluetooth_option_changed(RASettingData* setting)
|
|||
|
||||
- (void)checkInput
|
||||
{
|
||||
// Keyboard
|
||||
static const struct
|
||||
{
|
||||
const char* const keyname;
|
||||
const uint32_t hid_id;
|
||||
} ios_key_name_map[] = {
|
||||
{ "left", KEY_Left }, { "right", KEY_Right },
|
||||
{ "up", KEY_Up }, { "down", KEY_Down },
|
||||
{ "enter", KEY_Enter }, { "kp_enter", KP_Enter },
|
||||
{ "space", KEY_Space }, { "tab", KEY_Tab },
|
||||
{ "shift", KEY_LeftShift }, { "rshift", KEY_RightShift },
|
||||
{ "ctrl", KEY_LeftControl }, { "alt", KEY_LeftAlt },
|
||||
{ "escape", KEY_Escape }, { "backspace", KEY_DeleteForward },
|
||||
{ "backquote", KEY_Grave }, { "pause", KEY_Pause },
|
||||
int32_t value = 0;
|
||||
|
||||
{ "f1", KEY_F1 }, { "f2", KEY_F2 },
|
||||
{ "f3", KEY_F3 }, { "f4", KEY_F4 },
|
||||
{ "f5", KEY_F5 }, { "f6", KEY_F6 },
|
||||
{ "f7", KEY_F7 }, { "f8", KEY_F8 },
|
||||
{ "f9", KEY_F9 }, { "f10", KEY_F10 },
|
||||
{ "f11", KEY_F11 }, { "f12", KEY_F12 },
|
||||
|
||||
{ "num0", KEY_0 }, { "num1", KEY_1 },
|
||||
{ "num2", KEY_2 }, { "num3", KEY_3 },
|
||||
{ "num4", KEY_4 }, { "num5", KEY_5 },
|
||||
{ "num6", KEY_6 }, { "num7", KEY_7 },
|
||||
{ "num8", KEY_8 }, { "num9", KEY_9 },
|
||||
if ((value = apple_input_find_any_key()))
|
||||
_value->value = @(apple_keycode_hidusage_to_name(value));
|
||||
else if ((value = apple_input_find_any_button(0)) >= 0)
|
||||
_value->button_bind = [NSString stringWithFormat:@"%d", value];
|
||||
else if ((value = apple_input_find_any_axis(0)))
|
||||
_value->axis_bind = [NSString stringWithFormat:@"%s%d", (value > 0) ? "+" : "-", value - 1];
|
||||
else
|
||||
return;
|
||||
|
||||
{ "insert", KEY_Insert }, { "del", KEY_DeleteForward },
|
||||
{ "home", KEY_Home }, { "end", KEY_End },
|
||||
{ "pageup", KEY_PageUp }, { "pagedown", KEY_PageDown },
|
||||
|
||||
{ "add", KP_Add }, { "subtract", KP_Subtract },
|
||||
{ "multiply", KP_Multiply }, { "divide", KP_Divide },
|
||||
{ "keypad0", KP_0 }, { "keypad1", KP_1 },
|
||||
{ "keypad2", KP_2 }, { "keypad3", KP_3 },
|
||||
{ "keypad4", KP_4 }, { "keypad5", KP_5 },
|
||||
{ "keypad6", KP_6 }, { "keypad7", KP_7 },
|
||||
{ "keypad8", KP_8 }, { "keypad9", KP_9 },
|
||||
|
||||
{ "period", KEY_Period }, { "capslock", KEY_CapsLock },
|
||||
{ "numlock", KP_NumLock }, { "print_screen", KEY_PrintScreen },
|
||||
{ "scroll_lock", KEY_ScrollLock },
|
||||
|
||||
{ "a", KEY_A }, { "b", KEY_B }, { "c", KEY_C }, { "d", KEY_D },
|
||||
{ "e", KEY_E }, { "f", KEY_F }, { "g", KEY_G }, { "h", KEY_H },
|
||||
{ "i", KEY_I }, { "j", KEY_J }, { "k", KEY_K }, { "l", KEY_L },
|
||||
{ "m", KEY_M }, { "n", KEY_N }, { "o", KEY_O }, { "p", KEY_P },
|
||||
{ "q", KEY_Q }, { "r", KEY_R }, { "s", KEY_S }, { "t", KEY_T },
|
||||
{ "u", KEY_U }, { "v", KEY_V }, { "w", KEY_W }, { "x", KEY_X },
|
||||
{ "y", KEY_Y }, { "z", KEY_Z },
|
||||
|
||||
{ "nul", 0x00},
|
||||
};
|
||||
|
||||
for (int i = 0; ios_key_name_map[i].hid_id; i++)
|
||||
{
|
||||
if (g_current_input_data.keys[ios_key_name_map[i].hid_id])
|
||||
{
|
||||
_value->value = [NSString stringWithUTF8String:ios_key_name_map[i].keyname];
|
||||
[self finish];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad Buttons
|
||||
uint32_t buttons = g_current_input_data.pad_buttons[_value->player] |
|
||||
((_value->player == 0) ? apple_input_get_icade_buttons() : 0);
|
||||
|
||||
for (int i = 0; buttons && i < sizeof(buttons) * 8; i++)
|
||||
{
|
||||
if (buttons & (1 << i))
|
||||
{
|
||||
_value->button_bind = [NSString stringWithFormat:@"%d", i];
|
||||
[self finish];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad Axis
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value = g_current_input_data.pad_axis[_value->player][i];
|
||||
|
||||
if (abs(value) > 0x1000)
|
||||
{
|
||||
_value->axis_bind = [NSString stringWithFormat:@"%s%d", (value > 0x1000) ? "+" : "-", i];
|
||||
[self finish];
|
||||
break;
|
||||
}
|
||||
}
|
||||
[self finish];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
- (id)initWithStyle:(UITableViewStyle)style;
|
||||
- (id)itemForIndexPath:(NSIndexPath*)indexPath;
|
||||
- (void)reset;
|
||||
@end
|
||||
|
||||
// browser.m
|
||||
|
@ -38,17 +39,22 @@
|
|||
@end
|
||||
|
||||
// browser.m
|
||||
@protocol RADirectoryListDelegate
|
||||
- (bool)directoryList:(id)list itemWasSelected:(RADirectoryItem*)path;
|
||||
@end
|
||||
|
||||
@interface RADirectoryList : RATableViewController <UIActionSheetDelegate>
|
||||
@property (nonatomic, weak) RADirectoryItem *selectedItem;
|
||||
|
||||
+ (id)directoryListAtBrowseRoot;
|
||||
+ (id)directoryListForPath:(NSString*)path;
|
||||
- (id)initWithPath:(NSString*)path;
|
||||
- (id)initWithPath:(NSString*)path delegate:(id<RADirectoryListDelegate>)delegate;
|
||||
@end
|
||||
|
||||
// browser.m
|
||||
@protocol RAModuleListDelegate
|
||||
- (bool)moduleList:(id)list itemWasSelected:(RAModuleInfo*)module;
|
||||
@end
|
||||
|
||||
@interface RAModuleList : RATableViewController
|
||||
- (id)initWithGame:(NSString*)path;
|
||||
- (id)initWithGame:(NSString*)path delegate:(id<RAModuleListDelegate>)delegate;
|
||||
@end
|
||||
|
||||
// browser.m
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#include "../boolean.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef OSX
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#endif
|
||||
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AUComponent.h>
|
||||
|
@ -93,6 +97,48 @@ static OSStatus audio_write_cb(void *userdata, AudioUnitRenderActionFlags *actio
|
|||
return noErr;
|
||||
}
|
||||
|
||||
#ifdef OSX
|
||||
static void choose_output_device(coreaudio_t *dev, const char* device)
|
||||
{
|
||||
AudioObjectPropertyAddress propaddr =
|
||||
{
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
UInt32 size = 0;
|
||||
|
||||
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propaddr, 0, 0, &size) != noErr)
|
||||
return;
|
||||
|
||||
UInt32 deviceCount = size / sizeof(AudioDeviceID);
|
||||
AudioDeviceID *devices = malloc(size);
|
||||
|
||||
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject, &propaddr, 0, 0, &size, devices) != noErr)
|
||||
goto done;
|
||||
|
||||
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
||||
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
||||
size = 1024;
|
||||
|
||||
for (unsigned i = 0; i < deviceCount; i ++)
|
||||
{
|
||||
char device_name[1024];
|
||||
device_name[0] = 0;
|
||||
|
||||
if (AudioObjectGetPropertyData(devices[i], &propaddr, 0, 0, &size, device_name) == noErr && strcmp(device_name, device) == 0)
|
||||
{
|
||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
free(devices);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
|
@ -121,6 +167,11 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
|||
if (AudioComponentInstanceNew(comp, &dev->dev) != noErr)
|
||||
goto error;
|
||||
|
||||
#ifdef OSX
|
||||
if (device)
|
||||
choose_output_device(dev, device);
|
||||
#endif
|
||||
|
||||
dev->dev_alive = true;
|
||||
|
||||
// Set audio format
|
||||
|
|
|
@ -115,6 +115,8 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
|
|||
if (!sl)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[SLES]: Requested audio latency: %d ms.", latency);
|
||||
|
||||
GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL));
|
||||
GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE));
|
||||
GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine));
|
||||
|
@ -122,7 +124,11 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
|
|||
GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL));
|
||||
GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE));
|
||||
|
||||
sl->buf_size = next_pow2(32 * latency);
|
||||
if (g_settings.audio.block_frames)
|
||||
sl->buf_size = g_settings.audio.block_frames * 4;
|
||||
else
|
||||
sl->buf_size = next_pow2(32 * latency);
|
||||
|
||||
sl->buf_count = (latency * 4 * out_rate + 500) / 1000;
|
||||
sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size;
|
||||
|
||||
|
@ -137,7 +143,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency)
|
|||
for (unsigned i = 0; i < sl->buf_count; i++)
|
||||
sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size;
|
||||
|
||||
RARCH_LOG("[SLES] : Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n",
|
||||
RARCH_LOG("[SLES]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n",
|
||||
sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count);
|
||||
|
||||
fmt_pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../driver.h"
|
||||
#include "../general.h"
|
||||
|
||||
#include "../emscripten/RWebAudio.h"
|
||||
|
||||
static void ra_free(void *data)
|
||||
{
|
||||
RWebAudioFree();
|
||||
}
|
||||
|
||||
static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
(void)rate;
|
||||
void *data = RWebAudioInit(latency);
|
||||
if (data)
|
||||
g_settings.audio.out_rate = RWebAudioSampleRate();
|
||||
return data;
|
||||
}
|
||||
|
||||
static ssize_t ra_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioWrite(buf, size);
|
||||
}
|
||||
|
||||
static bool ra_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioStop();
|
||||
}
|
||||
|
||||
static void ra_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
(void)data;
|
||||
RWebAudioSetNonblockState(state);
|
||||
}
|
||||
|
||||
static bool ra_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioStart();
|
||||
}
|
||||
|
||||
static bool ra_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t ra_write_avail(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioWriteAvail();
|
||||
}
|
||||
|
||||
static size_t ra_buffer_size(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return RWebAudioBufferSize();
|
||||
}
|
||||
|
||||
const audio_driver_t audio_rwebaudio = {
|
||||
ra_init,
|
||||
ra_write,
|
||||
ra_stop,
|
||||
ra_start,
|
||||
ra_set_nonblock_state,
|
||||
ra_free,
|
||||
ra_use_float,
|
||||
"rwebaudio",
|
||||
ra_write_avail,
|
||||
ra_buffer_size,
|
||||
};
|
||||
|
|
@ -627,7 +627,7 @@ static int16_t qnx_input_state(void *data, const struct retro_keybind **retro_ke
|
|||
|
||||
static bool qnx_input_key_pressed(void *data, int key)
|
||||
{
|
||||
return ((g_extern.lifecycle_state | driver.overlay_state ) & (1ULL << key));
|
||||
return ((g_extern.lifecycle_state | driver.overlay_state.buttons ) & (1ULL << key));
|
||||
}
|
||||
|
||||
static void qnx_input_free_input(void *data)
|
||||
|
|
|
@ -355,6 +355,54 @@ static config_file_t *config_file_new_internal(const char *path, unsigned depth)
|
|||
return conf;
|
||||
}
|
||||
|
||||
config_file_t *config_file_new_from_string(const char *from_string)
|
||||
{
|
||||
struct config_file *conf = (struct config_file*)calloc(1, sizeof(*conf));
|
||||
if (!conf)
|
||||
return NULL;
|
||||
|
||||
if (!from_string)
|
||||
return conf;
|
||||
|
||||
conf->path = NULL;
|
||||
conf->include_depth = 0;
|
||||
|
||||
struct string_list *lines = string_split(from_string, "\n");
|
||||
if (!lines)
|
||||
return conf;
|
||||
|
||||
for (size_t i = 0; i < lines->size; i++)
|
||||
{
|
||||
struct config_entry_list *list = (struct config_entry_list*)calloc(1, sizeof(*list));
|
||||
|
||||
char* line = lines->elems[i].data;
|
||||
|
||||
if (line)
|
||||
{
|
||||
if (parse_line(conf, list, line))
|
||||
{
|
||||
if (conf->entries)
|
||||
{
|
||||
conf->tail->next = list;
|
||||
conf->tail = list;
|
||||
}
|
||||
else
|
||||
{
|
||||
conf->entries = list;
|
||||
conf->tail = list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (list != conf->tail)
|
||||
free(list);
|
||||
}
|
||||
|
||||
string_list_free(lines);
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
config_file_t *config_file_new(const char *path)
|
||||
{
|
||||
return config_file_new_internal(path, 0);
|
||||
|
|
|
@ -41,6 +41,8 @@ typedef struct config_file config_file_t;
|
|||
// Loads a config file. Returns NULL if file doesn't exist.
|
||||
// NULL path will create an empty config file.
|
||||
config_file_t *config_file_new(const char *path);
|
||||
// Load a config file from a string.
|
||||
config_file_t *config_file_new_from_string(const char *from_string);
|
||||
// Frees config file.
|
||||
void config_file_free(config_file_t *conf);
|
||||
|
||||
|
|
14
config.def.h
14
config.def.h
|
@ -63,6 +63,7 @@ enum
|
|||
AUDIO_PS3,
|
||||
AUDIO_XENON360,
|
||||
AUDIO_WII,
|
||||
AUDIO_RWEBAUDIO,
|
||||
AUDIO_NULL,
|
||||
|
||||
INPUT_ANDROID,
|
||||
|
@ -77,6 +78,7 @@ enum
|
|||
INPUT_LINUXRAW,
|
||||
INPUT_APPLE,
|
||||
INPUT_QNX,
|
||||
INPUT_RWEBINPUT,
|
||||
INPUT_NULL
|
||||
};
|
||||
|
||||
|
@ -130,6 +132,8 @@ enum
|
|||
#define AUDIO_DEFAULT_DRIVER AUDIO_SL
|
||||
#elif defined(HAVE_DSOUND)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_DSOUND
|
||||
#elif defined(EMSCRIPTEN)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_RWEBAUDIO
|
||||
#elif defined(HAVE_SDL)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_SDL
|
||||
#elif defined(HAVE_XAUDIO)
|
||||
|
@ -152,6 +156,8 @@ enum
|
|||
#define INPUT_DEFAULT_DRIVER INPUT_ANDROID
|
||||
#elif defined(_WIN32)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_DINPUT
|
||||
#elif defined(EMSCRIPTEN)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_RWEBINPUT
|
||||
#elif defined(HAVE_SDL)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_SDL
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
|
@ -215,6 +221,14 @@ static const bool hard_sync = false;
|
|||
// 2: Etc ...
|
||||
static const unsigned hard_sync_frames = 0;
|
||||
|
||||
// Inserts a black frame inbetween frames.
|
||||
// Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2).
|
||||
static bool black_frame_insertion = false;
|
||||
|
||||
// Uses a custom swap interval for VSync.
|
||||
// Set this to effectively halve monitor refresh rate.
|
||||
static unsigned swap_interval = 1;
|
||||
|
||||
// Threaded video. Will possibly increase performance significantly at cost of worse synchronization and latency.
|
||||
static const bool video_threaded = false;
|
||||
|
||||
|
|
8
driver.c
8
driver.c
|
@ -84,6 +84,9 @@ static const audio_driver_t *audio_drivers[] = {
|
|||
#ifdef GEKKO
|
||||
&audio_gx,
|
||||
#endif
|
||||
#ifdef EMSCRIPTEN
|
||||
&audio_rwebaudio,
|
||||
#endif
|
||||
#ifdef HAVE_NULLAUDIO
|
||||
&audio_null,
|
||||
#endif
|
||||
|
@ -165,6 +168,9 @@ static const input_driver_t *input_drivers[] = {
|
|||
#ifdef __BLACKBERRY_QNX__
|
||||
&input_qnx,
|
||||
#endif
|
||||
#ifdef EMSCRIPTEN
|
||||
&input_rwebinput,
|
||||
#endif
|
||||
#ifdef HAVE_NULLINPUT
|
||||
&input_null,
|
||||
#endif
|
||||
|
@ -1058,7 +1064,7 @@ void uninit_video_input(void)
|
|||
{
|
||||
input_overlay_free(driver.overlay);
|
||||
driver.overlay = NULL;
|
||||
driver.overlay_state = 0;
|
||||
memset(&driver.overlay_state, 0, sizeof(driver.overlay_state));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
6
driver.h
6
driver.h
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include "boolean.h"
|
||||
#include "libretro.h"
|
||||
#include "libretro_private.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "msvc/msvc_compat.h"
|
||||
|
@ -462,7 +462,7 @@ typedef struct driver
|
|||
|
||||
#ifdef HAVE_OVERLAY
|
||||
input_overlay_t *overlay;
|
||||
uint64_t overlay_state;
|
||||
input_overlay_state_t overlay_state;
|
||||
#endif
|
||||
|
||||
// Interface for "poking".
|
||||
|
@ -511,6 +511,7 @@ extern const audio_driver_t audio_coreaudio;
|
|||
extern const audio_driver_t audio_xenon360;
|
||||
extern const audio_driver_t audio_ps3;
|
||||
extern const audio_driver_t audio_gx;
|
||||
extern const audio_driver_t audio_rwebaudio;
|
||||
extern const audio_driver_t audio_null;
|
||||
extern const video_driver_t video_gl;
|
||||
extern const video_driver_t video_psp1;
|
||||
|
@ -536,6 +537,7 @@ extern const input_driver_t input_xinput;
|
|||
extern const input_driver_t input_linuxraw;
|
||||
extern const input_driver_t input_apple;
|
||||
extern const input_driver_t input_qnx;
|
||||
extern const input_driver_t input_rwebinput;
|
||||
extern const input_driver_t input_null;
|
||||
|
||||
#include "driver_funcs.h"
|
||||
|
|
|
@ -56,7 +56,7 @@ static inline bool input_key_pressed_func(int key)
|
|||
bool ret = driver.input->key_pressed(driver.input_data, key);
|
||||
|
||||
#ifdef HAVE_OVERLAY
|
||||
ret |= driver.overlay_state & (UINT64_C(1) << key);
|
||||
ret |= driver.overlay_state.buttons & (UINT64_C(1) << key);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMMAND
|
||||
|
|
43
dynamic.c
43
dynamic.c
|
@ -30,7 +30,7 @@
|
|||
#endif
|
||||
|
||||
#include "boolean.h"
|
||||
#include "libretro.h"
|
||||
#include "libretro_private.h"
|
||||
#include "dynamic_dummy.h"
|
||||
|
||||
#ifdef NEED_DYNAMIC
|
||||
|
@ -93,8 +93,6 @@ unsigned (*pretro_get_region)(void);
|
|||
void *(*pretro_get_memory_data)(unsigned);
|
||||
size_t (*pretro_get_memory_size)(unsigned);
|
||||
|
||||
static bool environment_cb(unsigned cmd, void *data);
|
||||
|
||||
#ifdef HAVE_DYNAMIC
|
||||
#if defined(__APPLE__)
|
||||
#define DYNAMIC_EXT "dylib"
|
||||
|
@ -397,7 +395,7 @@ void init_libretro_sym(bool dummy)
|
|||
|
||||
load_symbols(dummy);
|
||||
|
||||
pretro_set_environment(environment_cb);
|
||||
pretro_set_environment(rarch_environment_cb);
|
||||
}
|
||||
|
||||
void uninit_libretro_sym(void)
|
||||
|
@ -471,7 +469,7 @@ void dylib_close(dylib_t lib)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool environment_cb(unsigned cmd, void *data)
|
||||
bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
|
@ -758,6 +756,41 @@ static bool environment_cb(unsigned cmd, void *data)
|
|||
break;
|
||||
}
|
||||
|
||||
case RETRO_ENVIRONMENT_SET_LIBRETRO_PATH:
|
||||
RARCH_LOG("Environ (Private) SET_LIBRETRO_PATH.\n");
|
||||
|
||||
if (path_file_exists((const char*)data))
|
||||
strlcpy(g_settings.libretro, (const char*)data, sizeof(g_settings.libretro));
|
||||
else
|
||||
return false;
|
||||
break;
|
||||
|
||||
case RETRO_ENVIRONMENT_EXEC:
|
||||
case RETRO_ENVIRONMENT_EXEC_ESCAPE:
|
||||
|
||||
if (data)
|
||||
strlcpy(g_extern.fullpath, (const char*)data, sizeof(g_extern.fullpath));
|
||||
else
|
||||
*g_extern.fullpath = '\0';
|
||||
|
||||
#if !defined( HAVE_DYNAMIC) && defined(RARCH_CONSOLE)
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN);
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME);
|
||||
#elif defined(HAVE_DYNAMIC)
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME);
|
||||
#endif
|
||||
|
||||
if (cmd == RETRO_ENVIRONMENT_EXEC_ESCAPE)
|
||||
{
|
||||
RARCH_LOG("Environ (Private) EXEC_ESCAPE.\n");
|
||||
g_extern.exec = true;
|
||||
}
|
||||
else
|
||||
RARCH_LOG("Environ (Private) EXEC.\n");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
RARCH_LOG("Environ UNSUPPORTED (#%u).\n", cmd);
|
||||
return false;
|
||||
|
|
|
@ -101,6 +101,8 @@ extern unsigned (*pretro_get_region)(void);
|
|||
extern void *(*pretro_get_memory_data)(unsigned);
|
||||
extern size_t (*pretro_get_memory_size)(unsigned);
|
||||
|
||||
extern bool rarch_environment_cb(unsigned cmd, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
unsigned RWebAudioSampleRate(void);
|
||||
void *RWebAudioInit(unsigned latency);
|
||||
ssize_t RWebAudioWrite(const void *buf, size_t size);
|
||||
bool RWebAudioStop(void);
|
||||
bool RWebAudioStart(void);
|
||||
void RWebAudioSetNonblockState(bool state);
|
||||
void RWebAudioFree(void);
|
||||
size_t RWebAudioWriteAvail(void);
|
||||
size_t RWebAudioBufferSize(void);
|
|
@ -0,0 +1,29 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct rwebinput_state
|
||||
{
|
||||
char keys[32];
|
||||
int mouse_x;
|
||||
int mouse_y;
|
||||
char mouse_l;
|
||||
char mouse_r;
|
||||
} rwebinput_state_t;
|
||||
|
||||
int RWebInputInit(void);
|
||||
rwebinput_state_t *RWebInputPoll(int context);
|
||||
void RWebInputDestroy(int context);
|
|
@ -0,0 +1,166 @@
|
|||
//"use strict";
|
||||
|
||||
var LibraryRWebAudio = {
|
||||
$RA__deps: ['$Browser', 'usleep'],
|
||||
$RA: {
|
||||
BUFFER_SIZE: 256,
|
||||
|
||||
context: null,
|
||||
buffers: [],
|
||||
numBuffers: 0,
|
||||
bufIndex: 0,
|
||||
bufOffset: 0,
|
||||
startTime: 0,
|
||||
nonblock: false,
|
||||
currentTimeWorkaround: false,
|
||||
|
||||
setStartTime: function() {
|
||||
if (RA.context.currentTime) {
|
||||
RA.startTime = window['performance']['now']() - RA.context.currentTime * 1000;
|
||||
var time1 = RA.context.currentTime;
|
||||
_usleep(50);
|
||||
if (time1 === RA.context.currentTime) {
|
||||
RA.currentTimeWorkaround = true;
|
||||
if (RA.startTime === 0) throw 'startTime is 0';
|
||||
}
|
||||
Module["resumeMainLoop"]();
|
||||
} else window['setTimeout'](RA.setStartTime, 0);
|
||||
},
|
||||
|
||||
getCurrentPerfTime: function() {
|
||||
if (!RA.currentTimeWorkaround) return RA.context.currentTime;
|
||||
else if (RA.startTime) return (window['performance']['now']() - RA.startTime) / 1000;
|
||||
else throw 'getCurrentPerfTime() called before start time set';
|
||||
},
|
||||
|
||||
process: function(queueBuffers) {
|
||||
var currentTime = RA.getCurrentPerfTime();
|
||||
for (var i = 0; i < RA.bufIndex; i++) {
|
||||
if (RA.buffers[i].endTime < currentTime) {
|
||||
var buf = RA.buffers.splice(i, 1);
|
||||
RA.buffers[RA.numBuffers - 1] = buf[0];
|
||||
i--;
|
||||
RA.bufIndex--;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
fillBuffer: function(buf, samples) {
|
||||
var count = 0;
|
||||
var leftBuffer = RA.buffers[RA.bufIndex].getChannelData(0);
|
||||
var rightBuffer = RA.buffers[RA.bufIndex].getChannelData(1);
|
||||
while (samples && RA.bufOffset !== RA.BUFFER_SIZE) {
|
||||
leftBuffer[RA.bufOffset] = {{{ makeGetValue('buf', 'count * 8', 'float') }}};
|
||||
rightBuffer[RA.bufOffset] = {{{ makeGetValue('buf', 'count * 8 + 4', 'float') }}};
|
||||
RA.bufOffset++;
|
||||
count++;
|
||||
samples--;
|
||||
}
|
||||
|
||||
return count;
|
||||
},
|
||||
|
||||
queueAudio: function() {
|
||||
var index = RA.bufIndex;
|
||||
|
||||
var startTime;
|
||||
if (RA.bufIndex) startTime = RA.buffers[RA.bufIndex - 1].endTime;
|
||||
else startTime = RA.context.currentTime;
|
||||
RA.buffers[index].endTime = startTime + RA.buffers[index].duration;
|
||||
|
||||
var bufferSource = RA.context.createBufferSource();
|
||||
bufferSource.buffer = RA.buffers[index];
|
||||
bufferSource.connect(RA.context.destination);
|
||||
bufferSource.start(startTime);
|
||||
|
||||
RA.bufIndex++;
|
||||
RA.bufOffset = 0;
|
||||
},
|
||||
|
||||
block: function() {
|
||||
do {
|
||||
RA.process();
|
||||
} while (RA.bufIndex === RA.numBuffers - 1);
|
||||
}
|
||||
},
|
||||
|
||||
RWebAudioInit: function(latency) {
|
||||
var ac = window['AudioContext'] || window['webkitAudioContext'];
|
||||
|
||||
if (!ac) return 0;
|
||||
|
||||
RA.context = new ac();
|
||||
|
||||
RA.numBuffers = ((latency * RA.context.sampleRate) / (1000 * RA.BUFFER_SIZE))|0;
|
||||
if (RA.numBuffers < 2) RA.numBuffers = 2;
|
||||
|
||||
for (var i = 0; i < RA.numBuffers; i++) RA.buffers[i] = RA.context.createBuffer(2, RA.BUFFER_SIZE, RA.context.sampleRate);
|
||||
|
||||
RA.nonblock = false;
|
||||
RA.startTime = 0;
|
||||
// chrome hack to get currentTime running
|
||||
RA.context.createGain();
|
||||
window['setTimeout'](RA.setStartTime, 0);
|
||||
Module["pauseMainLoop"]();
|
||||
return 1;
|
||||
},
|
||||
|
||||
RWebAudioSampleRate: function() {
|
||||
return RA.context.sampleRate;
|
||||
},
|
||||
|
||||
RWebAudioWrite: function (buf, size) {
|
||||
RA.process();
|
||||
var samples = size / 8;
|
||||
var count = 0;
|
||||
|
||||
while (samples) {
|
||||
var fill = RA.fillBuffer(buf, samples);
|
||||
samples -= fill;
|
||||
count += fill;
|
||||
buf += fill * 8;
|
||||
|
||||
if (RA.bufOffset === RA.BUFFER_SIZE) {
|
||||
if (RA.bufIndex === RA.numBuffers - 1) {
|
||||
if (RA.nonblock) break;
|
||||
else RA.block();
|
||||
}
|
||||
RA.queueAudio();
|
||||
}
|
||||
}
|
||||
|
||||
return count * 8;
|
||||
},
|
||||
|
||||
RWebAudioStop: function() {
|
||||
RA.bufIndex = 0;
|
||||
RA.bufOffset = 0;
|
||||
return true;
|
||||
},
|
||||
|
||||
RWebAudioStart: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
RWebAudioSetNonblockState: function(state) {
|
||||
RA.nonblock = state;
|
||||
},
|
||||
|
||||
RWebAudioFree: function() {
|
||||
RA.bufIndex = 0;
|
||||
RA.bufOffset = 0;
|
||||
return;
|
||||
},
|
||||
|
||||
RWebAudioBufferSize: function() {
|
||||
return RA.numBuffers * RA.BUFFER_SIZE + RA.BUFFER_SIZE;
|
||||
},
|
||||
|
||||
RWebAudioWriteAvail: function() {
|
||||
RA.process();
|
||||
return ((RA.numBuffers - RA.bufIndex) * RA.BUFFER_SIZE - RA.bufOffset) * 8;
|
||||
}
|
||||
};
|
||||
|
||||
autoAddDeps(LibraryRWebAudio, '$RA');
|
||||
mergeInto(LibraryManager.library, LibraryRWebAudio);
|
|
@ -0,0 +1,108 @@
|
|||
//"use strict";
|
||||
|
||||
var LibraryRWebInput = {
|
||||
$RI__deps: ['$Browser'],
|
||||
$RI: {
|
||||
temp: null,
|
||||
contexts: [],
|
||||
|
||||
eventHandler: function(event) {
|
||||
var i;
|
||||
switch (event.type) {
|
||||
case 'mousemove':
|
||||
var x = event['movementX'] || event['mozMovementX'] || event['webkitMovementX'];
|
||||
var y = event['movementY'] || event['mozMovementY'] || event['webkitMovementY'];
|
||||
for (i = 0; i < RI.contexts.length; i++) {
|
||||
var oldX = {{{ makeGetValue('RI.contexts[i].state', '32', 'i32') }}};
|
||||
var oldY = {{{ makeGetValue('RI.contexts[i].state', '36', 'i32') }}};
|
||||
x += oldX;
|
||||
y += oldY;
|
||||
{{{ makeSetValue('RI.contexts[i].state', '32', 'x', 'i32') }}};
|
||||
{{{ makeSetValue('RI.contexts[i].state', '36', 'y', 'i32') }}};
|
||||
}
|
||||
break;
|
||||
case 'mouseup':
|
||||
case 'mousedown':
|
||||
var value;
|
||||
var offset;
|
||||
if (event.button === 0) offset = 40;
|
||||
else if (event.button === 2) offset = 41;
|
||||
else break;
|
||||
if (event.type === 'mouseup') value = 0;
|
||||
else value = 1;
|
||||
for (i = 0; i < RI.contexts.length; i++) {
|
||||
{{{ makeSetValue('RI.contexts[i].state', 'offset', 'value', 'i8') }}};
|
||||
}
|
||||
break;
|
||||
case 'keyup':
|
||||
case 'keydown':
|
||||
var key = event.keyCode;
|
||||
var offset = key >> 3;
|
||||
var bit = 1 << (key & 7);
|
||||
if (offset >= 32) throw 'key code error! bad code: ' + key;
|
||||
for (i = 0; i < RI.contexts.length; i++) {
|
||||
var value = {{{ makeGetValue('RI.contexts[i].state', 'offset', 'i8') }}};
|
||||
if (event.type === 'keyup') value &= ~bit;
|
||||
else value |= bit;
|
||||
{{{ makeSetValue('RI.contexts[i].state', 'offset', 'value', 'i8') }}};
|
||||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 'blur':
|
||||
case 'visibilitychange':
|
||||
for (i = 0; i < RI.contexts.length; i++) {
|
||||
_memset(RI.contexts[i].state, 0, 42);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
RWebInputInit: function(latency) {
|
||||
if (RI.contexts.length === 0) {
|
||||
document.addEventListener('keyup', RI.eventHandler, false);
|
||||
document.addEventListener('keydown', RI.eventHandler, false);
|
||||
document.addEventListener('mousemove', RI.eventHandler, false);
|
||||
document.addEventListener('mouseup', RI.eventHandler, false);
|
||||
document.addEventListener('mousedown', RI.eventHandler, false);
|
||||
document.addEventListener('blur', RI.eventHandler, false);
|
||||
document.addEventListener('onvisbilitychange', RI.eventHandler, false);
|
||||
}
|
||||
if (RI.temp === null) RI.temp = _malloc(42);
|
||||
|
||||
var s = _malloc(42);
|
||||
_memset(s, 0, 42);
|
||||
RI.contexts.push({
|
||||
state: s
|
||||
});
|
||||
return RI.contexts.length;
|
||||
},
|
||||
|
||||
RWebInputPoll: function(context) {
|
||||
context -= 1;
|
||||
var state = RI.contexts[context].state;
|
||||
_memcpy(RI.temp, state, 42);
|
||||
// reset mouse movements
|
||||
{{{ makeSetValue('RI.contexts[context].state', '32', '0', 'i32') }}};
|
||||
{{{ makeSetValue('RI.contexts[context].state', '36', '0', 'i32') }}};
|
||||
return RI.temp;
|
||||
},
|
||||
|
||||
RWebInputDestroy: function (context) {
|
||||
if (context === RI.contexts.length) {
|
||||
RI.contexts.pop();
|
||||
if (RI.contexts.length === 0) {
|
||||
document.removeEventListener('keyup', RI.eventHandler, false);
|
||||
document.removeEventListener('keydown', RI.eventHandler, false);
|
||||
document.removeEventListener('mousemove', RI.eventHandler, false);
|
||||
document.removeEventListener('mouseup', RI.eventHandler, false);
|
||||
document.removeEventListener('mousedown', RI.eventHandler, false);
|
||||
document.removeEventListener('blur', RI.eventHandler, false);
|
||||
document.removeEventListener('onvisbilitychange', RI.eventHandler, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
autoAddDeps(LibraryRWebInput, '$RI');
|
||||
mergeInto(LibraryManager.library, LibraryRWebInput);
|
|
@ -42,6 +42,8 @@
|
|||
#define EXT_EXECUTABLES "dol|DOL"
|
||||
#define SALAMANDER_FILE "boot.dol"
|
||||
#define DEFAULT_EXE_EXT ".dol"
|
||||
#elif defined(EMSCRIPTEN)
|
||||
#define EXT_EXECUTABLES ""
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -63,9 +63,7 @@ static bool libretro_install_core(const char *path_prefix,
|
|||
return false;
|
||||
}
|
||||
|
||||
strlcpy(g_settings.libretro, new_path,
|
||||
sizeof(g_settings.libretro));
|
||||
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)new_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,12 @@ static const frontend_ctx_driver_t *frontend_ctx_drivers[] = {
|
|||
#if defined(IOS) || defined(OSX)
|
||||
&frontend_ctx_apple,
|
||||
#endif
|
||||
NULL // zero length array is not valid
|
||||
};
|
||||
|
||||
const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++)
|
||||
for (unsigned i = 0; frontend_ctx_drivers[i]; i++)
|
||||
{
|
||||
if (strcmp(frontend_ctx_drivers[i]->ident, ident) == 0)
|
||||
return frontend_ctx_drivers[i];
|
||||
|
@ -51,7 +52,7 @@ const frontend_ctx_driver_t *frontend_ctx_find_driver(const char *ident)
|
|||
|
||||
const frontend_ctx_driver_t *frontend_ctx_init_first(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(frontend_ctx_drivers) / sizeof(frontend_ctx_drivers[0]); i++)
|
||||
for (unsigned i = 0; frontend_ctx_drivers[i]; i++)
|
||||
return frontend_ctx_drivers[i];
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2013 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include "../general.h"
|
||||
#include "../conf/config_file.h"
|
||||
#include "../file.h"
|
||||
#include "../emscripten/RWebAudio.h"
|
||||
|
||||
#ifdef HAVE_RGUI
|
||||
#include "../frontend/menu/rgui.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_RGUI) || defined(HAVE_RMENU) || defined(HAVE_RMENU_XUI)
|
||||
#define HAVE_MENU
|
||||
#else
|
||||
#undef HAVE_MENU
|
||||
#endif
|
||||
|
||||
static bool menuloop;
|
||||
|
||||
static void endloop(void)
|
||||
{
|
||||
g_extern.system.shutdown = false;
|
||||
menu_free();
|
||||
|
||||
if (g_extern.config_save_on_exit && *g_extern.config_path)
|
||||
config_save_file(g_extern.config_path);
|
||||
|
||||
if (g_extern.main_is_init)
|
||||
rarch_main_deinit();
|
||||
|
||||
rarch_deinit_msg_queue();
|
||||
|
||||
#ifdef PERF_TEST
|
||||
rarch_perf_log();
|
||||
#endif
|
||||
|
||||
rarch_main_clear_state();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void mainloop(void)
|
||||
{
|
||||
if (g_extern.system.shutdown)
|
||||
{
|
||||
endloop();
|
||||
}
|
||||
else if (menuloop)
|
||||
{
|
||||
if (!menu_iterate())
|
||||
{
|
||||
menuloop = false;
|
||||
driver_set_nonblock_state(driver.nonblock_state);
|
||||
|
||||
if (driver.audio_data && !audio_start_func())
|
||||
{
|
||||
RARCH_ERR("Failed to resume audio driver. Will continue without audio.\n");
|
||||
g_extern.audio_active = false;
|
||||
}
|
||||
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
|
||||
}
|
||||
}
|
||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME))
|
||||
{
|
||||
load_menu_game_prepare();
|
||||
|
||||
// If ROM load fails, we exit RetroArch. On console it might make more sense to go back to menu though ...
|
||||
if (load_menu_game())
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME);
|
||||
else
|
||||
{
|
||||
#ifdef RARCH_CONSOLE
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME);
|
||||
}
|
||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
|
||||
{
|
||||
bool r;
|
||||
if (g_extern.is_paused && !g_extern.is_oneshot)
|
||||
r = rarch_main_idle_iterate();
|
||||
else
|
||||
r = rarch_main_iterate();
|
||||
if (!r)
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
||||
}
|
||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
|
||||
{
|
||||
g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT;
|
||||
// Menu should always run with vsync on.
|
||||
video_set_nonblock_state_func(false);
|
||||
|
||||
if (driver.audio_data)
|
||||
audio_stop_func();
|
||||
|
||||
menuloop = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_extern.system.shutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
emscripten_set_canvas_size(800, 600);
|
||||
|
||||
rarch_main_clear_state();
|
||||
rarch_init_msg_queue();
|
||||
|
||||
int init_ret;
|
||||
if ((init_ret = rarch_main_init(argc, argv))) return init_ret;
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
menu_init();
|
||||
g_extern.lifecycle_mode_state |= 1ULL << MODE_GAME;
|
||||
|
||||
// If we started a ROM directly from command line,
|
||||
// push it to ROM history.
|
||||
if (!g_extern.libretro_dummy)
|
||||
menu_rom_history_push_current();
|
||||
#endif
|
||||
|
||||
emscripten_set_main_loop(mainloop, g_settings.video.vsync ? 0 : INT_MAX, 1);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -444,27 +444,18 @@ void load_menu_game_history(unsigned game_index)
|
|||
rom_history_get_index(rgui->history,
|
||||
game_index, &path, &core_path, &core_name);
|
||||
|
||||
strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro));
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)core_path);
|
||||
|
||||
if (path)
|
||||
{
|
||||
rgui->load_no_rom = false;
|
||||
strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath));
|
||||
}
|
||||
else
|
||||
{
|
||||
rgui->load_no_rom = true;
|
||||
*g_extern.fullpath = '\0';
|
||||
}
|
||||
|
||||
#if !defined( HAVE_DYNAMIC) && defined(RARCH_CONSOLE)
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN);
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME);
|
||||
#elif defined(HAVE_DYNAMIC)
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)path);
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
libretro_free_system_info(&rgui->info);
|
||||
libretro_get_system_info(g_settings.libretro, &rgui->info, NULL);
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -713,7 +704,7 @@ static uint64_t rgui_input(void)
|
|||
|
||||
#ifdef HAVE_OVERLAY
|
||||
for (unsigned i = 0; i < DEVICE_NAV_LAST; i++)
|
||||
input_state |= driver.overlay_state & menu_nav_binds[0][i].joykey ? (1ULL << i) : 0;
|
||||
input_state |= driver.overlay_state.buttons & menu_nav_binds[0][i].joykey ? (1ULL << i) : 0;
|
||||
#endif
|
||||
#else
|
||||
static const int maps[] = {
|
||||
|
@ -734,7 +725,7 @@ static uint64_t rgui_input(void)
|
|||
input_state |= input_input_state_func(binds,
|
||||
0, RETRO_DEVICE_JOYPAD, 0, maps[i + 0]) ? (1ULL << maps[i + 1]) : 0;
|
||||
#ifdef HAVE_OVERLAY
|
||||
input_state |= (driver.overlay_state & (UINT64_C(1) << maps[i + 0])) ? (1ULL << maps[i + 1]) : 0;
|
||||
input_state |= (driver.overlay_state.buttons & (UINT64_C(1) << maps[i + 0])) ? (1ULL << maps[i + 1]) : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,11 @@ typedef enum
|
|||
RGUI_SETTINGS_VIDEO_VSYNC,
|
||||
RGUI_SETTINGS_VIDEO_HARD_SYNC,
|
||||
RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES,
|
||||
RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION,
|
||||
RGUI_SETTINGS_VIDEO_SWAP_INTERVAL,
|
||||
RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X,
|
||||
RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y,
|
||||
RGUI_SETTINGS_VIDEO_CROP_OVERSCAN,
|
||||
RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO,
|
||||
RGUI_SETTINGS_VIDEO_OPTIONS_LAST,
|
||||
#ifdef HAVE_SHADER_MANAGER
|
||||
|
|
|
@ -418,6 +418,10 @@ static void render_text(rgui_handle_t *rgui)
|
|||
rgui->selection_ptr - TERM_HEIGHT / 2 : 0;
|
||||
size_t end = rgui->selection_ptr + TERM_HEIGHT <= rgui->selection_buf->size ?
|
||||
rgui->selection_ptr + TERM_HEIGHT : rgui->selection_buf->size;
|
||||
|
||||
// Do not scroll if all items are visible.
|
||||
if (rgui->selection_buf->size <= TERM_HEIGHT)
|
||||
begin = 0;
|
||||
|
||||
if (end - begin > TERM_HEIGHT)
|
||||
end = begin + TERM_HEIGHT;
|
||||
|
@ -598,6 +602,21 @@ static void render_text(rgui_handle_t *rgui)
|
|||
case RGUI_SETTINGS_VIDEO_HARD_SYNC:
|
||||
strlcpy(type_str, g_settings.video.hard_sync ? "ON" : "OFF", sizeof(type_str));
|
||||
break;
|
||||
case RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION:
|
||||
strlcpy(type_str, g_settings.video.black_frame_insertion ? "ON" : "OFF", sizeof(type_str));
|
||||
break;
|
||||
case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL:
|
||||
snprintf(type_str, sizeof(type_str), "%u", g_settings.video.swap_interval);
|
||||
break;
|
||||
case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X:
|
||||
snprintf(type_str, sizeof(type_str), "%.1fx", g_settings.video.xscale);
|
||||
break;
|
||||
case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y:
|
||||
snprintf(type_str, sizeof(type_str), "%.1fx", g_settings.video.yscale);
|
||||
break;
|
||||
case RGUI_SETTINGS_VIDEO_CROP_OVERSCAN:
|
||||
strlcpy(type_str, g_settings.video.crop_overscan ? "ON" : "OFF", sizeof(type_str));
|
||||
break;
|
||||
case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES:
|
||||
snprintf(type_str, sizeof(type_str), "%u", g_settings.video.hard_sync_frames);
|
||||
break;
|
||||
|
@ -1500,13 +1519,20 @@ static void rgui_settings_video_options_populate_entries(rgui_handle_t *rgui)
|
|||
rgui_list_push(rgui->selection_buf, "Integer Scale", RGUI_SETTINGS_VIDEO_INTEGER_SCALE, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Aspect Ratio", RGUI_SETTINGS_VIDEO_ASPECT_RATIO, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Custom Ratio", RGUI_SETTINGS_CUSTOM_VIEWPORT, 0);
|
||||
#ifndef RARCH_PERFORMANCE_MODE
|
||||
#if !defined(RARCH_CONSOLE) && !defined(RARCH_MOBILE)
|
||||
rgui_list_push(rgui->selection_buf, "Toggle Fullscreen", RGUI_SETTINGS_TOGGLE_FULLSCREEN, 0);
|
||||
#endif
|
||||
rgui_list_push(rgui->selection_buf, "Rotation", RGUI_SETTINGS_VIDEO_ROTATION, 0);
|
||||
rgui_list_push(rgui->selection_buf, "VSync", RGUI_SETTINGS_VIDEO_VSYNC, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Hard GPU Sync", RGUI_SETTINGS_VIDEO_HARD_SYNC, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Hard GPU Sync Frames", RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Black Frame Insertion", RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION, 0);
|
||||
rgui_list_push(rgui->selection_buf, "VSync Swap Interval", RGUI_SETTINGS_VIDEO_SWAP_INTERVAL, 0);
|
||||
#if !defined(RARCH_CONSOLE) && !defined(RARCH_MOBILE)
|
||||
rgui_list_push(rgui->selection_buf, "Windowed Scale (X)", RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Windowed Scale (Y)", RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y, 0);
|
||||
#endif
|
||||
rgui_list_push(rgui->selection_buf, "Crop Overscan (reload)", RGUI_SETTINGS_VIDEO_CROP_OVERSCAN, 0);
|
||||
rgui_list_push(rgui->selection_buf, "Estimated Monitor FPS", RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO, 0);
|
||||
}
|
||||
|
||||
|
@ -1854,12 +1880,10 @@ static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rg
|
|||
driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx);
|
||||
break;
|
||||
|
||||
#ifndef RARCH_PERFORMANCE_MODE
|
||||
case RGUI_SETTINGS_TOGGLE_FULLSCREEN:
|
||||
if (action == RGUI_ACTION_OK)
|
||||
rarch_set_fullscreen(!g_settings.video.fullscreen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef GEKKO
|
||||
case RGUI_SETTINGS_VIDEO_RESOLUTION:
|
||||
|
@ -1936,6 +1960,105 @@ static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rg
|
|||
}
|
||||
break;
|
||||
|
||||
case RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION:
|
||||
switch (action)
|
||||
{
|
||||
case RGUI_ACTION_START:
|
||||
g_settings.video.black_frame_insertion = false;
|
||||
break;
|
||||
|
||||
case RGUI_ACTION_LEFT:
|
||||
case RGUI_ACTION_RIGHT:
|
||||
case RGUI_ACTION_OK:
|
||||
g_settings.video.black_frame_insertion = !g_settings.video.black_frame_insertion;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RGUI_SETTINGS_VIDEO_CROP_OVERSCAN:
|
||||
switch (action)
|
||||
{
|
||||
case RGUI_ACTION_START:
|
||||
g_settings.video.crop_overscan = true;
|
||||
break;
|
||||
|
||||
case RGUI_ACTION_LEFT:
|
||||
case RGUI_ACTION_RIGHT:
|
||||
case RGUI_ACTION_OK:
|
||||
g_settings.video.crop_overscan = !g_settings.video.crop_overscan;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X:
|
||||
case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y:
|
||||
{
|
||||
float *scale = setting == RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X ? &g_settings.video.xscale : &g_settings.video.yscale;
|
||||
float old_scale = *scale;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case RGUI_ACTION_START:
|
||||
*scale = 3.0f;
|
||||
break;
|
||||
|
||||
case RGUI_ACTION_LEFT:
|
||||
*scale -= 1.0f;
|
||||
break;
|
||||
|
||||
case RGUI_ACTION_RIGHT:
|
||||
*scale += 1.0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*scale = roundf(*scale);
|
||||
*scale = max(*scale, 1.0f);
|
||||
|
||||
if (old_scale != *scale && !g_settings.video.fullscreen)
|
||||
rarch_set_fullscreen(g_settings.video.fullscreen); // Reinit video driver.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL:
|
||||
{
|
||||
unsigned old = g_settings.video.swap_interval;
|
||||
switch (action)
|
||||
{
|
||||
case RGUI_ACTION_START:
|
||||
g_settings.video.swap_interval = 1;
|
||||
break;
|
||||
|
||||
case RGUI_ACTION_LEFT:
|
||||
g_settings.video.swap_interval--;
|
||||
break;
|
||||
|
||||
case RGUI_ACTION_RIGHT:
|
||||
case RGUI_ACTION_OK:
|
||||
g_settings.video.swap_interval++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_settings.video.swap_interval = min(g_settings.video.swap_interval, 4);
|
||||
g_settings.video.swap_interval = max(g_settings.video.swap_interval, 1);
|
||||
if (old != g_settings.video.swap_interval && driver.video && driver.video_data)
|
||||
video_set_nonblock_state_func(false); // This will update the current swap interval. Since we're in RGUI now, always apply VSync.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES:
|
||||
switch (action)
|
||||
{
|
||||
|
@ -2654,7 +2777,8 @@ int rgui_iterate(rgui_handle_t *rgui)
|
|||
// Core selection on non-console just updates directory listing.
|
||||
// Will take affect on new ROM load.
|
||||
#elif defined(GEKKO) && defined(HW_RVL)
|
||||
strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro)); // Is this supposed to be here?
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)path);
|
||||
|
||||
fill_pathname_join(g_extern.fullpath, default_paths.core_dir,
|
||||
SALAMANDER_FILE, sizeof(g_extern.fullpath));
|
||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
||||
|
|
|
@ -460,7 +460,6 @@ static int select_file(void *data, uint64_t input)
|
|||
char extensions[128];
|
||||
char comment[128];
|
||||
char path[PATH_MAX];
|
||||
bool ret = true;
|
||||
bool pop_menu_stack = false;
|
||||
font_params_t font_parms = {0};
|
||||
|
||||
|
@ -495,7 +494,7 @@ static int select_file(void *data, uint64_t input)
|
|||
if (input & (1ULL << DEVICE_NAV_B))
|
||||
{
|
||||
if (filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_PATH_ISDIR))
|
||||
ret = filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_OK);
|
||||
filebrowser_iterate(rgui->browser, FILEBROWSER_ACTION_OK);
|
||||
else
|
||||
{
|
||||
strlcpy(path, rgui->browser->current_dir.path, sizeof(path));
|
||||
|
@ -560,7 +559,7 @@ static int select_file(void *data, uint64_t input)
|
|||
true, menu_texture->width, menu_texture->height, 1.0f);
|
||||
break;
|
||||
case LIBRETRO_CHOICE:
|
||||
strlcpy(g_settings.libretro, path, sizeof(g_settings.libretro));
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)path);
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1222,8 +1222,11 @@ HRESULT CRetroArchCoreBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandle
|
|||
wcstombs(str_buffer, (const wchar_t *)XuiListGetText(m_menulist, index), sizeof(str_buffer));
|
||||
if(path_file_exists(rgui->browser->list->elems[index].data))
|
||||
{
|
||||
snprintf(g_settings.libretro, sizeof(g_settings.libretro), "%s\\%s",
|
||||
rgui->browser->current_dir.directory_path, str_buffer);
|
||||
struct retro_variable var;
|
||||
var.key = "core_path";
|
||||
snprintf(var.value, sizeof(var.value), "%s\\%s", rgui->browser->current_dir.directory_path, str_buffer);
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, &var);
|
||||
|
||||
g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN);
|
||||
process_input_ret = -1;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <pthread.h>
|
||||
#include "../../apple/RetroArch/rarch_wrapper.h"
|
||||
#include "../../apple/common/rarch_wrapper.h"
|
||||
|
||||
#include "../frontend_context.h"
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <stdbool.h>
|
||||
#include "../../driver.h"
|
||||
#include "../../general.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../libretro_private.h"
|
||||
|
||||
#include "../../console/rarch_console.h"
|
||||
#include "../../file.h"
|
||||
|
@ -367,7 +367,11 @@ static int system_process_args(int argc, char *argv[], void *args)
|
|||
// a big hack: sometimes salamander doesn't save the new core it loads on first boot,
|
||||
// so we make sure g_settings.libretro is set here
|
||||
if (!g_settings.libretro[0] && argc >= 1 && strrchr(argv[0], '/'))
|
||||
strlcpy(g_settings.libretro, strrchr(argv[0], '/') + 1, sizeof(g_settings.libretro));
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
strlcpy(path, strrchr(argv[0], '/') + 1, sizeof(path));
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, path);
|
||||
}
|
||||
|
||||
if (argc > 2 && argv[1] != NULL && argv[2] != NULL)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "../../boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "../../dynamic.h"
|
||||
#include "../../libretro_private.h"
|
||||
|
||||
static void get_environment_settings(int argc, char *argv[], void *args)
|
||||
{
|
||||
|
@ -28,7 +30,8 @@ static void get_environment_settings(int argc, char *argv[], void *args)
|
|||
|
||||
/* FIXME - should this apply for both BB10 and PB? */
|
||||
#if defined(__QNX__) && !defined(HAVE_BB10)
|
||||
strlcpy(g_settings.libretro, "app/native/lib", sizeof(g_settings.libretro));
|
||||
rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)"app/native/lib");
|
||||
|
||||
strlcpy(g_extern.config_path, "app/native/retroarch.cfg", sizeof(g_extern.config_path));
|
||||
strlcpy(g_settings.video.shader_dir, "app/native/shaders_glsl", sizeof(g_settings.video.shader_dir));
|
||||
#endif
|
||||
|
|
|
@ -159,6 +159,8 @@ struct settings
|
|||
unsigned fullscreen_y;
|
||||
bool vsync;
|
||||
bool hard_sync;
|
||||
bool black_frame_insertion;
|
||||
unsigned swap_interval;
|
||||
unsigned hard_sync_frames;
|
||||
bool smooth;
|
||||
bool force_aspect;
|
||||
|
@ -201,6 +203,7 @@ struct settings
|
|||
char driver[32];
|
||||
bool enable;
|
||||
unsigned out_rate;
|
||||
unsigned block_frames;
|
||||
float in_rate;
|
||||
char device[PATH_MAX];
|
||||
unsigned latency;
|
||||
|
@ -471,6 +474,8 @@ struct global
|
|||
|
||||
msg_queue_t *msg_queue;
|
||||
|
||||
bool exec;
|
||||
|
||||
// Rewind support.
|
||||
state_manager_t *state_manager;
|
||||
void *state_buf;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "../shader_glsl.h"
|
||||
#endif
|
||||
|
||||
#include "../../apple/RetroArch/rarch_wrapper.h"
|
||||
#include "../../apple/common/rarch_wrapper.h"
|
||||
|
||||
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
{
|
||||
|
@ -38,22 +38,6 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned mino
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool gfx_ctx_set_video_mode(
|
||||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
(void)width;
|
||||
(void)height;
|
||||
(void)fullscreen;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gfx_ctx_update_window_title(void)
|
||||
{
|
||||
char buf[128];
|
||||
gfx_get_fps(buf, sizeof(buf), false);
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
||||
{
|
||||
|
@ -77,16 +61,6 @@ static void gfx_ctx_set_resize(unsigned width, unsigned height)
|
|||
(void)height;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_has_focus(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_buffers(void)
|
||||
{
|
||||
apple_flip_game_view();
|
||||
}
|
||||
|
||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||
{
|
||||
*input = NULL;
|
||||
|
@ -105,13 +79,13 @@ const gfx_ctx_driver_t gfx_ctx_apple = {
|
|||
apple_destroy_game_view,
|
||||
gfx_ctx_bind_api,
|
||||
apple_set_game_view_sync,
|
||||
gfx_ctx_set_video_mode,
|
||||
apple_set_video_mode,
|
||||
apple_get_game_view_size,
|
||||
NULL,
|
||||
gfx_ctx_update_window_title,
|
||||
apple_update_window_title,
|
||||
gfx_ctx_check_window,
|
||||
gfx_ctx_set_resize,
|
||||
gfx_ctx_has_focus,
|
||||
apple_game_view_has_focus,
|
||||
apple_flip_game_view,
|
||||
gfx_ctx_input_driver,
|
||||
gfx_ctx_get_proc_address,
|
||||
|
|
|
@ -93,6 +93,8 @@ static void sighandler(int sig)
|
|||
static void gfx_ctx_swap_interval(unsigned interval)
|
||||
{
|
||||
g_interval = interval;
|
||||
if (interval > 1)
|
||||
RARCH_WARN("[KMS/EGL]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n");
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2012 - Michael Lelli
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// VideoCore context, for Rasperry Pi.
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../gfx_context.h"
|
||||
#include "../gl_common.h"
|
||||
#include "../gfx_common.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
static EGLContext g_egl_ctx;
|
||||
static EGLSurface g_egl_surf;
|
||||
static EGLDisplay g_egl_dpy;
|
||||
static EGLConfig g_config;
|
||||
|
||||
static bool g_inited;
|
||||
|
||||
static unsigned g_fb_width;
|
||||
static unsigned g_fb_height;
|
||||
|
||||
static void gfx_ctx_swap_interval(unsigned interval)
|
||||
{
|
||||
// no way to control vsync in WebGL
|
||||
(void)interval;
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
||||
{
|
||||
(void)frame_count;
|
||||
int iWidth, iHeight, isFullscreen;
|
||||
|
||||
emscripten_get_canvas_size(&iWidth, &iHeight, &isFullscreen);
|
||||
*width = (unsigned) iWidth;
|
||||
*height = (unsigned) iHeight;
|
||||
|
||||
if (*width != g_fb_width || *height != g_fb_height)
|
||||
*resize = true;
|
||||
else
|
||||
*resize = false;
|
||||
|
||||
g_fb_width = (unsigned) iWidth;
|
||||
g_fb_height = (unsigned) iHeight;
|
||||
*quit = false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_buffers(void)
|
||||
{
|
||||
// no-op in emscripten, no way to force swap/wait for vsync in browsers
|
||||
//eglSwapBuffers(g_egl_dpy, g_egl_surf);
|
||||
}
|
||||
|
||||
static void gfx_ctx_set_resize(unsigned width, unsigned height)
|
||||
{
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_update_window_title(void)
|
||||
{
|
||||
char buf[128];
|
||||
if (gfx_get_fps(buf, sizeof(buf), false))
|
||||
RARCH_LOG("%s\n", buf);
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
{
|
||||
*width = g_fb_width;
|
||||
*height = g_fb_height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void);
|
||||
|
||||
static bool gfx_ctx_init(void)
|
||||
{
|
||||
EGLint width;
|
||||
EGLint height;
|
||||
|
||||
RARCH_LOG("[EMSCRIPTEN/EGL]: Initializing...\n");
|
||||
if (g_inited)
|
||||
{
|
||||
RARCH_LOG("[EMSCRIPTEN/EGL]: Attempted to re-initialize driver.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
EGLint num_config;
|
||||
|
||||
static const EGLint attribute_list[] =
|
||||
{
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static const EGLint context_attributes[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
// get an EGL display connection
|
||||
g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (!g_egl_dpy)
|
||||
goto error;
|
||||
|
||||
// initialize the EGL display connection
|
||||
if (!eglInitialize(g_egl_dpy, NULL, NULL))
|
||||
goto error;
|
||||
|
||||
// get an appropriate EGL frame buffer configuration
|
||||
if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config))
|
||||
goto error;
|
||||
|
||||
// create an EGL rendering context
|
||||
g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes);
|
||||
if (!g_egl_ctx)
|
||||
goto error;
|
||||
|
||||
// create an EGL window surface
|
||||
g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, 0, NULL);
|
||||
if (!g_egl_surf)
|
||||
goto error;
|
||||
|
||||
// connect the context to the surface
|
||||
if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
|
||||
goto error;
|
||||
|
||||
eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width);
|
||||
eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height);
|
||||
g_fb_width = width;
|
||||
g_fb_height = height;
|
||||
RARCH_LOG("[EMSCRIPTEN/EGL]: Dimensions: %ux%u\n", width, height);
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
gfx_ctx_destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_set_video_mode(
|
||||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
if (g_inited)
|
||||
return false;
|
||||
|
||||
g_inited = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
{
|
||||
(void)major;
|
||||
(void)minor;
|
||||
switch (api)
|
||||
{
|
||||
case GFX_CTX_OPENGL_ES_API:
|
||||
return eglBindAPI(EGL_OPENGL_ES_API);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void)
|
||||
{
|
||||
if (g_egl_dpy)
|
||||
{
|
||||
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (g_egl_ctx)
|
||||
{
|
||||
eglDestroyContext(g_egl_dpy, g_egl_ctx);
|
||||
}
|
||||
|
||||
if (g_egl_surf)
|
||||
{
|
||||
eglDestroySurface(g_egl_dpy, g_egl_surf);
|
||||
}
|
||||
|
||||
eglTerminate(g_egl_dpy);
|
||||
}
|
||||
|
||||
g_egl_ctx = NULL;
|
||||
g_egl_surf = NULL;
|
||||
g_egl_dpy = NULL;
|
||||
g_config = 0;
|
||||
g_inited = false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||
{
|
||||
*input = NULL;
|
||||
|
||||
void *rwebinput = input_rwebinput.init();
|
||||
|
||||
if (rwebinput)
|
||||
{
|
||||
*input = &input_rwebinput;
|
||||
*input_data = rwebinput;
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_ctx_has_focus(void)
|
||||
{
|
||||
return g_inited;
|
||||
}
|
||||
|
||||
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
|
||||
{
|
||||
return eglGetProcAddress(symbol);
|
||||
}
|
||||
|
||||
static float gfx_ctx_translate_aspect(unsigned width, unsigned height)
|
||||
{
|
||||
return (float)width / height;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_emscripten = {
|
||||
gfx_ctx_init,
|
||||
gfx_ctx_destroy,
|
||||
gfx_ctx_bind_api,
|
||||
gfx_ctx_swap_interval,
|
||||
gfx_ctx_set_video_mode,
|
||||
gfx_ctx_get_video_size,
|
||||
gfx_ctx_translate_aspect,
|
||||
gfx_ctx_update_window_title,
|
||||
gfx_ctx_check_window,
|
||||
gfx_ctx_set_resize,
|
||||
gfx_ctx_has_focus,
|
||||
gfx_ctx_swap_buffers,
|
||||
gfx_ctx_input_driver,
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
"emscripten",
|
||||
};
|
|
@ -469,6 +469,7 @@ static bool gfx_ctx_set_video_mode(
|
|||
if (!g_hwnd)
|
||||
goto error;
|
||||
|
||||
#ifdef HAVE_WIN32GUI
|
||||
if (!fullscreen)
|
||||
{
|
||||
SetMenu(g_hwnd, LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MENU)));
|
||||
|
@ -477,6 +478,7 @@ static bool gfx_ctx_set_video_mode(
|
|||
unsigned menu_height = rcTemp.top + rect.top; // rect.top is negative after AdjustWindowRect().
|
||||
SetWindowPos(g_hwnd, NULL, 0, 0, width, height + menu_height, SWP_NOMOVE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fullscreen || windowed_full)
|
||||
{
|
||||
|
|
|
@ -145,7 +145,20 @@ void D3DVideo::make_d3dpp(const video_info_t &info, D3DPRESENT_PARAMETERS &d3dpp
|
|||
|
||||
d3dpp.Windowed = g_settings.video.windowed_fullscreen || !info.fullscreen;
|
||||
|
||||
d3dpp.PresentationInterval = info.vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
if (info.vsync)
|
||||
{
|
||||
switch (g_settings.video.swap_interval)
|
||||
{
|
||||
default:
|
||||
case 1: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; break;
|
||||
case 2: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; break;
|
||||
case 3: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_THREE; break;
|
||||
case 4: d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = hWnd;
|
||||
d3dpp.BackBufferCount = 2;
|
||||
|
@ -614,6 +627,17 @@ bool D3DVideo::frame(const void *frame,
|
|||
dev->SetViewport(&screen_vp);
|
||||
dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0);
|
||||
|
||||
// Insert black frame first, so we can screenshot, etc.
|
||||
if (g_settings.video.black_frame_insertion)
|
||||
{
|
||||
if (dev->Present(nullptr, nullptr, nullptr, nullptr) != D3D_OK)
|
||||
{
|
||||
needs_restore = true;
|
||||
return true;
|
||||
}
|
||||
dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0);
|
||||
}
|
||||
|
||||
if (!chain->render(frame, width, height, pitch, rotation))
|
||||
{
|
||||
RARCH_ERR("[D3D9]: Failed to render scene.\n");
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../general.h"
|
||||
#include "gfx_context.h"
|
||||
#include "../general.h"
|
||||
#include <string.h>
|
||||
|
@ -52,6 +53,9 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = {
|
|||
#if defined(IOS) || defined(OSX) //< Don't use __APPLE__ as it breaks basic SDL builds
|
||||
&gfx_ctx_apple,
|
||||
#endif
|
||||
#ifdef EMSCRIPTEN
|
||||
&gfx_ctx_emscripten,
|
||||
#endif
|
||||
};
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
|
|
|
@ -108,6 +108,7 @@ extern const gfx_ctx_driver_t gfx_ctx_wgl;
|
|||
extern const gfx_ctx_driver_t gfx_ctx_videocore;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_bbqnx;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_apple;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_emscripten;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_null;
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
|
||||
|
|
29
gfx/gl.c
29
gfx/gl.c
|
@ -1402,18 +1402,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
|||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
// Data is already on GPU :) Have to reset some state however incase core changed it.
|
||||
if (gl->hw_render_fbo_init)
|
||||
{
|
||||
gl_update_input_size(gl, width, height, pitch, false);
|
||||
|
||||
if (!gl->fbo_inited)
|
||||
{
|
||||
gl_bind_backbuffer();
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!gl->hw_render_fbo_init)
|
||||
#endif
|
||||
{
|
||||
gl_update_input_size(gl, width, height, pitch, true);
|
||||
|
@ -1430,6 +1419,13 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
|||
#ifdef HAVE_FBO
|
||||
if (gl->hw_render_fbo_init)
|
||||
{
|
||||
gl_update_input_size(gl, width, height, pitch, false);
|
||||
if (!gl->fbo_inited)
|
||||
{
|
||||
gl_bind_backbuffer();
|
||||
gl_set_viewport(gl, gl->win_width, gl->win_height, false, true);
|
||||
}
|
||||
|
||||
#ifndef HAVE_OPENGLES
|
||||
if (!gl->core_context)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
@ -1454,6 +1450,11 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
|||
memcpy(tex_info.coord, gl->tex_coords, sizeof(gl->tex_coords));
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (g_settings.video.black_frame_insertion)
|
||||
{
|
||||
context_swap_buffers_func();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
if (gl->shader)
|
||||
gl->shader->set_params(width, height,
|
||||
|
@ -1623,7 +1624,7 @@ static void gl_set_nonblock_state(void *data, bool state)
|
|||
|
||||
gl_t *gl = (gl_t*)data;
|
||||
(void)gl;
|
||||
context_swap_interval_func(state ? 0 : 1);
|
||||
context_swap_interval_func(state ? 0 : g_settings.video.swap_interval);
|
||||
}
|
||||
|
||||
static bool resolve_extensions(gl_t *gl)
|
||||
|
@ -1945,7 +1946,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
|||
context_get_video_size_func(&gl->full_x, &gl->full_y);
|
||||
RARCH_LOG("Detecting screen resolution %ux%u.\n", gl->full_x, gl->full_y);
|
||||
|
||||
context_swap_interval_func(video->vsync ? 1 : 0);
|
||||
context_swap_interval_func(video->vsync ? g_settings.video.swap_interval : 0);
|
||||
|
||||
unsigned win_width = video->width;
|
||||
unsigned win_height = video->height;
|
||||
|
|
2
gfx/vg.c
2
gfx/vg.c
|
@ -87,7 +87,7 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo
|
|||
if (!vg)
|
||||
return NULL;
|
||||
|
||||
vg->driver = gfx_ctx_init_first(GFX_CTX_OPENVG_API);
|
||||
vg->driver = gfx_ctx_init_first(GFX_CTX_OPENVG_API, 0, 0);
|
||||
|
||||
if (!vg->driver)
|
||||
{
|
||||
|
|
|
@ -298,8 +298,8 @@ INPUT
|
|||
#include "../android/native/jni/input_autodetect.c"
|
||||
#include "../android/native/jni/input_android.c"
|
||||
#elif defined(IOS) || defined(OSX)
|
||||
#include "../apple/RetroArch/apple_input.c"
|
||||
#include "../apple/RetroArch/apple_joypad.c"
|
||||
#include "../apple/common/apple_input.c"
|
||||
#include "../apple/common/apple_joypad.c"
|
||||
#elif defined(__BLACKBERRY_QNX__)
|
||||
#include "../blackberry-qnx/qnx_input.c"
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - pinumbernumber
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef AUTOCONF_BUILTIN_H__
|
||||
#define AUTOCONF_BUILTIN_H__
|
||||
|
||||
#include "../input_common.h"
|
||||
#define DECL_BTN(btn, bind) "input_" #btn "_btn = " #bind "\n"
|
||||
#define DECL_AXIS(axis, bind) "input_" #axis "_axis = " #bind "\n"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2013 - pinumbernumber
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "builtin.h"
|
||||
|
||||
#define XINPUT_DEFAULT_BINDS \
|
||||
DECL_BTN(a, 1) \
|
||||
DECL_BTN(b, 0) \
|
||||
DECL_BTN(x, 3) \
|
||||
DECL_BTN(y, 2) \
|
||||
DECL_BTN(start, 6) \
|
||||
DECL_BTN(select, 7) \
|
||||
DECL_BTN(up, h0up) \
|
||||
DECL_BTN(down, h0down) \
|
||||
DECL_BTN(left, h0left) \
|
||||
DECL_BTN(right, h0right) \
|
||||
DECL_BTN(l, 4) \
|
||||
DECL_BTN(r, 5) \
|
||||
DECL_BTN(l3, 8 )\
|
||||
DECL_BTN(r3, 9) \
|
||||
DECL_BTN(menu_toggle, 10) \
|
||||
DECL_AXIS(l2, +4) \
|
||||
DECL_AXIS(r2, +5) \
|
||||
DECL_AXIS(l_x_plus, +0) \
|
||||
DECL_AXIS(l_x_minus, -0) \
|
||||
DECL_AXIS(l_y_plus, -1) \
|
||||
DECL_AXIS(l_y_minus, +1) \
|
||||
DECL_AXIS(r_x_plus, +2) \
|
||||
DECL_AXIS(r_x_minus, -2) \
|
||||
DECL_AXIS(r_y_plus, -3) \
|
||||
DECL_AXIS(r_y_minus, +3)
|
||||
|
||||
// Some hardcoded autoconfig information. Will be used for pads with no autoconfig cfg files.
|
||||
const char* const input_builtin_autoconfs[] =
|
||||
{
|
||||
"input_device = \"XInput Controller (Player 1)\" \n"
|
||||
"input_driver = \"winxinput\" \n"
|
||||
XINPUT_DEFAULT_BINDS,
|
||||
|
||||
"input_device = \"XInput Controller (Player 2)\" \n"
|
||||
"input_driver = \"winxinput\" \n"
|
||||
XINPUT_DEFAULT_BINDS,
|
||||
|
||||
"input_device = \"XInput Controller (Player 3)\" \n"
|
||||
"input_driver = \"winxinput\" \n"
|
||||
XINPUT_DEFAULT_BINDS,
|
||||
|
||||
"input_device = \"XInput Controller (Player 4)\" \n"
|
||||
"input_driver = \"winxinput\" \n"
|
||||
XINPUT_DEFAULT_BINDS,
|
||||
|
||||
"input_device = \"Dual Trigger 3-in-1\" \n"
|
||||
"input_driver = \"dinput\" \n"
|
||||
DECL_BTN(a, 2)
|
||||
DECL_BTN(b, 1)
|
||||
DECL_BTN(x, 3)
|
||||
DECL_BTN(y, 0)
|
||||
DECL_BTN(start, 9)
|
||||
DECL_BTN(select, 8)
|
||||
DECL_BTN(up, h0up)
|
||||
DECL_BTN(down, h0down)
|
||||
DECL_BTN(left, h0left)
|
||||
DECL_BTN(right, h0right)
|
||||
DECL_BTN(l, 4)
|
||||
DECL_BTN(r, 5)
|
||||
DECL_BTN(l2, 6)
|
||||
DECL_BTN(r2, 7)
|
||||
DECL_BTN(l3, 10)
|
||||
DECL_BTN(r3, 11)
|
||||
DECL_AXIS(l_x_plus, +0)
|
||||
DECL_AXIS(l_x_minus, -0)
|
||||
DECL_AXIS(l_y_plus, +1)
|
||||
DECL_AXIS(l_y_minus, -1)
|
||||
DECL_AXIS(r_x_plus, +2)
|
||||
DECL_AXIS(r_x_minus, -2)
|
||||
DECL_AXIS(r_y_plus, +5)
|
||||
DECL_AXIS(r_y_minus, -5),
|
||||
|
||||
NULL
|
||||
};
|
108
input/dinput.c
108
input/dinput.c
|
@ -49,6 +49,7 @@ struct dinput_joypad
|
|||
{
|
||||
LPDIRECTINPUTDEVICE8 joypad;
|
||||
DIJOYSTATE2 joy_state;
|
||||
char* joy_name;
|
||||
};
|
||||
|
||||
static unsigned g_joypad_cnt;
|
||||
|
@ -68,12 +69,6 @@ static bool dinput_init_context(void)
|
|||
if (g_ctx)
|
||||
return true;
|
||||
|
||||
if (driver.display_type != RARCH_DISPLAY_WIN32)
|
||||
{
|
||||
RARCH_ERR("Cannot open DInput as no Win32 window is present.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CoInitialize(NULL);
|
||||
|
||||
// Who said we shouldn't have same call signature in a COM API? <_<
|
||||
|
@ -351,6 +346,11 @@ const input_driver_t input_dinput = {
|
|||
dinput_grab_mouse,
|
||||
};
|
||||
|
||||
// Keep track of which pad indexes are 360 controllers
|
||||
// not static, will be read in winxinput_joypad.c
|
||||
// -1 = not xbox pad, otherwise 0..3
|
||||
int g_xbox_pad_indexes[MAX_PLAYERS];
|
||||
|
||||
static void dinput_joypad_destroy(void)
|
||||
{
|
||||
for (unsigned i = 0; i < MAX_PLAYERS; i++)
|
||||
|
@ -360,6 +360,10 @@ static void dinput_joypad_destroy(void)
|
|||
IDirectInputDevice8_Unacquire(g_pads[i].joypad);
|
||||
IDirectInputDevice8_Release(g_pads[i].joypad);
|
||||
}
|
||||
|
||||
free(g_pads[i].joy_name);
|
||||
g_pads[i].joy_name = NULL;
|
||||
|
||||
}
|
||||
|
||||
g_joypad_cnt = 0;
|
||||
|
@ -386,6 +390,54 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p)
|
|||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
// TODO: Use a better way of detecting dual XInput/DInput pads. This current method
|
||||
// will not work correctly for third-party controllers or future MS pads (Xbox One?).
|
||||
// An example of this is provided in the DX SDK, which advises "Enum each PNP device
|
||||
// using WMI and check each device ID to see if it contains "IG_"". Unfortunately the
|
||||
// example code is a horrible unsightly mess.
|
||||
static const char* const XINPUT_PAD_NAMES[] =
|
||||
{
|
||||
"XBOX 360 For Windows",
|
||||
"Controller (Gamepad for Xbox 360)",
|
||||
"Controller (XBOX 360 For Windows)",
|
||||
"Controller (Xbox 360 Wireless Receiver for Windows)",
|
||||
"Controller (Xbox wireless receiver for windows)",
|
||||
"XBOX 360 For Windows (Controller)",
|
||||
"Xbox 360 Wireless Receiver",
|
||||
"Xbox 360 Wireless Controller",
|
||||
"Xbox Receiver for Windows (Wireless Controller)",
|
||||
"Xbox wireless receiver for windows (Controller)",
|
||||
"Gamepad F310 (Controller)",
|
||||
"Controller (Gamepad F310)",
|
||||
"Wireless Gamepad F710 (Controller)",
|
||||
"Controller (Batarang wired controller (XBOX))",
|
||||
"Afterglow Gamepad for Xbox 360 (Controller)"
|
||||
"Controller (Rumble Gamepad F510)",
|
||||
"Controller (Wireless Gamepad F710)",
|
||||
"Controller (Xbox 360 Wireless Receiver for Windows)",
|
||||
"Controller (Xbox wireless receiver for windows)",
|
||||
"Controller (XBOX360 GAMEPAD)",
|
||||
"MadCatz GamePad",
|
||||
NULL
|
||||
};
|
||||
|
||||
static bool name_is_360_pad(const char* name)
|
||||
{
|
||||
for (unsigned i = 0; ; ++i)
|
||||
{
|
||||
const char* t = XINPUT_PAD_NAMES[i];
|
||||
if (t == NULL)
|
||||
return false;
|
||||
else if (strcasecmp(name, t) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
static const char *dinput_joypad_name(unsigned pad);
|
||||
|
||||
static int g_last_xbox_pad_index;
|
||||
|
||||
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
||||
{
|
||||
(void)p;
|
||||
|
@ -399,7 +451,22 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
|||
#else
|
||||
if (FAILED(IDirectInput8_CreateDevice(g_ctx, &inst->guidInstance, pad, NULL)))
|
||||
#endif
|
||||
return DIENUM_CONTINUE;
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);
|
||||
|
||||
#ifdef HAVE_WINXINPUT
|
||||
bool is_360_pad = name_is_360_pad(inst->tszProductName);
|
||||
|
||||
if (is_360_pad)
|
||||
{
|
||||
if (g_last_xbox_pad_index < 4)
|
||||
g_xbox_pad_indexes[g_joypad_cnt] = g_last_xbox_pad_index;
|
||||
++g_last_xbox_pad_index;
|
||||
|
||||
goto enum_iteration_done;
|
||||
}
|
||||
#endif
|
||||
|
||||
IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2);
|
||||
IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver.video_window,
|
||||
|
@ -407,9 +474,17 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
|||
|
||||
IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb,
|
||||
*pad, DIDFT_ABSAXIS);
|
||||
|
||||
#ifdef HAVE_WINXINPUT
|
||||
if (!is_360_pad)
|
||||
#endif
|
||||
{
|
||||
strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt]));
|
||||
input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), dinput_joypad.ident);
|
||||
}
|
||||
|
||||
enum_iteration_done:
|
||||
g_joypad_cnt++;
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -417,6 +492,14 @@ static bool dinput_joypad_init(void)
|
|||
{
|
||||
if (!dinput_init_context())
|
||||
return false;
|
||||
|
||||
g_last_xbox_pad_index = 0;
|
||||
|
||||
for (unsigned i = 0; i < MAX_PLAYERS; ++i)
|
||||
{
|
||||
g_xbox_pad_indexes[i] = -1;
|
||||
g_pads[i].joy_name = NULL;
|
||||
}
|
||||
|
||||
RARCH_LOG("Enumerating DInput joypads ...\n");
|
||||
IDirectInput8_EnumDevices(g_ctx, DI8DEVCLASS_GAMECTRL,
|
||||
|
@ -524,7 +607,7 @@ static void dinput_joypad_poll(void)
|
|||
{
|
||||
struct dinput_joypad *pad = &g_pads[i];
|
||||
|
||||
if (pad->joypad)
|
||||
if ((pad->joypad) && (g_xbox_pad_indexes[i] == -1))
|
||||
{
|
||||
memset(&pad->joy_state, 0, sizeof(pad->joy_state));
|
||||
|
||||
|
@ -555,10 +638,13 @@ static bool dinput_joypad_query_pad(unsigned pad)
|
|||
return pad < MAX_PLAYERS && g_pads[pad].joypad;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *dinput_joypad_name(unsigned pad)
|
||||
{
|
||||
(void)pad;
|
||||
// FIXME
|
||||
if (pad < MAX_PLAYERS)
|
||||
return g_pads[pad].joy_name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue