v0.7.4b: Initial LibGDX commit! more details below:
Large sections of game logic are now working through libgdx instead of android libraries. There is still work to do but this is the first major step. Big changes include: - Graphics code is now through LibGDX (except for text rendering) - Initialization and screen-handling logic is now mostly through LibGDX - Audio is now through LibGDX - Input handling is now through LibGDX - Most misc functions are now through LibGDX
This commit is contained in:
@@ -21,8 +21,7 @@
|
||||
|
||||
package com.watabou.noosa;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Matrix;
|
||||
@@ -264,8 +263,8 @@ public class BitmapText extends Visual {
|
||||
lineHeight = baseLine = height;
|
||||
}
|
||||
|
||||
protected void splitBy( Bitmap bitmap, int height, int color, String chars ) {
|
||||
|
||||
protected void splitBy( Pixmap bitmap, int height, int color, String chars ) {
|
||||
|
||||
int length = chars.length();
|
||||
|
||||
int width = bitmap.getWidth();
|
||||
@@ -302,7 +301,7 @@ public class BitmapText extends Visual {
|
||||
}
|
||||
found = false;
|
||||
for (int j=line; j < line + height; j++) {
|
||||
if (bitmap.getPixel( separator, j ) != color) {
|
||||
if (colorNotMatch( bitmap, separator, j, color)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -320,7 +319,7 @@ public class BitmapText extends Visual {
|
||||
}
|
||||
found = true;
|
||||
for (int j=line; j < line + height; j++) {
|
||||
if (bitmap.getPixel( separator, j ) != color) {
|
||||
if (colorNotMatch( bitmap, separator, j, color)) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
@@ -335,13 +334,22 @@ public class BitmapText extends Visual {
|
||||
lineHeight = baseLine = height( frames.get( chars.charAt( 0 ) ) );
|
||||
}
|
||||
|
||||
public static Font colorMarked( Bitmap bmp, int color, String chars ) {
|
||||
//FIXME
|
||||
private boolean colorNotMatch(Pixmap pixmap, int x, int y, int color) {
|
||||
int pixel = pixmap.getPixel(x, y);
|
||||
if ((pixel & 0xFF) == 0) {
|
||||
return color != 0;
|
||||
}
|
||||
return pixel != color;
|
||||
}
|
||||
|
||||
public static Font colorMarked( Pixmap bmp, int color, String chars ) {
|
||||
Font font = new Font( TextureCache.get( bmp ) );
|
||||
font.splitBy( bmp, bmp.getHeight(), color, chars );
|
||||
return font;
|
||||
}
|
||||
|
||||
public static Font colorMarked( Bitmap bmp, int height, int color, String chars ) {
|
||||
public static Font colorMarked( Pixmap bmp, int height, int color, String chars ) {
|
||||
Font font = new Font( TextureCache.get( bmp ) );
|
||||
font.splitBy( bmp, height, color, chars );
|
||||
return font;
|
||||
|
||||
@@ -21,42 +21,30 @@
|
||||
|
||||
package com.watabou.noosa;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.media.AudioManager;
|
||||
import android.opengl.GLES20;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Vibrator;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
|
||||
import com.badlogic.gdx.ApplicationListener;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.backends.android.AndroidApplication;
|
||||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
||||
import com.watabou.glscripts.Script;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
import com.watabou.glwrap.Blending;
|
||||
import com.watabou.glwrap.ScreenConfigChooser;
|
||||
import com.watabou.glwrap.Vertexbuffer;
|
||||
import com.watabou.input.InputHandler;
|
||||
import com.watabou.input.Keys;
|
||||
import com.watabou.input.Touchscreen;
|
||||
import com.watabou.noosa.audio.Music;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.BitmapCache;
|
||||
import com.watabou.utils.DeviceCompat;
|
||||
import com.watabou.utils.SystemTime;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTouchListener {
|
||||
public class Game extends AndroidApplication implements ApplicationListener {
|
||||
|
||||
public static Game instance;
|
||||
|
||||
@@ -95,13 +83,9 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
public static float timeTotal = 0f;
|
||||
|
||||
protected GLSurfaceView view;
|
||||
protected SurfaceHolder holder;
|
||||
//protected SurfaceHolder holder;
|
||||
|
||||
// Accumulated touch events
|
||||
protected ArrayList<MotionEvent> motionEvents = new ArrayList<MotionEvent>();
|
||||
|
||||
// Accumulated key events
|
||||
protected ArrayList<KeyEvent> keysEvents = new ArrayList<KeyEvent>();
|
||||
protected InputHandler inputHandler;
|
||||
|
||||
public Game( Class<? extends Scene> c ) {
|
||||
super();
|
||||
@@ -112,17 +96,9 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
protected void onCreate( Bundle savedInstanceState ) {
|
||||
super.onCreate( savedInstanceState );
|
||||
|
||||
BitmapCache.context = TextureCache.context = instance = this;
|
||||
|
||||
DisplayMetrics m = new DisplayMetrics();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
getWindowManager().getDefaultDisplay().getRealMetrics( m );
|
||||
else
|
||||
getWindowManager().getDefaultDisplay().getMetrics( m );
|
||||
density = m.density;
|
||||
dispHeight = m.heightPixels;
|
||||
dispWidth = m.widthPixels;
|
||||
|
||||
instance = this;
|
||||
|
||||
//FIXME this should be moved into a separate class, once we start to move to multiplatform
|
||||
try {
|
||||
version = getPackageManager().getPackageInfo( getPackageName(), 0 ).versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
@@ -134,20 +110,33 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
versionCode = 0;
|
||||
}
|
||||
|
||||
setVolumeControlStream( AudioManager.STREAM_MUSIC );
|
||||
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
|
||||
config.depth = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
//use rgb888 on more modern devices for better visuals
|
||||
config.r = config.g = config.b = 8;
|
||||
} else {
|
||||
//and rgb565 (default) on older ones for better performance
|
||||
}
|
||||
|
||||
view = new GLSurfaceView( this );
|
||||
view.setEGLContextClientVersion( 2 );
|
||||
|
||||
//Older devices are forced to RGB 565 for performance reasons.
|
||||
//Otherwise try to use RGB888 for best quality, but use RGB565 if it is what's available.
|
||||
view.setEGLConfigChooser( new ScreenConfigChooser(
|
||||
DeviceCompat.legacyDevice(),
|
||||
false ));
|
||||
|
||||
view.setRenderer( this );
|
||||
view.setOnTouchListener( this );
|
||||
setContentView( view );
|
||||
config.useCompass = false;
|
||||
config.useAccelerometer = false;
|
||||
//TODO consider the following additional options, might be better than setting manually
|
||||
//config.hideStatusBar
|
||||
//config.useImmersiveMode
|
||||
|
||||
initialize(this, config);
|
||||
|
||||
//FIXME shouldn't have a reference to the view here, remove things which access this
|
||||
view = (GLSurfaceView)graphics.getView();
|
||||
|
||||
inputHandler = new InputHandler();
|
||||
Gdx.input.setInputProcessor(inputHandler);
|
||||
Gdx.input.setCatchKey(Keys.BACK, true);
|
||||
Gdx.input.setCatchKey(Keys.MENU, true);
|
||||
|
||||
//FIXME this doesn't seem to work quite right. That might not be due to LibGDX though.
|
||||
Music.setMuteListener();
|
||||
|
||||
//so first call to onstart/onresume calls correct logic.
|
||||
paused = true;
|
||||
@@ -155,138 +144,46 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
|
||||
private boolean paused;
|
||||
|
||||
//Starting with honeycomb, android's lifecycle management changes slightly
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
|
||||
resumeGame();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (scene != null) {
|
||||
scene.onResume();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB){
|
||||
resumeGame();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (scene != null) {
|
||||
scene.onPause();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB){
|
||||
pauseGame();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
|
||||
pauseGame();
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseGame(){
|
||||
if (paused) return;
|
||||
|
||||
paused = true;
|
||||
view.onPause();
|
||||
Script.reset();
|
||||
|
||||
Music.INSTANCE.pause();
|
||||
Sample.INSTANCE.pause();
|
||||
}
|
||||
|
||||
public void resumeGame(){
|
||||
if (!paused) return;
|
||||
|
||||
now = 0;
|
||||
paused = false;
|
||||
view.onResume();
|
||||
|
||||
Music.INSTANCE.resume();
|
||||
Sample.INSTANCE.resume();
|
||||
}
|
||||
|
||||
public boolean isPaused(){
|
||||
return paused;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
destroyGame();
|
||||
public void create() {
|
||||
density = Gdx.graphics.getDensity();
|
||||
dispHeight = Gdx.graphics.getDisplayMode().height;
|
||||
dispWidth = Gdx.graphics.getDisplayMode().width;
|
||||
|
||||
Music.INSTANCE.mute();
|
||||
Sample.INSTANCE.reset();
|
||||
}
|
||||
|
||||
@SuppressLint({ "Recycle", "ClickableViewAccessibility" })
|
||||
@Override
|
||||
public boolean onTouch( View view, MotionEvent event ) {
|
||||
synchronized (motionEvents) {
|
||||
motionEvents.add( MotionEvent.obtain( event ) );
|
||||
}
|
||||
return true;
|
||||
Blending.useDefault();
|
||||
|
||||
//refreshes texture and vertex data stored on the gpu
|
||||
TextureCache.reload();
|
||||
RenderedText.reloadCache();
|
||||
Vertexbuffer.refreshAllBuffers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown( int keyCode, KeyEvent event ) {
|
||||
public void resize(int width, int height) {
|
||||
Gdx.gl.glViewport(0, 0, width, height);
|
||||
|
||||
if (keyCode != Keys.BACK &&
|
||||
keyCode != Keys.MENU) {
|
||||
return false;
|
||||
if (height != Game.height || width != Game.width) {
|
||||
|
||||
Game.width = width;
|
||||
Game.height = height;
|
||||
|
||||
resetScene();
|
||||
}
|
||||
|
||||
synchronized (motionEvents) {
|
||||
keysEvents.add( event );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp( int keyCode, KeyEvent event ) {
|
||||
|
||||
if (keyCode != Keys.BACK &&
|
||||
keyCode != Keys.MENU) {
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized (motionEvents) {
|
||||
keysEvents.add( event );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawFrame( GL10 gl ) {
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
NoosaScript.get().resetCamera();
|
||||
NoosaScriptNoLighting.get().resetCamera();
|
||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||
Gdx.gl.glDisable(Gdx.gl.GL_SCISSOR_TEST);
|
||||
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT);
|
||||
draw();
|
||||
|
||||
GLES20.glFlush();
|
||||
Gdx.gl.glFlush();
|
||||
|
||||
SystemTime.tick();
|
||||
long rightNow = SystemClock.elapsedRealtime();
|
||||
@@ -295,29 +192,39 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
|
||||
step();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged( GL10 gl, int width, int height ) {
|
||||
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
|
||||
if (height != Game.height || width != Game.width) {
|
||||
|
||||
Game.width = width;
|
||||
Game.height = height;
|
||||
|
||||
resetScene();
|
||||
public void pause() {
|
||||
paused = true;
|
||||
|
||||
if (scene != null) {
|
||||
scene.onPause();
|
||||
}
|
||||
|
||||
//view.onPause();
|
||||
Script.reset();
|
||||
|
||||
//Music.INSTANCE.pause();
|
||||
//Sample.INSTANCE.pause();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated( GL10 gl, EGLConfig config ) {
|
||||
Blending.useDefault();
|
||||
|
||||
//refreshes texture and vertex data stored on the gpu
|
||||
TextureCache.reload();
|
||||
RenderedText.reloadCache();
|
||||
Vertexbuffer.refreshAllBuffers();
|
||||
public void resume() {
|
||||
paused = false;
|
||||
|
||||
now = 0;
|
||||
//view.onResume();
|
||||
|
||||
//Music.INSTANCE.resume();
|
||||
//Sample.INSTANCE.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
destroyGame();
|
||||
|
||||
//Music.INSTANCE.mute();
|
||||
//Sample.INSTANCE.reset();
|
||||
}
|
||||
|
||||
protected void destroyGame() {
|
||||
@@ -392,14 +299,7 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
Game.elapsed = Game.timeScale * step * 0.001f;
|
||||
Game.timeTotal += Game.elapsed;
|
||||
|
||||
synchronized (motionEvents) {
|
||||
Touchscreen.processTouchEvents( motionEvents );
|
||||
motionEvents.clear();
|
||||
}
|
||||
synchronized (keysEvents) {
|
||||
Keys.processTouchEvents( keysEvents );
|
||||
keysEvents.clear();
|
||||
}
|
||||
inputHandler.processAllEvents();
|
||||
|
||||
scene.update();
|
||||
Camera.updateAll();
|
||||
@@ -410,11 +310,15 @@ public class Game extends Activity implements GLSurfaceView.Renderer, View.OnTou
|
||||
}
|
||||
|
||||
protected void logException( Throwable tr ){
|
||||
Log.e("GAME", Log.getStackTraceString(tr));
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
tr.printStackTrace(pw);
|
||||
pw.flush();
|
||||
Gdx.app.error("GAME", sw.toString());
|
||||
}
|
||||
|
||||
public static void vibrate( int milliseconds ) {
|
||||
((Vibrator)instance.getSystemService( VIBRATOR_SERVICE )).vibrate( milliseconds );
|
||||
Gdx.input.vibrate(milliseconds);
|
||||
}
|
||||
|
||||
public interface SceneChangeCallback{
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
|
||||
package com.watabou.noosa;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.gltextures.TextureCache;
|
||||
|
||||
@@ -41,14 +38,12 @@ public class Halo extends Image {
|
||||
super();
|
||||
|
||||
if (!TextureCache.contains( CACHE_KEY )) {
|
||||
Bitmap bmp = Bitmap.createBitmap( RADIUS * 2, RADIUS * 2, Bitmap.Config.ARGB_8888 );
|
||||
Canvas canvas = new Canvas( bmp );
|
||||
Paint paint = new Paint();
|
||||
paint.setColor( 0x0AFFFFFF );
|
||||
Pixmap pixmap = new Pixmap(RADIUS * 2, RADIUS * 2, Pixmap.Format.RGBA8888);
|
||||
pixmap.setColor( 0xFFFFFF0A );
|
||||
for (int i = 0; i < 50; i++) {
|
||||
canvas.drawCircle(RADIUS, RADIUS, RADIUS * (i+1)/50f, paint);
|
||||
pixmap.fillCircle(RADIUS, RADIUS, (int)(RADIUS * (i+1)/50f));
|
||||
}
|
||||
TextureCache.add( CACHE_KEY, new SmartTexture( bmp ) );
|
||||
TextureCache.add( CACHE_KEY, new SmartTexture( pixmap ) );
|
||||
}
|
||||
|
||||
texture( CACHE_KEY );
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
package com.watabou.noosa;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.watabou.glscripts.Script;
|
||||
import com.watabou.glwrap.Attribute;
|
||||
import com.watabou.glwrap.Quad;
|
||||
@@ -81,7 +80,7 @@ public class NoosaScript extends Script {
|
||||
aUV.vertexPointer( 2, 4, vertices );
|
||||
|
||||
Quad.releaseIndices();
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, size, GLES20.GL_UNSIGNED_SHORT, indices );
|
||||
Gdx.gl20.glDrawElements( Gdx.gl20.GL_TRIANGLES, size, Gdx.gl20.GL_UNSIGNED_SHORT, indices );
|
||||
Quad.bindIndices();
|
||||
}
|
||||
|
||||
@@ -92,8 +91,8 @@ public class NoosaScript extends Script {
|
||||
|
||||
vertices.position( 2 );
|
||||
aUV.vertexPointer( 2, 4, vertices );
|
||||
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE, GLES20.GL_UNSIGNED_SHORT, 0 );
|
||||
|
||||
Gdx.gl20.glDrawElements( Gdx.gl20.GL_TRIANGLES, Quad.SIZE, Gdx.gl20.GL_UNSIGNED_SHORT, 0 );
|
||||
}
|
||||
|
||||
public void drawQuad( Vertexbuffer buffer ) {
|
||||
@@ -106,8 +105,8 @@ public class NoosaScript extends Script {
|
||||
aUV.vertexBuffer( 2, 4, 2 );
|
||||
|
||||
buffer.release();
|
||||
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE, GLES20.GL_UNSIGNED_SHORT, 0 );
|
||||
|
||||
Gdx.gl20.glDrawElements( Gdx.gl20.GL_TRIANGLES, Quad.SIZE, Gdx.gl20.GL_UNSIGNED_SHORT, 0 );
|
||||
}
|
||||
|
||||
public void drawQuadSet( FloatBuffer vertices, int size ) {
|
||||
@@ -121,8 +120,8 @@ public class NoosaScript extends Script {
|
||||
|
||||
vertices.position( 2 );
|
||||
aUV.vertexPointer( 2, 4, vertices );
|
||||
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE * size, GLES20.GL_UNSIGNED_SHORT, 0 );
|
||||
|
||||
Gdx.gl20.glDrawElements( Gdx.gl20.GL_TRIANGLES, Quad.SIZE * size, Gdx.gl20.GL_UNSIGNED_SHORT, 0 );
|
||||
}
|
||||
|
||||
public void drawQuadSet( Vertexbuffer buffer, int length, int offset ){
|
||||
@@ -139,8 +138,8 @@ public class NoosaScript extends Script {
|
||||
aUV.vertexBuffer( 2, 4, 2 );
|
||||
|
||||
buffer.release();
|
||||
|
||||
GLES20.glDrawElements( GLES20.GL_TRIANGLES, Quad.SIZE * length, GLES20.GL_UNSIGNED_SHORT, Quad.SIZE * Short.SIZE/8 * offset );
|
||||
|
||||
Gdx.gl20.glDrawElements( Gdx.gl20.GL_TRIANGLES, Quad.SIZE * length, Gdx.gl20.GL_UNSIGNED_SHORT, Quad.SIZE * Short.SIZE/8 * offset );
|
||||
}
|
||||
|
||||
public void lighting( float rm, float gm, float bm, float am, float ra, float ga, float ba, float aa ) {
|
||||
@@ -161,14 +160,14 @@ public class NoosaScript extends Script {
|
||||
uCamera.valueM4( camera.matrix );
|
||||
|
||||
if (!camera.fullScreen) {
|
||||
GLES20.glEnable( GLES20.GL_SCISSOR_TEST );
|
||||
GLES20.glScissor(
|
||||
Gdx.gl20.glEnable( Gdx.gl20.GL_SCISSOR_TEST );
|
||||
Gdx.gl20.glScissor(
|
||||
camera.x,
|
||||
Game.height - camera.screenHeight - camera.y,
|
||||
camera.screenWidth,
|
||||
camera.screenHeight);
|
||||
} else {
|
||||
GLES20.glDisable( GLES20.GL_SCISSOR_TEST );
|
||||
Gdx.gl20.glDisable( Gdx.gl20.GL_SCISSOR_TEST );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,23 +183,34 @@ public class NoosaScript extends Script {
|
||||
|
||||
private static final String SHADER =
|
||||
|
||||
"uniform mat4 uCamera;" +
|
||||
"uniform mat4 uModel;" +
|
||||
"attribute vec4 aXYZW;" +
|
||||
"attribute vec2 aUV;" +
|
||||
"varying vec2 vUV;" +
|
||||
"void main() {" +
|
||||
" gl_Position = uCamera * uModel * aXYZW;" +
|
||||
" vUV = aUV;" +
|
||||
"}" +
|
||||
//vertex shader
|
||||
"uniform mat4 uCamera;\n" +
|
||||
"uniform mat4 uModel;\n" +
|
||||
"attribute vec4 aXYZW;\n" +
|
||||
"attribute vec2 aUV;\n" +
|
||||
"varying vec2 vUV;\n" +
|
||||
"void main() {\n" +
|
||||
" gl_Position = uCamera * uModel * aXYZW;\n" +
|
||||
" vUV = aUV;\n" +
|
||||
"}\n" +
|
||||
|
||||
//this symbol separates the vertex and fragment shaders (see Script.compile)
|
||||
"//\n" +
|
||||
|
||||
"varying mediump vec2 vUV;" +
|
||||
"uniform lowp sampler2D uTex;" +
|
||||
"uniform lowp vec4 uColorM;" +
|
||||
"uniform lowp vec4 uColorA;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = texture2D( uTex, vUV ) * uColorM + uColorA;" +
|
||||
"}";
|
||||
|
||||
//fragment shader
|
||||
//preprocessor directives let us define precision on GLES platforms, and ignore it elsewhere
|
||||
"#ifdef GL_ES\n" +
|
||||
" #define LOW lowp\n" +
|
||||
" #define MED mediump\n" +
|
||||
"#else\n" +
|
||||
" #define LOW\n" +
|
||||
" #define MED\n" +
|
||||
"#endif\n" +
|
||||
"varying MED vec2 vUV;\n" +
|
||||
"uniform LOW sampler2D uTex;\n" +
|
||||
"uniform LOW vec4 uColorM;\n" +
|
||||
"uniform LOW vec4 uColorA;\n" +
|
||||
"void main() {\n" +
|
||||
" gl_FragColor = texture2D( uTex, vUV ) * uColorM + uColorA;\n" +
|
||||
"}\n";
|
||||
}
|
||||
|
||||
@@ -45,22 +45,33 @@ public class NoosaScriptNoLighting extends NoosaScript {
|
||||
}
|
||||
|
||||
private static final String SHADER =
|
||||
|
||||
"uniform mat4 uCamera;" +
|
||||
"uniform mat4 uModel;" +
|
||||
"attribute vec4 aXYZW;" +
|
||||
"attribute vec2 aUV;" +
|
||||
"varying vec2 vUV;" +
|
||||
"void main() {" +
|
||||
" gl_Position = uCamera * uModel * aXYZW;" +
|
||||
" vUV = aUV;" +
|
||||
"}" +
|
||||
|
||||
"//\n" +
|
||||
|
||||
"varying mediump vec2 vUV;" +
|
||||
"uniform lowp sampler2D uTex;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = texture2D( uTex, vUV );" +
|
||||
"}";
|
||||
|
||||
//vertex shader
|
||||
"uniform mat4 uCamera;\n" +
|
||||
"uniform mat4 uModel;\n" +
|
||||
"attribute vec4 aXYZW;\n" +
|
||||
"attribute vec2 aUV;\n" +
|
||||
"varying vec2 vUV;\n" +
|
||||
"void main() {\n" +
|
||||
" gl_Position = uCamera * uModel * aXYZW;\n" +
|
||||
" vUV = aUV;\n" +
|
||||
"}\n" +
|
||||
|
||||
//this symbol separates the vertex and fragment shaders (see Script.compile)
|
||||
"//\n" +
|
||||
|
||||
//fragment shader
|
||||
//preprocessor directives let us define precision on GLES platforms, and ignore it elsewhere
|
||||
"#ifdef GL_ES\n" +
|
||||
" #define LOW lowp\n" +
|
||||
" #define MED mediump\n" +
|
||||
"#else\n" +
|
||||
" #define LOW\n" +
|
||||
" #define MED\n" +
|
||||
"#endif\n" +
|
||||
"varying MED vec2 vUV;\n" +
|
||||
"uniform LOW sampler2D uTex;\n" +
|
||||
"void main() {\n" +
|
||||
" gl_FragColor = texture2D( uTex, vUV );\n" +
|
||||
"}\n";
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.watabou.gltextures.SmartTexture;
|
||||
import com.watabou.glwrap.Matrix;
|
||||
import com.watabou.glwrap.Texture;
|
||||
@@ -169,7 +170,18 @@ public class RenderedText extends Image {
|
||||
|
||||
canvas.drawText(r.text, (r.size/10f), r.size, painter);
|
||||
|
||||
r.texture = new SmartTexture(bitmap, Texture.NEAREST, Texture.CLAMP, true);
|
||||
//FIXME really ugly and slow conversion between android bitmap and gdx pixmap
|
||||
int[] pixels = new int[bitmap.getWidth()*bitmap.getHeight()];
|
||||
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
// Convert from ARGB to RGBA
|
||||
for (int i = 0; i< pixels.length; i++) {
|
||||
int pixel = pixels[i];
|
||||
pixels[i] = (pixel << 8) | ((pixel >> 24) & 0xFF);
|
||||
}
|
||||
Pixmap pixmap = new Pixmap(bitmap.getWidth(), bitmap.getHeight(), Pixmap.Format.RGBA8888);
|
||||
pixmap.getPixels().asIntBuffer().put(pixels);
|
||||
r.texture = new SmartTexture(pixmap, Texture.NEAREST, Texture.CLAMP, true);
|
||||
bitmap.recycle();
|
||||
|
||||
RectF rect = r.texture.uvRect(0, 0, r.width, r.height);
|
||||
r.frame(rect);
|
||||
|
||||
@@ -22,20 +22,18 @@
|
||||
package com.watabou.noosa.audio;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.watabou.noosa.Game;
|
||||
|
||||
public enum Music {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
private MediaPlayer player;
|
||||
private com.badlogic.gdx.audio.Music player;
|
||||
|
||||
private String lastPlayed;
|
||||
private boolean looping;
|
||||
@@ -58,25 +56,11 @@ public enum Music {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
AssetFileDescriptor afd = Game.instance.getAssets().openFd( assetName );
|
||||
|
||||
MediaPlayer mp = new MediaPlayer();
|
||||
mp.setAudioStreamType( AudioManager.STREAM_MUSIC );
|
||||
mp.setDataSource( afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength() );
|
||||
mp.prepare();
|
||||
player = mp;
|
||||
player.start();
|
||||
player.setLooping(looping);
|
||||
player.setVolume(volume, volume);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
Game.reportException(e);
|
||||
player = null;
|
||||
|
||||
}
|
||||
player = Gdx.audio.newMusic(Gdx.files.internal(assetName));
|
||||
player.setLooping(looping);
|
||||
player.setVolume(volume);
|
||||
player.play();
|
||||
|
||||
}
|
||||
|
||||
public void mute() {
|
||||
@@ -92,19 +76,15 @@ public enum Music {
|
||||
|
||||
public void resume() {
|
||||
if (player != null) {
|
||||
player.start();
|
||||
player.play();
|
||||
player.setLooping(looping);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (player != null) {
|
||||
try {
|
||||
player.stop();
|
||||
player.release();
|
||||
} catch ( Exception e ){
|
||||
Game.reportException(e);
|
||||
}
|
||||
player.stop();
|
||||
player.dispose();
|
||||
player = null;
|
||||
}
|
||||
}
|
||||
@@ -112,7 +92,7 @@ public enum Music {
|
||||
public void volume( float value ) {
|
||||
volume = value;
|
||||
if (player != null) {
|
||||
player.setVolume( value, value );
|
||||
player.setVolume( value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,30 +114,29 @@ public enum Music {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public static final PhoneStateListener callMute = new PhoneStateListener(){
|
||||
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String incomingNumber)
|
||||
{
|
||||
if( state == TelephonyManager.CALL_STATE_RINGING ) {
|
||||
INSTANCE.pause();
|
||||
|
||||
} else if( state == TelephonyManager.CALL_STATE_IDLE ) {
|
||||
if (!Game.instance.isPaused()) {
|
||||
INSTANCE.resume();
|
||||
}
|
||||
}
|
||||
|
||||
super.onCallStateChanged(state, incomingNumber);
|
||||
}
|
||||
};
|
||||
|
||||
//FIXME android-specific code, that is also broken by being part of this class.
|
||||
public static void setMuteListener(){
|
||||
//versions lower than this require READ_PHONE_STATE permission
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
TelephonyManager mgr =
|
||||
(TelephonyManager) Game.instance.getSystemService(Activity.TELEPHONY_SERVICE);
|
||||
mgr.listen(Music.callMute, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
mgr.listen(new PhoneStateListener(){
|
||||
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String incomingNumber)
|
||||
{
|
||||
if( state == TelephonyManager.CALL_STATE_RINGING ) {
|
||||
INSTANCE.pause();
|
||||
|
||||
} else if( state == TelephonyManager.CALL_STATE_IDLE ) {
|
||||
if (!Game.instance.isPaused()) {
|
||||
INSTANCE.resume();
|
||||
}
|
||||
}
|
||||
|
||||
super.onCallStateChanged(state, incomingNumber);
|
||||
}
|
||||
}, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,113 +21,79 @@
|
||||
|
||||
package com.watabou.noosa.audio;
|
||||
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.content.res.AssetManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.SoundPool;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.audio.Sound;
|
||||
|
||||
import com.watabou.noosa.Game;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public enum Sample implements SoundPool.OnLoadCompleteListener {
|
||||
public enum Sample {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
public static final int MAX_STREAMS = 8;
|
||||
|
||||
protected SoundPool pool =
|
||||
new SoundPool( MAX_STREAMS, AudioManager.STREAM_MUSIC, 0 );
|
||||
|
||||
protected HashMap<Object, Integer> ids =
|
||||
new HashMap<>();
|
||||
protected HashMap<Object, Sound> ids = new HashMap<>();
|
||||
|
||||
private boolean enabled = true;
|
||||
private float volume = 1f;
|
||||
|
||||
private LinkedList<String> loadingQueue = new LinkedList<>();
|
||||
private float globalVolume = 1f;
|
||||
|
||||
public void reset() {
|
||||
|
||||
for (Sound sound : ids.values()){
|
||||
sound.dispose();
|
||||
}
|
||||
|
||||
ids.clear();
|
||||
loadingQueue = new LinkedList<>();
|
||||
pool.release();
|
||||
|
||||
pool = new SoundPool( MAX_STREAMS, AudioManager.STREAM_MUSIC, 0 );
|
||||
pool.setOnLoadCompleteListener( this );
|
||||
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (pool != null) {
|
||||
pool.autoPause();
|
||||
for (Sound sound : ids.values()) {
|
||||
sound.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
if (pool != null) {
|
||||
pool.autoResume();
|
||||
for (Sound sound : ids.values()) {
|
||||
sound.resume();
|
||||
}
|
||||
}
|
||||
|
||||
public void load( String... assets ) {
|
||||
|
||||
for (String asset : assets) {
|
||||
loadingQueue.add( asset );
|
||||
}
|
||||
loadNext();
|
||||
}
|
||||
|
||||
private void loadNext() {
|
||||
final String asset = loadingQueue.poll();
|
||||
if (asset != null) {
|
||||
if (!ids.containsKey( asset )) {
|
||||
try {
|
||||
pool.setOnLoadCompleteListener( new SoundPool.OnLoadCompleteListener() {
|
||||
@Override
|
||||
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
|
||||
loadNext();
|
||||
}
|
||||
} );
|
||||
|
||||
AssetManager manager = Game.instance.getAssets();
|
||||
AssetFileDescriptor fd = manager.openFd( asset );
|
||||
int streamID = pool.load( fd, 1 ) ;
|
||||
ids.put( asset, streamID );
|
||||
fd.close();
|
||||
} catch (IOException e) {
|
||||
loadNext();
|
||||
} catch (NullPointerException e) {
|
||||
// Do nothing (stop loading sounds)
|
||||
}
|
||||
} else {
|
||||
loadNext();
|
||||
//FIXME there used to be a queue here so that assets were loaded async.
|
||||
//This was to prevent hanging on specific android versions (implement in vanilla v1.7.5)
|
||||
//Maybe LibGDX already handles this?
|
||||
for (String asset : assets){
|
||||
if (!ids.containsKey(asset)){
|
||||
ids.put(asset, Gdx.audio.newSound(Gdx.files.internal(asset)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void unload( Object src ) {
|
||||
|
||||
if (ids.containsKey( src )) {
|
||||
|
||||
pool.unload( ids.get( src ) );
|
||||
ids.get( src ).dispose();
|
||||
ids.remove( src );
|
||||
}
|
||||
}
|
||||
|
||||
public int play( Object id ) {
|
||||
public long play( Object id ) {
|
||||
return play( id, 1 );
|
||||
}
|
||||
|
||||
public int play( Object id, float volume ) {
|
||||
public long play( Object id, float volume ) {
|
||||
return play( id, volume, volume, 1 );
|
||||
}
|
||||
|
||||
public int play( Object id, float leftVolume, float rightVolume, float rate ) {
|
||||
|
||||
public long play( Object id, float volume, float pitch ) {
|
||||
return play( id, volume, volume, pitch );
|
||||
}
|
||||
|
||||
public long play( Object id, float leftVolume, float rightVolume, float pitch ) {
|
||||
float volume = Math.max(leftVolume, rightVolume);
|
||||
float pan = rightVolume - leftVolume;
|
||||
if (enabled && ids.containsKey( id )) {
|
||||
return pool.play( ids.get( id ), leftVolume*volume, rightVolume*volume, 0, 0, rate );
|
||||
return ids.get(id).play( globalVolume*volume, pitch, pan );
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -138,14 +104,11 @@ public enum Sample implements SoundPool.OnLoadCompleteListener {
|
||||
}
|
||||
|
||||
public void volume( float value ) {
|
||||
this.volume = value;
|
||||
globalVolume = value;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadComplete( SoundPool soundPool, int sampleId, int status ) {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user