diff options
author | Holger Zickner <[email protected]> | 2004-07-07 19:59:59 +0000 |
---|---|---|
committer | Holger Zickner <[email protected]> | 2004-07-07 19:59:59 +0000 |
commit | 6e23fc1074d1f0c2c2812f4c2e663f5a21a43c20 (patch) | |
tree | 46ecc6d0255c874ba4cd26dc3d0733f785019896 /test/jake2/render |
import of Jake2 version sunrisesunrise
Diffstat (limited to 'test/jake2/render')
-rw-r--r-- | test/jake2/render/DancingQueens.java | 320 | ||||
-rw-r--r-- | test/jake2/render/DebugCulling.java | 363 | ||||
-rw-r--r-- | test/jake2/render/TestMap.java | 623 | ||||
-rw-r--r-- | test/jake2/render/TestRenderer.java | 829 |
4 files changed, 2135 insertions, 0 deletions
diff --git a/test/jake2/render/DancingQueens.java b/test/jake2/render/DancingQueens.java new file mode 100644 index 0000000..fbf233b --- /dev/null +++ b/test/jake2/render/DancingQueens.java @@ -0,0 +1,320 @@ +/* + * DancingQueens.java + * Copyright (C) 2003 + * + * $Id: DancingQueens.java,v 1.1 2004-07-07 19:59:58 hzi Exp $ + */ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +package jake2.render; + +import jake2.Defines; +import jake2.Globals; +import jake2.client.*; +import jake2.game.Cmd; +import jake2.game.cvar_t; +import jake2.qcommon.*; +import jake2.sys.IN; +import jake2.sys.KBD; +import jake2.util.Math3D; +import jake2.util.Vargs; + +import java.awt.Dimension; +import java.util.Arrays; + + +/** + * DancingQueens + * + * @author cwei + */ +public class DancingQueens +{ + String[] args; + + refexport_t re; + refimport_t ri; + viddef_t viddef; + int framecount = 0; + + public DancingQueens(String[] args) { + this.args = args; + } + + public static void main(String[] args) { + + DancingQueens test = new DancingQueens(args); + test.init(); + test.run(); + } + + void init() { + + // only for testing + // a simple refimport_t implementation + ri = new refimport_t() { + public void Sys_Error(int err_level, String str) { + VID.Error(err_level, str, null); + } + + public void Sys_Error(int err_level, String str, Vargs vargs) { + VID.Error(err_level, str, vargs); + } + + public void Cmd_AddCommand(String name, xcommand_t cmd) { + Cmd.AddCommand(name, cmd); + } + + public void Cmd_RemoveCommand(String name) { + Cmd.RemoveCommand(name); + } + + public int Cmd_Argc() { + return Cmd.Argc(); + } + + public String Cmd_Argv(int i) { + return Cmd.Argv(i); + } + + public void Cmd_ExecuteText(int exec_when, String text) { + Cbuf.ExecuteText(exec_when, text); + } + + public void Con_Printf(int print_level, String str) { + VID.Printf(print_level, str, null); + } + + public void Con_Printf(int print_level, String str, Vargs vargs) { + VID.Printf(print_level, str, vargs); + } + + public byte[] FS_LoadFile(String name) { + return FS.LoadFile(name); + } + + public int FS_FileLength(String name) { + return FS.FileLength(name); + } + + public void FS_FreeFile(byte[] buf) { + FS.FreeFile(buf); + } + + public String FS_Gamedir() { + return FS.Gamedir(); + } + + public cvar_t Cvar_Get(String name, String value, int flags) { + return Cvar.Get(name, value, flags); + } + + public cvar_t Cvar_Set(String name, String value) { + return Cvar.Set(name, value); + } + + public void Cvar_SetValue(String name, float value) { + Cvar.SetValue(name, value); + } + + public boolean Vid_GetModeInfo(Dimension dim, int mode) { + return VID.GetModeInfo(dim, mode); + } + + public void Vid_MenuInit() { + VID.MenuInit(); + } + + public void Vid_NewWindow(int width, int height) { + VID.NewWindow(width, height); + } + + public void updateScreenCallback() { + DancingQueens.this.updateScreen(); + } + }; + + + Qcommon.InitForTestMap(new String[] {"DancingQueens"}); + // sehr wichtig !!! + VID.Shutdown(); + + String[] names = Renderer.getDriverNames(); + System.out.println("Registered Drivers: " + Arrays.asList(names)); + + this.re = Renderer.getDriver("jogl", ri); + + System.out.println("Use driver: " + re); + System.out.println(); + + re.Init(0, 0); + + Cmd.AddCommand("togglemouse", togglemouse); + Cbuf.AddText("bind t togglemouse"); + Cbuf.Execute(); + Globals.cls.key_dest = Defines.key_game; + Globals.cls.state = Defines.ca_active; + + viddef = Globals.viddef; + fov_y = Math3D.CalcFov(fov_x, viddef.width, viddef.height); + } + + float fps = 0.0f; + long start = 0; + + void updateScreen() + { + re.BeginFrame(0.0f); + + if (framecount % 500 == 0) + { + long time = System.currentTimeMillis(); + fps = 500000.0f / (time - start); + start = time; + } + String text = fps + " fps"; + + testModel(); + + drawString(10, viddef.height - 16, text); + + re.EndFrame(); + framecount++; + } + + long startTime; + + void run() + { + startTime = System.currentTimeMillis(); + while (true) + { + re.updateScreen(null); + KBD.Update(); + Cbuf.Execute(); + } + } + +// =================================================================== + + private float yaw = 0; + private entity_t[] models; + + private final static String[] skinNames = { + "players/female/athena", + "players/female/lotus", + "players/female/venus", + "players/female/voodoo", + "players/female/cobalt", + "players/female/lotus", + "players/female/brianna" + }; + + private float fov_x = 50; + private float fov_y; + + private void testModel() { + + refdef_t refdef = new refdef_t(); + + refdef.x = 0; + refdef.y = 0; + refdef.width = viddef.width; + refdef.height = viddef.height; + refdef.fov_x = fov_x; + refdef.fov_y = fov_y; + refdef.time = 1.0f * 0.001f; + + if (models == null) { + models = new entity_t[12]; // model count + entity_t m = null; + for (int i = 0; i < models.length; i++) + { + m = getModel(skinNames[i % skinNames.length]); + m.origin[0] += 30 * i; + m.origin[1] += ((i % 4)) * 30 - 20; + models[i] = m; + } + } + + + yaw = time() * 0.1f; + if (yaw > 360) + yaw -= 360; + if (yaw < 0) + yaw += 360; + + for (int i = 0; i < models.length; i++) + { + models[i].frame = (time() / 70) % models[i].model.numframes; + models[i].angles[1] = yaw; + models[i].origin[0] += KBD.my; + models[i].origin[1] += KBD.mx; + + } + + refdef.areabits = null; + refdef.num_entities = models.length; + refdef.entities = models; + + refdef.lightstyles = null; + refdef.rdflags = Defines.RDF_NOWORLDMODEL; + + re.RenderFrame(refdef); + } + + private entity_t getModel(String name) { + entity_t entity = new entity_t(); + String modelName = "players/female/tris.md2"; + String modelSkin = name +".pcx"; + + entity.model = re.RegisterModel(modelName); + entity.skin = re.RegisterSkin(modelSkin); + entity.flags = Defines.RF_FULLBRIGHT; + entity.origin[0] = 80; + entity.origin[1] = 0; + entity.origin[2] = 0; + Math3D.VectorCopy(entity.origin, entity.oldorigin); + entity.frame = 0; + entity.oldframe = 0; + entity.backlerp = 0.0f; + return entity; + } + + + private void drawString(int x, int y, String text) + { + for (int i = 0; i < text.length(); i++) + { + re.DrawChar(x + 8 * i, y, (int) text.charAt(i)); + } + } + + private final int time() + { + return (int) (System.currentTimeMillis() - startTime); + } + + static xcommand_t togglemouse = new xcommand_t() { + public void execute() { + IN.toggleMouse(); + } + }; +}
\ No newline at end of file diff --git a/test/jake2/render/DebugCulling.java b/test/jake2/render/DebugCulling.java new file mode 100644 index 0000000..b85fb45 --- /dev/null +++ b/test/jake2/render/DebugCulling.java @@ -0,0 +1,363 @@ +/* + * DebugCulling.java + * Copyright (C) 2003 + * + * $Id: DebugCulling.java,v 1.1 2004-07-07 19:59:58 hzi Exp $ + */ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +package jake2.render; + +import jake2.Defines; +import jake2.Globals; +import jake2.client.VID; +import jake2.client.cparticle_t; +import jake2.client.entity_t; +import jake2.client.lightstyle_t; +import jake2.client.particle_t; +import jake2.client.refdef_t; +import jake2.client.refexport_t; +import jake2.client.refimport_t; +import jake2.client.viddef_t; +import jake2.game.Cmd; +import jake2.game.cvar_t; +import jake2.qcommon.Cbuf; +import jake2.qcommon.Cvar; +import jake2.qcommon.FS; +import jake2.qcommon.Qcommon; +import jake2.qcommon.qfiles; +import jake2.qcommon.xcommand_t; +import jake2.sys.KBD; +import jake2.util.Lib; +import jake2.util.Math3D; +import jake2.util.Vargs; + +import java.awt.Dimension; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Vector; + +/** + * DebugCulling + * + * @author cwei + */ +public class DebugCulling +{ + + static final float INSTANT_PARTICLE = -10000.0f; + static final float PARTICLE_GRAVITY = 40.0f; + + String[] args; + + refexport_t re; + refimport_t ri; + viddef_t viddef; + int framecount = 0; + + public DebugCulling(String[] args) + { + this.args = args; + } + + public static void main(String[] args) + { + + DebugCulling test = new DebugCulling(args); + test.init(); + test.run(); + } + + void init() + { + + // only for testing + // a simple refimport_t implementation + ri = new refimport_t() + { + public void Sys_Error(int err_level, String str) + { + VID.Error(err_level, str, null); + } + + public void Sys_Error(int err_level, String str, Vargs vargs) + { + VID.Error(err_level, str, vargs); + } + + public void Cmd_AddCommand(String name, xcommand_t cmd) + { + Cmd.AddCommand(name, cmd); + } + + public void Cmd_RemoveCommand(String name) + { + Cmd.RemoveCommand(name); + } + + public int Cmd_Argc() + { + return Cmd.Argc(); + } + + public String Cmd_Argv(int i) + { + return Cmd.Argv(i); + } + + public void Cmd_ExecuteText(int exec_when, String text) + { + Cbuf.ExecuteText(exec_when, text); + } + + public void Con_Printf(int print_level, String str) + { + VID.Printf(print_level, str, null); + } + + public void Con_Printf(int print_level, String str, Vargs vargs) + { + VID.Printf(print_level, str, vargs); + } + + public byte[] FS_LoadFile(String name) + { + return FS.LoadFile(name); + } + + public int FS_FileLength(String name) + { + return FS.FileLength(name); + } + + public void FS_FreeFile(byte[] buf) + { + FS.FreeFile(buf); + } + + public String FS_Gamedir() + { + return FS.Gamedir(); + } + + public cvar_t Cvar_Get(String name, String value, int flags) + { + return Cvar.Get(name, value, flags); + } + + public cvar_t Cvar_Set(String name, String value) + { + return Cvar.Set(name, value); + } + + public void Cvar_SetValue(String name, float value) + { + Cvar.SetValue(name, value); + } + + public boolean Vid_GetModeInfo(Dimension dim, int mode) + { + return VID.GetModeInfo(dim, mode); + } + + public void Vid_MenuInit() + { + VID.MenuInit(); + } + + public void Vid_NewWindow(int width, int height) + { + VID.NewWindow(width, height); + } + + public void updateScreenCallback() + { + DebugCulling.this.updateScreen(); + } + }; + + Qcommon.Init(new String[] { "$Id: DebugCulling.java,v 1.1 2004-07-07 19:59:58 hzi Exp $" }); + // sehr wichtig !!! + VID.Shutdown(); + + this.re = Renderer.getDriver("jogl", ri); + + re.Init(0, 0); + + viddef = Globals.viddef; + } + + float fps = 0.0f; + long start = 0; + long startTime; + + void run() + { + startTime = System.currentTimeMillis(); + while (true) + { + re.updateScreen(null); + KBD.Update(); +// try { +// Thread.sleep(5); +// } +// catch (InterruptedException e) { +// } + } + } + + int currentState = 0; + + void updateScreen() + { + re.BeginFrame(0.0f); + + switch (currentState) + { + case 0 : + re.DrawStretchPic(0, 0, viddef.width, viddef.height, "conback"); + re.DrawPic(viddef.width / 2 - 50, viddef.height / 2, "loading"); + currentState = 1; + break; + case 1 : + // register the map + re.SetSky("space1", 0, new float[]{ 0, 0, 0 }); + re.BeginRegistration("ColorTest"); + re.EndRegistration(); + currentState = 2; + //break; + default : + if (framecount % 500 == 0) + { + long time = System.currentTimeMillis(); + fps = 500000.0f / (time - start); + start = time; + } + String text = fps + " fps"; + + testMap(); + + drawString(10, viddef.height - 16, text); + } + + re.EndFrame(); + framecount++; + } + + // =================================================================== + + private float yaw = 0; + + private float fov_x = 90; + + private refdef_t refdef; + + private void testMap() + { + + if ( refdef == null ) { + refdef = new refdef_t(); + + refdef.x = 0; + refdef.y = 0; + refdef.width = viddef.width; + refdef.height = viddef.height; + refdef.fov_x = fov_x; + refdef.fov_y = CalcFov(fov_x, refdef.width -10, refdef.height-10); + refdef.vieworg = new float[] {0, 0, 0}; + + refdef.viewangles[0] = 0; + refdef.viewangles[1] = 90; + refdef.viewangles[2] = 0; + + refdef.blend = new float[] { 0.0f, 0.0f, 0.0f, 0.0f }; + + refdef.areabits = null; // draw all +// refdef.areabits = new byte[Defines.MAX_MAP_AREAS / 8]; +// Arrays.fill(refdef.areabits, (byte) 0xFF); + + + refdef.num_entities = 0; + refdef.entities = null; + + lightstyle_t light = new lightstyle_t(); + light.rgb = new float[] {1.0f, 1.0f, 1.0f}; + light.white = 3.0f; + + refdef.lightstyles = new lightstyle_t[Defines.MAX_LIGHTSTYLES]; + for (int i = 0; i < Defines.MAX_LIGHTSTYLES; i++) + { + refdef.lightstyles[i] = new lightstyle_t(); + refdef.lightstyles[i].rgb = new float[] { 1.0f, 1.0f, 1.0f }; + refdef.lightstyles[i].white = 3.0f; // r + g + b + } + + } + + refdef.time = time() * 0.001f; + + refdef.viewangles[0] += KBD.my * 0.1f; + refdef.viewangles[1] -= KBD.mx * 0.1f; + + refdef.vieworg[0] = 0; // + 30 * (float)Math.sin(time() * 0.0005f); + refdef.vieworg[1] = -79; + refdef.vieworg[2] = -131; + + // wichtig da aufloesung 1/8 + // --> ebenen schneiden nie genau die sicht + refdef.vieworg[0] += 1.0f / 16; + refdef.vieworg[1] += 1.0f / 16; + refdef.vieworg[2] += 1.0f / 16; + + re.RenderFrame(refdef); + } + + private float CalcFov(float fov_x, float width, float height) + { + double a; + double x; + + if (fov_x < 1 || fov_x > 179) + ri.Sys_Error(Defines.ERR_DROP, "Bad fov: " + fov_x); + + x = width / Math.tan(fov_x / 360 * Math.PI); + + a = Math.atan(height / x); + + a = a * 360 / Math.PI; + + return (float) a; + } + + private void drawString(int x, int y, String text) + { + for (int i = 0; i < text.length(); i++) + { + re.DrawChar(x + 8 * i, y, (int) text.charAt(i)); + } + } + + private final int time() + { + return (int) (System.currentTimeMillis() - startTime); + } + +}
\ No newline at end of file diff --git a/test/jake2/render/TestMap.java b/test/jake2/render/TestMap.java new file mode 100644 index 0000000..9419fa1 --- /dev/null +++ b/test/jake2/render/TestMap.java @@ -0,0 +1,623 @@ +/* + * TestMap.java + * Copyright (C) 2003 + * + * $Id: TestMap.java,v 1.1 2004-07-07 19:59:59 hzi Exp $ + */ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +package jake2.render; + +import jake2.Defines; +import jake2.Globals; +import jake2.client.*; +import jake2.game.Cmd; +import jake2.game.cvar_t; +import jake2.qcommon.*; +import jake2.sys.IN; +import jake2.sys.KBD; +import jake2.util.*; + +import java.awt.Dimension; +import java.util.*; + +/** + * TestMap + * + * @author cwei + */ +public class TestMap +{ + + static final float INSTANT_PARTICLE = -10000.0f; + static final float PARTICLE_GRAVITY = 40.0f; + + String[] args; + + refexport_t re; + refimport_t ri; + viddef_t viddef; + int framecount = 0; + + public TestMap(String[] args) + { + this.args = args; + } + + public static void main(String[] args) + { + + TestMap test = new TestMap(args); + test.init(); + test.run(); + } + + void init() + { + + // only for testing + // a simple refimport_t implementation + ri = new refimport_t() + { + public void Sys_Error(int err_level, String str) + { + VID.Error(err_level, str, null); + } + + public void Sys_Error(int err_level, String str, Vargs vargs) + { + VID.Error(err_level, str, vargs); + } + + public void Cmd_AddCommand(String name, xcommand_t cmd) + { + Cmd.AddCommand(name, cmd); + } + + public void Cmd_RemoveCommand(String name) + { + Cmd.RemoveCommand(name); + } + + public int Cmd_Argc() + { + return Cmd.Argc(); + } + + public String Cmd_Argv(int i) + { + return Cmd.Argv(i); + } + + public void Cmd_ExecuteText(int exec_when, String text) + { + Cbuf.ExecuteText(exec_when, text); + } + + public void Con_Printf(int print_level, String str) + { + VID.Printf(print_level, str, null); + } + + public void Con_Printf(int print_level, String str, Vargs vargs) + { + VID.Printf(print_level, str, vargs); + } + + public byte[] FS_LoadFile(String name) + { + return FS.LoadFile(name); + } + + public int FS_FileLength(String name) + { + return FS.FileLength(name); + } + + public void FS_FreeFile(byte[] buf) + { + FS.FreeFile(buf); + } + + public String FS_Gamedir() + { + return FS.Gamedir(); + } + + public cvar_t Cvar_Get(String name, String value, int flags) + { + return Cvar.Get(name, value, flags); + } + + public cvar_t Cvar_Set(String name, String value) + { + return Cvar.Set(name, value); + } + + public void Cvar_SetValue(String name, float value) + { + Cvar.SetValue(name, value); + } + + public boolean Vid_GetModeInfo(Dimension dim, int mode) + { + return VID.GetModeInfo(dim, mode); + } + + public void Vid_MenuInit() + { + VID.MenuInit(); + } + + public void Vid_NewWindow(int width, int height) + { + VID.NewWindow(width, height); + } + + public void updateScreenCallback() + { + TestMap.this.updateScreen(); + } + }; + + Qcommon.InitForTestMap(new String[] { "TestMap $Id: TestMap.java,v 1.1 2004-07-07 19:59:59 hzi Exp $" }); + // sehr wichtig !!! + VID.Shutdown(); + + this.re = Renderer.getDriver("jogl", ri); + + re.Init(0, 0); + + // init keyboard + Cmd.AddCommand("+tforward", forward_down); + Cmd.AddCommand("-tforward", forward_up); + Cbuf.AddText("bind UPARROW +tforward"); + Cbuf.Execute(); + Cmd.AddCommand("+tbackward", backward_down); + Cmd.AddCommand("-tbackward", backward_up); + Cbuf.AddText("bind DOWNARROW +tbackward"); + Cbuf.Execute(); + Cmd.AddCommand("+tleft", left_down); + Cmd.AddCommand("-tleft", left_up); + Cbuf.AddText("bind LEFTARROW +tleft"); + Cbuf.Execute(); + Cmd.AddCommand("+tright", right_down); + Cmd.AddCommand("-tright", right_up); + Cbuf.AddText("bind RIGHTARROW +tright"); + Cbuf.Execute(); + Cmd.AddCommand("togglemouse", togglemouse); + Cbuf.AddText("bind t togglemouse"); + Cbuf.Execute(); + Globals.cls.key_dest = Defines.key_game; + Globals.cls.state = Defines.ca_active; + + viddef = Globals.viddef; + } + + float fps = 0.0f; + long start = 0; + long startTime; + + void run() + { + startTime = System.currentTimeMillis(); + while (true) + { + re.updateScreen(null); + KBD.Update(); + Cbuf.Execute(); + } + } + + int currentState = 0; + + void updateScreen() + { + re.BeginFrame(0.0f); + + switch (currentState) + { + case 0 : + re.DrawStretchPic(0, 0, viddef.width, viddef.height, "conback"); + re.DrawPic(viddef.width / 2 - 50, viddef.height / 2, "loading"); + currentState = 1; + break; + case 1 : + // register the map + re.SetSky("space1", 0, new float[]{ 0, 0, 0 }); + re.BeginRegistration("base1"); + re.EndRegistration(); + currentState = 2; + //break; + default : + if (framecount % 500 == 0) + { + long time = System.currentTimeMillis(); + fps = 500000.0f / (time - start); + start = time; + } + String text = fps + " fps"; + + testMap(); + + drawString(10, viddef.height - 16, text); + } + + re.EndFrame(); + framecount++; + } + + // =================================================================== + + + static final int FORWARD = 2; + static final int FORWARD_MASK = ~FORWARD; + static final int BACKWARD = 4; + static final int BACKWARD_MASK = ~BACKWARD; + static final int LEFT = 8; + static final int LEFT_MASK = ~LEFT; + static final int RIGHT = 16; + static final int RIGHT_MASK = ~RIGHT; + + + int movePlayer = 0; + + // forward + xcommand_t forward_down = new xcommand_t() { + public void execute() { + movePlayer |= FORWARD; + movePlayer &= BACKWARD_MASK; + } + }; + xcommand_t forward_up = new xcommand_t() { + public void execute() { + movePlayer &= FORWARD_MASK; + } + }; + // backward + xcommand_t backward_down = new xcommand_t() { + public void execute() { + movePlayer |= BACKWARD; + movePlayer &= FORWARD_MASK; + } + }; + xcommand_t backward_up = new xcommand_t() { + public void execute() { + movePlayer &= BACKWARD_MASK; + } + }; + // left + xcommand_t left_down = new xcommand_t() { + public void execute() { + movePlayer |= LEFT; + movePlayer &= RIGHT_MASK; + } + }; + xcommand_t left_up = new xcommand_t() { + public void execute() { + movePlayer &= LEFT_MASK; + } + }; + // right + xcommand_t right_down = new xcommand_t() { + public void execute() { + movePlayer |= RIGHT; + movePlayer &= LEFT_MASK; + } + }; + xcommand_t right_up = new xcommand_t() { + public void execute() { + movePlayer &= RIGHT_MASK; + } + }; + + private float yaw = 0; + + private float fov_x = 90; + + private refdef_t refdef; + + private entity_t ent; + + float[] vpn = {0, 0, 0}; + float[] vright = {0, 0, 0}; + float[] vup = {0, 0, 0}; + + private void testMap() + { + + if ( refdef == null ) { + refdef = new refdef_t(); + + refdef.x = 0; + refdef.y = 0; + refdef.width = viddef.width; + refdef.height = viddef.height; + refdef.fov_x = (Globals.fov == null) ? this.fov_x : Globals.fov.value; + refdef.fov_x = this.fov_x; + refdef.fov_y = Math3D.CalcFov(refdef.fov_x, refdef.width, refdef.height); + refdef.vieworg = new float[] {140, -140, 50}; + refdef.viewangles = new float[] {0, 0, 0}; + + refdef.blend = new float[] { 0.0f, 0.0f, 0.0f, 0.0f }; + + refdef.areabits = null; // draw all +// refdef.areabits = new byte[Defines.MAX_MAP_AREAS / 8]; +// Arrays.fill(refdef.areabits, (byte) 0xFF); + + // load a monster + ent = new entity_t(); + + model_t weapon = re.RegisterModel("models/monsters/soldier/tris.md2"); + image_t weaponSkin = re.RegisterSkin("models/monsters/soldier/skin.pcx"); + + ent.model = weapon; + ent.skin = weaponSkin; + ent.origin = new float[] { -60, 80, 25 }; + Math3D.VectorCopy(ent.origin, ent.oldorigin); + ent.angles = new float[] { 0, 300, 0 }; + + refdef.num_entities = 1; + refdef.entities = new entity_t[] {ent}; + + lightstyle_t light = new lightstyle_t(); + light.rgb = new float[] {1.0f, 1.0f, 1.0f}; + light.white = 3.0f; + + refdef.lightstyles = new lightstyle_t[Defines.MAX_LIGHTSTYLES]; + for (int i = 0; i < Defines.MAX_LIGHTSTYLES; i++) { + refdef.lightstyles[i] = new lightstyle_t(); + refdef.lightstyles[i].rgb = new float[] {1.0f, 1.0f, 1.0f}; + refdef.lightstyles[i].white = 3.0f; // r + g + b + } + + refdef.viewangles[1] = 130; + // set the start time + refdef.time = time() * 0.001f; + } + + refdef.viewangles[0] += KBD.my * 0.1f; + refdef.viewangles[1] -= KBD.mx * 0.1f; // 90 + 180 * (float)Math.sin(time() * 0.0001f); + + float dt = time() * 0.001f - refdef.time; + + if (movePlayer != 0) { + + float velocity = 150f * dt; + Math3D.AngleVectors(refdef.viewangles, vpn, vright, vup); + + // forward + if ((movePlayer & FORWARD_MASK) != 0) + Math3D.VectorMA(refdef.vieworg, -velocity, vpn, refdef.vieworg); + // backward + if ((movePlayer & BACKWARD_MASK) != 0) + Math3D.VectorMA(refdef.vieworg, velocity, vpn, refdef.vieworg); + // left + if ((movePlayer & LEFT_MASK) != 0) + Math3D.VectorMA(refdef.vieworg, velocity, vright, refdef.vieworg); + // right + if ((movePlayer & RIGHT_MASK) != 0) + Math3D.VectorMA(refdef.vieworg, -velocity, vright, refdef.vieworg); + + // wichtig da aufloesung 1/8 + // --> ebenen schneiden nie genau die sicht + refdef.vieworg[0] += 1.0f / 16; + refdef.vieworg[1] += 1.0f / 16; + refdef.vieworg[2] += 1.0f / 16; + } + + refdef.time = time() * 0.001f; + + // particle init + particles.clear(); + + // check the enemy distance + float[] diff = {0, 0, 0}; + Math3D.VectorSubtract( refdef.vieworg, ent.origin, diff); + + if (Math3D.VectorLength(diff) < 250 && active_particles.size() == 0) { + RailTrail(ent.origin, refdef.vieworg); + } else { + // monster and partice animation + if (active_particles.size() > 0) { + // monster + ent.frame = (int)((time() * 0.013f) % 15); + // monster look at you :-) + Math3D.VectorNormalize(diff); + Math3D.vectoangles(diff, ent.angles); + + // particles + animateParticles(); + + particle_t[] tmp = new particle_t[particles.size()]; + particles.toArray(tmp); + + refdef.particles = tmp; + refdef.num_particles = tmp.length; + } + else { + ent.frame = 0; + refdef.num_particles = 0; + } + } + + re.RenderFrame(refdef); + } + + private Vector particles = new Vector(1024); // = new particle_t[20]; + private LinkedList active_particles = new LinkedList(); + private boolean explode = false; + private float[] target; + + private boolean initParticles = true; + + private void animateParticles() + { + cparticle_t p; + float alpha; + float time, time2; + float[] org = {0, 0, 0}; + int color; + particle_t particle; + + time = 0.0f; + + for (Iterator it = active_particles.iterator(); it.hasNext();) + { + p = (cparticle_t) it.next(); + + // PMM - added INSTANT_PARTICLE handling for heat beam + if (p.alphavel != INSTANT_PARTICLE) + { + time = (time() - p.time) * 0.001f; + alpha = p.alpha + time*p.alphavel; + if (alpha <= 0) + { // faded out + it.remove(); + continue; + } + } + else + { + alpha = p.alpha; + } + + if (alpha > 1.0) + alpha = 1; + color = (int)p.color; + + time2 = time*time; + + org[0] = p.org[0] + p.vel[0]*time + p.accel[0]*time2; + org[1] = p.org[1] + p.vel[1]*time + p.accel[1]*time2; + org[2] = p.org[2] + p.vel[2]*time + p.accel[2]*time2; + + particle = new particle_t(); + particle.alpha = alpha; + Math3D.VectorCopy(org, particle.origin); + particle.color = color; + + particles.add(particle); + + // PMM + if (p.alphavel == INSTANT_PARTICLE) + { + p.alphavel = 0.0f; + p.alpha = 0.0f; + } + } + } + + private void RailTrail(float[] start, float[] end) + { + float[] move = {0, 0, 0}; + float[] vec = {0, 0, 0}; + float len; + int j; + cparticle_t p; + float dec; + float[] right = {0, 0, 0}; + float[] up = {0, 0, 0}; + int i; + float d, c, s; + float[] dir = {0, 0, 0}; + + Math3D.VectorCopy (start, move); + Math3D.VectorSubtract (end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.MakeNormalVectors(vec, right, up); + + for (i=0 ; i<len ; i++) + { + + p = new cparticle_t(); + p.time = time(); + Math3D.VectorClear (p.accel); + + d = i * 0.1f; + c = (float)Math.cos(d); + s = (float)Math.sin(d); + + Math3D.VectorScale (right, c, dir); + Math3D.VectorMA (dir, s, up, dir); + + p.alpha = 1.0f; + p.alphavel = -1.0f / (1 + Lib.frand() * 0.2f); + p.color = 0x74 + (Lib.rand() & 7); + for (j=0 ; j<3 ; j++) + { + p.org[j] = move[j] + dir[j]*3; + p.vel[j] = dir[j]*6; + } + + Math3D.VectorAdd (move, vec, move); + + active_particles.add(p); + } + + dec = 0.75f; + Math3D.VectorScale (vec, dec, vec); + Math3D.VectorCopy (start, move); + + while (len > 0) + { + len -= dec; + + p = new cparticle_t(); + + p.time = time(); + Math3D.VectorClear (p.accel); + + p.alpha = 1.0f; + p.alphavel = -1.0f / (0.6f + Lib.frand() * 0.2f); + p.color = 0x0 + Lib.rand()&15; + + for (j=0 ; j<3 ; j++) + { + p.org[j] = move[j] + Lib.crand()*3; + p.vel[j] = Lib.crand()*3; + p.accel[j] = 0; + } + + Math3D.VectorAdd (move, vec, move); + active_particles.add(p); + } + } + + private void drawString(int x, int y, String text) + { + for (int i = 0; i < text.length(); i++) + { + re.DrawChar(x + 8 * i, y, (int) text.charAt(i)); + } + } + + private final int time() + { + return (int) (System.currentTimeMillis() - startTime); + } + + static xcommand_t togglemouse = new xcommand_t() { + public void execute() { + IN.toggleMouse(); + } + }; +} diff --git a/test/jake2/render/TestRenderer.java b/test/jake2/render/TestRenderer.java new file mode 100644 index 0000000..976d57c --- /dev/null +++ b/test/jake2/render/TestRenderer.java @@ -0,0 +1,829 @@ +/* + * TestRenderer.java + * Copyright (C) 2003 + * + * $Id: TestRenderer.java,v 1.1 2004-07-07 19:59:59 hzi Exp $ + */ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +package jake2.render; + +import java.awt.Dimension; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Vector; + +import jake2.Defines; +import jake2.Globals; +import jake2.client.*; +import jake2.game.Cmd; +import jake2.game.cvar_t; +import jake2.qcommon.*; +import jake2.sys.KBD; +import jake2.sys.Sys; +import jake2.util.Lib; +import jake2.util.Math3D; +import jake2.util.Vargs; + +/** + * TestRenderer + * + * @author cwei + */ +public class TestRenderer { + + String[] args; + + refexport_t re; + refimport_t ri; + viddef_t viddef; + int framecount = 0; + static int testnr = 0; + + public TestRenderer(String[] args) { + this.args = args; + } + + public static void main(String[] args) { + + TestRenderer test = new TestRenderer(args); + test.init(); + test.run(); + } + + void init() { + + // only for testing + // a simple refimport_t implementation + ri = new refimport_t() { + public void Sys_Error(int err_level, String str) { + VID.Error(err_level, str, null); + } + + public void Sys_Error(int err_level, String str, Vargs vargs) { + VID.Error(err_level, str, vargs); + } + + public void Cmd_AddCommand(String name, xcommand_t cmd) { + Cmd.AddCommand(name, cmd); + } + + public void Cmd_RemoveCommand(String name) { + Cmd.RemoveCommand(name); + } + + public int Cmd_Argc() { + return Cmd.Argc(); + } + + public String Cmd_Argv(int i) { + return Cmd.Argv(i); + } + + public void Cmd_ExecuteText(int exec_when, String text) { + Cbuf.ExecuteText(exec_when, text); + } + + public void Con_Printf(int print_level, String str) { + VID.Printf(print_level, str, null); + } + + public void Con_Printf(int print_level, String str, Vargs vargs) { + VID.Printf(print_level, str, vargs); + } + + public byte[] FS_LoadFile(String name) { + return FS.LoadFile(name); + } + + public int FS_FileLength(String name) { + return FS.FileLength(name); + } + + public void FS_FreeFile(byte[] buf) { + FS.FreeFile(buf); + } + + public String FS_Gamedir() { + return FS.Gamedir(); + } + + public cvar_t Cvar_Get(String name, String value, int flags) { + return Cvar.Get(name, value, flags); + } + + public cvar_t Cvar_Set(String name, String value) { + return Cvar.Set(name, value); + } + + public void Cvar_SetValue(String name, float value) { + Cvar.SetValue(name, value); + } + + public boolean Vid_GetModeInfo(Dimension dim, int mode) { + return VID.GetModeInfo(dim, mode); + } + + public void Vid_MenuInit() { + VID.MenuInit(); + } + + public void Vid_NewWindow(int width, int height) { + VID.NewWindow(width, height); + } + + public void updateScreenCallback() { + TestRenderer.this.updateScreen(); + } + }; + + + Qcommon.Init(new String[] {"TestRenderer"}); + // sehr wichtig !!! + VID.Shutdown(); + + String[] names = Renderer.getDriverNames(); + System.out.println("Registered Drivers: " + Arrays.asList(names)); + + this.re = Renderer.getDriver("jogl", ri); + + System.out.println("Use driver: " + re); + System.out.println(); + + re.Init(0, 0); + +// for (int i = 0; i < raw.length; i++) { +// raw[i] = (byte)((i % 3) + 1); //((i % 4) + 20); +// } + Cmd.AddCommand("nexttest", nexttest); + Cbuf.AddText("bind n nexttest"); + Cbuf.Execute(); + Globals.cls.key_dest = Defines.key_game; + Globals.cls.state = Defines.ca_active; + } + + float fps = 0.0f; + long start = 0; + + void updateScreen() { + re.BeginFrame(0.0f); + viddef = Globals.viddef; + re.DrawStretchPic(0,0,viddef.width, viddef.height, "conback"); + + if (framecount % 500 == 0) { + long time = System.currentTimeMillis(); + fps = 500000.0f / (time - start); + start = time; + } + String text = fps + " fps"; + + for (int i = 0; i < text.length(); i++) { + re.DrawChar(10 + 8 * i, viddef.height/2, (int)text.charAt(i)); + } + + Dimension wal = new Dimension(); + re.DrawGetPicSize(wal, "/textures/e1u1/basemap.wal"); + + re.DrawPic(0, viddef.height - wal.height, "/textures/e1u1/basemap.wal"); + + switch (testnr) { + case 0 : + testParticles(); + break; + case 1 : + testModel(); + break; + case 2 : + testSprites(); + break; + case 3: + testBeam(); + } + re.EndFrame(); + framecount++; + } + + + long startTime; + + void run() { + startTime = System.currentTimeMillis(); + while (true) { + re.updateScreen(null); + KBD.Update(); + Cbuf.Execute(); + try { + Thread.sleep(5); + } catch (InterruptedException e) { + } + } + } + +// =================================================================== + + private int yaw = 0; + + private void testModel() { + + refdef_t refdef = new refdef_t(); + + refdef.x = viddef.width/ 2; + refdef.y = viddef.height / 2 - 72; + refdef.width = 144 * 2; + refdef.height = 168 * 2; + refdef.fov_x = 40; + refdef.fov_y = Math3D.CalcFov(refdef.fov_x, refdef.width, refdef.height); + refdef.time = 1.0f * 0.001f; + + int maxframe = 29; + entity_t entity = new entity_t(); + String modelName = "players/female/tris.md2"; + + String modelSkin = "players/female/athena.pcx"; + + String modelImage = "/players/female/athena_i.pcx"; + String modelImage1 = "/players/female/brianna_i.pcx"; + String modelImage2 = "/players/female/cobalt_i.pcx"; + String modelImage3 = "/players/female/lotus_i.pcx"; + + entity.model = re.RegisterModel(modelName); + + drawString(refdef.x, refdef.y - 20, (entity.model != null) ? modelName : "DEBUG: NullModel"); + + entity.skin = re.RegisterSkin(modelSkin); + entity.flags = Defines.RF_FULLBRIGHT; + entity.origin[0] = 80; + entity.origin[1] = 0; + entity.origin[2] = 0; + Math3D.VectorCopy(entity.origin, entity.oldorigin); + entity.frame = (framecount / 3) % ((qfiles.dmdl_t)entity.model.extradata).num_frames; + entity.oldframe = 0; + entity.backlerp = 0.0f; + yaw+=KBD.mx; + KBD.mx = 0; + if (yaw > 360) + yaw -= 360; + if (yaw < 0) + yaw += 360; + entity.angles[1] = yaw; + + + refdef.areabits = null; + refdef.num_entities = 1; + refdef.entities = new entity_t[] { entity }; + refdef.lightstyles = null; + refdef.rdflags = Defines.RDF_NOWORLDMODEL; + + // Menu_Draw(& s_player_config_menu); + + M_DrawTextBox( + (int) ((refdef.x) * (320.0F / viddef.width) - 8), + (int) ((viddef.height / 2) * (240.0F / viddef.height) - 77), + refdef.width / 8, + refdef.height / 8); + refdef.height += 4; + + re.RenderFrame(refdef); + + re.DrawPic(refdef.x - 80, refdef.y, modelImage); + re.DrawPic(refdef.x - 80, refdef.y + 47, modelImage1); + re.DrawPic(refdef.x - 80, refdef.y + 94, modelImage2); + re.DrawPic(refdef.x - 80, refdef.y + 141, modelImage3); + } + + + private String[] sprites = { + "sprites/s_bfg1.sp2", + "sprites/s_bfg2.sp2", + "sprites/s_bfg3.sp2", + "sprites/s_explod.sp2", + "sprites/s_explo2.sp2", + "sprites/s_explo3.sp2", + "sprites/s_flash.sp2", + "sprites/s_bubble.sp2", + }; + + private int spriteCount = 0; + private boolean loading = true; + + private void testSprites() { + + if (loading) { + + re.DrawPic(viddef.width / 2 - 50, viddef.height / 2, "loading"); + String name = sprites[spriteCount]; + + drawString(viddef.width / 2 - 50, viddef.height / 2 + 50, name); + + re.RegisterModel(name); + loading = ++spriteCount < sprites.length; + return; + } + + + refdef_t refdef = new refdef_t(); + + refdef.x = viddef.width/ 2; + refdef.y = viddef.height / 2 - 72; + refdef.width = 144 * 2; + refdef.height = 168 * 2; + refdef.fov_x = 40; + refdef.fov_y = Math3D.CalcFov(refdef.fov_x, refdef.width, refdef.height); + refdef.time = 1.0f * 0.001f; + + int maxframe = 29; + entity_t entity = new entity_t(); + + String modelName = sprites[(framecount / 30) % sprites.length]; + drawString(refdef.x, refdef.y - 20, modelName); + + entity.model = re.RegisterModel(modelName); + + entity.flags = Defines.RF_FULLBRIGHT; + entity.origin[0] = 80 - (framecount % 200) + 200; + entity.origin[1] = 0 + (float)(40 * Math.sin(Math.toRadians(framecount))); + entity.origin[2] = 0 + 20; + Math3D.VectorCopy(entity.origin, entity.oldorigin); + entity.frame = framecount / 2; + entity.oldframe = 0; + entity.backlerp = 0.0f; + + refdef.areabits = null; + refdef.num_entities = 1; + refdef.entities = new entity_t[] { entity }; + refdef.lightstyles = null; + refdef.rdflags = Defines.RDF_NOWORLDMODEL; + + M_DrawTextBox( + (int) ((refdef.x) * (320.0F / viddef.width) - 8), + (int) ((viddef.height / 2) * (240.0F / viddef.height) - 77), + refdef.width / 8, + refdef.height / 8); + refdef.height += 4; + + re.RenderFrame(refdef); + + } + + private void testBeam() { + + refdef_t refdef = new refdef_t(); + + refdef.x = viddef.width/ 2; + refdef.y = viddef.height / 2 - 72; + refdef.width = 144 * 2; + refdef.height = 168 * 2; + refdef.fov_x = 40; + refdef.fov_y = Math3D.CalcFov(refdef.fov_x, refdef.width, refdef.height); + refdef.time = 1.0f * 0.001f; + + int maxframe = 29; + entity_t entity = new entity_t(); + + drawString(refdef.x, refdef.y - 20, "Beam Test"); + + entity.flags = Defines.RF_BEAM; + entity.origin[0] = 200; + entity.origin[1] = 0 + (float)(80 * Math.sin(4 * Math.toRadians(framecount))); + entity.origin[2] = 20 + (float)(40 * Math.cos(4 * Math.toRadians(framecount))); + + entity.oldorigin[0] = 20; + entity.oldorigin[1] = 0; // + (float)(40 * Math.sin(Math.toRadians(framecount))); + entity.oldorigin[2] = -20; // + 20; + + entity.frame = 3; + entity.oldframe = 0; + entity.backlerp = 0.0f; + // the four beam colors are encoded in 32 bits of skinnum (hack) + entity.alpha = 0.6f; + + int[] color = { 0xd0, 0xd1, 0xe0, 0xb0 }; + + entity.skinnum = color[framecount / 2 % 4]; + entity.model = null; + + refdef.areabits = null; + refdef.num_entities = 1; + refdef.entities = new entity_t[] { entity }; + refdef.lightstyles = null; + refdef.rdflags = Defines.RDF_NOWORLDMODEL; + + M_DrawTextBox( + (int) ((refdef.x) * (320.0F / viddef.width) - 8), + (int) ((viddef.height / 2) * (240.0F / viddef.height) - 77), + refdef.width / 8, + refdef.height / 8); + refdef.height += 4; + + re.RenderFrame(refdef); + } + + private Vector particles = new Vector(1024); // = new particle_t[20]; + private LinkedList active_particles = new LinkedList(); + private boolean explode = false; + private float[] target; + + private boolean initParticles = true; + + private void testParticles() { + + particles.clear(); + + if (active_particles.size() == 0) { + if (explode) + Explosion(target); + else { + target = new float[] {150 + Lib.crand() * 80, Lib.crand() * 40, Lib.crand() * 40}; + RailTrail(new float[]{30, -20, -20}, target); + //Heatbeam(new float[]{30, 20, -20}, target); + } + explode = !explode; + } + refdef_t refdef = new refdef_t(); + + refdef.x = viddef.width/ 2; + refdef.y = viddef.height / 2 - 72; + refdef.width = 400; + refdef.height = 400; + refdef.fov_x = 50; + refdef.fov_y = Math3D.CalcFov(refdef.fov_x, refdef.width, refdef.height); + refdef.time = 1.0f * 0.001f; + + animateParticles(); + + drawString(refdef.x, refdef.y - 20, "active particles: " + particles.size()); + + particle_t[] tmp = new particle_t[particles.size()]; + + particles.toArray(tmp); + + refdef.particles = tmp; + refdef.num_particles = tmp.length; + + refdef.areabits = null; + refdef.num_entities = 0; + refdef.entities = null; + refdef.lightstyles = null; + refdef.rdflags = Defines.RDF_NOWORLDMODEL; + + M_DrawTextBox( + (int) ((refdef.x) * (320.0F / viddef.width) - 8), + (int) ((viddef.height / 2) * (240.0F / viddef.height) - 77), + refdef.width / 8, + refdef.height / 8); + refdef.height += 4; + + re.RenderFrame(refdef); + } + + private void drawString(int x, int y, String text) { + for (int i = 0; i < text.length(); i++) { + re.DrawChar(x + 8 * i, y, (int)text.charAt(i)); + } + } + + + private void M_DrawTextBox(int x, int y, int width, int lines) { + int cx, cy; + int n; + + // draw left side + cx = x; + cy = y; + M_DrawCharacter(cx, cy, 1); + for (n = 0; n < lines; n++) { + cy += 8; + M_DrawCharacter(cx, cy, 4); + } + M_DrawCharacter(cx, cy + 8, 7); + + // draw middle + cx += 8; + while (width > 0) { + cy = y; + M_DrawCharacter(cx, cy, 2); + for (n = 0; n < lines; n++) { + cy += 8; + M_DrawCharacter(cx, cy, 5); + } + M_DrawCharacter(cx, cy + 8, 8); + width -= 1; + cx += 8; + } + + // draw right side + cy = y; + M_DrawCharacter(cx, cy, 3); + for (n = 0; n < lines; n++) { + cy += 8; + M_DrawCharacter(cx, cy, 6); + } + M_DrawCharacter(cx, cy + 8, 9); + } + + /* + ================ + M_DrawCharacter + + Draws one solid graphics character + cx and cy are in 320*240 coordinates, and will be centered on + higher res screens. + ================ + */ + private void M_DrawCharacter(int cx, int cy, int num) { + re.DrawChar( + cx + ((viddef.width - 320) >> 1), + cy + ((viddef.height - 240) >> 1), + num); + } + + long endtime; + + private void Explosion(float[] org) { + float[] dir = {0, 0, 0}; + int i; + cparticle_t p; + + for(i=0; i<256; i++) + { + p = new cparticle_t(); + + p.time = time() * 1.0f; + p.color = /*0xe0*/ 223 - (Lib.rand() & 7); + for (int j=0 ; j<3 ; j++) + { + p.org[j] = org[j] + (float)(Lib.rand() % 32) - 16; + p.vel[j] = (float)(Lib.rand() % 384) - 192; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -PARTICLE_GRAVITY; + p.alpha = 1.0f; + p.alphavel = -0.8f / (0.5f + Lib.frand() * 0.3f); + + active_particles.add(p); + } + } + + static final float INSTANT_PARTICLE = -10000.0f; + static final float PARTICLE_GRAVITY = 40.0f; + + + /* + =============== + CL_AddParticles + =============== + */ + private void animateParticles() + { + cparticle_t p; + float alpha; + float time, time2; + float[] org = {0, 0, 0}; + int color; + particle_t particle; + + time = 0.0f; + + for (Iterator it = active_particles.iterator(); it.hasNext();) + { + p = (cparticle_t) it.next(); + + // PMM - added INSTANT_PARTICLE handling for heat beam + if (p.alphavel != INSTANT_PARTICLE) + { + time = (time() - p.time) * 0.001f; + alpha = p.alpha + time*p.alphavel; + if (alpha <= 0) + { // faded out + it.remove(); + continue; + } + } + else + { + alpha = p.alpha; + } + + if (alpha > 1.0) + alpha = 1; + color = (int)p.color; + + time2 = time*time; + + org[0] = p.org[0] + p.vel[0]*time + p.accel[0]*time2; + org[1] = p.org[1] + p.vel[1]*time + p.accel[1]*time2; + org[2] = p.org[2] + p.vel[2]*time + p.accel[2]*time2; + + particle = new particle_t(); + particle.alpha = alpha; + Math3D.VectorCopy(org, particle.origin); + particle.color = color; + + particles.add(particle); + + // PMM + if (p.alphavel == INSTANT_PARTICLE) + { + p.alphavel = 0.0f; + p.alpha = 0.0f; + } + } + } + + private void Heatbeam (float[] start, float[] forward) + { + + float[] v_up = {0, 0, 10}; + float[] v_right = {0, 10, 0}; + + + float[] move = {0, 0, 0}; + float[] vec = {0, 0, 0}; + float len; + int j; + cparticle_t p; + float[] right = {0, 0, 0}; + float[] up = {0, 0, 0}; + int i; + float c, s; + float[] dir = {0, 0, 0}; + float ltime; + float step = 32.0f, rstep; + float start_pt; + float rot; + float variance; + float[] end = {0, 0, 0}; + + Math3D.VectorMA (start, 4096, forward, end); + + Math3D.VectorCopy (start, move); + Math3D.VectorSubtract (end, start, vec); + len = Math3D.VectorNormalize (vec); + + Math3D.VectorCopy (v_right, right); + Math3D.VectorCopy (v_up, up); +// if (vidref_val == VIDREF_GL) +// { // GL mode + Math3D.VectorMA (move, -0.5f, right, move); + Math3D.VectorMA (move, -0.5f, up, move); +// } +// // otherwise assume SOFT + + ltime = (float)time()/1000.0f; + start_pt = (ltime*96.0f) % step; + Math3D.VectorMA (move, start_pt, vec, move); + + Math3D.VectorScale (vec, step, vec); + + rstep = (float)Math.PI / 10.0f; + for (i=(int)start_pt ; i<len ; i+=step) + { + if (i>step*5) // don't bother after the 5th ring + break; + + for (rot = 0; rot < Math.PI * 2; rot += rstep) + { + + p = new cparticle_t(); + + p.time = time(); + Math3D.VectorClear (p.accel); + variance = 0.5f; + c = (float)Math.cos(rot)*variance; + s = (float)Math.sin(rot)*variance; + + // trim it so it looks like it's starting at the origin + if (i < 10) + { + Math3D.VectorScale (right, c*(i/10.0f), dir); + Math3D.VectorMA (dir, s*(i/10.0f), up, dir); + } + else + { + Math3D.VectorScale (right, c, dir); + Math3D.VectorMA (dir, s, up, dir); + } + + p.alpha = 0.8f; + p.alphavel = -1000.0f; + p.color = /* 223 */0x74 - (Lib.rand()&7); + for (j=0 ; j<3 ; j++) + { + p.org[j] = move[j] + dir[j]*3; + p.vel[j] = 0; + } + + active_particles.add(p); + } + Math3D.VectorAdd (move, vec, move); + } + } + + private void RailTrail(float[] start, float[] end) + { + float[] move = {0, 0, 0}; + float[] vec = {0, 0, 0}; + float len; + int j; + cparticle_t p; + float dec; + float[] right = {0, 0, 0}; + float[] up = {0, 0, 0}; + int i; + float d, c, s; + float[] dir = {0, 0, 0}; + + Math3D.VectorCopy (start, move); + Math3D.VectorSubtract (end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.MakeNormalVectors(vec, right, up); + + for (i=0 ; i<len ; i++) + { + + p = new cparticle_t(); + p.time = time(); + Math3D.VectorClear (p.accel); + + d = i * 0.1f; + c = (float)Math.cos(d); + s = (float)Math.sin(d); + + Math3D.VectorScale (right, c, dir); + Math3D.VectorMA (dir, s, up, dir); + + p.alpha = 1.0f; + p.alphavel = -1.0f / (1 + Lib.frand() * 0.2f); + p.color = 0x74 + (Lib.rand() & 7); + for (j=0 ; j<3 ; j++) + { + p.org[j] = move[j] + dir[j]*3; + p.vel[j] = dir[j]*6; + } + + Math3D.VectorAdd (move, vec, move); + + active_particles.add(p); + } + + dec = 0.75f; + Math3D.VectorScale (vec, dec, vec); + Math3D.VectorCopy (start, move); + + while (len > 0) + { + len -= dec; + + p = new cparticle_t(); + + p.time = time(); + Math3D.VectorClear (p.accel); + + p.alpha = 1.0f; + p.alphavel = -1.0f / (0.6f + Lib.frand() * 0.2f); + p.color = 0x0 + Lib.rand()&15; + + for (j=0 ; j<3 ; j++) + { + p.org[j] = move[j] + Lib.crand()*3; + p.vel[j] = Lib.crand()*3; + p.accel[j] = 0; + } + + Math3D.VectorAdd (move, vec, move); + active_particles.add(p); + } + } + + private int time() { + return (int)(System.currentTimeMillis() - startTime); + } + + static xcommand_t nexttest = new xcommand_t() { + public void execute() { + testnr++; + testnr = testnr % 3; + } + }; + +} |