This commit is contained in:
aenu
2025-07-09 19:23:39 +08:00
parent 3036869a4c
commit ff71b794b1
55 changed files with 1994 additions and 634 deletions

View File

@@ -13,30 +13,36 @@
android:name="aenu.aps3e.Application"
android:allowNativeHeapPointerTagging="false"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:icon="@drawable/app_icon"
android:isGame="true">
<activity android:name="aenu.aps3e.MainActivity"
android:theme="@style/Theme.AppCompat"
android:launchMode="singleTask"
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
<activity android:name="aenu.aps3e.QuickStartActivity"
android:exported="true"
android:label="@string/app_name">
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="aenu.intent.action.REENTRY_QUISK_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="aenu.aps3e.MainActivity"
android:launchMode="singleTask"
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
android:exported="false"
android:label="@string/app_name">
</activity>
<activity android:name="aenu.aps3e.AboutActivity"
android:theme="@style/Theme.AppCompat"
android:exported="false"
android:label="@string/about">
</activity>
<activity android:name="aenu.aps3e.KeyMapActivity"
android:theme="@style/Theme.AppCompat"
android:exported="false"
android:label="@string/key_mappers"/>
<activity android:name="aenu.aps3e.UserDataActivity"
android:theme="@style/Theme.AppCompat"
android:exported="false"/>
<activity android:name="aenu.aps3e.VirtualPadEdit"
android:screenOrientation="sensorLandscape"
@@ -59,7 +65,6 @@
</intent-filter>
</activity>
<activity android:name="aenu.aps3e.EmulatorSettings"
android:theme="@style/Theme.AppCompat"
android:exported="false"
android:label="@string/settings"/>
<provider

View File

@@ -123,7 +123,7 @@ Video:
Disable Asynchronous Memory Manager: false
Output Scaling Mode: Bilinear
Vertex Buffer Upload Mode: Auto
Texture Upload Mode: CPU
Texture Upload Mode: GPU
Use BGRA Format: true
Force Convert Texture: false
Vulkan:
@@ -265,7 +265,7 @@ Miscellaneous:
Silence All Logs: false
Window Title Format: "FPS: %F | %R | %V | %T [%t]"
Pause Emulation During Home Menu: false
Font File Selection: From Firmware
Font File Selection: Custom
Custom Font File Path: ""
Font Size: 22
Memory Debug overlay: false

View File

