added landscape & portrait toggle - fixed audio bug causing crashes

This commit is contained in:
izzy2lost
2025-12-07 12:01:57 -05:00
parent 19f5bff995
commit 69a937c997
5 changed files with 236 additions and 61 deletions
@@ -370,6 +370,9 @@ void AudioStream::StereoSampleReaderImpl(SampleType* dest, const SampleType* src
void AudioStream::InternalWriteFrames(const SampleType* data, u32 num_frames)
{
if (!m_buffer || m_buffer_size == 0)
return;
const u32 free = m_buffer_size - GetBufferedFramesRelaxed();
if (free <= num_frames)
{
@@ -635,6 +638,9 @@ void AudioStream::EndWrite(u32 num_frames)
void AudioStream::WriteChunk(const SampleType* chunk)
{
if (!m_buffer || m_buffer_size == 0)
return;
if (!IsExpansionEnabled() && !IsStretchEnabled())
{
InternalWriteFrames(chunk, CHUNK_SIZE);
+2 -1
View File
@@ -444,7 +444,8 @@ __forceinline void spu2Output(StereoOut32 out)
{
s_current_chunk_pos = 0;
s_output_stream->WriteChunk(s_current_chunk.data());
if (s_output_stream)
s_output_stream->WriteChunk(s_current_chunk.data());
if (SPU2::IsAudioCaptureActive()) [[unlikely]]
GSCapture::DeliverAudioPacket(s_current_chunk.data());
@@ -634,10 +634,34 @@ public class GamesCoverDialogFragment extends DialogFragment {
} catch (Throwable ignored) {}
}
private void setupDialogDrawerSettings(View header) {
private void setupDialogDrawerSettings(View header) {
if (header == null) return;
android.content.SharedPreferences prefs = requireContext().getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
MaterialButtonToggleGroup tgOrientation = header.findViewById(R.id.drawer_tg_orientation);
View tbOrientAuto = header.findViewById(R.id.drawer_tb_orientation_auto);
View tbOrientLand = header.findViewById(R.id.drawer_tb_orientation_landscape);
View tbOrientPort = header.findViewById(R.id.drawer_tb_orientation_portrait);
if (tgOrientation != null && tbOrientAuto != null && tbOrientLand != null && tbOrientPort != null) {
int savedOrientation = prefs.getInt("orientation_lock", MainActivity.ORIENTATION_AUTO);
int checkId = savedOrientation == MainActivity.ORIENTATION_LANDSCAPE ? tbOrientLand.getId()
: (savedOrientation == MainActivity.ORIENTATION_PORTRAIT ? tbOrientPort.getId() : tbOrientAuto.getId());
tgOrientation.check(checkId);
tgOrientation.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
int mode = MainActivity.ORIENTATION_AUTO;
if (checkedId == tbOrientLand.getId()) mode = MainActivity.ORIENTATION_LANDSCAPE;
else if (checkedId == tbOrientPort.getId()) mode = MainActivity.ORIENTATION_PORTRAIT;
try {
if (getActivity() instanceof MainActivity) {
((MainActivity) getActivity()).setOrientationPreference(mode);
} else {
prefs.edit().putInt("orientation_lock", mode).apply();
}
} catch (Throwable ignored) {}
});
}
// Aspect Ratio spinner
android.widget.Spinner spAspect = header.findViewById(R.id.drawer_sp_aspect_ratio);
if (spAspect != null) {
@@ -1245,66 +1269,81 @@ public class GamesCoverDialogFragment extends DialogFragment {
try {
View root = getView();
if (root == null) return;
com.google.android.material.navigation.NavigationView nav = root.findViewById(R.id.dialog_nav_view);
if (nav != null && nav.getHeaderCount() > 0) {
View header = nav.getHeaderView(0);
if (header != null) {
android.content.SharedPreferences prefs = requireContext().getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
// Refresh spinner values to reflect current settings
android.widget.Spinner spAspect = header.findViewById(R.id.drawer_sp_aspect_ratio);
if (spAspect != null && spAspect.getAdapter() != null) {
int savedAspect = prefs.getInt("aspect_ratio", 1);
android.widget.ArrayAdapter<?> aspectAdapter = (android.widget.ArrayAdapter<?>) spAspect.getAdapter();
if (savedAspect >= 0 && savedAspect < aspectAdapter.getCount()) {
spAspect.setSelection(savedAspect);
}
}
if (nav == null || nav.getHeaderCount() == 0) return;
android.widget.Spinner spScale = header.findViewById(R.id.drawer_sp_scale);
if (spScale != null && spScale.getAdapter() != null) {
float savedScale = prefs.getFloat("upscale_multiplier", 1.0f);
android.widget.ArrayAdapter<?> scaleAdapter = (android.widget.ArrayAdapter<?>) spScale.getAdapter();
int scaleIndex = Math.max(0, Math.min(scaleAdapter.getCount() - 1, Math.round(savedScale) - 1));
spScale.setSelection(scaleIndex);
}
View header = nav.getHeaderView(0);
if (header == null) return;
android.widget.Spinner spBlending = header.findViewById(R.id.drawer_sp_blending_accuracy);
if (spBlending != null && spBlending.getAdapter() != null) {
int savedBlend = prefs.getInt("blending_accuracy", 1);
android.widget.ArrayAdapter<?> blendAdapter = (android.widget.ArrayAdapter<?>) spBlending.getAdapter();
if (savedBlend >= 0 && savedBlend < blendAdapter.getCount()) {
spBlending.setSelection(savedBlend);
}
}
// Refresh switch states
com.google.android.material.materialswitch.MaterialSwitch swWide = header.findViewById(R.id.drawer_sw_widescreen);
if (swWide != null) {
swWide.setChecked(prefs.getBoolean("widescreen_patches", true));
}
android.content.SharedPreferences prefs = requireContext().getSharedPreferences("app_prefs", Context.MODE_PRIVATE);
com.google.android.material.materialswitch.MaterialSwitch swNoInt = header.findViewById(R.id.drawer_sw_no_interlacing);
if (swNoInt != null) {
swNoInt.setChecked(prefs.getBoolean("no_interlacing_patches", true));
}
com.google.android.material.materialswitch.MaterialSwitch swLoadTex = header.findViewById(R.id.drawer_sw_load_textures);
if (swLoadTex != null) {
swLoadTex.setChecked(prefs.getBoolean("load_textures", false));
}
com.google.android.material.materialswitch.MaterialSwitch swAsyncTex = header.findViewById(R.id.drawer_sw_async_textures);
if (swAsyncTex != null) {
swAsyncTex.setChecked(prefs.getBoolean("async_texture_loading", true));
}
com.google.android.material.materialswitch.MaterialSwitch swPrecache = header.findViewById(R.id.drawer_sw_precache_textures);
if (swPrecache != null) {
swPrecache.setChecked(prefs.getBoolean("precache_textures", false));
}
try {
MaterialButtonToggleGroup tgOrientation = header.findViewById(R.id.drawer_tg_orientation);
View tbOrientAuto = header.findViewById(R.id.drawer_tb_orientation_auto);
View tbOrientLand = header.findViewById(R.id.drawer_tb_orientation_landscape);
View tbOrientPort = header.findViewById(R.id.drawer_tb_orientation_portrait);
if (tgOrientation != null && tbOrientAuto != null && tbOrientLand != null && tbOrientPort != null) {
int savedOrientation = prefs.getInt("orientation_lock", MainActivity.ORIENTATION_AUTO);
int checkId = savedOrientation == MainActivity.ORIENTATION_LANDSCAPE ? tbOrientLand.getId()
: (savedOrientation == MainActivity.ORIENTATION_PORTRAIT ? tbOrientPort.getId() : tbOrientAuto.getId());
tgOrientation.check(checkId);
}
} catch (Exception e) {
android.util.Log.e("GamesCoverDialog", "Error refreshing orientation toggle: " + e.getMessage());
}
// Refresh spinner values to reflect current settings
android.widget.Spinner spAspect = header.findViewById(R.id.drawer_sp_aspect_ratio);
if (spAspect != null && spAspect.getAdapter() != null) {
int savedAspect = prefs.getInt("aspect_ratio", 1);
android.widget.ArrayAdapter<?> aspectAdapter = (android.widget.ArrayAdapter<?>) spAspect.getAdapter();
if (savedAspect >= 0 && savedAspect < aspectAdapter.getCount()) {
spAspect.setSelection(savedAspect);
}
}
android.widget.Spinner spScale = header.findViewById(R.id.drawer_sp_scale);
if (spScale != null && spScale.getAdapter() != null) {
float savedScale = prefs.getFloat("upscale_multiplier", 1.0f);
android.widget.ArrayAdapter<?> scaleAdapter = (android.widget.ArrayAdapter<?>) spScale.getAdapter();
int scaleIndex = Math.max(0, Math.min(scaleAdapter.getCount() - 1, Math.round(savedScale) - 1));
spScale.setSelection(scaleIndex);
}
android.widget.Spinner spBlending = header.findViewById(R.id.drawer_sp_blending_accuracy);
if (spBlending != null && spBlending.getAdapter() != null) {
int savedBlend = prefs.getInt("blending_accuracy", 1);
android.widget.ArrayAdapter<?> blendAdapter = (android.widget.ArrayAdapter<?>) spBlending.getAdapter();
if (savedBlend >= 0 && savedBlend < blendAdapter.getCount()) {
spBlending.setSelection(savedBlend);
}
}
// Refresh switch states
com.google.android.material.materialswitch.MaterialSwitch swWide = header.findViewById(R.id.drawer_sw_widescreen);
if (swWide != null) {
swWide.setChecked(prefs.getBoolean("widescreen_patches", true));
}
com.google.android.material.materialswitch.MaterialSwitch swNoInt = header.findViewById(R.id.drawer_sw_no_interlacing);
if (swNoInt != null) {
swNoInt.setChecked(prefs.getBoolean("no_interlacing_patches", true));
}
com.google.android.material.materialswitch.MaterialSwitch swLoadTex = header.findViewById(R.id.drawer_sw_load_textures);
if (swLoadTex != null) {
swLoadTex.setChecked(prefs.getBoolean("load_textures", false));
}
com.google.android.material.materialswitch.MaterialSwitch swAsyncTex = header.findViewById(R.id.drawer_sw_async_textures);
if (swAsyncTex != null) {
swAsyncTex.setChecked(prefs.getBoolean("async_texture_loading", true));
}
com.google.android.material.materialswitch.MaterialSwitch swPrecache = header.findViewById(R.id.drawer_sw_precache_textures);
if (swPrecache != null) {
swPrecache.setChecked(prefs.getBoolean("precache_textures", false));
}
} catch (Throwable ignored) {}
}
@@ -38,6 +38,7 @@ import android.app.RemoteAction;
import android.graphics.drawable.Icon;
import android.app.PendingIntent;
import android.content.pm.PackageManager;
import android.content.pm.ActivityInfo;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
@@ -55,7 +56,6 @@ import androidx.core.view.WindowInsetsCompat;
import androidx.core.graphics.Insets;
import com.google.android.material.button.MaterialButton;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -70,6 +70,10 @@ import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity implements GamesCoverDialogFragment.OnGameSelectedListener, ControllerInputHandler.ControllerInputListener {
public static final int ORIENTATION_AUTO = 0;
public static final int ORIENTATION_LANDSCAPE = 1;
public static final int ORIENTATION_PORTRAIT = 2;
private String m_szGamefile = "";
private HIDDeviceManager mHIDDeviceManager;
@@ -1942,11 +1946,67 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
}
}
private int normalizeOrientationPref(int value) {
if (value == ORIENTATION_LANDSCAPE || value == ORIENTATION_PORTRAIT) return value;
return ORIENTATION_AUTO;
}
public void setOrientationPreference(int mode) {
int normalized = normalizeOrientationPref(mode);
try {
SharedPreferences prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
prefs.edit().putInt("orientation_lock", normalized).apply();
} catch (Throwable ignored) {}
applyOrientationPreference(normalized);
}
public void applyOrientationPreference() {
int mode = ORIENTATION_AUTO;
try {
SharedPreferences prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
mode = normalizeOrientationPref(prefs.getInt("orientation_lock", ORIENTATION_AUTO));
} catch (Throwable ignored) {}
applyOrientationPreference(mode);
}
private void applyOrientationPreference(int mode) {
int requested = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
if (mode == ORIENTATION_LANDSCAPE) {
requested = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
} else if (mode == ORIENTATION_PORTRAIT) {
requested = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
}
try {
setRequestedOrientation(requested);
} catch (Throwable e) {
android.util.Log.e("MainActivity", "Failed to apply orientation preference: " + e.getMessage());
}
}
private void setupDrawerSettings(View header) {
if (header == null) return;
SharedPreferences prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
MaterialButtonToggleGroup tgOrientation = header.findViewById(R.id.drawer_tg_orientation);
View tbOrientAuto = header.findViewById(R.id.drawer_tb_orientation_auto);
View tbOrientLand = header.findViewById(R.id.drawer_tb_orientation_landscape);
View tbOrientPort = header.findViewById(R.id.drawer_tb_orientation_portrait);
if (tgOrientation != null && tbOrientAuto != null && tbOrientLand != null && tbOrientPort != null) {
int savedOrientation = normalizeOrientationPref(prefs.getInt("orientation_lock", ORIENTATION_AUTO));
int checkId = savedOrientation == ORIENTATION_LANDSCAPE ? tbOrientLand.getId()
: (savedOrientation == ORIENTATION_PORTRAIT ? tbOrientPort.getId() : tbOrientAuto.getId());
tgOrientation.check(checkId);
tgOrientation.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
int mode = ORIENTATION_AUTO;
if (checkedId == tbOrientLand.getId()) mode = ORIENTATION_LANDSCAPE;
else if (checkedId == tbOrientPort.getId()) mode = ORIENTATION_PORTRAIT;
setOrientationPreference(mode);
});
}
// Aspect Ratio spinner - setup like QuickActions
Spinner spAspect = header.findViewById(R.id.drawer_sp_aspect_ratio);
if (spAspect != null) {
@@ -2118,7 +2178,22 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
android.util.Log.e("MainActivity", "SharedPreferences is null during refreshDrawerSettings");
return;
}
try {
MaterialButtonToggleGroup tgOrientation = header.findViewById(R.id.drawer_tg_orientation);
View tbOrientAuto = header.findViewById(R.id.drawer_tb_orientation_auto);
View tbOrientLand = header.findViewById(R.id.drawer_tb_orientation_landscape);
View tbOrientPort = header.findViewById(R.id.drawer_tb_orientation_portrait);
if (tgOrientation != null && tbOrientAuto != null && tbOrientLand != null && tbOrientPort != null) {
int savedOrientation = normalizeOrientationPref(prefs.getInt("orientation_lock", ORIENTATION_AUTO));
int checkId = savedOrientation == ORIENTATION_LANDSCAPE ? tbOrientLand.getId()
: (savedOrientation == ORIENTATION_PORTRAIT ? tbOrientPort.getId() : tbOrientAuto.getId());
tgOrientation.check(checkId);
}
} catch (Exception e) {
android.util.Log.e("MainActivity", "Error refreshing orientation toggle: " + e.getMessage());
}
// Refresh spinner values to reflect current settings
try {
Spinner spAspect = header.findViewById(R.id.drawer_sp_aspect_ratio);
@@ -2249,6 +2324,8 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
// Apply renderer setting
int renderer = prefs.getInt("renderer", -1);
NativeApp.renderGpu(renderer);
applyOrientationPreference();
} catch (Throwable ignored) {}
}
@@ -104,14 +104,66 @@
android:textColor="@color/brand_primary"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_sw"
style="@style/PSX2.ToggleButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="SW"
android:textColor="@color/brand_primary"
android:checkable="true" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<!-- Orientation -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Orientation"
android:textStyle="bold"
android:textColor="@color/brand_primary"
android:paddingTop="8dp"
android:paddingBottom="4dp" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/drawer_tg_orientation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:singleSelection="true"
app:selectionRequired="true"
android:layout_marginBottom="8dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_sw"
android:id="@+id/drawer_tb_orientation_auto"
style="@style/PSX2.ToggleButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="SW"
android:text="Auto"
android:textColor="@color/brand_primary"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_orientation_landscape"
style="@style/PSX2.ToggleButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="Landscape"
android:textColor="@color/brand_primary"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_orientation_portrait"
style="@style/PSX2.ToggleButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="Portrait"
android:textColor="@color/brand_primary"
android:checkable="true" />
</com.google.android.material.button.MaterialButtonToggleGroup>