feat: Enhance audio renderer with new features and simplify Android UI indicators

Audio Core:
- Add support for splitter previous volume reset (REV 13+)
- Implement new audio processing time limits (REV 14-15)
- Add voice channel resource limits and effect processing v3
- Support float biquad filters for improved audio quality
- Enhance error handling to prevent audio system crashes

Android UI:
- Simplify FPS, RAM, and thermal indicator views
- Remove complex backgrounds and icons for cleaner display
- Reduce view sizes and improve text-based rendering
- Maintain color-coded status indicators for performance metrics

Core System:
- Improve file system save data space handling
- Enhance kernel synchronization error handling
- Add new error modules and result codes
- Fix potential infinite loops in handle operations

These changes improve audio processing capabilities while providing a cleaner,
more performant Android UI experience.

Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2025-09-23 21:15:06 +10:00
parent af6a54751e
commit af223e445f
18 changed files with 448 additions and 255 deletions

View File

@@ -20,44 +20,15 @@ class FpsIndicatorView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.parseColor("#80000000") // Semi-transparent black
style = Paint.Style.FILL
}
private val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
style = Paint.Style.STROKE
strokeWidth = 2f
}
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 22f
textSize = 18f
typeface = Typeface.DEFAULT_BOLD
textAlign = Paint.Align.CENTER
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val smallTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 16f
typeface = Typeface.DEFAULT
textAlign = Paint.Align.CENTER
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val iconPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 24f
textAlign = Paint.Align.CENTER
textAlign = Paint.Align.LEFT
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private var currentFps: Float = 0f
private val fpsIcon: String = "📊"
private val backgroundRect = RectF()
fun updateFps(fps: Float) {
try {
@@ -73,8 +44,6 @@ class FpsIndicatorView @JvmOverloads constructor(
}
textPaint.color = fpsColor
smallTextPaint.color = fpsColor
borderPaint.color = fpsColor
// Always invalidate to trigger a redraw
invalidate()
@@ -88,8 +57,8 @@ class FpsIndicatorView @JvmOverloads constructor(
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredWidth = 120
val desiredHeight = 60
val desiredWidth = 80
val desiredHeight = 30
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
@@ -111,30 +80,12 @@ class FpsIndicatorView @JvmOverloads constructor(
setMeasuredDimension(width, height)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
backgroundRect.set(4f, 4f, w - 4f, h - 4f)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Draw background with rounded corners
canvas.drawRoundRect(backgroundRect, 12f, 12f, backgroundPaint)
canvas.drawRoundRect(backgroundRect, 12f, 12f, borderPaint)
val centerX = width / 2f
val centerY = height / 2f
// Draw FPS icon on the left
canvas.drawText(fpsIcon, 18f, centerY - 8f, iconPaint)
// Draw FPS value (main text)
val fpsText = "${currentFps.roundToInt()}"
canvas.drawText(fpsText, centerX, centerY - 8f, textPaint)
// Draw "FPS" label (smaller text below)
canvas.drawText("FPS", centerX, centerY + 12f, smallTextPaint)
// Draw simple text-based FPS display
val fpsText = "FPS: ${currentFps.roundToInt()}"
canvas.drawText(fpsText, 8f, height - 8f, textPaint)
Log.d("FpsIndicator", "onDraw called - FPS: $fpsText")
}

View File

@@ -21,58 +21,17 @@ class RamMeterView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.parseColor("#80000000") // Semi-transparent black
style = Paint.Style.FILL
}
private val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
style = Paint.Style.STROKE
strokeWidth = 2f
}
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 20f
textSize = 18f
typeface = Typeface.DEFAULT_BOLD
textAlign = Paint.Align.CENTER
textAlign = Paint.Align.LEFT
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val smallTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 14f
typeface = Typeface.DEFAULT
textAlign = Paint.Align.CENTER
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val iconPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 24f
textAlign = Paint.Align.CENTER
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val meterBackgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.parseColor("#40FFFFFF") // Semi-transparent white
style = Paint.Style.FILL
}
private val meterFillPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.GREEN
style = Paint.Style.FILL
}
private var ramUsagePercent: Float = 0f
private var usedRamMB: Long = 0L
private var totalRamMB: Long = 0L
private var ramIcon: String = "🧠"
private val backgroundRect = RectF()
private val meterBackgroundRect = RectF()
private val meterFillRect = RectF()
fun updateRamUsage() {
try {
@@ -85,26 +44,15 @@ class RamMeterView @JvmOverloads constructor(
usedRamMB = totalRamMB - availableRamMB
ramUsagePercent = (usedRamMB.toFloat() / totalRamMB.toFloat()) * 100f
// Update meter color based on usage
val meterColor = when {
// Update text color based on usage
val ramColor = when {
ramUsagePercent < 50f -> Color.parseColor("#4CAF50") // Green
ramUsagePercent < 75f -> Color.parseColor("#FF9800") // Orange
ramUsagePercent < 90f -> Color.parseColor("#FF5722") // Red orange
else -> Color.parseColor("#F44336") // Red
}
meterFillPaint.color = meterColor
textPaint.color = meterColor
smallTextPaint.color = meterColor
borderPaint.color = meterColor
// Update icon based on usage
ramIcon = when {
ramUsagePercent < 50f -> "🧠" // Normal brain
ramUsagePercent < 75f -> "" // Warning
ramUsagePercent < 90f -> "🔥" // Hot
else -> "💥" // Critical
}
textPaint.color = ramColor
invalidate()
Log.d("RamMeter", "RAM usage updated: ${ramUsagePercent.roundToInt()}% (${usedRamMB}MB/${totalRamMB}MB)")
@@ -118,8 +66,8 @@ class RamMeterView @JvmOverloads constructor(
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredWidth = 140
val desiredHeight = 60
val desiredWidth = 120
val desiredHeight = 30
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
@@ -141,55 +89,19 @@ class RamMeterView @JvmOverloads constructor(
setMeasuredDimension(width, height)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
backgroundRect.set(4f, 4f, w - 4f, h - 4f)
// Setup meter rectangles - compact horizontal bar at the bottom
val meterLeft = 30f
val meterTop = h - 18f
val meterRight = w - 10f
val meterBottom = h - 10f
meterBackgroundRect.set(meterLeft, meterTop, meterRight, meterBottom)
meterFillRect.set(meterLeft, meterTop, meterRight, meterBottom)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Draw background with rounded corners
canvas.drawRoundRect(backgroundRect, 12f, 12f, backgroundPaint)
canvas.drawRoundRect(backgroundRect, 12f, 12f, borderPaint)
val centerX = width / 2f
val centerY = height / 2f
// Draw RAM icon on the left
canvas.drawText(ramIcon, 18f, centerY - 8f, iconPaint)
// Draw percentage text at the top center
val percentText = "${ramUsagePercent.roundToInt()}%"
canvas.drawText(percentText, centerX, centerY - 8f, textPaint)
// Draw memory usage text below percentage
// Draw simple text-based RAM display
val usedGB = usedRamMB / 1024f
val totalGB = totalRamMB / 1024f
val memoryText = if (totalGB >= 1.0f) {
"%.1fGB/%.1fGB".format(usedGB, totalGB)
val ramText = if (totalGB >= 1.0f) {
"RAM: ${ramUsagePercent.roundToInt()}% (%.1fGB/%.1fGB)".format(usedGB, totalGB)
} else {
"${usedRamMB}MB/${totalRamMB}MB"
"RAM: ${ramUsagePercent.roundToInt()}% (${usedRamMB}MB/${totalRamMB}MB)"
}
canvas.drawText(memoryText, centerX, centerY + 8f, smallTextPaint)
canvas.drawText(ramText, 8f, height - 8f, textPaint)
// Draw RAM meter background at the bottom
canvas.drawRoundRect(meterBackgroundRect, 4f, 4f, meterBackgroundPaint)
// Draw RAM meter fill
val fillWidth = meterBackgroundRect.width() * (ramUsagePercent / 100f)
meterFillRect.right = meterBackgroundRect.left + fillWidth
canvas.drawRoundRect(meterFillRect, 4f, 4f, meterFillPaint)
Log.d("RamMeter", "onDraw called - Usage: $percentText, Memory: $memoryText")
Log.d("RamMeter", "onDraw called - RAM: $ramText")
}
}

View File

@@ -25,59 +25,21 @@ class ThermalIndicatorView @JvmOverloads constructor(
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.parseColor("#80000000") // Semi-transparent black
style = Paint.Style.FILL
}
private val borderPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
style = Paint.Style.STROKE
strokeWidth = 2f
}
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 22f
textSize = 18f
typeface = Typeface.DEFAULT_BOLD
textAlign = Paint.Align.CENTER
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val smallTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 16f
typeface = Typeface.DEFAULT
textAlign = Paint.Align.CENTER
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private val iconPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.WHITE
textSize = 24f
textAlign = Paint.Align.CENTER
textAlign = Paint.Align.LEFT
setShadowLayer(2f, 1f, 1f, Color.BLACK)
}
private var batteryTemperature: Float = 0f
private var thermalStatus: String = "🌡️"
private val backgroundRect = RectF()
fun updateTemperature(temperature: Float) {
try {
batteryTemperature = temperature
Log.d("ThermalIndicator", "Battery temperature updated: ${batteryTemperature}°C")
// Update thermal status icon based on temperature
thermalStatus = when {
batteryTemperature < 20f -> "❄️" // Cold
batteryTemperature < 30f -> "🌡️" // Normal
batteryTemperature < 40f -> "🔥" // Warm
batteryTemperature < 50f -> "🥵" // Hot
else -> "☢️" // Critical
}
// Update text color based on temperature
val tempColor = when {
batteryTemperature < 20f -> Color.parseColor("#87CEEB") // Sky blue
@@ -88,24 +50,21 @@ class ThermalIndicatorView @JvmOverloads constructor(
}
textPaint.color = tempColor
smallTextPaint.color = tempColor
borderPaint.color = tempColor
// Always invalidate to trigger a redraw
invalidate()
Log.d("ThermalIndicator", "View invalidated, temperature: ${batteryTemperature}°C, status: $thermalStatus")
Log.d("ThermalIndicator", "View invalidated, temperature: ${batteryTemperature}°C")
} catch (e: Exception) {
// Fallback in case of any errors
batteryTemperature = 25f
thermalStatus = "🌡️"
Log.e("ThermalIndicator", "Error updating temperature", e)
invalidate()
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val desiredWidth = 120
val desiredHeight = 60
val desiredWidth = 100
val desiredHeight = 30
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
@@ -127,33 +86,13 @@ class ThermalIndicatorView @JvmOverloads constructor(
setMeasuredDimension(width, height)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
backgroundRect.set(4f, 4f, w - 4f, h - 4f)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Draw background with rounded corners
canvas.drawRoundRect(backgroundRect, 12f, 12f, backgroundPaint)
canvas.drawRoundRect(backgroundRect, 12f, 12f, borderPaint)
// Draw simple text-based temperature display
val tempText = "TEMP: ${batteryTemperature.roundToInt()}°C"
canvas.drawText(tempText, 8f, height - 8f, textPaint)
val centerX = width / 2f
val centerY = height / 2f
// Draw thermal icon on the left
canvas.drawText(thermalStatus, 18f, centerY - 8f, iconPaint)
// Draw temperature in Celsius (main temperature)
val celsiusText = "${batteryTemperature.roundToInt()}°C"
canvas.drawText(celsiusText, centerX, centerY - 8f, textPaint)
// Draw temperature in Fahrenheit (smaller, below)
val fahrenheit = (batteryTemperature * 9f / 5f + 32f).roundToInt()
val fahrenheitText = "${fahrenheit}°F"
canvas.drawText(fahrenheitText, centerX, centerY + 12f, smallTextPaint)
Log.d("ThermalIndicator", "onDraw called - Celsius: $celsiusText, Fahrenheit: $fahrenheitText")
Log.d("ThermalIndicator", "onDraw called - Temperature: $tempText")
}
}