@@ -1638,6 +1638,7 @@ int register_Emulator(JNIEnv* env){
{"simple_device_info", "()Ljava/lang/String;",(void *)j_simple_device_info},
{"get_native_llvm_cpu_list", "()[Ljava/lang/String;",(void *)j_get_native_llvm_cpu_list},
{"get_support_llvm_cpu_list", "()[Ljava/lang/String;",(void *)j_get_support_llvm_cpu_list},
{"get_vulkan_physical_dev_list", "()[Ljava/lang/String;",(void *)j_get_vulkan_physical_dev_list},
@@ -1682,6 +1683,8 @@ int register_Emulator_cfg(JNIEnv* env){
static const JNINativeMethod methods[] = {
{ "native_open_config", "(Ljava/lang/String;)J", (void *) open_config_str },
{ "native_close_config", "(J)Ljava/lang/String;", (void *) close_config_str },
{ "native_open_config_file", "(Ljava/lang/String;)J", (void *) open_config_file },
{ "native_load_config_entry", "(JLjava/lang/String;)Ljava/lang/String;", (void *) load_config_entry },
{ "native_load_config_entry_ty_arr", "(JLjava/lang/String;)[Ljava/lang/String;", (void *) load_config_entry_ty_arr },

View File

@@ -5,6 +5,25 @@
static_assert(sizeof(YAML::Node*)==8,"");
static YAML::Node* open_config_str(JNIEnv* env,jobject self,jstring jconfig_str){
jboolean is_copy=false;
const char* config_str=env->GetStringUTFChars(jconfig_str,&is_copy);
std::istringstream config_stream(config_str);
YAML::Node* config_node = new YAML::Node(YAML::Load(config_stream));
env->ReleaseStringUTFChars(jconfig_str,config_str);
return config_node;
}
static jstring close_config_str(JNIEnv* env,jobject self,YAML::Node* config_node){
YAML::Emitter out;
out << *config_node;
jboolean is_copy=false;
jstring result=env->NewStringUTF(out.c_str());
delete config_node;
return result;
}
static YAML::Node* open_config_file(JNIEnv* env,jobject self,jstring config_path){
jboolean is_copy=false;
const char* path=env->GetStringUTFChars(config_path,&is_copy);
@@ -248,6 +267,11 @@ static bool gen_is_parent(const std::string& parent_name){
return true;
return false;
}
#define SEEKBAR_PREF_TAG "aenu.preference.SeekBarPreference"
#define CHECKBOX_PREF_TAG "aenu.preference.CheckBoxPreference"
#define LIST_PREF_TAG "aenu.preference.ListPreference"
static jstring generate_config_xml(JNIEnv* env,jobject self){
auto gen_one_preference=[&](const std::string parent_name,cfg::_base* node)->std::string{
@@ -260,12 +284,12 @@ static jstring generate_config_xml(JNIEnv* env,jobject self){
switch (node->get_type()) {
case cfg::type::_bool:
out<<"<CheckBoxPreference app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
out<<"<" CHECKBOX_PREF_TAG " app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
out<<"app:key=\""<<parent_name<<"|"<<name<<"\" />\n";
break;
case cfg::type::_int:
case cfg::type::uint:
out<<"<aenu.preference.SeekbarPreference app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
out<<"<" SEEKBAR_PREF_TAG " app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
out<<"app:min=\""<<node->get_min()<<"\"\n";
if(node->get_max()!=-1)
out<<"android:max=\""<<node->get_max()<<"\"\n";
@@ -276,7 +300,7 @@ static jstring generate_config_xml(JNIEnv* env,jobject self){
break;
case cfg::type::_enum:
out<<"<ListPreference app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
out<<"<" LIST_PREF_TAG " app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
out<<"app:entries=\""<<"@array/"<<parent_name_l<<"_"<<key<<"_entries\"\n";
out<<"app:entryValues=\""<<"@array/"<<parent_name_l<<"_"<<key<<"_values\"\n";
out<<"app:key=\""<<parent_name<<"|"<<name<<"\" />\n";
@@ -306,7 +330,7 @@ static jstring generate_config_xml(JNIEnv* env,jobject self){
LOGE("unexpected type");
continue;
}
out<<"<CheckBoxPreference app:title=\""<<n3->get_name()<<"\" \n";
out<<"<" CHECKBOX_PREF_TAG " app:title=\""<<n3->get_name()<<"\" \n";
out<<"app:key=\""<<node_key<<"|"<<n3->get_name()<<"\" />\n";
}
out<<"</PreferenceScreen>\n";
@@ -363,6 +387,9 @@ static jstring generate_config_xml(JNIEnv* env,jobject self){
return env->NewStringUTF(out.str().c_str());
}
#undef SEEKBAR_PREF_TAG
#undef CHECKBOX_PREF_TAG
#undef LIST_PREF_TAG
//public native String generate_strings_xml();
static jstring generate_strings_xml(JNIEnv* env,jobject self){
@@ -551,14 +578,43 @@ static jstring generate_java_string_arr(JNIEnv* env,jobject self){
return env->NewStringUTF(out.str().c_str());
}
//public native String[] get_support_llvm_cpu_list();
static jobjectArray j_get_native_llvm_cpu_list(JNIEnv* env,jobject self){
const std::vector<core_info_t> core_info_list = cpu_get_core_info();
const std::set<std::string,std::greater<>> llvm_cpu_list=get_processor_name_set(core_info_list);
int count=llvm_cpu_list.size();
static jobjectArray j_get_support_llvm_cpu_list(JNIEnv* env,jobject self){
std::set<std::string> cpu_list=get_processor_name_set();
int count=cpu_list.size();
jobjectArray ret=env->NewObjectArray(count,env->FindClass("java/lang/String"),nullptr);
int n=0;
for(const std::string& cpu_name:cpu_list){
for(const std::string& cpu_name:llvm_cpu_list){
env->SetObjectArrayElement(ret,n++,env->NewStringUTF(cpu_name.c_str()));
}
return ret;
}
static jobjectArray j_get_support_llvm_cpu_list(JNIEnv* env,jobject self){
const std::vector<core_info_t> core_info_list = cpu_get_core_info();
const std::set<std::string,std::greater<>> llvm_cpu_list=get_processor_name_set(core_info_list);
const std::string isa=cpu_get_processor_isa(core_info_list[0]);
std::vector<std::string> append_llvm_cpu_list;
int count=llvm_cpu_list.size();
if(isa=="armv9-a"||isa=="armv9.2-a"){
count+=4;
append_llvm_cpu_list={"cortex-x1","cortex-a55","cortex-a73","cortex-a53"};
}
else if(isa=="armv8.2-a"){
count+=2;
append_llvm_cpu_list={"cortex-a73","cortex-a53"};
}
jobjectArray ret=env->NewObjectArray(count,env->FindClass("java/lang/String"),nullptr);
int n=0;
for(const std::string& cpu_name:llvm_cpu_list){
env->SetObjectArrayElement(ret,n++,env->NewStringUTF(cpu_name.c_str()));
}
for(const std::string& cpu_name:append_llvm_cpu_list){
env->SetObjectArrayElement(ret,n++,env->NewStringUTF(cpu_name.c_str()));
}
return ret;

View File

@@ -72,18 +72,20 @@ std::string cpu_get_simple_info(const std::vector<core_info_t>& core_info_list){
return ss.str();
}
std::set<std::string,std::greater<>> get_processor_name_set(const std::vector<core_info_t>& core_info_list){
std::set<std::string,std::greater<>> processor_name_set;
if(!core_info_list.empty()){
std::for_each(core_info_list.begin(), core_info_list.end(), [&processor_name_set](const core_info_t& core_info) {
processor_name_set.insert(cpu_get_processor_name(core_info));
});
}
else{
const std::vector<core_info_t> core_info_list2= cpu_get_core_info();
std::for_each(core_info_list2.begin(), core_info_list2.end(), [&processor_name_set](const core_info_t& core_info) {
processor_name_set.insert(cpu_get_processor_name(core_info));
});
}
std::set<core_info_t> get_processor_info_set(){
std::vector<core_info_t> core_info_list = cpu_get_core_info();
return std::set<core_info_t>(core_info_list.begin(), core_info_list.end());
}
std::set<std::string> get_processor_name_set(){
std::vector<core_info_t> core_info_list = cpu_get_core_info();
std::set<std::string> processor_name_set;
std::for_each(core_info_list.begin(), core_info_list.end(), [&processor_name_set](const core_info_t& core_info) {
processor_name_set.insert(cpu_get_processor_name(core_info));
});
return processor_name_set;
}

View File

@@ -19,7 +19,7 @@ struct core_info_t {
std::vector<core_info_t> cpu_get_core_info();
std::string cpu_get_simple_info(const std::vector<core_info_t>& core_info_list);
std::set<core_info_t> get_processor_info_set();
std::set<std::string> get_processor_name_set();
std::set<std::string,std::greater<>> get_processor_name_set(const std::vector<core_info_t>& core_info_list={});
std::string cpu_get_processor_name(const core_info_t& core_info);
std::string cpu_get_processor_isa(const core_info_t& core_info);

View File

@@ -272,126 +272,6 @@ result << "extensions:\n";
#include <sstream>
#include <string>
#include <vector>
#if 0
std::string get_cpu_info() {
std::ifstream cpuinfo("/proc/cpuinfo");
if (!cpuinfo.is_open()) {
return "获取cpuinfo失败";
}
struct CoreInfo {
int implementer;
int variant;
int part;
std::vector<std::string> features;
};
std::vector<CoreInfo> cores;
std::map<std::tuple<int,int,int>,int> core_n;
std::string line;
CoreInfo core;
while (std::getline(cpuinfo, line)) {
if (line.find("CPU implementer") != std::string::npos) {
core.implementer = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
}
else if (line.find("CPU variant") != std::string::npos) {
core.variant = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
}
else if (line.find("CPU part") != std::string::npos) {
core.part = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
cores.push_back(core);
if (core_n.find({core.implementer, core.variant, core.part}) == core_n.end()) {
core_n[{core.implementer, core.variant, core.part}] = 1;
}
else {
core_n[{core.implementer, core.variant, core.part}]++;
}
}
else if (line.find("Features") != std::string::npos) {
std::string features = line.substr(line.find(":") + 2);
std::istringstream iss(features);
std::string feature;
while (iss >> feature) {
core.features.push_back(feature);
}
}
}
auto cpu_core_info = [&]() {
static const std::map<std::tuple<int,int>,std::string> core_map{
{{ 0x41, 0xd01}, "Cortex-A32" },
{{ 0x41, 0xd04}, "Cortex-A35" },
{{ 0x41, 0xd03}, "Cortex-A53" },
{{ 0x41, 0xd07}, "Cortex-A57" },
{{ 0x41, 0xd08}, "Cortex-A72" },
{{ 0x41, 0xd09}, "Cortex-A73" },
{{ 0x41, 0xd05}, "Cortex-A55" },
{{ 0x41, 0xd0a}, "Cortex-A75" },
{{ 0x41, 0xd0b}, "Cortex-A76" },
{{ 0x41, 0xd0d}, "Cortex-A77" },
{{ 0x41, 0xd41}, "Cortex-A78" },
{{ 0x41, 0xd44}, "Cortex-X1" },
{{ 0x41, 0xd46}, "Cortex-A510" },
{{ 0x41, 0xd47}, "Cortex-A710" },
{{ 0x41, 0xd48}, "Cortex-X2" },
{{ 0x41, 0xd4d}, "Cortex-A715" },
{{ 0x41, 0xd4e}, "Cortex-X3" },
{{ 0x41, 0xd80}, "Cortex-A520" },
{{ 0x41, 0xd81}, "Cortex-A720" },
{{ 0x41, 0xd87}, "Cortex-A725" },
{{ 0x41, 0xd82}, "Cortex-X4" },
{{ 0x41, 0xd85}, "Cortex-X925" },
{{ 0x51, 0x001}, "X-Elite" },
};
std::ostringstream ss;
for(const auto& [k,v] : core_n){
auto &[implementer, variant, part] = k;
if (auto core = core_map.find(std::make_tuple(implementer, part)); core != core_map.end()) {
ss <<core->second << "*"<< v << "+";
}
else{
ss <<"[" <<implementer<<" | "<<part<< "]*"<< v << "+";
}
}
std::string r=ss.str();
if(r.size()<1) return "获取cpu信息失败"s;
return r.substr(0,r.size()-1);
}();
std::stringstream result;
result << "CPU [" << cpu_core_info << "]:\n";
if (cores.size() > 0) {
//TODO 理论上来讲所有核心的feature应该都是相同的
for (const auto& frature : cores[0].features) {
result << " * " << frature << "\n";
}
}
return result.str();
}
#endif
/*
int main() {
std::cout<< get_supported_extensions() << std::endl;
}*/
std::string get_auther_info(){
return "b站 路人aenu \n" \
"个人主页https://aenu.cc \n";
}
std::pair<std::string,bool> vk_lib_info(){
const std::pair<std::string,bool> dedault_info={"libvulkan.so",false};

View File

@@ -84,7 +84,7 @@ namespace gl
}
fmt::throw_exception("Unsupported blend factor 0x%X", static_cast<u32>(op));
}
#ifndef USE_GLES
GLenum logic_op(rsx::logic_op op)
{
switch (op)
@@ -108,7 +108,7 @@ namespace gl
}
fmt::throw_exception("Unsupported logic op 0x%X", static_cast<u32>(op));
}
#endif
GLenum front_face(rsx::front_face op)
{
//NOTE: RSX face winding is always based off of upper-left corner like vulkan, but GL is bottom left
@@ -147,19 +147,19 @@ void GLGSRender::update_draw_state()
// Z-buffer is active.
gl_state.depth_mask(rsx::method_registers.depth_write_enabled());
gl_state.stencil_mask(rsx::method_registers.stencil_mask());
#ifndef USE_GLES
gl_state.enable(rsx::method_registers.depth_clamp_enabled() || !rsx::method_registers.depth_clip_enabled(), GL_DEPTH_CLAMP);
#endif
if (gl_state.enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST))
{
gl_state.depth_func(gl::comparison_op(rsx::method_registers.depth_func()));
}
#ifndef USE_GLES
if (gl::get_driver_caps().EXT_depth_bounds_test_supported && (gl_state.enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT)))
{
gl_state.depth_bounds(rsx::method_registers.depth_bounds_min(), rsx::method_registers.depth_bounds_max());
}
#endif
if (gl::get_driver_caps().NV_depth_buffer_float_supported)
{
gl_state.depth_range(rsx::method_registers.clip_min(), rsx::method_registers.clip_max());
@@ -220,16 +220,17 @@ void GLGSRender::update_draw_state()
// LogicOp and Blend are mutually exclusive. If both are enabled, LogicOp takes precedence.
// In OpenGL, this behavior is enforced in spec, but let's enforce it at renderer level as well.
#ifndef USE_GLES
if (gl_state.enable(rsx::method_registers.logic_op_enabled(), GL_COLOR_LOGIC_OP))
{
gl_state.logic_op(gl::logic_op(rsx::method_registers.logic_operation()));
gl_state.enablei(GL_FALSE, GL_BLEND, 0);
gl_state.enablei(GL_FALSE, GL_BLEND, 1);
gl_state.enablei(GL_FALSE, GL_BLEND, 2);
gl_state.enablei(GL_FALSE, GL_BLEND, 3);
}
else
#endif
{
bool mrt_blend_enabled[] =
{
@@ -262,8 +263,9 @@ void GLGSRender::update_draw_state()
// Antialias control
if (backend_config.supports_hw_msaa)
{
#ifndef USE_GLES
gl_state.enable(/*REGS(m_ctx)->msaa_enabled()*/GL_MULTISAMPLE);
#endif
gl_state.enable(GL_SAMPLE_MASK);
gl_state.sample_mask(REGS(m_ctx)->msaa_sample_mask());
@@ -280,10 +282,12 @@ void GLGSRender::update_draw_state()
gl_state.enable(hw_enable && REGS(m_ctx)->msaa_alpha_to_coverage_enabled(), GL_SAMPLE_ALPHA_TO_COVERAGE);
}
#ifndef USE_GLES
if (backend_config.supports_hw_a2one)
{
gl_state.enable(REGS(m_ctx)->msaa_alpha_to_one_enabled(), GL_SAMPLE_ALPHA_TO_ONE);
}
#endif
}
switch (rsx::method_registers.current_draw_clause.primitive)
@@ -292,11 +296,17 @@ void GLGSRender::update_draw_state()
case rsx::primitive_type::line_loop:
case rsx::primitive_type::line_strip:
gl_state.line_width(rsx::method_registers.line_width() * rsx::get_resolution_scale());
#ifndef USE_GLES
gl_state.enable(rsx::method_registers.line_smooth_enabled(), GL_LINE_SMOOTH);
#endif
break;
default:
#ifndef USE_GLES
gl_state.enable(rsx::method_registers.poly_offset_point_enabled(), GL_POLYGON_OFFSET_POINT);
gl_state.enable(rsx::method_registers.poly_offset_line_enabled(), GL_POLYGON_OFFSET_LINE);
#endif
gl_state.enable(rsx::method_registers.poly_offset_fill_enabled(), GL_POLYGON_OFFSET_FILL);
// offset_bias is the constant factor, multiplied by the implementation factor R
@@ -647,6 +657,12 @@ void GLGSRender::emit_geometry(u32 sub_index)
first += range.count;
}
#ifdef USE_GLES
for (u32 n = 0; n < draw_count; ++n)
{
glDrawArrays(draw_mode, firsts[n], counts[n]);
}
#else
if (use_draw_arrays_fallback)
{
// MultiDrawArrays is broken on some primitive types using AMD. One known type is GL_TRIANGLE_STRIP but there could be more
@@ -666,6 +682,7 @@ void GLGSRender::emit_geometry(u32 sub_index)
// Normal render
glMultiDrawArrays(draw_mode, firsts, counts, static_cast<GLsizei>(draw_count));
}
#endif
}
}
else

View File

@@ -133,8 +133,11 @@ void GLGSRender::on_init_thread()
gl::set_primary_context_thread();
zcull_ctrl.reset(static_cast<::rsx::reports::ZCULL_control*>(this));
#ifdef USE_GLES
m_occlusion_type = GL_ANY_SAMPLES_PASSED;
#else
m_occlusion_type = g_cfg.video.precise_zpass_count ? GL_SAMPLES_PASSED : GL_ANY_SAMPLES_PASSED;
#endif
gl::init();
gl::set_command_context(gl_state);
@@ -197,7 +200,7 @@ void GLGSRender::on_init_thread()
// NVIDIA's attribute interpolation requires some workarounds
backend_config.supports_normalized_barycentrics = false;
}
#ifndef USE_GLES
if (gl_caps.AMD_pinned_memory_supported && g_cfg.video.host_label_synchronization)
{
backend_config.supports_host_gpu_labels = true;
@@ -211,13 +214,15 @@ void GLGSRender::on_init_thread()
m_enqueued_host_write_buffer = std::make_unique<gl::scratch_ring_buffer>();
m_enqueued_host_write_buffer->create(gl::buffer::target::array, 64 * 0x100000, gl::buffer::usage::dynamic_update);
}
#endif
// Use industry standard resource alignment values as defaults
m_uniform_buffer_offset_align = 256;
m_min_texbuffer_alignment = 256;
m_max_texbuffer_size = 0;
#ifndef USE_GLES
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &m_uniform_buffer_offset_align);
glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &m_min_texbuffer_alignment);
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &m_max_texbuffer_size);
@@ -250,6 +255,23 @@ void GLGSRender::on_init_thread()
{
std::array<u32, 8> pixeldata = { 0, 0, 0, 0, 0, 0, 0, 0 };
#ifdef USE_GLES
// 1D
auto tex1D = std::make_unique<gl::texture>(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
tex1D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::ubyte, {});
// 2D
auto tex2D = std::make_unique<gl::texture>(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
tex2D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::ubyte, {});
// 3D
auto tex3D = std::make_unique<gl::texture>(GL_TEXTURE_3D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
tex3D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::ubyte, {});
// CUBE
auto texCUBE = std::make_unique<gl::texture>(GL_TEXTURE_CUBE_MAP, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
texCUBE->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::ubyte, {});
#else
// 1D
auto tex1D = std::make_unique<gl::texture>(GL_TEXTURE_1D, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
tex1D->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
@@ -265,7 +287,7 @@ void GLGSRender::on_init_thread()
// CUBE
auto texCUBE = std::make_unique<gl::texture>(GL_TEXTURE_CUBE_MAP, 1, 1, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
texCUBE->copy_from(pixeldata.data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
#endif
m_null_textures[GL_TEXTURE_1D] = std::move(tex1D);
m_null_textures[GL_TEXTURE_2D] = std::move(tex2D);
m_null_textures[GL_TEXTURE_3D] = std::move(tex3D);
@@ -278,8 +300,9 @@ void GLGSRender::on_init_thread()
// TODO: do not modify config options
g_cfg.video.renderdoc_compatiblity.from_string("true");
}
#ifndef USE_GLES
if (g_cfg.video.renderdoc_compatiblity)
#endif
{
rsx_log.warning("Using legacy openGL buffers.");
manually_flush_ring_buffers = true;
@@ -298,6 +321,7 @@ void GLGSRender::on_init_thread()
m_scratch_ring_buffer = std::make_unique<gl::legacy_ring_buffer>();
m_instancing_ring_buffer = std::make_unique<gl::legacy_ring_buffer>();
}
#ifndef USE_GLES
else
{
m_attrib_ring_buffer = std::make_unique<gl::ring_buffer>();
@@ -314,7 +338,7 @@ void GLGSRender::on_init_thread()
m_scratch_ring_buffer = std::make_unique<gl::ring_buffer>();
m_instancing_ring_buffer = std::make_unique<gl::ring_buffer>();
}
#endif
m_attrib_ring_buffer->create(gl::buffer::target::texture, 256 * 0x100000);
m_index_ring_buffer->create(gl::buffer::target::element_array, 16 * 0x100000);
m_transform_constants_buffer->create(gl::buffer::target::uniform, 64 * 0x100000);

View File

@@ -221,9 +221,21 @@ namespace gl
gl::texture_view* ui_overlay_renderer::load_simple_image(rsx::overlays::image_info* desc, bool temp_resource, u32 owner_uid)
{
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
#ifdef USE_GLES
tex->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::ubyte, {});
const GLenum remap[] = {
GL_RED,
GL_GREEN,
GL_BLUE,
GL_ALPHA,
};
#else
tex->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
const GLenum remap[] = { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN };
#endif
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
auto result = view.get();

View File

@@ -132,7 +132,12 @@ gl::texture* GLGSRender::get_present_source(gl::present_surface_info* info, cons
const auto range = utils::address_range::start_length(info->address, info->pitch * info->height);
m_gl_texture_cache.invalidate_range(cmd, range, rsx::invalidation_cause::read);
#ifdef USE_GLES
flip_image->copy_from(vm::base(info->address), static_cast<gl::texture::format>(expected_format), gl::texture::type::ubyte, unpack_settings);
#else
flip_image->copy_from(vm::base(info->address), static_cast<gl::texture::format>(expected_format), gl::texture::type::uint_8_8_8_8, unpack_settings);
#endif
image = flip_image.get();
}
else if (image->get_internal_format() != static_cast<gl::texture::internal_format>(expected_format))

View File

@@ -54,12 +54,23 @@ struct GLTraits
const_cast<gl::glsl::shader*>(fp)->compile();
}
#ifdef USE_GLES
program->attach(*vp)
.attach(*fp);
#else
program->attach(*vp)
.attach(*fp)
.bind_fragment_data_location("ocol0", 0)
.bind_fragment_data_location("ocol1", 1)
.bind_fragment_data_location("ocol2", 2)
.bind_fragment_data_location("ocol3", 3);
#endif // USE_GLES
if (g_cfg.video.log_programs)
{

View File

@@ -14,8 +14,13 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
return{ ::gl::texture::type::ushort_5_6_5, ::gl::texture::format::rgb, ::gl::texture::internal_format::rgb565, true };
case rsx::surface_color_format::a8r8g8b8:
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true };
#ifdef USE_GLES
return {::gl::texture::type::ubyte, ::gl::texture::format::rgba, ::gl::texture::internal_format::bgra8, true};
#else
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true };
#endif
//These formats discard their alpha component, forced to 0 or 1
//All XBGR formats will have remapping before they can be read back in shaders as DRGB8
//Prefix o = 1, z = 0
@@ -28,20 +33,45 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
{ ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
case rsx::surface_color_format::x8r8g8b8_z8r8g8b8:
#ifdef USE_GLES
return {::gl::texture::type::ubyte, ::gl::texture::format::rgba, ::gl::texture::internal_format::bgra8, true,
{::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b}};
#else
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true,
{ ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
#endif
case rsx::surface_color_format::x8b8g8r8_o8b8g8r8:
#ifdef USE_GLES
return {::gl::texture::type::ubyte, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true,
{::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b}};
#else
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true,
{ ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
#endif
case rsx::surface_color_format::x8b8g8r8_z8b8g8r8:
#ifdef USE_GLES
return {::gl::texture::type::ubyte, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true,
{::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b}};
#else
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true,
{ ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
#endif
case rsx::surface_color_format::x8r8g8b8_o8r8g8b8:
#ifdef USE_GLES
return {::gl::texture::type::ubyte, ::gl::texture::format::rgba, ::gl::texture::internal_format::bgra8, true,
{::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b}};
#else
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true,
{ ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } };
#endif
case rsx::surface_color_format::w16z16y16x16:
return{ ::gl::texture::type::f16, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba16f, true};
@@ -62,7 +92,12 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma
{ ::gl::texture::channel::r, ::gl::texture::channel::r, ::gl::texture::channel::r, ::gl::texture::channel::r } };
case rsx::surface_color_format::a8b8g8r8:
#ifdef USE_GLES
return {::gl::texture::type::ubyte, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true};
#else
return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true };
#endif
default:
fmt::throw_exception("Unsupported surface color format 0x%x", static_cast<u32>(color_format));

View File

@@ -84,8 +84,13 @@ namespace gl
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return GL_DEPTH32F_STENCIL8;
case CELL_GCM_TEXTURE_DEPTH16: return GL_DEPTH_COMPONENT16;
case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return GL_DEPTH_COMPONENT32F;
#ifdef USE_GLES
case CELL_GCM_TEXTURE_X16: return GL_R16_EXT;
case CELL_GCM_TEXTURE_Y16_X16: return GL_RG16_EXT;
#else
case CELL_GCM_TEXTURE_X16: return GL_R16;
case CELL_GCM_TEXTURE_Y16_X16: return GL_RG16;
#endif
case CELL_GCM_TEXTURE_R5G5B5A1: return GL_RGB5_A1;
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return GL_RGBA16F;
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return GL_RGBA32F;
@@ -110,10 +115,20 @@ namespace gl
switch (texture_format)
{
case CELL_GCM_TEXTURE_B8: return std::make_tuple(GL_RED, GL_UNSIGNED_BYTE);
#ifdef USE_GLES
case CELL_GCM_TEXTURE_A1R5G5B5: return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_A4R4G4B4: return std::make_tuple(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
#else
case CELL_GCM_TEXTURE_A1R5G5B5: return std::make_tuple(GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
case CELL_GCM_TEXTURE_A4R4G4B4: return std::make_tuple(GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4);
#endif
case CELL_GCM_TEXTURE_R5G6B5: return std::make_tuple(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
#ifdef USE_GLES
case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE);
#else
case CELL_GCM_TEXTURE_A8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
#endif
case CELL_GCM_TEXTURE_G8B8: return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_R6G5B5: return std::make_tuple(GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
case CELL_GCM_TEXTURE_DEPTH24_D8: return std::make_tuple(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
@@ -126,16 +141,32 @@ namespace gl
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return std::make_tuple(GL_RGBA, GL_HALF_FLOAT);
case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return std::make_tuple(GL_RGBA, GL_FLOAT);
case CELL_GCM_TEXTURE_X32_FLOAT: return std::make_tuple(GL_RED, GL_FLOAT);
#ifdef USE_GLES
case CELL_GCM_TEXTURE_D1R5G5B5: return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_RGBA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT3_EXT : GL_RGBA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_RGBA, GL_UNSIGNED_BYTE);
#else
case CELL_GCM_TEXTURE_D1R5G5B5: return std::make_tuple(GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
case CELL_GCM_TEXTURE_D8R8G8B8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT3_EXT : GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_BGRA, GL_UNSIGNED_BYTE);
#endif
case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return std::make_tuple(GL_RG, GL_HALF_FLOAT);
case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT3_EXT : GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return std::make_tuple(supports_dxt ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return std::make_tuple(GL_RG, GL_BYTE);
#ifdef USE_GLES
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE);
#else
case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_BYTE);
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_BYTE);
#endif
}
fmt::throw_exception("Compressed or unknown texture format 0x%x", texture_format);
}
@@ -164,6 +195,17 @@ namespace gl
return { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, true };
case texture::internal_format::rgb5a1:
return { GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 2, true };
#ifdef USE_GLES
case texture::internal_format::bgr5a1:
return { GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 2, true };
case texture::internal_format::rgba4:
return { GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, false };
case texture::internal_format::rgba8:
return { GL_RGBA, GL_UNSIGNED_BYTE, 4, true };
case texture::internal_format::bgra8:
return { GL_RGBA, GL_UNSIGNED_BYTE, 4, true };
#else
case texture::internal_format::bgr5a1:
return { GL_RGB, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, true };
case texture::internal_format::rgba4:
@@ -172,6 +214,7 @@ namespace gl
return { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true };
case texture::internal_format::bgra8:
return { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true };
#endif
case texture::internal_format::rgba16f:
return { GL_RGBA, GL_HALF_FLOAT, 2, true };
case texture::internal_format::rgba32f:

View File

@@ -105,8 +105,14 @@ namespace gl
switch (type)
{
#ifdef USE_GLES
case gl::texture::type::ubyte:
#else
case gl::texture::type::uint_8_8_8_8_rev:
case gl::texture::type::uint_8_8_8_8:
#endif
case gl::texture::type::uint_24_8:
rsx::convert_linear_swizzle<u32, false>(tmp_data.data(), dst, width, height, rsx_pitch);
break;

View File

@@ -675,7 +675,16 @@ namespace gl
{
case CELL_GCM_TEXTURE_A8R8G8B8:
{
#ifdef USE_GLES
cached.set_format(gl::texture::format::rgba, gl::texture::type::ubyte, true);
#else
cached.set_format(gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8_rev, true);
#endif // USE_GLES
break;
}
case CELL_GCM_TEXTURE_R5G6B5:
@@ -751,17 +760,19 @@ namespace gl
section.set_view_flags(flags);
}
void insert_texture_barrier(gl::command_context&, gl::texture*, bool) override
{
#ifndef USE_GLES
auto &caps = gl::get_driver_caps();
if (caps.ARB_texture_barrier_supported)
glTextureBarrier();
else if (caps.NV_texture_barrier_supported)
glTextureBarrierNV();
}
#endif
}
bool render_target_format_is_compatible(gl::texture* tex, u32 gcm_format) override
{
auto ifmt = tex->get_internal_format();

View File

@@ -24,8 +24,21 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval);
#include <OpenGL/glu.h>
#elif defined(__ANDROID__)
#include <GLES3/gl32.h>
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2ext.h>
#define USE_GLES
#else
#include <GL/gl.h>
#ifdef HAVE_X11
#include <GL/glxew.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#endif
#endif
#ifdef USE_GLES
#define _GL_DOUBLE 0x140A
#define _GL_UNSIGNED_BYTE_3_3_2 0x8032
#define _GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
@@ -42,20 +55,13 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval);
#define _GL_R16 0x822A
#define _GL_RG16 0x822C
#define _GL_MIRROR_CLAMP_EXT 0x8742
//#define _GL_MIRROR_CLAMP_TO_EDGE 0x8743
// #define _GL_MIRROR_CLAMP_TO_EDGE 0x8743
#define _GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
#define _GL_BGR 0x80E0
#define _GL_BGRA 0x80E1
#define _GL_TEXTURE_1D 0x0DE0
#endif
#else
#include <GL/gl.h>
#ifdef HAVE_X11
#include <GL/glxew.h>
#include <GL/glx.h>
#include <GL/glxext.h>
#endif
#endif
#ifndef GL_TEXTURE_BUFFER_BINDING
//During spec release, this enum was removed during upgrade from ARB equivalent

View File

@@ -8,7 +8,37 @@ namespace gl
{
m_memory_type = type;
#ifndef USE_GLES
#ifdef USE_GLES
if (type != memory_type::userptr)
{
GLenum flags = 0;
if (usage_flags & usage::host_write)
{
flags |= GL_MAP_WRITE_BIT;
}
if (usage_flags & usage::host_read)
{
flags |= GL_MAP_READ_BIT;
}
if (usage_flags & usage::persistent_map)
{
flags |= GL_MAP_PERSISTENT_BIT_EXT;
}
if (usage_flags & usage::dynamic_update)
{
flags |= GL_DYNAMIC_STORAGE_BIT_EXT;
}
ensure((flags & (GL_MAP_PERSISTENT_BIT_EXT | GL_DYNAMIC_STORAGE_BIT_EXT)) != (GL_MAP_PERSISTENT_BIT_EXT | GL_DYNAMIC_STORAGE_BIT_EXT),
"Mutually exclusive usage flags set!");
ensure(type == memory_type::local || flags != 0, "Host-visible memory must have usage flags set!");
glBindBuffer(GL_ARRAY_BUFFER, m_id);
glBufferStorageEXT(GL_ARRAY_BUFFER, size, data_, flags);
m_size = size;
}
#else
if (const auto& caps = get_driver_caps();
type != memory_type::userptr && caps.ARB_buffer_storage_supported)
{
@@ -48,8 +78,8 @@ namespace gl
DSA_CALL2(NamedBufferStorage, m_id, size, data_, flags);
m_size = size;
}
else
#endif
else
{
data(size, data_, GL_STREAM_COPY);
}

View File

@@ -216,7 +216,24 @@ namespace gl
{
save_binding_state save(*this);
pixel_settings.apply();
#ifdef USE_GLES
//FIXME
/*GLuint pbo_id;
glGenBuffers(1, &pbo_id);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_id);
GLubyte* pbo_ptr = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size.width * size.height * 4, GL_MAP_WRITE_BIT);
ensure(pbo_ptr!=nullptr);
memcpy(pbo_ptr, pixels, size.width * size.height * 4);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE);
glDeleteBuffers(1, &pbo_id);*/
#else
glDrawPixels(size.width, size.height, static_cast<GLenum>(format_), static_cast<GLenum>(type_), pixels);
#endif
}
void fbo::copy_from(const buffer& buf, const sizei& size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings) const
@@ -224,7 +241,11 @@ namespace gl
save_binding_state save(*this);
buffer::save_binding_state save_buffer(buffer::target::pixel_unpack, buf);
pixel_settings.apply();
#ifndef USE_GLES
//FIXME
glDrawPixels(size.width, size.height, static_cast<GLenum>(format_), static_cast<GLenum>(type_), nullptr);
#endif
}
void fbo::copy_to(void* pixels, coordi coord, gl::texture::format format_, gl::texture::type type_, class pixel_pack_settings pixel_settings) const

View File

@@ -129,7 +129,11 @@ namespace gl
rhs.get_target() == texture::target::texture2DMS);
m_parent.m_resource_bindings[m_id] = rhs.id();
#ifndef USE_GLES
#ifdef USE_GLES
glBindFramebuffer(GL_FRAMEBUFFER, m_parent.id());
glFramebufferTexture(GL_FRAMEBUFFER, m_id, rhs.id(), 0);
#else
DSA_CALL2(NamedFramebufferTexture, m_parent.id(), m_id, rhs.id(), 0);
#endif
}
@@ -137,7 +141,10 @@ namespace gl
void operator = (const GLuint rhs)
{
m_parent.m_resource_bindings[m_id] = rhs;
#ifndef USE_GLES
#ifdef USE_GLES
glBindFramebuffer(GL_FRAMEBUFFER, m_parent.id());
glFramebufferTexture(GL_FRAMEBUFFER, m_id, rhs, 0);
#else
DSA_CALL2(NamedFramebufferTexture, m_parent.id(), m_id, rhs, 0);
#endif
}

View File

@@ -48,7 +48,11 @@ namespace gl
default:
fmt::throw_exception("Invalid image target 0x%X", target);
case GL_TEXTURE_1D:
#ifdef USE_GLES
glTexStorage2D(GL_TEXTURE_2D, mipmaps, storage_fmt, width, 1);
#else
glTexStorage1D(target, mipmaps, storage_fmt, width);
#endif
height = depth = 1;
break;
case GL_TEXTURE_2D:
@@ -185,7 +189,12 @@ namespace gl
{
case GL_TEXTURE_1D:
{
#ifdef USE_GLES
glBindTexture(GL_TEXTURE_2D,m_id);
glTexSubImage2D(GL_TEXTURE_2D, level, region.x, 0, region.width, 1, static_cast<GLenum>(format), static_cast<GLenum>(type), src);
#else
DSA_CALL(TextureSubImage1D, m_id, GL_TEXTURE_1D, level, region.x, region.width, static_cast<GLenum>(format), static_cast<GLenum>(type), src);
#endif
break;
}
case GL_TEXTURE_2D:
@@ -213,6 +222,11 @@ namespace gl
}
case GL_TEXTURE_CUBE_MAP:
{
#ifdef USE_GLES
glBindTexture(target_,m_id);
glTexSubImage3D( target_, level, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast<GLenum>(format), static_cast<GLenum>(type), src);
#else
if (get_driver_caps().ARB_direct_state_access_supported)
{
glTextureSubImage3D(m_id, level, region.x, region.y, region.z, region.width, region.height, region.depth, static_cast<GLenum>(format), static_cast<GLenum>(type), src);
@@ -228,6 +242,7 @@ namespace gl
ptr += (region.width * region.height * 4); //TODO
}
}
#endif
break;
}
}
@@ -239,8 +254,12 @@ namespace gl
if (get_target() != target::textureBuffer)
fmt::throw_exception("OpenGL error: texture cannot copy from buffer");
#ifdef USE_GLES
glBindTexture(GL_TEXTURE_BUFFER, m_id);
glTexBufferRange(GL_TEXTURE_BUFFER, gl_format_type, buf.id(), offset, length);
#else
DSA_CALL(TextureBufferRange, m_id, GL_TEXTURE_BUFFER, gl_format_type, buf.id(), offset, length);
#endif
}
void texture::copy_from(buffer_view& view)
@@ -301,7 +320,9 @@ namespace gl
component_swizzle[2] = argb_swizzle[3];
component_swizzle[3] = argb_swizzle[0];
#ifndef USE_GLES
DSA_CALL(TextureParameteriv, m_id, m_target, GL_TEXTURE_SWIZZLE_RGBA, reinterpret_cast<GLint*>(component_swizzle));
#endif
}
else
{
@@ -316,7 +337,12 @@ namespace gl
constexpr u32 depth_stencil_mask = (image_aspect::depth | image_aspect::stencil);
ensure((range.aspect_mask & depth_stencil_mask) != depth_stencil_mask); // "Invalid aspect mask combination"
DSA_CALL(TextureParameteri, m_id, m_target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
#ifndef USE_GLES
glBindTexture(m_id, m_target);
glTexParameteri(m_target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
#else
DSA_CALL(TextureParameteri, m_id, m_target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
#endif
}
}

View File

@@ -85,6 +85,22 @@ namespace gl
uint_10_10_10_2 = GL_UNSIGNED_INT_10_10_10_2,
f64 = GL_DOUBLE,
#else
/* ubyte_3_3_2 = _GL_UNSIGNED_BYTE_3_3_2,
ubyte_2_3_3_rev = _GL_UNSIGNED_BYTE_2_3_3_REV,
ushort_5_6_5_rev = _GL_UNSIGNED_SHORT_5_6_5_REV,
ushort_4_4_4_4_rev = _GL_UNSIGNED_SHORT_4_4_4_4_REV,
ushort_1_5_5_5_rev = _GL_UNSIGNED_SHORT_1_5_5_5_REV,
uint_8_8_8_8 = _GL_UNSIGNED_INT_8_8_8_8,
uint_8_8_8_8_rev = _GL_UNSIGNED_INT_8_8_8_8_REV,
uint_10_10_10_2 = _GL_UNSIGNED_INT_10_10_10_2,
f64 = _GL_DOUBLE,*/
#endif
ushort_5_6_5 = GL_UNSIGNED_SHORT_5_6_5,
ushort_4_4_4_4 = GL_UNSIGNED_SHORT_4_4_4_4,
@@ -135,12 +151,11 @@ namespace gl
depth24_stencil8 = GL_DEPTH24_STENCIL8,
depth32f_stencil8 = GL_DEPTH32F_STENCIL8,
#ifndef USE_GLES
compressed_rgb_s3tc_dxt1 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
compressed_rgba_s3tc_dxt1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
compressed_rgba_s3tc_dxt3 = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
compressed_rgba_s3tc_dxt5 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
#endif
//Sized internal formats, see opengl spec document on glTexImage2D, table 3
rgba8 = GL_RGBA8,
bgra8 = GL_BGRA8,
@@ -150,13 +165,17 @@ namespace gl
rgba4 = GL_RGBA4,
r8 = GL_R8,
#ifndef USE_GLES
#ifdef USE_GLES
r16 = GL_R16_EXT,
#else
r16 = GL_R16,
#endif
r32f = GL_R32F,
rg8 = GL_RG8,
#ifndef USE_GLES
#ifdef USE_GLES
rg16 = GL_RG16_EXT,
#else
rg16 = GL_RG16,
#endif
rg16f = GL_RG16F,
@@ -189,7 +208,9 @@ namespace gl
enum class target
{
#ifndef USE_GLES
#ifdef USE_GLES
texture1D = _GL_TEXTURE_1D,
#else
texture1D = GL_TEXTURE_1D,
#endif
texture2D = GL_TEXTURE_2D,
@@ -238,7 +259,7 @@ namespace gl
return m_target;
}
#ifndef USE_GLES
#if 1//ndef USE_GLES
static bool compressed_format(internal_format format_) noexcept
{
switch (format_)

View File

@@ -3,6 +3,123 @@
namespace gl
{
#ifdef USE_GLES
void ring_buffer::recreate(GLsizeiptr size, const void* data)
{
if (m_id)
remove();
buffer::create();
buffer::data(size, data, GL_DYNAMIC_DRAW);
m_memory_type = memory_type::host_visible;
m_memory_mapping = nullptr;
m_data_loc = 0;
m_size = ::narrow<u32>(size);
}
void ring_buffer::create(target target_, GLsizeiptr size, const void* data_)
{
m_target = target_;
recreate(size, data_);
}
void ring_buffer::reserve_storage_on_heap(u32 alloc_size)
{
ensure(m_memory_mapping == nullptr);
u32 offset = m_data_loc;
if (m_data_loc)
offset = utils::align(offset, 256);
const u32 block_size = utils::align(alloc_size + 16, 256); // Overallocate just in case we need to realign base
if ((offset + block_size) > m_size)
{
buffer::data(m_size, nullptr, GL_DYNAMIC_DRAW);
m_data_loc = 0;
}
glBindBuffer(GL_ARRAY_BUFFER, m_id);
m_memory_mapping = glMapBufferRange(GL_ARRAY_BUFFER, m_data_loc, block_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
m_mapped_bytes = block_size;
m_mapping_offset = m_data_loc;
m_alignment_offset = 0;
// When using debugging tools, the mapped base might not be aligned as expected
const u64 mapped_address_base = reinterpret_cast<u64>(m_memory_mapping);
if (mapped_address_base & 0xF)
{
// Unaligned result was returned. We have to modify the base address a bit
// We lose some memory here, but the 16 byte overallocation above makes up for it
const u64 new_base = (mapped_address_base & ~0xF) + 16;
const u64 diff_bytes = new_base - mapped_address_base;
m_memory_mapping = reinterpret_cast<void*>(new_base);
m_mapped_bytes -= ::narrow<u32>(diff_bytes);
m_alignment_offset = ::narrow<u32>(diff_bytes);
}
ensure(m_mapped_bytes >= alloc_size);
}
std::pair<void*, u32> ring_buffer::alloc_from_heap(u32 alloc_size, u16 alignment)
{
u32 offset = m_data_loc;
if (m_data_loc)
offset = utils::align(offset, alignment);
u32 padding = (offset - m_data_loc);
u32 real_size = utils::align(padding + alloc_size, alignment); // Ensures we leave the loc pointer aligned after we exit
if (real_size > m_mapped_bytes)
{
// Missed allocation. We take a performance hit on doing this.
// Overallocate slightly for the next allocation if requested size is too small
unmap();
reserve_storage_on_heap(std::max(real_size, 4096U));
offset = m_data_loc;
if (m_data_loc)
offset = utils::align(offset, alignment);
padding = (offset - m_data_loc);
real_size = utils::align(padding + alloc_size, alignment);
}
m_data_loc = offset + real_size;
m_mapped_bytes -= real_size;
u32 local_offset = (offset - m_mapping_offset);
return std::make_pair(static_cast<char*>(m_memory_mapping) + local_offset, offset + m_alignment_offset);
}
void ring_buffer::remove()
{
if (m_memory_mapping)
{
buffer::unmap();
m_memory_mapping = nullptr;
m_data_loc = 0;
m_size = 0;
}
buffer::remove();
m_mapped_bytes = 0;
}
void ring_buffer::unmap()
{
buffer::unmap();
m_memory_mapping = nullptr;
m_mapped_bytes = 0;
m_mapping_offset = 0;
}
#else
void ring_buffer::recreate(GLsizeiptr size, const void* data)
{
if (m_id)
@@ -14,18 +131,12 @@ namespace gl
buffer::create();
save_binding_state save(current_target(), *this);
#ifndef USE_GLES
GLbitfield buffer_storage_flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
if (gl::get_driver_caps().vendor_MESA) buffer_storage_flags |= GL_CLIENT_STORAGE_BIT;
DSA_CALL2(NamedBufferStorage, m_id, size, data, buffer_storage_flags);
m_memory_mapping = DSA_CALL2_RET(MapNamedBufferRange, m_id, 0, size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
#else
GLbitfield buffer_storage_flags = GL_MAP_WRITE_BIT;
glBindBuffer(GL_ARRAY_BUFFER, m_id);
glBufferData(GL_ARRAY_BUFFER, size, data, buffer_storage_flags);
m_memory_mapping = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, buffer_storage_flags);
#endif
ensure(m_memory_mapping != nullptr);
m_data_loc = 0;
m_size = ::narrow<u32>(size);
@@ -121,12 +232,8 @@ namespace gl
m_data_loc = 0;
}
#ifndef USE_GLES
m_memory_mapping = DSA_CALL2_RET(MapNamedBufferRange, m_id, m_data_loc, block_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
#else
glBindBuffer(GL_ARRAY_BUFFER, m_id);
m_memory_mapping = glMapBufferRange(GL_ARRAY_BUFFER, m_data_loc, block_size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
#endif
m_mapped_bytes = block_size;
m_mapping_offset = m_data_loc;
m_alignment_offset = 0;
@@ -199,12 +306,8 @@ namespace gl
dirty = true;
#ifndef USE_GLES
return DSA_CALL2_RET(MapNamedBufferRange, m_id, offset, length, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
#else
glBindBuffer(GL_ARRAY_BUFFER, m_id);
return glMapBufferRange(GL_ARRAY_BUFFER, offset, length, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
#endif
}
void transient_ring_buffer::bind()
@@ -224,12 +327,8 @@ namespace gl
buffer::create();
save_binding_state save(current_target(), *this);
#ifndef USE_GLES
DSA_CALL2(NamedBufferStorage, m_id, size, data, GL_MAP_WRITE_BIT);
#else
glBindBuffer(GL_ARRAY_BUFFER, m_id);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_MAP_WRITE_BIT);
#endif
m_data_loc = 0;
m_size = ::narrow<u32>(size);
m_memory_type = memory_type::host_visible;
@@ -255,7 +354,7 @@ namespace gl
{
flush();
}
#endif
scratch_ring_buffer::~scratch_ring_buffer()
{
if (m_storage)
@@ -328,4 +427,4 @@ namespace gl
barrier_.signal.create();
m_barriers.emplace_back(barrier_);
}
}
}

View File

@@ -6,6 +6,45 @@
namespace gl
{
#ifdef USE_GLES
class ring_buffer final: public buffer
{
protected:
u32 m_data_loc = 0;
void* m_memory_mapping = nullptr;
fence m_fence;
u32 m_mapped_bytes = 0;
u32 m_mapping_offset = 0;
u32 m_alignment_offset = 0;
public:
~ring_buffer() = default;
void bind()
{
buffer::bind();
}
void recreate(GLsizeiptr size, const void* data = nullptr);
void create(target target_, GLsizeiptr size, const void* data_ = nullptr);
std::pair<void*, u32> alloc_from_heap(u32 alloc_size, u16 alignment);
void remove();
void reserve_storage_on_heap(u32 /*alloc_size*/);
void unmap();
void flush() {}
void notify() {}
};
using legacy_ring_buffer = ring_buffer;
#else
class ring_buffer : public buffer
{
protected:
@@ -81,7 +120,7 @@ namespace gl
void unmap() override;
};
#endif
// Simple GPU-side ring buffer with no map/unmap semantics
class scratch_ring_buffer
{

View File

@@ -19,8 +19,10 @@ namespace gl
case rsx::texture_wrap_mode::border: return GL_CLAMP_TO_BORDER;
case rsx::texture_wrap_mode::clamp: return GL_CLAMP_TO_EDGE;
case rsx::texture_wrap_mode::mirror_once_clamp_to_edge: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
#ifndef USE_GLES
case rsx::texture_wrap_mode::mirror_once_border: return GL_MIRROR_CLAMP_TO_BORDER_EXT;
case rsx::texture_wrap_mode::mirror_once_clamp: return GL_MIRROR_CLAMP_EXT;
#endif
}
rsx_log.error("Texture wrap error: bad wrap (%d)", static_cast<u32>(wrap));
@@ -113,14 +115,18 @@ namespace gl
}
set_parameteri(GL_TEXTURE_MIN_FILTER, min_filter);
#ifndef USE_GLES
set_parameterf(GL_TEXTURE_LOD_BIAS, 0.f);
#endif
set_parameterf(GL_TEXTURE_MIN_LOD, -1000.f);
set_parameterf(GL_TEXTURE_MAX_LOD, 1000.f);
}
else
{
set_parameteri(GL_TEXTURE_MIN_FILTER, tex_min_filter(tex.min_filter()));
#ifndef USE_GLES
set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias());
#endif
set_parameterf(GL_TEXTURE_MIN_LOD, tex.min_lod());
set_parameterf(GL_TEXTURE_MAX_LOD, tex.max_lod());
}
@@ -171,7 +177,9 @@ namespace gl
set_parameteri(GL_TEXTURE_WRAP_R, wrap_mode(tex.wrap_r()));
set_parameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
set_parameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifndef USE_GLES
set_parameterf(GL_TEXTURE_LOD_BIAS, tex.bias());
#endif
set_parameterf(GL_TEXTURE_MIN_LOD, tex.min_lod());
set_parameterf(GL_TEXTURE_MAX_LOD, tex.max_lod());
set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE);
@@ -184,7 +192,9 @@ namespace gl
set_parameteri(GL_TEXTURE_WRAP_R, GL_REPEAT);
set_parameteri(GL_TEXTURE_MIN_FILTER, default_filter);
set_parameteri(GL_TEXTURE_MAG_FILTER, default_filter);
#ifndef USE_GLES
set_parameterf(GL_TEXTURE_LOD_BIAS, 0.f);
#endif
set_parameteri(GL_TEXTURE_MIN_LOD, 0);
set_parameteri(GL_TEXTURE_MAX_LOD, 0);
set_parameteri(GL_TEXTURE_COMPARE_MODE, GL_NONE);

View File

@@ -258,7 +258,9 @@ namespace gl
const u64 value = (static_cast<u64>(std::bit_cast<u32>(max)) << 32) | std::bit_cast<u32>(min);
if (!test_and_set_property(DEPTH_RANGE, value))
{
#ifndef USE_GLES
#ifdef USE_GLES
glDepthRangef(min, max);
#else
if (get_driver_caps().NV_depth_buffer_float_supported)
{
glDepthRangedNV(min, max);
@@ -347,7 +349,17 @@ namespace gl
{
for (u32 i = 0; i < 6; ++i)
{
#ifndef USE_GLES
#ifdef USE_GLES
if (mask & (1 << i))
{
glEnable(GL_CLIP_DISTANCE0_EXT + i);
}
else
{
glDisable(GL_CLIP_DISTANCE0_EXT + i);
}
#else
if (mask & (1 << i))
{
glEnable(GL_CLIP_DISTANCE0 + i);

View File

@@ -135,6 +135,7 @@ namespace vk
case CELL_GCM_TEXTURE_COMPRESSED_DXT1:
case CELL_GCM_TEXTURE_COMPRESSED_DXT23:
case CELL_GCM_TEXTURE_COMPRESSED_DXT45:
case CELL_GCM_TEXTURE_A4R4G4B4:
mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break;
case CELL_GCM_TEXTURE_DEPTH24_D8:
@@ -143,8 +144,8 @@ namespace vk
case CELL_GCM_TEXTURE_DEPTH16_FLOAT:
mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }; break;
case CELL_GCM_TEXTURE_A4R4G4B4:
mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; break;
//case CELL_GCM_TEXTURE_A4R4G4B4:
// mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; break;
case CELL_GCM_TEXTURE_G8B8:
mapping = { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; break;
@@ -197,24 +198,15 @@ namespace vk
static const bool supports_dxt = vk::get_current_renderer()->get_texture_compression_bc_support();
static const VkFormat default_sampler_format=g_cfg.video.bgra_format.get()?VK_FORMAT_B8G8R8A8_UNORM:VK_FORMAT_R8G8B8A8_UNORM;
static const bool convert_texture=g_cfg.video.force_convert_texture.get();
switch (format)
{
#ifndef __APPLE__
case CELL_GCM_TEXTURE_R5G6B5: return VK_FORMAT_R5G6B5_UNORM_PACK16;
case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_R5G6B5_UNORM_PACK16; // Expand, discard high bit?
case CELL_GCM_TEXTURE_R5G5B5A1: return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
case CELL_GCM_TEXTURE_D1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
case CELL_GCM_TEXTURE_A1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
case CELL_GCM_TEXTURE_A4R4G4B4: return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
#else
// assign B8G8R8A8_UNORM to formats that are not supported by Metal
case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_B8G8R8A8_UNORM;
case CELL_GCM_TEXTURE_R5G6B5: return VK_FORMAT_B8G8R8A8_UNORM;
case CELL_GCM_TEXTURE_R5G5B5A1: return VK_FORMAT_B8G8R8A8_UNORM;
case CELL_GCM_TEXTURE_D1R5G5B5: return VK_FORMAT_B8G8R8A8_UNORM;
case CELL_GCM_TEXTURE_A1R5G5B5: return VK_FORMAT_B8G8R8A8_UNORM;
case CELL_GCM_TEXTURE_A4R4G4B4: return VK_FORMAT_B8G8R8A8_UNORM;
#endif
case CELL_GCM_TEXTURE_R5G6B5: return convert_texture?default_sampler_format:VK_FORMAT_R5G6B5_UNORM_PACK16;
case CELL_GCM_TEXTURE_R6G5B5: return convert_texture?default_sampler_format:VK_FORMAT_R5G6B5_UNORM_PACK16; // Expand, discard high bit?
case CELL_GCM_TEXTURE_R5G5B5A1: return convert_texture?default_sampler_format:VK_FORMAT_R5G5B5A1_UNORM_PACK16;
case CELL_GCM_TEXTURE_D1R5G5B5: return convert_texture?default_sampler_format:VK_FORMAT_A1R5G5B5_UNORM_PACK16;
case CELL_GCM_TEXTURE_A1R5G5B5: return convert_texture?default_sampler_format:VK_FORMAT_A1R5G5B5_UNORM_PACK16;
case CELL_GCM_TEXTURE_A4R4G4B4: return convert_texture?default_sampler_format:VK_FORMAT_R4G4B4A4_UNORM_PACK16;
case CELL_GCM_TEXTURE_B8: return VK_FORMAT_R8_UNORM;
case CELL_GCM_TEXTURE_A8R8G8B8: return default_sampler_format;

View File

@@ -1,7 +1,8 @@
// Wrangler for Vulkan functions.
// TODO: Eventually, we shall declare vulkan with NO_PROTOTYPES and wrap everything here for android multi-driver support.
// For now, we just use it for extensions since we're on VK_1_0
#if 1
#ifndef DBG_ADRENO_GPU_MEM
#if defined(DECL_VK_FUNCTION)
#define VK_FUNC(func) extern PFN_##func _##func
#elif defined(DEF_VK_FUNCTION)
@@ -14,13 +15,20 @@
#else
#if defined(DECL_VK_FUNCTION)
#define VK_FUNC(func) extern int n_##func;\
#define VK_FUNC(func) extern int64_t n_##func;\
template<typename... Args> \
auto _##func(Args&&... args)->decltype(func(args...)){ \
++n_##func;return func(std::forward<Args>(args)...);\
}
auto _##func(Args&&... args)->decltype(func(args...)){ \
n_##func= static_cast<int64_t>(meminfo_gpu_mem_usage_kb()); \
if constexpr(std::is_same_v<decltype(func(args...)),void>){ \
func(std::forward<Args>(args)...); \
save_msg(std::format("/storage/emulated/0/Android/data/aenu.aps3e/files/aps3e/logs/{}.txt",#func),#func,static_cast<int64_t>(meminfo_gpu_mem_usage_kb())-n_##func) ; \
}else{ \
auto r= func(std::forward<Args>(args)...); \
save_msg(std::format("/storage/emulated/0/Android/data/aenu.aps3e/files/aps3e/logs/{}.txt",#func),#func,static_cast<int64_t>(meminfo_gpu_mem_usage_kb())-n_##func) ; \
return r; \
}}
#elif defined(DEF_VK_FUNCTION)
#define VK_FUNC(func) int n_##func=0
#define VK_FUNC(func) int64_t n_##func=0
#elif defined(LOAD_VK_FUNCTION)
#define VK_FUNC(func)
@@ -188,6 +196,7 @@ VK_FUNC(vkAcquireNextImageKHR);
VK_FUNC(vkQueuePresentKHR);
#ifndef DBG_ADRENO_GPU_MEM
#if defined(DECL_VK_FUNCTION)||defined(DEF_VK_FUNCTION)||defined(CLEAR_N_VK_FUNCTION)||defined(PRINT_N_VK_FUNCTION)
#define INSTANCE_VK_FUNCTION
#define DEVICE_VK_FUNCTION
@@ -195,5 +204,6 @@ VK_FUNC(vkQueuePresentKHR);
#undef INSTANCE_VK_FUNCTION
#undef DEVICE_VK_FUNCTION
#endif
#endif
#undef VK_FUNC

View File

@@ -657,8 +657,7 @@ namespace vk
dst->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
_vkCmdCopyBufferToImage(cmd, m_spilled_mem->value, dst->value, dst->current_layout, ::size32(regions), regions.data());
if (samples() > 1)
if (samples() > 1)
{
msaa_flags &= ~rsx::surface_state_flags::require_resolve;
msaa_flags |= rsx::surface_state_flags::require_unresolve;

View File

@@ -142,6 +142,7 @@ namespace vk
bool require_rw_barrier = true;
image_readback_options_t xfer_options{};
xfer_options.swap_bytes = require_format_conversion && pack_unpack_swap_bytes;
vk::copy_image_to_buffer(cmd, src, working_buffer, region, xfer_options);
// NOTE: For depth/stencil formats, copying to buffer and byteswap are combined into one step above
@@ -157,9 +158,9 @@ namespace vk
}
else if (elem_size == 4)
{
if(is_ror8)
/*if(replace_swap_as_ror8)
shuffle_kernel = vk::get_compute_task<vk::cs_shuffle_ror8>();
else
else*/
shuffle_kernel = vk::get_compute_task<vk::cs_shuffle_32>();
}
else
@@ -455,11 +456,13 @@ namespace vk
if (section.xform == rsx::surface_transform::coordinate_transform)
{
// Dimensions were given in 'dst' space. Work out the real source coordinates
const auto src_bpp = vk::get_format_texel_width(section.src->format());
const auto _src_bpp = vk::get_format_texel_width(section.src->format());
static const bool force_convert_texture=g_cfg.video.force_convert_texture.get();
//FIXME 需要验证
const auto src_bpp = force_convert_texture?(_src_bpp==2?dst_bpp:_src_bpp):_src_bpp;
src_x = (src_x * dst_bpp) / src_bpp;
src_w = utils::aligned_div<u16>(src_w * dst_bpp, src_bpp);
transform &= ~(rsx::surface_transform::coordinate_transform);
transform &= ~(rsx::surface_transform::coordinate_transform);
}
if (auto surface = dynamic_cast<vk::render_target*>(section.src))
@@ -481,7 +484,7 @@ namespace vk
// TODO: Handle level and layer offsets
const areai src_rect = coordi{{ src_x, src_y }, { src_w, src_h }};
const areai dst_rect = coordi{{ section.dst_x, section.dst_y }, { section.dst_w, section.dst_h }};
vk::copy_image_typeless(cmd, section.src, dst, src_rect, dst_rect, 1);
vk::copy_image_typeless(cmd, section.src, dst, src_rect, dst_rect, 1);
section.src->pop_layout(cmd);
continue;
@@ -492,6 +495,7 @@ namespace vk
const areai src_rect = coordi{{ src_x, src_y }, { src_w, src_h }};
const areai dst_rect = coordi{{ 0, 0 }, { convert_w, src_h }};
vk::copy_image_typeless(cmd, section.src, src_image, src_rect, dst_rect, 1);
src_image->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
@@ -730,6 +734,7 @@ namespace vk
} };
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
copy_transfer_regions_impl(cmd, image.get(), region);
vk::change_image_layout(cmd, image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
@@ -780,7 +785,6 @@ namespace vk
VkClearDepthStencilValue clear = { 1.f, 0 };
_vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
copy_transfer_regions_impl(cmd, image, sections_to_copy);
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
@@ -853,7 +857,6 @@ namespace vk
_vkCmdClearDepthStencilImage(cmd, image->value, image->current_layout, &clear, 1, &dst_range);
}
}
copy_transfer_regions_impl(cmd, image, sections_to_copy);
vk::change_image_layout(cmd, image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, dst_range);
@@ -920,6 +923,7 @@ namespace vk
auto dst = dst_view->image();
dst->push_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
copy_transfer_regions_impl(cmd, dst, region);
dst->pop_layout(cmd);
}

View File

@@ -41,7 +41,7 @@ namespace vk
std::unique_ptr<vk::event> dma_fence;
vk::render_device* m_device = nullptr;
vk::viewable_image* vram_texture = nullptr;
bool is_ror8=false;
bool replace_swap_as_ror8=false;
public:
using baseclass::cached_texture_section;
@@ -74,8 +74,8 @@ namespace vk
this->gcm_format = gcm_format;
this->pack_unpack_swap_bytes = pack_swap_bytes;
this->is_ror8=gcm_format==CELL_GCM_TEXTURE_A8R8G8B8||gcm_format==CELL_GCM_TEXTURE_D8R8G8B8;
if(g_cfg.video.bgra_format)this->is_ror8=false;
this->replace_swap_as_ror8=!g_cfg.video.bgra_format
&&(gcm_format==CELL_GCM_TEXTURE_A8R8G8B8||gcm_format==CELL_GCM_TEXTURE_D8R8G8B8);
if (managed)
{

View File

@@ -10,7 +10,8 @@
#define DEF_VK_FUNCTION
#include "VKPFNTable.h"
#undef DEF_VK_FUNCTION
#if 0
#ifdef DBG_ADRENO_GPU_MEM
#define VK_FUNC(func) PFN_##func _##func
#define INSTANCE_VK_FUNCTION
#define DEVICE_VK_FUNCTION
@@ -20,6 +21,16 @@
#undef VK_FUNC
#endif
#ifdef DBG_ADRENO_GPU_MEM
#include <fstream>
void save_msg(const std::string& path,const std::string& tag,int64_t v){
std::ofstream f(path,std::ios::app);
f<<tag<<"|"<<v<<std::endl;
f.close();
}
#endif
namespace vk
{
void init_base_pfn()
@@ -65,23 +76,19 @@ namespace vk
void init_instance_pfn(VkInstance instance){
#if 1
#define INSTANCE_VK_FUNCTION
#define VK_FUNC(func) _##func = reinterpret_cast<PFN_##func>(_vkGetInstanceProcAddr(instance, #func))
#include "VKPFNTableEXT.h"
#undef INSTANCE_VK_FUNCTION
#undef VK_FUNC
#endif
}
void init_device_pfn(VkDevice device){
#if 1
#define DEVICE_VK_FUNCTION
#define VK_FUNC(func) _##func = reinterpret_cast<PFN_##func>(_vkGetDeviceProcAddr(device, #func))
#include "VKPFNTableEXT.h"
#undef DEVICE_VK_FUNCTION
#undef VK_FUNC
#endif
}
}

View File

@@ -6,7 +6,7 @@
#define VK_USE_PLATFORM_MACOS_MVK
#elif defined(__ANDROID__)
#define VK_USE_PLATFORM_ANDROID_KHR
#define VK_NO_PROTOTYPES
//#define VK_NO_PROTOTYPES
#elif HAVE_X11
#define VK_USE_PLATFORM_XLIB_KHR
#endif
@@ -29,12 +29,18 @@ constexpr VkDriverId VK_DRIVER_ID_MESA_HONEYKRISP = static_cast<VkDriverId>(26);
#endif
extern bool cfg_vertex_buffer_upload_mode_use_buffer_view();
//#define DBG_ADRENO_GPU_MEM 1
#include "meminfo.h"
#ifdef DBG_ADRENO_GPU_MEM
extern void save_msg(const std::string& path,const std::string& tag,int64_t v);
#endif
#define DECL_VK_FUNCTION 1
#include "VKPFNTable.h"
#undef DECL_VK_FUNCTION
#if 0
#ifdef DBG_ADRENO_GPU_MEM
#define VK_FUNC(func) extern PFN_##func _##func
#define INSTANCE_VK_FUNCTION
#define DEVICE_VK_FUNCTION

View File

@@ -9,11 +9,9 @@
#include "rpcs3/3rdparty/libadrenotools/include/adrenotools/priv.h"
#include "rpcs3/3rdparty/libadrenotools/include/adrenotools/driver.h"
#if 0
#define VKFN(func) PFN_##func _##func
#define VKFN(func) PFN_##func func##_
#include "vksym.h"
#undef VKFN
#endif
namespace {
void* lib_handle = nullptr;
}
@@ -33,7 +31,7 @@ void vk_load(const char* lib_path,bool is_adreno_custom){
,custom_lib_name.c_str()
,nullptr,nullptr);
}
#define VKFN(func) _##func=reinterpret_cast<PFN_##func>(dlsym(lib_handle, #func))
#define VKFN(func) func##_=reinterpret_cast<PFN_##func>(dlsym(lib_handle, #func))
#include "vksym.h"
#undef VKFN
}
@@ -41,7 +39,7 @@ void vk_unload(){
if (!lib_handle) return;
dlclose(lib_handle);
lib_handle = nullptr;
#define VKFN(func) _##func=nullptr
#define VKFN(func) func##_=nullptr
#include "vksym.h"
#undef VKFN
}

View File

@@ -10,7 +10,7 @@
#define VK_NO_PROTOTYPES
#include <vulkan/vulkan.h>
#define VKFN(func) extern PFN_##func _##func
#define VKFN(func) extern PFN_##func func##_
#include "vksym.h"
#undef VKFN

View File

@@ -26,19 +26,19 @@ std::optional<VkInstance> vk_create_instance(const char * name) {
inst_create_info.pApplicationInfo = &appinfo;
VkInstance inst;
if (_vkCreateInstance(&inst_create_info, nullptr, &inst)!= VK_SUCCESS) {
if (vkCreateInstance_(&inst_create_info, nullptr, &inst)!= VK_SUCCESS) {
return std::nullopt;
}
return inst;
}
void vk_destroy_instance(VkInstance inst) {
_vkDestroyInstance(inst, nullptr);
vkDestroyInstance_(inst, nullptr);
}
int vk_get_physical_device_count(VkInstance inst){
uint32_t count;
_vkEnumeratePhysicalDevices(inst, &count, nullptr);
vkEnumeratePhysicalDevices_(inst, &count, nullptr);
return count;
}
std::optional<VkPhysicalDevice> vk_get_physical_device(VkInstance inst, int index){
@@ -46,13 +46,13 @@ std::optional<VkPhysicalDevice> vk_get_physical_device(VkInstance inst, int inde
if (count == 0)
return std::nullopt;
std ::vector<VkPhysicalDevice> devices(count);
_vkEnumeratePhysicalDevices(inst, &count, devices.data());
vkEnumeratePhysicalDevices_(inst, &count, devices.data());
return devices[index];
}
VkPhysicalDeviceProperties vk_get_physical_device_properties(VkPhysicalDevice dev){
VkPhysicalDeviceProperties props;
_vkGetPhysicalDeviceProperties(dev, &props);
vkGetPhysicalDeviceProperties_(dev, &props);
return props;
}
@@ -62,9 +62,9 @@ VkPhysicalDeviceLimits vk_get_physical_device_limits(VkPhysicalDevice dev){
std::vector<VkExtensionProperties> vk_get_physical_device_extension_properties(VkPhysicalDevice dev){
uint32_t count;
_vkEnumerateDeviceExtensionProperties(dev, nullptr, &count, nullptr);
vkEnumerateDeviceExtensionProperties_(dev, nullptr, &count, nullptr);
std::vector<VkExtensionProperties> props(count);
_vkEnumerateDeviceExtensionProperties(dev, nullptr, &count, props.data());
vkEnumerateDeviceExtensionProperties_(dev, nullptr, &count, props.data());
std::sort(props.begin(), props.end(), [](const VkExtensionProperties& a, const VkExtensionProperties& b) {
return strcmp(a.extensionName, b.extensionName) < 0;
});
@@ -73,14 +73,14 @@ std::vector<VkExtensionProperties> vk_get_physical_device_extension_properties(V
int vk_get_queue_family_properties_count(VkPhysicalDevice dev) {
uint32_t count;
_vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, nullptr);
vkGetPhysicalDeviceQueueFamilyProperties_(dev, &count, nullptr);
return count;
}
VkQueueFamilyProperties vk_get_queue_family_properties(VkPhysicalDevice dev,int index) {
uint32_t count= vk_get_queue_family_properties_count( dev);
std::vector<VkQueueFamilyProperties> props(count);
_vkGetPhysicalDeviceQueueFamilyProperties(dev, &count, props.data());
vkGetPhysicalDeviceQueueFamilyProperties_(dev, &count, props.data());
return props[index];
}
@@ -108,14 +108,14 @@ std::optional<VkDevice> vk_create_device(VkPhysicalDevice pdev,uint32_t queueFam
.pEnabledFeatures = nullptr
};
VkDevice dev;
if(_vkCreateDevice(pdev, &device_create_info, nullptr, &dev) != VK_SUCCESS){
if(vkCreateDevice_(pdev, &device_create_info, nullptr, &dev) != VK_SUCCESS){
return std::nullopt;
}
return dev;
}
void vk_destroy_device(VkDevice dev) {
_vkDestroyDevice(dev, nullptr);
vkDestroyDevice_(dev, nullptr);
}
std::optional<VkDescriptorSetLayout> vk_create_descriptor_set_layout(VkDevice dev,const std::vector<VkDescriptorSetLayoutBinding>& binds) {
@@ -127,7 +127,7 @@ std::optional<VkDescriptorSetLayout> vk_create_descriptor_set_layout(VkDevice de
.pBindings = binds .data()
};
VkDescriptorSetLayout layout;
if(_vkCreateDescriptorSetLayout( dev, &descriptor_set_layout_create_info, nullptr, &layout)!= VK_SUCCESS){
if(vkCreateDescriptorSetLayout_( dev, &descriptor_set_layout_create_info, nullptr, &layout)!= VK_SUCCESS){
LOGE( "create descriptor set layout failed");
return std::nullopt;
}
@@ -135,7 +135,7 @@ std::optional<VkDescriptorSetLayout> vk_create_descriptor_set_layout(VkDevice de
}
void vk_destroy_descriptor_set_layout(VkDevice dev,VkDescriptorSetLayout layout) {
_vkDestroyDescriptorSetLayout(dev,layout, nullptr);
vkDestroyDescriptorSetLayout_(dev,layout, nullptr);
}
std::optional<VkPipelineLayout> vk_create_pipeline_layout(VkDevice dev,VkDescriptorSetLayout descriptor_set_layout) {
@@ -149,7 +149,7 @@ std::optional<VkPipelineLayout> vk_create_pipeline_layout(VkDevice dev,VkDescrip
.pPushConstantRanges = nullptr
};
VkPipelineLayout layout;
if(_vkCreatePipelineLayout(dev, &pipeline_layout_create_info, nullptr, &layout)!= VK_SUCCESS){
if(vkCreatePipelineLayout_(dev, &pipeline_layout_create_info, nullptr, &layout)!= VK_SUCCESS){
LOGE( "create pipeline layout failed");
return std::nullopt;
}
@@ -175,7 +175,7 @@ std::optional<VkShaderModule> vk_create_shader_module(VkDevice dev,const std::ve
.pCode = code.data()
};
VkShaderModule module;
if(_vkCreateShaderModule(dev, &shader_module_create_info, nullptr, &module)!= VK_SUCCESS){
if(vkCreateShaderModule_(dev, &shader_module_create_info, nullptr, &module)!= VK_SUCCESS){
LOGE( "create shader module failed");
return std::nullopt;
}
@@ -183,11 +183,11 @@ std::optional<VkShaderModule> vk_create_shader_module(VkDevice dev,const std::ve
}
void vk_destroy_shader_module(VkDevice dev,VkShaderModule module){
_vkDestroyShaderModule(dev, module, nullptr);
vkDestroyShaderModule_(dev, module, nullptr);
}
void vk_destroy_pipeline_layout(VkDevice dev,VkPipelineLayout layout) {
_vkDestroyPipelineLayout(dev, layout, nullptr);
vkDestroyPipelineLayout_(dev, layout, nullptr);
}
std::optional <VkPipeline> vk_create_compute_pipeline(VkDevice dev,VkPipelineLayout layout,VkShaderModule module) {
@@ -208,7 +208,7 @@ std::optional <VkPipeline> vk_create_compute_pipeline(VkDevice dev,VkPipelineLay
.basePipelineIndex = -1,
};
VkPipeline pipeline;
if(_vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, nullptr, &pipeline)!= VK_SUCCESS){
if(vkCreateComputePipelines_(dev, VK_NULL_HANDLE, 1, &compute_pipeline_create_info, nullptr, &pipeline)!= VK_SUCCESS){
LOGE( "create pipeline failed");
return std::nullopt;
}
@@ -216,5 +216,5 @@ std::optional <VkPipeline> vk_create_compute_pipeline(VkDevice dev,VkPipelineLay
}
void vk_destroy_pipeline(VkDevice dev,VkPipeline pipeline) {
_vkDestroyPipeline(dev, pipeline, nullptr);
vkDestroyPipeline_(dev, pipeline, nullptr);
}

View File

@@ -151,6 +151,14 @@ public class AboutActivity extends AppCompatActivity {
+ " *虚拟键盘更新,增加动态摇杆,可设置组缩放\n"
+ " *增加了按键震动\n"
+ " *更改ffmpeg版本为5.1.6\n"
+ "1.26(2025-07-09)\n"
+ " *调整风格为跟随系统\n"
+ " *加入了快速开始页面\n"
+ " *修正了强制转换纹理选项\n"
//+ " *自定义配置可重置为默认\n"
//+ " *适配目标版本为安卓15\n"
+ " *修正删除着色器缓存无效的问题\n"
//+ " *添加自定义驱动(*.zip)时自动处理命名\n"
+ " \n";
return log;

View File

@@ -60,6 +60,20 @@ public class Application extends android.app.Application
}
}
public static byte[] load_assets_file(Context ctx,String asset_file_path) {
try {
InputStream in = ctx.getAssets().open(asset_file_path);
int size = in.available();
byte[] buffer = new byte[size];
in.read(buffer);
in.close();
return buffer;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static File get_app_data_dir() {
return ctx.getExternalFilesDir("aps3e");
}
@@ -101,13 +115,38 @@ public class Application extends android.app.Application
return new File(Application.get_app_data_dir(),"config/config.yml");
}
public static File get_default_config_file(){
return new File(Application.get_app_data_dir(),"config/default_config.yml");
}
static void copy_file(File src,File dst) {
try {
FileInputStream in=new FileInputStream(src);
FileOutputStream out=new FileOutputStream(dst);
byte buf[]=new byte[16384];
int n;
while((n=in.read(buf))!=-1)
out.write(buf,0,n);
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Context ctx;
@Override
public void onCreate()
{
super.onCreate();
Application.ctx=this;
Emulator.get.setup_env(this);
try {
Emulator.get.setup_env(this);
}finally {
System.loadLibrary("e");
}
//get_app_data_dir().mkdirs();
get_app_log_dir().mkdirs();

View File

@@ -65,15 +65,18 @@ public class Emulator
public static class Config{
String config_path;
String config_path=null;
private long n_handle;
private Config(String config_path) throws ConfigFileException
/*private Config(String config_path) throws ConfigFileException
{
this.config_path=config_path;
if((n_handle=native_open_config_file(config_path))==0)
throw new ConfigFileException();
}
}*/
private native long native_open_config(String config_str) ;
private native String native_close_config(long n_handle);
private native long native_open_config_file(String config_path) ;
private native String native_load_config_entry(long n_handle,String tag);
@@ -84,7 +87,19 @@ public class Emulator
private native void native_close_config_file(long n_handle,String config_path);
public static Config open_config_file(String config_path) throws ConfigFileException
{
return new Config(config_path);
Config config=new Config();
config.config_path=config_path;
if((config.n_handle=config.native_open_config_file(config_path))==0)
throw new ConfigFileException();
return config;
}
public static Config open_config_from_string(String config_str) throws ConfigFileException
{
Config config=new Config();
if((config.n_handle=config.native_open_config(config_str))==0)
throw new ConfigFileException();
return config;
}
public String load_config_entry(String tag)
@@ -108,8 +123,17 @@ public class Emulator
}
public void close_config_file()
{
if(config_path==null)
throw new RuntimeException("should use method close_config");
native_close_config_file(n_handle,config_path);
}
public String close_config()
{
if(config_path!=null)
throw new RuntimeException("should use method close_config_file");
return native_close_config(n_handle);
}
}
/*public static String nc_get_emu_proc_name(){
@@ -458,6 +482,9 @@ public class Emulator
public native String[] get_support_llvm_cpu_list();
public native String[] get_native_llvm_cpu_list();
public native String[] get_vulkan_physical_dev_list();
//public native boolean support_custom_driver();

View File

@@ -19,7 +19,7 @@ import java.io.File;
public class EmulatorActivity extends Activity implements View.OnGenericMotionListener,SurfaceHolder.Callback
{
{ System.loadLibrary("e"); }
//{ System.loadLibrary("e"); }
private SparseIntArray keysMap = new SparseIntArray();
private GameFrameView gv;

View File

@@ -7,7 +7,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -15,8 +14,6 @@ import android.os.ParcelFileDescriptor;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -34,21 +31,22 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import androidx.preference.CheckBoxPreference;
import androidx.preference.ListPreference;
import androidx.preference.ListPreferenceDialogFragmentCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceDataStore;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
//import androidx.preference.SeekBarPreference;
import aenu.preference.SeekbarPreference;
import aenu.preference.CheckBoxPreference;
import aenu.preference.ListPreference;
import aenu.preference.SeekBarPreference;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -64,8 +62,19 @@ public class EmulatorSettings extends AppCompatActivity {
static final String EXTRA_CONFIG_PATH="config_path";
static final int REQUEST_CODE_SELECT_CUSTOM_DRIVER=6001;
static final int REQUEST_CODE_SELECT_CUSTOM_FONT=6002;
static final int REQUEST_CODE_SELECT_CUSTOM_DRIVER=6101;
static final int REQUEST_CODE_SELECT_CUSTOM_FONT=6102;
static final int WARNING_COLOR=0xffff8000;
static final String Miscellaneous$Font_File_Selection="Miscellaneous|Font File Selection";
static final String Miscellaneous$Custom_Font_File_Path="Miscellaneous|Custom Font File Path";
static final String Video$Vulkan$Use_Custom_Driver="Video|Vulkan|Use Custom Driver";
static final String Video$Vulkan$Custom_Driver_Library_Path="Video|Vulkan|Custom Driver Library Path";
static final String Video$Use_BGRA_Format="Video|Use BGRA Format";
static final String Video$Force_Convert_Texture="Video|Force Convert Texture";
static final String Video$Texture_Upload_Mode ="Video|Texture Upload Mode";
static final String Core$Use_LLVM_CPU="Core|Use LLVM CPU";
@SuppressLint("ValidFragment")
public static class SettingsFragment extends PreferenceFragmentCompat implements
@@ -153,7 +162,7 @@ public class EmulatorSettings extends AppCompatActivity {
}
};
Preference reset_as_default_pref(){
Preference reset_as_default_pref(File _config_file){
Preference p=new Preference(requireContext());
p.setTitle(R.string.reset_as_default);
p.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener(){
@@ -167,8 +176,9 @@ public class EmulatorSettings extends AppCompatActivity {
config.close_config_file();
config=null;
}
Application.get_global_config_file().delete();
Application.extractAssetsDir(requireContext(),"config",Application.get_global_config_file().getParentFile());
//Application.get_global_config_file().delete();
//Application.extractAssetsDir(requireContext(),"config",Application.get_global_config_file().getParentFile());
Application.copy_file(Application.get_default_config_file(),_config_file);
requireActivity().finish();
}
})
@@ -223,10 +233,13 @@ public class EmulatorSettings extends AppCompatActivity {
setPreferencesFromResource(R.xml.emulator_settings, rootKey);
root_pref=getPreferenceScreen();
if(is_global)
root_pref.addPreference(reset_as_default_pref());
else
root_pref.addPreference(reset_as_global_pref());
if(is_global) {
root_pref.addPreference(reset_as_default_pref(Application.get_global_config_file()));
}
else{
root_pref.addPreference(reset_as_default_pref(new File(config_path)));
root_pref.addPreference(reset_as_global_pref());
}
requireActivity().getOnBackPressedDispatcher().addCallback(back_callback);
@@ -248,7 +261,6 @@ public class EmulatorSettings extends AppCompatActivity {
final String[] BOOL_KEYS={
"Video|Force Convert Texture",
"Miscellaneous|Memory Debug overlay",
"Video|Vulkan|Debug|disable_barycentric_coords",
@@ -334,10 +346,11 @@ public class EmulatorSettings extends AppCompatActivity {
"Video|DECR memory layout",
"Video|Allow Host GPU Labels",
"Video|Disable Asynchronous Memory Manager",
"Video|Use BGRA Format",
Video$Use_BGRA_Format,
Video$Force_Convert_Texture,
"Video|Vulkan|Force FIFO present mode",
"Video|Vulkan|Asynchronous Texture Streaming 2",
"Video|Vulkan|Use Custom Driver",
Video$Vulkan$Use_Custom_Driver,
"Video|Vulkan|Custom Driver Force Max Clocks",
"Video|Performance Overlay|Enabled",
"Video|Performance Overlay|Enable Framerate Graph",
@@ -445,7 +458,7 @@ public class EmulatorSettings extends AppCompatActivity {
"Video|3D Display Mode",
"Video|Output Scaling Mode",
"Video|Vertex Buffer Upload Mode",
"Video|Texture Upload Mode",
Video$Texture_Upload_Mode,
"Video|Vulkan|Exclusive Fullscreen Mode",
"Video|Vulkan|Asynchronous Queue Scheduler",
"Video|Performance Overlay|Detail level",
@@ -473,7 +486,7 @@ public class EmulatorSettings extends AppCompatActivity {
"System|Language",
"System|Keyboard Type",
"System|Enter button assignment",
"Miscellaneous|Font File Selection",
Miscellaneous$Font_File_Selection
};
final String[] NODE_KEYS={
"Core",
@@ -498,11 +511,12 @@ public class EmulatorSettings extends AppCompatActivity {
pref.setChecked(val);
}
//pref.setOnPreferenceChangeListener(this);
//pref.set_title_color(WARNING_COLOR);
pref.setPreferenceDataStore(data_store);
}
for (String key:INT_KEYS){
SeekbarPreference pref=findPreference(key);
SeekBarPreference pref=findPreference(key);
String val_str=config.load_config_entry(key);
if (val_str!=null) {
//FIXME
@@ -553,21 +567,21 @@ public class EmulatorSettings extends AppCompatActivity {
findPreference("Core|Libraries Control").setOnPreferenceClickListener(this);
String val;
findPreference("Core|Use LLVM CPU").setOnPreferenceClickListener(this);
if((val=config.load_config_entry("Core|Use LLVM CPU"))!=null) findPreference("Core|Use LLVM CPU").setSummary(val);
findPreference(Core$Use_LLVM_CPU).setOnPreferenceClickListener(this);
if((val=config.load_config_entry(Core$Use_LLVM_CPU))!=null) findPreference(Core$Use_LLVM_CPU).setSummary(val);
findPreference("Video|Vulkan|Adapter").setOnPreferenceClickListener(this);
if((val=config.load_config_entry("Video|Vulkan|Adapter"))!=null) findPreference("Video|Vulkan|Adapter").setSummary(val);
findPreference("Video|Vulkan|Custom Driver Library Path").setOnPreferenceClickListener(this);
findPreference("Miscellaneous|Custom Font File Path").setOnPreferenceClickListener(this);
findPreference(Video$Vulkan$Custom_Driver_Library_Path).setOnPreferenceClickListener(this);
findPreference(Miscellaneous$Custom_Font_File_Path).setOnPreferenceClickListener(this);
setup_costom_driver_library_path(null);
setup_costom_font_path(null);
if(!Emulator.get.support_custom_driver()){
findPreference("Video|Vulkan|Use Custom Driver").setEnabled(false);
findPreference("Video|Vulkan|Custom Driver Library Path").setEnabled(false);
findPreference(Video$Vulkan$Use_Custom_Driver).setEnabled(false);
findPreference(Video$Vulkan$Custom_Driver_Library_Path).setEnabled(false);
findPreference("Video|Vulkan|Custom Driver Force Max Clocks").setEnabled(false);
//return;
}
@@ -608,8 +622,8 @@ public class EmulatorSettings extends AppCompatActivity {
f.show(getParentFragmentManager(), "DIALOG_FRAGMENT_TAG");
return;
}
if (pref instanceof aenu.preference.SeekbarPreference) {
final DialogFragment f = aenu.preference.SeekbarPreference.SeekbarPreferenceFragmentCompat.newInstance(pref.getKey());
if (pref instanceof SeekBarPreference) {
final DialogFragment f = SeekBarPreference.SeekBarPreferenceFragmentCompat.newInstance(pref.getKey());
f.setTargetFragment(this, 0);
f.show(getParentFragmentManager(), "DIALOG_FRAGMENT_TAG");
return;
@@ -620,7 +634,7 @@ public class EmulatorSettings extends AppCompatActivity {
void setup_costom_driver_library_path(String new_path) {
final String key="Video|Vulkan|Custom Driver Library Path";
final String key=Video$Vulkan$Custom_Driver_Library_Path;
if(new_path==null){
String val_str=config.load_config_entry(key);
if (val_str!=null) {
@@ -634,7 +648,7 @@ public class EmulatorSettings extends AppCompatActivity {
}
void setup_costom_font_path(String new_path) {
final String key="Miscellaneous|Custom Font File Path";
final String key=Miscellaneous$Custom_Font_File_Path;
if(new_path==null){
String val_str=config.load_config_entry(key);
if (val_str!=null) {
@@ -684,7 +698,7 @@ public class EmulatorSettings extends AppCompatActivity {
@Override
public boolean onPreferenceClick(@NonNull Preference preference) {
if(preference.getKey().equals("Core|Use LLVM CPU")){
if(preference.getKey().equals(Core$Use_LLVM_CPU)){
show_select_llvm_cpu_list();
return false;
}
@@ -694,11 +708,11 @@ public class EmulatorSettings extends AppCompatActivity {
return false;
}
if(preference.getKey().equals("Video|Vulkan|Custom Driver Library Path")){
if(preference.getKey().equals(Video$Vulkan$Custom_Driver_Library_Path)){
show_select_custom_driver_list();
return false;
}
if(preference.getKey().equals("Miscellaneous|Custom Font File Path")){
if(preference.getKey().equals(Miscellaneous$Custom_Font_File_Path)){
//request_select_font_file();
show_select_font_file_list();
return false;
@@ -729,8 +743,8 @@ public class EmulatorSettings extends AppCompatActivity {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
config.save_config_entry("Core|Use LLVM CPU",items[which]);
findPreference("Core|Use LLVM CPU").setSummary(items[which]);
config.save_config_entry(Core$Use_LLVM_CPU,items[which]);
findPreference(Core$Use_LLVM_CPU).setSummary(items[which]);
}
});
}
@@ -861,7 +875,11 @@ public class EmulatorSettings extends AppCompatActivity {
ZipInputStream zis = new ZipInputStream(fis);
for (ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
if (ze.getName().endsWith(".so")) {
String lib_path=new File(Application.get_custom_driver_dir() , ze.getName()).getAbsolutePath();
//String lib_path=new File(Application.get_custom_driver_dir() , ze.getName()).getAbsolutePath();
String lib_name=MainActivity.getFileNameFromUri(uri);
lib_name=lib_name.substring(0,lib_name.lastIndexOf('.'));
lib_name=lib_name+".so";
String lib_path=new File(Application.get_custom_driver_dir() , lib_name).getAbsolutePath();
FileOutputStream lib_os = new FileOutputStream(lib_path);
try {
byte[] buffer = new byte[16384];
@@ -1208,4 +1226,5 @@ libs.put("libwmadec.sprx", 0);
return convertView;
}
}
}

View File

@@ -74,15 +74,13 @@ import org.json.JSONObject;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_INSTALL_FIRMWARE=6001;
public static final int REQUEST_INSTALL_FIRMWARE=6001;
private static final int REQUEST_INSTALL_GAME=6002;
//private static final int REQUEST_INSTALL_GAME_PKG=6003;
private static final int REQUEST_SELECT_ISO_DIR=6004;
public static final int REQUEST_SELECT_ISO_DIR=6004;
private static final String PREF_KEY_ISO_DIR="iso_dir";
static{System.loadLibrary("e");}
public static File get_hdd0_game_dir(){
return new File(Application.get_app_data_dir(),"config/dev_hdd0/game");
}
@@ -95,12 +93,16 @@ public class MainActivity extends AppCompatActivity {
return new File(Application.get_app_data_dir(),"config/dev_hdd0/home/00000001/trophy");
}
public static File get_shader_cache_dir(String serial){
public static File[] get_shader_cache_dirs(String serial){
File cache_dir=new File(Application.get_app_data_dir(),"cache/cache/"+serial);
if(!cache_dir.exists()) return null;
File[] cache_sub_dir=cache_dir.listFiles();
if( cache_sub_dir==null||cache_sub_dir.length!=1) return null;
return new File(cache_sub_dir[0],"shaders_cache");
if( cache_sub_dir==null||cache_sub_dir.length==0) return null;
File[] shader_cache_dirs=new File[cache_sub_dir.length];
for(int i=0;i<cache_sub_dir.length;i++){
shader_cache_dirs[i]=new File(cache_sub_dir[i],"shaders_cache");
}
return shader_cache_dirs;
}
public static File get_disc_game_dir(){
@@ -185,24 +187,24 @@ public class MainActivity extends AppCompatActivity {
return true;
}
void request_file_select(int request_code){
static void request_file_select(Activity activity,int request_code){
Intent intent=new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, request_code);
activity.startActivityForResult(intent, request_code);
}
void request_iso_dir_select(){
static void request_iso_dir_select(Activity activity){
Intent intent=new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
startActivityForResult(intent, REQUEST_SELECT_ISO_DIR);
activity.startActivityForResult(intent, REQUEST_SELECT_ISO_DIR);
}
void save_pref_iso_dir(Uri uri){
static void save_pref_iso_dir(Context ctx,Uri uri){
try{
getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION);
SharedPreferences.Editor editor=PreferenceManager.getDefaultSharedPreferences(this).edit();
ctx.getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION);
SharedPreferences.Editor editor=PreferenceManager.getDefaultSharedPreferences(ctx).edit();
editor.putString(PREF_KEY_ISO_DIR,uri.toString());
editor.apply();
}
@@ -211,13 +213,13 @@ public class MainActivity extends AppCompatActivity {
}
}
Uri load_pref_iso_dir(){
static Uri load_pref_iso_dir(Context ctx){
try{
String uri_str=PreferenceManager.getDefaultSharedPreferences(this).getString(PREF_KEY_ISO_DIR,null);
String uri_str=PreferenceManager.getDefaultSharedPreferences(ctx).getString(PREF_KEY_ISO_DIR,null);
if(uri_str==null)
return null;
Uri uri= Uri.parse(uri_str);
getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION);
ctx.getContentResolver().takePersistableUriPermission(uri,Intent.FLAG_GRANT_READ_URI_PERMISSION);
return uri;
}
catch(Exception e){
@@ -231,11 +233,11 @@ public class MainActivity extends AppCompatActivity {
int item_id=item.getItemId();
if(item_id==R.id.menu_install_firmware){
request_file_select(REQUEST_INSTALL_FIRMWARE);
request_file_select(this,REQUEST_INSTALL_FIRMWARE);
return true;
}
else if(item_id==R.id.menu_install_game){
request_file_select(REQUEST_INSTALL_GAME);
request_file_select(this,REQUEST_INSTALL_GAME);
return true;
}
else if(item_id==R.id.menu_refresh_list){
@@ -274,7 +276,13 @@ public class MainActivity extends AppCompatActivity {
return true;
}
else if(item_id==R.id.menu_set_iso_dir){
request_iso_dir_select();
request_iso_dir_select(this);
return true;
}
else if(item_id==R.id.menu_quick_start_page){
Intent it=new Intent(this,QuickStartActivity.class);
it.setAction(QuickStartActivity.ACTION_REENTRY);
startActivity(it);
return true;
}
return super.onOptionsItemSelected(item);
@@ -348,7 +356,7 @@ public class MainActivity extends AppCompatActivity {
Uri uri = data.getData();
if(requestCode == REQUEST_SELECT_ISO_DIR){
save_pref_iso_dir(uri);
save_pref_iso_dir(this,uri);
refresh_game_list();
return;
}
@@ -593,26 +601,24 @@ public class MainActivity extends AppCompatActivity {
.create().show();
}
private void initialize(){
//private final File APP_DIR=new File(Environment.getExternalStorageDirectory(),"aps3e");
static void mk_dirs(){
String[] sub_dir_paths={
"aps3e",
"aps3e/config",
"aps3e/config/dev_flash",
"aps3e/config/dev_flash2",
"aps3e/config/dev_flash3",
"aps3e/config/dev_bdvd",
"aps3e/config/dev_hdd0",
"aps3e/config/dev_hdd1",
"aps3e/config/dev_hdd0/game",
"aps3e/config/Icons",
"aps3e",
"aps3e/config",
"aps3e/config/dev_flash",
"aps3e/config/dev_flash2",
"aps3e/config/dev_flash3",
"aps3e/config/dev_bdvd",
"aps3e/config/dev_hdd0",
"aps3e/config/dev_hdd1",
"aps3e/config/dev_hdd0/game",
"aps3e/config/Icons",
"aps3e/config/games",
"aps3e/config/Icons/ui",
"aps3e/config/Icons/ui",
"aps3e/config/custom_cfg",
"aps3e/logs",
"aps3e/logs",
"aps3e/font",
};
for(String sp:sub_dir_paths){
@@ -621,7 +627,12 @@ public class MainActivity extends AppCompatActivity {
dir.mkdir();
}
}
}
private void initialize(){
//private final File APP_DIR=new File(Environment.getExternalStorageDirectory(),"aps3e");
mk_dirs();
File icons_ui_output_dir=new File(Application.get_app_data_dir().getParent(),"aps3e/config/Icons/ui");
Application.extractAssetsDir(this,"Icons/ui",icons_ui_output_dir);
@@ -650,7 +661,8 @@ public class MainActivity extends AppCompatActivity {
File config_yml_output_dir=new File(Application.get_app_data_dir().getParent(),"aps3e/config");
if(!new File(config_yml_output_dir,"config.yml").exists()) {
Application.extractAssetsDir(this, "config", config_yml_output_dir);
//Application.extractAssetsDir(this, "config", config_yml_output_dir);
Application.copy_file(Application.get_default_config_file(),new File(config_yml_output_dir,"config.yml"));
}
/*File nomedia=new File(Environment.getExternalStorageDirectory(),"aps3e/.nomedia");
@@ -750,7 +762,7 @@ public class MainActivity extends AppCompatActivity {
}
}
static void deleteDirectory(File directory) {
/*static void deleteDirectory(File directory) {
if (directory.isDirectory()) {
File[] files = directory.listFiles();
if (files!= null) {
@@ -764,7 +776,20 @@ public class MainActivity extends AppCompatActivity {
}
}
directory.delete();
}*/
static void recursive_delete_sub_files(File dir) {
File[] files = dir.listFiles();
if(files == null)
return;
for(File file : files){
if(file.isDirectory()) {
recursive_delete_sub_files(file);
}
file.delete();
}
}
ArrayList<Emulator.MetaInfo> metas;
private final MainActivity context_;
private GameMetaInfoAdapter(MainActivity context,ArrayList<Emulator.MetaInfo> metas){
@@ -835,7 +860,7 @@ public class MainActivity extends AppCompatActivity {
private static ArrayList<DocumentFile> get_game_iso_list(MainActivity context_){
ArrayList<DocumentFile> iso_list=new ArrayList<DocumentFile>();
Uri uri=context_.load_pref_iso_dir();
Uri uri=context_.load_pref_iso_dir(context_);
if(uri==null)
return iso_list;
DocumentFile iso_dir=DocumentFile.fromTreeUri(context_, uri);
@@ -894,7 +919,9 @@ public class MainActivity extends AppCompatActivity {
if(trophy_dirs!=null){
for(File f:trophy_dirs){
if(f.getName().startsWith(serial)){
deleteDirectory(f);
if(f.isDirectory())
recursive_delete_sub_files(f);
f.delete();
}
}
}
@@ -904,7 +931,9 @@ public class MainActivity extends AppCompatActivity {
if(data_dirs!=null){
for(File f:data_dirs){
if(f.getName().startsWith(serial)){
deleteDirectory(f);
if(f.isDirectory())
recursive_delete_sub_files(f);
f.delete();
}
}
}
@@ -915,7 +944,9 @@ public class MainActivity extends AppCompatActivity {
if(game_dirs!=null){
for(File f:game_dirs){
if(f.getName().startsWith(serial)){
deleteDirectory(f);
if(f.isDirectory())
recursive_delete_sub_files(f);
f.delete();
}
}
}
@@ -926,8 +957,10 @@ public class MainActivity extends AppCompatActivity {
_del_game_data(info.serial);
File game_dir=new File(get_hdd0_game_dir(),info.serial);
if(game_dir.exists())
deleteDirectory(game_dir);
if(game_dir.exists()){
recursive_delete_sub_files(game_dir);
game_dir.delete();
}
}
public void del_hdd0_install_data(int pos){
@@ -943,9 +976,12 @@ public class MainActivity extends AppCompatActivity {
public void del_shaders_cache(int pos){
Emulator.MetaInfo info=metas.get(pos);
File shader_cache_dir=get_shader_cache_dir(info.serial);
if(shader_cache_dir!=null&& shader_cache_dir.exists())
deleteDirectory(shader_cache_dir);
File[] shader_cache_dirs=get_shader_cache_dirs(info.serial);
if(shader_cache_dirs!=null)
for(File dir:shader_cache_dirs){
recursive_delete_sub_files( dir);
dir.delete();
}
}
@Override

View File

@@ -0,0 +1,516 @@
package aenu.aps3e;
import android.app.ComponentCaller;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static aenu.aps3e.MainActivity.getFileNameFromUri;
import kotlin.contracts.Returns;
public class QuickStartActivity extends AppCompatActivity {
static final String ACTION_REENTRY="aenu.intent.action.REENTRY_QUISK_START";
List<LinearLayout> layout_list;
ProgressBar progress;
int page;
//ProgressTask progress_task;
Emulator.Config config;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!ACTION_REENTRY.equals(getIntent().getAction())&&Application.get_default_config_file().exists()){
goto_main_activity();
return;
}
getSupportActionBar().setTitle(R.string.welcome);
setContentView(R.layout.activity_quick_start);
MainActivity.mk_dirs();
try{config=Emulator.Config.open_config_from_string(load_default_config_str());}catch (Exception e){}
init_layout_list();
select_layout(0);
}
@Override
protected void onDestroy() {
if(config!=null) {
config.close_config();
config = null;
}
/*if(progress_task!=null){
progress_task.force_close();
progress_task=null;
}*/
super.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK || data == null) return;
Uri uri = data.getData();
if(uri==null) return;
if(requestCode == MainActivity.REQUEST_SELECT_ISO_DIR){
MainActivity.save_pref_iso_dir(this,uri);
return;
}
String file_name = getFileNameFromUri(uri);
switch (requestCode) {
case MainActivity.REQUEST_INSTALL_FIRMWARE:
(/*progress_task = */new ProgressTask(this)
.set_progress_message(getString(R.string.installing_firmware))
.set_failed_task(new ProgressTask.UI_Task() {
@Override
public void run() {
Toast.makeText(QuickStartActivity.this, getString(R.string.msg_failed), Toast.LENGTH_LONG).show();
}
})
.set_done_task(new ProgressTask.UI_Task() {
@Override
public void run() {
try {
MainActivity.firmware_installed_file().createNewFile();
} catch (IOException e) {
}
select_layout(page);
}
}
)).call(new ProgressTask.Task() {
@Override
public void run(ProgressTask task) {
int pfd;
try {
ParcelFileDescriptor pfd_ = getContentResolver().openFileDescriptor(uri, "r");
pfd = pfd_.detachFd();
pfd_.close();
} catch (Exception e) {
task.task_handler.sendEmptyMessage(ProgressTask.TASK_FAILED);
return;
}
MainActivity.firmware_installed_file().delete();
int result = Emulator.get.install_firmware(pfd) ? ProgressTask.TASK_DONE : ProgressTask.TASK_FAILED;
task.task_handler.sendEmptyMessage(result);
}
});
return;
case EmulatorSettings.REQUEST_CODE_SELECT_CUSTOM_FONT:
if (file_name.endsWith(".ttf") || file_name.endsWith(".ttc") || file_name.endsWith(".otf")) {
install_custom_font(uri);
}
return;
case EmulatorSettings.REQUEST_CODE_SELECT_CUSTOM_DRIVER:
if (file_name.endsWith(".zip")) {
install_custom_driver_from_zip(uri);
} else if (file_name.endsWith(".so")) {
install_custom_driver_from_lib(uri);
}
return;
}
}
void init_layout_list(){
layout_list=new ArrayList<>();
layout_list.add(findViewById(R.id.quick_start_page_welcome));
layout_list.add(findViewById(R.id.quick_start_page_install_firmware));
layout_list.add(findViewById(R.id.quick_start_page_select_iso_dir));
layout_list.add(findViewById(R.id.quick_start_page_install_font));
if(Emulator.get.support_custom_driver()) {
layout_list.add(findViewById(R.id.quick_start_page_install_gpu_driver));
config.save_config_entry(EmulatorSettings.Video$Vulkan$Use_Custom_Driver,"true");
}
else
findViewById(R.id.quick_start_page_install_gpu_driver).setVisibility(View.GONE);
layout_list.add(findViewById(R.id.quick_start_page_config_modify));
for(int i=0;i<layout_list.size();i++){
layout_list.get(i).setVisibility(View.GONE);
}
progress=findViewById(android.R.id.progress);
progress.setMax(layout_list.size());
findViewById(R.id.prev_step).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(page>0){
select_layout(page-1);
}
}
});
findViewById(R.id.next_step).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(page==layout_list.size()-1){
goto_main_activity();
}else{
select_layout(page+1);
}
}
});
}
void select_layout(int pos){
for(int i=0;i<layout_list.size();i++){
layout_list.get(i).setVisibility(View.GONE);
}
page=pos;
layout_list.get(page).setVisibility(View.VISIBLE);
progress.setProgress(page+1);
if(page==0) findViewById(R.id.prev_step).setVisibility(View.GONE);
else findViewById(R.id.prev_step).setVisibility(View.VISIBLE);
if(page==layout_list.size()-1) ((Button)findViewById(R.id.next_step)).setText(R.string.finish);
else ((Button)findViewById(R.id.next_step)).setText(R.string.next_step);
findViewById(R.id.next_step).setEnabled(true);
update_layout(layout_list.get(page));
}
void update_layout(LinearLayout layout){
if(layout.getId()==R.id.quick_start_page_welcome){
((TextView)layout.findViewById(R.id.welcome_text1))
.setText(String.format(getString(R.string.welcome_content),getString(R.string.app_name)));
((TextView)layout.findViewById(R.id.welcome_text2))
.setText(String.format(getString(R.string.welcome_content2),getString(R.string.next_step)));
}
else if(layout.getId()==R.id.quick_start_page_install_firmware){
int btn_text_res_id=MainActivity.firmware_installed_file().exists()?R.string.ps3_firmware_installed:R.string.select_ps3_firmware;
((Button)findViewById(R.id.install_firmware_btn)).setText(btn_text_res_id);
((Button)findViewById(R.id.next_step)).setEnabled(MainActivity.firmware_installed_file().exists());
((Button)findViewById(R.id.install_firmware_btn)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity.request_file_select(QuickStartActivity.this,MainActivity.REQUEST_INSTALL_FIRMWARE);
}
});
}
else if(layout.getId()==R.id.quick_start_page_select_iso_dir){
int btn_text_res_id=MainActivity.load_pref_iso_dir(this)==null?R.string.set_iso_dir:R.string.ps3_iso_dir_is_set;
((Button)findViewById(R.id.select_ps3_iso_dir_btn)).setText(btn_text_res_id);
((Button)findViewById(R.id.select_ps3_iso_dir_btn)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity.request_iso_dir_select(QuickStartActivity.this);
}
});
}
else if(layout.getId()==R.id.quick_start_page_install_font){
final String[] font_select_list_values=getResources().getStringArray(R.array.miscellaneous_font_file_selection_values);
final String[] font_select_list=getResources().getStringArray(R.array.miscellaneous_font_file_selection_entries);
if(((RadioGroup)findViewById(R.id.font_select_list)).getChildCount()==0)
{
((RadioGroup)findViewById(R.id.font_select_list)).removeAllViews();
for(int i=0;i<font_select_list.length;i++){
RadioButton btn=new RadioButton(this);
btn.setId(i);
btn.setText(font_select_list[i]);
RadioGroup.LayoutParams lp=new RadioGroup.LayoutParams(RadioGroup.LayoutParams.MATCH_PARENT,RadioGroup.LayoutParams.WRAP_CONTENT);
((RadioGroup)findViewById(R.id.font_select_list)).addView(btn,lp);
}
((RadioGroup)findViewById(R.id.font_select_list)).setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
String font_sel=font_select_list_values[checkedId];
config.save_config_entry(EmulatorSettings.Miscellaneous$Font_File_Selection,font_sel);
findViewById(R.id.custom_font_path).setEnabled(checkedId!=0);
findViewById(R.id.select_custom_font_list).setEnabled(checkedId!=0);
select_layout(page);
}
});
((RadioGroup)findViewById(R.id.font_select_list)).check(1);
}
final String font_path_prefix=getString(R.string.custom_font_path_prefix);
String font_path=config.load_config_entry(EmulatorSettings.Miscellaneous$Custom_Font_File_Path);
((TextView)findViewById(R.id.custom_font_path)).setText(font_path_prefix+font_path);
if(font_path.isEmpty()){
if(((RadioGroup)findViewById(R.id.font_select_list)).getCheckedRadioButtonId()==1)
//if(config.load_config_entry(EmulatorSettings.Miscellaneous$Font_File_Selection)
// .equals(font_select_list_values[1]))
findViewById(R.id.next_step).setEnabled(false);
}
ArrayList<String> font_list=new ArrayList<>();
{
File[] files=Application.get_custom_font_dir().listFiles();
if(files==null||files.length==0){
font_list.add(getString(R.string.emulator_settings_miscellaneous_custom_font_file_path_dialog_add_hint));
}
else{
for(File f:files){
font_list.add(f.getName());
}
font_list.add(getString(R.string.emulator_settings_miscellaneous_custom_font_file_path_dialog_add_hint));
}
}
((ListView)findViewById(R.id.select_custom_font_list)).setAdapter(new ArrayAdapter<String>(this
,android.R.layout.simple_list_item_1,font_list));
((ListView)findViewById(R.id.select_custom_font_list)).setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position==font_list.size()-1){
MainActivity.request_file_select(QuickStartActivity.this,EmulatorSettings.REQUEST_CODE_SELECT_CUSTOM_FONT);
}
else {
File font_file=new File(Application.get_custom_font_dir(),font_list.get(position));
config.save_config_entry(EmulatorSettings.Miscellaneous$Custom_Font_File_Path,font_file.getAbsolutePath());
select_layout(page);
}
}
});
}
else if(layout.getId()==R.id.quick_start_page_install_gpu_driver){
((CheckBox)findViewById(R.id.enable_custom_gpu_driver)).setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
config.save_config_entry(EmulatorSettings.Video$Vulkan$Use_Custom_Driver,Boolean.toString(isChecked));
select_layout(page);
}
});
((CheckBox)findViewById(R.id.enable_custom_gpu_driver)).setChecked(Boolean.valueOf(
config.load_config_entry(EmulatorSettings.Video$Vulkan$Use_Custom_Driver)));
final boolean enable_gpu_driver=((CheckBox)findViewById(R.id.enable_custom_gpu_driver)).isChecked();
findViewById(R.id.custom_gpu_driver_path).setEnabled(enable_gpu_driver);
findViewById(R.id.select_custom_gpu_driver_list).setEnabled(enable_gpu_driver);
String gpu_driver_path_prefix=getString(R.string.custom_gpu_driver_path_prefix);
String gpu_driver_path=config.load_config_entry(EmulatorSettings.Video$Vulkan$Custom_Driver_Library_Path);
((TextView)findViewById(R.id.custom_gpu_driver_path)).setText(gpu_driver_path_prefix+gpu_driver_path);
if(enable_gpu_driver&&gpu_driver_path.isEmpty()){
findViewById(R.id.next_step).setEnabled(false);
}
ArrayList<String> gpu_driver_list=new ArrayList<>();
{
File[] files=Application.get_custom_driver_dir().listFiles();
if(files==null||files.length==0){
gpu_driver_list.add(getString(R.string.emulator_settings_video_vulkan_custom_driver_library_path_dialog_add_hint));
}
else{
for(File f:files){
gpu_driver_list.add(f.getName());
}
gpu_driver_list.add(getString(R.string.emulator_settings_video_vulkan_custom_driver_library_path_dialog_add_hint));
}
}
((ListView)findViewById(R.id.select_custom_gpu_driver_list)).setAdapter(new ArrayAdapter<String>(this
,android.R.layout.simple_list_item_1,gpu_driver_list));
((ListView)findViewById(R.id.select_custom_gpu_driver_list)).setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(position==gpu_driver_list.size()-1){
MainActivity.request_file_select(QuickStartActivity.this,EmulatorSettings.REQUEST_CODE_SELECT_CUSTOM_DRIVER);
}
else {
File driver_file=new File(Application.get_custom_driver_dir(),gpu_driver_list.get(position));
config.save_config_entry(EmulatorSettings.Video$Vulkan$Custom_Driver_Library_Path,driver_file.getAbsolutePath());
select_layout(page);
}
}
});
}
else if(layout.getId()==R.id.quick_start_page_config_modify){
if(!Boolean.valueOf(config.load_config_entry(EmulatorSettings.Video$Vulkan$Use_Custom_Driver))){
if(Emulator.get.get_vulkan_physical_dev_list()[0].contains("Adreno")){
config.save_config_entry(EmulatorSettings.Video$Texture_Upload_Mode,"CPU");
config.save_config_entry(EmulatorSettings.Video$Use_BGRA_Format,"false");
config.save_config_entry(EmulatorSettings.Video$Force_Convert_Texture,"true");
}
}
boolean fix_llvm_cpu_cfg=false;
String fix_llvm_cpu_val=null;
{
String llvm_cpu = Emulator.get.get_native_llvm_cpu_list()[0];
if (llvm_cpu.equals("cortex-a510")
|| llvm_cpu.equals("cortex-a710")
|| llvm_cpu.equals("cortex-x2")
|| llvm_cpu.equals("cortex-a715")
|| llvm_cpu.equals("cortex-x3")
|| llvm_cpu.equals("cortex-a520")
|| llvm_cpu.equals("cortex-a720")
|| llvm_cpu.equals("cortex-a725")
|| llvm_cpu.equals("cortex-x4")
|| llvm_cpu.equals("cortex-a925")
) {
fix_llvm_cpu_cfg = true;
fix_llvm_cpu_val = "cortex-x1";
}
}
if(fix_llvm_cpu_cfg)
config.save_config_entry(EmulatorSettings.Core$Use_LLVM_CPU,fix_llvm_cpu_val);
}
}
String load_default_config_str(){
return new String(Application.load_assets_file(
this,"config/config.yml"));
}
void goto_main_activity(){
if(config!=null){
String config_str=config.close_config();
try {
FileOutputStream default_cfg_strm = new FileOutputStream(Application.get_default_config_file());
default_cfg_strm.write(config_str.getBytes());
default_cfg_strm.close();
config=null;
}catch (Exception e){
Toast.makeText(this,e.getMessage(),Toast.LENGTH_LONG).show();
if(Application.get_default_config_file().exists())
Application.get_default_config_file().delete();
return;
}
}
startActivity(new Intent(this,MainActivity.class));
finish();
}
boolean install_custom_driver_from_zip(Uri uri){
try {
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "r");
FileInputStream fis = new FileInputStream(pfd.getFileDescriptor());
ZipInputStream zis = new ZipInputStream(fis);
for (ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
if (ze.getName().endsWith(".so")) {
//String lib_path=new File(Application.get_custom_driver_dir() , ze.getName()).getAbsolutePath();
String lib_name=MainActivity.getFileNameFromUri(uri);
lib_name=lib_name.substring(0,lib_name.lastIndexOf('.'));
lib_name=lib_name+".so";
String lib_path=new File(Application.get_custom_driver_dir() , lib_name).getAbsolutePath();
FileOutputStream lib_os = new FileOutputStream(lib_path);
try {
byte[] buffer = new byte[16384];
int n;
while ((n = zis.read(buffer)) != -1)
lib_os.write(buffer, 0, n);
lib_os.close();
//fragment.setup_costom_driver_library_path(lib_path);
config.save_config_entry(EmulatorSettings.Video$Vulkan$Custom_Driver_Library_Path,lib_path);
select_layout(page);
zis.closeEntry();
break;
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
}
}
zis.closeEntry();
}
zis.close();
fis.close();
pfd.close();
return true;
}
catch (Exception e){
Toast.makeText(this,e.toString(),Toast.LENGTH_SHORT).show();
return false;
}
}
boolean install_custom_driver_from_lib(Uri uri){
try {
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "r");
FileInputStream lib_is = new FileInputStream(pfd.getFileDescriptor());
String lib_path=new File(Application.get_custom_driver_dir() , MainActivity.getFileNameFromUri(uri)).getAbsolutePath();
FileOutputStream lib_os = new FileOutputStream(lib_path);
byte[] buffer = new byte[16384];
int n;
while ((n = lib_is.read(buffer)) != -1)
lib_os.write(buffer, 0, n);
lib_os.close();
//fragment.setup_costom_driver_library_path(lib_path);
config.save_config_entry(EmulatorSettings.Video$Vulkan$Custom_Driver_Library_Path,lib_path);
select_layout(page);
lib_is.close();
pfd.close();
return true;
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
}
}
boolean install_custom_font(Uri uri){
try {
ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "r");
FileInputStream font_is = new FileInputStream(pfd.getFileDescriptor());
String font_path=new File(Application.get_custom_font_dir(), MainActivity.getFileNameFromUri(uri)).getAbsolutePath();
FileOutputStream font_os = new FileOutputStream(font_path);
byte[] buffer = new byte[16384];
int n;
while ((n = font_is.read(buffer)) != -1)
font_os.write(buffer, 0, n);
font_os.close();
//fragment.setup_costom_font_path(font_path);
config.save_config_entry(EmulatorSettings.Miscellaneous$Custom_Font_File_Path,font_path);
select_layout(page);
font_is.close();
pfd.close();
return true;
} catch (Exception e) {
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
return false;
}
}
}

