com.gameminers.mav.Mav.java Source code

Java tutorial

Introduction

Here is the source code for com.gameminers.mav.Mav.java

Source

/*
 * This file is part of Mav.
 *
 * Mav is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * Mav is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with Mav. If not, see <http://www.gnu.org/licenses/>.
 */
package com.gameminers.mav;

import java.io.File;
import java.util.BitSet;

import javax.swing.UIManager;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color;

import com.gameminers.mav.audio.AudioManager;
import com.gameminers.mav.firstrun.EnterNameScreen;
import com.gameminers.mav.personality.Personality;
import com.gameminers.mav.personality.poly.PolygonPersonality;
import com.gameminers.mav.render.Fonts;
import com.gameminers.mav.render.IconRenderer;
import com.gameminers.mav.render.PersonalityRenderer;
import com.gameminers.mav.render.RenderState;
import com.gameminers.mav.render.Rendering;
import com.gameminers.mav.screen.MainScreen;
import com.gameminers.mav.screen.Screen;
import com.gameminers.mav.tts.TTSInterface;
import com.gameminers.mav.tts.mary.MaryTTSInterface;

public class Mav {
    public static final File configDir = new File(System.getProperty("user.home"), ".mav");

    public static final int TARGET_FPS = 30;
    public static final float FADE_TIME = 30;

    private static int frameCounter = 0;
    private static int fps = 0;
    private static long nspf = 0;
    private static long frameTime = 0;
    private static long lastFPSUpdate = System.currentTimeMillis();

    public static Screen currentScreen = new MainScreen();
    private static boolean run = true;
    private static boolean render = true;

    public static final PersonalityRenderer personalityRenderer = new PersonalityRenderer();
    public static final AudioManager audioManager = new AudioManager();
    public static final IconRenderer iconRenderer = new IconRenderer();

    public static Personality personality = new PolygonPersonality(3);

    public static long totalFrameCounter = 0;
    private static int fadeFrames = 0;
    private static int stopFrames = 0;

    private static int goodbye;

    public static String userName;
    public static String phoneticUserName;

    public static VoiceThread voiceThread;
    public static TTSInterface ttsInterface;

    private static BitSet mouseButtonStates;

    public static int silentFrames = 0;
    public static int silentListenFrames = 0;

    public static long lastInputEvent = System.currentTimeMillis();

    public static boolean listening = false;

    public static void stop() {
        if (!run)
            return;
        RenderState.targetSat = 0;
        RenderState.targetDim = 0.3f;
        RenderState.setText("\u00A7LGoodbye.");
        RenderState.idle = false;
        RenderState.attention = true;
        currentScreen = null;
        if (personality instanceof PolygonPersonality) {
            ((PolygonPersonality) personality).calm();
            ((PolygonPersonality) personality).targetPulse = 0.075f;
        }
        if (ttsInterface != null) {
            ttsInterface.sayPreparedSentence(goodbye);
        }
        if (voiceThread != null) {
            voiceThread.interrupt();
        }
        iconRenderer.finish();
        run = false;
    }

