Exemplo n.º 1
0
  private final class CanvasThread extends Thread {

    final LTimerContext timerContext = new LTimerContext();

    final SystemTimer timer = LSystem.getSystemTimer();

    private long lastTimeMicros,
        currTimeMicros,
        goalTimeMicros,
        elapsedTimeMicros,
        remainderMicros,
        elapsedTime,
        frameCount,
        frames;

    public CanvasThread() {
      isRunning = true;
      setName("CanvasThread");
    }

    synchronized void updateCapture(final Bitmap bit) {
      if (!handler.next()) {
        return;
      }
      handler.calls();

      handler.runTimer(timerContext);

      if (LSystem.AUTO_REPAINT) {
        canvas = surfaceHolder.lockCanvas(null);
        if (canvas == null) {
          return;
        }
        synchronized (surfaceHolder) {
          gl.update(bit);
          repaintMode = handler.getRepaintMode();
          switch (repaintMode) {
            case Screen.SCREEN_BITMAP_REPAINT:
              gl.drawBitmap(handler.getBackground(), 0, 0);
              break;
            case Screen.SCREEN_CANVAS_REPAINT:
              gl.drawClear();
              break;
            case Screen.SCREEN_NOT_REPAINT:
              break;
            default:
              gl.drawBitmap(
                  handler.getBackground(),
                  repaintMode / 2 - LSystem.random.nextInt(repaintMode),
                  repaintMode / 2 - LSystem.random.nextInt(repaintMode));
              break;
          }

          handler.draw(gl);

          if (isFPS) {
            tickFrames();
            gl.setFont(fpsFont);
            gl.setColor(LColor.white);
            gl.drawString("FPS:" + curFPS, 5, 20);
          }

          if (isMemory) {
            Runtime runtime = Runtime.getRuntime();
            long totalMemory = runtime.totalMemory();
            long currentMemory = totalMemory - runtime.freeMemory();

            String memory =
                ((float) ((currentMemory * 10) >> 20) / 10)
                    + " of "
                    + ((float) ((totalMemory * 10) >> 20) / 10)
                    + " MB";

            gl.setFont(fpsFont);
            gl.setColor(LColor.white);
            gl.drawString("MEMORY:" + memory, 5, 45);
          }
          if (emulatorButtons != null) {
            emulatorButtons.draw(gl);
          }
        }
        surfaceHolder.unlockCanvasAndPost(canvas);
      }
    }

    /** 游戏窗体主循环 */
    public void run() {

      boolean isScale = handler.isScale();

      Thread currentThread = Thread.currentThread();
      int restoreCount = 0;
      try {
        do {
          if (LSystem.isPaused || !isFocusable()) {
            pause(500);
            lastTimeMicros = timer.getTimeMicros();
            elapsedTime = 0;
            remainderMicros = 0;
            continue;
          }
          if (!handler.next()) {
            continue;
          }
          handler.calls();

          goalTimeMicros = lastTimeMicros + 1000000L / maxFrames;
          currTimeMicros = timer.sleepTimeMicros(goalTimeMicros);
          elapsedTimeMicros = currTimeMicros - lastTimeMicros + remainderMicros;
          elapsedTime = Math.max(0, (int) (elapsedTimeMicros / 1000));
          remainderMicros = elapsedTimeMicros - elapsedTime * 1000;
          lastTimeMicros = currTimeMicros;
          timerContext.millisSleepTime = remainderMicros;
          timerContext.timeSinceLastUpdate = elapsedTime;

          handler.runTimer(timerContext);

          if (LSystem.AUTO_REPAINT) {
            canvas = surfaceHolder.lockCanvas(null);
            if (canvas == null) {
              continue;
            }
            synchronized (surfaceHolder) {
              if (isScale) {

                canvas.setDrawFilter(zoomFilter);
                canvas.scale(LSystem.scaleWidth, LSystem.scaleHeight);
                restoreCount = canvas.save();
              }
              gl.update(canvas);

              repaintMode = handler.getRepaintMode();
              switch (repaintMode) {
                case Screen.SCREEN_BITMAP_REPAINT:
                  if (handler.getX() == 0 && handler.getY() == 0) {
                    gl.drawBitmap(handler.getBackground(), 0, 0);
                  } else {
                    gl.drawClear();
                    gl.drawBitmap(handler.getBackground(), handler.getX(), handler.getY());
                  }
                  break;
                case Screen.SCREEN_CANVAS_REPAINT:
                  gl.drawClear();
                  break;
                case Screen.SCREEN_NOT_REPAINT:
                  break;
                default:
                  if (handler.getX() == 0 && handler.getY() == 0) {
                    gl.drawBitmap(
                        handler.getBackground(),
                        repaintMode / 2 - LSystem.random.nextInt(repaintMode),
                        repaintMode / 2 - LSystem.random.nextInt(repaintMode));
                  } else {
                    gl.drawClear();
                    gl.drawBitmap(
                        handler.getBackground(),
                        handler.getX() + repaintMode / 2 - LSystem.random.nextInt(repaintMode),
                        handler.getY() + repaintMode / 2 - LSystem.random.nextInt(repaintMode));
                  }
                  break;
              }

              handler.draw(gl);

              if (isFPS) {
                tickFrames();
                gl.setFont(fpsFont);
                gl.setColor(LColor.white);
                gl.drawString("FPS:" + curFPS, 5, 20);
              }

              if (isMemory) {
                Runtime runtime = Runtime.getRuntime();
                long totalMemory = runtime.totalMemory();
                long currentMemory = totalMemory - runtime.freeMemory();

                String memory =
                    ((float) ((currentMemory * 10) >> 20) / 10)
                        + " of "
                        + ((float) ((totalMemory * 10) >> 20) / 10)
                        + " MB";

                gl.setFont(fpsFont);
                gl.setColor(LColor.white);
                gl.drawString("MEMORY:" + memory, 5, 45);
              }
              if (emulatorButtons != null) {
                emulatorButtons.draw(gl);
              }
              if (isScale) {
                canvas.restoreToCount(restoreCount);
              }
            }
            surfaceHolder.unlockCanvasAndPost(canvas);
          }

        } while (isRunning && mainLoop == currentThread);
      } catch (Exception ex) {
        Log.d("Android2DView", "LGame 2D View Error :", ex);
      } finally {
        destroyView();
      }
    }

    private final void pause(long sleep) {
      try {
        Thread.sleep(sleep);
      } catch (InterruptedException ex) {
      }
    }

    private void tickFrames() {
      long time = System.currentTimeMillis();
      if (time - frameCount > 1000L) {
        curFPS = Math.min(maxFrames, frames);
        frames = 0;
        frameCount = time;
      }
      frames++;
    }
  }