View File

@@ -0,0 +1,42 @@
package aenu.preference;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceViewHolder;
public class CheckBoxPreference extends androidx.preference.CheckBoxPreference{
public CheckBoxPreference(@NonNull Context context) {
super(context);
}
public CheckBoxPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CheckBoxPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CheckBoxPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public int get_title_color(){
return title_color;
}
public void set_title_color(int color){
title_color=color;
}
int title_color=0;
@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
TextView title_v=(TextView) holder.itemView.findViewById(android.R.id.title);
if(title_v!=null&&title_color!=0)
title_v.setTextColor(title_color);
}
}

View File

@@ -0,0 +1,43 @@
package aenu.preference;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.PreferenceViewHolder;
public class ListPreference extends androidx.preference.ListPreference{
public ListPreference(@NonNull Context context){
super(context);
}
public ListPreference(@NonNull Context context, @Nullable AttributeSet attrs){
super(context,attrs);
}
public ListPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr){
super(context,attrs,defStyleAttr);
}
public ListPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes){
super(context,attrs,defStyleAttr,defStyleRes);
}
public int get_title_color(){
return title_color;
}
public void set_title_color(int color){
title_color=color;
}
int title_color=0;
@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
TextView title_v=(TextView) holder.itemView.findViewById(android.R.id.title);
if(title_v!=null&&title_color!=0)
title_v.setTextColor(title_color);
}
}

