package electrosphere.engine; import static org.lwjgl.glfw.GLFW.glfwGetTime; import static org.lwjgl.glfw.GLFW.glfwTerminate; import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; import java.util.concurrent.TimeUnit; import electrosphere.audio.AudioEngine; import electrosphere.client.sim.ClientFunctions; import electrosphere.controls.ControlHandler; import electrosphere.engine.cli.CLIParser; import electrosphere.engine.loadingthreads.LoadingThread; import electrosphere.game.config.UserSettings; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.TerrainMessage; import electrosphere.net.parser.net.raw.NetworkParser; import electrosphere.net.parser.util.ByteStreamUtils; import electrosphere.renderer.Model; import electrosphere.renderer.RenderingEngine; import electrosphere.util.worldviewer.TerrainViewer; public class Main { // //Visualization Controls // //These are used in calculating the time between frames for visualization (camera) control and such static double deltaTime = 0.0f; static double lastFrame = 0.0f; static long frameCount = 0; public static float deltaFrames = 0; public static boolean running = true; //target amount of time per frame public static float targetFrameRate = 60.0f; static float targetFramePeriod = 1.0f/targetFrameRate; //framestep variable static int framestep = 2; public static void main(String args[]){ // // // I N I T I A L I Z A T I O N // // //parse command line arguments CLIParser.parseCLIArgs(args); startUp(); mainLoop(); } public static void startUp(){ //initialize logging interfaces LoggerInterface.initLoggers(); //load user settings UserSettings.loadUserSettings(); //controls if(Globals.RUN_CLIENT){ initControlHandler(); } //init global variables Globals.initGlobals(); // if(1==1){ // SaveUtils.loadSave("arena"); // Globals.authenticationManager = new AuthenticationManager(); // String rawPass = "testpassword"; // String hashedPassword = AuthenticationManager.getHashedString(rawPass); // boolean authed = Globals.authenticationManager.authenticate("testuser", hashedPassword); // System.out.println("Authenticated: " + authed); // System.exit(0); // } //world gen testing //gen terrain // Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0); // Globals.serverTerrainManager.load(); // Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager); // //gen world // Globals.macroData = MacroData.generateWorld(0); // Globals.macroData.describeWorld(); // boolean run = true; // Globals.macroSimulation = new MacroSimulation(); // while(run){ // Globals.macroSimulation.simulate(); // try { // TimeUnit.MILLISECONDS.sleep(1000); // } catch (InterruptedException ex) { // ex.printStackTrace(); // } // } // if(1==1){ // Globals.audioEngine = new AudioEngine(); // Globals.audioEngine.init(); // Globals.assetManager.addAudioPathToQueue("/Audio/MenuStartup.ogg"); // Globals.assetManager.loadAssetsInQueue(); // Globals.audioEngine.setGain(0.1f); // AudioSource startupSound = AudioUtils.playAudioAtLocation("/Audio/MenuStartup.ogg", new Vector3f(3,0,0)); // if(startupSound != null){ // while(startupSound.isPlaying()){ // try { // TimeUnit.MILLISECONDS.sleep(10); // } catch (InterruptedException ex) { // ex.printStackTrace(); // } // } // } // System.exit(0); // } //debug: create terrain/world viewer // TerrainViewer.runViewer(); //create the drawing context if(Globals.RUN_CLIENT && !Globals.HEADLESS){ Globals.renderingEngine = new RenderingEngine(); Globals.renderingEngine.createOpenglContext(); } //uncomment to test loading a model into engine // if(1==1){ // Globals.assetManager.addModelPathToQueue("/Models/tank1.fbx"); // Globals.assetManager.loadAssetsInQueue(); // Model model = Globals.assetManager.fetchModel("/Models/tank1.fbx"); // // for(electrosphere.renderer.anim.Animation anim : model.animations){ // // if(anim.name.equals("Armature|Idle1")){ // // System.out.println(anim.duration); // // for(electrosphere.renderer.anim.AnimChannel channel : anim.channels){ // // if(channel.getNodeID().equals("Torso")){ // // channel.fullDescribeChannel(); // // } // // // System.out.println("CHannel: " + channel.getNodeID()); // // } // // break; // // } // // } // model.animations.get(0).fullDescribeAnimation(); // // model.describeHighLevel(); // System.exit(0); // } //create the audio context if(Globals.RUN_CLIENT && !Globals.HEADLESS){ Globals.audioEngine = new AudioEngine(); Globals.audioEngine.init(); // Globals.audioEngine.setGain(0.1f); } //init default resources if(Globals.RUN_CLIENT && !Globals.HEADLESS){ Globals.initDefaultGraphicalResources(); Globals.initDefaultAudioResources(); } //fire off a loading thread for the title menus/screen LoggerInterface.loggerStartup.INFO("Fire off loading thread"); if(Globals.RUN_CLIENT){ LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_TITLE_MENU); Globals.loadingThreadsList.add(serverThread); serverThread.start(); } else { LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_ARENA); Globals.loadingThreadsList.add(clientThread); clientThread.start(); } //recapture the screen for rendering if(Globals.RUN_CLIENT && !Globals.HEADLESS){ LoggerInterface.loggerStartup.INFO("Recapture screen"); Globals.controlHandler.setShouldRecapture(true); } // RenderUtils.recaptureScreen(); } /** * Runs the main loop indefinitely. Blocks the thread this is called in. */ public static void mainLoop(){ mainLoop(0); } /** * Runs the main loop for a specified number of frames. * @param maxFrames The number of frames to run for. If 0, will run indefinitely. */ public static void mainLoop(long maxFrames){ //main loop while (running) { /* Frame calculation */ double currentTime = glfwGetTime(); deltaTime = currentTime - lastFrame; deltaFrames = targetFrameRate * (float)deltaTime; lastFrame = currentTime; /// /// A S S E T M A N A G E R S T U F F /// if(Globals.RUN_CLIENT){ Globals.assetManager.loadAssetsInQueue(); } /// /// C L I E N T N E T W O R K I N G S T U F F /// //Why is this its own function? Just to get the networking code out of main() if(Globals.RUN_CLIENT && Globals.clientConnection != null){ Globals.clientConnection.parseMessages(); } //handle framestep if(framestep == 1){ framestep = 0; } /// /// I N P U T C O N T R O L S /// //Poll controls if(Globals.RUN_CLIENT){ Globals.controlHandler.pollControls(); Globals.controlHandler.recaptureIfNecessary(); } /// /// C L I E N T S I M U L A T I O N S T U F F /// if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){ ClientFunctions.runBeforeSimulationFunctions(); } if(Globals.clientSimulation != null && Globals.clientSimulation.isLoadingTerrain() && framestep > 0){ ClientFunctions.loadTerrain(); } if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){ Globals.clientSimulation.simulate(); } if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){ ClientFunctions.runClientFunctions(); } /// /// S E R V E R M I C R O S I M U L A T I O N /// if(Globals.realmManager != null){ Globals.realmManager.simulate(); } /// /// M A C R O S I M U L A T I O N S T U F F /// if(Globals.macroSimulation != null && Globals.macroSimulation.isReady() && framestep > 0){ Globals.macroSimulation.simulate(); } if(Globals.RUN_CLIENT && !Globals.HEADLESS){ Globals.renderingEngine.drawScreen(); } if(Globals.ENGINE_SHUTDOWN_FLAG || (!Globals.HEADLESS && Globals.RUN_CLIENT && glfwWindowShouldClose(Globals.window))){ running = false; } if(deltaTime < targetFramePeriod){ sleep((int)(1000.0 * (targetFramePeriod - deltaTime))); } else { sleep(1); } frameCount++; if(maxFrames > 0 && frameCount > maxFrames){ running = false; } } // // S H U T D O W N // //Terminate the program. if(!Globals.HEADLESS && Globals.RUN_CLIENT){ glfwTerminate(); } //used to signal threads to stop running = false; if(Globals.server != null){ Globals.server.close(); Globals.serverThread.interrupt(); } //shut down audio engine if(!Globals.HEADLESS && Globals.RUN_CLIENT){ Globals.audioEngine.shutdown(); } //if netmonitor is running, close if(Globals.netMonitor != null){ Globals.netMonitor.close(); } } public static long getCurrentFrame(){ return frameCount; } static void sleep(int i) { try { TimeUnit.MILLISECONDS.sleep(i); } catch (InterruptedException ex) { System.out.println("Sleep somehow interrupted?!"); } } public static boolean isRunning(){ return running; } public static void initControlHandler(){ LoggerInterface.loggerStartup.INFO("Initialize control handler"); Globals.controlHandler = ControlHandler.generateExampleControlsMap(); Globals.controlHandler.setCallbacks(); // Globals.controlHandler = FileLoadingUtils.loadModelObjectFromBakedJsonFile("/Config/keybinds.json",ControlHandler.class); } /** * Sets the framestep state (2 to resume automatic, 1 to make single step) * @param framestep 2 - automatic framestep, 1 - single step, 0 - no step */ public static void setFramestep(int framestep){ Main.framestep = framestep; } // public static void updateMouseVariables(){ // glfwGetCursorPos(Globals.window, mouse_X_Buffer, mouse_Y_Buffer); // xpos = mouse_X_Buffer[0]; // ypos = mouse_Y_Buffer[0]; // float xoffset = (float) (xpos - mouse_lastX) * mouseSensitivity; // float yoffset = (float) (mouse_lastY - ypos) * mouseSensitivity; // mouse_lastX = (float) xpos; // mouse_lastY = (float) ypos; // if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){ // yaw = yaw + xoffset; // pitch = pitch - yoffset; // if (pitch > 100.0f) { // pitch = 100.0f; // } // if (pitch < -99.0f) { // pitch = -99.0f; // } // } // } }