]> Pileus Git - ~andy/spades/blobdiff - src/org/pileus/spades/Cards.java
Fix texture loading with new Android
[~andy/spades] / src / org / pileus / spades / Cards.java
index 9c66c87614bda014fe424a022fc0e4f13dbfdd9f..8506e212a36c708722e90acdc30a3d0351ee0ffe 100644 (file)
@@ -14,6 +14,7 @@ import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
 import android.opengl.GLES20;
 import android.opengl.GLSurfaceView;
 import android.opengl.GLUtils;
@@ -91,6 +92,7 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
 
        /* Private data */
        private Resources    res;         // app resources
+       private Options      options;     // bitmap options
        private int          program;     // opengl program
 
        private float[]      model;       // model matrix
@@ -124,7 +126,9 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
        private Map<String,Integer> index; // card name to index map
 
        /* Properties */
+       public Spades        game;        // the spades game
        public String[]      hand;        // cards to display
+       public String[]      pile;        // played cards to display
 
        /* GLSurfaceView Methods */
        public Cards(Context context)
@@ -142,10 +146,8 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
 
                this.ylim  = 0.4f;
 
-               this.hand  = new String[] {
-                       "As", "7s", "6s",  "6h", "2h", "Ac",
-                       "Kc", "3c", "10d", "9d", "8d", "7d", "2d"
-               };
+               this.hand  = "As Ks Qs Js 10s 9s 8s 7s 6s 5s 4s 3s 2s".split(" ");
+               this.pile  = "Ah Ac Ad".split(" ");
 
                this.index = new HashMap<String,Integer>(52);
                for (int i = 0; i < 52; i++)
@@ -187,6 +189,10 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
                this.tableBuf = this.loadBuffer(this.tableCoords);
                this.mapBuf   = this.loadBuffer(this.mapCoords);
 
+               /* Prevent texture scaling */
+               this.options = new BitmapFactory.Options();
+               this.options.inScaled = false;
+
                /* Load textures */
                for (int i = 0; i < 52; i++) {
                        String name = "card_" + this.cards[i].toLowerCase();
@@ -203,7 +209,7 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
        @Override
        public void onDrawFrame(GL10 unused)
        {
-               Os.debug("Cards: onDrawFrame");
+               //Os.debug("Cards: onDrawFrame");
 
                /* Turn on the program */
                GLES20.glUseProgram(program);
@@ -227,50 +233,11 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
                GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
                GLES20.glUniform1i(this.texHandle, 0);
 
-               /* Draw "Table" */
-               Matrix.setIdentityM(this.model, 0);
-               GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
+               /* Draw objects */
                this.drawTable();
-
-               /* Draw hand */
-               int num = this.hand.length;
-               for (int i = 0; i < num; i++) {
-                       if (this.drag && this.ypos >= this.ylim && i == this.pick)
-                               continue;
-
-                       Matrix.setIdentityM(this.model, 0);
-
-                       Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
-                       Matrix.translateM(this.model, 0, 0f, -0.3f, 1.20f);
-
-                       if (this.drag) {
-                               float pct = (float)(i+0.5) / num;
-                               float err = this.xpos - pct;
-                               float y   = (float)this.ypos / this.ylim;
-                               float lim = Math.min(Math.max(y,0),1);
-                               float fcn = 0.1f
-                                       * (float)Math.exp(-10*num*Math.pow(y*err,2))
-                                       * (1f-(float)Math.pow(1-lim, 2));
-                               Matrix.translateM(this.model, 0, 0, fcn, 0);
-                       }
-                       float left  = -20f + 20f*(1f/num);
-                       float right =  54f - 54f*(1f/num);
-                       float ang   = left + i*(right-left)/num;
-                       Matrix.rotateM(this.model, 0, ang, 0f, 0f, -1f);
-                       Matrix.translateM(this.model, 0, 0f, 0.15f, 0f);
-
-                       GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
-                       this.drawCard(this.hand[i]);
-               }
-
-               /* Draw selected card */
-               if (this.drag && this.ypos >= this.ylim) {
-                       Matrix.setIdentityM(this.model, 0);
-                       Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
-                       Matrix.translateM(this.model, 0, 0f, 0f, 1.20f);
-                       GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
-                       this.drawCard(this.hand[this.pick]);
-               }
+               this.drawPile();
+               this.drawHand();
+               this.drawPick();
        }
 
        @Override
@@ -304,7 +271,7 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
-               boolean up   = event.getActionMasked() == MotionEvent.ACTION_UP;
+               boolean up = event.getActionMasked() == MotionEvent.ACTION_UP;
 
                float x =    event.getX() / this.getWidth();
                float y = 1-(event.getY() / this.getHeight());
@@ -318,19 +285,19 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
                        if (this.pick >= num) this.pick = num-1;
                }
                if (y < this.ylim && !this.drag) {
-                       Os.debug("Cards: onTouchEvent - starting drag");
+                       //Os.debug("Cards: onTouchEvent - starting drag");
                        this.drag = true;
                }
                if (this.drag) {
-                       Os.debug("Cards: onTouchEvent - move "
-                                       + x + "," + y);
+                       //Os.debug("Cards: onTouchEvent - move " + x + "," + y);
                        this.requestRender();
                }
                if (y >= this.ylim && this.drag && up) {
-                       Os.debug("Cards: onTouchEvent - playing card");
+                       //Os.debug("Cards: onTouchEvent - playing card");
+                       this.game.onPlay(this.hand[this.pick]);
                }
                if (up) {
-                       Os.debug("Cards: onTouchEvent - ending drag");
+                       //Os.debug("Cards: onTouchEvent - ending drag");
                        this.drag = false;
                }
                return true;