View File

@@ -21,23 +21,20 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.DialogPreference;
import androidx.preference.ListPreference;
import androidx.preference.ListPreferenceDialogFragmentCompat;
import androidx.preference.PreferenceDialogFragmentCompat;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SeekBarPreference;
import androidx.preference.R;
public class SeekbarPreference extends DialogPreference {
public class SeekBarPreference extends DialogPreference {
public static class SeekbarPreferenceFragmentCompat extends PreferenceDialogFragmentCompat {
public static class SeekBarPreferenceFragmentCompat extends PreferenceDialogFragmentCompat {
private static final String SAVE_STATE_VALUE = "SeekbarPreferenceFragmentCompat.value";
private static final String SAVE_STATE_MIN = "SeekbarPreferenceFragmentCompat.min";
private static final String SAVE_STATE_VALUE = "SeekBarPreferenceFragmentCompat.value";
private static final String SAVE_STATE_MIN = "SeekBarPreferenceFragmentCompat.min";
private static final String SAVE_STATE_MAX =
"SeekbarPreferenceFragmentCompat.max";
"SeekBarPreferenceFragmentCompat.max";
int m_value;
int m_min;
@@ -46,9 +43,9 @@ public class SeekbarPreference extends DialogPreference {
EditText mEditText;
@NonNull
public static SeekbarPreference.SeekbarPreferenceFragmentCompat newInstance(String key) {
final SeekbarPreference.SeekbarPreferenceFragmentCompat fragment =
new SeekbarPreference.SeekbarPreferenceFragmentCompat();
public static SeekBarPreference.SeekBarPreferenceFragmentCompat newInstance(String key) {
final SeekBarPreference.SeekBarPreferenceFragmentCompat fragment =
new SeekBarPreference.SeekBarPreferenceFragmentCompat();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
@@ -59,7 +56,7 @@ public class SeekbarPreference extends DialogPreference {
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
final SeekbarPreference preference = getSeekbarPreference();
final SeekBarPreference preference = getSeekBarPreference();
m_value = preference.getValue();
m_min = preference.getMin();
m_max = preference.getMax();
@@ -78,8 +75,8 @@ public class SeekbarPreference extends DialogPreference {
outState.putInt(SAVE_STATE_MAX, m_max);
}
private SeekbarPreference getSeekbarPreference() {
return (SeekbarPreference) getPreference();
private SeekBarPreference getSeekBarPreference() {
return (SeekBarPreference) getPreference();
}
@@ -105,7 +102,7 @@ public class SeekbarPreference extends DialogPreference {
try{
int value = Integer.parseInt(mEditText.getText().toString());
if (value >= m_min && value <= m_max){
final SeekbarPreference preference = getSeekbarPreference();
final SeekBarPreference preference = getSeekBarPreference();
if(preference.callChangeListener(value))
preference.setValue(value);
}
@@ -124,7 +121,7 @@ public class SeekbarPreference extends DialogPreference {
try{
int value = Integer.parseInt(mEditText.getText().toString());
if (value >= m_min && value <= m_max){
final SeekbarPreference preference = getSeekbarPreference();
final SeekBarPreference preference = getSeekBarPreference();
if(preference.callChangeListener(value))
preference.setValue(value);
}
@@ -209,7 +206,7 @@ public class SeekbarPreference extends DialogPreference {
}
};
public SeekbarPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
public SeekBarPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setDialogLayoutResource(aenu.aps3e.R.layout.edit_seek_bar);
@@ -229,23 +226,25 @@ public class SeekbarPreference extends DialogPreference {
a.recycle();
}
public SeekbarPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
public SeekBarPreference(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public SeekbarPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
public SeekBarPreference(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, R.attr.seekBarPreferenceStyle);
}
public SeekbarPreference(@NonNull Context context) {
public SeekBarPreference(@NonNull Context context) {
this(context, null);
}
@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setOnKeyListener(mSeekBarKeyListener);
mSeekBar = (SeekBar) holder.findViewById(R.id.seekbar);
mSeekBarValueTextView = (TextView) holder.findViewById(R.id.seekbar_value);

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/prev_step"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/prev_step"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"/>
<Button
android:id="@+id/next_step"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_step"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"/>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:layout_alignParentBottom="true"
android:layout_toEndOf="@id/prev_step"
android:layout_toStartOf="@id/next_step"
android:id="@android:id/progress"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/next_step">
<!--欢迎页-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/quick_start_page_welcome">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/welcome_text1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/welcome_text2"/>
</LinearLayout>
<!--安装固件-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/quick_start_page_install_firmware">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/install_ps3_firmware_hiht_content"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/install_firmware_btn"/>
</LinearLayout>
<!--选择ISO目录-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/quick_start_page_select_iso_dir">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/select_ps3_iso_dir_hiht_content"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/select_ps3_iso_dir_btn"/>
</LinearLayout>
<!--安装字体-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/quick_start_page_install_font">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/font_select_hiht_content"/>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/font_select_list"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/custom_font_path"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/select_custom_font_list"/>
</LinearLayout>
<!--安装驱动-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/quick_start_page_install_gpu_driver">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/select_gpu_driver_hiht_content"
/>
<CheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/enable_custom_gpu_driver"
android:text="@string/emulator_settings_video_vulkan_use_custom_driver"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/custom_gpu_driver_path"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/select_custom_gpu_driver_list"
/>
</LinearLayout>
<!--修改配置-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/quick_start_page_config_modify">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/modify_config_hiht_content"/>
</LinearLayout>
</FrameLayout>
</RelativeLayout>

View File

@@ -32,5 +32,9 @@
<item
android:id="@+id/menu_set_iso_dir"
android:title="@string/set_iso_dir"/>
<item
android:id="@+id/menu_quick_start_page"
android:title="@string/quick_start_page"/>
</menu>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>

View File

@@ -1,10 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="quick_start_page">快速开始页</string>
<string name="prev_step">上一步</string>
<string name="next_step">下一步</string>
<string name="finish">完成</string>
<string name="welcome">欢迎</string>
<string name="welcome_content">欢迎使用 %s !</string>
<string name="welcome_content2">只需几步简单的步骤,就可以开始畅玩游戏了,点击" %s "即可开始。</string>
<string name="install_ps3_firmware_hiht_content">想要进行游戏您必须安装PS3固件PS3UPDAT.PUP请选择固件文件。</string>
<string name="ps3_firmware_installed">固件安装完毕</string>
<string name="select_ps3_firmware">选择固件(PS3UPDAT.PUP)</string>
<string name="firmware_not_install">固件未安装</string>
<string name="select_ps3_iso_dir_hiht_content">请指定PS3 ISO目录APP会自动扫描以检索有效的游戏您也可以跳过此步骤直接安装.pkg文件 。</string>
<string name="ps3_iso_dir_is_set">PS3 ISO目录以设置</string>
<string name="font_select_hiht_content">请选择一个字体文件(*.ttf、*.ttc、*.otf进行安装您也可以使用来自PS3固件中的字体可能会缺字</string>
<string name="custom_font_path_prefix">字体路径: </string>
<string name="select_gpu_driver_hiht_content">请选择一个GPU驱动您也可以跳过此步骤游戏运行可能会出错</string>
<string name="custom_gpu_driver_path_prefix">GPU驱动路径: </string>
<string name="modify_config_hiht_content">模拟器会自动选择最合适的配置,但部分配置在您的设备可能会发生异常,稍后您可以在设置中自行修改。</string>
<string name="msg_processing">处理中...</string>
<string name="msg_failed">失败!</string>
<string name="emulator_settings_video_vulkan_debug">调试</string>
<string name="emulator_settings_miscellaneous_memory_debug_overlay">内存调试覆盖层</string>
<string name="vibrator_duration">震动时长</string>
<string name="enable_vibrator">启用震动</string>
@@ -44,9 +69,6 @@
<string name="about">关于</string>
<string name="quit">退出</string>
<string name="update_log">更新日志</string>
<string name="firmware_not_install">固件未安装</string>
<string name="request_title_INSTALL_FIRMWARE">选择固件(PS3UPDAT.PUP)</string>
<string name="request_title_INSTALL_GAME">选择一个PS3 RAP,ISO或PKG文件</string>
<string name="empty_game_list">游戏列表为空</string>
<string name="delete">删除</string>
<string name="settings">设置</string>
@@ -666,7 +688,6 @@
<string name="emulator_settings_miscellaneous_font_file_selection">字体文件选择</string>
<string-array name="miscellaneous_font_file_selection_entries">
<item>来自固件</item>
<item>来自系统</item>
<item>自定义</item>
</string-array>
<string name="emulator_settings_miscellaneous_custom_font_file_path">自定义字体文件路径</string>

View File

@@ -392,7 +392,6 @@
<string-array name="miscellaneous_font_file_selection_values">
<item>From Firmware</item>
<item>From OS</item>
<item>Custom</item>
</string-array>

View File

@@ -3,10 +3,36 @@
<!--string name="app_name">aPS3e Premium</string-->
<string name="app_name">aPS3e</string>
<string name="quick_start_page">Quick Start Page</string>
<string name="prev_step">Prev Step</string>
<string name="next_step">Next Step</string>
<string name="finish">Finish</string>
<string name="welcome">Welcome</string>
<string name="welcome_content">Welcome to %s!</string>
<string name="welcome_content2">With just a few simple steps, you re ready to start playing, click on " %s " to get started.</string>
<string name="install_ps3_firmware_hiht_content">To play the game, you must install the PS3 firmware (PS3UPDAT.PUP). Please select the firmware file.</string>
<string name="ps3_firmware_installed">Firmware Installed</string>
<string name="select_ps3_firmware">Select Firmware(PS3UPDAT.PUP)</string>
<string name="firmware_not_install">firmware not install</string>
<string name="select_ps3_iso_dir_hiht_content">Please specify the PS3 ISO directory, the APP will automatically scan to retrieve valid games, you can also skip this step and install the .pkg file directly.</string>
<string name="ps3_iso_dir_is_set">PS3 ISO directory to set</string>
<string name="font_select_hiht_content">Please select a font file (*.ttf, *.ttc, *.otf) to install, or you can use a font from the PS3 firmware (words may be missing).</string>
<string name="custom_font_path_prefix">Font Path: </string>
<string name="select_gpu_driver_hiht_content">Please select a GPU driver, you can also skip this step (the game may run with errors).</string>
<string name="custom_gpu_driver_path_prefix">GPU Driver Path: </string>
<string name="modify_config_hiht_content">The emulator will automatically select the most suitable configuration, but some configurations may cause issues on your device. You can modify them later in the settings.</string>
<string name="msg_processing">Processing...</string>
<string name="msg_failed">Failed!</string>
<string name="emulator_settings_video_vulkan_debug">Debug</string>
<string name="emulator_settings_miscellaneous_memory_debug_overlay">Memory Debug overlay</string>
<string name="vibrator_duration">Virbrator Duration</string>
<string name="enable_vibrator">Enable Vibrator</string>
@@ -46,9 +72,6 @@
<string name="about">About</string>
<string name="quit">Quit</string>
<string name="update_log">Update Log</string>
<string name="firmware_not_install">firmware not install</string>
<string name="request_title_INSTALL_FIRMWARE">Select Firmware(PS3UPDAT.PUP)</string>
<string name="request_title_INSTALL_GAME">Select a PS3 ISO,RAP or PKG</string>
<string name="empty_game_list">The game list is empty</string>
<string name="delete">Delete</string>
<string name="settings">Settings</string>
@@ -663,7 +686,6 @@
<string name="emulator_settings_miscellaneous_font_file_selection">Font File Selection</string>
<string-array name="miscellaneous_font_file_selection_entries">
<item>From Firmware</item>
<item>From OS</item>
<item>Custom</item>
</string-array>
<string name="emulator_settings_miscellaneous_custom_font_file_path">Custom Font File Path</string>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
</style>
</resources>

File diff suppressed because it is too large Load Diff