Moved to NDK r4 and SDK 2.2, updated readme, still catching the crash in audio output with Android 2.2 - added lot of debug spam

This commit is contained in:
pelya
2010-06-25 18:52:45 +03:00
parent ee1dde5745
commit 09388a7599
14 changed files with 153 additions and 55 deletions

View File

@@ -3,7 +3,9 @@
package="de.schwardtnet.alienblaster"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name">
<application android:label="@string/app_name"
android:debuggable="true"
>
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape"
@@ -14,7 +16,7 @@
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="8"/>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

View File

@@ -8,6 +8,4 @@
# project structure.
# Project target.
target=android-4
# Indicates whether an apk should be generated for each density.
split.density=false
target=android-8

View File

@@ -74,13 +74,19 @@ int difficultyLevel;
float actBackgroundPos;
Game::Game() {
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 1");
videoserver = new Video();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 2");
screen = 0;
screen = videoserver->init();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 3");
settings = new Settings();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 4");
intro = new Intro( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 5");
setDifficulty = new SetDifficulty( screen );
menuArcadeMode = new MenuArcadeMode( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 6");
pauseSprite = surfaceDB.loadSurface( FN_PAUSED );
youLoseSprite = surfaceDB.loadSurface( FN_YOU_LOSE );
@@ -92,6 +98,8 @@ Game::Game() {
bossAlarm = Mixer::mixer().loadSample( FN_SOUND_BOSS_ALARM, 60 );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 7");
fontTime = new Font( FN_FONT_NUMBERS_TIME );
fontSizeTime = fontTime->getCharWidth();
@@ -125,18 +133,27 @@ Game::Game() {
sonic1 = new Sonic();
sonic2 = new Sonic();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 8");
background = new Background();
loadLevel( FN_LEVEL_ONE_PLAYER );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 9");
SDL_Surface *loadingSprite = surfaceDB.loadSurface( FN_LOADING );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 10");
SDL_Rect dest;
dest.x = (SCREEN_WIDTH - loadingSprite->w ) / 2;
dest.y = (SCREEN_HEIGHT - loadingSprite->h ) / 2;
dest.w = loadingSprite->w;
dest.h = loadingSprite->h;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 11");
SDL_BlitSurface( loadingSprite, 0, screen, &dest );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 12");
SDL_Flip( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 13");
initAllSurfaces();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 14");
}
Game::~Game(){

View File

@@ -31,15 +31,25 @@ using namespace std;
#include "infoscreen.h"
Intro::Intro( SDL_Surface *scr ) {
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 1");
screen = scr;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 2");
introSprite = surfaceDB.loadSurface( FN_ALIENBLASTER_INTRO );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 3");
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 4");
font = new Font( FN_FONT_INTRO );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 5");
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 6");
activeChoice = 0;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 7");
choose = Mixer::mixer().loadSample( FN_SOUND_INTRO_CHOOSE, 100 );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 8");
confirm = Mixer::mixer().loadSample( FN_SOUND_INTRO_CONFIRM, 100 );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 9");
infoscreen = new Infoscreen( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Intro() 10");
}
Intro::~Intro() {}

View File

@@ -25,10 +25,15 @@
using namespace std;
int main(int argc, char *argv[]) {
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 0");
SDL_Init(0);
srand(0);
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 1");
Game game;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 2");
game.run();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 3");
SDL_Quit();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "main() 4");
return 0;
}

View File

@@ -24,6 +24,7 @@ using namespace std;
#include <string>
#include <fstream>
#include <iostream>
#include <android/log.h>
Mixer * mixerInstance = NULL;
@@ -35,17 +36,22 @@ Mixer & Mixer::mixer()
}
Mixer::Mixer() {
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio");
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
printf("Couldn't initialize SDL audio subsystem: %s\n", SDL_GetError());
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't initialize SDL audio subsystem: %s", SDL_GetError());
exit(1);
}
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 2");
mixChunks = MixChunks(0);
musics = Musics(0);
enabled = false;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 3");
initMixer();
lastUsedReservedChannel = 0;
reservedChannels = 0;
musicPlaying = MUSIC_NONE;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio done");
}
Mixer::~Mixer() {
@@ -55,6 +61,7 @@ Mixer::~Mixer() {
}
void Mixer::initMixer() {
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 4");
enabled = (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 1, 1024) >= 0);
if (enabled) {
Mix_AllocateChannels(MIXER_NUMBER_CHANNELS);
@@ -66,6 +73,7 @@ void Mixer::initMixer() {
fn2mus.clear();
playsOn.clear();
}
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing audio 5");
}
void Mixer::freeMixer() {

View File

@@ -40,14 +40,17 @@ SDL_Surface *Video::init(){
// SDL initialisation
// -----------------------------------------------------
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing video");
fullscreen = false;
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
printf("Couldn't initialize SDL video subsystem: %s\n", SDL_GetError());
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't initialize SDL video subsystem: %s\n", SDL_GetError());
exit(1);
}
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF /* | SDL_FULLSCREEN */ );
if (!screen) {
printf("Couldn't set %dx%d, %dbit video mode: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_GetError());
__android_log_print(ANDROID_LOG_ERROR, "Alien Blaster", "Couldn't set %dx%d, %dbit video mode: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_GetError());
exit(2);
}
@@ -55,6 +58,7 @@ SDL_Surface *Video::init(){
SDL_WM_SetIcon(SDL_LoadBMP( FN_ALIENBLASTER_ICON.c_str() ), NULL);
SDL_ShowCursor(SDL_DISABLE);
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Initializing video done");
return screen;
}

View File

@@ -26,6 +26,10 @@
#include "SDL_error.h"
#include "SDL_error_c.h"
#ifdef ANDROID
#include <android/log.h>
#endif
/* Routine to get the thread-specific error variable */
#if SDL_THREADS_DISABLED
/* !!! FIXME: what does this comment mean? Victim of Search and Replace? */
@@ -111,6 +115,9 @@ SDL_SetError(const char *fmt, ...)
#ifdef DEBUG_ERROR
fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError());
#endif
#ifdef ANDROID
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "SDL_SetError: %s", SDL_GetError());
#endif
}
/* This function has a bit more overhead than most error functions

View File

@@ -100,8 +100,8 @@ static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS)
static int ANDROIDAUD_OpenAudio(_THIS, const char *devname, int iscapture)
{
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio: enter");
SDL_AudioSpec *audioFormat = &this->spec;
jboolean isCopy = JNI_TRUE;
int bytesPerSample;
JNIEnv * jniEnv = NULL;
@@ -129,32 +129,26 @@ static int ANDROIDAUD_OpenAudio(_THIS, const char *devname, int iscapture)
return (-1); // TODO: enable format conversion? Don't know how to do that in SDL
}
audioBufferJNI = (*jniEnv)->CallObjectMethod( jniEnv, JavaAudioThread, JavaInitAudio,
audioBufferSize = (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaInitAudio,
(jint)audioFormat->freq, (jint)audioFormat->channels,
(jint)(( bytesPerSample == 2 ) ? 1 : 0), (jint)audioFormat->size);
if( ! audioBufferJNI )
if( audioBufferSize == 0 )
{
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): failed to get audio buffer from JNI");
ANDROIDAUD_CloseAudio(this);
return(-1);
}
audioBufferJNI = (*jniEnv)->NewGlobalRef(jniEnv, audioBufferJNI);
audioBufferSize = (*jniEnv)->GetArrayLength(jniEnv, audioBufferJNI);
audioBuffer = (unsigned char *) (*jniEnv)->GetByteArrayElements(jniEnv, audioBufferJNI, &isCopy);
if( isCopy == JNI_TRUE )
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_OpenAudio(): JNI returns a copy of byte array - no audio will be played");
/* We cannot call DetachCurrentThread() from main thread or we'll crash */
/* (*jniVM)->DetachCurrentThread(jniVM); */
audioFormat->samples = audioBufferSize / bytesPerSample / audioFormat->channels;
audioFormat->size = audioBufferSize;
SDL_memset(audioBuffer, audioFormat->silence, audioFormat->size);
SDL_CalculateAudioSpec(&this->spec);
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio: exit, audioBufferSize %d", audioBufferSize);
return(1);
}
@@ -190,12 +184,13 @@ static jmethodID JavaFillBuffer = NULL;
static void ANDROIDAUD_ThreadInit(_THIS)
{
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_ThreadInit: enter");
jclass JavaAudioThreadClass = NULL;
jmethodID JavaInitThread = NULL;
struct sched_param param;
jmethodID JavaGetBuffer = NULL;
jboolean isCopy = JNI_TRUE;
(*jniVM)->AttachCurrentThread(jniVM, &jniEnvPlaying, NULL);
JavaAudioThreadClass = (*jniEnvPlaying)->GetObjectClass(jniEnvPlaying, JavaAudioThread);
JavaFillBuffer = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "fillBuffer", "()I");
@@ -203,6 +198,22 @@ static void ANDROIDAUD_ThreadInit(_THIS)
/* HACK: raise our own thread priority to max to get rid of "W/AudioFlinger: write blocked for 54 msecs" errors */
JavaInitThread = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "initAudioThread", "()I");
(*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaInitThread );
JavaGetBuffer = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "getBuffer", "()[B");
audioBufferJNI = (*jniEnvPlaying)->CallObjectMethod( jniEnvPlaying, JavaAudioThread, JavaGetBuffer );
audioBufferJNI = (*jniEnvPlaying)->NewGlobalRef(jniEnvPlaying, audioBufferJNI);
audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy);
if( !audioBuffer )
{
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_PlayAudio() JNI::GetByteArrayElements() failed! we will crash now");
return;
}
if( isCopy == JNI_TRUE )
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_OpenAudio(): JNI returns a copy of byte array - no audio will be played");
SDL_memset(audioBuffer, this->spec.silence, this->spec.size);
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_ThreadInit: exit, audioBuffer %p", audioBuffer);
};
static void ANDROIDAUD_ThreadDeinit(_THIS)
@@ -212,18 +223,23 @@ static void ANDROIDAUD_ThreadDeinit(_THIS)
static void ANDROIDAUD_PlayAudio(_THIS)
{
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio: enter, audiobuffer %p", audioBuffer);
jboolean isCopy = JNI_TRUE;
(*jniEnvPlaying)->ReleaseByteArrayElements(jniEnvPlaying, audioBufferJNI, (jbyte *)audioBuffer, 0);
audioBuffer = NULL;
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio: before JavaFillBuffer");
(*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaFillBuffer );
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio: after JavaFillBuffer");
audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy);
if( !audioBuffer )
__android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_PlayAudio() JNI::GetByteArrayElements() failed! we will crash now");
if( isCopy == JNI_TRUE )
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio() JNI returns a copy of byte array - that's slow");
__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio: exit audioBuffer %p", audioBuffer);
}
#ifndef SDL_JAVA_PACKAGE_PATH
@@ -238,7 +254,7 @@ JNIEXPORT jint JNICALL JAVA_EXPORT_NAME(AudioThread_nativeAudioInitJavaCallbacks
jclass JavaAudioThreadClass = NULL;
JavaAudioThread = (*jniEnv)->NewGlobalRef(jniEnv, thiz);
JavaAudioThreadClass = (*jniEnv)->GetObjectClass(jniEnv, JavaAudioThread);
JavaInitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "initAudio", "(IIII)[B");
JavaInitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "initAudio", "(IIII)I");
JavaDeinitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "deinitAudio", "()I");
/*
__android_log_print(ANDROID_LOG_INFO, "libSDL", "nativeAudioInitJavaCallbacks(): JavaAudioThread %p JavaFillBuffer %p JavaInitAudio %p JavaDeinitAudio %p",

View File

@@ -28,6 +28,11 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz )
int argc = 1;
char * argv[] = { "sdl" };
chdir(SDL_CURDIR_PATH);
/*
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Waiting 30s for debugger");
sleep(30); // Wait for debugger to attach
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Starting main()");
*/
main( argc, argv );
};

View File

@@ -34,11 +34,18 @@ class AudioThread {
public int fillBuffer()
{
mAudio.write( mAudioBuffer, 0, mAudioBuffer.length );
Log.i("libSDL", "JNI: fillBuffer() enter, mAudioBuffer len " + String.valueOf(mAudioBuffer.length));
int ret = 0;
try{
ret = mAudio.write( mAudioBuffer, 0, mAudioBuffer.length );
} catch( Throwable t ) {
Log.i("libSDL", "JNI: fillBuffer() caught exception!");
}
Log.i("libSDL", "JNI: fillBuffer() exit, written " + String.valueOf(ret));
return 1;
}
public byte[] initAudio(int rate, int channels, int encoding, int bufSize)
public int initAudio(int rate, int channels, int encoding, int bufSize)
{
if( mAudio == null )
{
@@ -60,7 +67,12 @@ class AudioThread {
AudioTrack.MODE_STREAM );
mAudio.play();
}
return mAudioBuffer;
return mAudioBuffer.length;
}
public byte[] getBuffer()
{
return mAudioBuffer;
}
public int deinitAudio()