@@ -349,7 +316,7 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
 
        private int loadTexture(String name)
        {
-               Os.debug("Cards: loadTexture - " + name);
+               //Os.debug("Cards: loadTexture - " + name);
 
                final int[] tex = new int[1];
 
@@ -363,14 +330,14 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
                }
 
                /* Load the bitmap */
-               Bitmap bitmap = BitmapFactory.decodeResource(this.res, id);
+               Bitmap bitmap = BitmapFactory.decodeResource(this.res, id, this.options);
 
                /* Copy into OpenGL */
                GLES20.glGenTextures(1, tex, 0);
                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
                GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
-               GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
-               GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
+               GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+               GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
 
                return tex[0];
        }
@@ -390,6 +357,10 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
        /* Private drawing methods */
        private void drawTable()
        {
+               /* Setup view */
+               Matrix.setIdentityM(this.model, 0);
+               GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
+
                /* Draw table */
                GLES20.glVertexAttribPointer(this.vertHandle, 3, GLES20.GL_FLOAT, false, 3*4, this.tableBuf);
                GLES20.glVertexAttribPointer(this.mapHandle,  2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);
@@ -397,12 +368,82 @@ public class Cards extends GLSurfaceView implements GLSurfaceView.Renderer
                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);
        }
 
+       private void drawPile()
+       {
+               /* Draw played cards */
+               for (int i = 0; i < 4; i++) {
+                       if (i >= this.pile.length || this.pile[i] == null)
+                               continue;
+
+                       float ang = i * 90f;
+
+                       Matrix.setIdentityM(this.model, 0);
+
+                       Matrix.rotateM(this.model, 0, -ang, 0f, 0f, 1f);
+                       Matrix.translateM(this.model, 0, -0.30f, 0f, 0f);
+                       Matrix.rotateM(this.model, 0,  ang, 0f, 0f, 1f);
+                       Matrix.scaleM(this.model, 0, 3f, 3f, 0f);
+
+                       this.drawCard(this.pile[i]);
+               }
+       }
+
+       private void drawHand()
+       {
+               /* Draw hand */
+               int num = this.hand.length;
+               for (int i = 0; i < num; i++) {
+                       if (this.drag && this.ypos >= this.ylim && i == this.pick)
+                               continue;
+
+                       Matrix.setIdentityM(this.model, 0);
+
+                       Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
+                       Matrix.translateM(this.model, 0, 0f, -0.3f, 1.20f);
+
+                       if (this.drag) {
+                               float pct = (float)(i+0.5) / num;
+                               float err = this.xpos - pct;
+                               float y   = (float)this.ypos / this.ylim;
+                               float lim = Math.min(Math.max(y,0),1);
+                               float fcn = 0.1f
+                                       * (float)Math.exp(-10*num*Math.pow(y*err,2))
+                                       * (1f-(float)Math.pow(1-lim, 2));
+                               Matrix.translateM(this.model, 0, 0, fcn, 0);
+                       }
+
+                       float left  = -20f + 20f*(1f/num);
+                       float right =  54f - 54f*(1f/num);
+                       float ang   = left + i*(right-left)/num;
+                       Matrix.rotateM(this.model, 0, ang, 0f, 0f, -1f);
+                       Matrix.translateM(this.model, 0, 0f, 0.15f, 0f);
+
+                       this.drawCard(this.hand[i]);
+               }
+       }
+
+       private void drawPick()
+       {
+               /* Draw selected card */
+               if (this.drag && this.ypos >= this.ylim) {
+                       Matrix.setIdentityM(this.model, 0);
+                       Matrix.rotateM(this.model, 0, 45f, 1f, 0f, 0f);
+                       Matrix.translateM(this.model, 0, 0f, 0f, 1.20f);
+                       this.drawCard(this.hand[this.pick]);
+               }
+       }
+
        private void drawCard(String name)
        {
+               if (!this.index.containsKey(name))
+                       return;
                int idx   = this.index.get(name);
                int front = this.face[idx];
                int back  = this.red;
 
+               /* Set model matrix */
+               GLES20.glUniformMatrix4fv(this.modelHandle, 1, false, this.model, 0);
+
                /* Draw front */
                GLES20.glVertexAttribPointer(this.vertHandle, 3, GLES20.GL_FLOAT, false, 3*4, this.faceBuf);
                GLES20.glVertexAttribPointer(this.mapHandle,  2, GLES20.GL_FLOAT, false, 2*4, this.mapBuf);