    public static void main(String[] args) {
        Thread.currentThread().setName("Init thread");
        configDir.mkdirs();
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception ex) {
            }
        }
        try {
            Rendering.setUpDisplay();
        } catch (Throwable t) {
            Dialogs.showErrorDialog(null, "An error occurred while initializing LWJGL. Mav will now exit.", t);
        }
        try {
            Fonts.loadFonts();
            for (int i = 0; i < FADE_TIME + 10; i++) {
                drawBasicScreen("Getting ready", 1.0f - (i / FADE_TIME));
                Display.sync(TARGET_FPS);
            }
            drawBasicScreen("Initializing MARY", 0.0f);
            ttsInterface = new MaryTTSInterface();
            goodbye = ttsInterface.prepare("Goodbye.");
            drawBasicScreen("Setting up audio", 0.0f);
            audioManager.init();
            drawBasicScreen("Setting up input", 0.0f);
            initMouse();
            Keyboard.enableRepeatEvents(true);
        } catch (Throwable t) {
            Dialogs.showErrorDialog(null, "An error occurred while setting up the UI. Mav will now exit.", t);
            return;
        }
        try {
            Thread.currentThread().setName("Render thread");
            iconRenderer.start();
            Rendering.setUpGL();
            RenderState.setText(
                    "\u00A7LHi! I'm Mav.\nI don't know who you are,\nso let's fix that.\n\nFirst off, what's your name?\n\u00A7sClick inside the box to start typing.\n\u00A7sPress Enter when you're finished.");
            currentScreen = new EnterNameScreen(false);
            ttsInterface.sayWithEmotion(
                    "<emotionml version='1.0' xmlns='http://www.w3.org/2009/10/emotionml' category-set='http://www.w3.org/TR/emotion-voc/xml#everyday-categories'><emotion><category name='happy'/>Hi! I'm Mav.</emotion>I dont know who you are, so let's fix that.<emotion><category name='interested'/>First off, what is your name?</emotion></emotionml>",
                    "Hi! I'm Mav. I dont know who you are, so let's fix that. First off, what is your name?");
            /*voiceThread = new VoiceThread();
            voiceThread.start();*/
            while (render) {
                long start = System.nanoTime();
                Rendering.beforeFrame(Display.getWidth(), Display.getHeight());
                RenderState.update();
                processInput();
                doRender();
                long time = System.nanoTime() - start;
                totalFrameCounter++;
                frameCounter++;
                frameTime += time;
                if (System.currentTimeMillis() - lastFPSUpdate >= 1000) {
                    fps = frameCounter;
                    nspf = frameTime / frameCounter;
                    frameTime = 0;
                    frameCounter = 0;
                    lastFPSUpdate = System.currentTimeMillis();
                }
                Display.update();
                Display.sync(TARGET_FPS);
                if (Display.isCloseRequested()) {
                    stop();
                }
                if (!run) {
                    stopFrames++;
                    if (stopFrames >= 40) {
                        fadeFrames++;
                        if (fadeFrames >= FADE_TIME + 10) {
                            audioManager.destroy();
                            render = false;
                        }
                    }
                }
            }
        } catch (Throwable t) {
            Dialogs.showErrorDialog(null, "An uncaught exception was thrown in the render loop. Mav will now exit.",
                    t);
            audioManager.destroy();
        }
    }

    public static void initMouse() {
        mouseButtonStates = new BitSet(Mouse.getButtonCount());
    }

    private static void processInput() {
        while (Keyboard.next()) {
            if (Keyboard.getEventKeyState()) {
                if (currentScreen != null) {
                    currentScreen.keyDown(Keyboard.getEventKey(), Keyboard.getEventCharacter(),
                            Keyboard.getEventNanoseconds());
                }
            } else {
                if (currentScreen != null) {
                    currentScreen.keyUp(Keyboard.getEventKey(), Keyboard.getEventCharacter(),
                            Keyboard.getEventNanoseconds());
                }
            }
            inputReceived();
        }
        while (Mouse.next()) {
            if (Mouse.getEventButton() != -1
                    && Mouse.getEventButtonState() != mouseButtonStates.get(Mouse.getEventButton())) {
                mouseButtonStates.set(Mouse.getEventButton(), Mouse.getEventButtonState());
                if (Mouse.getEventButtonState()) {
                    if (currentScreen != null) {
                        currentScreen.mouseDown(Mouse.getEventX(), Display.getHeight() - Mouse.getEventY(),
                                Mouse.getEventButton(), Mouse.getEventNanoseconds());
                    }
                } else {
                    if (currentScreen != null) {
                        currentScreen.mouseUp(Mouse.getEventX(), Display.getHeight() - Mouse.getEventY(),
                                Mouse.getEventButton(), Mouse.getEventNanoseconds());
                    }
                }
            } else {
                if (currentScreen != null) {
                    currentScreen.mouseMove(Mouse.getEventX(), Display.getHeight() - Mouse.getEventY(),
                            Mouse.getEventNanoseconds());
                }
            }
            if (Mouse.getEventDWheel() != 0) {
                if (currentScreen != null) {
                    currentScreen.mouseWheel(Mouse.getEventX(), Display.getHeight() - Mouse.getEventY(),
                            Mouse.getEventDWheel(), Mouse.getEventNanoseconds());
                }
            }
            inputReceived();
        }
    }

    private static void inputReceived() {
        lastInputEvent = System.currentTimeMillis();
    }

    private static void drawBasicScreen(String s, float dim) {
        Rendering.setUpGL();
        Rendering.beforeFrame(Display.getWidth(), Display.getHeight());
        GL11.glClearColor(0, 0, 0, 1);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
        Fonts.light[2].drawString((Display.getWidth() / 2) - (Fonts.light[2].getWidth(s) / 2), 160, s, Color.white);
        Rendering.drawTriangle(Display.getWidth() / 2f, 90, 74, 0.5f, 0.5f, 0.5f, 0.5f, 0);
        Rendering.drawTriangle(Display.getWidth() / 2f, 90, 64, 0.5f, 0.5f, 0.5f, 1, 0.5f);
        Rendering.drawTriangle(Display.getWidth() / 2f, 90, 56, 0, 0, 0, 1, 1f);
        Rendering.drawRectangle(0, 0, Display.getWidth(), Display.getHeight(), 0, 0, 0, dim, 1);
        Display.update();
    }

    private static void doRender() {
        GL11.glPushMatrix();
        if (audioManager.getSink().getLevel() <= 8) {
            if (silentFrames == 0 && personality instanceof PolygonPersonality) {
                ((PolygonPersonality) personality).calm();
            }
            silentFrames++;
        } else {
            silentFrames = 0;
        }
        if (silentFrames < 10) {
            RenderState.idle = false;
            if (personality instanceof PolygonPersonality) {
                ((PolygonPersonality) personality).targetPulse = (audioManager.getSink().getLevel() / 64f);
            }
        } else {
            RenderState.idle = true;
        }

        if (listening) {
            if (audioManager.getSource().getLevel() <= 8) {
                silentListenFrames++;
            } else {
                silentListenFrames = 0;
            }
            if (silentListenFrames < 10) {
                RenderState.idle = false;
                if (personality instanceof PolygonPersonality) {
                    ((PolygonPersonality) personality).targetInnerPulse = (audioManager.getSource().getLevel()
                            / 64f);
                }
            }
        }
        personalityRenderer.render();
        if (currentScreen != null && personality.renderScreen()) {
            GL11.glPushMatrix();
            currentScreen.render();
            GL11.glPopMatrix();
        }
        personality.postRender();
        String size = Display.getWidth() + "x" + Display.getHeight();
        Fonts.base[0].drawString((Display.getWidth() - Fonts.base[0].getWidth(size)) - 8, 8, size);
        Fonts.base[0].drawString(8, 8, fps + " FPS");
        Fonts.base[0].drawString(8, 24, (nspf / 1000000f) + " ms/f");
        Fonts.base[0].drawString(8, 40,
                (((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024) / 1024f)
                        + "MiB");
        if (personality instanceof PolygonPersonality) {
            Fonts.base[0].drawString(8, 56, ((PolygonPersonality) personality).angle + "");
        }
        Rendering.drawRectangle(0, 0, Display.getWidth(), Display.getHeight(), 0, 0, 0, (fadeFrames / FADE_TIME),
                1);
        GL11.glPopMatrix();
    }

}