diff options
author | Sven Gothel <[email protected]> | 2013-06-28 19:06:14 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-06-28 19:06:14 +0200 |
commit | 54bbd1a726e73841f0bd4cc79e5b12e83a88ba18 (patch) | |
tree | 6e71430ad8217e1fce810b5310ec0b5b2766340c /src/jake2 | |
parent | 28ed823b1a804145b4dd741807a83570abc139e1 (diff) |
Add Applet Feature incl. required fixes.
- Jake2Applet
- Reenable JavaScript Bridge to resize Applet
- Pass through 4:3 aspect custom video mode (Jake2 args)
- Pass through applet parameter 'jake_args' (Jake2 args)
- OSX Hack: Re-create Game at init, otherwise flickering appears (??)
- Fix VID.init: Set vid_ref.modifier = true, otherwise not guaranteed VID creation
- BeginFrame, R_BeginFrame, beginFrame, activateGLContext:
Return 'true', if ctx is available, otherwise false to skip frame.
- NEWTWin:
- Applet mode (in Applet container): Always release GL ctx
- Use GLAnimatorControl impl, to state whether we are animating or not
and to tell us, whether we have to release the GL ctx.
- Add HOME -> Reparent feature for Applets
- Workaround for NEWT/Windows Bug 798
- NEWT Key Handling:
- Ignore auto-repeat
- Workaround for NEWT/Windows Bug 798
- Add HTML page
- normal
- debug mode
Diffstat (limited to 'src/jake2')
-rwxr-xr-x | src/jake2/Jake2Applet.java | 208 | ||||
-rw-r--r-- | src/jake2/client/SCR.java | 153 | ||||
-rw-r--r-- | src/jake2/client/VID.java | 3 | ||||
-rw-r--r-- | src/jake2/client/refexport_t.java | 2 | ||||
-rw-r--r-- | src/jake2/render/DummyRenderer.java | 3 | ||||
-rw-r--r-- | src/jake2/render/JoglDummyRenderer.java | 22 | ||||
-rw-r--r-- | src/jake2/render/JoglES1Renderer.java | 22 | ||||
-rw-r--r-- | src/jake2/render/JoglES2Renderer.java | 22 | ||||
-rw-r--r-- | src/jake2/render/JoglGL2Renderer.java | 22 | ||||
-rw-r--r-- | src/jake2/render/RenderAPI.java | 2 | ||||
-rw-r--r-- | src/jake2/render/basic/Main.java | 9 | ||||
-rw-r--r-- | src/jake2/render/fast/Main.java | 118 | ||||
-rw-r--r-- | src/jake2/render/opengl/GLDriver.java | 3 | ||||
-rw-r--r-- | src/jake2/render/opengl/JoglDummyDriver.java | 11 | ||||
-rw-r--r-- | src/jake2/render/opengl/JoglES1Driver.java | 11 | ||||
-rw-r--r-- | src/jake2/render/opengl/JoglES2Driver.java | 10 | ||||
-rw-r--r-- | src/jake2/render/opengl/JoglGL2Driver.java | 12 | ||||
-rw-r--r-- | src/jake2/render/opengl/NEWTWin.java | 368 | ||||
-rw-r--r-- | src/jake2/sys/InputListener.java | 18 | ||||
-rw-r--r-- | src/jake2/sys/NEWTKBD.java | 4 | ||||
-rw-r--r-- | src/jake2/sys/Sys.java | 2 |
21 files changed, 695 insertions, 330 deletions
diff --git a/src/jake2/Jake2Applet.java b/src/jake2/Jake2Applet.java index 91ce077..e444ebc 100755 --- a/src/jake2/Jake2Applet.java +++ b/src/jake2/Jake2Applet.java @@ -29,107 +29,185 @@ import jake2.game.Cmd; import jake2.qcommon.*; import jake2.sys.Timer; -import java.awt.BorderLayout; -import java.awt.Color; +import java.applet.Applet; +import java.awt.*; +import java.util.StringTokenizer; -import javax.swing.JApplet; +import com.jogamp.common.os.Platform; -// import netscape.javascript.*; +import netscape.javascript.*; /** * Jake2 is the main class of Quake2 for Java. */ @SuppressWarnings("serial") -public class Jake2Applet extends JApplet { +public class Jake2Applet extends Applet { - // FIXME private JSObject self; - private volatile boolean shouldShutDown; - private boolean shutDown; - private Object shutDownLock = new Object(); + private JSObject self; + private volatile boolean gameShouldShutDown; + private volatile boolean gameShutDown; + private volatile boolean gameStarted; + private Object gameLifecycleLock = new Object(); + + private static String sz0_args = " +set gl_mode 11 +set vid_width "; + private static String sz1_args = " +set vid_height "; + @Override public void init() { - // Before Jake2 is fully initialized, make the applet black - // like the rest of the web page - setBackground(Color.BLACK); + System.err.println("Jake2 Applet Init: "+Thread.currentThread().getName()); + setBackground(new Color(0x33, 0x33, 0x33, 0xff)); // web page + setLayout(new java.awt.BorderLayout()); } + @Override public void start() { - setLayout(new BorderLayout()); - new GameThread().start(); + System.err.println("Jake2 Applet Start.0: "+Thread.currentThread().getName()); + synchronized(gameLifecycleLock) { + gameShouldShutDown = false; + gameShutDown = false; + gameStarted = false; + } + if( EventQueue.isDispatchThread() ) { // Game thread offloads to AWT-EDT in Applet mode + new GameThread().start(); + } else { + synchronized(gameLifecycleLock) { + new GameThread().start(); + while (!gameStarted) { + try { + gameLifecycleLock.wait(); + } catch (InterruptedException e) { + } + } + } + } + System.err.println("Jake2 Applet Start.X: "+Thread.currentThread().getName()); } + @Override public void stop() { - synchronized(shutDownLock) { - shouldShutDown = true; - while (!shutDown) { + System.err.println("Jake2 Applet Stop.0: "+Thread.currentThread().getName()); + synchronized(gameLifecycleLock) { + gameShouldShutDown = true; + while (!gameShutDown) { try { - shutDownLock.wait(); + gameLifecycleLock.wait(); } catch (InterruptedException e) { } } } - Cmd.ExecuteString("quit"); + System.err.println("Jake2 Applet Stop.X: "+Thread.currentThread().getName()); } - + + @Override + public void destroy() { + System.err.println("Jake2 Applet Destroy.0: "+Thread.currentThread().getName()); + } + class GameThread extends Thread { public GameThread() { super("Jake2 Game Thread"); } public void run() { - // TODO: check if dedicated is set in config file - - Globals.dedicated= Cvar.Get("dedicated", "0", Qcommon.CVAR_NOSET); - - // Set things up for applet execution - Qcommon.appletMode = true; - Qcommon.applet = Jake2Applet.this; - Qcommon.sizeChangeListener = new SizeChangeListener() { - public void sizeChanged(int width, int height) { - /** FIXME - try { - if (self == null) { - JSObject win = JSObject.getWindow(Jake2Applet.this); - self = (JSObject) win.eval("document.getElementById(\"" + - getParameter("id") + "\")"); + synchronized(gameLifecycleLock) { + // TODO: check if dedicated is set in config file + + System.err.println("Jake2 Applet Game START: "+Thread.currentThread().getName()); + + Globals.dedicated= Cvar.Get("dedicated", "0", Qcommon.CVAR_NOSET); + + // Set things up for applet execution + Globals.appletMode = true; + Globals.applet = Jake2Applet.this; + Globals.sizeChangeListener = new SizeChangeListener() { + public void sizeChanged(int width, int height) { + try { + if (self == null) { + JSObject win = JSObject.getWindow(Jake2Applet.this); + self = (JSObject) win.eval("document.getElementById(\"" + + getParameter("id") + "\")"); + } + self.setMember("width", new Integer(width)); + self.setMember("height", new Integer(height)); + } catch (Exception e) { + e.printStackTrace(); } - - self.setMember("width", new Integer(width)); - self.setMember("height", new Integer(height)); - } catch (Exception e) { - e.printStackTrace(); - } */ + } + }; + + // open the q2dialog, if we are not in dedicated mode. + if (Globals.dedicated.value != 1.0f) { + Jake2.initQ2DataTool(); + } + + final int a_width = Jake2Applet.this.getWidth(); + final int a_height = (int) ( a_width * 0.75f ); + + final String cmd_args; + { + final String applet_args = getParameter("jake_args"); + StringBuffer sb = new StringBuffer(); + sb.append("Jake2 "); + if( null != applet_args && applet_args.length() > 0 ) { + sb.append(applet_args); } - }; - - // open the q2dialog, if we are not in dedicated mode. - if (Globals.dedicated.value != 1.0f) { - Jake2.initQ2DataTool(); + sb.append(sz0_args); + sb.append(a_width); + sb.append(sz1_args); + sb.append(a_height); + cmd_args = sb.toString(); + } + System.err.println("Jake2 Applet Cmd: "+cmd_args); + final String[] c_args; + StringTokenizer tokens = new StringTokenizer(cmd_args); + final int argc = tokens.countTokens(); + c_args = new String[argc]; + int i=0; + while( tokens.hasMoreTokens() ) { + c_args[i++] = tokens.nextToken().trim(); + } + + Qcommon.Init(c_args); + if( Platform.OSType.MACOS == Platform.getOSType() ) { + // FIXME: Bug on OSX: 1st NewtCanvasAWT added .. causes flickering, so 'do it again'. + // Interesting that our JOGLNewtApplet1Run does not suffer from this behavior! + Cmd.ExecuteString("quit"); + Qcommon.Init(c_args); + } + Globals.nostdout = Cvar.Get("nostdout", "0", 0); + + gameStarted = true; + gameLifecycleLock.notifyAll(); } - Qcommon.Init(new String[] { "Jake2" }); - - Globals.nostdout = Cvar.Get("nostdout", "0", 0); - try { - while (!shouldShutDown) { - int oldtime = Timer.Milliseconds(); - int newtime; - int time; - while (true) { - // find time spending rendering last frame - newtime = Timer.Milliseconds(); - time = newtime - oldtime; - - if (time > 0) - Qcommon.Frame(time); - oldtime = newtime; + int oldtime = Timer.Milliseconds(); + while (!gameShouldShutDown) { + // find time spending rendering last frame + final int newtime = Timer.Milliseconds(); + final int time = newtime - oldtime; + + if (time > 0) { + Qcommon.Frame(time); } + oldtime = newtime; } + } catch(Throwable t) { + System.err.println("Jake2 Applet Game Exception: "+t.getClass().getName()+": "+t.getMessage()); + t.printStackTrace(); } finally { - synchronized(shutDownLock) { - shutDown = true; - shutDownLock.notifyAll(); + synchronized(gameLifecycleLock) { + System.err.println("Jake2 Applet Game STOP.0: "+Thread.currentThread().getName()); + try { + Cmd.ExecuteString("quit"); + } catch (Exception e) { + System.err.println("Jake2 Applet Game STOP Catched:"); + e.printStackTrace(); + } + gameShutDown = true; + gameStarted = false; + gameLifecycleLock.notifyAll(); + System.err.println("Jake2 Applet Game STOP.X: "+Thread.currentThread().getName()); } } } diff --git a/src/jake2/client/SCR.java b/src/jake2/client/SCR.java index 50cd74c..937b293 100644 --- a/src/jake2/client/SCR.java +++ b/src/jake2/client/SCR.java @@ -286,10 +286,9 @@ public final class SCR extends Globals { int x, y; int remaining; - if (cs == null) - return; - if (cs.length() == 0) + if (cs.length() == 0) { return; + } // the finale prints the characters one at a time remaining = 9999; @@ -621,19 +620,21 @@ public final class SCR extends Globals { start = Timer.Milliseconds(); if (Cmd.Argc() == 2) { // run without page flipping - re.BeginFrame(0); - for (i = 0; i < 128; i++) { - cl.refdef.viewangles[1] = i / 128.0f * 360.0f; - re.RenderFrame(cl.refdef); + if ( re.BeginFrame(0) ) { + for (i = 0; i < 128; i++) { + cl.refdef.viewangles[1] = i / 128.0f * 360.0f; + re.RenderFrame(cl.refdef); + } + re.EndFrame(); } - re.EndFrame(); } else { for (i = 0; i < 128; i++) { cl.refdef.viewangles[1] = i / 128.0f * 360.0f; - re.BeginFrame(0); - re.RenderFrame(cl.refdef); - re.EndFrame(); + if( re.BeginFrame(0) ) { + re.RenderFrame(cl.refdef); + re.EndFrame(); + } } } @@ -1206,79 +1207,85 @@ public final class SCR extends Globals { numframes = 1; } + boolean frameRendered = false; + for (i = 0; i < numframes; i++) { - re.BeginFrame(separation[i]); - - if (scr_draw_loading == 2) { // loading plaque over black screen - Dimension dim = new Dimension(); - - re.CinematicSetPalette(null); - scr_draw_loading = 0; // false - re.DrawGetPicSize(dim, "loading"); - re.DrawPic((viddef.getWidth() - dim.getWidth()) / 2, - (viddef.getHeight() - dim.getHeight()) / 2, "loading"); - } - // if a cinematic is supposed to be running, handle menus - // and console specially - else if (cl.cinematictime > 0) { - if (cls.key_dest == key_menu) { - if (cl.cinematicpalette_active) { - re.CinematicSetPalette(null); - cl.cinematicpalette_active = false; + if ( re.BeginFrame(separation[i]) ) { + frameRendered = true; + + if (scr_draw_loading == 2) { // loading plaque over black screen + Dimension dim = new Dimension(); + + re.CinematicSetPalette(null); + scr_draw_loading = 0; // false + re.DrawGetPicSize(dim, "loading"); + re.DrawPic((viddef.getWidth() - dim.getWidth()) / 2, + (viddef.getHeight() - dim.getHeight()) / 2, "loading"); + } + // if a cinematic is supposed to be running, handle menus + // and console specially + else if (cl.cinematictime > 0) { + if (cls.key_dest == key_menu) { + if (cl.cinematicpalette_active) { + re.CinematicSetPalette(null); + cl.cinematicpalette_active = false; + } + Menu.Draw(); + } else if (cls.key_dest == key_console) { + if (cl.cinematicpalette_active) { + re.CinematicSetPalette(null); + cl.cinematicpalette_active = false; + } + DrawConsole(); + } else { + // TODO implement cinematics completely + DrawCinematic(); } - Menu.Draw(); - } else if (cls.key_dest == key_console) { + } else { + // make sure the game palette is active if (cl.cinematicpalette_active) { re.CinematicSetPalette(null); cl.cinematicpalette_active = false; } + + // do 3D refresh drawing, and then update the screen + CalcVrect(); + + // clear any dirty part of the background + TileClear(); + + V.RenderView(separation[i]); + + DrawStats(); + + if ((cl.frame.playerstate.stats[STAT_LAYOUTS] & 1) != 0) + DrawLayout(); + if ((cl.frame.playerstate.stats[STAT_LAYOUTS] & 2) != 0) + CL_inv.DrawInventory(); + + DrawNet(); + CheckDrawCenterString(); + DrawFPS(); + + // + // if (scr_timegraph->value) + // SCR_DebugGraph (cls.frametime*300, 0); + // + // if (scr_debuggraph->value || scr_timegraph->value || + // scr_netgraph->value) + // SCR_DrawDebugGraph (); + // + DrawPause(); DrawConsole(); - } else { - // TODO implement cinematics completely - DrawCinematic(); - } - } else { - // make sure the game palette is active - if (cl.cinematicpalette_active) { - re.CinematicSetPalette(null); - cl.cinematicpalette_active = false; + Menu.Draw(); + DrawLoading(); } - - // do 3D refresh drawing, and then update the screen - CalcVrect(); - - // clear any dirty part of the background - TileClear(); - - V.RenderView(separation[i]); - - DrawStats(); - - if ((cl.frame.playerstate.stats[STAT_LAYOUTS] & 1) != 0) - DrawLayout(); - if ((cl.frame.playerstate.stats[STAT_LAYOUTS] & 2) != 0) - CL_inv.DrawInventory(); - - DrawNet(); - CheckDrawCenterString(); - DrawFPS(); - - // - // if (scr_timegraph->value) - // SCR_DebugGraph (cls.frametime*300, 0); - // - // if (scr_debuggraph->value || scr_timegraph->value || - // scr_netgraph->value) - // SCR_DrawDebugGraph (); - // - DrawPause(); - DrawConsole(); - Menu.Draw(); - DrawLoading(); } } - Globals.re.EndFrame(); + if( frameRendered ) { + Globals.re.EndFrame(); + } } /* diff --git a/src/jake2/client/VID.java b/src/jake2/client/VID.java index d34a967..04bbf08 100644 --- a/src/jake2/client/VID.java +++ b/src/jake2/client/VID.java @@ -327,11 +327,12 @@ public class VID extends Globals { Restart_f(); } }); - + /* Disable the 3Dfx splash screen */ // putenv("FX_GLIDE_NO_SPLASH=0"); /* Start the graphics mode and load refresh DLL */ + vid_ref.modified = true; CheckChanges(); } diff --git a/src/jake2/client/refexport_t.java b/src/jake2/client/refexport_t.java index 2238e4b..e89aa37 100644 --- a/src/jake2/client/refexport_t.java +++ b/src/jake2/client/refexport_t.java @@ -97,7 +97,7 @@ public interface refexport_t { */ /* 256 r,g,b values; null = game palette, size = 768 bytes */ void CinematicSetPalette(final byte[] palette); - void BeginFrame(float camera_separation); + boolean BeginFrame(float camera_separation); void EndFrame(); void AppActivate(boolean activate); diff --git a/src/jake2/render/DummyRenderer.java b/src/jake2/render/DummyRenderer.java index fcef2fd..07a3002 100644 --- a/src/jake2/render/DummyRenderer.java +++ b/src/jake2/render/DummyRenderer.java @@ -141,7 +141,8 @@ public class DummyRenderer implements refexport_t { /* (non-Javadoc) * @see jake2.client.refexport_t#BeginFrame(float) */ - public void BeginFrame(float camera_separation) { + public boolean BeginFrame(float camera_separation) { + return true; } /* (non-Javadoc) diff --git a/src/jake2/render/JoglDummyRenderer.java b/src/jake2/render/JoglDummyRenderer.java index e39bd23..cdd3cbb 100644 --- a/src/jake2/render/JoglDummyRenderer.java +++ b/src/jake2/render/JoglDummyRenderer.java @@ -73,7 +73,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re // pre init, reads Cvar's if (!impl.R_Init(vid_xpos, vid_ypos)) return false; // activates the OpenGL context - activateGLContext(); + activateGLContext(true); // post init return impl.R_Init2(); @@ -90,7 +90,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re * @see jake2.client.refexport_t#BeginRegistration(java.lang.String) */ public final void BeginRegistration(String map) { - activateGLContext(); + activateGLContext(true); impl.R_BeginRegistration(map); } @@ -98,7 +98,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re * @see jake2.client.refexport_t#RegisterModel(java.lang.String) */ public final model_t RegisterModel(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterModel(name); } @@ -106,7 +106,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re * @see jake2.client.refexport_t#RegisterSkin(java.lang.String) */ public final image_t RegisterSkin(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterSkin(name); } @@ -114,14 +114,14 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re * @see jake2.client.refexport_t#RegisterPic(java.lang.String) */ public final image_t RegisterPic(String name) { - activateGLContext(); + activateGLContext(true); return impl.Draw_FindPic(name); } /** * @see jake2.client.refexport_t#SetSky(java.lang.String, float, float[]) */ public final void SetSky(String name, float rotate, float[] axis) { - activateGLContext(); + activateGLContext(true); impl.R_SetSky(name, rotate, axis); } @@ -129,7 +129,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re * @see jake2.client.refexport_t#EndRegistration() */ public final void EndRegistration() { - activateGLContext(); + activateGLContext(true); impl.R_EndRegistration(); } @@ -165,7 +165,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re * @see jake2.client.refexport_t#DrawChar(int, int, int) */ public final void DrawChar(int x, int y, int num) { - activateGLContext(); + activateGLContext(true); impl.Draw_Char(x, y, num); } @@ -207,8 +207,8 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re /** * @see jake2.client.refexport_t#BeginFrame(float) */ - public final void BeginFrame(float camera_separation) { - impl.R_BeginFrame(camera_separation); + public final boolean BeginFrame(float camera_separation) { + return impl.R_BeginFrame(camera_separation); } /** @@ -226,7 +226,7 @@ final class JoglDummyRenderer extends JoglDummyDriver implements refexport_t, Re } public void screenshot() { - activateGLContext(); + activateGLContext(true); impl.GL_ScreenShot_f(); } diff --git a/src/jake2/render/JoglES1Renderer.java b/src/jake2/render/JoglES1Renderer.java index f798857..59399ea 100644 --- a/src/jake2/render/JoglES1Renderer.java +++ b/src/jake2/render/JoglES1Renderer.java @@ -73,7 +73,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { return false; } // activates the OpenGL context - activateGLContext(); + activateGLContext(true); // post init return impl.R_Init2(); @@ -90,7 +90,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#BeginRegistration(java.lang.String) */ public final void BeginRegistration(String map) { - activateGLContext(); + activateGLContext(true); impl.R_BeginRegistration(map); } @@ -98,7 +98,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterModel(java.lang.String) */ public final model_t RegisterModel(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterModel(name); } @@ -106,7 +106,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterSkin(java.lang.String) */ public final image_t RegisterSkin(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterSkin(name); } @@ -114,14 +114,14 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterPic(java.lang.String) */ public final image_t RegisterPic(String name) { - activateGLContext(); + activateGLContext(true); return impl.Draw_FindPic(name); } /** * @see jake2.client.refexport_t#SetSky(java.lang.String, float, float[]) */ public final void SetSky(String name, float rotate, float[] axis) { - activateGLContext(); + activateGLContext(true); impl.R_SetSky(name, rotate, axis); } @@ -129,7 +129,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#EndRegistration() */ public final void EndRegistration() { - activateGLContext(); + activateGLContext(true); impl.R_EndRegistration(); } @@ -165,7 +165,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#DrawChar(int, int, int) */ public final void DrawChar(int x, int y, int num) { - activateGLContext(); + activateGLContext(true); impl.Draw_Char(x, y, num); } @@ -207,8 +207,8 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { /** * @see jake2.client.refexport_t#BeginFrame(float) */ - public final void BeginFrame(float camera_separation) { - impl.R_BeginFrame(camera_separation); + public final boolean BeginFrame(float camera_separation) { + return impl.R_BeginFrame(camera_separation); } /** @@ -226,7 +226,7 @@ final class JoglES1Renderer extends JoglES1Driver implements refexport_t, Ref { } public void screenshot() { - activateGLContext(); + activateGLContext(true); impl.GL_ScreenShot_f(); } diff --git a/src/jake2/render/JoglES2Renderer.java b/src/jake2/render/JoglES2Renderer.java index a832ac1..f81000f 100644 --- a/src/jake2/render/JoglES2Renderer.java +++ b/src/jake2/render/JoglES2Renderer.java @@ -71,7 +71,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { // pre init, reads Cvar's if (!impl.R_Init(vid_xpos, vid_ypos)) return false; // activates the OpenGL context - activateGLContext(); + activateGLContext(true); // post init return impl.R_Init2(); @@ -88,7 +88,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#BeginRegistration(java.lang.String) */ public final void BeginRegistration(String map) { - activateGLContext(); + activateGLContext(true); impl.R_BeginRegistration(map); } @@ -96,7 +96,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterModel(java.lang.String) */ public final model_t RegisterModel(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterModel(name); } @@ -104,7 +104,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterSkin(java.lang.String) */ public final image_t RegisterSkin(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterSkin(name); } @@ -112,14 +112,14 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterPic(java.lang.String) */ public final image_t RegisterPic(String name) { - activateGLContext(); + activateGLContext(true); return impl.Draw_FindPic(name); } /** * @see jake2.client.refexport_t#SetSky(java.lang.String, float, float[]) */ public final void SetSky(String name, float rotate, float[] axis) { - activateGLContext(); + activateGLContext(true); impl.R_SetSky(name, rotate, axis); } @@ -127,7 +127,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#EndRegistration() */ public final void EndRegistration() { - activateGLContext(); + activateGLContext(true); impl.R_EndRegistration(); } @@ -163,7 +163,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#DrawChar(int, int, int) */ public final void DrawChar(int x, int y, int num) { - activateGLContext(); + activateGLContext(true); impl.Draw_Char(x, y, num); } @@ -205,8 +205,8 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { /** * @see jake2.client.refexport_t#BeginFrame(float) */ - public final void BeginFrame(float camera_separation) { - impl.R_BeginFrame(camera_separation); + public final boolean BeginFrame(float camera_separation) { + return impl.R_BeginFrame(camera_separation); } /** @@ -224,7 +224,7 @@ final class JoglES2Renderer extends JoglES2Driver implements refexport_t, Ref { } public void screenshot() { - activateGLContext(); + activateGLContext(true); impl.GL_ScreenShot_f(); } diff --git a/src/jake2/render/JoglGL2Renderer.java b/src/jake2/render/JoglGL2Renderer.java index ef5117b..3ff7ec6 100644 --- a/src/jake2/render/JoglGL2Renderer.java +++ b/src/jake2/render/JoglGL2Renderer.java @@ -71,7 +71,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { // pre init, reads Cvar's if (!impl.R_Init(vid_xpos, vid_ypos)) return false; // activates the OpenGL context - activateGLContext(); + activateGLContext(true); // post init return impl.R_Init2(); @@ -88,7 +88,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#BeginRegistration(java.lang.String) */ public final void BeginRegistration(String map) { - activateGLContext(); + activateGLContext(true); impl.R_BeginRegistration(map); } @@ -96,7 +96,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterModel(java.lang.String) */ public final model_t RegisterModel(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterModel(name); } @@ -104,7 +104,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterSkin(java.lang.String) */ public final image_t RegisterSkin(String name) { - activateGLContext(); + activateGLContext(true); return impl.R_RegisterSkin(name); } @@ -112,14 +112,14 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#RegisterPic(java.lang.String) */ public final image_t RegisterPic(String name) { - activateGLContext(); + activateGLContext(true); return impl.Draw_FindPic(name); } /** * @see jake2.client.refexport_t#SetSky(java.lang.String, float, float[]) */ public final void SetSky(String name, float rotate, float[] axis) { - activateGLContext(); + activateGLContext(true); impl.R_SetSky(name, rotate, axis); } @@ -127,7 +127,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#EndRegistration() */ public final void EndRegistration() { - activateGLContext(); + activateGLContext(true); impl.R_EndRegistration(); } @@ -163,7 +163,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { * @see jake2.client.refexport_t#DrawChar(int, int, int) */ public final void DrawChar(int x, int y, int num) { - activateGLContext(); + activateGLContext(true); impl.Draw_Char(x, y, num); } @@ -205,8 +205,8 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { /** * @see jake2.client.refexport_t#BeginFrame(float) */ - public final void BeginFrame(float camera_separation) { - impl.R_BeginFrame(camera_separation); + public final boolean BeginFrame(float camera_separation) { + return impl.R_BeginFrame(camera_separation); } /** @@ -224,7 +224,7 @@ final class JoglGL2Renderer extends JoglGL2Driver implements refexport_t, Ref { } public void screenshot() { - activateGLContext(); + activateGLContext(true); impl.GL_ScreenShot_f(); } diff --git a/src/jake2/render/RenderAPI.java b/src/jake2/render/RenderAPI.java index 0c5f9f1..8e75f2f 100644 --- a/src/jake2/render/RenderAPI.java +++ b/src/jake2/render/RenderAPI.java @@ -48,7 +48,7 @@ public interface RenderAPI { void R_SetPalette(byte[] palette); - void R_BeginFrame(float camera_separation); + boolean R_BeginFrame(float camera_separation); void GL_ScreenShot_f(); } diff --git a/src/jake2/render/basic/Main.java b/src/jake2/render/basic/Main.java index 79bb86e..cc12a6c 100644 --- a/src/jake2/render/basic/Main.java +++ b/src/jake2/render/basic/Main.java @@ -1358,7 +1358,7 @@ public abstract class Main extends Base { R_BeginFrame @@@@@@@@@@@@@@@@@@@@@ */ - public void R_BeginFrame(float camera_separation) { + public boolean R_BeginFrame(float camera_separation) { vid.update(); @@ -1408,7 +1408,7 @@ public abstract class Main extends Base { } } - glImpl.beginFrame(camera_separation); + if( glImpl.beginFrame(camera_separation) ) { /* ** go into 2D mode @@ -1466,6 +1466,11 @@ public abstract class Main extends Base { // clear screen if desired // R_Clear(); + + return true; + } else { + return false; + } } int[] r_rawpalette = new int[256]; diff --git a/src/jake2/render/fast/Main.java b/src/jake2/render/fast/Main.java index 5459f20..13a31b3 100644 --- a/src/jake2/render/fast/Main.java +++ b/src/jake2/render/fast/Main.java @@ -1312,7 +1312,7 @@ public abstract class Main extends Base { /** * R_BeginFrame */ - public void R_BeginFrame(float camera_separation) { + public boolean R_BeginFrame(float camera_separation) { vid.update(); @@ -1363,64 +1363,68 @@ public abstract class Main extends Base { } } - glImpl.beginFrame(camera_separation); - - /* - ** go into 2D mode - */ - gl.glViewport(0, 0, vid.getWidth(), vid.getHeight()); - gl.glMatrixMode(GL_PROJECTION); - gl.glLoadIdentity(); - gl.glOrtho(0, vid.getWidth(), vid.getHeight(), 0, -99999, 99999); - gl.glMatrixMode(GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glDisable(GL_DEPTH_TEST); - gl.glDisable(GL_CULL_FACE); - gl.glDisable(GL_BLEND); - gl.glEnable(GL_ALPHA_TEST); - gl.glColor4f(1, 1, 1, 1); - - /* - ** draw buffer stuff - */ - if (gl_drawbuffer.modified) { - gl_drawbuffer.modified = false; - - if (gl_state.camera_separation == 0 || !gl_state.stereo_enabled) { - if (gl_drawbuffer.string.equalsIgnoreCase("GL_FRONT")) - gl.glDrawBuffer(GL_FRONT); - else - gl.glDrawBuffer(GL_BACK); + if( glImpl.beginFrame(camera_separation) ) { + /* + ** go into 2D mode + */ + gl.glViewport(0, 0, vid.getWidth(), vid.getHeight()); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, vid.getWidth(), vid.getHeight(), 0, -99999, 99999); + gl.glMatrixMode(GL_MODELVIEW); + gl.glLoadIdentity(); + gl.glDisable(GL_DEPTH_TEST); + gl.glDisable(GL_CULL_FACE); + gl.glDisable(GL_BLEND); + gl.glEnable(GL_ALPHA_TEST); + gl.glColor4f(1, 1, 1, 1); + + /* + ** draw buffer stuff + */ + if (gl_drawbuffer.modified) { + gl_drawbuffer.modified = false; + + if (gl_state.camera_separation == 0 || !gl_state.stereo_enabled) { + if (gl_drawbuffer.string.equalsIgnoreCase("GL_FRONT")) + gl.glDrawBuffer(GL_FRONT); + else + gl.glDrawBuffer(GL_BACK); + } } + + /* + ** texturemode stuff + */ + if (gl_texturemode.modified) { + GL_TextureMode(gl_texturemode.string); + gl_texturemode.modified = false; + } + + if (gl_texturealphamode.modified) { + GL_TextureAlphaMode(gl_texturealphamode.string); + gl_texturealphamode.modified = false; + } + + if (gl_texturesolidmode.modified) { + GL_TextureSolidMode(gl_texturesolidmode.string); + gl_texturesolidmode.modified = false; + } + + /* + ** swapinterval stuff + */ + GL_UpdateSwapInterval(); + + // + // clear screen if desired + // + R_Clear(); + + return true; + } else { + return true; } - - /* - ** texturemode stuff - */ - if (gl_texturemode.modified) { - GL_TextureMode(gl_texturemode.string); - gl_texturemode.modified = false; - } - - if (gl_texturealphamode.modified) { - GL_TextureAlphaMode(gl_texturealphamode.string); - gl_texturealphamode.modified = false; - } - - if (gl_texturesolidmode.modified) { - GL_TextureSolidMode(gl_texturesolidmode.string); - gl_texturesolidmode.modified = false; - } - - /* - ** swapinterval stuff - */ - GL_UpdateSwapInterval(); - - // - // clear screen if desired - // - R_Clear(); } int[] r_rawpalette = new int[256]; diff --git a/src/jake2/render/opengl/GLDriver.java b/src/jake2/render/opengl/GLDriver.java index 7f86430..9d82593 100644 --- a/src/jake2/render/opengl/GLDriver.java +++ b/src/jake2/render/opengl/GLDriver.java @@ -16,7 +16,8 @@ public interface GLDriver { void shutdown(); - void beginFrame(float camera_separation); + /** @return true if successful, otherwise false. */ + boolean beginFrame(float camera_separation); /** Performs <code>swapBuffers()</code>, ticks the fps counter and performs <code>QUIT</code> if requested. */ void endFrame(); diff --git a/src/jake2/render/opengl/JoglDummyDriver.java b/src/jake2/render/opengl/JoglDummyDriver.java index e962c37..4ba98a0 100644 --- a/src/jake2/render/opengl/JoglDummyDriver.java +++ b/src/jake2/render/opengl/JoglDummyDriver.java @@ -97,8 +97,9 @@ public abstract class JoglDummyDriver extends DummyGL implements GLDriver { return true; } - public void beginFrame(float camera_separation) { - activateGLContext(); + @Override + public boolean beginFrame(float camera_separation) { + return activateGLContext(false); } public void endFrame() { @@ -126,12 +127,12 @@ public abstract class JoglDummyDriver extends DummyGL implements GLDriver { callback.execute(); } - protected final void activateGLContext() { - newtWin.activateGLContext(); + protected final boolean activateGLContext(boolean force) { + return newtWin.activateGLContext(false); } protected final void deactivateGLContext() { - newtWin.activateGLContext(); + newtWin.deactivateGLContext(); } // -------------------------------------------------------------------------- diff --git a/src/jake2/render/opengl/JoglES1Driver.java b/src/jake2/render/opengl/JoglES1Driver.java index 6f138cd..d798c72 100644 --- a/src/jake2/render/opengl/JoglES1Driver.java +++ b/src/jake2/render/opengl/JoglES1Driver.java @@ -108,8 +108,9 @@ public abstract class JoglES1Driver extends JoglGL2ES1 implements GLDriver { return true; } - public void beginFrame(float camera_separation) { - newtWin.activateGLContext(); + @Override + public boolean beginFrame(float camera_separation) { + return activateGLContext(false); } public void endFrame() { @@ -136,12 +137,12 @@ public abstract class JoglES1Driver extends JoglGL2ES1 implements GLDriver { callback.execute(); } - protected final void activateGLContext() { - newtWin.activateGLContext(); + protected final boolean activateGLContext(boolean force) { + return newtWin.activateGLContext(force); } protected final void deactivateGLContext() { - newtWin.activateGLContext(); + newtWin.deactivateGLContext(); } // -------------------------------------------------------------------------- diff --git a/src/jake2/render/opengl/JoglES2Driver.java b/src/jake2/render/opengl/JoglES2Driver.java index 08c95b9..f18a9cb 100644 --- a/src/jake2/render/opengl/JoglES2Driver.java +++ b/src/jake2/render/opengl/JoglES2Driver.java @@ -113,8 +113,8 @@ public abstract class JoglES2Driver extends JoglGL2ES1 implements GLDriver { return true; } - public void beginFrame(float camera_separation) { - activateGLContext(); + public boolean beginFrame(float camera_separation) { + return activateGLContext(false); } public void endFrame() { @@ -141,12 +141,12 @@ public abstract class JoglES2Driver extends JoglGL2ES1 implements GLDriver { callback.execute(); } - protected final void activateGLContext() { - newtWin.activateGLContext(); + protected final boolean activateGLContext(boolean force) { + return newtWin.activateGLContext(force); } protected final void deactivateGLContext() { - newtWin.activateGLContext(); + newtWin.deactivateGLContext(); } // -------------------------------------------------------------------------- diff --git a/src/jake2/render/opengl/JoglGL2Driver.java b/src/jake2/render/opengl/JoglGL2Driver.java index 0c95680..32195cb 100644 --- a/src/jake2/render/opengl/JoglGL2Driver.java +++ b/src/jake2/render/opengl/JoglGL2Driver.java @@ -27,6 +27,7 @@ package jake2.render.opengl; import java.util.List; +import jake2.client.VID; import jake2.game.cvar_t; import jake2.qcommon.Cvar; import jake2.qcommon.xcommand_t; @@ -109,8 +110,9 @@ public abstract class JoglGL2Driver extends JoglGL2ES1 implements GLDriver { return true; } - public void beginFrame(float camera_separation) { - activateGLContext(); + @Override + public boolean beginFrame(float camera_separation) { + return activateGLContext(false); } public void endFrame() { @@ -137,12 +139,12 @@ public abstract class JoglGL2Driver extends JoglGL2ES1 implements GLDriver { callback.execute(); } - protected final void activateGLContext() { - newtWin.activateGLContext(); + protected final boolean activateGLContext(boolean force) { + return newtWin.activateGLContext(force); } protected final void deactivateGLContext() { - newtWin.activateGLContext(); + newtWin.deactivateGLContext(); } // -------------------------------------------------------------------------- diff --git a/src/jake2/render/opengl/NEWTWin.java b/src/jake2/render/opengl/NEWTWin.java index ff7b949..df47bb1 100644 --- a/src/jake2/render/opengl/NEWTWin.java +++ b/src/jake2/render/opengl/NEWTWin.java @@ -15,6 +15,7 @@ import jake2.qcommon.Cvar; import jake2.render.Base; import jake2.sys.NEWTKBD; +import java.io.PrintStream; import java.util.List; import javax.media.nativewindow.CapabilitiesChooser; @@ -22,26 +23,34 @@ import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.SurfaceSize; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLContext; -import javax.media.opengl.GLProfile; +import javax.media.opengl.*; import jogamp.opengl.FPSCounterImpl; import com.jogamp.common.os.Platform; import com.jogamp.newt.*; -import com.jogamp.newt.event.WindowAdapter; -import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.event.*; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.util.MonitorModeUtil; import com.jogamp.opengl.GenericGLCapabilitiesChooser; public class NEWTWin { + final static boolean DEBUG = false; + /** Required due to AWT lock of surface, if Applet! */ + final static boolean FORCE_RELEASE_CTX_VAL = true; + MonitorMode oldDisplayMode = null; volatile Screen screen = null; volatile GLWindow window = null; + volatile GameAnimatorControl animCtrl = null; + /** Encapsulateed AWT dependency */ + volatile Object newtCanvasObject = null; + boolean forceReleaseCtx = false; volatile boolean shouldQuit = false; - final FPSCounterImpl fpsCounter = new FPSCounterImpl(); + volatile boolean shouldPause = false; + volatile boolean shouldReparent = false; + volatile boolean isAnimating = false; public List<MonitorMode> getModeList() { if( null != window ) { @@ -79,12 +88,10 @@ public class NEWTWin { * @param dim * @param mode * @param fullscreen - * @param driverName TODO + * @param driverName * @return enum Base.rserr_t */ public int setMode(GLProfile glp, Dimension dim, int mode, boolean fullscreen, String driverName) { - final boolean isARM = Platform.CPUFamily.ARM == Platform.getCPUFamily(); - final Dimension newDim = new Dimension(); VID.Printf(Defines.PRINT_ALL, "Initializing OpenGL display for profile "+glp+"\n"); @@ -120,7 +127,9 @@ public class NEWTWin { chooser = new GenericGLCapabilitiesChooser(); // don't trust native GL-TK chooser } } + window = GLWindow.create(screen, caps); + window.setAutoSwapBufferMode(false); window.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE); // we do handle QUIT on our own, no GLWindow.display() called. window.setCapabilitiesChooser(chooser); window.addWindowListener(new WindowAdapter() { @@ -133,6 +142,9 @@ public class NEWTWin { } }); window.setTitle("Jake2 ("+driverName+"-newt-"+glp.getName().toLowerCase()+")"); + + animCtrl = new GameAnimatorControl(); + window.setAnimator(animCtrl); final MonitorDevice mainMonitor = window.getMainMonitor(); @@ -146,88 +158,170 @@ public class NEWTWin { window.addWindowListener(NEWTKBD.listener); window.addKeyListener(NEWTKBD.listener); window.addMouseListener(NEWTKBD.listener); - - if (fullscreen) { - MonitorMode mm = findDisplayMode(newDim); - final DimensionImmutable smDim = mm.getSurfaceSize().getResolution(); - newDim.setWidth( smDim.getWidth() ); - newDim.setHeight( smDim.getHeight() ); - mainMonitor.setCurrentMode(mm); - window.setFullscreen(true); - } else { - window.setSize(newDim.getWidth(), newDim.getHeight()); - if (Globals.appletMode) { - // Notify the size listener about the change - final SizeChangeListener listener = Globals.sizeChangeListener; - if (listener != null) { - listener.sizeChanged(newDim.getWidth(), newDim.getHeight()); - } + window.setSize(newDim.getWidth(), newDim.getHeight()); + + isAnimating = true; // no display() invocation on other thread! + + if( !fullscreen && Globals.appletMode ) { + forceReleaseCtx = FORCE_RELEASE_CTX_VAL; + + // Notify the size listener about the change + final SizeChangeListener listener = Globals.sizeChangeListener; + if (listener != null) { + listener.sizeChanged(newDim.getWidth(), newDim.getHeight()); } - } - window.setVisible(true); - - if (!Globals.appletMode) { - while ( !window.isNativeValid()|| !window.isRealized() ) { + window.addKeyListener( new ReparentKeyListener() ); + + final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(window); + final java.applet.Applet applet = (java.applet.Applet) Globals.applet; + final Runnable appletAddAction = new Runnable() { + public void run() { + applet.add(newtCanvasAWT, java.awt.BorderLayout.CENTER); + applet.validate(); + newtCanvasAWT.setFocusable(true); + newtCanvasAWT.requestFocus(); + if( Platform.OSType.MACOS == Platform.getOSType() && newtCanvasAWT.isOffscreenLayerSurfaceEnabled() ) { + System.err.println("XXX Relayout"); + // force relayout + final int cW = newtCanvasAWT.getWidth(); + final int cH = newtCanvasAWT.getHeight(); + newtCanvasAWT.setSize(cW+1, cH+1); + newtCanvasAWT.setSize(cW, cH); + } + } }; + if( java.awt.EventQueue.isDispatchThread() ) { + System.err.println("XXX Adding on AWT EDT - same thread"); + appletAddAction.run(); + } else { + System.err.println("XXX Adding on AWT EDT - off thread"); + try { + java.awt.EventQueue.invokeAndWait(appletAddAction); + } catch (Exception e) { + throw new RuntimeException("NEWT Exception during NewtCanvasAWT on AWT-EDT", e); + } + } + newtCanvasObject = newtCanvasAWT; + int w=0; + while ( w<10 && !window.isNativeValid()|| !window.isRealized() ) { + w++; try { Thread.sleep(100); } catch (InterruptedException e) {} } + System.err.println("XXX waited = "+w+" * 100 ms"); + } else { + forceReleaseCtx = false; + newtCanvasObject = null; + + if (fullscreen) { + MonitorMode mm = findDisplayMode(newDim); + final DimensionImmutable smDim = mm.getSurfaceSize().getResolution(); + newDim.setWidth( smDim.getWidth() ); + newDim.setHeight( smDim.getHeight() ); + mainMonitor.setCurrentMode(mm); + VID.Printf(Defines.PRINT_ALL, "...MonitorMode "+mm+'\n'); + window.setFullscreen(true); + } + + window.setVisible(true); + window.requestFocus(); + } + if( !window.isNativeValid()|| !window.isRealized() ) { + throw new RuntimeException("NEWT window didn't not realize: "+window); + } + window.display(); // force GL creation + final GLContext ctx = window.getContext(); + if( !ctx.isCreated() ) { + System.err.println("Warning: GL context not created: "+ctx); + } + if( ctx.isCurrent() ) { + throw new RuntimeException("NEWT GL context still current: "+ctx); } - window.requestFocus(); - window.display(); // force GL resource validation - window.setAutoSwapBufferMode(false); VID.Printf(Defines.PRINT_ALL, "...reques GLCaps "+window.getRequestedCapabilities()+'\n'); VID.Printf(Defines.PRINT_ALL, "...chosen GLCaps "+window.getChosenGLCapabilities()+'\n'); VID.Printf(Defines.PRINT_ALL, "...size "+window.getWidth()+" x "+window.getHeight()+'\n'); - fpsCounter.setUpdateFPSFrames(isARM ? 60 : 4*60, System.err); // propagateNewSize("init"); - activateGLContext(); + activateGLContext(true); return Base.rserr_ok; } private void propagateNewSize() { - final int width = window.getWidth(); - final int height = window.getHeight(); - final int _width; - final int mask = ~0x03; - if ((width & 0x03) != 0) { - _width = ( width & mask ) + 4; - } else { - _width = width; + if( null != window ) { + final int width = window.getWidth(); + final int height = window.getHeight(); + final int _width; + final int mask = ~0x03; + if ((width & 0x03) != 0) { + _width = ( width & mask ) + 4; + } else { + _width = width; + } + VID.Printf(Defines.PRINT_ALL, "Resize: " + width + " x " + height + ", masked " + _width + "x" + height + "\n"); + + Base.setVid(_width, height); + // let the sound and input subsystems know about the new window + VID.NewWindow(_width, height); } - VID.Printf(Defines.PRINT_ALL, "Resize: " + width + " x " + height + ", masked " + _width + "x" + height + "\n"); - - Base.setVid(_width, height); - // let the sound and input subsystems know about the new window - VID.NewWindow(_width, height); } - protected final void activateGLContext() { - final GLContext ctx = window.getContext(); - if ( null != ctx && GLContext.getCurrent() != ctx ) { - ctx.makeCurrent(); + protected final boolean activateGLContext(boolean force) { + boolean ctxCurrent = false; + if( force || !shouldPause ) { + final GLContext ctx = window.getContext(); + if ( null != ctx && GLContext.getCurrent() != ctx ) { + if( DEBUG ) { + System.err.println("GLCtx Current pause "+shouldPause+": "+Thread.currentThread().getName()); + } + ctxCurrent = GLContext.CONTEXT_NOT_CURRENT < ctx.makeCurrent(); + } else { + ctxCurrent = true; + } + isAnimating = ctxCurrent; } + return ctxCurrent; } protected final void deactivateGLContext() { final GLContext ctx = window.getContext(); if ( null != ctx && GLContext.getCurrent() == ctx) { + if( DEBUG ) { + System.err.println("GLCtx Release pause "+shouldPause+": "+Thread.currentThread().getName()); + } ctx.release(); } } - /** Performs {@link GLWindow#swapBuffers()}, ticks the fps counter and performs <code>QUIT</code> if requested. */ + /** + * Performs {@link GLWindow#swapBuffers()}, ticks the fps counter and performs <code>QUIT</code> if requested. + */ public final void endFrame() { window.swapBuffers(); - fpsCounter.tickFPS(); + animCtrl.fpsCounter.tickFPS(); if( shouldQuit ) { deactivateGLContext(); Cbuf.ExecuteText(Defines.EXEC_APPEND, "quit"); + } else if( shouldReparent ) { + shouldReparent = false; + deactivateGLContext(); + if( null != newtCanvasObject && null != window ) { + isAnimating = false; // don't let GLDrawableHelper.invoke(..) defer the GLRunnable (preserving GLState that is on OSX/CALayer) + final NewtCanvasAWT newtCanvasAWT = (NewtCanvasAWT) newtCanvasObject; + if(null == window.getParent()) { + forceReleaseCtx = FORCE_RELEASE_CTX_VAL; // Applet + window.reparentWindow( newtCanvasAWT.getNativeWindow() ); + } else { + window.reparentWindow(null); + forceReleaseCtx = false; + } + } + } else if( forceReleaseCtx || shouldPause ) { + deactivateGLContext(); } } + /** Performs <code>QUIT</code> if requested. */ public final void checkQuit() { if( shouldQuit ) { @@ -245,12 +339,174 @@ public class NEWTWin { deactivateGLContext(); final GLWindow _window = window; window = null; - _window.destroy(); // same thing + _window.destroy(); + if( null != Globals.applet && null != newtCanvasObject ) { + final java.applet.Applet applet = (java.applet.Applet) Globals.applet; + final NewtCanvasAWT newtCanvasAWT = (NewtCanvasAWT) newtCanvasObject; + final Runnable appletRemoveAction = new Runnable() { + public void run() { + applet.remove(newtCanvasAWT); + applet.validate(); + } }; + if( java.awt.EventQueue.isDispatchThread() ) { + appletRemoveAction.run(); + } else { + try { + java.awt.EventQueue.invokeAndWait(appletRemoveAction); + } catch (Throwable e) { + System.err.println("Catched "+e.getClass().getName()+": "+e.getMessage()); + e.printStackTrace(); + } + } + newtCanvasAWT.setNEWTChild(null); + newtCanvasObject = null; + } } if( withScreen && null != screen ) { - screen.destroy(); + try { + screen.destroy(); + } catch (Throwable e) { + System.err.println("Catched "+e.getClass().getName()+": "+e.getMessage()); + e.printStackTrace(); + } screen = null; } } + class GameAnimatorControl implements GLAnimatorControl { + final FPSCounterImpl fpsCounter; + final Thread thread; + + GameAnimatorControl() { + final boolean isARM = Platform.CPUFamily.ARM == Platform.getCPUFamily(); + fpsCounter = new FPSCounterImpl(); + fpsCounter.setUpdateFPSFrames(isARM ? 60 : 4*60, System.err); + thread = Thread.currentThread(); + } + + @Override + public final boolean start() { + return false; + } + + @Override + public final boolean stop() { + shouldQuit = true; + return true; + } + + @Override + public final boolean pause() { + if( DEBUG ) { + System.err.println("GLCtx Pause Anim: "+Thread.currentThread().getName()); + Thread.dumpStack(); + } + shouldPause = true; + return true; + } + + @Override + public final boolean resume() { + shouldPause = false; + return true; + } + + @Override + public final boolean isStarted() { + return null != window; + } + + @Override + public final boolean isAnimating() { + return isAnimating; // null != window && !shouldPause; + } + + @Override + public final boolean isPaused() { + return null == window || shouldPause; + } + + @Override + public final Thread getThread() { + return thread; + } + + @Override + public final void add(GLAutoDrawable drawable) {} + + @Override + public final void remove(GLAutoDrawable drawable) {} + + @Override + public final void setUpdateFPSFrames(int frames, PrintStream out) { + fpsCounter.setUpdateFPSFrames(frames, out); + } + + @Override + public final void resetFPSCounter() { + fpsCounter.resetFPSCounter(); + } + + @Override + public final int getUpdateFPSFrames() { + return fpsCounter.getUpdateFPSFrames(); + } + + @Override + public final long getFPSStartTime() { + return fpsCounter.getFPSStartTime(); + } + + @Override + public final long getLastFPSUpdateTime() { + return fpsCounter.getLastFPSUpdateTime(); + } + + @Override + public final long getLastFPSPeriod() { + return fpsCounter.getLastFPSPeriod(); + } + + @Override + public final float getLastFPS() { + return fpsCounter.getLastFPS(); + } + + @Override + public final int getTotalFPSFrames() { + return fpsCounter.getTotalFPSFrames(); + } + + @Override + public final long getTotalFPSDuration() { + return fpsCounter.getTotalFPSDuration(); + } + + @Override + public final float getTotalFPS() { + return fpsCounter.getTotalFPS(); + } + } + + class ReparentKeyListener implements KeyListener { + @Override + public void keyPressed(KeyEvent e) { + System.err.println(e); + if( !e.isAutoRepeat() ) { + int keyCode = e.getKeyCode(); + // FIXME: Workaround JOGL/NEWT Bug 798 + if( 0 == keyCode ) { + keyCode = e.getKeySymbol(); + } + if( KeyEvent.VK_HOME == keyCode ) { + shouldReparent = true; + } + } + } + @Override + public void keyReleased(KeyEvent e) { + System.err.println(e); + } + } + } diff --git a/src/jake2/sys/InputListener.java b/src/jake2/sys/InputListener.java index bff13d5..0b55f52 100644 --- a/src/jake2/sys/InputListener.java +++ b/src/jake2/sys/InputListener.java @@ -44,21 +44,25 @@ public final class InputListener implements KeyListener, MouseListener, WindowLi } static Jake2InputEvent nextEvent() { - Jake2InputEvent ev; - synchronized (eventQueue) { - ev = (!eventQueue.isEmpty())?(Jake2InputEvent)eventQueue.removeFirst():null; - } - return ev; + Jake2InputEvent ev; + synchronized (eventQueue) { + ev = (!eventQueue.isEmpty())?(Jake2InputEvent)eventQueue.removeFirst():null; + } + return ev; } @Override public void keyPressed(KeyEvent e) { - addEvent(new Jake2InputEvent(Jake2InputEvent.KeyPress, e)); + if( !e.isAutoRepeat() ) { + addEvent(new Jake2InputEvent(Jake2InputEvent.KeyPress, e)); + } } @Override public void keyReleased(KeyEvent e) { - addEvent(new Jake2InputEvent(Jake2InputEvent.KeyRelease, e)); + if( !e.isAutoRepeat() ) { + addEvent(new Jake2InputEvent(Jake2InputEvent.KeyRelease, e)); + } } @Override diff --git a/src/jake2/sys/NEWTKBD.java b/src/jake2/sys/NEWTKBD.java index 4a0ba76..af54a36 100644 --- a/src/jake2/sys/NEWTKBD.java +++ b/src/jake2/sys/NEWTKBD.java @@ -119,6 +119,10 @@ final public class NEWTKBD extends KBD private static int XLateKeyCode(KeyEvent ev) { int code = ev.getKeyCode(); + // FIXME: Workaround JOGL/NEWT Bug 798 + if( 0 == code ) { + code = ev.getKeySymbol(); + } int key = 0; switch(code) { // 00626 case XK_KP_Page_Up: key = K_KP_PGUP; break; diff --git a/src/jake2/sys/Sys.java b/src/jake2/sys/Sys.java index 8ac8fb1..cefb303 100644 --- a/src/jake2/sys/Sys.java +++ b/src/jake2/sys/Sys.java @@ -226,7 +226,7 @@ public final class Sys extends Defines { } public static void SendKeyEvents() { - Globals.re.getKeyboardHandler().Update(); + Globals.re.getKeyboardHandler().Update(); // grab frame time Globals.sys_frame_time = Timer.Milliseconds(); |