diff --git a/jni/device.c b/jni/device.c index c2d9d5c..5f131d0 100644 --- a/jni/device.c +++ b/jni/device.c @@ -179,13 +179,62 @@ check_devices() #endif } -#if 0 +#if 1 #include #include #include #include +static char last_state = 0; +//double last_time = 0; +short audio_buf_short [32768]; +static int freq_counter = 0; +static char speaker_state = 0; + +jint +Java_org_ab_x48_X48_fillAudioData( JNIEnv* env, jobject this, jshortArray array) { + + /*struct timeval tv; + gettimeofday(&tv, NULL); + double now = (double)tv.tv_sec + ((double)tv.tv_usec/1000000);*/ + int numSamples = 0; + //if (last_time > 0) { + int count = device.speaker_counter; + //double deltaT = now-last_time; + double deltaT = 0.1; // on a mis le TimerTask à 100ms + numSamples = 44100 * deltaT; + + int i; + + if(count) { + + float freq = count/deltaT; + int delta = 44100 / freq; + //LOGI("freq: %f count: %d delta: %d deltaT: %f numSamples: %d", freq, count, delta, deltaT, numSamples); + device.speaker_counter = 0; + for(i=0; iSetShortArrayRegion(env, array, 0, numSamples, audio_buf_short); + //} + //last_time = now; + return numSamples; +} + + void #ifdef __FunctionProto__ check_out_register(void) @@ -193,17 +242,13 @@ check_out_register(void) check_out_register() #endif { - /*static int au = -2; - unsigned char c[] = { 0xff, 0x00 }; - if (au == -2) - if ((au = open("/dev/audio", O_WRONLY)) < 0) - if (au < 0) - return; - if (saturn.OUT[2] & 0x8) - write(au, c, 1); - else - write(au, &c[1], 1);*/ + char state = (saturn.OUT[2] & 0x8) == 0x8; + if (state != last_state) { + device.speaker_counter++; + last_state = state; + } + } #endif diff --git a/jni/device.h b/jni/device.h index 34fa31d..29615c5 100644 --- a/jni/device.h +++ b/jni/device.h @@ -113,6 +113,8 @@ typedef struct device_t { char t1_touched; char t2_touched; + int speaker_counter; + } device_t; extern device_t device; diff --git a/jni/emulate.c b/jni/emulate.c index b1370f8..dae0441 100644 --- a/jni/emulate.c +++ b/jni/emulate.c @@ -128,14 +128,14 @@ decode_group_80() case 0: /* OUT=CS */ saturn.PC += 3; copy_register(saturn.OUT, saturn.C, OUTS_FIELD); -#if 0 +#if 1 check_out_register(); #endif return 0; case 1: /* OUT=C */ saturn.PC += 3; copy_register(saturn.OUT, saturn.C, OUT_FIELD); -#if 0 +#if 1 check_out_register(); #endif return 0; diff --git a/res/values/strings.xml b/res/values/strings.xml index dad0d7f..8904c89 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -13,6 +13,8 @@ This program cannot be loaded.\nMake sure it\'s a valid one and you have enough memory to load it Rom files not found! This shouldn\'t happen :\\. Quitting now... General settings +Display/Sound settings + Contrast Select the contrast Back key behavior @@ -46,6 +48,10 @@ Also, easy shortcut: touch the LCD Hide the status bar Full screen mode +Autoscale touch controls +Scale when touch controls are too large (less sharp though) Disable minimal controls Prevents lite controls to show up when touching LCD +Enable (buggy) sound +EXPERIMENTAL: system beeps ok, so far diff --git a/src/org/ab/x48/HPView.java b/src/org/ab/x48/HPView.java index c661673..714c8c2 100644 --- a/src/org/ab/x48/HPView.java +++ b/src/org/ab/x48/HPView.java @@ -3,6 +3,8 @@ package org.ab.x48; import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import java.util.Vector; import android.content.Context; @@ -17,6 +19,9 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Paint.Style; +import android.media.AudioFormat; +import android.media.AudioManager; +import android.media.AudioTrack; import android.preference.PreferenceManager; import android.util.AttributeSet; import android.util.Log; @@ -41,8 +46,12 @@ public class HPView extends SurfaceView implements SurfaceHolder.Callback, Runna private int touches [] = new int [MAX_TOUCHES]; protected boolean needFlip; private short buf []; + private short audiobuf []; private int currentOrientation; private boolean multiTouch; + private AudioTrack track; + private TimerTask audioTask; + private Timer audioTimer; int buttons_coords [][] = new int [MAX_TOUCHES][4]; int icons_coords [][] = new int [6][2]; @@ -64,6 +73,8 @@ public class HPView extends SurfaceView implements SurfaceHolder.Callback, Runna queuedCodes = new Vector(); ann = new boolean [6]; buf = new short [(14+128)*262]; + audiobuf = new short [44100]; // 1s worth + track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 16384, AudioTrack.MODE_STREAM); annImages = new Bitmap [6]; updateContrast(); matrixScreen = new Matrix(); @@ -90,7 +101,20 @@ public class HPView extends SurfaceView implements SurfaceHolder.Callback, Runna screenPaint = null; screenPaint = new Paint(); - + audioTask = new TimerTask() { + @Override + public void run() { + if (mRun && track.getState() == AudioTrack.STATE_INITIALIZED) { + if (sound) { + track.play(); + track.write(audiobuf, 0, x48.fillAudioData(audiobuf)); + } else + track.stop(); + } + } + }; + audioTimer = new Timer(); + audioTimer.schedule(audioTask, 0, 100); } public void updateContrast() { @@ -122,6 +146,16 @@ public class HPView extends SurfaceView implements SurfaceHolder.Callback, Runna this.fullWidth = fullWidth; } + private boolean scaleControls; + + public boolean isScaleControls() { + return scaleControls; + } + + public void setScaleControls(boolean scaleControls) { + this.scaleControls = scaleControls; + } + public void refreshMainScreen(short data []) { Canvas c = null; try { @@ -417,14 +451,21 @@ public class HPView extends SurfaceView implements SurfaceHolder.Callback, Runna if (bw < (int) key_width) { delta_x = ((int)key_width-bw)/2; } else if (bw > (int) key_width) { - //ratio_kx = key_width / (float) bw; - delta_x = ((int)key_width-bw)/2; + if (scaleControls) { + float scaler = 1.0f; + if (k < 29) + scaler = 1.1f; + ratio_kx = scaler * key_width / (float) bw; + } else + delta_x = ((int)key_width-bw)/2; } if (bh < (int) key_height) { delta_y = ((int)key_height-bh)/2; } else if (bh > (int) key_height) { - //ratio_ky = key_height / (float) bh; - delta_y = ((int)key_height-bh)/2; + if (scaleControls) + ratio_ky = key_height / (float) bh; + else + delta_y = ((int)key_height-bh)/2; } if (!keybLite && !land && (k == 30 || k == 31 || k == 32 || k == 35 || k == 36 || k == 37 || @@ -561,6 +602,16 @@ public class HPView extends SurfaceView implements SurfaceHolder.Callback, Runna public void setKeybLite(boolean keybLite) { this.keybLite = keybLite; } + + private boolean sound = false; + + public boolean isSound() { + return sound; + } + + public void setSound(boolean sound) { + this.sound = sound; + } public void key(int code, boolean down) { key(code, down, 255); // Use pointerID 255 for keyboard diff --git a/src/org/ab/x48/Settings.java b/src/org/ab/x48/Settings.java index fdc0ba9..0871219 100644 --- a/src/org/ab/x48/Settings.java +++ b/src/org/ab/x48/Settings.java @@ -30,19 +30,6 @@ public class Settings extends PreferenceActivity { savePref.setSummary(R.string.saveonexit_msgbox_value); inlinePrefCat.addPreference(savePref); - CheckBoxPreference hapticPref = new CheckBoxPreference(this); - hapticPref.setKey("haptic"); - hapticPref.setTitle(R.string.haptic_feedback); - hapticPref.setDefaultValue(true); - inlinePrefCat.addPreference(hapticPref); - - CheckBoxPreference largeLCDPref = new CheckBoxPreference(this); - largeLCDPref.setKey("large_width"); - largeLCDPref.setTitle(R.string.large_width); - largeLCDPref.setSummary(R.string.large_width_summary); - largeLCDPref.setDefaultValue(false); - inlinePrefCat.addPreference(largeLCDPref); - CheckBoxPreference keybLitePref = new CheckBoxPreference(this); keybLitePref.setKey("keybLite"); keybLitePref.setTitle(R.string.show_lite_keyb); @@ -57,24 +44,6 @@ public class Settings extends PreferenceActivity { disableLite.setDefaultValue(false); inlinePrefCat.addPreference(disableLite); - CheckBoxPreference fullScreenPref = new CheckBoxPreference(this); - fullScreenPref.setKey("fullScreen"); - fullScreenPref.setTitle(R.string.full_screen); - fullScreenPref.setSummary(R.string.full_screen_summary); - fullScreenPref.setDefaultValue(false); - inlinePrefCat.addPreference(fullScreenPref); - - - ListPreference listPref = new ListPreference(this); - listPref.setEntries(R.array.contrast_entries); - listPref.setEntryValues(R.array.contrast_values); - listPref.setDefaultValue("1"); - listPref.setDialogTitle(R.string.choose_contrast_value); - listPref.setKey("contrast"); - listPref.setTitle(R.string.choose_contrast); - listPref.setSummary(R.string.choose_contrast_value); - inlinePrefCat.addPreference(listPref); - ListPreference backKeyPref = new ListPreference(this); backKeyPref.setEntries(R.array.backkey_entries); backKeyPref.setEntryValues(R.array.backkey_values); @@ -91,6 +60,56 @@ public class Settings extends PreferenceActivity { togglePref.setSummary(R.string.choose_msgbox_value); inlinePrefCat.addPreference(togglePref); + PreferenceCategory inlineDispPrefCat = new PreferenceCategory(this); + inlineDispPrefCat.setTitle(R.string.display_preferences); + root.addPreference(inlineDispPrefCat); + + CheckBoxPreference hapticPref = new CheckBoxPreference(this); + hapticPref.setKey("haptic"); + hapticPref.setTitle(R.string.haptic_feedback); + hapticPref.setDefaultValue(true); + inlineDispPrefCat.addPreference(hapticPref); + + CheckBoxPreference soundPref = new CheckBoxPreference(this); + soundPref.setKey("sound"); + soundPref.setTitle(R.string.sound); + soundPref.setSummary(R.string.sound_summary); + soundPref.setDefaultValue(false); + inlineDispPrefCat.addPreference(soundPref); + + CheckBoxPreference largeLCDPref = new CheckBoxPreference(this); + largeLCDPref.setKey("large_width"); + largeLCDPref.setTitle(R.string.large_width); + largeLCDPref.setSummary(R.string.large_width_summary); + largeLCDPref.setDefaultValue(false); + inlineDispPrefCat.addPreference(largeLCDPref); + + CheckBoxPreference scaleControlsPref = new CheckBoxPreference(this); + scaleControlsPref.setKey("scale_buttons"); + scaleControlsPref.setTitle(R.string.scale_buttons); + scaleControlsPref.setSummary(R.string.scale_buttons_summary); + scaleControlsPref.setDefaultValue(false); + inlineDispPrefCat.addPreference(scaleControlsPref); + + CheckBoxPreference fullScreenPref = new CheckBoxPreference(this); + fullScreenPref.setKey("fullScreen"); + fullScreenPref.setTitle(R.string.full_screen); + fullScreenPref.setSummary(R.string.full_screen_summary); + fullScreenPref.setDefaultValue(false); + inlineDispPrefCat.addPreference(fullScreenPref); + + ListPreference listPref = new ListPreference(this); + listPref.setEntries(R.array.contrast_entries); + listPref.setEntryValues(R.array.contrast_values); + listPref.setDefaultValue("1"); + listPref.setDialogTitle(R.string.choose_contrast_value); + listPref.setKey("contrast"); + listPref.setTitle(R.string.choose_contrast); + listPref.setSummary(R.string.choose_contrast_value); + inlineDispPrefCat.addPreference(listPref); + + + PreferenceCategory portPrefCat = new PreferenceCategory(this); portPrefCat.setTitle(R.string.ramcards_preferences); root.addPreference(portPrefCat); diff --git a/src/org/ab/x48/X48.java b/src/org/ab/x48/X48.java index 10a0ced..8efada1 100644 --- a/src/org/ab/x48/X48.java +++ b/src/org/ab/x48/X48.java @@ -81,7 +81,9 @@ public class X48 extends Activity { if (mainView != null) { mainView.setHapticFeedbackEnabled(mPrefs.getBoolean("haptic", true)); mainView.setFullWidth(mPrefs.getBoolean("large_width", false)); + mainView.setScaleControls(mPrefs.getBoolean("scale_buttons", false)); mainView.setKeybLite(mPrefs.getBoolean("keybLite", false)); + mainView.setSound(mPrefs.getBoolean("sound", false)); } if (mPrefs.getBoolean("fullScreen", false)) { getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN); @@ -126,6 +128,7 @@ public class X48 extends Activity { public native int buttonPressed(int code); public native int buttonReleased(int code); public native void registerClass(X48 instance); + public native int fillAudioData(short data []); public native int fillScreenData(short data []); public native void flipScreen(); public native int loadProg(String filename);