From 5d88e7a90c16580086fbe9a848ef8596be624363 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 28 Sep 2019 00:25:13 +0100 Subject: [PATCH] Got sound working Also added world scale cvar --- .../Android/jni/Quake2VR/Q2VR_SurfaceView.c | 25 +++++++ Projects/Android/jni/Quake2VR/VrCvars.h | 1 + .../Android/jni/quake2/src/client/cl_main.c | 8 --- .../Android/jni/quake2/src/client/cl_scrn.c | 44 ++---------- .../Android/jni/quake2/src/client/client.h | 3 +- assets/config.cfg | 3 - .../drbeef/quake2quest/GLES3JNIActivity.java | 71 ++++++++++++++++++- java/com/drbeef/quake2quest/GLES3JNILib.java | 5 ++ 8 files changed, 107 insertions(+), 53 deletions(-) diff --git a/Projects/Android/jni/Quake2VR/Q2VR_SurfaceView.c b/Projects/Android/jni/Quake2VR/Q2VR_SurfaceView.c index 24f8652..0954600 100644 --- a/Projects/Android/jni/Quake2VR/Q2VR_SurfaceView.c +++ b/Projects/Android/jni/Quake2VR/Q2VR_SurfaceView.c @@ -1327,6 +1327,13 @@ void VR_Init() vr_height_adjust = Cvar_Get( "vr_height_adjust", "0.0", CVAR_ARCHIVE); vr_flashlight_model = Cvar_Get( "vr_flashlight_model", "1", CVAR_ARCHIVE); vr_mirror_weapons = Cvar_Get( "vr_mirror_weapons", "0", CVAR_ARCHIVE); + + //The Engine (which is a derivative of Quake) uses a very specific unit size: + //Wolfenstein 3D, DOOM and QUAKE use the same coordinate/unit system: + //8 foot (96 inch) height wall == 64 units, 1.5 inches per pixel unit + //1.0 pixel unit / 1.5 inch == 0.666666 pixel units per inch + //This make a world scale of: 26.2467 + vr_worldscale = Cvar_Get( "vr_worldscale", "26.2467", CVAR_ARCHIVE); } void * AppThreadFunction( void * parm ) @@ -1905,3 +1912,21 @@ JNIEXPORT void JNICALL Java_com_drbeef_quake2quest_GLES3JNILib_onSurfaceDestroye ANativeWindow_release( appThread->NativeWindow ); appThread->NativeWindow = NULL; } + +/************************* + * Audio stuff + *************************/ + +JNIEXPORT jint JNICALL Java_com_drbeef_quake2quest_GLES3JNILib_Quake2PaintAudio( JNIEnv* env, jobject thiz, jobject buf ) +{ + extern int paint_audio (void *unused, void * stream, int len); + + void *stream; + int len; + + stream = (*env)->GetDirectBufferAddress( env, buf); + len = (*env)->GetDirectBufferCapacity( env, buf); + + return paint_audio ( NULL, stream, len ); +} + diff --git a/Projects/Android/jni/Quake2VR/VrCvars.h b/Projects/Android/jni/Quake2VR/VrCvars.h index f4c3885..9d55efe 100644 --- a/Projects/Android/jni/Quake2VR/VrCvars.h +++ b/Projects/Android/jni/Quake2VR/VrCvars.h @@ -12,3 +12,4 @@ cvar_t *vr_enable_crouching; cvar_t *vr_height_adjust; cvar_t *vr_flashlight_model; cvar_t *vr_mirror_weapons; +cvar_t *vr_worldscale; diff --git a/Projects/Android/jni/quake2/src/client/cl_main.c b/Projects/Android/jni/quake2/src/client/cl_main.c index db1361a..818d40e 100644 --- a/Projects/Android/jni/quake2/src/client/cl_main.c +++ b/Projects/Android/jni/quake2/src/client/cl_main.c @@ -34,11 +34,6 @@ cvar_t *adr6; cvar_t *adr7; cvar_t *adr8; -cvar_t *cl_stereo_separation; -cvar_t *cl_stereo; - - - cvar_t *rcon_client_password; cvar_t *rcon_address; @@ -1452,9 +1447,6 @@ void CL_InitLocal (void) // // register our variables // - cl_stereo_separation = Cvar_Get( "cl_stereo_separation", "1.5", CVAR_ARCHIVE ); - cl_stereo = Cvar_Get( "cl_stereo", "0", 0 ); - cl_add_blend = Cvar_Get ("cl_blend", "1", 0); cl_add_lights = Cvar_Get ("cl_lights", "1", 0); cl_add_particles = Cvar_Get ("cl_particles", "1", 0); diff --git a/Projects/Android/jni/quake2/src/client/cl_scrn.c b/Projects/Android/jni/quake2/src/client/cl_scrn.c index 1d20ea9..f20bf10 100644 --- a/Projects/Android/jni/quake2/src/client/cl_scrn.c +++ b/Projects/Android/jni/quake2/src/client/cl_scrn.c @@ -1325,43 +1325,12 @@ void SCR_UpdateScreen (void) ** brain Dont do that... i know what i am up to */ -/* -#ifdef REDBLUE - if ( cl_stereo_separation->value > 10.0 ) - Cvar_SetValue( "cl_stereo_separation", 10.0 ); -#else - if ( cl_stereo_separation->value > 1.0 ) - Cvar_SetValue( "cl_stereo_separation", 1.0 ); -#endif - else if ( cl_stereo_separation->value < 0 ) - Cvar_SetValue( "cl_stereo_separation", 0.0 ); -*/ - - - - -#ifdef REDBLUE - if ( !cl_stereo->value ) - Cvar_SetValue( "cl_stereo", 1 ); numframes = 2; - separation[0] = -cl_stereo_separation->value / 2.0; - separation[1] = cl_stereo_separation->value / 2.0; -#else - if ( cl_stereo->value ) - { - numframes = 2; - separation[0] = -cl_stereo_separation->value / 2; - separation[1] = cl_stereo_separation->value / 2; - } - else - { - separation[0] = 0; - separation[1] = 0; - numframes = 1; - } -#endif + separation[0] = -1.3f; + separation[1] = 1.3f; + for ( i = 0; i < numframes; i++ ) { re.BeginFrame( separation[i] ); @@ -1501,11 +1470,8 @@ void SCR_UpdateForEye (int eye) return; // not initialized yet - //TODO: Replace with world scale - float sep = -3.5; - separation = (sep / 2) * (1 - (2*eye)); - //separation = (cl_stereo_separation->value / 2) * (1 - (2*eye)); - + //World scale based separation + separation = ((-vr_worldscale->value * 0.065f) / 2) * (1 - (2*eye)); re.BeginFrame( separation ); diff --git a/Projects/Android/jni/quake2/src/client/client.h b/Projects/Android/jni/quake2/src/client/client.h index 80cb911..a1fbaef 100644 --- a/Projects/Android/jni/quake2/src/client/client.h +++ b/Projects/Android/jni/quake2/src/client/client.h @@ -266,9 +266,8 @@ extern client_static_t cls; // // cvars // -extern cvar_t *cl_stereo_separation; -extern cvar_t *cl_stereo; +extern cvar_t *vr_worldscale; extern cvar_t *cl_gun; extern cvar_t *cl_add_blend; diff --git a/assets/config.cfg b/assets/config.cfg index 30a2b5a..f05487b 100644 --- a/assets/config.cfg +++ b/assets/config.cfg @@ -1,9 +1,6 @@ // good config for Quake 2 on Android set cl_drawfps "1" -set cl_stereo "1" -set cl_stereo_separation "1.5" - //set cl_maxfps "25" set gl_ext_multitexture "1" //set developer "1" diff --git a/java/com/drbeef/quake2quest/GLES3JNIActivity.java b/java/com/drbeef/quake2quest/GLES3JNIActivity.java index 4a60c3c..2d8f75a 100644 --- a/java/com/drbeef/quake2quest/GLES3JNIActivity.java +++ b/java/com/drbeef/quake2quest/GLES3JNIActivity.java @@ -10,6 +10,7 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.ByteBuffer; import android.Manifest; import android.annotation.SuppressLint; @@ -17,7 +18,11 @@ import android.app.Activity; import android.content.pm.PackageManager; import android.content.res.AssetManager; +import android.media.AudioFormat; +import android.media.AudioManager; +import android.media.AudioTrack; import android.os.Bundle; +import android.os.SystemClock; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; @@ -47,7 +52,7 @@ import android.support.v4.content.ContextCompat; private SurfaceHolder mSurfaceHolder; private long mNativeHandle; - private final boolean m_asynchronousTracking = false; + private boolean please_exit = false; @Override protected void onCreate( Bundle icicle ) { @@ -210,6 +215,57 @@ import android.support.v4.content.ContextCompat; } + private static Object quake2Lock = new Object(); + + private static int sQuake2PaintAudio( ByteBuffer buf ){ + int ret; + synchronized(quake2Lock) { + ret = GLES3JNILib.Quake2PaintAudio(buf); + } + return ret; + } + + /*---------------------------- + * Audio + *----------------------------*/ + + public void audio_thread() throws IOException{ + + int audioSize = (2048*4); + + ByteBuffer audioBuffer = ByteBuffer.allocateDirect(audioSize); + + byte[] audioData = new byte[audioSize]; + + int sampleFreq = 22050; + AudioTrack oTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleFreq, + AudioFormat.CHANNEL_OUT_STEREO, + AudioFormat.ENCODING_PCM_16BIT, + AudioTrack.getMinBufferSize(sampleFreq, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT), + AudioTrack.MODE_STREAM); + + Log.i("Quake2", "start audio"); + + // Start playing data that is written + oTrack.play(); + + long tstart = SystemClock.uptimeMillis(); + + while (!please_exit){ + + sQuake2PaintAudio( audioBuffer ); + + audioBuffer.position(0); + audioBuffer.get(audioData); + + // Write the byte array to the track + oTrack.write(audioData, 0, audioData.length); + } + + // Done writing to the track + oTrack.stop(); + } + @Override protected void onStart() { Log.v( TAG, "GLES3JNIActivity::onStart()" ); @@ -237,6 +293,7 @@ import android.support.v4.content.ContextCompat; { Log.v( TAG, "GLES3JNIActivity::onStop()" ); GLES3JNILib.onStop( mNativeHandle ); + please_exit = true; super.onStop(); } @@ -251,6 +308,8 @@ import android.support.v4.content.ContextCompat; GLES3JNILib.onDestroy( mNativeHandle ); + please_exit = true; + super.onDestroy(); mNativeHandle = 0; } @@ -262,6 +321,16 @@ import android.support.v4.content.ContextCompat; { GLES3JNILib.onSurfaceCreated( mNativeHandle, holder.getSurface() ); mSurfaceHolder = holder; + + //Start Audio Thread + new Thread( new Runnable(){ + public void run() { + try { + audio_thread(); + } catch (IOException e) { + e.printStackTrace(); + } + }}).start(); } } diff --git a/java/com/drbeef/quake2quest/GLES3JNILib.java b/java/com/drbeef/quake2quest/GLES3JNILib.java index e714836..f502dfd 100644 --- a/java/com/drbeef/quake2quest/GLES3JNILib.java +++ b/java/com/drbeef/quake2quest/GLES3JNILib.java @@ -4,6 +4,8 @@ package com.drbeef.quake2quest; import android.app.Activity; import android.view.Surface; +import java.nio.ByteBuffer; + // Wrapper for native library public class GLES3JNILib @@ -20,4 +22,7 @@ public class GLES3JNILib public static native void onSurfaceCreated( long handle, Surface s ); public static native void onSurfaceChanged( long handle, Surface s ); public static native void onSurfaceDestroyed( long handle ); + + //Audio + public static native int Quake2PaintAudio( ByteBuffer buf ); }