mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-03-26 11:29:33 -04:00
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:
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user