diff options
Diffstat (limited to 'src/jake2/client')
-rw-r--r-- | src/jake2/client/CL.java | 3207 | ||||
-rw-r--r-- | src/jake2/client/CL_ents.java | 1281 | ||||
-rw-r--r-- | src/jake2/client/CL_fx.java | 2324 | ||||
-rw-r--r-- | src/jake2/client/CL_input.java | 675 | ||||
-rw-r--r-- | src/jake2/client/CL_inv.java | 93 | ||||
-rw-r--r-- | src/jake2/client/CL_newfx.java | 2000 | ||||
-rw-r--r-- | src/jake2/client/CL_parse.java | 1525 | ||||
-rw-r--r-- | src/jake2/client/CL_pred.java | 552 | ||||
-rw-r--r-- | src/jake2/client/CL_tent.java | 3482 | ||||
-rw-r--r-- | src/jake2/client/CL_view.java | 340 | ||||
-rw-r--r-- | src/jake2/client/Console.java | 1166 | ||||
-rw-r--r-- | src/jake2/client/M.java | 1157 | ||||
-rw-r--r-- | src/jake2/client/Menu.java | 9794 | ||||
-rw-r--r-- | src/jake2/client/SCR.java | 3946 | ||||
-rw-r--r-- | src/jake2/client/V.java | 774 |
15 files changed, 16197 insertions, 16119 deletions
diff --git a/src/jake2/client/CL.java b/src/jake2/client/CL.java index 3170112..dcdf7db 100644 --- a/src/jake2/client/CL.java +++ b/src/jake2/client/CL.java @@ -2,36 +2,39 @@ * CL.java * Copyright (C) 2004 * - * $Id: CL.java,v 1.10 2004-09-08 09:37:39 hzi Exp $ + * $Id: CL.java,v 1.11 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; import jake2.Defines; import jake2.Globals; import jake2.game.*; import jake2.qcommon.*; +import jake2.qcommon.qfiles.dmdl_t; import jake2.server.SV_MAIN; import jake2.sound.*; import jake2.sys.*; +import jake2.util.Lib; +import jake2.util.Math3D; import jake2.util.Vargs; import java.io.IOException; @@ -42,1590 +45,1630 @@ import java.nio.ByteOrder; /** * CL */ -public final class CL extends CL_pred { - - /* - ==================== - CL_WriteDemoMessage - - Dumps the current net message, prefixed by the length - ==================== - */ - static void WriteDemoMessage() { - int swlen; - - // the first eight bytes are just packet sequencing stuff - swlen = net_message.cursize - 8; - - try { - cls.demofile.writeInt(swlen); - //fwrite (&swlen, 4, 1, cls.demofile); - cls.demofile.write(net_message.data, 8, swlen); - //fwrite (net_message.data+8, len, 1, cls.demofile); - } catch (IOException e) {} - - } - - /* - ==================== - CL_Stop_f - - stop recording a demo - ==================== - */ - static xcommand_t Stop_f = new xcommand_t() { - public void execute() { - try { - - int len; - - if (!cls.demorecording) { - Com.Printf("Not recording a demo.\n"); - return; - } - - // finish up - len = -1; - cls.demofile.writeInt(len); - cls.demofile.close(); - cls.demofile = null; - cls.demorecording = false; - Com.Printf("Stopped demo.\n"); - } - catch (IOException e) { - } - } - }; - - /* - ==================== - CL_Record_f - - record <demoname> - - Begins recording a demo from the current position - ==================== - */ - static entity_state_t nullstate = new entity_state_t(null); - - static xcommand_t Record_f = new xcommand_t() { - public void execute() { - try { - String name; - byte buf_data[] = new byte[MAX_MSGLEN]; - sizebuf_t buf = new sizebuf_t(); - int i; - entity_state_t ent; - - if (Cmd.Argc() != 2) { - Com.Printf("record <demoname>\n"); - return; - } - - if (cls.demorecording) { - Com.Printf("Already recording.\n"); - return; - } - - if (cls.state != ca_active) { - Com.Printf("You must be in a level to record.\n"); - return; - } - - // - // open the demo file - // - name = FS.Gamedir() + "/demos/" + Cmd.Argv(1) + ".dm2"; - - Com.Printf("recording to " + name + ".\n"); - FS.CreatePath(name); - cls.demofile = new RandomAccessFile(name, "rw"); - if (cls.demofile == null) { - Com.Printf("ERROR: couldn't open.\n"); - return; - } - cls.demorecording = true; - - // don't start saving messages until a non-delta compressed message is received - cls.demowaiting = true; - - // - // write out messages to hold the startup information - // - SZ.Init(buf, buf_data, MAX_MSGLEN); - - // send the serverdata - MSG.WriteByte(buf, svc_serverdata); - MSG.WriteInt(buf, PROTOCOL_VERSION); - MSG.WriteInt(buf, 0x10000 + cl.servercount); - MSG.WriteByte(buf, 1); // demos are always attract loops - MSG.WriteString(buf, cl.gamedir); - MSG.WriteShort(buf, cl.playernum); - - MSG.WriteString(buf, cl.configstrings[CS_NAME]); - - // configstrings - for (i = 0; i < MAX_CONFIGSTRINGS; i++) { - if (cl.configstrings[i].length()>0) { - if (buf.cursize + cl.configstrings[i].length() + 32 > buf.maxsize) { // write it out - //len = LittleLong(buf.cursize); - //fwrite(& len, 4, 1, cls.demofile); - cls.demofile.writeInt(buf.cursize); - //fwrite(buf.data, buf.cursize, 1, cls.demofile); - cls.demofile.write(buf.data, 0, buf.cursize); - buf.cursize = 0; - } - - MSG.WriteByte(buf, svc_configstring); - MSG.WriteShort(buf, i); - MSG.WriteString(buf, cl.configstrings[i]); - } - - } - - // baselines - //memset( nullstate, 0, sizeof(nullstate)); - for (i = 0; i < MAX_EDICTS; i++) { - ent = cl_entities[i].baseline; - if (ent.modelindex == 0) - continue; - - if (buf.cursize + 64 > buf.maxsize) { // write it out - //len = LittleLong(buf.cursize); - //fwrite(& len, 4, 1, cls.demofile); - cls.demofile.writeInt(buf.cursize); - //fwrite(buf.data, buf.cursize, 1, cls.demofile); - cls.demofile.write(buf.data, 0, buf.cursize); - buf.cursize = 0; - } - - MSG.WriteByte(buf, svc_spawnbaseline); - MSG.WriteDeltaEntity(nullstate, cl_entities[i].baseline, buf, true, true); - } - - MSG.WriteByte(buf, svc_stufftext); - MSG.WriteString(buf, "precache\n"); - - // write it to the demo file - - //len = LittleLong(buf.cursize); - //fwrite(& len, 4, 1, cls.demofile); - cls.demofile.writeInt(buf.cursize); - //fwrite(buf.data, buf.cursize, 1, cls.demofile); - cls.demofile.write(buf.data, 0, buf.cursize); - // the rest of the demo file will be individual frames - - } - catch (IOException e) { - } - } - }; - - /* - ================== - CL_ForwardToServer_f - ================== - */ - static xcommand_t ForwardToServer_f = new xcommand_t() { - public void execute() { - if (cls.state != ca_connected && cls.state != ca_active) { - Com.Printf("Can't \"" + Cmd.Argv(0) + "\", not connected\n"); - return; - } - - // don't forward the first argument - if (Cmd.Argc() > 1) { - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - SZ.Print(cls.netchan.message, Cmd.Args()); - } - } - }; - - /* - ================== - CL_Pause_f - ================== - */ - static xcommand_t Pause_f = new xcommand_t() { - public void execute() { - // never pause in multiplayer - - if (Cvar.VariableValue("maxclients") > 1 || Globals.server_state == 0) { - Cvar.SetValue("paused", 0); - return; - } - - Cvar.SetValue("paused", cl_paused.value); - } - }; - - /* - ================== - CL_Quit_f - ================== - */ - static xcommand_t Quit_f = new xcommand_t() { - public void execute() { - Disconnect(); - Com.Quit(); - } - }; - - /* - ======================= - CL_SendConnectPacket - - We have gotten a challenge from the server, so try and - connect. - ====================== - */ - static void SendConnectPacket() { - netadr_t adr = new netadr_t(); - int port; - - if (!NET.StringToAdr(cls.servername, adr)) { - Com.Printf("Bad server address\n"); - cls.connect_time = 0; - return; - } - if (adr.port == 0) - adr.port = PORT_SERVER; - // adr.port = BigShort(PORT_SERVER); - - port = (int) Cvar.VariableValue("qport"); - userinfo_modified = false; - - Netchan.OutOfBandPrint( - NS_CLIENT, - adr, - "connect " + PROTOCOL_VERSION + " " + port + " " + cls.challenge + " \"" + Cvar.Userinfo() + "\"\n"); - } - - /* - ================= - CL_CheckForResend - - Resend a connect message if the last one has timed out - ================= - */ - static void CheckForResend() { - netadr_t adr = new netadr_t(); - - // if the local server is running and we aren't - // then connect - if (cls.state == ca_disconnected && Globals.server_state != 0) { - cls.state = ca_connecting; - cls.servername = "localhost"; - // we don't need a challenge on the localhost - CL.SendConnectPacket(); - return; - } - - // resend if we haven't gotten a reply yet - if (cls.state != ca_connecting) - return; - - if (cls.realtime - cls.connect_time < 3000) - return; - - if (!NET.StringToAdr(cls.servername, adr)) { - Com.Printf("Bad server address\n"); - cls.state = ca_disconnected; - return; - } - if (adr.port == 0) - // adr.port = BigShort(PORT_SERVER); - adr.port = PORT_SERVER; - - cls.connect_time = cls.realtime; // for retransmit requests - - Com.Printf("Connecting to " + cls.servername + "...\n"); - - Netchan.OutOfBandPrint(NS_CLIENT, adr, "getchallenge\n"); - } - - /* - ================ - CL_Connect_f - - ================ - */ - static xcommand_t Connect_f = new xcommand_t() { - public void execute() { - String server; - - if (Cmd.Argc() != 2) { - Com.Printf("usage: connect <server>\n"); - return; - } - - if (Globals.server_state != 0) { - // if running a local server, kill it and reissue - SV_MAIN.SV_Shutdown("Server quit\n", false); - } else { - CL.Disconnect(); - } - - server = Cmd.Argv(1); - - NET.Config(true); // allow remote - - CL.Disconnect(); - - cls.state = ca_connecting; - //strncpy (cls.servername, server, sizeof(cls.servername)-1); - cls.servername = server; - cls.connect_time = -99999; - // CL_CheckForResend() will fire immediately - } - }; - - /* - ===================== - CL_Rcon_f - - Send the rest of the command line over as - an unconnected command. - ===================== - */ - static xcommand_t Rcon_f = new xcommand_t() { - public void execute() { - StringBuffer message = new StringBuffer(1024); - int i; - netadr_t to = new netadr_t(); - - if (rcon_client_password.string == null) { - Com.Printf("You must set 'rcon_password' before\nissuing an rcon command.\n"); - return; - } - - message.append((char)255); - message.append((char)255); - message.append((char)255); - message.append((char)255); - - NET.Config(true); // allow remote - - //strcat (message, "rcon "); - message.append("rcon "); - - //strcat (message, rcon_client_password.string); - message.append(rcon_client_password.string); - //strcat (message, " "); - message.append(" "); - - for (i = 1; i < Cmd.Argc(); i++) { - //strcat (message, Cmd.Argv(i)); - message.append(Cmd.Argv(i)); - //strcat (message, " "); - message.append(" "); - } - - if (cls.state >= ca_connected) - to = cls.netchan.remote_address; - else { - if (rcon_address.string.length() == 0) { - Com.Printf( - "You must either be connected,\nor set the 'rcon_address' cvar\nto issue rcon commands\n"); - - return; - } - NET.StringToAdr(rcon_address.string, to); - if (to.port == 0) - //to.port = BigShort (PORT_SERVER); - to.port = PORT_SERVER; - } - message.append('\0'); - String b = message.toString(); - NET.SendPacket(NS_CLIENT, b.length(), b.getBytes(), to); - } - }; - - /* - ===================== - CL_ClearState - - ===================== - */ - - static void ClearState() { - S.StopAllSounds(); - CL.ClearEffects(); - CL.ClearTEnts(); - - // wipe the entire cl structure - - cl = new client_state_t(); - for (int i = 0; i < cl_entities.length; i++) { - cl_entities[i] = new centity_t(); - } - - SZ.Clear(cls.netchan.message); - } - - /* - ===================== - CL_Disconnect - - Goes from a connected state to full screen console state - Sends a disconnect message to the server - This is also called on Com_Error, so it shouldn't cause any errors - ===================== - */ - - static void Disconnect() { - - String fin; - - if (cls.state == ca_disconnected) - return; - - if (cl_timedemo != null && cl_timedemo.value != 0.0f) { - int time; - - time = (int) (Sys.Milliseconds() - cl.timedemo_start); - if (time > 0) - Com.Printf( - "%i frames, %3.1f seconds: %3.1f fps\n", - new Vargs(3).add(cl.timedemo_frames).add(time / 1000.0).add(cl.timedemo_frames * 1000.0 / time)); - } - - VectorClear(cl.refdef.blend); - //re.CinematicSetPalette(null); - - Menu.ForceMenuOff(); - - cls.connect_time = 0; - - // SCR.StopCinematic(); - - if (cls.demorecording) - CL.Stop_f.execute(); - - // send a disconnect message to the server - fin = (char) clc_stringcmd + "disconnect"; - Netchan.Transmit(cls.netchan, fin.length(), fin.getBytes()); - Netchan.Transmit(cls.netchan, fin.length(), fin.getBytes()); - Netchan.Transmit(cls.netchan, fin.length(), fin.getBytes()); - - CL.ClearState(); - - // stop download - if (cls.download != null) { - fclose(cls.download); - cls.download = null; - // fclose(cls.download); - // cls.download = NULL; - } - - cls.state = ca_disconnected; - } - - static xcommand_t Disconnect_f = new xcommand_t() { - public void execute() { - Com.Error(ERR_DROP, "Disconnected from server"); - } - }; - - /* - ================= - CL_Changing_f - - Just sent as a hint to the client that they should - drop to full console - ================= - */ - static xcommand_t Changing_f = new xcommand_t() { - public void execute() { - //ZOID - //if we are downloading, we don't change! - // This so we don't suddenly stop downloading a map - - if (cls.download != null) - return; - - SCR.BeginLoadingPlaque(); - cls.state = ca_connected; // not active anymore, but not disconnected - Com.Printf("\nChanging map...\n"); - } - }; - - /* - ================= - CL_Reconnect_f - - The server is changing levels - ================= - */ - static xcommand_t Reconnect_f = new xcommand_t() { - public void execute() { - //ZOID - //if we are downloading, we don't change! This so we don't suddenly stop downloading a map - if (cls.download != null) - return; - - S.StopAllSounds(); - if (cls.state == ca_connected) { - Com.Printf("reconnecting...\n"); - cls.state = ca_connected; - MSG.WriteChar(cls.netchan.message, clc_stringcmd); - MSG.WriteString(cls.netchan.message, "new"); - return; - } - - if (cls.servername != null) { - if (cls.state >= ca_connected) { - CL.Disconnect(); - cls.connect_time = cls.realtime - 1500; - } else - cls.connect_time = -99999; // fire immediately - - cls.state = ca_connecting; - Com.Printf("reconnecting...\n"); - } - } - }; - - /* - ================= - CL_ParseStatusMessage - - Handle a reply from a ping - ================= - */ - static void ParseStatusMessage() { - String s; - - s = MSG.ReadString(net_message); - - Com.Printf(s + "\n"); - Menu.AddToServerList(net_from, s); - } - - /* - ================= - CL_PingServers_f - ================= - */ - static xcommand_t PingServers_f = new xcommand_t() { - public void execute() { - int i; - netadr_t adr = new netadr_t(); - //char name[32]; - String name; - String adrstring; - cvar_t noudp; - cvar_t noipx; - - NET.Config(true); // allow remote - - // send a broadcast packet - Com.Printf("pinging broadcast...\n"); - - noudp = Cvar.Get("noudp", "0", CVAR_NOSET); - if (noudp.value == 0.0f) { - adr.type = NA_BROADCAST; - adr.port = PORT_SERVER; - //adr.port = BigShort(PORT_SERVER); - Netchan.OutOfBandPrint(NS_CLIENT, adr, "info " + PROTOCOL_VERSION); - } - - // we use no IPX - noipx = Cvar.Get("noipx", "1", CVAR_NOSET); - if (noipx.value == 0.0f) { - adr.type = NA_BROADCAST_IPX; - //adr.port = BigShort(PORT_SERVER); - adr.port = PORT_SERVER; - Netchan.OutOfBandPrint(NS_CLIENT, adr, "info " + PROTOCOL_VERSION); - } - - // send a packet to each address book entry - for (i = 0; i < 16; i++) { - //Com_sprintf (name, sizeof(name), "adr%i", i); - name = "adr" + i; - adrstring = Cvar.VariableString(name); - if (adrstring == null || adrstring.length() == 0) - continue; - - Com.Printf("pinging " + adrstring + "...\n"); - if (!NET.StringToAdr(adrstring, adr)) { - Com.Printf("Bad address: " + adrstring + "\n"); - continue; - } - if (adr.port == 0) - //adr.port = BigShort(PORT_SERVER); - adr.port = PORT_SERVER; - Netchan.OutOfBandPrint(NS_CLIENT, adr, "info " + PROTOCOL_VERSION); - } - } - }; - - - /* - ================= - CL_Skins_f - - Load or download any custom player skins and models - ================= - */ - static xcommand_t Skins_f = new xcommand_t() { - public void execute() { - int i; - - for (i = 0; i < MAX_CLIENTS; i++) { - if (cl.configstrings[CS_PLAYERSKINS + i] == null) - continue; - Com.Printf("client " + i + ": " + cl.configstrings[CS_PLAYERSKINS + i] + "\n"); - SCR.UpdateScreen(); - Sys.SendKeyEvents(); // pump message loop - CL.ParseClientinfo(i); - } - } - }; - - /* - ================= - CL_ConnectionlessPacket - - Responses to broadcasts, etc - ================= - */ - static void ConnectionlessPacket() { - String s; - String c; - - MSG.BeginReading(net_message); - MSG.ReadLong(net_message); // skip the -1 - - s = MSG.ReadStringLine(net_message); - - Cmd.TokenizeString(s.toCharArray(), false); - - c = Cmd.Argv(0); - - Com.Printf(NET.AdrToString(net_from) + ": " + c + "\n"); - - // server connection - if (c.equals("client_connect")) { - if (cls.state == ca_connected) { - Com.Printf("Dup connect received. Ignored.\n"); - return; - } - Netchan.Setup(NS_CLIENT, cls.netchan, net_from, cls.quakePort); - MSG.WriteChar(cls.netchan.message, clc_stringcmd); - MSG.WriteString(cls.netchan.message, "new"); - cls.state = ca_connected; - return; - } - - // server responding to a status broadcast - if (c.equals("info")) { - CL.ParseStatusMessage(); - return; - } - - // remote command from gui front end - if (c.equals ("cmd")) { - if (!NET.IsLocalAddress(net_from)) { - Com.Printf("Command packet from remote host. Ignored.\n"); - return; - } - s = MSG.ReadString(net_message); - Cbuf.AddText(s); - Cbuf.AddText("\n"); - return; - } - // print command from somewhere - if (c.equals("print")) { - s = MSG.ReadString(net_message); - Com.Printf(s); - return; - } - - // ping from somewhere - if (c.equals("ping")) { - Netchan.OutOfBandPrint(NS_CLIENT, net_from, "ack"); - return; - } - - // challenge from the server we are connecting to - if (c.equals("challenge")) { - cls.challenge = Integer.parseInt(Cmd.Argv(1)); - CL.SendConnectPacket(); - return; - } - - // echo request from server - if (c.equals("echo")) { - Netchan.OutOfBandPrint(NS_CLIENT, net_from, Cmd.Argv(1)); - return; - } - - Com.Printf("Unknown command.\n"); - } - - /* - ================= - CL_DumpPackets - - A vain attempt to help bad TCP stacks that cause problems - when they overflow - ================= - */ - static void DumpPackets() { - while (NET.GetPacket(NS_CLIENT, net_from, net_message)) { - Com.Printf("dumping a packet\n"); - } - } - - /* - ================= - CL_ReadPackets - ================= - */ - static void ReadPackets() { - while (NET.GetPacket(NS_CLIENT, net_from, net_message)) { - - // - // remote command packet - // - if (net_message.data[0] == -1 && net_message.data[1] == -1 - && net_message.data[2] == -1 && net_message.data[3] == -1) { - // if (*(int *)net_message.data == -1) - CL.ConnectionlessPacket(); - continue; - } - - if (cls.state == ca_disconnected || cls.state == ca_connecting) - continue; // dump it if not connected - - if (net_message.cursize < 8) { - Com.Printf(NET.AdrToString(net_from) + ": Runt packet\n"); - continue; - } - - // - // packet from server - // - if (!NET.CompareAdr(net_from, cls.netchan.remote_address)) { - Com.DPrintf(NET.AdrToString(net_from) + ":sequenced packet without connection\n"); - continue; - } - if (!Netchan.Process(cls.netchan, net_message)) - continue; // wasn't accepted for some reason - ParseServerMessage(); - } - - // - // check timeout - // - if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout.value * 1000) { - if (++cl.timeoutcount > 5) // timeoutcount saves debugger - { - Com.Printf("\nServer connection timed out.\n"); - CL.Disconnect(); - return; - } - } - else - cl.timeoutcount = 0; - } - - // ============================================================================= - - /* - ============== - CL_FixUpGender_f - ============== - */ - static void FixUpGender() { - - String sk; - - if (gender_auto.value != 0.0f) { - - if (gender.modified) { - // was set directly, don't override the user - gender.modified = false; - return; - } - - sk = skin.string; - if (sk.startsWith("male") || sk.startsWith("cyborg")) - Cvar.Set("gender", "male"); - else if (sk.startsWith("female") || sk.startsWith("crackhor")) - Cvar.Set("gender", "female"); - else - Cvar.Set("gender", "none"); - gender.modified = false; - } - } - - /* - ============== - CL_Userinfo_f - ============== - */ - static xcommand_t Userinfo_f = new xcommand_t() { - public void execute() { - Com.Printf("User info settings:\n"); - Info.Print(Cvar.Userinfo()); - } - }; - - /* - ================= - CL_Snd_Restart_f - - Restart the sound subsystem so it can pick up - new parameters and flush all sounds - ================= - */ - static xcommand_t Snd_Restart_f = new xcommand_t() { - public void execute() { - S.Shutdown(); - S.Init(); - CL.RegisterSounds(); - } - }; - - static int precache_check; // for autodownload of precache items - static int precache_spawncount; - static int precache_tex; - static int precache_model_skin; - - static byte precache_model[]; // used for skin checking in alias models - - public static final int PLAYER_MULT = 5; - - // ENV_CNT is map load, ENV_CNT+1 is first env map - public static final int ENV_CNT = (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT); - public static final int TEXTURE_CNT = (ENV_CNT + 13); - - static String env_suf[] = { "rt", "bk", "lf", "ft", "up", "dn" }; - - public static void RequestNextDownload() { - int map_checksum = 0; // for detecting cheater maps - //char fn[MAX_OSPATH]; - String fn; - - qfiles.dmdl_t pheader; - - if (cls.state != ca_connected) - return; - - if (SV_MAIN.allow_download.value == 0 && precache_check < ENV_CNT) - precache_check = ENV_CNT; - - // ZOID - if (precache_check == CS_MODELS) { // confirm map - precache_check = CS_MODELS + 2; // 0 isn't used - if (SV_MAIN.allow_download_maps.value != 0) - if (!CheckOrDownloadFile(cl.configstrings[CS_MODELS + 1])) - return; // started a download - } - if (precache_check >= CS_MODELS && precache_check < CS_MODELS + MAX_MODELS) { - if (SV_MAIN.allow_download_models.value != 0) { - while (precache_check < CS_MODELS + MAX_MODELS && cl.configstrings[precache_check].length() > 0) { - if (cl.configstrings[precache_check].charAt(0) == '*' || cl.configstrings[precache_check].charAt(0) == '#') { - precache_check++; - continue; - } - if (precache_model_skin == 0) { - if (!CheckOrDownloadFile(cl.configstrings[precache_check])) { - precache_model_skin = 1; - return; // started a download - } - precache_model_skin = 1; - } - - // checking for skins in the model - if (precache_model == null) { - - precache_model = FS.LoadFile(cl.configstrings[precache_check]); - if (precache_model == null) { - precache_model_skin = 0; - precache_check++; - continue; // couldn't load it - } - ByteBuffer bb = ByteBuffer.wrap(precache_model); - bb.order(ByteOrder.LITTLE_ENDIAN); - - int header = bb.getInt(); - - if (header != qfiles.IDALIASHEADER) { - // not an alias model - FS.FreeFile(precache_model); - precache_model = null; - precache_model_skin = 0; - precache_check++; - continue; - } - pheader = new qfiles.dmdl_t(ByteBuffer.wrap(precache_model).order(ByteOrder.LITTLE_ENDIAN)); - if (pheader.version != ALIAS_VERSION) { - precache_check++; - precache_model_skin = 0; - continue; // couldn't load it - } - } - - pheader = new qfiles.dmdl_t(ByteBuffer.wrap(precache_model).order(ByteOrder.LITTLE_ENDIAN)); - - int num_skins = pheader.num_skins; - - while (precache_model_skin - 1 < num_skins) { - //Com.Printf("critical code section because of endian mess!\n"); - - String name = - new String( - precache_model, - pheader.ofs_skins + (precache_model_skin - 1) * MAX_SKINNAME, - MAX_SKINNAME * num_skins); - - if (!CheckOrDownloadFile(name)) { - precache_model_skin++; - return; // started a download - } - precache_model_skin++; - } - if (precache_model != null) { - FS.FreeFile(precache_model); - precache_model = null; - } - precache_model_skin = 0; - precache_check++; - } - } - precache_check = CS_SOUNDS; - } - if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS + MAX_SOUNDS) { - if (SV_MAIN.allow_download_sounds.value != 0) { - if (precache_check == CS_SOUNDS) - precache_check++; // zero is blank - while (precache_check < CS_SOUNDS + MAX_SOUNDS && cl.configstrings[precache_check].length() > 0) { - if (cl.configstrings[precache_check].charAt(0) == '*') { - precache_check++; - continue; - } - fn = "sound/" + cl.configstrings[precache_check++]; - if (!CheckOrDownloadFile(fn)) - return; // started a download - } - } - precache_check = CS_IMAGES; - } - if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES + MAX_IMAGES) { - if (precache_check == CS_IMAGES) - precache_check++; // zero is blank - - while (precache_check < CS_IMAGES + MAX_IMAGES && cl.configstrings[precache_check].length() > 0) { - fn = "pics/" + cl.configstrings[precache_check++] + ".pcx"; - if (!CheckOrDownloadFile(fn)) - return; // started a download - } - precache_check = CS_PLAYERSKINS; - } - // skins are special, since a player has three things to download: - // model, weapon model and skin - // so precache_check is now *3 - if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) { - if (SV_MAIN.allow_download_players.value != 0) { - while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) { - - int i, n; - //char model[MAX_QPATH], skin[MAX_QPATH], * p; - String model, skin; - - i = (precache_check - CS_PLAYERSKINS) / PLAYER_MULT; - n = (precache_check - CS_PLAYERSKINS) % PLAYER_MULT; - - if (cl.configstrings[CS_PLAYERSKINS + i].length() == 0) { - precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT; - continue; - } - - int pos = cl.configstrings[CS_PLAYERSKINS + i].indexOf('\\'); - if (pos != -1) - pos++; - else - pos = 0; - - model = cl.configstrings[CS_PLAYERSKINS + i].substring(pos); - - pos = model.indexOf('/'); - - if (pos == -1) - pos = model.indexOf('\\'); - - if (pos != -1) { - skin = model.substring(pos + 1); - } - else - skin = ""; - - switch (n) { - case 0 : // model - fn = "players/" + model + "/tris.md2"; - if (!CheckOrDownloadFile(fn)) { - precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1; - return; // started a download - } - n++; - /*FALL THROUGH*/ - - case 1 : // weapon model - fn = "players/" + model + "/weapon.md2"; - if (!CheckOrDownloadFile(fn)) { - precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2; - return; // started a download - } - n++; - /*FALL THROUGH*/ - - case 2 : // weapon skin - fn = "players/" + model + "/weapon.pcx"; - if (!CheckOrDownloadFile(fn)) { - precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 3; - return; // started a download - } - n++; - /*FALL THROUGH*/ - - case 3 : // skin - fn = "players/" + model + "/" + skin + ".pcx"; - if (!CheckOrDownloadFile(fn)) { - precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 4; - return; // started a download - } - n++; - /*FALL THROUGH*/ - - case 4 : // skin_i - fn = "players/" + model + "/" + skin + "_i.pcx"; - if (!CheckOrDownloadFile(fn)) { - precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5; - return; // started a download - } - // move on to next model - precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT; - } - } - } - // precache phase completed - precache_check = ENV_CNT; - } - - if (precache_check == ENV_CNT) { - precache_check = ENV_CNT + 1; - - int iw[] = {map_checksum}; - - CM.CM_LoadMap(cl.configstrings[CS_MODELS + 1], true, iw); - map_checksum = iw[0]; - - if ((map_checksum ^ atoi(cl.configstrings[CS_MAPCHECKSUM])) != 0) { - Com.Error( - ERR_DROP, - "Local map version differs from server: " + map_checksum + " != '" + cl.configstrings[CS_MAPCHECKSUM] + "'\n"); - return; - } - } - - if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT) { - if (SV_MAIN.allow_download.value != 0 && SV_MAIN.allow_download_maps.value != 0) { - while (precache_check < TEXTURE_CNT) { - int n = precache_check++ -ENV_CNT - 1; - - if ((n & 1) != 0) - fn = "env/" + cl.configstrings[CS_SKY] + env_suf[n / 2] + ".pcx"; - else - fn = "env/" + cl.configstrings[CS_SKY] + env_suf[n / 2] + ".tga"; - if (!CheckOrDownloadFile(fn)) - return; // started a download - } - } - precache_check = TEXTURE_CNT; - } - - if (precache_check == TEXTURE_CNT) { - precache_check = TEXTURE_CNT + 1; - precache_tex = 0; - } - - // confirm existance of textures, download any that don't exist - if (precache_check == TEXTURE_CNT + 1) { - // from qcommon/cmodel.c - // extern int numtexinfo; - // extern mapsurface_t map_surfaces[]; - - if (SV_MAIN.allow_download.value != 0 && SV_MAIN.allow_download_maps.value != 0) { - while (precache_tex < CM.numtexinfo) { - //char fn[MAX_OSPATH]; - - fn = "textures/" + CM.map_surfaces[precache_tex++].rname + ".wal"; - if (!CheckOrDownloadFile(fn)) - return; // started a download - } - } - precache_check = TEXTURE_CNT + 999; - } - - // ZOID - CL.RegisterSounds(); - PrepRefresh(); - - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - MSG.WriteString(cls.netchan.message, "begin " + precache_spawncount + "\n"); - } - - /* - ================= - CL_Precache_f - - The server will send this command right - before allowing the client into the server - ================= - */ - static xcommand_t Precache_f = new xcommand_t() { - public void execute() { - /* Yet another hack to let old demos work - the old precache sequence */ - - if (Cmd.Argc() < 2) { - - int iw[] ={0};// for detecting cheater maps - - - CM.CM_LoadMap(cl.configstrings[CS_MODELS + 1], true, iw); - int mapchecksum = iw[0] ; - CL.RegisterSounds(); - CL.PrepRefresh(); - return; - } - - precache_check = CS_MODELS; - precache_spawncount = atoi(Cmd.Argv(1)); - precache_model = null; - precache_model_skin = 0; - - RequestNextDownload(); - } - }; - - /* - ================= - CL_InitLocal - ================= - */ - public static void InitLocal() { - cls.state = Defines.ca_disconnected; - cls.realtime = Sys.Milliseconds(); - - InitInput(); - - // never used !! -// adr0 = Cvar.Get("adr0", "", CVAR_ARCHIVE); -// adr1 = Cvar.Get("adr1", "", CVAR_ARCHIVE); -// adr2 = Cvar.Get("adr2", "", CVAR_ARCHIVE); -// adr3 = Cvar.Get("adr3", "", CVAR_ARCHIVE); -// adr4 = Cvar.Get("adr4", "", CVAR_ARCHIVE); -// adr5 = Cvar.Get("adr5", "", CVAR_ARCHIVE); -// adr6 = Cvar.Get("adr6", "", CVAR_ARCHIVE); -// adr7 = Cvar.Get("adr7", "", CVAR_ARCHIVE); -// adr8 = Cvar.Get("adr8", "", CVAR_ARCHIVE); - - // - // register our variables - // - cl_stereo_separation = Cvar.Get("cl_stereo_separation", "0.4", CVAR_ARCHIVE); - cl_stereo = Cvar.Get("cl_stereo", "0", 0); - - cl_add_blend = Cvar.Get("cl_blend", "1", 0); - cl_add_lights = Cvar.Get("cl_lights", "1", 0); - cl_add_particles = Cvar.Get("cl_particles", "1", 0); - cl_add_entities = Cvar.Get("cl_entities", "1", 0); - cl_gun = Cvar.Get("cl_gun", "1", 0); - cl_footsteps = Cvar.Get("cl_footsteps", "1", 0); - cl_noskins = Cvar.Get("cl_noskins", "0", 0); - cl_autoskins = Cvar.Get("cl_autoskins", "0", 0); - cl_predict = Cvar.Get("cl_predict", "1", 0); - - cl_maxfps = Cvar.Get("cl_maxfps", "90", 0); - - cl_upspeed = Cvar.Get("cl_upspeed", "200", 0); - cl_forwardspeed = Cvar.Get("cl_forwardspeed", "200", 0); - cl_sidespeed = Cvar.Get("cl_sidespeed", "200", 0); - cl_yawspeed = Cvar.Get("cl_yawspeed", "140", 0); - cl_pitchspeed = Cvar.Get("cl_pitchspeed", "150", 0); - cl_anglespeedkey = Cvar.Get("cl_anglespeedkey", "1.5", 0); - - cl_run = Cvar.Get("cl_run", "0", CVAR_ARCHIVE); - lookspring = Cvar.Get("lookspring", "0", CVAR_ARCHIVE); - lookstrafe = Cvar.Get("lookstrafe", "0", CVAR_ARCHIVE); - sensitivity = Cvar.Get("sensitivity", "3", CVAR_ARCHIVE); - - m_pitch = Cvar.Get("m_pitch", "0.022", CVAR_ARCHIVE); - m_yaw = Cvar.Get("m_yaw", "0.022", 0); - m_forward = Cvar.Get("m_forward", "1", 0); - m_side = Cvar.Get("m_side", "1", 0); - - cl_shownet = Cvar.Get("cl_shownet", "0", 0); - cl_showmiss = Cvar.Get("cl_showmiss", "0", 0); - cl_showclamp = Cvar.Get("showclamp", "0", 0); - cl_timeout = Cvar.Get("cl_timeout", "120", 0); - cl_paused = Cvar.Get("paused", "0", 0); - cl_timedemo = Cvar.Get("timedemo", "0", 0); - - rcon_client_password = Cvar.Get("rcon_password", "", 0); - rcon_address = Cvar.Get("rcon_address", "", 0); - - cl_lightlevel = Cvar.Get("r_lightlevel", "0", 0); - - // - // userinfo - // - info_password = Cvar.Get("password", "", CVAR_USERINFO); - info_spectator = Cvar.Get("spectator", "0", CVAR_USERINFO); - name = Cvar.Get("name", "unnamed", CVAR_USERINFO | CVAR_ARCHIVE); - skin = Cvar.Get("skin", "male/grunt", CVAR_USERINFO | CVAR_ARCHIVE); - rate = Cvar.Get("rate", "25000", CVAR_USERINFO | CVAR_ARCHIVE); // FIXME - msg = Cvar.Get("msg", "1", CVAR_USERINFO | CVAR_ARCHIVE); - hand = Cvar.Get("hand", "0", CVAR_USERINFO | CVAR_ARCHIVE); - fov = Cvar.Get("fov", "90", CVAR_USERINFO | CVAR_ARCHIVE); - gender = Cvar.Get("gender", "male", CVAR_USERINFO | CVAR_ARCHIVE); - gender_auto = Cvar.Get("gender_auto", "1", CVAR_ARCHIVE); - gender.modified = false; // clear this so we know when user sets it manually - - cl_vwep = Cvar.Get("cl_vwep", "1", CVAR_ARCHIVE); - - // - // register our commands - // - Cmd.AddCommand("cmd", ForwardToServer_f); - Cmd.AddCommand("pause", Pause_f); - Cmd.AddCommand("pingservers", PingServers_f); - Cmd.AddCommand("skins", Skins_f); - - Cmd.AddCommand("userinfo", Userinfo_f); - Cmd.AddCommand("snd_restart", Snd_Restart_f); - - Cmd.AddCommand("changing", Changing_f); - Cmd.AddCommand("disconnect", Disconnect_f); - Cmd.AddCommand("record", Record_f); - Cmd.AddCommand("stop", Stop_f); - - Cmd.AddCommand("quit", Quit_f); - - Cmd.AddCommand("connect", Connect_f); - Cmd.AddCommand("reconnect", Reconnect_f); - - Cmd.AddCommand("rcon", Rcon_f); - - Cmd.AddCommand("precache", Precache_f); - - Cmd.AddCommand("download", Download_f); - - // - // forward to server commands - // - // the only thing this does is allow command completion - // to work -- all unknown commands are automatically - // forwarded to the server - Cmd.AddCommand("wave", null); - Cmd.AddCommand("inven", null); - Cmd.AddCommand("kill", null); - Cmd.AddCommand("use", null); - Cmd.AddCommand("drop", null); - Cmd.AddCommand("say", null); - Cmd.AddCommand("say_team", null); - Cmd.AddCommand("info", null); - Cmd.AddCommand("prog", null); - Cmd.AddCommand("give", null); - Cmd.AddCommand("god", null); - Cmd.AddCommand("notarget", null); - Cmd.AddCommand("noclip", null); - Cmd.AddCommand("invuse", null); - Cmd.AddCommand("invprev", null); - Cmd.AddCommand("invnext", null); - Cmd.AddCommand("invdrop", null); - Cmd.AddCommand("weapnext", null); - Cmd.AddCommand("weapprev", null); - - } - - /* - =============== - CL_WriteConfiguration - - Writes key bindings and archived cvars to config.cfg - =============== - */ - static void WriteConfiguration() { - RandomAccessFile f; - String path; - - if (cls.state == ca_uninitialized) - return; - - path = FS.Gamedir() + "/config.cfg"; - f = fopen(path, "rw"); - if (f == null) { - Com.Printf("Couldn't write config.cfg.\n"); - return; - } - try - { - f.seek(0); - f.setLength(0); - } - catch (IOException e1) - {} - try { - f.writeBytes("// generated by quake, do not modify\n"); - } - catch (IOException e) {} - - Key.WriteBindings(f); - fclose(f); - Cvar.WriteVariables(path); - } - - /* - ================== - CL_FixCvarCheats - - ================== - */ - public static class cheatvar_t { - String name; - String value; - cvar_t var; - } - - public static String cheatvarsinfo[][] = { { "timescale", "1" }, { - "timedemo", "0" }, { - "r_drawworld", "1" }, { - "cl_testlights", "0" }, { - "r_fullbright", "0" }, { - "r_drawflat", "0" }, { - "paused", "0" }, { - "fixedtime", "0" }, { - "sw_draworder", "0" }, { - "gl_lightmap", "0" }, { - "gl_saturatelighting", "0" }, { - null, null } - }; - public static cheatvar_t cheatvars[]; - - static { - cheatvars = new cheatvar_t[cheatvarsinfo.length]; - for (int n = 0; n < cheatvarsinfo.length; n++) { - cheatvars[n] = new cheatvar_t(); - cheatvars[n].name = cheatvarsinfo[n][0]; - cheatvars[n].value = cheatvarsinfo[n][1]; - } - } - - static int numcheatvars; - - public static void FixCvarCheats() { - int i; - cheatvar_t var; - - if ("1".equals(cl.configstrings[CS_MAXCLIENTS]) || 0 == cl.configstrings[CS_MAXCLIENTS].length()) - return; // single player can cheat - - // find all the cvars if we haven't done it yet - if (0 == numcheatvars) { - while (cheatvars[numcheatvars].name != null) { - cheatvars[numcheatvars].var = Cvar.Get(cheatvars[numcheatvars].name, cheatvars[numcheatvars].value, 0); - numcheatvars++; - } - } - - // make sure they are all set to the proper values - for (i = 0; i < numcheatvars; i++) { - var = cheatvars[i]; - if (!var.var.string.equals(var.value)) { - Cvar.Set(var.name, var.value); - } - } - } - - // ============================================================================ - - /* - ================== - CL_SendCommand - - ================== - */ - public static void SendCommand() { - // get new key events - Sys.SendKeyEvents(); - - // allow mice or other external controllers to add commands - IN.Commands(); - - // process console commands - Cbuf.Execute(); - - // fix any cheating cvars - FixCvarCheats(); - - // send intentions now - SendCmd(); - - // resend a connection request if necessary - CheckForResend(); - } - - /* - ================== - CL_Frame - - ================== - */ - private static int extratime; -// private static int lasttimecalled; - - public static void Frame(int msec) { - - extratime += msec; - - if (cl_timedemo.value == 0.0f) { - if (cls.state == ca_connected && extratime < 100) { - return; // don't flood packets out while connecting - } - if (extratime < 1000 / cl_maxfps.value) { - return; // framerate is too high - } - } - - // let the mouse activate or deactivate - IN.Frame(); - - // decide the simulation time - cls.frametime = extratime / 1000.0f; - cl.time += extratime; - cls.realtime = curtime; - - extratime = 0; - - if (cls.frametime > (1.0f / 5)) - cls.frametime = (1.0f / 5); - - // if in the debugger last frame, don't timeout - if (msec > 5000) - cls.netchan.last_received = Sys.Milliseconds(); - - // fetch results from server - CL.ReadPackets(); - - // send a new command message to the server - SendCommand(); - - // predict all unacknowledged movements - CL.PredictMovement(); - - // allow rendering DLL change - VID.CheckChanges(); - if (!cl.refresh_prepped && cls.state == ca_active) { - CL.PrepRefresh(); - // force GC after level loading - System.gc(); - } - - SCR.UpdateScreen(); - - // update audio - S.Update(cl.refdef.vieworg, cl.v_forward, cl.v_right, cl.v_up); - - // advance local effects for next frame - CL.RunDLights(); - CL.RunLightStyles(); - - SCR.RunConsole(); - - cls.framecount++; - if (cls.state != ca_active || cls.key_dest != key_game) { - try { - Thread.sleep(20); - } catch (InterruptedException e) {} - } - } - - // ============================================================================ +public final class CL { + + static int precache_check; // for autodownload of precache items + + static int precache_spawncount; + + static int precache_tex; + + static int precache_model_skin; + + static byte precache_model[]; // used for skin checking in alias models + + public static final int PLAYER_MULT = 5; + + /* + * ================== CL_FixCvarCheats + * + * ================== + */ + public static class cheatvar_t { + String name; + + String value; + + cvar_t var; + } + + public static String cheatvarsinfo[][] = { { "timescale", "1" }, + { "timedemo", "0" }, { "r_drawworld", "1" }, + { "cl_testlights", "0" }, { "r_fullbright", "0" }, + { "r_drawflat", "0" }, { "paused", "0" }, { "fixedtime", "0" }, + { "sw_draworder", "0" }, { "gl_lightmap", "0" }, + { "gl_saturatelighting", "0" }, { null, null } }; + + public static cheatvar_t cheatvars[]; + + static { + cheatvars = new cheatvar_t[cheatvarsinfo.length]; + for (int n = 0; n < cheatvarsinfo.length; n++) { + cheatvars[n] = new cheatvar_t(); + cheatvars[n].name = cheatvarsinfo[n][0]; + cheatvars[n].value = cheatvarsinfo[n][1]; + } + } + + static int numcheatvars; + + /* + * ==================== CL_Stop_f + * + * stop recording a demo ==================== + */ + static xcommand_t Stop_f = new xcommand_t() { + public void execute() { + try { + + int len; + + if (!Globals.cls.demorecording) { + Com.Printf("Not recording a demo.\n"); + return; + } + + // finish up + len = -1; + Globals.cls.demofile.writeInt(len); + Globals.cls.demofile.close(); + Globals.cls.demofile = null; + Globals.cls.demorecording = false; + Com.Printf("Stopped demo.\n"); + } catch (IOException e) { + } + } + }; + + /* + * ==================== CL_Record_f + * + * record <demoname> + * + * Begins recording a demo from the current position ==================== + */ + static entity_state_t nullstate = new entity_state_t(null); + + static xcommand_t Record_f = new xcommand_t() { + public void execute() { + try { + String name; + byte buf_data[] = new byte[Defines.MAX_MSGLEN]; + sizebuf_t buf = new sizebuf_t(); + int i; + entity_state_t ent; + + if (Cmd.Argc() != 2) { + Com.Printf("record <demoname>\n"); + return; + } + + if (Globals.cls.demorecording) { + Com.Printf("Already recording.\n"); + return; + } + + if (Globals.cls.state != Defines.ca_active) { + Com.Printf("You must be in a level to record.\n"); + return; + } + + // + // open the demo file + // + name = FS.Gamedir() + "/demos/" + Cmd.Argv(1) + ".dm2"; + + Com.Printf("recording to " + name + ".\n"); + FS.CreatePath(name); + Globals.cls.demofile = new RandomAccessFile(name, "rw"); + if (Globals.cls.demofile == null) { + Com.Printf("ERROR: couldn't open.\n"); + return; + } + Globals.cls.demorecording = true; + + // don't start saving messages until a non-delta compressed + // message is received + Globals.cls.demowaiting = true; + + // + // write out messages to hold the startup information + // + SZ.Init(buf, buf_data, Defines.MAX_MSGLEN); + + // send the serverdata + MSG.WriteByte(buf, Defines.svc_serverdata); + MSG.WriteInt(buf, Defines.PROTOCOL_VERSION); + MSG.WriteInt(buf, 0x10000 + Globals.cl.servercount); + MSG.WriteByte(buf, 1); // demos are always attract loops + MSG.WriteString(buf, Globals.cl.gamedir); + MSG.WriteShort(buf, Globals.cl.playernum); + + MSG.WriteString(buf, Globals.cl.configstrings[Defines.CS_NAME]); + + // configstrings + for (i = 0; i < Defines.MAX_CONFIGSTRINGS; i++) { + if (Globals.cl.configstrings[i].length() > 0) { + if (buf.cursize + Globals.cl.configstrings[i].length() + + 32 > buf.maxsize) { // write it out + //len = LittleLong(buf.cursize); + //fwrite(& len, 4, 1, cls.demofile); + Globals.cls.demofile.writeInt(buf.cursize); + //fwrite(buf.data, buf.cursize, 1, cls.demofile); + Globals.cls.demofile + .write(buf.data, 0, buf.cursize); + buf.cursize = 0; + } + + MSG.WriteByte(buf, Defines.svc_configstring); + MSG.WriteShort(buf, i); + MSG.WriteString(buf, Globals.cl.configstrings[i]); + } + + } + + // baselines + //memset( nullstate, 0, sizeof(nullstate)); + for (i = 0; i < Defines.MAX_EDICTS; i++) { + ent = Globals.cl_entities[i].baseline; + if (ent.modelindex == 0) + continue; + + if (buf.cursize + 64 > buf.maxsize) { // write it out + //len = LittleLong(buf.cursize); + //fwrite(& len, 4, 1, cls.demofile); + Globals.cls.demofile.writeInt(buf.cursize); + //fwrite(buf.data, buf.cursize, 1, cls.demofile); + Globals.cls.demofile.write(buf.data, 0, buf.cursize); + buf.cursize = 0; + } + + MSG.WriteByte(buf, Defines.svc_spawnbaseline); + MSG.WriteDeltaEntity(nullstate, + Globals.cl_entities[i].baseline, buf, true, true); + } + + MSG.WriteByte(buf, Defines.svc_stufftext); + MSG.WriteString(buf, "precache\n"); + + // write it to the demo file + + //len = LittleLong(buf.cursize); + //fwrite(& len, 4, 1, cls.demofile); + Globals.cls.demofile.writeInt(buf.cursize); + //fwrite(buf.data, buf.cursize, 1, cls.demofile); + Globals.cls.demofile.write(buf.data, 0, buf.cursize); + // the rest of the demo file will be individual frames + + } catch (IOException e) { + } + } + }; + + /* + * ================== CL_ForwardToServer_f ================== + */ + static xcommand_t ForwardToServer_f = new xcommand_t() { + public void execute() { + if (Globals.cls.state != Defines.ca_connected + && Globals.cls.state != Defines.ca_active) { + Com.Printf("Can't \"" + Cmd.Argv(0) + "\", not connected\n"); + return; + } + + // don't forward the first argument + if (Cmd.Argc() > 1) { + MSG.WriteByte(Globals.cls.netchan.message, + Defines.clc_stringcmd); + SZ.Print(Globals.cls.netchan.message, Cmd.Args()); + } + } + }; + + /* + * ================== CL_Pause_f ================== + */ + static xcommand_t Pause_f = new xcommand_t() { + public void execute() { + // never pause in multiplayer + + if (Cvar.VariableValue("maxclients") > 1 + || Globals.server_state == 0) { + Cvar.SetValue("paused", 0); + return; + } + + Cvar.SetValue("paused", Globals.cl_paused.value); + } + }; + + /* + * ================== CL_Quit_f ================== + */ + static xcommand_t Quit_f = new xcommand_t() { + public void execute() { + Disconnect(); + Com.Quit(); + } + }; + + /* + * ================ CL_Connect_f + * + * ================ + */ + static xcommand_t Connect_f = new xcommand_t() { + public void execute() { + String server; + + if (Cmd.Argc() != 2) { + Com.Printf("usage: connect <server>\n"); + return; + } + + if (Globals.server_state != 0) { + // if running a local server, kill it and reissue + SV_MAIN.SV_Shutdown("Server quit\n", false); + } else { + Disconnect(); + } + + server = Cmd.Argv(1); + + NET.Config(true); // allow remote + + Disconnect(); + + Globals.cls.state = Defines.ca_connecting; + //strncpy (cls.servername, server, sizeof(cls.servername)-1); + Globals.cls.servername = server; + Globals.cls.connect_time = -99999; + // CL_CheckForResend() will fire immediately + } + }; + + /* + * ===================== CL_Rcon_f + * + * Send the rest of the command line over as an unconnected command. + * ===================== + */ + static xcommand_t Rcon_f = new xcommand_t() { + public void execute() { + StringBuffer message = new StringBuffer(1024); + int i; + netadr_t to = new netadr_t(); + + if (Globals.rcon_client_password.string == null) { + Com + .Printf("You must set 'rcon_password' before\nissuing an rcon command.\n"); + return; + } + + message.append((char) 255); + message.append((char) 255); + message.append((char) 255); + message.append((char) 255); + + NET.Config(true); // allow remote + + //strcat (message, "rcon "); + message.append("rcon "); + + //strcat (message, rcon_client_password.string); + message.append(Globals.rcon_client_password.string); + //strcat (message, " "); + message.append(" "); + + for (i = 1; i < Cmd.Argc(); i++) { + //strcat (message, Cmd.Argv(i)); + message.append(Cmd.Argv(i)); + //strcat (message, " "); + message.append(" "); + } + + if (Globals.cls.state >= Defines.ca_connected) + to = Globals.cls.netchan.remote_address; + else { + if (Globals.rcon_address.string.length() == 0) { + Com + .Printf("You must either be connected,\nor set the 'rcon_address' cvar\nto issue rcon commands\n"); + + return; + } + NET.StringToAdr(Globals.rcon_address.string, to); + if (to.port == 0) + //to.port = BigShort (PORT_SERVER); + to.port = Defines.PORT_SERVER; + } + message.append('\0'); + String b = message.toString(); + NET.SendPacket(Defines.NS_CLIENT, b.length(), b.getBytes(), to); + } + }; + + static xcommand_t Disconnect_f = new xcommand_t() { + public void execute() { + Com.Error(Defines.ERR_DROP, "Disconnected from server"); + } + }; + + /* + * ================= CL_Changing_f + * + * Just sent as a hint to the client that they should drop to full console + * ================= + */ + static xcommand_t Changing_f = new xcommand_t() { + public void execute() { + //ZOID + //if we are downloading, we don't change! + // This so we don't suddenly stop downloading a map + + if (Globals.cls.download != null) + return; + + SCR.BeginLoadingPlaque(); + Globals.cls.state = Defines.ca_connected; // not active anymore, but + // not disconnected + Com.Printf("\nChanging map...\n"); + } + }; + + /* + * ================= CL_Reconnect_f + * + * The server is changing levels ================= + */ + static xcommand_t Reconnect_f = new xcommand_t() { + public void execute() { + //ZOID + //if we are downloading, we don't change! This so we don't suddenly + // stop downloading a map + if (Globals.cls.download != null) + return; + + S.StopAllSounds(); + if (Globals.cls.state == Defines.ca_connected) { + Com.Printf("reconnecting...\n"); + Globals.cls.state = Defines.ca_connected; + MSG.WriteChar(Globals.cls.netchan.message, + Defines.clc_stringcmd); + MSG.WriteString(Globals.cls.netchan.message, "new"); + return; + } + + if (Globals.cls.servername != null) { + if (Globals.cls.state >= Defines.ca_connected) { + Disconnect(); + Globals.cls.connect_time = Globals.cls.realtime - 1500; + } else + Globals.cls.connect_time = -99999; // fire immediately + + Globals.cls.state = Defines.ca_connecting; + Com.Printf("reconnecting...\n"); + } + } + }; + + /* + * ================= CL_PingServers_f ================= + */ + static xcommand_t PingServers_f = new xcommand_t() { + public void execute() { + int i; + netadr_t adr = new netadr_t(); + //char name[32]; + String name; + String adrstring; + cvar_t noudp; + cvar_t noipx; + + NET.Config(true); // allow remote + + // send a broadcast packet + Com.Printf("pinging broadcast...\n"); + + noudp = Cvar.Get("noudp", "0", Defines.CVAR_NOSET); + if (noudp.value == 0.0f) { + adr.type = Defines.NA_BROADCAST; + adr.port = Defines.PORT_SERVER; + //adr.port = BigShort(PORT_SERVER); + Netchan.OutOfBandPrint(Defines.NS_CLIENT, adr, "info " + + Defines.PROTOCOL_VERSION); + } + + // we use no IPX + noipx = Cvar.Get("noipx", "1", Defines.CVAR_NOSET); + if (noipx.value == 0.0f) { + adr.type = Defines.NA_BROADCAST_IPX; + //adr.port = BigShort(PORT_SERVER); + adr.port = Defines.PORT_SERVER; + Netchan.OutOfBandPrint(Defines.NS_CLIENT, adr, "info " + + Defines.PROTOCOL_VERSION); + } + + // send a packet to each address book entry + for (i = 0; i < 16; i++) { + //Com_sprintf (name, sizeof(name), "adr%i", i); + name = "adr" + i; + adrstring = Cvar.VariableString(name); + if (adrstring == null || adrstring.length() == 0) + continue; + + Com.Printf("pinging " + adrstring + "...\n"); + if (!NET.StringToAdr(adrstring, adr)) { + Com.Printf("Bad address: " + adrstring + "\n"); + continue; + } + if (adr.port == 0) + //adr.port = BigShort(PORT_SERVER); + adr.port = Defines.PORT_SERVER; + Netchan.OutOfBandPrint(Defines.NS_CLIENT, adr, "info " + + Defines.PROTOCOL_VERSION); + } + } + }; + + /* + * ================= CL_Skins_f + * + * Load or download any custom player skins and models ================= + */ + static xcommand_t Skins_f = new xcommand_t() { + public void execute() { + int i; + + for (i = 0; i < Defines.MAX_CLIENTS; i++) { + if (Globals.cl.configstrings[Defines.CS_PLAYERSKINS + i] == null) + continue; + Com.Printf("client " + i + ": " + + Globals.cl.configstrings[Defines.CS_PLAYERSKINS + i] + + "\n"); + SCR.UpdateScreen(); + Sys.SendKeyEvents(); // pump message loop + CL_parse.ParseClientinfo(i); + } + } + }; + + /* + * ============== CL_Userinfo_f ============== + */ + static xcommand_t Userinfo_f = new xcommand_t() { + public void execute() { + Com.Printf("User info settings:\n"); + Info.Print(Cvar.Userinfo()); + } + }; + + /* + * ================= CL_Snd_Restart_f + * + * Restart the sound subsystem so it can pick up new parameters and flush + * all sounds ================= + */ + static xcommand_t Snd_Restart_f = new xcommand_t() { + public void execute() { + S.Shutdown(); + S.Init(); + CL_parse.RegisterSounds(); + } + }; + + // ENV_CNT is map load, ENV_CNT+1 is first env map + public static final int ENV_CNT = (Defines.CS_PLAYERSKINS + Defines.MAX_CLIENTS + * CL.PLAYER_MULT); + + public static final int TEXTURE_CNT = (ENV_CNT + 13); + + static String env_suf[] = { "rt", "bk", "lf", "ft", "up", "dn" }; + + /* + * ================= CL_Precache_f + * + * The server will send this command right before allowing the client into + * the server ================= + */ + static xcommand_t Precache_f = new xcommand_t() { + public void execute() { + /* + * Yet another hack to let old demos work the old precache sequence + */ + + if (Cmd.Argc() < 2) { + + int iw[] = { 0 }; // for detecting cheater maps + + CM.CM_LoadMap(Globals.cl.configstrings[Defines.CS_MODELS + 1], + true, iw); + int mapchecksum = iw[0]; + CL_parse.RegisterSounds(); + CL_view.PrepRefresh(); + return; + } + + CL.precache_check = Defines.CS_MODELS; + CL.precache_spawncount = Lib.atoi(Cmd.Argv(1)); + CL.precache_model = null; + CL.precache_model_skin = 0; + + RequestNextDownload(); + } + }; + + /* + * ================== CL_Frame + * + * ================== + */ + private static int extratime; + + // ============================================================================ + + /* + * =============== CL_Shutdown + * + * FIXME: this is a callback from Sys_Quit and Com_Error. It would be better + * to run quit through here before the final handoff to the sys code. + * =============== + */ + static boolean isdown = false; + + /* + * ==================== CL_WriteDemoMessage + * + * Dumps the current net message, prefixed by the length + * ==================== + */ + static void WriteDemoMessage() { + int swlen; + + // the first eight bytes are just packet sequencing stuff + swlen = Globals.net_message.cursize - 8; + + try { + Globals.cls.demofile.writeInt(swlen); + //fwrite (&swlen, 4, 1, cls.demofile); + Globals.cls.demofile.write(Globals.net_message.data, 8, swlen); + //fwrite (net_message.data+8, len, 1, cls.demofile); + } catch (IOException e) { + } + + } + + /* + * ======================= CL_SendConnectPacket + * + * We have gotten a challenge from the server, so try and connect. + * ====================== + */ + static void SendConnectPacket() { + netadr_t adr = new netadr_t(); + int port; + + if (!NET.StringToAdr(Globals.cls.servername, adr)) { + Com.Printf("Bad server address\n"); + Globals.cls.connect_time = 0; + return; + } + if (adr.port == 0) + adr.port = Defines.PORT_SERVER; + // adr.port = BigShort(PORT_SERVER); + + port = (int) Cvar.VariableValue("qport"); + Globals.userinfo_modified = false; + + Netchan.OutOfBandPrint(Defines.NS_CLIENT, adr, "connect " + + Defines.PROTOCOL_VERSION + " " + port + " " + + Globals.cls.challenge + " \"" + Cvar.Userinfo() + "\"\n"); + } + + /* + * ================= CL_CheckForResend + * + * Resend a connect message if the last one has timed out ================= + */ + static void CheckForResend() { + netadr_t adr = new netadr_t(); + + // if the local server is running and we aren't + // then connect + if (Globals.cls.state == Defines.ca_disconnected + && Globals.server_state != 0) { + Globals.cls.state = Defines.ca_connecting; + Globals.cls.servername = "localhost"; + // we don't need a challenge on the localhost + SendConnectPacket(); + return; + } + + // resend if we haven't gotten a reply yet + if (Globals.cls.state != Defines.ca_connecting) + return; + + if (Globals.cls.realtime - Globals.cls.connect_time < 3000) + return; + + if (!NET.StringToAdr(Globals.cls.servername, adr)) { + Com.Printf("Bad server address\n"); + Globals.cls.state = Defines.ca_disconnected; + return; + } + if (adr.port == 0) + // adr.port = BigShort(PORT_SERVER); + adr.port = Defines.PORT_SERVER; + + Globals.cls.connect_time = Globals.cls.realtime; // for retransmit + // requests + + Com.Printf("Connecting to " + Globals.cls.servername + "...\n"); + + Netchan.OutOfBandPrint(Defines.NS_CLIENT, adr, "getchallenge\n"); + } + + /* + * ===================== CL_ClearState + * + * ===================== + */ + + static void ClearState() { + S.StopAllSounds(); + CL_fx.ClearEffects(); + CL_tent.ClearTEnts(); + + // wipe the entire cl structure + + Globals.cl = new client_state_t(); + for (int i = 0; i < Globals.cl_entities.length; i++) { + Globals.cl_entities[i] = new centity_t(); + } + + SZ.Clear(Globals.cls.netchan.message); + } + + /* + * ===================== CL_Disconnect + * + * Goes from a connected state to full screen console state Sends a + * disconnect message to the server This is also called on Com_Error, so it + * shouldn't cause any errors ===================== + */ + + static void Disconnect() { + + String fin; + + if (Globals.cls.state == Defines.ca_disconnected) + return; + + if (Globals.cl_timedemo != null && Globals.cl_timedemo.value != 0.0f) { + int time; + + time = (int) (Sys.Milliseconds() - Globals.cl.timedemo_start); + if (time > 0) + Com.Printf("%i frames, %3.1f seconds: %3.1f fps\n", + new Vargs(3).add(Globals.cl.timedemo_frames).add( + time / 1000.0).add( + Globals.cl.timedemo_frames * 1000.0 / time)); + } + + Math3D.VectorClear(Globals.cl.refdef.blend); + //re.CinematicSetPalette(null); + + Menu.ForceMenuOff(); + + Globals.cls.connect_time = 0; + + // SCR.StopCinematic(); + + if (Globals.cls.demorecording) + Stop_f.execute(); + + // send a disconnect message to the server + fin = (char) Defines.clc_stringcmd + "disconnect"; + Netchan.Transmit(Globals.cls.netchan, fin.length(), fin.getBytes()); + Netchan.Transmit(Globals.cls.netchan, fin.length(), fin.getBytes()); + Netchan.Transmit(Globals.cls.netchan, fin.length(), fin.getBytes()); + + ClearState(); + + // stop download + if (Globals.cls.download != null) { + Lib.fclose(Globals.cls.download); + Globals.cls.download = null; + // fclose(cls.download); + // cls.download = NULL; + } + + Globals.cls.state = Defines.ca_disconnected; + } + + /* + * ================= CL_ParseStatusMessage + * + * Handle a reply from a ping ================= + */ + static void ParseStatusMessage() { + String s; + + s = MSG.ReadString(Globals.net_message); + + Com.Printf(s + "\n"); + Menu.AddToServerList(Globals.net_from, s); + } + + /* + * ================= CL_ConnectionlessPacket + * + * Responses to broadcasts, etc ================= + */ + static void ConnectionlessPacket() { + String s; + String c; + + MSG.BeginReading(Globals.net_message); + MSG.ReadLong(Globals.net_message); // skip the -1 + + s = MSG.ReadStringLine(Globals.net_message); + + Cmd.TokenizeString(s.toCharArray(), false); + + c = Cmd.Argv(0); + + Com.Printf(NET.AdrToString(Globals.net_from) + ": " + c + "\n"); + + // server connection + if (c.equals("client_connect")) { + if (Globals.cls.state == Defines.ca_connected) { + Com.Printf("Dup connect received. Ignored.\n"); + return; + } + Netchan.Setup(Defines.NS_CLIENT, Globals.cls.netchan, + Globals.net_from, Globals.cls.quakePort); + MSG.WriteChar(Globals.cls.netchan.message, Defines.clc_stringcmd); + MSG.WriteString(Globals.cls.netchan.message, "new"); + Globals.cls.state = Defines.ca_connected; + return; + } + + // server responding to a status broadcast + if (c.equals("info")) { + ParseStatusMessage(); + return; + } + + // remote command from gui front end + if (c.equals("cmd")) { + if (!NET.IsLocalAddress(Globals.net_from)) { + Com.Printf("Command packet from remote host. Ignored.\n"); + return; + } + s = MSG.ReadString(Globals.net_message); + Cbuf.AddText(s); + Cbuf.AddText("\n"); + return; + } + // print command from somewhere + if (c.equals("print")) { + s = MSG.ReadString(Globals.net_message); + Com.Printf(s); + return; + } + + // ping from somewhere + if (c.equals("ping")) { + Netchan.OutOfBandPrint(Defines.NS_CLIENT, Globals.net_from, "ack"); + return; + } + + // challenge from the server we are connecting to + if (c.equals("challenge")) { + Globals.cls.challenge = Integer.parseInt(Cmd.Argv(1)); + SendConnectPacket(); + return; + } + + // echo request from server + if (c.equals("echo")) { + Netchan.OutOfBandPrint(Defines.NS_CLIENT, Globals.net_from, Cmd + .Argv(1)); + return; + } + + Com.Printf("Unknown command.\n"); + } + + /* + * ================= CL_DumpPackets + * + * A vain attempt to help bad TCP stacks that cause problems when they + * overflow ================= + */ + static void DumpPackets() { + while (NET.GetPacket(Defines.NS_CLIENT, Globals.net_from, + Globals.net_message)) { + Com.Printf("dumping a packet\n"); + } + } + + /* + * ================= CL_ReadPackets ================= + */ + static void ReadPackets() { + while (NET.GetPacket(Defines.NS_CLIENT, Globals.net_from, + Globals.net_message)) { + + // + // remote command packet + // + if (Globals.net_message.data[0] == -1 + && Globals.net_message.data[1] == -1 + && Globals.net_message.data[2] == -1 + && Globals.net_message.data[3] == -1) { + // if (*(int *)net_message.data == -1) + ConnectionlessPacket(); + continue; + } + + if (Globals.cls.state == Defines.ca_disconnected + || Globals.cls.state == Defines.ca_connecting) + continue; // dump it if not connected + + if (Globals.net_message.cursize < 8) { + Com.Printf(NET.AdrToString(Globals.net_from) + + ": Runt packet\n"); + continue; + } + + // + // packet from server + // + if (!NET.CompareAdr(Globals.net_from, + Globals.cls.netchan.remote_address)) { + Com.DPrintf(NET.AdrToString(Globals.net_from) + + ":sequenced packet without connection\n"); + continue; + } + if (!Netchan.Process(Globals.cls.netchan, Globals.net_message)) + continue; // wasn't accepted for some reason + CL_parse.ParseServerMessage(); + } + + // + // check timeout + // + if (Globals.cls.state >= Defines.ca_connected + && Globals.cls.realtime - Globals.cls.netchan.last_received > Globals.cl_timeout.value * 1000) { + if (++Globals.cl.timeoutcount > 5) // timeoutcount saves debugger + { + Com.Printf("\nServer connection timed out.\n"); + Disconnect(); + return; + } + } else + Globals.cl.timeoutcount = 0; + } + + // ============================================================================= + + /* + * ============== CL_FixUpGender_f ============== + */ + static void FixUpGender() { + + String sk; + + if (Globals.gender_auto.value != 0.0f) { + + if (Globals.gender.modified) { + // was set directly, don't override the user + Globals.gender.modified = false; + return; + } + + sk = Globals.skin.string; + if (sk.startsWith("male") || sk.startsWith("cyborg")) + Cvar.Set("gender", "male"); + else if (sk.startsWith("female") || sk.startsWith("crackhor")) + Cvar.Set("gender", "female"); + else + Cvar.Set("gender", "none"); + Globals.gender.modified = false; + } + } + + public static void RequestNextDownload() { + int map_checksum = 0; // for detecting cheater maps + //char fn[MAX_OSPATH]; + String fn; + + qfiles.dmdl_t pheader; + + if (Globals.cls.state != Defines.ca_connected) + return; + + if (SV_MAIN.allow_download.value == 0 && CL.precache_check < ENV_CNT) + CL.precache_check = ENV_CNT; + + // ZOID + if (CL.precache_check == Defines.CS_MODELS) { // confirm map + CL.precache_check = Defines.CS_MODELS + 2; // 0 isn't used + if (SV_MAIN.allow_download_maps.value != 0) + if (!CL_parse + .CheckOrDownloadFile(Globals.cl.configstrings[Defines.CS_MODELS + 1])) + return; // started a download + } + if (CL.precache_check >= Defines.CS_MODELS + && CL.precache_check < Defines.CS_MODELS + Defines.MAX_MODELS) { + if (SV_MAIN.allow_download_models.value != 0) { + while (CL.precache_check < Defines.CS_MODELS + + Defines.MAX_MODELS + && Globals.cl.configstrings[CL.precache_check].length() > 0) { + if (Globals.cl.configstrings[CL.precache_check].charAt(0) == '*' + || Globals.cl.configstrings[CL.precache_check] + .charAt(0) == '#') { + CL.precache_check++; + continue; + } + if (CL.precache_model_skin == 0) { + if (!CL_parse + .CheckOrDownloadFile(Globals.cl.configstrings[CL.precache_check])) { + CL.precache_model_skin = 1; + return; // started a download + } + CL.precache_model_skin = 1; + } + + // checking for skins in the model + if (CL.precache_model == null) { + + CL.precache_model = FS + .LoadFile(Globals.cl.configstrings[CL.precache_check]); + if (CL.precache_model == null) { + CL.precache_model_skin = 0; + CL.precache_check++; + continue; // couldn't load it + } + ByteBuffer bb = ByteBuffer.wrap(CL.precache_model); + bb.order(ByteOrder.LITTLE_ENDIAN); + + int header = bb.getInt(); + + if (header != qfiles.IDALIASHEADER) { + // not an alias model + FS.FreeFile(CL.precache_model); + CL.precache_model = null; + CL.precache_model_skin = 0; + CL.precache_check++; + continue; + } + pheader = new qfiles.dmdl_t(ByteBuffer.wrap( + CL.precache_model).order( + ByteOrder.LITTLE_ENDIAN)); + if (pheader.version != Defines.ALIAS_VERSION) { + CL.precache_check++; + CL.precache_model_skin = 0; + continue; // couldn't load it + } + } + + pheader = new qfiles.dmdl_t(ByteBuffer.wrap( + CL.precache_model).order(ByteOrder.LITTLE_ENDIAN)); + + int num_skins = pheader.num_skins; + + while (CL.precache_model_skin - 1 < num_skins) { + //Com.Printf("critical code section because of endian + // mess!\n"); + + String name = new String(CL.precache_model, + pheader.ofs_skins + + (CL.precache_model_skin - 1) + * Defines.MAX_SKINNAME, + Defines.MAX_SKINNAME * num_skins); + + if (!CL_parse.CheckOrDownloadFile(name)) { + CL.precache_model_skin++; + return; // started a download + } + CL.precache_model_skin++; + } + if (CL.precache_model != null) { + FS.FreeFile(CL.precache_model); + CL.precache_model = null; + } + CL.precache_model_skin = 0; + CL.precache_check++; + } + } + CL.precache_check = Defines.CS_SOUNDS; + } + if (CL.precache_check >= Defines.CS_SOUNDS + && CL.precache_check < Defines.CS_SOUNDS + Defines.MAX_SOUNDS) { + if (SV_MAIN.allow_download_sounds.value != 0) { + if (CL.precache_check == Defines.CS_SOUNDS) + CL.precache_check++; // zero is blank + while (CL.precache_check < Defines.CS_SOUNDS + + Defines.MAX_SOUNDS + && Globals.cl.configstrings[CL.precache_check].length() > 0) { + if (Globals.cl.configstrings[CL.precache_check].charAt(0) == '*') { + CL.precache_check++; + continue; + } + fn = "sound/" + + Globals.cl.configstrings[CL.precache_check++]; + if (!CL_parse.CheckOrDownloadFile(fn)) + return; // started a download + } + } + CL.precache_check = Defines.CS_IMAGES; + } + if (CL.precache_check >= Defines.CS_IMAGES + && CL.precache_check < Defines.CS_IMAGES + Defines.MAX_IMAGES) { + if (CL.precache_check == Defines.CS_IMAGES) + CL.precache_check++; // zero is blank + + while (CL.precache_check < Defines.CS_IMAGES + Defines.MAX_IMAGES + && Globals.cl.configstrings[CL.precache_check].length() > 0) { + fn = "pics/" + Globals.cl.configstrings[CL.precache_check++] + + ".pcx"; + if (!CL_parse.CheckOrDownloadFile(fn)) + return; // started a download + } + CL.precache_check = Defines.CS_PLAYERSKINS; + } + // skins are special, since a player has three things to download: + // model, weapon model and skin + // so precache_check is now *3 + if (CL.precache_check >= Defines.CS_PLAYERSKINS + && CL.precache_check < Defines.CS_PLAYERSKINS + + Defines.MAX_CLIENTS * CL.PLAYER_MULT) { + if (SV_MAIN.allow_download_players.value != 0) { + while (CL.precache_check < Defines.CS_PLAYERSKINS + + Defines.MAX_CLIENTS * CL.PLAYER_MULT) { + + int i, n; + //char model[MAX_QPATH], skin[MAX_QPATH], * p; + String model, skin; + + i = (CL.precache_check - Defines.CS_PLAYERSKINS) + / CL.PLAYER_MULT; + n = (CL.precache_check - Defines.CS_PLAYERSKINS) + % CL.PLAYER_MULT; + + if (Globals.cl.configstrings[Defines.CS_PLAYERSKINS + i] + .length() == 0) { + CL.precache_check = Defines.CS_PLAYERSKINS + (i + 1) + * CL.PLAYER_MULT; + continue; + } + + int pos = Globals.cl.configstrings[Defines.CS_PLAYERSKINS + + i].indexOf('\\'); + if (pos != -1) + pos++; + else + pos = 0; + + model = Globals.cl.configstrings[Defines.CS_PLAYERSKINS + i] + .substring(pos); + + pos = model.indexOf('/'); + + if (pos == -1) + pos = model.indexOf('\\'); + + if (pos != -1) { + skin = model.substring(pos + 1); + } else + skin = ""; + + switch (n) { + case 0: // model + fn = "players/" + model + "/tris.md2"; + if (!CL_parse.CheckOrDownloadFile(fn)) { + CL.precache_check = Defines.CS_PLAYERSKINS + i + * CL.PLAYER_MULT + 1; + return; // started a download + } + n++; + /* FALL THROUGH */ + + case 1: // weapon model + fn = "players/" + model + "/weapon.md2"; + if (!CL_parse.CheckOrDownloadFile(fn)) { + CL.precache_check = Defines.CS_PLAYERSKINS + i + * CL.PLAYER_MULT + 2; + return; // started a download + } + n++; + /* FALL THROUGH */ + + case 2: // weapon skin + fn = "players/" + model + "/weapon.pcx"; + if (!CL_parse.CheckOrDownloadFile(fn)) { + CL.precache_check = Defines.CS_PLAYERSKINS + i + * CL.PLAYER_MULT + 3; + return; // started a download + } + n++; + /* FALL THROUGH */ + + case 3: // skin + fn = "players/" + model + "/" + skin + ".pcx"; + if (!CL_parse.CheckOrDownloadFile(fn)) { + CL.precache_check = Defines.CS_PLAYERSKINS + i + * CL.PLAYER_MULT + 4; + return; // started a download + } + n++; + /* FALL THROUGH */ + + case 4: // skin_i + fn = "players/" + model + "/" + skin + "_i.pcx"; + if (!CL_parse.CheckOrDownloadFile(fn)) { + CL.precache_check = Defines.CS_PLAYERSKINS + i + * CL.PLAYER_MULT + 5; + return; // started a download + } + // move on to next model + CL.precache_check = Defines.CS_PLAYERSKINS + (i + 1) + * CL.PLAYER_MULT; + } + } + } + // precache phase completed + CL.precache_check = ENV_CNT; + } + + if (CL.precache_check == ENV_CNT) { + CL.precache_check = ENV_CNT + 1; + + int iw[] = { map_checksum }; + + CM.CM_LoadMap(Globals.cl.configstrings[Defines.CS_MODELS + 1], + true, iw); + map_checksum = iw[0]; + + if ((map_checksum ^ Lib + .atoi(Globals.cl.configstrings[Defines.CS_MAPCHECKSUM])) != 0) { + Com + .Error( + Defines.ERR_DROP, + "Local map version differs from server: " + + map_checksum + + " != '" + + Globals.cl.configstrings[Defines.CS_MAPCHECKSUM] + + "'\n"); + return; + } + } + + if (CL.precache_check > ENV_CNT && CL.precache_check < TEXTURE_CNT) { + if (SV_MAIN.allow_download.value != 0 + && SV_MAIN.allow_download_maps.value != 0) { + while (CL.precache_check < TEXTURE_CNT) { + int n = CL.precache_check++ - ENV_CNT - 1; + + if ((n & 1) != 0) + fn = "env/" + Globals.cl.configstrings[Defines.CS_SKY] + + env_suf[n / 2] + ".pcx"; + else + fn = "env/" + Globals.cl.configstrings[Defines.CS_SKY] + + env_suf[n / 2] + ".tga"; + if (!CL_parse.CheckOrDownloadFile(fn)) + return; // started a download + } + } + CL.precache_check = TEXTURE_CNT; + } + + if (CL.precache_check == TEXTURE_CNT) { + CL.precache_check = TEXTURE_CNT + 1; + CL.precache_tex = 0; + } + + // confirm existance of textures, download any that don't exist + if (CL.precache_check == TEXTURE_CNT + 1) { + // from qcommon/cmodel.c + // extern int numtexinfo; + // extern mapsurface_t map_surfaces[]; + + if (SV_MAIN.allow_download.value != 0 + && SV_MAIN.allow_download_maps.value != 0) { + while (CL.precache_tex < CM.numtexinfo) { + //char fn[MAX_OSPATH]; + + fn = "textures/" + CM.map_surfaces[CL.precache_tex++].rname + + ".wal"; + if (!CL_parse.CheckOrDownloadFile(fn)) + return; // started a download + } + } + CL.precache_check = TEXTURE_CNT + 999; + } + + // ZOID + CL_parse.RegisterSounds(); + CL_view.PrepRefresh(); + + MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_stringcmd); + MSG.WriteString(Globals.cls.netchan.message, "begin " + + CL.precache_spawncount + "\n"); + } + + /* + * ================= CL_InitLocal ================= + */ + public static void InitLocal() { + Globals.cls.state = Defines.ca_disconnected; + Globals.cls.realtime = Sys.Milliseconds(); + + CL_input.InitInput(); + + // never used !! + // adr0 = Cvar.Get("adr0", "", CVAR_ARCHIVE); + // adr1 = Cvar.Get("adr1", "", CVAR_ARCHIVE); + // adr2 = Cvar.Get("adr2", "", CVAR_ARCHIVE); + // adr3 = Cvar.Get("adr3", "", CVAR_ARCHIVE); + // adr4 = Cvar.Get("adr4", "", CVAR_ARCHIVE); + // adr5 = Cvar.Get("adr5", "", CVAR_ARCHIVE); + // adr6 = Cvar.Get("adr6", "", CVAR_ARCHIVE); + // adr7 = Cvar.Get("adr7", "", CVAR_ARCHIVE); + // adr8 = Cvar.Get("adr8", "", CVAR_ARCHIVE); + + // + // register our variables + // + Globals.cl_stereo_separation = Cvar.Get("cl_stereo_separation", "0.4", + Defines.CVAR_ARCHIVE); + Globals.cl_stereo = Cvar.Get("cl_stereo", "0", 0); + + Globals.cl_add_blend = Cvar.Get("cl_blend", "1", 0); + Globals.cl_add_lights = Cvar.Get("cl_lights", "1", 0); + Globals.cl_add_particles = Cvar.Get("cl_particles", "1", 0); + Globals.cl_add_entities = Cvar.Get("cl_entities", "1", 0); + Globals.cl_gun = Cvar.Get("cl_gun", "1", 0); + Globals.cl_footsteps = Cvar.Get("cl_footsteps", "1", 0); + Globals.cl_noskins = Cvar.Get("cl_noskins", "0", 0); + Globals.cl_autoskins = Cvar.Get("cl_autoskins", "0", 0); + Globals.cl_predict = Cvar.Get("cl_predict", "1", 0); + + Globals.cl_maxfps = Cvar.Get("cl_maxfps", "90", 0); + + Globals.cl_upspeed = Cvar.Get("cl_upspeed", "200", 0); + Globals.cl_forwardspeed = Cvar.Get("cl_forwardspeed", "200", 0); + Globals.cl_sidespeed = Cvar.Get("cl_sidespeed", "200", 0); + Globals.cl_yawspeed = Cvar.Get("cl_yawspeed", "140", 0); + Globals.cl_pitchspeed = Cvar.Get("cl_pitchspeed", "150", 0); + Globals.cl_anglespeedkey = Cvar.Get("cl_anglespeedkey", "1.5", 0); + + Globals.cl_run = Cvar.Get("cl_run", "0", Defines.CVAR_ARCHIVE); + Globals.lookspring = Cvar.Get("lookspring", "0", Defines.CVAR_ARCHIVE); + Globals.lookstrafe = Cvar.Get("lookstrafe", "0", Defines.CVAR_ARCHIVE); + Globals.sensitivity = Cvar + .Get("sensitivity", "3", Defines.CVAR_ARCHIVE); + + Globals.m_pitch = Cvar.Get("m_pitch", "0.022", Defines.CVAR_ARCHIVE); + Globals.m_yaw = Cvar.Get("m_yaw", "0.022", 0); + Globals.m_forward = Cvar.Get("m_forward", "1", 0); + Globals.m_side = Cvar.Get("m_side", "1", 0); + + Globals.cl_shownet = Cvar.Get("cl_shownet", "0", 0); + Globals.cl_showmiss = Cvar.Get("cl_showmiss", "0", 0); + Globals.cl_showclamp = Cvar.Get("showclamp", "0", 0); + Globals.cl_timeout = Cvar.Get("cl_timeout", "120", 0); + Globals.cl_paused = Cvar.Get("paused", "0", 0); + Globals.cl_timedemo = Cvar.Get("timedemo", "0", 0); + + Globals.rcon_client_password = Cvar.Get("rcon_password", "", 0); + Globals.rcon_address = Cvar.Get("rcon_address", "", 0); + + Globals.cl_lightlevel = Cvar.Get("r_lightlevel", "0", 0); + + // + // userinfo + // + Globals.info_password = Cvar.Get("password", "", Defines.CVAR_USERINFO); + Globals.info_spectator = Cvar.Get("spectator", "0", + Defines.CVAR_USERINFO); + Globals.name = Cvar.Get("name", "unnamed", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); + Globals.skin = Cvar.Get("skin", "male/grunt", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); + Globals.rate = Cvar.Get("rate", "25000", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); // FIXME + Globals.msg = Cvar.Get("msg", "1", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); + Globals.hand = Cvar.Get("hand", "0", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); + Globals.fov = Cvar.Get("fov", "90", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); + Globals.gender = Cvar.Get("gender", "male", Defines.CVAR_USERINFO + | Defines.CVAR_ARCHIVE); + Globals.gender_auto = Cvar + .Get("gender_auto", "1", Defines.CVAR_ARCHIVE); + Globals.gender.modified = false; // clear this so we know when user sets + // it manually + + Globals.cl_vwep = Cvar.Get("cl_vwep", "1", Defines.CVAR_ARCHIVE); + + // + // register our commands + // + Cmd.AddCommand("cmd", ForwardToServer_f); + Cmd.AddCommand("pause", Pause_f); + Cmd.AddCommand("pingservers", PingServers_f); + Cmd.AddCommand("skins", Skins_f); + + Cmd.AddCommand("userinfo", Userinfo_f); + Cmd.AddCommand("snd_restart", Snd_Restart_f); + + Cmd.AddCommand("changing", Changing_f); + Cmd.AddCommand("disconnect", Disconnect_f); + Cmd.AddCommand("record", Record_f); + Cmd.AddCommand("stop", Stop_f); + + Cmd.AddCommand("quit", Quit_f); + + Cmd.AddCommand("connect", Connect_f); + Cmd.AddCommand("reconnect", Reconnect_f); + + Cmd.AddCommand("rcon", Rcon_f); + + Cmd.AddCommand("precache", Precache_f); + + Cmd.AddCommand("download", CL_parse.Download_f); + + // + // forward to server commands + // + // the only thing this does is allow command completion + // to work -- all unknown commands are automatically + // forwarded to the server + Cmd.AddCommand("wave", null); + Cmd.AddCommand("inven", null); + Cmd.AddCommand("kill", null); + Cmd.AddCommand("use", null); + Cmd.AddCommand("drop", null); + Cmd.AddCommand("say", null); + Cmd.AddCommand("say_team", null); + Cmd.AddCommand("info", null); + Cmd.AddCommand("prog", null); + Cmd.AddCommand("give", null); + Cmd.AddCommand("god", null); + Cmd.AddCommand("notarget", null); + Cmd.AddCommand("noclip", null); + Cmd.AddCommand("invuse", null); + Cmd.AddCommand("invprev", null); + Cmd.AddCommand("invnext", null); + Cmd.AddCommand("invdrop", null); + Cmd.AddCommand("weapnext", null); + Cmd.AddCommand("weapprev", null); + + } + + /* + * =============== CL_WriteConfiguration + * + * Writes key bindings and archived cvars to config.cfg =============== + */ + static void WriteConfiguration() { + RandomAccessFile f; + String path; + + if (Globals.cls.state == Defines.ca_uninitialized) + return; + + path = FS.Gamedir() + "/config.cfg"; + f = Lib.fopen(path, "rw"); + if (f == null) { + Com.Printf("Couldn't write config.cfg.\n"); + return; + } + try { + f.seek(0); + f.setLength(0); + } catch (IOException e1) { + } + try { + f.writeBytes("// generated by quake, do not modify\n"); + } catch (IOException e) { + } + + Key.WriteBindings(f); + Lib.fclose(f); + Cvar.WriteVariables(path); + } + + public static void FixCvarCheats() { + int i; + CL.cheatvar_t var; + + if ("1".equals(Globals.cl.configstrings[Defines.CS_MAXCLIENTS]) + || 0 == Globals.cl.configstrings[Defines.CS_MAXCLIENTS] + .length()) + return; // single player can cheat + + // find all the cvars if we haven't done it yet + if (0 == CL.numcheatvars) { + while (CL.cheatvars[CL.numcheatvars].name != null) { + CL.cheatvars[CL.numcheatvars].var = Cvar.Get( + CL.cheatvars[CL.numcheatvars].name, + CL.cheatvars[CL.numcheatvars].value, 0); + CL.numcheatvars++; + } + } + + // make sure they are all set to the proper values + for (i = 0; i < CL.numcheatvars; i++) { + var = CL.cheatvars[i]; + if (!var.var.string.equals(var.value)) { + Cvar.Set(var.name, var.value); + } + } + } + + // ============================================================================ + + /* + * ================== CL_SendCommand + * + * ================== + */ + public static void SendCommand() { + // get new key events + Sys.SendKeyEvents(); + + // allow mice or other external controllers to add commands + IN.Commands(); + + // process console commands + Cbuf.Execute(); + + // fix any cheating cvars + FixCvarCheats(); + + // send intentions now + CL_input.SendCmd(); + + // resend a connection request if necessary + CheckForResend(); + } + + // private static int lasttimecalled; + + public static void Frame(int msec) { + + extratime += msec; + + if (Globals.cl_timedemo.value == 0.0f) { + if (Globals.cls.state == Defines.ca_connected && extratime < 100) { + return; // don't flood packets out while connecting + } + if (extratime < 1000 / Globals.cl_maxfps.value) { + return; // framerate is too high + } + } + + // let the mouse activate or deactivate + IN.Frame(); + + // decide the simulation time + Globals.cls.frametime = extratime / 1000.0f; + Globals.cl.time += extratime; + Globals.cls.realtime = Globals.curtime; + + extratime = 0; + + if (Globals.cls.frametime > (1.0f / 5)) + Globals.cls.frametime = (1.0f / 5); + + // if in the debugger last frame, don't timeout + if (msec > 5000) + Globals.cls.netchan.last_received = Sys.Milliseconds(); + + // fetch results from server + ReadPackets(); + + // send a new command message to the server + SendCommand(); + + // predict all unacknowledged movements + CL_pred.PredictMovement(); + + // allow rendering DLL change + VID.CheckChanges(); + if (!Globals.cl.refresh_prepped + && Globals.cls.state == Defines.ca_active) { + CL_view.PrepRefresh(); + // force GC after level loading + System.gc(); + } + + SCR.UpdateScreen(); + + // update audio + S.Update(Globals.cl.refdef.vieworg, Globals.cl.v_forward, + Globals.cl.v_right, Globals.cl.v_up); + + // advance local effects for next frame + CL_fx.RunDLights(); + CL_fx.RunLightStyles(); - /* - =============== - CL_Shutdown + SCR.RunConsole(); - FIXME: this is a callback from Sys_Quit and Com_Error. It would be better - to run quit through here before the final handoff to the sys code. - =============== - */ - static boolean isdown = false; - public static void Shutdown() { + Globals.cls.framecount++; + if (Globals.cls.state != Defines.ca_active + || Globals.cls.key_dest != Defines.key_game) { + try { + Thread.sleep(20); + } catch (InterruptedException e) { + } + } + } - if (isdown) { - System.out.print("recursive shutdown\n"); - return; - } - isdown = true; + public static void Shutdown() { - WriteConfiguration(); + if (isdown) { + System.out.print("recursive shutdown\n"); + return; + } + isdown = true; - S.Shutdown(); - IN.Shutdown(); - VID.Shutdown(); - } + WriteConfiguration(); - /** - * initialize client subsystem - */ - public static void Init() { - if (Globals.dedicated.value != 0.0f) - return; // nothing running on the client + S.Shutdown(); + IN.Shutdown(); + VID.Shutdown(); + } - // all archived variables will now be loaded + /** + * initialize client subsystem + */ + public static void Init() { + if (Globals.dedicated.value != 0.0f) + return; // nothing running on the client - Console.Init(); //ok + // all archived variables will now be loaded - S.Init(); //empty - VID.Init(); + Console.Init(); //ok - V.Init(); + S.Init(); //empty + VID.Init(); - Globals.net_message.data = Globals.net_message_buffer; - Globals.net_message.maxsize = Globals.net_message_buffer.length; + V.Init(); - Menu.Init(); + Globals.net_message.data = Globals.net_message_buffer; + Globals.net_message.maxsize = Globals.net_message_buffer.length; - SCR.Init(); - //Globals.cls.disable_screen = 1.0f; // don't draw yet + Menu.Init(); - CL.InitLocal(); - IN.Init(); + SCR.Init(); + //Globals.cls.disable_screen = 1.0f; // don't draw yet - FS.ExecAutoexec(); - Cbuf.Execute(); - } + InitLocal(); + IN.Init(); - /** - * Called after an ERR_DROP was thrown. - */ - public static void Drop() { - if (Globals.cls.state == Defines.ca_uninitialized) - return; - if (Globals.cls.state == Defines.ca_disconnected) - return; + FS.ExecAutoexec(); + Cbuf.Execute(); + } - CL.Disconnect(); + /** + * Called after an ERR_DROP was thrown. + */ + public static void Drop() { + if (Globals.cls.state == Defines.ca_uninitialized) + return; + if (Globals.cls.state == Defines.ca_disconnected) + return; - // drop loading plaque unless this is the initial game start - if (Globals.cls.disable_servercount != -1) - SCR.EndLoadingPlaque(); // get rid of loading plaque - } + Disconnect(); -} + // drop loading plaque unless this is the initial game start + if (Globals.cls.disable_servercount != -1) + SCR.EndLoadingPlaque(); // get rid of loading plaque + } +}
\ No newline at end of file diff --git a/src/jake2/client/CL_ents.java b/src/jake2/client/CL_ents.java index 37d044c..df189fa 100644 --- a/src/jake2/client/CL_ents.java +++ b/src/jake2/client/CL_ents.java @@ -1,74 +1,79 @@ /* - * CL_ents.java + * java * Copyright (C) 2004 * - * $Id: CL_ents.java,v 1.5 2004-07-12 20:47:01 hzi Exp $ + * $Id: CL_ents.java,v 1.6 2004-09-22 19:22:07 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; +import jake2.Defines; +import jake2.Globals; import jake2.game.entity_state_t; import jake2.game.player_state_t; -import jake2.qcommon.*; +import jake2.game.pmove_t; +import jake2.qcommon.Com; +import jake2.qcommon.FS; +import jake2.qcommon.MSG; import jake2.render.model_t; +import jake2.util.Math3D; /** * CL_ents */ // cl_ents.c -- entity parsing and management -public class CL_ents extends CL_inv { +/* + * ========================================================================= + * + * FRAME PARSING + * + * ========================================================================= + */ +public class CL_ents { + static int bitcounts[] = new int[32]; /// just for protocol profiling - /* - ========================================================================= - - FRAME PARSING - - ========================================================================= - */ + static int bfg_lightramp[] = { 300, 400, 600, 300, 150, 75 }; /* - ================= - CL_ParseEntityBits - - Returns the entity number and the header bits - ================= - */ - static int bitcounts[] = new int[32]; /// just for protocol profiling + * ================= CL_ParseEntityBits + * + * Returns the entity number and the header bits ================= + */ public static int ParseEntityBits(int bits[]) { int b, total; int i; int number; - total = MSG.ReadByte(net_message); - if ((total & U_MOREBITS1) != 0) { - b = MSG.ReadByte(net_message); + total = MSG.ReadByte(Globals.net_message); + if ((total & Defines.U_MOREBITS1) != 0) { + b = MSG.ReadByte(Globals.net_message); total |= b << 8; } - if ((total & U_MOREBITS2) != 0) { - b = MSG.ReadByte(net_message); + if ((total & Defines.U_MOREBITS2) != 0) { + b = MSG.ReadByte(Globals.net_message); total |= b << 16; } - if ((total & U_MOREBITS3) != 0) { - b = MSG.ReadByte(net_message); + if ((total & Defines.U_MOREBITS3) != 0) { + b = MSG.ReadByte(Globals.net_message); total |= b << 24; } @@ -77,10 +82,10 @@ public class CL_ents extends CL_inv { if ((total & (1 << i)) != 0) bitcounts[i]++; - if ((total & U_NUMBER16) != 0) - number = MSG.ReadShort(net_message); + if ((total & Defines.U_NUMBER16) != 0) + number = MSG.ReadShort(Globals.net_message); else - number = MSG.ReadByte(net_message); + number = MSG.ReadByte(Globals.net_message); bits[0] = total; @@ -88,155 +93,152 @@ public class CL_ents extends CL_inv { } /* - ================== - CL_ParseDelta - - Can go from either a baseline or a previous packet_entity - ================== - */ + * ================== CL_ParseDelta + * + * Can go from either a baseline or a previous packet_entity + * ================== + */ public static void ParseDelta(entity_state_t from, entity_state_t to, int number, int bits) { // set everything to the state we are delta'ing from to.set(from); - VectorCopy(from.origin, to.old_origin); + Math3D.VectorCopy(from.origin, to.old_origin); to.number = number; - if ((bits & U_MODEL) != 0) - to.modelindex = MSG.ReadByte(net_message); - if ((bits & U_MODEL2) != 0) - to.modelindex2 = MSG.ReadByte(net_message); - if ((bits & U_MODEL3) != 0) - to.modelindex3 = MSG.ReadByte(net_message); - if ((bits & U_MODEL4) != 0) - to.modelindex4 = MSG.ReadByte(net_message); - - if ((bits & U_FRAME8) != 0) - to.frame = MSG.ReadByte(net_message); - if ((bits & U_FRAME16) != 0) - to.frame = MSG.ReadShort(net_message); - - if ((bits & U_SKIN8) != 0 && (bits & U_SKIN16) != 0) //used for laser colors - to.skinnum = MSG.ReadLong(net_message); - else if ((bits & U_SKIN8) != 0) - to.skinnum = MSG.ReadByte(net_message); - else if ((bits & U_SKIN16) != 0) - to.skinnum = MSG.ReadShort(net_message); - - if ((bits & (U_EFFECTS8 | U_EFFECTS16)) == (U_EFFECTS8 | U_EFFECTS16)) - to.effects = MSG.ReadLong(net_message); - else if ((bits & U_EFFECTS8) != 0) - to.effects = MSG.ReadByte(net_message); - else if ((bits & U_EFFECTS16) != 0) - to.effects = MSG.ReadShort(net_message); - - if ((bits & (U_RENDERFX8 | U_RENDERFX16)) == (U_RENDERFX8 | U_RENDERFX16)) - to.renderfx = MSG.ReadLong(net_message); - else if ((bits & U_RENDERFX8) != 0) - to.renderfx = MSG.ReadByte(net_message); - else if ((bits & U_RENDERFX16) != 0) - to.renderfx = MSG.ReadShort(net_message); - - if ((bits & U_ORIGIN1) != 0) - to.origin[0] = MSG.ReadCoord(net_message); - if ((bits & U_ORIGIN2) != 0) - to.origin[1] = MSG.ReadCoord(net_message); - if ((bits & U_ORIGIN3) != 0) - to.origin[2] = MSG.ReadCoord(net_message); - - if ((bits & U_ANGLE1) != 0) - to.angles[0] = MSG.ReadAngle(net_message); - if ((bits & U_ANGLE2) != 0) - to.angles[1] = MSG.ReadAngle(net_message); - if ((bits & U_ANGLE3) != 0) - to.angles[2] = MSG.ReadAngle(net_message); - - if ((bits & U_OLDORIGIN) != 0) - MSG.ReadPos(net_message, to.old_origin); - - if ((bits & U_SOUND) != 0) - to.sound = MSG.ReadByte(net_message); - - if ((bits & U_EVENT) != 0) - to.event = MSG.ReadByte(net_message); + if ((bits & Defines.U_MODEL) != 0) + to.modelindex = MSG.ReadByte(Globals.net_message); + if ((bits & Defines.U_MODEL2) != 0) + to.modelindex2 = MSG.ReadByte(Globals.net_message); + if ((bits & Defines.U_MODEL3) != 0) + to.modelindex3 = MSG.ReadByte(Globals.net_message); + if ((bits & Defines.U_MODEL4) != 0) + to.modelindex4 = MSG.ReadByte(Globals.net_message); + + if ((bits & Defines.U_FRAME8) != 0) + to.frame = MSG.ReadByte(Globals.net_message); + if ((bits & Defines.U_FRAME16) != 0) + to.frame = MSG.ReadShort(Globals.net_message); + + if ((bits & Defines.U_SKIN8) != 0 && (bits & Defines.U_SKIN16) != 0) //used + // for + // laser + // colors + to.skinnum = MSG.ReadLong(Globals.net_message); + else if ((bits & Defines.U_SKIN8) != 0) + to.skinnum = MSG.ReadByte(Globals.net_message); + else if ((bits & Defines.U_SKIN16) != 0) + to.skinnum = MSG.ReadShort(Globals.net_message); + + if ((bits & (Defines.U_EFFECTS8 | Defines.U_EFFECTS16)) == (Defines.U_EFFECTS8 | Defines.U_EFFECTS16)) + to.effects = MSG.ReadLong(Globals.net_message); + else if ((bits & Defines.U_EFFECTS8) != 0) + to.effects = MSG.ReadByte(Globals.net_message); + else if ((bits & Defines.U_EFFECTS16) != 0) + to.effects = MSG.ReadShort(Globals.net_message); + + if ((bits & (Defines.U_RENDERFX8 | Defines.U_RENDERFX16)) == (Defines.U_RENDERFX8 | Defines.U_RENDERFX16)) + to.renderfx = MSG.ReadLong(Globals.net_message); + else if ((bits & Defines.U_RENDERFX8) != 0) + to.renderfx = MSG.ReadByte(Globals.net_message); + else if ((bits & Defines.U_RENDERFX16) != 0) + to.renderfx = MSG.ReadShort(Globals.net_message); + + if ((bits & Defines.U_ORIGIN1) != 0) + to.origin[0] = MSG.ReadCoord(Globals.net_message); + if ((bits & Defines.U_ORIGIN2) != 0) + to.origin[1] = MSG.ReadCoord(Globals.net_message); + if ((bits & Defines.U_ORIGIN3) != 0) + to.origin[2] = MSG.ReadCoord(Globals.net_message); + + if ((bits & Defines.U_ANGLE1) != 0) + to.angles[0] = MSG.ReadAngle(Globals.net_message); + if ((bits & Defines.U_ANGLE2) != 0) + to.angles[1] = MSG.ReadAngle(Globals.net_message); + if ((bits & Defines.U_ANGLE3) != 0) + to.angles[2] = MSG.ReadAngle(Globals.net_message); + + if ((bits & Defines.U_OLDORIGIN) != 0) + MSG.ReadPos(Globals.net_message, to.old_origin); + + if ((bits & Defines.U_SOUND) != 0) + to.sound = MSG.ReadByte(Globals.net_message); + + if ((bits & Defines.U_EVENT) != 0) + to.event = MSG.ReadByte(Globals.net_message); else to.event = 0; - if ((bits & U_SOLID) != 0) - to.solid = MSG.ReadShort(net_message); + if ((bits & Defines.U_SOLID) != 0) + to.solid = MSG.ReadShort(Globals.net_message); } /* - ================== - CL_DeltaEntity - - Parses deltas from the given base and adds the resulting entity - to the current frame - ================== - */ + * ================== CL_DeltaEntity + * + * Parses deltas from the given base and adds the resulting entity to the + * current frame ================== + */ public static void DeltaEntity(frame_t frame, int newnum, entity_state_t old, int bits) { centity_t ent; entity_state_t state; - ent = cl_entities[newnum]; + ent = Globals.cl_entities[newnum]; - state = cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES - 1)]; - cl.parse_entities++; + state = Globals.cl_parse_entities[Globals.cl.parse_entities & (Defines.MAX_PARSE_ENTITIES - 1)]; + Globals.cl.parse_entities++; frame.num_entities++; ParseDelta(old, state, newnum, bits); // some data changes will force no lerping - if (state.modelindex != ent.current.modelindex - || state.modelindex2 != ent.current.modelindex2 - || state.modelindex3 != ent.current.modelindex3 - || state.modelindex4 != ent.current.modelindex4 - || Math.abs(state.origin[0] - ent.current.origin[0]) > 512 - || Math.abs(state.origin[1] - ent.current.origin[1]) > 512 - || Math.abs(state.origin[2] - ent.current.origin[2]) > 512 - || state.event == EV_PLAYER_TELEPORT - || state.event == EV_OTHER_TELEPORT) { + if (state.modelindex != ent.current.modelindex || state.modelindex2 != ent.current.modelindex2 + || state.modelindex3 != ent.current.modelindex3 || state.modelindex4 != ent.current.modelindex4 + || Math.abs(state.origin[0] - ent.current.origin[0]) > 512 || Math.abs(state.origin[1] - ent.current.origin[1]) > 512 + || Math.abs(state.origin[2] - ent.current.origin[2]) > 512 || state.event == Defines.EV_PLAYER_TELEPORT + || state.event == Defines.EV_OTHER_TELEPORT) { ent.serverframe = -99; } - if (ent.serverframe != cl.frame.serverframe - 1) { // wasn't in last update, so initialize some things + if (ent.serverframe != Globals.cl.frame.serverframe - 1) { // wasn't in + // last + // update, so + // initialize + // some + // things ent.trailcount = 1024; // for diminishing rocket / grenade trails // duplicate the current state so lerping doesn't hurt anything ent.prev.set(state); - if (state.event == EV_OTHER_TELEPORT) { - VectorCopy(state.origin, ent.prev.origin); - VectorCopy(state.origin, ent.lerp_origin); - } - else { - VectorCopy(state.old_origin, ent.prev.origin); - VectorCopy(state.old_origin, ent.lerp_origin); + if (state.event == Defines.EV_OTHER_TELEPORT) { + Math3D.VectorCopy(state.origin, ent.prev.origin); + Math3D.VectorCopy(state.origin, ent.lerp_origin); + } else { + Math3D.VectorCopy(state.old_origin, ent.prev.origin); + Math3D.VectorCopy(state.old_origin, ent.lerp_origin); } - } - else { // shuffle the last state to previous + } else { // shuffle the last state to previous // Copy ! ent.prev.set(ent.current); } - ent.serverframe = cl.frame.serverframe; + ent.serverframe = Globals.cl.frame.serverframe; // Copy ! ent.current.set(state); } /* - ================== - CL_ParsePacketEntities - - An svc_packetentities has just been parsed, deal with the - rest of the data stream. - ================== - */ + * ================== CL_ParsePacketEntities + * + * An svc_packetentities has just been parsed, deal with the rest of the + * data stream. ================== + */ public static void ParsePacketEntities(frame_t oldframe, frame_t newframe) { int newnum; - int bits=0; + int bits = 0; - entity_state_t oldstate=null; + entity_state_t oldstate = null; int oldnum; - newframe.parse_entities = cl.parse_entities; + newframe.parse_entities = Globals.cl.parse_entities; newframe.num_entities = 0; // delta from the entities present in oldframe @@ -245,30 +247,31 @@ public class CL_ents extends CL_inv { oldnum = 99999; else { // oldindex == 0. hoz -// if (oldindex >= oldframe.num_entities) -// oldnum = 99999; -// else { - oldstate = cl_parse_entities[(oldframe.parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)]; - oldnum = oldstate.number; -// } + // if (oldindex >= oldframe.num_entities) + // oldnum = 99999; + // else { + oldstate = Globals.cl_parse_entities[(oldframe.parse_entities + oldindex) & (Defines.MAX_PARSE_ENTITIES - 1)]; + oldnum = oldstate.number; + // } } while (true) { - int iw[] = {bits}; + int iw[] = { bits }; newnum = ParseEntityBits(iw); bits = iw[0]; - if (newnum >= MAX_EDICTS) - Com.Error(ERR_DROP, "CL_ParsePacketEntities: bad number:" + newnum); + if (newnum >= Defines.MAX_EDICTS) + Com.Error(Defines.ERR_DROP, "CL_ParsePacketEntities: bad number:" + newnum); - if (net_message.readcount > net_message.cursize) - Com.Error(ERR_DROP, "CL_ParsePacketEntities: end of message"); + if (Globals.net_message.readcount > Globals.net_message.cursize) + Com.Error(Defines.ERR_DROP, "CL_ParsePacketEntities: end of message"); if (0 == newnum) break; - while (oldnum < newnum) { // one or more entities from the old packet are unchanged - if (cl_shownet.value == 3) + while (oldnum < newnum) { // one or more entities from the old + // packet are unchanged + if (Globals.cl_shownet.value == 3) Com.Printf(" unchanged: " + oldnum + "\n"); DeltaEntity(newframe, oldnum, oldstate, 0); @@ -277,13 +280,15 @@ public class CL_ents extends CL_inv { if (oldindex >= oldframe.num_entities) oldnum = 99999; else { - oldstate = cl_parse_entities[(oldframe.parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)]; + oldstate = Globals.cl_parse_entities[(oldframe.parse_entities + oldindex) & (Defines.MAX_PARSE_ENTITIES - 1)]; oldnum = oldstate.number; } } - if ((bits & U_REMOVE) != 0) { // the entity present in oldframe is not in the current frame - if (cl_shownet.value == 3) + if ((bits & Defines.U_REMOVE) != 0) { // the entity present in + // oldframe is not in the + // current frame + if (Globals.cl_shownet.value == 3) Com.Printf(" remove: " + newnum + "\n"); if (oldnum != newnum) Com.Printf("U_REMOVE: oldnum != newnum\n"); @@ -293,14 +298,14 @@ public class CL_ents extends CL_inv { if (oldindex >= oldframe.num_entities) oldnum = 99999; else { - oldstate = cl_parse_entities[(oldframe.parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)]; + oldstate = Globals.cl_parse_entities[(oldframe.parse_entities + oldindex) & (Defines.MAX_PARSE_ENTITIES - 1)]; oldnum = oldstate.number; } continue; } if (oldnum == newnum) { // delta from previous state - if (cl_shownet.value == 3) + if (Globals.cl_shownet.value == 3) Com.Printf(" delta: " + newnum + "\n"); DeltaEntity(newframe, newnum, oldstate, bits); @@ -309,24 +314,25 @@ public class CL_ents extends CL_inv { if (oldindex >= oldframe.num_entities) oldnum = 99999; else { - oldstate = cl_parse_entities[(oldframe.parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)]; + oldstate = Globals.cl_parse_entities[(oldframe.parse_entities + oldindex) & (Defines.MAX_PARSE_ENTITIES - 1)]; oldnum = oldstate.number; } continue; } if (oldnum > newnum) { // delta from baseline - if (cl_shownet.value == 3) + if (Globals.cl_shownet.value == 3) Com.Printf(" baseline: " + newnum + "\n"); - DeltaEntity(newframe, newnum, cl_entities[newnum].baseline, bits); + DeltaEntity(newframe, newnum, Globals.cl_entities[newnum].baseline, bits); continue; } } // any remaining entities in the old frame are copied over - while (oldnum != 99999) { // one or more entities from the old packet are unchanged - if (cl_shownet.value == 3) + while (oldnum != 99999) { // one or more entities from the old packet + // are unchanged + if (Globals.cl_shownet.value == 3) Com.Printf(" unchanged: " + oldnum + "\n"); DeltaEntity(newframe, oldnum, oldstate, 0); @@ -335,17 +341,15 @@ public class CL_ents extends CL_inv { if (oldindex >= oldframe.num_entities) oldnum = 99999; else { - oldstate = cl_parse_entities[(oldframe.parse_entities + oldindex) & (MAX_PARSE_ENTITIES - 1)]; + oldstate = Globals.cl_parse_entities[(oldframe.parse_entities + oldindex) & (Defines.MAX_PARSE_ENTITIES - 1)]; oldnum = oldstate.number; } } } /* - =================== - CL_ParsePlayerstate - =================== - */ + * =================== CL_ParsePlayerstate =================== + */ public static void ParsePlayerstate(frame_t oldframe, frame_t newframe) { int flags; player_state_t state; @@ -361,233 +365,230 @@ public class CL_ents extends CL_inv { //memset (state, 0, sizeof(*state)); state.clear(); - flags = MSG.ReadShort(net_message); + flags = MSG.ReadShort(Globals.net_message); // // parse the pmove_state_t // - if ((flags & PS_M_TYPE) != 0) - state.pmove.pm_type = MSG.ReadByte(net_message); + if ((flags & Defines.PS_M_TYPE) != 0) + state.pmove.pm_type = MSG.ReadByte(Globals.net_message); - if ((flags & PS_M_ORIGIN) != 0) { - state.pmove.origin[0] = MSG.ReadShort(net_message); - state.pmove.origin[1] = MSG.ReadShort(net_message); - state.pmove.origin[2] = MSG.ReadShort(net_message); + if ((flags & Defines.PS_M_ORIGIN) != 0) { + state.pmove.origin[0] = MSG.ReadShort(Globals.net_message); + state.pmove.origin[1] = MSG.ReadShort(Globals.net_message); + state.pmove.origin[2] = MSG.ReadShort(Globals.net_message); } - if ((flags & PS_M_VELOCITY) != 0) { - state.pmove.velocity[0] = MSG.ReadShort(net_message); - state.pmove.velocity[1] = MSG.ReadShort(net_message); - state.pmove.velocity[2] = MSG.ReadShort(net_message); + if ((flags & Defines.PS_M_VELOCITY) != 0) { + state.pmove.velocity[0] = MSG.ReadShort(Globals.net_message); + state.pmove.velocity[1] = MSG.ReadShort(Globals.net_message); + state.pmove.velocity[2] = MSG.ReadShort(Globals.net_message); } - if ((flags & PS_M_TIME) != 0) - { - state.pmove.pm_time = (byte) MSG.ReadByte(net_message); + if ((flags & Defines.PS_M_TIME) != 0) { + state.pmove.pm_time = (byte) MSG.ReadByte(Globals.net_message); } - if ((flags & PS_M_FLAGS) != 0) - state.pmove.pm_flags = (byte) MSG.ReadByte(net_message); + if ((flags & Defines.PS_M_FLAGS) != 0) + state.pmove.pm_flags = (byte) MSG.ReadByte(Globals.net_message); - if ((flags & PS_M_GRAVITY) != 0) - state.pmove.gravity = MSG.ReadShort(net_message); + if ((flags & Defines.PS_M_GRAVITY) != 0) + state.pmove.gravity = MSG.ReadShort(Globals.net_message); - if ((flags & PS_M_DELTA_ANGLES) != 0) { - state.pmove.delta_angles[0] = MSG.ReadShort(net_message); - state.pmove.delta_angles[1] = MSG.ReadShort(net_message); - state.pmove.delta_angles[2] = MSG.ReadShort(net_message); + if ((flags & Defines.PS_M_DELTA_ANGLES) != 0) { + state.pmove.delta_angles[0] = MSG.ReadShort(Globals.net_message); + state.pmove.delta_angles[1] = MSG.ReadShort(Globals.net_message); + state.pmove.delta_angles[2] = MSG.ReadShort(Globals.net_message); } - if (cl.attractloop) - state.pmove.pm_type = PM_FREEZE; // demo playback + if (Globals.cl.attractloop) + state.pmove.pm_type = Defines.PM_FREEZE; // demo playback // // parse the rest of the player_state_t // - if ((flags & PS_VIEWOFFSET) != 0) { - state.viewoffset[0] = MSG.ReadChar(net_message) * 0.25f; - state.viewoffset[1] = MSG.ReadChar(net_message) * 0.25f; - state.viewoffset[2] = MSG.ReadChar(net_message) * 0.25f; + if ((flags & Defines.PS_VIEWOFFSET) != 0) { + state.viewoffset[0] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.viewoffset[1] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.viewoffset[2] = MSG.ReadChar(Globals.net_message) * 0.25f; } - if ((flags & PS_VIEWANGLES) != 0) { - state.viewangles[0] = MSG.ReadAngle16(net_message); - state.viewangles[1] = MSG.ReadAngle16(net_message); - state.viewangles[2] = MSG.ReadAngle16(net_message); + if ((flags & Defines.PS_VIEWANGLES) != 0) { + state.viewangles[0] = MSG.ReadAngle16(Globals.net_message); + state.viewangles[1] = MSG.ReadAngle16(Globals.net_message); + state.viewangles[2] = MSG.ReadAngle16(Globals.net_message); } - if ((flags & PS_KICKANGLES) != 0) { - - state.kick_angles[0] = MSG.ReadChar(net_message) * 0.25f; - state.kick_angles[1] = MSG.ReadChar(net_message) * 0.25f; - state.kick_angles[2] = MSG.ReadChar(net_message) * 0.25f; - + if ((flags & Defines.PS_KICKANGLES) != 0) { + + state.kick_angles[0] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.kick_angles[1] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.kick_angles[2] = MSG.ReadChar(Globals.net_message) * 0.25f; + } - if ((flags & PS_WEAPONINDEX) != 0) { - state.gunindex = MSG.ReadByte(net_message); + if ((flags & Defines.PS_WEAPONINDEX) != 0) { + state.gunindex = MSG.ReadByte(Globals.net_message); } - if ((flags & PS_WEAPONFRAME) != 0) { - state.gunframe = MSG.ReadByte(net_message); - state.gunoffset[0] = MSG.ReadChar(net_message) * 0.25f; - state.gunoffset[1] = MSG.ReadChar(net_message) * 0.25f; - state.gunoffset[2] = MSG.ReadChar(net_message) * 0.25f; - state.gunangles[0] = MSG.ReadChar(net_message) * 0.25f; - state.gunangles[1] = MSG.ReadChar(net_message) * 0.25f; - state.gunangles[2] = MSG.ReadChar(net_message) * 0.25f; + if ((flags & Defines.PS_WEAPONFRAME) != 0) { + state.gunframe = MSG.ReadByte(Globals.net_message); + state.gunoffset[0] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.gunoffset[1] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.gunoffset[2] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.gunangles[0] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.gunangles[1] = MSG.ReadChar(Globals.net_message) * 0.25f; + state.gunangles[2] = MSG.ReadChar(Globals.net_message) * 0.25f; } - if ((flags & PS_BLEND) != 0) { - state.blend[0] = MSG.ReadByte(net_message) / 255.0f; - state.blend[1] = MSG.ReadByte(net_message) / 255.0f; - state.blend[2] = MSG.ReadByte(net_message) / 255.0f; - state.blend[3] = MSG.ReadByte(net_message) / 255.0f; + if ((flags & Defines.PS_BLEND) != 0) { + state.blend[0] = MSG.ReadByte(Globals.net_message) / 255.0f; + state.blend[1] = MSG.ReadByte(Globals.net_message) / 255.0f; + state.blend[2] = MSG.ReadByte(Globals.net_message) / 255.0f; + state.blend[3] = MSG.ReadByte(Globals.net_message) / 255.0f; } - if ((flags & PS_FOV) != 0) - state.fov = MSG.ReadByte(net_message); + if ((flags & Defines.PS_FOV) != 0) + state.fov = MSG.ReadByte(Globals.net_message); - if ((flags & PS_RDFLAGS) != 0) - state.rdflags = MSG.ReadByte(net_message); + if ((flags & Defines.PS_RDFLAGS) != 0) + state.rdflags = MSG.ReadByte(Globals.net_message); // parse stats - statbits = MSG.ReadLong(net_message); - for (i = 0; i < MAX_STATS; i++) - if ((statbits & (1 << i))!=0) - state.stats[i] = MSG.ReadShort(net_message); + statbits = MSG.ReadLong(Globals.net_message); + for (i = 0; i < Defines.MAX_STATS; i++) + if ((statbits & (1 << i)) != 0) + state.stats[i] = MSG.ReadShort(Globals.net_message); } /* - ================== - CL_FireEntityEvents - - ================== - */ + * ================== CL_FireEntityEvents + * + * ================== + */ public static void FireEntityEvents(frame_t frame) { entity_state_t s1; int pnum, num; for (pnum = 0; pnum < frame.num_entities; pnum++) { - num = (frame.parse_entities + pnum) & (MAX_PARSE_ENTITIES - 1); - s1 = cl_parse_entities[num]; - if (s1.event!=0) - EntityEvent(s1); + num = (frame.parse_entities + pnum) & (Defines.MAX_PARSE_ENTITIES - 1); + s1 = Globals.cl_parse_entities[num]; + if (s1.event != 0) + CL_fx.EntityEvent(s1); // EF_TELEPORTER acts like an event, but is not cleared each frame - if ((s1.effects & EF_TELEPORTER)!=0) + if ((s1.effects & Defines.EF_TELEPORTER) != 0) CL_fx.TeleporterParticles(s1); } } /* - ================ - CL_ParseFrame - ================ - */ + * ================ CL_ParseFrame ================ + */ public static void ParseFrame() { int cmd; int len; frame_t old; //memset( cl.frame, 0, sizeof(cl.frame)); - cl.frame.reset(); + Globals.cl.frame.reset(); - cl.frame.serverframe = MSG.ReadLong(net_message); - cl.frame.deltaframe = MSG.ReadLong(net_message); - cl.frame.servertime = cl.frame.serverframe * 100; + Globals.cl.frame.serverframe = MSG.ReadLong(Globals.net_message); + Globals.cl.frame.deltaframe = MSG.ReadLong(Globals.net_message); + Globals.cl.frame.servertime = Globals.cl.frame.serverframe * 100; // BIG HACK to let old demos continue to work - if (cls.serverProtocol != 26) - cl.surpressCount = MSG.ReadByte(net_message); + if (Globals.cls.serverProtocol != 26) + Globals.cl.surpressCount = MSG.ReadByte(Globals.net_message); - if (cl_shownet.value == 3) - Com.Printf(" frame:" + cl.frame.serverframe + " delta:" + cl.frame.deltaframe + "\n"); + if (Globals.cl_shownet.value == 3) + Com.Printf(" frame:" + Globals.cl.frame.serverframe + " delta:" + Globals.cl.frame.deltaframe + "\n"); // If the frame is delta compressed from data that we // no longer have available, we must suck up the rest of // the frame, but not use it, then ask for a non-compressed - // message - if (cl.frame.deltaframe <= 0) { - cl.frame.valid = true; // uncompressed frame + // message + if (Globals.cl.frame.deltaframe <= 0) { + Globals.cl.frame.valid = true; // uncompressed frame old = null; - cls.demowaiting = false; // we can start recording now - } - else { - old = cl.frames[cl.frame.deltaframe & UPDATE_MASK]; + Globals.cls.demowaiting = false; // we can start recording now + } else { + old = Globals.cl.frames[Globals.cl.frame.deltaframe & Defines.UPDATE_MASK]; if (!old.valid) { // should never happen Com.Printf("Delta from invalid frame (not supposed to happen!).\n"); } - if (old.serverframe != cl.frame.deltaframe) { // The frame that the server did the delta from + if (old.serverframe != Globals.cl.frame.deltaframe) { // The frame + // that the + // server did + // the delta + // from // is too old, so we can't reconstruct it properly. Com.Printf("Delta frame too old.\n"); - } - else if (cl.parse_entities - old.parse_entities > MAX_PARSE_ENTITIES - 128) { + } else if (Globals.cl.parse_entities - old.parse_entities > Defines.MAX_PARSE_ENTITIES - 128) { Com.Printf("Delta parse_entities too old.\n"); - } - else - cl.frame.valid = true; // valid delta parse + } else + Globals.cl.frame.valid = true; // valid delta parse } - // clamp time - if (cl.time > cl.frame.servertime) - cl.time = cl.frame.servertime; - else if (cl.time < cl.frame.servertime - 100) - cl.time = cl.frame.servertime - 100; + // clamp time + if (Globals.cl.time > Globals.cl.frame.servertime) + Globals.cl.time = Globals.cl.frame.servertime; + else if (Globals.cl.time < Globals.cl.frame.servertime - 100) + Globals.cl.time = Globals.cl.frame.servertime - 100; // read areabits - len = MSG.ReadByte(net_message); - MSG.ReadData(net_message, cl.frame.areabits, len); + len = MSG.ReadByte(Globals.net_message); + MSG.ReadData(Globals.net_message, Globals.cl.frame.areabits, len); // read playerinfo - cmd = MSG.ReadByte(net_message); + cmd = MSG.ReadByte(Globals.net_message); CL_parse.SHOWNET(CL_parse.svc_strings[cmd]); - if (cmd != svc_playerinfo) - Com.Error(ERR_DROP, "CL_ParseFrame: not playerinfo"); - ParsePlayerstate(old, cl.frame); + if (cmd != Defines.svc_playerinfo) + Com.Error(Defines.ERR_DROP, "CL_ParseFrame: not playerinfo"); + ParsePlayerstate(old, Globals.cl.frame); // read packet entities - cmd = MSG.ReadByte(net_message); + cmd = MSG.ReadByte(Globals.net_message); CL_parse.SHOWNET(CL_parse.svc_strings[cmd]); - if (cmd != svc_packetentities) - Com.Error(ERR_DROP, "CL_ParseFrame: not packetentities"); - - ParsePacketEntities(old, cl.frame); + if (cmd != Defines.svc_packetentities) + Com.Error(Defines.ERR_DROP, "CL_ParseFrame: not packetentities"); + + ParsePacketEntities(old, Globals.cl.frame); // save the frame off in the backup array for later delta comparisons - cl.frames[cl.frame.serverframe & UPDATE_MASK].set(cl.frame); + Globals.cl.frames[Globals.cl.frame.serverframe & Defines.UPDATE_MASK].set(Globals.cl.frame); - if (cl.frame.valid) { + if (Globals.cl.frame.valid) { // getting a valid frame message ends the connection process - if (cls.state != ca_active) { - cls.state = ca_active; - cl.force_refdef = true; - - cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0] * 0.125f; - cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1] * 0.125f; - cl.predicted_origin[2] = cl.frame.playerstate.pmove.origin[2] * 0.125f; - - VectorCopy(cl.frame.playerstate.viewangles, cl.predicted_angles); - if (cls.disable_servercount != cl.servercount && cl.refresh_prepped) + if (Globals.cls.state != Defines.ca_active) { + Globals.cls.state = Defines.ca_active; + Globals.cl.force_refdef = true; + + Globals.cl.predicted_origin[0] = Globals.cl.frame.playerstate.pmove.origin[0] * 0.125f; + Globals.cl.predicted_origin[1] = Globals.cl.frame.playerstate.pmove.origin[1] * 0.125f; + Globals.cl.predicted_origin[2] = Globals.cl.frame.playerstate.pmove.origin[2] * 0.125f; + + Math3D.VectorCopy(Globals.cl.frame.playerstate.viewangles, Globals.cl.predicted_angles); + if (Globals.cls.disable_servercount != Globals.cl.servercount && Globals.cl.refresh_prepped) SCR.EndLoadingPlaque(); // get rid of loading plaque } - cl.sound_prepped = true; // can start mixing ambient sounds + Globals.cl.sound_prepped = true; // can start mixing ambient sounds // fire entity events - FireEntityEvents(cl.frame); + FireEntityEvents(Globals.cl.frame); CL_pred.CheckPredictionError(); } } /* - ========================================================================== - - INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS - - ========================================================================== - */ - - public static model_t S_RegisterSexedModel(entity_state_t ent, String base) { + * ========================================================================== + * + * INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS + * + * ========================================================================== + */ + + public static model_t S_RegisterSexedModel(entity_state_t ent, String base) { int n; model_t mdl; String model; @@ -595,38 +596,38 @@ public class CL_ents extends CL_inv { // determine what model the client is using model = ""; - - n = CS_PLAYERSKINS + ent.number - 1; - - if (cl.configstrings[n].length() >0) { - - int pos = cl.configstrings[n].indexOf('\\'); - if (pos!=-1) { + + n = Defines.CS_PLAYERSKINS + ent.number - 1; + + if (Globals.cl.configstrings[n].length() > 0) { + + int pos = Globals.cl.configstrings[n].indexOf('\\'); + if (pos != -1) { pos++; - model = cl.configstrings[n].substring(pos); + model = Globals.cl.configstrings[n].substring(pos); pos = model.indexOf('/'); - if (pos !=-1) - model = model.substring(0,pos); + if (pos != -1) + model = model.substring(0, pos); } } // if we can't figure it out, they're male - if (model.length()==0) + if (model.length() == 0) model = "male"; - buffer= "players/" + model + "/" + base + 1; - mdl = re.RegisterModel(buffer); - if (mdl==null) { + buffer = "players/" + model + "/" + base + 1; + mdl = Globals.re.RegisterModel(buffer); + if (mdl == null) { // not found, try default weapon model - buffer = "players/" + model + "/weapon.md2"; - mdl = re.RegisterModel(buffer); - if (mdl==null) { + buffer = "players/" + model + "/weapon.md2"; + mdl = Globals.re.RegisterModel(buffer); + if (mdl == null) { // no, revert to the male model - buffer="players/male/" + base + 1; - mdl = re.RegisterModel(buffer); - if (mdl==null) { + buffer = "players/male/" + base + 1; + mdl = Globals.re.RegisterModel(buffer); + if (mdl == null) { // last try, default male weapon.md2 buffer = "players/male/weapon.md2"; - mdl = re.RegisterModel(buffer); + mdl = Globals.re.RegisterModel(buffer); } } } @@ -634,220 +635,215 @@ public class CL_ents extends CL_inv { return mdl; } - // PMM - used in shell code + // PMM - used in shell code /* - =============== - CL_AddPacketEntities - - =============== - */ - static int bfg_lightramp[] = { 300, 400, 600, 300, 150, 75 }; - - static void AddPacketEntities(frame_t frame) { + * =============== CL_AddPacketEntities + * + * =============== + */ + static void AddPacketEntities(frame_t frame) { entity_t ent; entity_state_t s1; float autorotate; int i; int pnum; - centity_t cent; + centity_t cent; int autoanim; - clientinfo_t ci; + clientinfo_t ci; int effects, renderfx; // bonus items rotate at a fixed rate - autorotate = anglemod(cl.time / 10); + autorotate = Math3D.anglemod(Globals.cl.time / 10); // brush models can auto animate their frames - autoanim = 2 * cl.time / 1000; + autoanim = 2 * Globals.cl.time / 1000; //memset( ent, 0, sizeof(ent)); ent = new entity_t(); for (pnum = 0; pnum < frame.num_entities; pnum++) { - s1 = cl_parse_entities[(frame.parse_entities + pnum) & (MAX_PARSE_ENTITIES - 1)]; + s1 = Globals.cl_parse_entities[(frame.parse_entities + pnum) & (Defines.MAX_PARSE_ENTITIES - 1)]; - cent = cl_entities[s1.number]; + cent = Globals.cl_entities[s1.number]; effects = s1.effects; renderfx = s1.renderfx; // set frame - if ((effects & EF_ANIM01)!=0) + if ((effects & Defines.EF_ANIM01) != 0) ent.frame = autoanim & 1; - else if ((effects & EF_ANIM23)!=0) + else if ((effects & Defines.EF_ANIM23) != 0) ent.frame = 2 + (autoanim & 1); - else if ((effects & EF_ANIM_ALL)!=0) + else if ((effects & Defines.EF_ANIM_ALL) != 0) ent.frame = autoanim; - else if ((effects & EF_ANIM_ALLFAST)!=0) - ent.frame = cl.time / 100; + else if ((effects & Defines.EF_ANIM_ALLFAST) != 0) + ent.frame = Globals.cl.time / 100; else ent.frame = s1.frame; // quad and pent can do different things on client - if ((effects & EF_PENT)!=0) { - effects &= ~EF_PENT; - effects |= EF_COLOR_SHELL; - renderfx |= RF_SHELL_RED; + if ((effects & Defines.EF_PENT) != 0) { + effects &= ~Defines.EF_PENT; + effects |= Defines.EF_COLOR_SHELL; + renderfx |= Defines.RF_SHELL_RED; } - if ((effects & EF_QUAD)!=0) { - effects &= ~EF_QUAD; - effects |= EF_COLOR_SHELL; - renderfx |= RF_SHELL_BLUE; + if ((effects & Defines.EF_QUAD) != 0) { + effects &= ~Defines.EF_QUAD; + effects |= Defines.EF_COLOR_SHELL; + renderfx |= Defines.RF_SHELL_BLUE; } // ====== // PMM - if ((effects & EF_DOUBLE)!=0) { - effects &= ~EF_DOUBLE; - effects |= EF_COLOR_SHELL; - renderfx |= RF_SHELL_DOUBLE; + if ((effects & Defines.EF_DOUBLE) != 0) { + effects &= ~Defines.EF_DOUBLE; + effects |= Defines.EF_COLOR_SHELL; + renderfx |= Defines.RF_SHELL_DOUBLE; } - if ((effects & EF_HALF_DAMAGE) !=0){ - effects &= ~EF_HALF_DAMAGE; - effects |= EF_COLOR_SHELL; - renderfx |= RF_SHELL_HALF_DAM; + if ((effects & Defines.EF_HALF_DAMAGE) != 0) { + effects &= ~Defines.EF_HALF_DAMAGE; + effects |= Defines.EF_COLOR_SHELL; + renderfx |= Defines.RF_SHELL_HALF_DAM; } // pmm // ====== ent.oldframe = cent.prev.frame; - ent.backlerp = 1.0f - cl.lerpfrac; + ent.backlerp = 1.0f - Globals.cl.lerpfrac; - if ((renderfx & (RF_FRAMELERP | RF_BEAM))!=0) { // step origin discretely, because the frames + if ((renderfx & (Defines.RF_FRAMELERP | Defines.RF_BEAM)) != 0) { + // step origin discretely, because the frames // do the animation properly - VectorCopy(cent.current.origin, ent.origin); - VectorCopy(cent.current.old_origin, ent.oldorigin); - } - else { // interpolate origin + Math3D.VectorCopy(cent.current.origin, ent.origin); + Math3D.VectorCopy(cent.current.old_origin, ent.oldorigin); + } else { // interpolate origin for (i = 0; i < 3; i++) { - ent.origin[i] = - ent.oldorigin[i] = cent.prev.origin[i] + cl.lerpfrac * (cent.current.origin[i] - cent.prev.origin[i]); + ent.origin[i] = ent.oldorigin[i] = cent.prev.origin[i] + Globals.cl.lerpfrac + * (cent.current.origin[i] - cent.prev.origin[i]); } } // create a new entity // tweak the color of beams - if ((renderfx & RF_BEAM)!=0) { // the four beam colors are encoded in 32 bits of skinnum (hack) + if ((renderfx & Defines.RF_BEAM) != 0) { // the four beam colors are + // encoded in 32 bits of + // skinnum (hack) ent.alpha = 0.30f; - ent.skinnum = (s1.skinnum >> ((rnd.nextInt(4)) * 8)) & 0xff; + ent.skinnum = (s1.skinnum >> ((Globals.rnd.nextInt(4)) * 8)) & 0xff; Math.random(); ent.model = null; - } - else { + } else { // set skin if (s1.modelindex == 255) { // use custom player skin ent.skinnum = 0; - ci = cl.clientinfo[s1.skinnum & 0xff]; + ci = Globals.cl.clientinfo[s1.skinnum & 0xff]; ent.skin = ci.skin; ent.model = ci.model; - if (null==ent.skin || null==ent.model) { - ent.skin = cl.baseclientinfo.skin; - ent.model = cl.baseclientinfo.model; + if (null == ent.skin || null == ent.model) { + ent.skin = Globals.cl.baseclientinfo.skin; + ent.model = Globals.cl.baseclientinfo.model; } // ============ // PGM - if ((renderfx & RF_USE_DISGUISE)!=0) { + if ((renderfx & Defines.RF_USE_DISGUISE) != 0) { if (ent.skin.name.startsWith("players/male")) { - ent.skin = re.RegisterSkin("players/male/disguise.pcx"); - ent.model = re.RegisterModel("players/male/tris.md2"); - } - else if (ent.skin.name.startsWith( "players/female")) { - ent.skin = re.RegisterSkin("players/female/disguise.pcx"); - ent.model = re.RegisterModel("players/female/tris.md2"); - } - else if (ent.skin.name.startsWith("players/cyborg")) { - ent.skin = re.RegisterSkin("players/cyborg/disguise.pcx"); - ent.model = re.RegisterModel("players/cyborg/tris.md2"); + ent.skin = Globals.re.RegisterSkin("players/male/disguise.pcx"); + ent.model = Globals.re.RegisterModel("players/male/tris.md2"); + } else if (ent.skin.name.startsWith("players/female")) { + ent.skin = Globals.re.RegisterSkin("players/female/disguise.pcx"); + ent.model = Globals.re.RegisterModel("players/female/tris.md2"); + } else if (ent.skin.name.startsWith("players/cyborg")) { + ent.skin = Globals.re.RegisterSkin("players/cyborg/disguise.pcx"); + ent.model = Globals.re.RegisterModel("players/cyborg/tris.md2"); } } // PGM // ============ - } - else { + } else { ent.skinnum = s1.skinnum; ent.skin = null; - ent.model = cl.model_draw[s1.modelindex]; + ent.model = Globals.cl.model_draw[s1.modelindex]; } } // only used for black hole model right now, FIXME: do better - if (renderfx == RF_TRANSLUCENT) + if (renderfx == Defines.RF_TRANSLUCENT) ent.alpha = 0.70f; // render effects (fullbright, translucent, etc) - if ((effects & EF_COLOR_SHELL)!=0) + if ((effects & Defines.EF_COLOR_SHELL) != 0) ent.flags = 0; // renderfx go on color shell entity else ent.flags = renderfx; // calculate angles - if ((effects & EF_ROTATE)!=0) { // some bonus items auto-rotate + if ((effects & Defines.EF_ROTATE) != 0) { // some bonus items + // auto-rotate ent.angles[0] = 0; ent.angles[1] = autorotate; ent.angles[2] = 0; } // RAFAEL - else if ((effects & EF_SPINNINGLIGHTS)!=0) { + else if ((effects & Defines.EF_SPINNINGLIGHTS) != 0) { ent.angles[0] = 0; - ent.angles[1] = anglemod(cl.time / 2) + s1.angles[1]; + ent.angles[1] = Math3D.anglemod(Globals.cl.time / 2) + s1.angles[1]; ent.angles[2] = 180; { - float[] forward={0,0,0}; - float[] start={0,0,0}; + float[] forward = { 0, 0, 0 }; + float[] start = { 0, 0, 0 }; - AngleVectors(ent.angles, forward, null, null); - VectorMA(ent.origin, 64, forward, start); + Math3D.AngleVectors(ent.angles, forward, null, null); + Math3D.VectorMA(ent.origin, 64, forward, start); V.AddLight(start, 100, 1, 0, 0); } - } - else { // interpolate angles + } else { // interpolate angles float a1, a2; for (i = 0; i < 3; i++) { a1 = cent.current.angles[i]; a2 = cent.prev.angles[i]; - ent.angles[i] = LerpAngle(a2, a1, cl.lerpfrac); + ent.angles[i] = Math3D.LerpAngle(a2, a1, Globals.cl.lerpfrac); } } - if (s1.number == cl.playernum + 1) { - ent.flags |= RF_VIEWERMODEL; // only draw from mirrors + if (s1.number == Globals.cl.playernum + 1) { + ent.flags |= Defines.RF_VIEWERMODEL; // only draw from mirrors // FIXME: still pass to refresh - if ((effects & EF_FLAG1)!=0) + if ((effects & Defines.EF_FLAG1) != 0) V.AddLight(ent.origin, 225, 1.0f, 0.1f, 0.1f); - else if ((effects & EF_FLAG2)!=0) + else if ((effects & Defines.EF_FLAG2) != 0) V.AddLight(ent.origin, 225, 0.1f, 0.1f, 1.0f); - else if ((effects & EF_TAGTRAIL)!=0) //PGM + else if ((effects & Defines.EF_TAGTRAIL) != 0) //PGM V.AddLight(ent.origin, 225, 1.0f, 1.0f, 0.0f); //PGM - else if ((effects & EF_TRACKERTRAIL)!=0) //PGM + else if ((effects & Defines.EF_TRACKERTRAIL) != 0) //PGM V.AddLight(ent.origin, 225, -1.0f, -1.0f, -1.0f); //PGM continue; } // if set to invisible, skip - if (s1.modelindex==0) + if (s1.modelindex == 0) continue; - if ((effects & EF_BFG)!=0) { - ent.flags |= RF_TRANSLUCENT; + if ((effects & Defines.EF_BFG) != 0) { + ent.flags |= Defines.RF_TRANSLUCENT; ent.alpha = 0.30f; } // RAFAEL - if ((effects & EF_PLASMA)!=0) { - ent.flags |= RF_TRANSLUCENT; + if ((effects & Defines.EF_PLASMA) != 0) { + ent.flags |= Defines.RF_TRANSLUCENT; ent.alpha = 0.6f; } - if ((effects & EF_SPHERETRANS)!=0) { - ent.flags |= RF_TRANSLUCENT; - // PMM - *sigh* yet more EF overloading - if ((effects & EF_TRACKERTRAIL)!=0) + if ((effects & Defines.EF_SPHERETRANS) != 0) { + ent.flags |= Defines.RF_TRANSLUCENT; + // PMM - *sigh* yet more EF overloading + if ((effects & Defines.EF_TRACKERTRAIL) != 0) ent.alpha = 0.6f; else ent.alpha = 0.3f; @@ -855,50 +851,54 @@ public class CL_ents extends CL_inv { // pmm // add to refresh list - V.AddEntity( ent); + V.AddEntity(ent); // color shells generate a seperate entity for the main model - if ((effects & EF_COLOR_SHELL)!=0) { + if ((effects & Defines.EF_COLOR_SHELL) != 0) { /* - PMM - at this point, all of the shells have been handled - if we're in the rogue pack, set up the custom mixing, otherwise just - keep going - if(Developer_searchpath(2) == 2) - { - all of the solo colors are fine. we need to catch any of the combinations that look bad - (double & half) and turn them into the appropriate color, and make double/quad something special - + * PMM - at this point, all of the shells have been handled if + * we're in the rogue pack, set up the custom mixing, otherwise + * just keep going if(Developer_searchpath(2) == 2) { all of the + * solo colors are fine. we need to catch any of the + * combinations that look bad (double & half) and turn them into + * the appropriate color, and make double/quad something special + * */ - if ((renderfx & RF_SHELL_HALF_DAM)!=0) { + if ((renderfx & Defines.RF_SHELL_HALF_DAM) != 0) { if (FS.Developer_searchpath(2) == 2) { - // ditch the half damage shell if any of red, blue, or double are on - if ((renderfx & (RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE))!=0) - renderfx &= ~RF_SHELL_HALF_DAM; + // ditch the half damage shell if any of red, blue, or + // double are on + if ((renderfx & (Defines.RF_SHELL_RED | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE)) != 0) + renderfx &= ~Defines.RF_SHELL_HALF_DAM; } } - if ((renderfx & RF_SHELL_DOUBLE)!=0) { + if ((renderfx & Defines.RF_SHELL_DOUBLE) != 0) { if (FS.Developer_searchpath(2) == 2) { - // lose the yellow shell if we have a red, blue, or green shell - if ((renderfx & (RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_GREEN))!=0) - renderfx &= ~RF_SHELL_DOUBLE; - // if we have a red shell, turn it to purple by adding blue - if ((renderfx & RF_SHELL_RED)!=0) - renderfx |= RF_SHELL_BLUE; - // if we have a blue shell (and not a red shell), turn it to cyan by adding green - else if ((renderfx & RF_SHELL_BLUE)!=0) - // go to green if it's on already, otherwise do cyan (flash green) - if ((renderfx & RF_SHELL_GREEN)!=0) - renderfx &= ~RF_SHELL_BLUE; + // lose the yellow shell if we have a red, blue, or + // green shell + if ((renderfx & (Defines.RF_SHELL_RED | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_GREEN)) != 0) + renderfx &= ~Defines.RF_SHELL_DOUBLE; + // if we have a red shell, turn it to purple by adding + // blue + if ((renderfx & Defines.RF_SHELL_RED) != 0) + renderfx |= Defines.RF_SHELL_BLUE; + // if we have a blue shell (and not a red shell), turn + // it to cyan by adding green + else if ((renderfx & Defines.RF_SHELL_BLUE) != 0) + // go to green if it's on already, otherwise do cyan + // (flash green) + if ((renderfx & Defines.RF_SHELL_GREEN) != 0) + renderfx &= ~Defines.RF_SHELL_BLUE; else - renderfx |= RF_SHELL_GREEN; + renderfx |= Defines.RF_SHELL_GREEN; } } // } // pmm - ent.flags = renderfx | RF_TRANSLUCENT; + ent.flags = renderfx | Defines.RF_TRANSLUCENT; ent.alpha = 0.30f; - V.AddEntity( ent); + V.AddEntity(ent); } ent.skin = null; // never use a custom skin on others @@ -907,146 +907,138 @@ public class CL_ents extends CL_inv { ent.alpha = 0; // duplicate for linked models - if (s1.modelindex2!=0) { + if (s1.modelindex2 != 0) { if (s1.modelindex2 == 255) { // custom weapon - ci = cl.clientinfo[s1.skinnum & 0xff]; + ci = Globals.cl.clientinfo[s1.skinnum & 0xff]; i = (s1.skinnum >> 8); // 0 is default weapon model - if (0==cl_vwep.value || i > MAX_CLIENTWEAPONMODELS - 1) + if (0 == Globals.cl_vwep.value || i > Defines.MAX_CLIENTWEAPONMODELS - 1) i = 0; ent.model = ci.weaponmodel[i]; - if (null==ent.model) { + if (null == ent.model) { if (i != 0) ent.model = ci.weaponmodel[0]; - if (null==ent.model) - ent.model = cl.baseclientinfo.weaponmodel[0]; + if (null == ent.model) + ent.model = Globals.cl.baseclientinfo.weaponmodel[0]; } - } - else - ent.model = cl.model_draw[s1.modelindex2]; - - // PMM - check for the defender sphere shell .. make it translucent - // replaces the previous version which used the high bit on modelindex2 to determine transparency - if (cl.configstrings[CS_MODELS + (s1.modelindex2)].equalsIgnoreCase( "models/items/shell/tris.md2")) { + } else + ent.model = Globals.cl.model_draw[s1.modelindex2]; + + // PMM - check for the defender sphere shell .. make it + // translucent + // replaces the previous version which used the high bit on + // modelindex2 to determine transparency + if (Globals.cl.configstrings[Defines.CS_MODELS + (s1.modelindex2)].equalsIgnoreCase("models/items/shell/tris.md2")) { ent.alpha = 0.32f; - ent.flags = RF_TRANSLUCENT; + ent.flags = Defines.RF_TRANSLUCENT; } // pmm - V.AddEntity( ent); + V.AddEntity(ent); //PGM - make sure these get reset. ent.flags = 0; ent.alpha = 0; //PGM } - if (s1.modelindex3!=0) { - ent.model = cl.model_draw[s1.modelindex3]; - V.AddEntity( ent); + if (s1.modelindex3 != 0) { + ent.model = Globals.cl.model_draw[s1.modelindex3]; + V.AddEntity(ent); } - if (s1.modelindex4!=0) { - ent.model = cl.model_draw[s1.modelindex4]; - V.AddEntity( ent); + if (s1.modelindex4 != 0) { + ent.model = Globals.cl.model_draw[s1.modelindex4]; + V.AddEntity(ent); } - if ((effects & EF_POWERSCREEN)!=0) { + if ((effects & Defines.EF_POWERSCREEN) != 0) { ent.model = CL_tent.cl_mod_powerscreen; ent.oldframe = 0; ent.frame = 0; - ent.flags |= (RF_TRANSLUCENT | RF_SHELL_GREEN); + ent.flags |= (Defines.RF_TRANSLUCENT | Defines.RF_SHELL_GREEN); ent.alpha = 0.30f; - V.AddEntity( ent); + V.AddEntity(ent); } // add automatic particle trails - if ((effects & ~EF_ROTATE)!=0) { - if ((effects & EF_ROCKET)!=0) { - RocketTrail(cent.lerp_origin, ent.origin, cent); + if ((effects & ~Defines.EF_ROTATE) != 0) { + if ((effects & Defines.EF_ROCKET) != 0) { + CL_fx.RocketTrail(cent.lerp_origin, ent.origin, cent); V.AddLight(ent.origin, 200, 1, 1, 0); } - // PGM - Do not reorder EF_BLASTER and EF_HYPERBLASTER. - // EF_BLASTER | EF_TRACKER is a special case for EF_BLASTER2... Cheese! - else if ((effects & EF_BLASTER)!=0) { + // PGM - Do not reorder EF_BLASTER and EF_HYPERBLASTER. + // EF_BLASTER | EF_TRACKER is a special case for EF_BLASTER2... + // Cheese! + else if ((effects & Defines.EF_BLASTER) != 0) { // CL_BlasterTrail (cent.lerp_origin, ent.origin); // PGM - if ((effects & EF_TRACKER)!=0) // lame... problematic? - { + if ((effects & Defines.EF_TRACKER) != 0) // lame... + // problematic? + { CL_newfx.BlasterTrail2(cent.lerp_origin, ent.origin); V.AddLight(ent.origin, 200, 0, 1, 0); - } - else { - BlasterTrail(cent.lerp_origin, ent.origin); + } else { + CL_fx.BlasterTrail(cent.lerp_origin, ent.origin); V.AddLight(ent.origin, 200, 1, 1, 0); } // PGM - } - else if ((effects & EF_HYPERBLASTER)!=0) { - if ((effects & EF_TRACKER)!=0) // PGM overloaded for blaster2. + } else if ((effects & Defines.EF_HYPERBLASTER) != 0) { + if ((effects & Defines.EF_TRACKER) != 0) // PGM overloaded + // for blaster2. V.AddLight(ent.origin, 200, 0, 1, 0); // PGM - else // PGM + else + // PGM V.AddLight(ent.origin, 200, 1, 1, 0); - } - else if ((effects & EF_GIB)!=0) { - DiminishingTrail(cent.lerp_origin, ent.origin, cent, effects); - } - else if ((effects & EF_GRENADE)!=0) { - DiminishingTrail(cent.lerp_origin, ent.origin, cent, effects); - } - else if ((effects & EF_FLIES)!=0) { - FlyEffect(cent, ent.origin); - } - else if ((effects & EF_BFG)!=0) { - - - if ((effects & EF_ANIM_ALLFAST)!=0) { - BfgParticles( ent); + } else if ((effects & Defines.EF_GIB) != 0) { + CL_fx.DiminishingTrail(cent.lerp_origin, ent.origin, cent, effects); + } else if ((effects & Defines.EF_GRENADE) != 0) { + CL_fx.DiminishingTrail(cent.lerp_origin, ent.origin, cent, effects); + } else if ((effects & Defines.EF_FLIES) != 0) { + CL_fx.FlyEffect(cent, ent.origin); + } else if ((effects & Defines.EF_BFG) != 0) { + + if ((effects & Defines.EF_ANIM_ALLFAST) != 0) { + CL_fx.BfgParticles(ent); i = 200; - } - else { + } else { i = bfg_lightramp[s1.frame]; } V.AddLight(ent.origin, i, 0, 1, 0); } // RAFAEL - else if ((effects & EF_TRAP)!=0) { + else if ((effects & Defines.EF_TRAP) != 0) { ent.origin[2] += 32; - TrapParticles( ent); - i = (rnd.nextInt(100)) + 100; + CL_fx.TrapParticles(ent); + i = (Globals.rnd.nextInt(100)) + 100; V.AddLight(ent.origin, i, 1, 0.8f, 0.1f); - } - else if ((effects & EF_FLAG1)!=0) { - FlagTrail(cent.lerp_origin, ent.origin, 242); + } else if ((effects & Defines.EF_FLAG1) != 0) { + CL_fx.FlagTrail(cent.lerp_origin, ent.origin, 242); V.AddLight(ent.origin, 225, 1, 0.1f, 0.1f); - } - else if ((effects & EF_FLAG2)!=0) { - FlagTrail(cent.lerp_origin, ent.origin, 115); + } else if ((effects & Defines.EF_FLAG2) != 0) { + CL_fx.FlagTrail(cent.lerp_origin, ent.origin, 115); V.AddLight(ent.origin, 225, 0.1f, 0.1f, 1); } // ====== // ROGUE - else if ((effects & EF_TAGTRAIL)!=0) { + else if ((effects & Defines.EF_TAGTRAIL) != 0) { CL_newfx.TagTrail(cent.lerp_origin, ent.origin, 220); V.AddLight(ent.origin, 225, 1.0f, 1.0f, 0.0f); - } - else if ((effects & EF_TRACKERTRAIL)!=0) { - if ((effects & EF_TRACKER)!=0) { + } else if ((effects & Defines.EF_TRACKERTRAIL) != 0) { + if ((effects & Defines.EF_TRACKER) != 0) { float intensity; - intensity = (float) (50 + (500 * (Math.sin(cl.time / 500.0) + 1.0))); + intensity = (float) (50 + (500 * (Math.sin(Globals.cl.time / 500.0) + 1.0))); // FIXME - check out this effect in rendition - if (vidref_val == VIDREF_GL) + if (Globals.vidref_val == Defines.VIDREF_GL) V.AddLight(ent.origin, intensity, -1.0f, -1.0f, -1.0f); else V.AddLight(ent.origin, -1.0f * intensity, 1.0f, 1.0f, 1.0f); - } - else { + } else { CL_newfx.Tracker_Shell(cent.lerp_origin); V.AddLight(ent.origin, 155, -1.0f, -1.0f, -1.0f); } - } - else if ((effects & EF_TRACKER)!=0) { + } else if ((effects & Defines.EF_TRACKER) != 0) { CL_newfx.TrackerTrail(cent.lerp_origin, ent.origin, 0); // FIXME - check out this effect in rendition - if (vidref_val == VIDREF_GL) + if (Globals.vidref_val == Defines.VIDREF_GL) V.AddLight(ent.origin, 200, -1, -1, -1); else V.AddLight(ent.origin, -200, 1, 1, 1); @@ -1054,42 +1046,40 @@ public class CL_ents extends CL_inv { // ROGUE // ====== // RAFAEL - else if ((effects & EF_GREENGIB)!=0) { - DiminishingTrail(cent.lerp_origin, ent.origin, cent, effects); + else if ((effects & Defines.EF_GREENGIB) != 0) { + CL_fx.DiminishingTrail(cent.lerp_origin, ent.origin, cent, effects); } // RAFAEL - else if ((effects & EF_IONRIPPER)!=0) { - IonripperTrail(cent.lerp_origin, ent.origin); + else if ((effects & Defines.EF_IONRIPPER) != 0) { + CL_fx.IonripperTrail(cent.lerp_origin, ent.origin); V.AddLight(ent.origin, 100, 1, 0.5f, 0.5f); } // RAFAEL - else if ((effects & EF_BLUEHYPERBLASTER)!=0) { + else if ((effects & Defines.EF_BLUEHYPERBLASTER) != 0) { V.AddLight(ent.origin, 200, 0, 0, 1); } // RAFAEL - else if ((effects & EF_PLASMA)!=0) { - if ((effects & EF_ANIM_ALLFAST)!=0) { - BlasterTrail(cent.lerp_origin, ent.origin); + else if ((effects & Defines.EF_PLASMA) != 0) { + if ((effects & Defines.EF_ANIM_ALLFAST) != 0) { + CL_fx.BlasterTrail(cent.lerp_origin, ent.origin); } V.AddLight(ent.origin, 130, 1, 0.5f, 0.5f); } } - VectorCopy(ent.origin, cent.lerp_origin); + Math3D.VectorCopy(ent.origin, cent.lerp_origin); } } /* - ============== - CL_AddViewWeapon - ============== - */ - static void AddViewWeapon(player_state_t ps, player_state_t ops) { + * ============== CL_AddViewWeapon ============== + */ + static void AddViewWeapon(player_state_t ps, player_state_t ops) { entity_t gun; // view model int i; // allow the gun to be completely removed - if (0==cl_gun.value) + if (0 == Globals.cl_gun.value) return; // don't draw gun if in wide angle view @@ -1099,25 +1089,25 @@ public class CL_ents extends CL_inv { //memset( gun, 0, sizeof(gun)); gun = new entity_t(); - if (gun_model!=null) - gun.model = gun_model; // development tool + if (Globals.gun_model != null) + gun.model = Globals.gun_model; // development tool else - gun.model = cl.model_draw[ps.gunindex]; - - if (gun.model==null) + gun.model = Globals.cl.model_draw[ps.gunindex]; + + if (gun.model == null) return; // set up gun position for (i = 0; i < 3; i++) { - gun.origin[i] = cl.refdef.vieworg[i] + ops.gunoffset[i] + cl.lerpfrac * (ps.gunoffset[i] - ops.gunoffset[i]); - gun.angles[i] = cl.refdef.viewangles[i] + LerpAngle(ops.gunangles[i], ps.gunangles[i], cl.lerpfrac); + gun.origin[i] = Globals.cl.refdef.vieworg[i] + ops.gunoffset[i] + Globals.cl.lerpfrac + * (ps.gunoffset[i] - ops.gunoffset[i]); + gun.angles[i] = Globals.cl.refdef.viewangles[i] + Math3D.LerpAngle(ops.gunangles[i], ps.gunangles[i], Globals.cl.lerpfrac); } - if (gun_frame!=0) { - gun.frame = gun_frame; // development tool - gun.oldframe = gun_frame; // development tool - } - else { + if (Globals.gun_frame != 0) { + gun.frame = Globals.gun_frame; // development tool + gun.oldframe = Globals.gun_frame; // development tool + } else { gun.frame = ps.gunframe; if (gun.frame == 0) gun.oldframe = 0; // just changed weapons, don't lerp from old @@ -1125,159 +1115,146 @@ public class CL_ents extends CL_inv { gun.oldframe = ops.gunframe; } - gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL; - gun.backlerp = 1.0f - cl.lerpfrac; - VectorCopy(gun.origin, gun.oldorigin); // don't lerp at all - V.AddEntity( gun); + gun.flags = Defines.RF_MINLIGHT | Defines.RF_DEPTHHACK | Defines.RF_WEAPONMODEL; + gun.backlerp = 1.0f - Globals.cl.lerpfrac; + Math3D.VectorCopy(gun.origin, gun.oldorigin); // don't lerp at all + V.AddEntity(gun); } /* - =============== - CL_CalcViewValues - - Sets cl.refdef view values - =============== - */ + * =============== CL_CalcViewValues + * + * Sets cl.refdef view values =============== + */ static void CalcViewValues() { int i; float lerp, backlerp; - frame_t oldframe; - player_state_t ps, ops; + frame_t oldframe; + player_state_t ps, ops; // find the previous frame to interpolate from - ps = cl.frame.playerstate; - - i = (cl.frame.serverframe - 1) & UPDATE_MASK; - oldframe = cl.frames[i]; - - if (oldframe.serverframe != cl.frame.serverframe - 1 || !oldframe.valid) - oldframe = cl.frame; // previous frame was dropped or involid - ops = oldframe.playerstate; + ps = Globals.cl.frame.playerstate; + + i = (Globals.cl.frame.serverframe - 1) & Defines.UPDATE_MASK; + oldframe = Globals.cl.frames[i]; + + if (oldframe.serverframe != Globals.cl.frame.serverframe - 1 || !oldframe.valid) + oldframe = Globals.cl.frame; // previous frame was dropped or + // involid + ops = oldframe.playerstate; // see if the player entity was teleported this frame if (Math.abs(ops.pmove.origin[0] - ps.pmove.origin[0]) > 256 * 8 - || Math.abs(ops.pmove.origin[1] - ps.pmove.origin[1]) > 256 * 8 - || Math.abs(ops.pmove.origin[2] - ps.pmove.origin[2]) > 256 * 8) + || Math.abs(ops.pmove.origin[1] - ps.pmove.origin[1]) > 256 * 8 + || Math.abs(ops.pmove.origin[2] - ps.pmove.origin[2]) > 256 * 8) ops = ps; // don't interpolate - lerp = cl.lerpfrac; + lerp = Globals.cl.lerpfrac; // calculate the origin - if ((cl_predict.value!=0) && 0==(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) { // use predicted values + if ((Globals.cl_predict.value != 0) && 0 == (Globals.cl.frame.playerstate.pmove.pm_flags & pmove_t.PMF_NO_PREDICTION)) { // use + // predicted + // values int delta; backlerp = 1.0f - lerp; for (i = 0; i < 3; i++) { - cl.refdef.vieworg[i] = - cl.predicted_origin[i] - + ops.viewoffset[i] - + cl.lerpfrac * (ps.viewoffset[i] - ops.viewoffset[i]) - - backlerp * cl.prediction_error[i]; + Globals.cl.refdef.vieworg[i] = Globals.cl.predicted_origin[i] + ops.viewoffset[i] + Globals.cl.lerpfrac + * (ps.viewoffset[i] - ops.viewoffset[i]) - backlerp * Globals.cl.prediction_error[i]; } // smooth out stair climbing - delta = (int) (cls.realtime - cl.predicted_step_time); + delta = (int) (Globals.cls.realtime - Globals.cl.predicted_step_time); if (delta < 100) - cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01; - } - else { // just use interpolated values + Globals.cl.refdef.vieworg[2] -= Globals.cl.predicted_step * (100 - delta) * 0.01; + } else { // just use interpolated values for (i = 0; i < 3; i++) - cl.refdef.vieworg[i] = - ops.pmove.origin[i] * 0.125f - + ops.viewoffset[i] - + lerp * (ps.pmove.origin[i] * 0.125f + ps.viewoffset[i] - (ops.pmove.origin[i] * 0.125f + ops.viewoffset[i])); + Globals.cl.refdef.vieworg[i] = ops.pmove.origin[i] * 0.125f + ops.viewoffset[i] + lerp + * (ps.pmove.origin[i] * 0.125f + ps.viewoffset[i] - (ops.pmove.origin[i] * 0.125f + ops.viewoffset[i])); } - // if not running a demo or on a locked frame, add the local angle movement - if (cl.frame.playerstate.pmove.pm_type < PM_DEAD) { // use predicted values + // if not running a demo or on a locked frame, add the local angle + // movement + if (Globals.cl.frame.playerstate.pmove.pm_type < Defines.PM_DEAD) { // use + // predicted + // values for (i = 0; i < 3; i++) - cl.refdef.viewangles[i] = cl.predicted_angles[i]; - } - else { // just use interpolated values + Globals.cl.refdef.viewangles[i] = Globals.cl.predicted_angles[i]; + } else { // just use interpolated values for (i = 0; i < 3; i++) - cl.refdef.viewangles[i] = LerpAngle(ops.viewangles[i], ps.viewangles[i], lerp); + Globals.cl.refdef.viewangles[i] = Math3D.LerpAngle(ops.viewangles[i], ps.viewangles[i], lerp); } for (i = 0; i < 3; i++) - cl.refdef.viewangles[i] += LerpAngle(ops.kick_angles[i], ps.kick_angles[i], lerp); + Globals.cl.refdef.viewangles[i] += Math3D.LerpAngle(ops.kick_angles[i], ps.kick_angles[i], lerp); - AngleVectors(cl.refdef.viewangles, cl.v_forward, cl.v_right, cl.v_up); + Math3D.AngleVectors(Globals.cl.refdef.viewangles, Globals.cl.v_forward, Globals.cl.v_right, Globals.cl.v_up); // interpolate field of view - cl.refdef.fov_x = ops.fov + lerp * (ps.fov - ops.fov); + Globals.cl.refdef.fov_x = ops.fov + lerp * (ps.fov - ops.fov); // don't interpolate blend color for (i = 0; i < 4; i++) - cl.refdef.blend[i] = ps.blend[i]; + Globals.cl.refdef.blend[i] = ps.blend[i]; // add the weapon AddViewWeapon(ps, ops); } /* - =============== - CL_AddEntities - - Emits all entities, particles, and lights to the refresh - =============== - */ + * =============== CL_AddEntities + * + * Emits all entities, particles, and lights to the refresh =============== + */ static void AddEntities() { - if (cls.state != ca_active) + if (Globals.cls.state != Defines.ca_active) return; - if (cl.time > cl.frame.servertime) { - if (cl_showclamp.value!=0) - Com.Printf("high clamp " + (cl.time - cl.frame.servertime) + "\n"); - cl.time = cl.frame.servertime; - cl.lerpfrac = 1.0f; - } - else if (cl.time < cl.frame.servertime - 100) { - if (cl_showclamp.value!=0) - Com.Printf("low clamp " + (cl.frame.servertime - 100 - cl.time)+"\n"); - cl.time = cl.frame.servertime - 100; - cl.lerpfrac = 0; - } - else - cl.lerpfrac = 1.0f - (cl.frame.servertime - cl.time) * 0.01f; - - if (cl_timedemo.value!=0) - cl.lerpfrac = 1.0f; - - - /* is ok.. - CL_AddPacketEntities (cl.frame); - CL_AddTEnts (); - CL_AddParticles (); - CL_AddDLights (); - CL_AddLightStyles (); - */ - + if (Globals.cl.time > Globals.cl.frame.servertime) { + if (Globals.cl_showclamp.value != 0) + Com.Printf("high clamp " + (Globals.cl.time - Globals.cl.frame.servertime) + "\n"); + Globals.cl.time = Globals.cl.frame.servertime; + Globals.cl.lerpfrac = 1.0f; + } else if (Globals.cl.time < Globals.cl.frame.servertime - 100) { + if (Globals.cl_showclamp.value != 0) + Com.Printf("low clamp " + (Globals.cl.frame.servertime - 100 - Globals.cl.time) + "\n"); + Globals.cl.time = Globals.cl.frame.servertime - 100; + Globals.cl.lerpfrac = 0; + } else + Globals.cl.lerpfrac = 1.0f - (Globals.cl.frame.servertime - Globals.cl.time) * 0.01f; + + if (Globals.cl_timedemo.value != 0) + Globals.cl.lerpfrac = 1.0f; + + /* + * is ok.. CL_AddPacketEntities (cl.frame); CL_AddTEnts (); + * CL_AddParticles (); CL_AddDLights (); CL_AddLightStyles (); + */ + CalcViewValues(); - // PMM - moved this here so the heat beam has the right values for the vieworg, and can lock the beam to the gun - AddPacketEntities( cl.frame); + // PMM - moved this here so the heat beam has the right values for the + // vieworg, and can lock the beam to the gun + AddPacketEntities(Globals.cl.frame); CL_tent.AddTEnts(); - AddParticles(); + CL_fx.AddParticles(); CL_fx.AddDLights(); - AddLightStyles(); + CL_fx.AddLightStyles(); } /* - =============== - CL_GetEntitySoundOrigin - - Called to get the sound spatialization origin - =============== - */ + * =============== CL_GetEntitySoundOrigin + * + * Called to get the sound spatialization origin =============== + */ public static void GetEntitySoundOrigin(int ent, float[] org) { centity_t old; - if (ent < 0 || ent >= MAX_EDICTS) - Com.Error(ERR_DROP, "CL_GetEntitySoundOrigin: bad ent"); - old = cl_entities[ent]; - VectorCopy(old.lerp_origin, org); + if (ent < 0 || ent >= Defines.MAX_EDICTS) + Com.Error(Defines.ERR_DROP, "CL_GetEntitySoundOrigin: bad ent"); + old = Globals.cl_entities[ent]; + Math3D.VectorCopy(old.lerp_origin, org); // FIXME: bmodel issues... } - -} +}
\ No newline at end of file diff --git a/src/jake2/client/CL_fx.java b/src/jake2/client/CL_fx.java index 529101b..3032f81 100644 --- a/src/jake2/client/CL_fx.java +++ b/src/jake2/client/CL_fx.java @@ -1,92 +1,136 @@ /* - * CL_fx.java + * java * Copyright (C) 2004 * - * $Id: CL_fx.java,v 1.5 2004-07-13 11:09:55 hzi Exp $ + * $Id: CL_fx.java,v 1.6 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; +import jake2.Defines; import jake2.Globals; import jake2.game.M_Flash; import jake2.game.entity_state_t; import jake2.qcommon.Com; import jake2.qcommon.MSG; -import jake2.sound.*; +import jake2.sound.S; +import jake2.util.Lib; +import jake2.util.Math3D; /** - * CL_fx + * Client Graphics Effects. */ -public class CL_fx extends CL_tent { - - static final float INSTANT_PARTICLE = -10000.0f; - +public class CL_fx { + static class cdlight_t { int key; // so entities can reuse same entry + float[] color = { 0, 0, 0 }; + float[] origin = { 0, 0, 0 }; + float radius; + float die; // stop lighting after this time + //float decay; // drop this each second float minlight; // don't add when contributing less + void clear() { radius = minlight = color[0] = color[1] = color[2] = 0; } } - static float[][] avelocities = new float[NUMVERTEXNORMALS][3]; + static cparticle_t[] particles = new cparticle_t[Defines.MAX_PARTICLES]; + static { + for (int i = 0; i < particles.length; i++) + particles[i] = new cparticle_t(); + } + + static int cl_numparticles = Defines.MAX_PARTICLES; - /* - ============================================================== + static final float INSTANT_PARTICLE = -10000.0f; - LIGHT STYLE MANAGEMENT + static float[][] avelocities = new float[Defines.NUMVERTEXNORMALS][3]; - ============================================================== - */ + static clightstyle_t[] cl_lightstyle = new clightstyle_t[Defines.MAX_LIGHTSTYLES]; + + static int lastofs; + + /* + * ============================================================== + * + * LIGHT STYLE MANAGEMENT + * + * ============================================================== + */ static class clightstyle_t { int length; + float[] value = new float[3]; - float[] map = new float[MAX_QPATH]; + + float[] map = new float[Defines.MAX_QPATH]; + void clear() { value[0] = value[1] = value[2] = length = 0; for (int i = 0; i < map.length; i++) map[i] = 0.0f; } } - static clightstyle_t[] cl_lightstyle = new clightstyle_t[MAX_LIGHTSTYLES]; + static { - for(int i=0; i<cl_lightstyle.length; i++) { + for (int i = 0; i < cl_lightstyle.length; i++) { cl_lightstyle[i] = new clightstyle_t(); } } - static int lastofs; /* - ================ - CL_ClearLightStyles - ================ - */ - static void ClearLightStyles () - { + * ============================================================== + * + * DLIGHT MANAGEMENT + * + * ============================================================== + */ + + static cdlight_t[] cl_dlights = new cdlight_t[Defines.MAX_DLIGHTS]; + static { + for (int i = 0; i < cl_dlights.length; i++) + cl_dlights[i] = new cdlight_t(); + } + + /* + * ================ CL_ClearDlights ================ + */ + static void ClearDlights() { + // memset (cl_dlights, 0, sizeof(cl_dlights)); + for (int i = 0; i < cl_dlights.length; i++) { + cl_dlights[i].clear(); + } + } + + /* + * ================ CL_ClearLightStyles ================ + */ + static void ClearLightStyles() { //memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); for (int i = 0; i < cl_lightstyle.length; i++) cl_lightstyle[i].clear(); @@ -94,18 +138,16 @@ public class CL_fx extends CL_tent { } /* - ================ - CL_RunLightStyles - ================ - */ + * ================ CL_RunLightStyles ================ + */ static void RunLightStyles() { clightstyle_t ls; - int ofs = cl.time / 100; + int ofs = Globals.cl.time / 100; if (ofs == lastofs) return; lastofs = ofs; - + for (int i = 0; i < cl_lightstyle.length; i++) { ls = cl_lightstyle[i]; if (ls.length == 0) { @@ -123,11 +165,11 @@ public class CL_fx extends CL_tent { String s; int j, k; - s = cl.configstrings[i + CS_LIGHTS]; + s = Globals.cl.configstrings[i + Defines.CS_LIGHTS]; j = s.length(); - if (j >= MAX_QPATH) - Com.Error(ERR_DROP, "svc_lightstyle length=" + j); + if (j >= Defines.MAX_QPATH) + Com.Error(Defines.ERR_DROP, "svc_lightstyle length=" + j); cl_lightstyle[i].length = j; @@ -136,10 +178,8 @@ public class CL_fx extends CL_tent { } /* - ================ - CL_AddLightStyles - ================ - */ + * ================ CL_AddLightStyles ================ + */ static void AddLightStyles() { clightstyle_t ls; @@ -150,44 +190,17 @@ public class CL_fx extends CL_tent { } /* - ============================================================== - - DLIGHT MANAGEMENT - - ============================================================== - */ - - static cdlight_t[] cl_dlights = new cdlight_t[MAX_DLIGHTS]; - static { - for (int i = 0; i < cl_dlights.length; i++) - cl_dlights[i] = new cdlight_t(); - } - - /* - ================ - CL_ClearDlights - ================ - */ - static void ClearDlights() { - // memset (cl_dlights, 0, sizeof(cl_dlights)); - for (int i = 0; i < cl_dlights.length; i++) { - cl_dlights[i].clear(); - } - } - - /* - =============== - CL_AllocDlight - - =============== - */ + * =============== CL_AllocDlight + * + * =============== + */ static cdlight_t AllocDlight(int key) { int i; cdlight_t dl; // first look for an exact key match - if (key != 0) { - for (i = 0; i < MAX_DLIGHTS; i++) { + if (key != 0) { + for (i = 0; i < Defines.MAX_DLIGHTS; i++) { dl = cl_dlights[i]; if (dl.key == key) { //memset (dl, 0, sizeof(*dl)); @@ -199,9 +212,9 @@ public class CL_fx extends CL_tent { } // then look for anything else - for (i = 0; i < MAX_DLIGHTS; i++) { + for (i = 0; i < Defines.MAX_DLIGHTS; i++) { dl = cl_dlights[i]; - if (dl.die < cl.time) { + if (dl.die < Globals.cl.time) { //memset (dl, 0, sizeof(*dl)); dl.clear(); dl.key = key; @@ -218,36 +231,33 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_NewDlight - =============== - */ + * =============== CL_NewDlight =============== + */ static void NewDlight(int key, float x, float y, float z, float radius, float time) { cdlight_t dl; - dl = CL.AllocDlight(key); + dl = AllocDlight(key); dl.origin[0] = x; dl.origin[1] = y; dl.origin[2] = z; dl.radius = radius; - dl.die = cl.time + time; + dl.die = Globals.cl.time + time; } /* - =============== - CL_RunDLights - - =============== - */ + * =============== CL_RunDLights + * + * =============== + */ static void RunDLights() { cdlight_t dl; - for (int i = 0; i < MAX_DLIGHTS; i++) { + for (int i = 0; i < Defines.MAX_DLIGHTS; i++) { dl = cl_dlights[i]; if (dl.radius == 0.0f) continue; - if (dl.die < cl.time) { + if (dl.die < Globals.cl.time) { dl.radius = 0.0f; return; } @@ -258,37 +268,35 @@ public class CL_fx extends CL_tent { } /* - ============== - CL_ParseMuzzleFlash - ============== - */ + * ============== CL_ParseMuzzleFlash ============== + */ static void ParseMuzzleFlash() { float[] fv = new float[3]; float[] rv = new float[3]; float volume; String soundname; - int i = MSG.ReadShort(net_message); - if (i < 1 || i >= MAX_EDICTS) - Com.Error(ERR_DROP, "CL_ParseMuzzleFlash: bad entity"); + int i = MSG.ReadShort(Globals.net_message); + if (i < 1 || i >= Defines.MAX_EDICTS) + Com.Error(Defines.ERR_DROP, "CL_ParseMuzzleFlash: bad entity"); - int weapon = MSG.ReadByte(net_message); - int silenced = weapon & MZ_SILENCED; - weapon &= ~MZ_SILENCED; + int weapon = MSG.ReadByte(Globals.net_message); + int silenced = weapon & Defines.MZ_SILENCED; + weapon &= ~Defines.MZ_SILENCED; - centity_t pl = cl_entities[i]; + centity_t pl = Globals.cl_entities[i]; - cdlight_t dl = CL.AllocDlight(i); - VectorCopy(pl.current.origin, dl.origin); - AngleVectors(pl.current.angles, fv, rv, null); - VectorMA(dl.origin, 18, fv, dl.origin); - VectorMA(dl.origin, 16, rv, dl.origin); + cdlight_t dl = AllocDlight(i); + Math3D.VectorCopy(pl.current.origin, dl.origin); + Math3D.AngleVectors(pl.current.angles, fv, rv, null); + Math3D.VectorMA(dl.origin, 18, fv, dl.origin); + Math3D.VectorMA(dl.origin, 16, rv, dl.origin); if (silenced != 0) - dl.radius = 100 + (rnd.nextInt() & 31); + dl.radius = 100 + (Globals.rnd.nextInt() & 31); else - dl.radius = 200 + (rnd.nextInt() & 31); + dl.radius = 200 + (Globals.rnd.nextInt() & 31); dl.minlight = 32; - dl.die = cl.time; // + 0.1; + dl.die = Globals.cl.time; // + 0.1; if (silenced != 0) volume = 0.2f; @@ -296,682 +304,682 @@ public class CL_fx extends CL_tent { volume = 1; switch (weapon) { - case MZ_BLASTER : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); - break; - case MZ_BLUEHYPERBLASTER : - dl.color[0] = 0; - dl.color[1] = 0; - dl.color[2] = 1; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); - break; - case MZ_HYPERBLASTER : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0); - break; - case MZ_MACHINEGUN : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); - break; - case MZ_SHOTGUN : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0); - S.StartSound(null, i, CHAN_AUTO, S.RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1f); - break; - case MZ_SSHOTGUN : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0); - break; - case MZ_CHAINGUN1 : - dl.radius = 200 + (rnd.nextInt() & 31); - dl.color[0] = 1; - dl.color[1] = 0.25f; - dl.color[2] = 0; - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); - break; - case MZ_CHAINGUN2 : - dl.radius = 225 + (rnd.nextInt() & 31); - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0; - dl.die = cl.time + 0.1f; // long delay - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0.05f); - break; - case MZ_CHAINGUN3 : - dl.radius = 250 + (rnd.nextInt() & 31); - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - dl.die = cl.time + 0.1f; // long delay - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0); - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0.033f); - //Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1); - soundname = "weapons/machgf" + ((rnd.nextInt(5)) + 1) + "b.wav"; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound(soundname), volume, ATTN_NORM, 0.066f); - break; - case MZ_RAILGUN : - dl.color[0] = 0.5f; - dl.color[1] = 0.5f; - dl.color[2] = 1.0f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0); - break; - case MZ_ROCKET : - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0.2f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0); - S.StartSound(null, i, CHAN_AUTO, S.RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1f); - break; - case MZ_GRENADE : - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0); - S.StartSound(null, i, CHAN_AUTO, S.RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1f); - break; - case MZ_BFG : - dl.color[0] = 0; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0); - break; - - case MZ_LOGIN : - dl.color[0] = 0; - dl.color[1] = 1; - dl.color[2] = 0; - dl.die = cl.time + 1.0f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); - CL.LogoutEffect(pl.current.origin, weapon); - break; - case MZ_LOGOUT : - dl.color[0] = 1; - dl.color[1] = 0; - dl.color[2] = 0; - dl.die = cl.time + 1.0f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); - CL.LogoutEffect(pl.current.origin, weapon); - break; - case MZ_RESPAWN : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - dl.die = cl.time + 1.0f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0); - CL.LogoutEffect(pl.current.origin, weapon); - break; - // RAFAEL - case MZ_PHALANX : - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0.5f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/plasshot.wav"), volume, ATTN_NORM, 0); - break; - // RAFAEL - case MZ_IONRIPPER : - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0.5f; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/rippfire.wav"), volume, ATTN_NORM, 0); - break; - - // ====================== - // PGM - case MZ_ETF_RIFLE : - dl.color[0] = 0.9f; - dl.color[1] = 0.7f; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/nail1.wav"), volume, ATTN_NORM, 0); - break; - case MZ_SHOTGUN2 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/shotg2.wav"), volume, ATTN_NORM, 0); - break; - case MZ_HEATBEAM : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - dl.die = cl.time + 100; - // S.StartSound (null, i, CHAN_WEAPON, S.RegisterSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0); - break; - case MZ_BLASTER2 : - dl.color[0] = 0; - dl.color[1] = 1; - dl.color[2] = 0; - // FIXME - different sound for blaster2 ?? - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0); - break; - case MZ_TRACKER : - // negative flashes handled the same in gl/soft until CL_AddDLights - dl.color[0] = -1; - dl.color[1] = -1; - dl.color[2] = -1; - S.StartSound(null, i, CHAN_WEAPON, S.RegisterSound("weapons/disint2.wav"), volume, ATTN_NORM, 0); - break; - case MZ_NUKE1 : - dl.color[0] = 1; - dl.color[1] = 0; - dl.color[2] = 0; - dl.die = cl.time + 100; - break; - case MZ_NUKE2 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - dl.die = cl.time + 100; - break; - case MZ_NUKE4 : - dl.color[0] = 0; - dl.color[1] = 0; - dl.color[2] = 1; - dl.die = cl.time + 100; - break; - case MZ_NUKE8 : - dl.color[0] = 0; - dl.color[1] = 1; - dl.color[2] = 1; - dl.die = cl.time + 100; - break; - // PGM - // ====================== + case Defines.MZ_BLASTER: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/blastf1a.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_BLUEHYPERBLASTER: + dl.color[0] = 0; + dl.color[1] = 0; + dl.color[2] = 1; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/hyprbf1a.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_HYPERBLASTER: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/hyprbf1a.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_MACHINEGUN: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_SHOTGUN: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/shotgf1b.wav"), volume, Defines.ATTN_NORM, 0); + S.StartSound(null, i, Defines.CHAN_AUTO, S.RegisterSound("weapons/shotgr1b.wav"), volume, Defines.ATTN_NORM, 0.1f); + break; + case Defines.MZ_SSHOTGUN: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/sshotf1b.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_CHAINGUN1: + dl.radius = 200 + (Globals.rnd.nextInt() & 31); + dl.color[0] = 1; + dl.color[1] = 0.25f; + dl.color[2] = 0; + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_CHAINGUN2: + dl.radius = 225 + (Globals.rnd.nextInt() & 31); + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0; + dl.die = Globals.cl.time + 0.1f; // long delay + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0); + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0.05f); + break; + case Defines.MZ_CHAINGUN3: + dl.radius = 250 + (Globals.rnd.nextInt() & 31); + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + dl.die = Globals.cl.time + 0.1f; // long delay + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0); + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0.033f); + //Com_sprintf(soundname, sizeof(soundname), + // "weapons/machgf%ib.wav", (rand() % 5) + 1); + soundname = "weapons/machgf" + ((Globals.rnd.nextInt(5)) + 1) + "b.wav"; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound(soundname), volume, Defines.ATTN_NORM, 0.066f); + break; + case Defines.MZ_RAILGUN: + dl.color[0] = 0.5f; + dl.color[1] = 0.5f; + dl.color[2] = 1.0f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/railgf1a.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_ROCKET: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0.2f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/rocklf1a.wav"), volume, Defines.ATTN_NORM, 0); + S.StartSound(null, i, Defines.CHAN_AUTO, S.RegisterSound("weapons/rocklr1b.wav"), volume, Defines.ATTN_NORM, 0.1f); + break; + case Defines.MZ_GRENADE: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), volume, Defines.ATTN_NORM, 0); + S.StartSound(null, i, Defines.CHAN_AUTO, S.RegisterSound("weapons/grenlr1b.wav"), volume, Defines.ATTN_NORM, 0.1f); + break; + case Defines.MZ_BFG: + dl.color[0] = 0; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/bfg__f1y.wav"), volume, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ_LOGIN: + dl.color[0] = 0; + dl.color[1] = 1; + dl.color[2] = 0; + dl.die = Globals.cl.time + 1.0f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, Defines.ATTN_NORM, 0); + LogoutEffect(pl.current.origin, weapon); + break; + case Defines.MZ_LOGOUT: + dl.color[0] = 1; + dl.color[1] = 0; + dl.color[2] = 0; + dl.die = Globals.cl.time + 1.0f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, Defines.ATTN_NORM, 0); + LogoutEffect(pl.current.origin, weapon); + break; + case Defines.MZ_RESPAWN: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + dl.die = Globals.cl.time + 1.0f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/grenlf1a.wav"), 1, Defines.ATTN_NORM, 0); + LogoutEffect(pl.current.origin, weapon); + break; + // RAFAEL + case Defines.MZ_PHALANX: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0.5f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/plasshot.wav"), volume, Defines.ATTN_NORM, 0); + break; + // RAFAEL + case Defines.MZ_IONRIPPER: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0.5f; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/rippfire.wav"), volume, Defines.ATTN_NORM, 0); + break; + + // ====================== + // PGM + case Defines.MZ_ETF_RIFLE: + dl.color[0] = 0.9f; + dl.color[1] = 0.7f; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/nail1.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_SHOTGUN2: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/shotg2.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_HEATBEAM: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + dl.die = Globals.cl.time + 100; + // S.StartSound (null, i, CHAN_WEAPON, + // S.RegisterSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0); + break; + case Defines.MZ_BLASTER2: + dl.color[0] = 0; + dl.color[1] = 1; + dl.color[2] = 0; + // FIXME - different sound for blaster2 ?? + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/blastf1a.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_TRACKER: + // negative flashes handled the same in gl/soft until CL_AddDLights + dl.color[0] = -1; + dl.color[1] = -1; + dl.color[2] = -1; + S.StartSound(null, i, Defines.CHAN_WEAPON, S.RegisterSound("weapons/disint2.wav"), volume, Defines.ATTN_NORM, 0); + break; + case Defines.MZ_NUKE1: + dl.color[0] = 1; + dl.color[1] = 0; + dl.color[2] = 0; + dl.die = Globals.cl.time + 100; + break; + case Defines.MZ_NUKE2: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + dl.die = Globals.cl.time + 100; + break; + case Defines.MZ_NUKE4: + dl.color[0] = 0; + dl.color[1] = 0; + dl.color[2] = 1; + dl.die = Globals.cl.time + 100; + break; + case Defines.MZ_NUKE8: + dl.color[0] = 0; + dl.color[1] = 1; + dl.color[2] = 1; + dl.die = Globals.cl.time + 100; + break; + // PGM + // ====================== } } /* - ============== - CL_ParseMuzzleFlash2 - ============== - */ + * ============== CL_ParseMuzzleFlash2 ============== + */ static void ParseMuzzleFlash2() { float[] origin = new float[3]; float[] forward = new float[3]; float[] right = new float[3]; String soundname; - int ent = MSG.ReadShort(net_message); - if (ent < 1 || ent >= MAX_EDICTS) - Com.Error(ERR_DROP, "CL_ParseMuzzleFlash2: bad entity"); + int ent = MSG.ReadShort(Globals.net_message); + if (ent < 1 || ent >= Defines.MAX_EDICTS) + Com.Error(Defines.ERR_DROP, "CL_ParseMuzzleFlash2: bad entity"); - int flash_number = MSG.ReadByte(net_message); + int flash_number = MSG.ReadByte(Globals.net_message); // locate the origin - AngleVectors(cl_entities[ent].current.angles, forward, right, null); - origin[0] = - cl_entities[ent].current.origin[0] - + forward[0] * M_Flash.monster_flash_offset[flash_number][0] - + right[0] * M_Flash.monster_flash_offset[flash_number][1]; - origin[1] = - cl_entities[ent].current.origin[1] - + forward[1] * M_Flash.monster_flash_offset[flash_number][0] - + right[1] * M_Flash.monster_flash_offset[flash_number][1]; - origin[2] = - cl_entities[ent].current.origin[2] - + forward[2] * M_Flash.monster_flash_offset[flash_number][0] - + right[2] * M_Flash.monster_flash_offset[flash_number][1] - + M_Flash.monster_flash_offset[flash_number][2]; - - cdlight_t dl = CL.AllocDlight(ent); - VectorCopy(origin, dl.origin); - dl.radius = 200 + (rnd.nextInt() & 31); + Math3D.AngleVectors(Globals.cl_entities[ent].current.angles, forward, right, null); + origin[0] = Globals.cl_entities[ent].current.origin[0] + forward[0] * M_Flash.monster_flash_offset[flash_number][0] + right[0] + * M_Flash.monster_flash_offset[flash_number][1]; + origin[1] = Globals.cl_entities[ent].current.origin[1] + forward[1] * M_Flash.monster_flash_offset[flash_number][0] + right[1] + * M_Flash.monster_flash_offset[flash_number][1]; + origin[2] = Globals.cl_entities[ent].current.origin[2] + forward[2] * M_Flash.monster_flash_offset[flash_number][0] + right[2] + * M_Flash.monster_flash_offset[flash_number][1] + M_Flash.monster_flash_offset[flash_number][2]; + + cdlight_t dl = AllocDlight(ent); + Math3D.VectorCopy(origin, dl.origin); + dl.radius = 200 + (Globals.rnd.nextInt() & 31); dl.minlight = 32; - dl.die = cl.time; // + 0.1; + dl.die = Globals.cl.time; // + 0.1; switch (flash_number) { - case MZ2_INFANTRY_MACHINEGUN_1 : - case MZ2_INFANTRY_MACHINEGUN_2 : - case MZ2_INFANTRY_MACHINEGUN_3 : - case MZ2_INFANTRY_MACHINEGUN_4 : - case MZ2_INFANTRY_MACHINEGUN_5 : - case MZ2_INFANTRY_MACHINEGUN_6 : - case MZ2_INFANTRY_MACHINEGUN_7 : - case MZ2_INFANTRY_MACHINEGUN_8 : - case MZ2_INFANTRY_MACHINEGUN_9 : - case MZ2_INFANTRY_MACHINEGUN_10 : - case MZ2_INFANTRY_MACHINEGUN_11 : - case MZ2_INFANTRY_MACHINEGUN_12 : - case MZ2_INFANTRY_MACHINEGUN_13 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_SOLDIER_MACHINEGUN_1 : - case MZ2_SOLDIER_MACHINEGUN_2 : - case MZ2_SOLDIER_MACHINEGUN_3 : - case MZ2_SOLDIER_MACHINEGUN_4 : - case MZ2_SOLDIER_MACHINEGUN_5 : - case MZ2_SOLDIER_MACHINEGUN_6 : - case MZ2_SOLDIER_MACHINEGUN_7 : - case MZ2_SOLDIER_MACHINEGUN_8 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("soldier/solatck3.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_GUNNER_MACHINEGUN_1 : - case MZ2_GUNNER_MACHINEGUN_2 : - case MZ2_GUNNER_MACHINEGUN_3 : - case MZ2_GUNNER_MACHINEGUN_4 : - case MZ2_GUNNER_MACHINEGUN_5 : - case MZ2_GUNNER_MACHINEGUN_6 : - case MZ2_GUNNER_MACHINEGUN_7 : - case MZ2_GUNNER_MACHINEGUN_8 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("gunner/gunatck2.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_ACTOR_MACHINEGUN_1 : - case MZ2_SUPERTANK_MACHINEGUN_1 : - case MZ2_SUPERTANK_MACHINEGUN_2 : - case MZ2_SUPERTANK_MACHINEGUN_3 : - case MZ2_SUPERTANK_MACHINEGUN_4 : - case MZ2_SUPERTANK_MACHINEGUN_5 : - case MZ2_SUPERTANK_MACHINEGUN_6 : - case MZ2_TURRET_MACHINEGUN : // PGM - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_BOSS2_MACHINEGUN_L1 : - case MZ2_BOSS2_MACHINEGUN_L2 : - case MZ2_BOSS2_MACHINEGUN_L3 : - case MZ2_BOSS2_MACHINEGUN_L4 : - case MZ2_BOSS2_MACHINEGUN_L5 : - case MZ2_CARRIER_MACHINEGUN_L1 : // PMM - case MZ2_CARRIER_MACHINEGUN_L2 : // PMM - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, ATTN_NONE, 0); - break; - - case MZ2_SOLDIER_BLASTER_1 : - case MZ2_SOLDIER_BLASTER_2 : - case MZ2_SOLDIER_BLASTER_3 : - case MZ2_SOLDIER_BLASTER_4 : - case MZ2_SOLDIER_BLASTER_5 : - case MZ2_SOLDIER_BLASTER_6 : - case MZ2_SOLDIER_BLASTER_7 : - case MZ2_SOLDIER_BLASTER_8 : - case MZ2_TURRET_BLASTER : // PGM - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("soldier/solatck2.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_FLYER_BLASTER_1 : - case MZ2_FLYER_BLASTER_2 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("flyer/flyatck3.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_MEDIC_BLASTER_1 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("medic/medatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_HOVER_BLASTER_1 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("hover/hovatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_FLOAT_BLASTER_1 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("floater/fltatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_SOLDIER_SHOTGUN_1 : - case MZ2_SOLDIER_SHOTGUN_2 : - case MZ2_SOLDIER_SHOTGUN_3 : - case MZ2_SOLDIER_SHOTGUN_4 : - case MZ2_SOLDIER_SHOTGUN_5 : - case MZ2_SOLDIER_SHOTGUN_6 : - case MZ2_SOLDIER_SHOTGUN_7 : - case MZ2_SOLDIER_SHOTGUN_8 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("soldier/solatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_TANK_BLASTER_1 : - case MZ2_TANK_BLASTER_2 : - case MZ2_TANK_BLASTER_3 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_TANK_MACHINEGUN_1 : - case MZ2_TANK_MACHINEGUN_2 : - case MZ2_TANK_MACHINEGUN_3 : - case MZ2_TANK_MACHINEGUN_4 : - case MZ2_TANK_MACHINEGUN_5 : - case MZ2_TANK_MACHINEGUN_6 : - case MZ2_TANK_MACHINEGUN_7 : - case MZ2_TANK_MACHINEGUN_8 : - case MZ2_TANK_MACHINEGUN_9 : - case MZ2_TANK_MACHINEGUN_10 : - case MZ2_TANK_MACHINEGUN_11 : - case MZ2_TANK_MACHINEGUN_12 : - case MZ2_TANK_MACHINEGUN_13 : - case MZ2_TANK_MACHINEGUN_14 : - case MZ2_TANK_MACHINEGUN_15 : - case MZ2_TANK_MACHINEGUN_16 : - case MZ2_TANK_MACHINEGUN_17 : - case MZ2_TANK_MACHINEGUN_18 : - case MZ2_TANK_MACHINEGUN_19 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - //Com_sprintf(soundname, sizeof(soundname), "tank/tnkatk2%c.wav", 'a' + rand() % 5); - soundname = "tank/tnkatk2" + (char) ('a' + rnd.nextInt(5)) + ".wav"; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound(soundname), 1, ATTN_NORM, 0); - break; - - case MZ2_CHICK_ROCKET_1 : - case MZ2_TURRET_ROCKET : // PGM - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0.2f; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("chick/chkatck2.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_TANK_ROCKET_1 : - case MZ2_TANK_ROCKET_2 : - case MZ2_TANK_ROCKET_3 : - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0.2f; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/tnkatck1.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_SUPERTANK_ROCKET_1 : - case MZ2_SUPERTANK_ROCKET_2 : - case MZ2_SUPERTANK_ROCKET_3 : - case MZ2_BOSS2_ROCKET_1 : - case MZ2_BOSS2_ROCKET_2 : - case MZ2_BOSS2_ROCKET_3 : - case MZ2_BOSS2_ROCKET_4 : - case MZ2_CARRIER_ROCKET_1 : - // case MZ2_CARRIER_ROCKET_2: - // case MZ2_CARRIER_ROCKET_3: - // case MZ2_CARRIER_ROCKET_4: - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0.2f; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/rocket.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_GUNNER_GRENADE_1 : - case MZ2_GUNNER_GRENADE_2 : - case MZ2_GUNNER_GRENADE_3 : - case MZ2_GUNNER_GRENADE_4 : - dl.color[0] = 1; - dl.color[1] = 0.5f; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("gunner/gunatck3.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_GLADIATOR_RAILGUN_1 : - // PMM - case MZ2_CARRIER_RAILGUN : - case MZ2_WIDOW_RAIL : - // pmm - dl.color[0] = 0.5f; - dl.color[1] = 0.5f; - dl.color[2] = 1.0f; - break; - - // --- Xian's shit starts --- - case MZ2_MAKRON_BFG : - dl.color[0] = 0.5f; - dl.color[1] = 1; - dl.color[2] = 0.5f; - //S.StartSound (null, ent, CHAN_WEAPON, S.RegisterSound("makron/bfg_fire.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_MAKRON_BLASTER_1 : - case MZ2_MAKRON_BLASTER_2 : - case MZ2_MAKRON_BLASTER_3 : - case MZ2_MAKRON_BLASTER_4 : - case MZ2_MAKRON_BLASTER_5 : - case MZ2_MAKRON_BLASTER_6 : - case MZ2_MAKRON_BLASTER_7 : - case MZ2_MAKRON_BLASTER_8 : - case MZ2_MAKRON_BLASTER_9 : - case MZ2_MAKRON_BLASTER_10 : - case MZ2_MAKRON_BLASTER_11 : - case MZ2_MAKRON_BLASTER_12 : - case MZ2_MAKRON_BLASTER_13 : - case MZ2_MAKRON_BLASTER_14 : - case MZ2_MAKRON_BLASTER_15 : - case MZ2_MAKRON_BLASTER_16 : - case MZ2_MAKRON_BLASTER_17 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("makron/blaster.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_JORG_MACHINEGUN_L1 : - case MZ2_JORG_MACHINEGUN_L2 : - case MZ2_JORG_MACHINEGUN_L3 : - case MZ2_JORG_MACHINEGUN_L4 : - case MZ2_JORG_MACHINEGUN_L5 : - case MZ2_JORG_MACHINEGUN_L6 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("boss3/xfire.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_JORG_MACHINEGUN_R1 : - case MZ2_JORG_MACHINEGUN_R2 : - case MZ2_JORG_MACHINEGUN_R3 : - case MZ2_JORG_MACHINEGUN_R4 : - case MZ2_JORG_MACHINEGUN_R5 : - case MZ2_JORG_MACHINEGUN_R6 : - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - break; - - case MZ2_JORG_BFG_1 : - dl.color[0] = 0.5f; - dl.color[1] = 1; - dl.color[2] = 0.5f; - break; - - case MZ2_BOSS2_MACHINEGUN_R1 : - case MZ2_BOSS2_MACHINEGUN_R2 : - case MZ2_BOSS2_MACHINEGUN_R3 : - case MZ2_BOSS2_MACHINEGUN_R4 : - case MZ2_BOSS2_MACHINEGUN_R5 : - case MZ2_CARRIER_MACHINEGUN_R1 : // PMM - case MZ2_CARRIER_MACHINEGUN_R2 : // PMM - - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - - CL.ParticleEffect(origin, vec3_origin, 0, 40); - CL.SmokeAndFlash(origin); - break; - - // ====== - // ROGUE - case MZ2_STALKER_BLASTER : - case MZ2_DAEDALUS_BLASTER : - case MZ2_MEDIC_BLASTER_2 : - case MZ2_WIDOW_BLASTER : - case MZ2_WIDOW_BLASTER_SWEEP1 : - case MZ2_WIDOW_BLASTER_SWEEP2 : - case MZ2_WIDOW_BLASTER_SWEEP3 : - case MZ2_WIDOW_BLASTER_SWEEP4 : - case MZ2_WIDOW_BLASTER_SWEEP5 : - case MZ2_WIDOW_BLASTER_SWEEP6 : - case MZ2_WIDOW_BLASTER_SWEEP7 : - case MZ2_WIDOW_BLASTER_SWEEP8 : - case MZ2_WIDOW_BLASTER_SWEEP9 : - case MZ2_WIDOW_BLASTER_100 : - case MZ2_WIDOW_BLASTER_90 : - case MZ2_WIDOW_BLASTER_80 : - case MZ2_WIDOW_BLASTER_70 : - case MZ2_WIDOW_BLASTER_60 : - case MZ2_WIDOW_BLASTER_50 : - case MZ2_WIDOW_BLASTER_40 : - case MZ2_WIDOW_BLASTER_30 : - case MZ2_WIDOW_BLASTER_20 : - case MZ2_WIDOW_BLASTER_10 : - case MZ2_WIDOW_BLASTER_0 : - case MZ2_WIDOW_BLASTER_10L : - case MZ2_WIDOW_BLASTER_20L : - case MZ2_WIDOW_BLASTER_30L : - case MZ2_WIDOW_BLASTER_40L : - case MZ2_WIDOW_BLASTER_50L : - case MZ2_WIDOW_BLASTER_60L : - case MZ2_WIDOW_BLASTER_70L : - case MZ2_WIDOW_RUN_1 : - case MZ2_WIDOW_RUN_2 : - case MZ2_WIDOW_RUN_3 : - case MZ2_WIDOW_RUN_4 : - case MZ2_WIDOW_RUN_5 : - case MZ2_WIDOW_RUN_6 : - case MZ2_WIDOW_RUN_7 : - case MZ2_WIDOW_RUN_8 : - dl.color[0] = 0; - dl.color[1] = 1; - dl.color[2] = 0; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_WIDOW_DISRUPTOR : - dl.color[0] = -1; - dl.color[1] = -1; - dl.color[2] = -1; - S.StartSound(null, ent, CHAN_WEAPON, S.RegisterSound("weapons/disint2.wav"), 1, ATTN_NORM, 0); - break; - - case MZ2_WIDOW_PLASMABEAM : - case MZ2_WIDOW2_BEAMER_1 : - case MZ2_WIDOW2_BEAMER_2 : - case MZ2_WIDOW2_BEAMER_3 : - case MZ2_WIDOW2_BEAMER_4 : - case MZ2_WIDOW2_BEAMER_5 : - case MZ2_WIDOW2_BEAM_SWEEP_1 : - case MZ2_WIDOW2_BEAM_SWEEP_2 : - case MZ2_WIDOW2_BEAM_SWEEP_3 : - case MZ2_WIDOW2_BEAM_SWEEP_4 : - case MZ2_WIDOW2_BEAM_SWEEP_5 : - case MZ2_WIDOW2_BEAM_SWEEP_6 : - case MZ2_WIDOW2_BEAM_SWEEP_7 : - case MZ2_WIDOW2_BEAM_SWEEP_8 : - case MZ2_WIDOW2_BEAM_SWEEP_9 : - case MZ2_WIDOW2_BEAM_SWEEP_10 : - case MZ2_WIDOW2_BEAM_SWEEP_11 : - dl.radius = 300 + (rnd.nextInt() & 100); - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 0; - dl.die = cl.time + 200; - break; - // ROGUE - // ====== - - // --- Xian's shit ends --- + case Defines.MZ2_INFANTRY_MACHINEGUN_1: + case Defines.MZ2_INFANTRY_MACHINEGUN_2: + case Defines.MZ2_INFANTRY_MACHINEGUN_3: + case Defines.MZ2_INFANTRY_MACHINEGUN_4: + case Defines.MZ2_INFANTRY_MACHINEGUN_5: + case Defines.MZ2_INFANTRY_MACHINEGUN_6: + case Defines.MZ2_INFANTRY_MACHINEGUN_7: + case Defines.MZ2_INFANTRY_MACHINEGUN_8: + case Defines.MZ2_INFANTRY_MACHINEGUN_9: + case Defines.MZ2_INFANTRY_MACHINEGUN_10: + case Defines.MZ2_INFANTRY_MACHINEGUN_11: + case Defines.MZ2_INFANTRY_MACHINEGUN_12: + case Defines.MZ2_INFANTRY_MACHINEGUN_13: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_SOLDIER_MACHINEGUN_1: + case Defines.MZ2_SOLDIER_MACHINEGUN_2: + case Defines.MZ2_SOLDIER_MACHINEGUN_3: + case Defines.MZ2_SOLDIER_MACHINEGUN_4: + case Defines.MZ2_SOLDIER_MACHINEGUN_5: + case Defines.MZ2_SOLDIER_MACHINEGUN_6: + case Defines.MZ2_SOLDIER_MACHINEGUN_7: + case Defines.MZ2_SOLDIER_MACHINEGUN_8: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("soldier/solatck3.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_GUNNER_MACHINEGUN_1: + case Defines.MZ2_GUNNER_MACHINEGUN_2: + case Defines.MZ2_GUNNER_MACHINEGUN_3: + case Defines.MZ2_GUNNER_MACHINEGUN_4: + case Defines.MZ2_GUNNER_MACHINEGUN_5: + case Defines.MZ2_GUNNER_MACHINEGUN_6: + case Defines.MZ2_GUNNER_MACHINEGUN_7: + case Defines.MZ2_GUNNER_MACHINEGUN_8: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("gunner/gunatck2.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_ACTOR_MACHINEGUN_1: + case Defines.MZ2_SUPERTANK_MACHINEGUN_1: + case Defines.MZ2_SUPERTANK_MACHINEGUN_2: + case Defines.MZ2_SUPERTANK_MACHINEGUN_3: + case Defines.MZ2_SUPERTANK_MACHINEGUN_4: + case Defines.MZ2_SUPERTANK_MACHINEGUN_5: + case Defines.MZ2_SUPERTANK_MACHINEGUN_6: + case Defines.MZ2_TURRET_MACHINEGUN: // PGM + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_BOSS2_MACHINEGUN_L1: + case Defines.MZ2_BOSS2_MACHINEGUN_L2: + case Defines.MZ2_BOSS2_MACHINEGUN_L3: + case Defines.MZ2_BOSS2_MACHINEGUN_L4: + case Defines.MZ2_BOSS2_MACHINEGUN_L5: + case Defines.MZ2_CARRIER_MACHINEGUN_L1: // PMM + case Defines.MZ2_CARRIER_MACHINEGUN_L2: // PMM + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("infantry/infatck1.wav"), 1, Defines.ATTN_NONE, 0); + break; + + case Defines.MZ2_SOLDIER_BLASTER_1: + case Defines.MZ2_SOLDIER_BLASTER_2: + case Defines.MZ2_SOLDIER_BLASTER_3: + case Defines.MZ2_SOLDIER_BLASTER_4: + case Defines.MZ2_SOLDIER_BLASTER_5: + case Defines.MZ2_SOLDIER_BLASTER_6: + case Defines.MZ2_SOLDIER_BLASTER_7: + case Defines.MZ2_SOLDIER_BLASTER_8: + case Defines.MZ2_TURRET_BLASTER: // PGM + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("soldier/solatck2.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_FLYER_BLASTER_1: + case Defines.MZ2_FLYER_BLASTER_2: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("flyer/flyatck3.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_MEDIC_BLASTER_1: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("medic/medatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_HOVER_BLASTER_1: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("hover/hovatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_FLOAT_BLASTER_1: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("floater/fltatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_SOLDIER_SHOTGUN_1: + case Defines.MZ2_SOLDIER_SHOTGUN_2: + case Defines.MZ2_SOLDIER_SHOTGUN_3: + case Defines.MZ2_SOLDIER_SHOTGUN_4: + case Defines.MZ2_SOLDIER_SHOTGUN_5: + case Defines.MZ2_SOLDIER_SHOTGUN_6: + case Defines.MZ2_SOLDIER_SHOTGUN_7: + case Defines.MZ2_SOLDIER_SHOTGUN_8: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("soldier/solatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_TANK_BLASTER_1: + case Defines.MZ2_TANK_BLASTER_2: + case Defines.MZ2_TANK_BLASTER_3: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("tank/tnkatck3.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_TANK_MACHINEGUN_1: + case Defines.MZ2_TANK_MACHINEGUN_2: + case Defines.MZ2_TANK_MACHINEGUN_3: + case Defines.MZ2_TANK_MACHINEGUN_4: + case Defines.MZ2_TANK_MACHINEGUN_5: + case Defines.MZ2_TANK_MACHINEGUN_6: + case Defines.MZ2_TANK_MACHINEGUN_7: + case Defines.MZ2_TANK_MACHINEGUN_8: + case Defines.MZ2_TANK_MACHINEGUN_9: + case Defines.MZ2_TANK_MACHINEGUN_10: + case Defines.MZ2_TANK_MACHINEGUN_11: + case Defines.MZ2_TANK_MACHINEGUN_12: + case Defines.MZ2_TANK_MACHINEGUN_13: + case Defines.MZ2_TANK_MACHINEGUN_14: + case Defines.MZ2_TANK_MACHINEGUN_15: + case Defines.MZ2_TANK_MACHINEGUN_16: + case Defines.MZ2_TANK_MACHINEGUN_17: + case Defines.MZ2_TANK_MACHINEGUN_18: + case Defines.MZ2_TANK_MACHINEGUN_19: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + //Com_sprintf(soundname, sizeof(soundname), "tank/tnkatk2%c.wav", + // 'a' + rand() % 5); + soundname = "tank/tnkatk2" + (char) ('a' + Globals.rnd.nextInt(5)) + ".wav"; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound(soundname), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_CHICK_ROCKET_1: + case Defines.MZ2_TURRET_ROCKET: // PGM + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0.2f; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("chick/chkatck2.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_TANK_ROCKET_1: + case Defines.MZ2_TANK_ROCKET_2: + case Defines.MZ2_TANK_ROCKET_3: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0.2f; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("tank/tnkatck1.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_SUPERTANK_ROCKET_1: + case Defines.MZ2_SUPERTANK_ROCKET_2: + case Defines.MZ2_SUPERTANK_ROCKET_3: + case Defines.MZ2_BOSS2_ROCKET_1: + case Defines.MZ2_BOSS2_ROCKET_2: + case Defines.MZ2_BOSS2_ROCKET_3: + case Defines.MZ2_BOSS2_ROCKET_4: + case Defines.MZ2_CARRIER_ROCKET_1: + // case MZ2_CARRIER_ROCKET_2: + // case MZ2_CARRIER_ROCKET_3: + // case MZ2_CARRIER_ROCKET_4: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0.2f; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("tank/rocket.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_GUNNER_GRENADE_1: + case Defines.MZ2_GUNNER_GRENADE_2: + case Defines.MZ2_GUNNER_GRENADE_3: + case Defines.MZ2_GUNNER_GRENADE_4: + dl.color[0] = 1; + dl.color[1] = 0.5f; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("gunner/gunatck3.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_GLADIATOR_RAILGUN_1: + // PMM + case Defines.MZ2_CARRIER_RAILGUN: + case Defines.MZ2_WIDOW_RAIL: + // pmm + dl.color[0] = 0.5f; + dl.color[1] = 0.5f; + dl.color[2] = 1.0f; + break; + + // --- Xian's shit starts --- + case Defines.MZ2_MAKRON_BFG: + dl.color[0] = 0.5f; + dl.color[1] = 1; + dl.color[2] = 0.5f; + //S.StartSound (null, ent, CHAN_WEAPON, + // S.RegisterSound("makron/bfg_fire.wav"), 1, ATTN_NORM, 0); + break; + + case Defines.MZ2_MAKRON_BLASTER_1: + case Defines.MZ2_MAKRON_BLASTER_2: + case Defines.MZ2_MAKRON_BLASTER_3: + case Defines.MZ2_MAKRON_BLASTER_4: + case Defines.MZ2_MAKRON_BLASTER_5: + case Defines.MZ2_MAKRON_BLASTER_6: + case Defines.MZ2_MAKRON_BLASTER_7: + case Defines.MZ2_MAKRON_BLASTER_8: + case Defines.MZ2_MAKRON_BLASTER_9: + case Defines.MZ2_MAKRON_BLASTER_10: + case Defines.MZ2_MAKRON_BLASTER_11: + case Defines.MZ2_MAKRON_BLASTER_12: + case Defines.MZ2_MAKRON_BLASTER_13: + case Defines.MZ2_MAKRON_BLASTER_14: + case Defines.MZ2_MAKRON_BLASTER_15: + case Defines.MZ2_MAKRON_BLASTER_16: + case Defines.MZ2_MAKRON_BLASTER_17: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("makron/blaster.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_JORG_MACHINEGUN_L1: + case Defines.MZ2_JORG_MACHINEGUN_L2: + case Defines.MZ2_JORG_MACHINEGUN_L3: + case Defines.MZ2_JORG_MACHINEGUN_L4: + case Defines.MZ2_JORG_MACHINEGUN_L5: + case Defines.MZ2_JORG_MACHINEGUN_L6: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("boss3/xfire.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_JORG_MACHINEGUN_R1: + case Defines.MZ2_JORG_MACHINEGUN_R2: + case Defines.MZ2_JORG_MACHINEGUN_R3: + case Defines.MZ2_JORG_MACHINEGUN_R4: + case Defines.MZ2_JORG_MACHINEGUN_R5: + case Defines.MZ2_JORG_MACHINEGUN_R6: + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + break; + + case Defines.MZ2_JORG_BFG_1: + dl.color[0] = 0.5f; + dl.color[1] = 1; + dl.color[2] = 0.5f; + break; + + case Defines.MZ2_BOSS2_MACHINEGUN_R1: + case Defines.MZ2_BOSS2_MACHINEGUN_R2: + case Defines.MZ2_BOSS2_MACHINEGUN_R3: + case Defines.MZ2_BOSS2_MACHINEGUN_R4: + case Defines.MZ2_BOSS2_MACHINEGUN_R5: + case Defines.MZ2_CARRIER_MACHINEGUN_R1: // PMM + case Defines.MZ2_CARRIER_MACHINEGUN_R2: // PMM + + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + + ParticleEffect(origin, Globals.vec3_origin, 0, 40); + CL_tent.SmokeAndFlash(origin); + break; + + // ====== + // ROGUE + case Defines.MZ2_STALKER_BLASTER: + case Defines.MZ2_DAEDALUS_BLASTER: + case Defines.MZ2_MEDIC_BLASTER_2: + case Defines.MZ2_WIDOW_BLASTER: + case Defines.MZ2_WIDOW_BLASTER_SWEEP1: + case Defines.MZ2_WIDOW_BLASTER_SWEEP2: + case Defines.MZ2_WIDOW_BLASTER_SWEEP3: + case Defines.MZ2_WIDOW_BLASTER_SWEEP4: + case Defines.MZ2_WIDOW_BLASTER_SWEEP5: + case Defines.MZ2_WIDOW_BLASTER_SWEEP6: + case Defines.MZ2_WIDOW_BLASTER_SWEEP7: + case Defines.MZ2_WIDOW_BLASTER_SWEEP8: + case Defines.MZ2_WIDOW_BLASTER_SWEEP9: + case Defines.MZ2_WIDOW_BLASTER_100: + case Defines.MZ2_WIDOW_BLASTER_90: + case Defines.MZ2_WIDOW_BLASTER_80: + case Defines.MZ2_WIDOW_BLASTER_70: + case Defines.MZ2_WIDOW_BLASTER_60: + case Defines.MZ2_WIDOW_BLASTER_50: + case Defines.MZ2_WIDOW_BLASTER_40: + case Defines.MZ2_WIDOW_BLASTER_30: + case Defines.MZ2_WIDOW_BLASTER_20: + case Defines.MZ2_WIDOW_BLASTER_10: + case Defines.MZ2_WIDOW_BLASTER_0: + case Defines.MZ2_WIDOW_BLASTER_10L: + case Defines.MZ2_WIDOW_BLASTER_20L: + case Defines.MZ2_WIDOW_BLASTER_30L: + case Defines.MZ2_WIDOW_BLASTER_40L: + case Defines.MZ2_WIDOW_BLASTER_50L: + case Defines.MZ2_WIDOW_BLASTER_60L: + case Defines.MZ2_WIDOW_BLASTER_70L: + case Defines.MZ2_WIDOW_RUN_1: + case Defines.MZ2_WIDOW_RUN_2: + case Defines.MZ2_WIDOW_RUN_3: + case Defines.MZ2_WIDOW_RUN_4: + case Defines.MZ2_WIDOW_RUN_5: + case Defines.MZ2_WIDOW_RUN_6: + case Defines.MZ2_WIDOW_RUN_7: + case Defines.MZ2_WIDOW_RUN_8: + dl.color[0] = 0; + dl.color[1] = 1; + dl.color[2] = 0; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("tank/tnkatck3.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_WIDOW_DISRUPTOR: + dl.color[0] = -1; + dl.color[1] = -1; + dl.color[2] = -1; + S.StartSound(null, ent, Defines.CHAN_WEAPON, S.RegisterSound("weapons/disint2.wav"), 1, Defines.ATTN_NORM, 0); + break; + + case Defines.MZ2_WIDOW_PLASMABEAM: + case Defines.MZ2_WIDOW2_BEAMER_1: + case Defines.MZ2_WIDOW2_BEAMER_2: + case Defines.MZ2_WIDOW2_BEAMER_3: + case Defines.MZ2_WIDOW2_BEAMER_4: + case Defines.MZ2_WIDOW2_BEAMER_5: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_1: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_2: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_3: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_4: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_5: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_6: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_7: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_8: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_9: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_10: + case Defines.MZ2_WIDOW2_BEAM_SWEEP_11: + dl.radius = 300 + (Globals.rnd.nextInt() & 100); + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 0; + dl.die = Globals.cl.time + 200; + break; + // ROGUE + // ====== + + // --- Xian's shit ends --- } } /* - =============== - CL_AddDLights - - =============== - */ + * =============== CL_AddDLights + * + * =============== + */ static void AddDLights() { cdlight_t dl; // ===== // PGM - if (vidref_val == VIDREF_GL) { - for (int i = 0; i < MAX_DLIGHTS; i++) { + if (Globals.vidref_val == Defines.VIDREF_GL) { + for (int i = 0; i < Defines.MAX_DLIGHTS; i++) { dl = cl_dlights[i]; if (dl.radius == 0.0f) continue; V.AddLight(dl.origin, dl.radius, dl.color[0], dl.color[1], dl.color[2]); } } else { - for (int i = 0; i < MAX_DLIGHTS; i++) { + for (int i = 0; i < Defines.MAX_DLIGHTS; i++) { dl = cl_dlights[i]; if (dl.radius == 0.0f) continue; // negative light in software. only black allowed if ((dl.color[0] < 0) || (dl.color[1] < 0) || (dl.color[2] < 0)) { - dl.radius = - (dl.radius); + dl.radius = -(dl.radius); dl.color[0] = 1; dl.color[1] = 1; dl.color[2] = 1; @@ -984,47 +992,24 @@ public class CL_fx extends CL_tent { } /* - ============================================================== - - PARTICLE MANAGEMENT - - ============================================================== - */ - - static final int PARTICLE_GRAVITY = 40; - static cparticle_t active_particles, free_particles; - - static cparticle_t[] particles = new cparticle_t[MAX_PARTICLES]; - static { - for (int i = 0; i < particles.length; i++) - particles[i] = new cparticle_t(); - } - static int cl_numparticles = MAX_PARTICLES; + * =============== CL_ClearParticles =============== + */ + static void ClearParticles() { + int i; - /* - =============== - CL_ClearParticles - =============== - */ - static void ClearParticles() - { - int i; - free_particles = particles[0]; active_particles = null; - for (i=0 ; i<particles.length - 1; i++) - particles[i].next = particles[i+1]; + for (i = 0; i < particles.length - 1; i++) + particles[i].next = particles[i + 1]; particles[particles.length - 1].next = null; } /* - =============== - CL_ParticleEffect - - Wall impact puffs - =============== - */ + * =============== CL_ParticleEffect + * + * Wall impact puffs =============== + */ static void ParticleEffect(float[] org, float[] dir, int color, int count) { int i, j; cparticle_t p; @@ -1038,13 +1023,13 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - p.color = color + (rand() & 7); + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); - d = rand() & 31; + d = Lib.rand() & 31; for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() & 7) - 4) + d * dir[j]; - p.vel[j] = crand() * 20; + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = Lib.crand() * 20; } p.accel[0] = p.accel[1] = 0; @@ -1056,10 +1041,8 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_ParticleEffect2 - =============== - */ + * =============== CL_ParticleEffect2 =============== + */ static void ParticleEffect2(float[] org, float[] dir, int color, int count) { int i, j; cparticle_t p; @@ -1073,13 +1056,13 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; p.color = color; - d = rand() & 7; + d = Lib.rand() & 7; for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() & 7) - 4) + d * dir[j]; - p.vel[j] = crand() * 20; + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = Lib.crand() * 20; } p.accel[0] = p.accel[1] = 0; @@ -1092,10 +1075,8 @@ public class CL_fx extends CL_tent { // RAFAEL /* - =============== - CL_ParticleEffect3 - =============== - */ + * =============== CL_ParticleEffect3 =============== + */ static void ParticleEffect3(float[] org, float[] dir, int color, int count) { int i, j; cparticle_t p; @@ -1109,13 +1090,13 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; p.color = color; - d = rand() & 7; + d = Lib.rand() & 7; for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() & 7) - 4) + d * dir[j]; - p.vel[j] = crand() * 20; + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = Lib.crand() * 20; } p.accel[0] = p.accel[1] = 0; @@ -1127,10 +1108,8 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_TeleporterParticles - =============== - */ + * =============== CL_TeleporterParticles =============== + */ static void TeleporterParticles(entity_state_t ent) { int i, j; cparticle_t p; @@ -1143,16 +1122,16 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; p.color = 0xdb; for (j = 0; j < 2; j++) { - p.org[j] = ent.origin[j] - 16 + (rand() & 31); - p.vel[j] = crand() * 14; + p.org[j] = ent.origin[j] - 16 + (Lib.rand() & 31); + p.vel[j] = Lib.crand() * 14; } - p.org[2] = ent.origin[2] - 8 + (rand() & 7); - p.vel[2] = 80 + (rand() & 7); + p.org[2] = ent.origin[2] - 8 + (Lib.rand() & 7); + p.vel[2] = 80 + (Lib.rand() & 7); p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; @@ -1163,11 +1142,10 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_LogoutEffect - - =============== - */ + * =============== CL_LogoutEffect + * + * =============== + */ static void LogoutEffect(float[] org, int type) { int i, j; cparticle_t p; @@ -1180,21 +1158,21 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; - if (type == MZ_LOGIN) - p.color = 0xd0 + (rand() & 7); // green - else if (type == MZ_LOGOUT) - p.color = 0x40 + (rand() & 7); // red + if (type == Defines.MZ_LOGIN) + p.color = 0xd0 + (Lib.rand() & 7); // green + else if (type == Defines.MZ_LOGOUT) + p.color = 0x40 + (Lib.rand() & 7); // red else - p.color = 0xe0 + (rand() & 7); // yellow + p.color = 0xe0 + (Lib.rand() & 7); // yellow p.org[0] = org[0] - 16 + Globals.rnd.nextFloat() * 32; p.org[1] = org[1] - 16 + Globals.rnd.nextFloat() * 32; p.org[2] = org[2] - 24 + Globals.rnd.nextFloat() * 56; for (j = 0; j < 3; j++) - p.vel[j] = crand() * 20; + p.vel[j] = Lib.crand() * 20; p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; @@ -1205,11 +1183,10 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_ItemRespawnParticles - - =============== - */ + * =============== CL_ItemRespawnParticles + * + * =============== + */ static void ItemRespawnParticles(float[] org) { int i, j; cparticle_t p; @@ -1222,16 +1199,16 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; - p.color = 0xd4 + (rand() & 3); // green + p.color = 0xd4 + (Lib.rand() & 3); // green - p.org[0] = org[0] + crand() * 8; - p.org[1] = org[1] + crand() * 8; - p.org[2] = org[2] + crand() * 8; + p.org[0] = org[0] + Lib.crand() * 8; + p.org[1] = org[1] + Lib.crand() * 8; + p.org[2] = org[2] + Lib.crand() * 8; for (j = 0; j < 3; j++) - p.vel[j] = crand() * 8; + p.vel[j] = Lib.crand() * 8; p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY * 0.2f; @@ -1242,10 +1219,8 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_ExplosionParticles - =============== - */ + * =============== CL_ExplosionParticles =============== + */ static void ExplosionParticles(float[] org) { int i, j; cparticle_t p; @@ -1258,12 +1233,12 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - p.color = 0xe0 + (rand() & 7); + p.time = Globals.cl.time; + p.color = 0xe0 + (Lib.rand() & 7); for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() % 32) - 16); - p.vel[j] = (rand() % 384) - 192; + p.org[j] = org[j] + ((Lib.rand() % 32) - 16); + p.vel[j] = (Lib.rand() % 384) - 192; } p.accel[0] = p.accel[1] = 0.0f; @@ -1274,12 +1249,6 @@ public class CL_fx extends CL_tent { } } - /* - =============== - CL_BigTeleportParticles - =============== - */ - private static int[] colortable = { 2 * 8, 13 * 8, 21 * 8, 18 * 8 }; static void BigTeleportParticles(float[] org) { int i; cparticle_t p; @@ -1293,22 +1262,22 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; - p.color = colortable[rand() & 3]; + p.color = colortable[Lib.rand() & 3]; - angle = (float) (Math.PI * 2 * (rand() & 1023) / 1023.0); - dist = rand() & 31; + angle = (float) (Math.PI * 2 * (Lib.rand() & 1023) / 1023.0); + dist = Lib.rand() & 31; p.org[0] = (float) (org[0] + Math.cos(angle) * dist); - p.vel[0] = (float) (Math.cos(angle) * (70 + (rand() & 63))); + p.vel[0] = (float) (Math.cos(angle) * (70 + (Lib.rand() & 63))); p.accel[0] = (float) (-Math.cos(angle) * 100); p.org[1] = (float) (org[1] + Math.sin(angle) * dist); - p.vel[1] = (float) (Math.sin(angle) * (70 + (rand() & 63))); + p.vel[1] = (float) (Math.sin(angle) * (70 + (Lib.rand() & 63))); p.accel[1] = (float) (-Math.sin(angle) * 100); - p.org[2] = org[2] + 8 + (rand() % 90); - p.vel[2] = -100 + (rand() & 31); + p.org[2] = org[2] + 8 + (Lib.rand() % 90); + p.vel[2] = -100 + (Lib.rand() & 31); p.accel[2] = PARTICLE_GRAVITY * 4; p.alpha = 1.0f; @@ -1317,12 +1286,10 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_BlasterParticles - - Wall impact puffs - =============== - */ + * =============== CL_BlasterParticles + * + * Wall impact puffs =============== + */ static void BlasterParticles(float[] org, float[] dir) { int i, j; cparticle_t p; @@ -1338,13 +1305,13 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - p.color = 0xe0 + (rand() & 7); + p.time = Globals.cl.time; + p.color = 0xe0 + (Lib.rand() & 7); - d = rand() & 15; + d = Lib.rand() & 15; for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() & 7) - 4) + d * dir[j]; - p.vel[j] = dir[j] * 30 + crand() * 40; + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = dir[j] * 30 + Lib.crand() * 40; } p.accel[0] = p.accel[1] = 0; @@ -1356,11 +1323,10 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_BlasterTrail - - =============== - */ + * =============== CL_BlasterTrail + * + * =============== + */ static void BlasterTrail(float[] start, float[] end) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1369,12 +1335,12 @@ public class CL_fx extends CL_tent { cparticle_t p; int dec; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); dec = 5; - VectorScale(vec, 5, vec); + Math3D.VectorScale(vec, 5, vec); // FIXME: this is a really silly way to have a loop while (len > 0) { @@ -1386,29 +1352,28 @@ public class CL_fx extends CL_tent { free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); + Math3D.VectorClear(p.accel); - p.time = cl.time; + p.time = Globals.cl.time; p.alpha = 1.0f; p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); p.color = 0xe0; for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand(); - p.vel[j] = crand() * 5; + p.org[j] = move[j] + Lib.crand(); + p.vel[j] = Lib.crand() * 5; p.accel[j] = 0; } - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_QuadTrail - - =============== - */ + * =============== CL_QuadTrail + * + * =============== + */ static void QuadTrail(float[] start, float[] end) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1417,12 +1382,12 @@ public class CL_fx extends CL_tent { cparticle_t p; int dec; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); dec = 5; - VectorScale(vec, 5, vec); + Math3D.VectorScale(vec, 5, vec); while (len > 0) { len -= dec; @@ -1433,29 +1398,28 @@ public class CL_fx extends CL_tent { free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); + Math3D.VectorClear(p.accel); - p.time = cl.time; + p.time = Globals.cl.time; p.alpha = 1.0f; p.alphavel = -1.0f / (0.8f + Globals.rnd.nextFloat() * 0.2f); p.color = 115; for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 16; - p.vel[j] = crand() * 5; + p.org[j] = move[j] + Lib.crand() * 16; + p.vel[j] = Lib.crand() * 5; p.accel[j] = 0; } - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_FlagTrail - - =============== - */ + * =============== CL_FlagTrail + * + * =============== + */ static void FlagTrail(float[] start, float[] end, float color) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1464,12 +1428,12 @@ public class CL_fx extends CL_tent { cparticle_t p; int dec; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); dec = 5; - VectorScale(vec, 5, vec); + Math3D.VectorScale(vec, 5, vec); while (len > 0) { len -= dec; @@ -1480,29 +1444,28 @@ public class CL_fx extends CL_tent { free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); + Math3D.VectorClear(p.accel); - p.time = cl.time; + p.time = Globals.cl.time; p.alpha = 1.0f; p.alphavel = -1.0f / (0.8f + Globals.rnd.nextFloat() * 0.2f); p.color = color; for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 16; - p.vel[j] = crand() * 5; + p.org[j] = move[j] + Lib.crand() * 16; + p.vel[j] = Lib.crand() * 5; p.accel[j] = 0; } - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_DiminishingTrail - - =============== - */ + * =============== CL_DiminishingTrail + * + * =============== + */ static void DiminishingTrail(float[] start, float[] end, centity_t old, int flags) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1510,12 +1473,12 @@ public class CL_fx extends CL_tent { float orgscale; float velscale; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - float len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + float len = Math3D.VectorNormalize(vec); float dec = 0.5f; - VectorScale(vec, dec, vec); + Math3D.VectorScale(vec, dec, vec); if (old.trailcount > 900) { orgscale = 4; @@ -1535,42 +1498,42 @@ public class CL_fx extends CL_tent { return; // drop less particles as it flies - if ((rand() & 1023) < old.trailcount) { + if ((Lib.rand() & 1023) < old.trailcount) { p = free_particles; free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); + Math3D.VectorClear(p.accel); - p.time = cl.time; + p.time = Globals.cl.time; - if ((flags & EF_GIB) != 0) { + if ((flags & Defines.EF_GIB) != 0) { p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + Globals.rnd.nextFloat() * 0.4f); - p.color = 0xe8 + (rand() & 7); + p.color = 0xe8 + (Lib.rand() & 7); for (int j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * orgscale; - p.vel[j] = crand() * velscale; + p.org[j] = move[j] + Lib.crand() * orgscale; + p.vel[j] = Lib.crand() * velscale; p.accel[j] = 0; } p.vel[2] -= PARTICLE_GRAVITY; - } else if ((flags & EF_GREENGIB) != 0) { + } else if ((flags & Defines.EF_GREENGIB) != 0) { p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + Globals.rnd.nextFloat() * 0.4f); - p.color = 0xdb + (rand() & 7); + p.color = 0xdb + (Lib.rand() & 7); for (int j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * orgscale; - p.vel[j] = crand() * velscale; + p.org[j] = move[j] + Lib.crand() * orgscale; + p.vel[j] = Lib.crand() * velscale; p.accel[j] = 0; } p.vel[2] -= PARTICLE_GRAVITY; } else { p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + Globals.rnd.nextFloat() * 0.2f); - p.color = 4 + (rand() & 7); + p.color = 4 + (Lib.rand() & 7); for (int j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * orgscale; - p.vel[j] = crand() * velscale; + p.org[j] = move[j] + Lib.crand() * orgscale; + p.vel[j] = Lib.crand() * velscale; } p.accel[2] = 20; } @@ -1579,16 +1542,15 @@ public class CL_fx extends CL_tent { old.trailcount -= 5; if (old.trailcount < 100) old.trailcount = 100; - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_RocketTrail - - =============== - */ + * =============== CL_RocketTrail + * + * =============== + */ static void RocketTrail(float[] start, float[] end, centity_t old) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1598,15 +1560,15 @@ public class CL_fx extends CL_tent { float dec; // smoke - CL.DiminishingTrail(start, end, old, EF_ROCKET); + DiminishingTrail(start, end, old, Defines.EF_ROCKET); // fire - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); dec = 1; - VectorScale(vec, dec, vec); + Math3D.VectorScale(vec, dec, vec); while (len > 0) { len -= dec; @@ -1614,34 +1576,33 @@ public class CL_fx extends CL_tent { if (free_particles == null) return; - if ((rand() & 7) == 0) { + if ((Lib.rand() & 7) == 0) { p = free_particles; free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); - p.time = cl.time; + Math3D.VectorClear(p.accel); + p.time = Globals.cl.time; p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + Globals.rnd.nextFloat() * 0.2f); - p.color = 0xdc + (rand() & 3); + p.color = 0xdc + (Lib.rand() & 3); for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 5; - p.vel[j] = crand() * 20; + p.org[j] = move[j] + Lib.crand() * 5; + p.vel[j] = Lib.crand() * 20; } p.accel[2] = -PARTICLE_GRAVITY; } - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_RailTrail - - =============== - */ + * =============== CL_RailTrail + * + * =============== + */ static void RailTrail(float[] start, float[] end) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1656,11 +1617,11 @@ public class CL_fx extends CL_tent { float[] dir = new float[3]; byte clr = 0x74; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); - MakeNormalVectors(vec, right, up); + Math3D.MakeNormalVectors(vec, right, up); for (i = 0; i < len; i++) { if (free_particles == null) @@ -1671,30 +1632,30 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - VectorClear(p.accel); + p.time = Globals.cl.time; + Math3D.VectorClear(p.accel); d = i * 0.1f; - c = (float)Math.cos(d); - s = (float)Math.sin(d); + c = (float) Math.cos(d); + s = (float) Math.sin(d); - VectorScale(right, c, dir); - VectorMA(dir, s, up, dir); + Math3D.VectorScale(right, c, dir); + Math3D.VectorMA(dir, s, up, dir); p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + Globals.rnd.nextFloat() * 0.2f); - p.color = clr + (rand() & 7); + p.color = clr + (Lib.rand() & 7); for (j = 0; j < 3; j++) { p.org[j] = move[j] + dir[j] * 3; p.vel[j] = dir[j] * 6; } - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } dec = 0.75f; - VectorScale(vec, dec, vec); - VectorCopy(start, move); + Math3D.VectorScale(vec, dec, vec); + Math3D.VectorCopy(start, move); while (len > 0) { len -= dec; @@ -1706,29 +1667,27 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - VectorClear(p.accel); + p.time = Globals.cl.time; + Math3D.VectorClear(p.accel); p.alpha = 1.0f; p.alphavel = -1.0f / (0.6f + Globals.rnd.nextFloat() * 0.2f); - p.color = 0x0 + rand() & 15; + p.color = 0x0 + Lib.rand() & 15; for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 3; - p.vel[j] = crand() * 3; + p.org[j] = move[j] + Lib.crand() * 3; + p.vel[j] = Lib.crand() * 3; p.accel[j] = 0; } - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } // RAFAEL /* - =============== - CL_IonripperTrail - =============== - */ + * =============== CL_IonripperTrail =============== + */ static void IonripperTrail(float[] start, float[] ent) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1737,30 +1696,30 @@ public class CL_fx extends CL_tent { cparticle_t p; int dec; int left = 0; - - VectorCopy(start, move); - VectorSubtract(ent, start, vec); - len = VectorNormalize(vec); - + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(ent, start, vec); + len = Math3D.VectorNormalize(vec); + dec = 5; - VectorScale(vec, 5, vec); - + Math3D.VectorScale(vec, 5, vec); + while (len > 0) { len -= dec; - + if (free_particles == null) return; p = free_particles; free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; p.alpha = 0.5f; p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); - p.color = 0xe4 + (rand() & 3); - + p.color = 0xe4 + (Lib.rand() & 3); + for (j = 0; j < 3; j++) { p.org[j] = move[j]; p.accel[j] = 0; @@ -1772,20 +1731,19 @@ public class CL_fx extends CL_tent { left = 1; p.vel[0] = -10; } - + p.vel[1] = 0; p.vel[2] = 0; - - VectorAdd(move, vec, move); + + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_BubbleTrail - - =============== - */ + * =============== CL_BubbleTrail + * + * =============== + */ static void BubbleTrail(float[] start, float[] end) { float[] move = new float[3]; float[] vec = new float[3]; @@ -1794,12 +1752,12 @@ public class CL_fx extends CL_tent { cparticle_t p; float dec; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); dec = 32; - VectorScale(vec, dec, vec); + Math3D.VectorScale(vec, dec, vec); for (i = 0; i < len; i += dec) { if (free_particles == null) @@ -1810,65 +1768,57 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - VectorClear(p.accel); - p.time = cl.time; + Math3D.VectorClear(p.accel); + p.time = Globals.cl.time; p.alpha = 1.0f; p.alphavel = -1.0f / (1.0f + Globals.rnd.nextFloat() * 0.2f); - p.color = 4 + (rand() & 7); + p.color = 4 + (Lib.rand() & 7); for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 2; - p.vel[j] = crand() * 5; + p.org[j] = move[j] + Lib.crand() * 2; + p.vel[j] = Lib.crand() * 5; } p.vel[2] += 6; - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } } /* - =============== - CL_FlyParticles - =============== - */ - private static final int BEAMLENGTH = 16; - static void FlyParticles (float [] origin, int count) - { - int i; - cparticle_t p; - float angle; - float sp, sy, cp, cy; - float [] forward= new float[3]; - float dist = 64; - float ltime; - - - if (count > NUMVERTEXNORMALS) - count = NUMVERTEXNORMALS; - - if (avelocities[0][0] == 0.0f) - { - for (i=0 ; i<NUMVERTEXNORMALS ; i++) { - avelocities[i][0] = (rand()&255) * 0.01f; - avelocities[i][1] = (rand()&255) * 0.01f; - avelocities[i][2] = (rand()&255) * 0.01f; + * =============== CL_FlyParticles =============== + */ + static void FlyParticles(float[] origin, int count) { + int i; + cparticle_t p; + float angle; + float sp, sy, cp, cy; + float[] forward = new float[3]; + float dist = 64; + float ltime; + + if (count > Defines.NUMVERTEXNORMALS) + count = Defines.NUMVERTEXNORMALS; + + if (avelocities[0][0] == 0.0f) { + for (i = 0; i < Defines.NUMVERTEXNORMALS; i++) { + avelocities[i][0] = (Lib.rand() & 255) * 0.01f; + avelocities[i][1] = (Lib.rand() & 255) * 0.01f; + avelocities[i][2] = (Lib.rand() & 255) * 0.01f; } } - - ltime = cl.time / 1000.0f; - for (i=0 ; i<count ; i+=2) - { + ltime = Globals.cl.time / 1000.0f; + for (i = 0; i < count; i += 2) { angle = ltime * avelocities[i][0]; - sy = (float)Math.sin(angle); - cy = (float)Math.cos(angle); + sy = (float) Math.sin(angle); + cy = (float) Math.cos(angle); angle = ltime * avelocities[i][1]; - sp = (float)Math.sin(angle); - cp = (float)Math.cos(angle); + sp = (float) Math.sin(angle); + cp = (float) Math.cos(angle); angle = ltime * avelocities[i][2]; - - forward[0] = cp*cy; - forward[1] = cp*sy; + + forward[0] = cp * cy; + forward[1] = cp * sy; forward[2] = -sp; if (free_particles == null) @@ -1878,15 +1828,15 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; - dist = (float)Math.sin(ltime + i)*64; - p.org[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH; - p.org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH; - p.org[2] = origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH; + dist = (float) Math.sin(ltime + i) * 64; + p.org[0] = origin[0] + Globals.bytedirs[i][0] * dist + forward[0] * BEAMLENGTH; + p.org[1] = origin[1] + Globals.bytedirs[i][1] * dist + forward[1] * BEAMLENGTH; + p.org[2] = origin[2] + Globals.bytedirs[i][2] * dist + forward[2] * BEAMLENGTH; - VectorClear (p.vel); - VectorClear (p.accel); + Math3D.VectorClear(p.vel); + Math3D.VectorClear(p.accel); p.color = 0; //p.colorvel = 0; @@ -1901,33 +1851,31 @@ public class CL_fx extends CL_tent { int count; int starttime; - if (ent.fly_stoptime < cl.time) { - starttime = cl.time; - ent.fly_stoptime = cl.time + 60000; + if (ent.fly_stoptime < Globals.cl.time) { + starttime = Globals.cl.time; + ent.fly_stoptime = Globals.cl.time + 60000; } else { starttime = ent.fly_stoptime - 60000; } - n = cl.time - starttime; + n = Globals.cl.time - starttime; if (n < 20000) count = (int) ((n * 162) / 20000.0); else { - n = ent.fly_stoptime - cl.time; + n = ent.fly_stoptime - Globals.cl.time; if (n < 20000) count = (int) ((n * 162) / 20000.0); else count = 162; } - CL.FlyParticles(origin, count); + FlyParticles(origin, count); } /* - =============== - CL_BfgParticles - =============== - */ - //#define BEAMLENGTH 16 + * =============== CL_BfgParticles =============== + */ + //#define BEAMLENGTH 16 static void BfgParticles(entity_t ent) { int i; cparticle_t p; @@ -1939,21 +1887,21 @@ public class CL_fx extends CL_tent { float ltime; if (avelocities[0][0] == 0.0f) { - for (i = 0; i < NUMVERTEXNORMALS; i++) { - avelocities[i][0] = (rand() & 255) * 0.01f; - avelocities[i][1] = (rand() & 255) * 0.01f; - avelocities[i][2] = (rand() & 255) * 0.01f; + for (i = 0; i < Defines.NUMVERTEXNORMALS; i++) { + avelocities[i][0] = (Lib.rand() & 255) * 0.01f; + avelocities[i][1] = (Lib.rand() & 255) * 0.01f; + avelocities[i][2] = (Lib.rand() & 255) * 0.01f; } } - ltime = cl.time / 1000.0f; - for (i = 0; i < NUMVERTEXNORMALS; i++) { + ltime = Globals.cl.time / 1000.0f; + for (i = 0; i < Defines.NUMVERTEXNORMALS; i++) { angle = ltime * avelocities[i][0]; - sy = (float)Math.sin(angle); - cy = (float)Math.cos(angle); + sy = (float) Math.sin(angle); + cy = (float) Math.cos(angle); angle = ltime * avelocities[i][1]; - sp = (float)Math.sin(angle); - cp = (float)Math.cos(angle); + sp = (float) Math.sin(angle); + cp = (float) Math.cos(angle); angle = ltime * avelocities[i][2]; forward[0] = cp * cy; @@ -1967,19 +1915,19 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; + p.time = Globals.cl.time; dist = (float) (Math.sin(ltime + i) * 64); - p.org[0] = ent.origin[0] + bytedirs[i][0] * dist + forward[0] * BEAMLENGTH; - p.org[1] = ent.origin[1] + bytedirs[i][1] * dist + forward[1] * BEAMLENGTH; - p.org[2] = ent.origin[2] + bytedirs[i][2] * dist + forward[2] * BEAMLENGTH; + p.org[0] = ent.origin[0] + Globals.bytedirs[i][0] * dist + forward[0] * BEAMLENGTH; + p.org[1] = ent.origin[1] + Globals.bytedirs[i][1] * dist + forward[1] * BEAMLENGTH; + p.org[2] = ent.origin[2] + Globals.bytedirs[i][2] * dist + forward[2] * BEAMLENGTH; - VectorClear(p.vel); - VectorClear(p.accel); + Math3D.VectorClear(p.vel); + Math3D.VectorClear(p.accel); - VectorSubtract(p.org, ent.origin, v); - dist = VectorLength(v) / 90.0f; - p.color = (float)Math.floor(0xd0 + dist * 7); + Math3D.VectorSubtract(p.org, ent.origin, v); + dist = Math3D.VectorLength(v) / 90.0f; + p.color = (float) Math.floor(0xd0 + dist * 7); //p.colorvel = 0; p.alpha = 1.0f - dist; @@ -1988,10 +1936,8 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_TrapParticles - =============== - */ + * =============== CL_TrapParticles =============== + */ // RAFAEL static void TrapParticles(entity_t ent) { float[] move = new float[3]; @@ -2004,16 +1950,16 @@ public class CL_fx extends CL_tent { int dec; ent.origin[2] -= 14; - VectorCopy(ent.origin, start); - VectorCopy(ent.origin, end); + Math3D.VectorCopy(ent.origin, start); + Math3D.VectorCopy(ent.origin, end); end[2] += 64; - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); dec = 5; - VectorScale(vec, 5, vec); + Math3D.VectorScale(vec, 5, vec); // FIXME: this is a really silly way to have a loop while (len > 0) { @@ -2025,31 +1971,31 @@ public class CL_fx extends CL_tent { free_particles = p.next; p.next = active_particles; active_particles = p; - VectorClear(p.accel); + Math3D.VectorClear(p.accel); - p.time = cl.time; + p.time = Globals.cl.time; p.alpha = 1.0f; p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); p.color = 0xe0; for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand(); - p.vel[j] = crand() * 15; + p.org[j] = move[j] + Lib.crand(); + p.vel[j] = Lib.crand() * 15; p.accel[j] = 0; } p.accel[2] = PARTICLE_GRAVITY; - VectorAdd(move, vec, move); + Math3D.VectorAdd(move, vec, move); } int i, k; - //cparticle_t p; + //cparticle_t p; float vel; float[] dir = new float[3]; float[] org = new float[3]; ent.origin[2] += 14; - VectorCopy(ent.origin, org); + Math3D.VectorCopy(ent.origin, org); for (i = -2; i <= 2; i += 4) for (j = -2; j <= 2; j += 4) @@ -2061,23 +2007,23 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - p.color = 0xe0 + (rand() & 3); + p.time = Globals.cl.time; + p.color = 0xe0 + (Lib.rand() & 3); p.alpha = 1.0f; - p.alphavel = -1.0f / (0.3f + (rand() & 7) * 0.02f); + p.alphavel = -1.0f / (0.3f + (Lib.rand() & 7) * 0.02f); - p.org[0] = org[0] + i + ((rand() & 23) * crand()); - p.org[1] = org[1] + j + ((rand() & 23) * crand()); - p.org[2] = org[2] + k + ((rand() & 23) * crand()); + p.org[0] = org[0] + i + ((Lib.rand() & 23) * Lib.crand()); + p.org[1] = org[1] + j + ((Lib.rand() & 23) * Lib.crand()); + p.org[2] = org[2] + k + ((Lib.rand() & 23) * Lib.crand()); dir[0] = j * 8; dir[1] = i * 8; dir[2] = k * 8; - VectorNormalize(dir); - vel = 50 + rand() & 63; - VectorScale(dir, vel, p.vel); + Math3D.VectorNormalize(dir); + vel = 50 + Lib.rand() & 63; + Math3D.VectorScale(dir, vel, p.vel); p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; @@ -2085,12 +2031,9 @@ public class CL_fx extends CL_tent { } - /* - =============== - CL_BFGExplosionParticles - =============== - */ + * =============== CL_BFGExplosionParticles =============== + */ // FIXME combined with CL_ExplosionParticles static void BFGExplosionParticles(float[] org) { int i, j; @@ -2104,12 +2047,12 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - p.color = 0xd0 + (rand() & 7); + p.time = Globals.cl.time; + p.color = 0xd0 + (Lib.rand() & 7); for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() % 32) - 16); - p.vel[j] = (rand() % 384) - 192; + p.org[j] = org[j] + ((Lib.rand() % 32) - 16); + p.vel[j] = (Lib.rand() % 384) - 192; } p.accel[0] = p.accel[1] = 0; @@ -2121,11 +2064,10 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_TeleportParticles - - =============== - */ + * =============== CL_TeleportParticles + * + * =============== + */ static void TeleportParticles(float[] org) { cparticle_t p; @@ -2142,23 +2084,23 @@ public class CL_fx extends CL_tent { p.next = active_particles; active_particles = p; - p.time = cl.time; - p.color = 7 + (rand() & 7); + p.time = Globals.cl.time; + p.color = 7 + (Lib.rand() & 7); p.alpha = 1.0f; - p.alphavel = -1.0f / (0.3f + (rand() & 7) * 0.02f); + p.alphavel = -1.0f / (0.3f + (Lib.rand() & 7) * 0.02f); - p.org[0] = org[0] + i + (rand() & 3); - p.org[1] = org[1] + j + (rand() & 3); - p.org[2] = org[2] + k + (rand() & 3); + p.org[0] = org[0] + i + (Lib.rand() & 3); + p.org[1] = org[1] + j + (Lib.rand() & 3); + p.org[2] = org[2] + k + (Lib.rand() & 3); dir[0] = j * 8; dir[1] = i * 8; dir[2] = k * 8; - VectorNormalize(dir); - vel = 50 + (rand() & 63); - VectorScale(dir, vel, p.vel); + Math3D.VectorNormalize(dir); + vel = 50 + (Lib.rand() & 63); + Math3D.VectorScale(dir, vel, p.vel); p.accel[0] = p.accel[1] = 0; p.accel[2] = -PARTICLE_GRAVITY; @@ -2166,10 +2108,8 @@ public class CL_fx extends CL_tent { } /* - =============== - CL_AddParticles - =============== - */ + * =============== CL_AddParticles =============== + */ static void AddParticles() { cparticle_t p, next; float alpha; @@ -2187,7 +2127,7 @@ public class CL_fx extends CL_tent { // PMM - added INSTANT_PARTICLE handling for heat beam if (p.alphavel != INSTANT_PARTICLE) { - time = (cl.time - p.time) * 0.001f; + time = (Globals.cl.time - p.time) * 0.001f; alpha = p.alpha + time * p.alphavel; if (alpha <= 0) { // faded out p.next = free_particles; @@ -2208,7 +2148,7 @@ public class CL_fx extends CL_tent { if (alpha > 1.0) alpha = 1; - color = (int)p.color; + color = (int) p.color; time2 = time * time; @@ -2226,52 +2166,68 @@ public class CL_fx extends CL_tent { active_particles = active; } - - /* - ============== - CL_EntityEvent - - An entity has just been parsed that has an event value - the female events are there for backwards compatability - ============== - */ + /* + * ============== CL_EntityEvent + * + * An entity has just been parsed that has an event value + * + * the female events are there for backwards compatability ============== + */ static void EntityEvent(entity_state_t ent) { switch (ent.event) { - case EV_ITEM_RESPAWN : - S.StartSound(null, ent.number, CHAN_WEAPON, S.RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0); - CL.ItemRespawnParticles(ent.origin); - break; - case EV_PLAYER_TELEPORT : - S.StartSound(null, ent.number, CHAN_WEAPON, S.RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0); - CL.TeleportParticles(ent.origin); - break; - case EV_FOOTSTEP : - if (cl_footsteps.value != 0.0f) - S.StartSound(null, ent.number, CHAN_BODY, cl_sfx_footsteps[rand() & 3], 1, ATTN_NORM, 0); - break; - case EV_FALLSHORT : - S.StartSound(null, ent.number, CHAN_AUTO, S.RegisterSound("player/land1.wav"), 1, ATTN_NORM, 0); - break; - case EV_FALL : - S.StartSound(null, ent.number, CHAN_AUTO, S.RegisterSound("*fall2.wav"), 1, ATTN_NORM, 0); - break; - case EV_FALLFAR : - S.StartSound(null, ent.number, CHAN_AUTO, S.RegisterSound("*fall1.wav"), 1, ATTN_NORM, 0); - break; + case Defines.EV_ITEM_RESPAWN: + S.StartSound(null, ent.number, Defines.CHAN_WEAPON, S.RegisterSound("items/respawn1.wav"), 1, Defines.ATTN_IDLE, 0); + ItemRespawnParticles(ent.origin); + break; + case Defines.EV_PLAYER_TELEPORT: + S.StartSound(null, ent.number, Defines.CHAN_WEAPON, S.RegisterSound("misc/tele1.wav"), 1, Defines.ATTN_IDLE, 0); + TeleportParticles(ent.origin); + break; + case Defines.EV_FOOTSTEP: + if (Globals.cl_footsteps.value != 0.0f) + S.StartSound(null, ent.number, Defines.CHAN_BODY, CL_tent.cl_sfx_footsteps[Lib.rand() & 3], 1, Defines.ATTN_NORM, 0); + break; + case Defines.EV_FALLSHORT: + S.StartSound(null, ent.number, Defines.CHAN_AUTO, S.RegisterSound("player/land1.wav"), 1, Defines.ATTN_NORM, 0); + break; + case Defines.EV_FALL: + S.StartSound(null, ent.number, Defines.CHAN_AUTO, S.RegisterSound("*fall2.wav"), 1, Defines.ATTN_NORM, 0); + break; + case Defines.EV_FALLFAR: + S.StartSound(null, ent.number, Defines.CHAN_AUTO, S.RegisterSound("*fall1.wav"), 1, Defines.ATTN_NORM, 0); + break; } } /* - ============== - CL_ClearEffects - - ============== - */ + * ============== CL_ClearEffects + * + * ============== + */ static void ClearEffects() { - CL.ClearParticles(); - CL.ClearDlights(); - CL.ClearLightStyles(); + ClearParticles(); + ClearDlights(); + ClearLightStyles(); } -} + /* + * ============================================================== + * + * PARTICLE MANAGEMENT + * + * ============================================================== + */ + + static final int PARTICLE_GRAVITY = 40; + + static cparticle_t active_particles, free_particles; + + /* + * =============== CL_BigTeleportParticles =============== + */ + private static int[] colortable = { 2 * 8, 13 * 8, 21 * 8, 18 * 8 }; + + private static final int BEAMLENGTH = 16; + +}
\ No newline at end of file diff --git a/src/jake2/client/CL_input.java b/src/jake2/client/CL_input.java index 47132bb..b470967 100644 --- a/src/jake2/client/CL_input.java +++ b/src/jake2/client/CL_input.java @@ -1,30 +1,32 @@ /* - * CL_input.java + * java * Copyright (C) 2004 * - * $Id: CL_input.java,v 1.3 2004-07-09 06:50:50 hzi Exp $ + * $Id: CL_input.java,v 1.4 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; +import jake2.Defines; +import jake2.Globals; import jake2.game.*; import jake2.game.Cmd; import jake2.game.usercmd_t; @@ -32,57 +34,73 @@ import jake2.qcommon.*; import jake2.qcommon.Cvar; import jake2.qcommon.xcommand_t; import jake2.sys.IN; +import jake2.util.Math3D; /** * CL_input */ -public class CL_input extends CL_ents { - +public class CL_input { + static long frame_msec; + static long old_sys_frame_time; static cvar_t cl_nodelta; /* - =============================================================================== - - KEY BUTTONS - - Continuous button event tracking is complicated by the fact that two different - input sources (say, mouse button 1 and the control key) can both press the - same button, but the button should only be released when both of the - pressing key have been released. - - When a key event issues a button command (+forward, +attack, etc), it appends - its key number as a parameter to the command so it can be matched up with - the release. - - state bit 0 is the current state of the key - state bit 1 is edge triggered on the up to down transition - state bit 2 is edge triggered on the down to up transition - - - Key_Event (int key, qboolean down, unsigned time); - - +mlook src time - - =============================================================================== - */ + * =============================================================================== + * + * KEY BUTTONS + * + * Continuous button event tracking is complicated by the fact that two + * different input sources (say, mouse button 1 and the control key) can + * both press the same button, but the button should only be released when + * both of the pressing key have been released. + * + * When a key event issues a button command (+forward, +attack, etc), it + * appends its key number as a parameter to the command so it can be matched + * up with the release. + * + * state bit 0 is the current state of the key state bit 1 is edge triggered + * on the up to down transition state bit 2 is edge triggered on the down to + * up transition + * + * + * Key_Event (int key, qboolean down, unsigned time); + * + * +mlook src time + * + * =============================================================================== + */ static kbutton_t in_klook = new kbutton_t(); + static kbutton_t in_left = new kbutton_t(); + static kbutton_t in_right = new kbutton_t(); + static kbutton_t in_forward = new kbutton_t(); + static kbutton_t in_back = new kbutton_t(); + static kbutton_t in_lookup = new kbutton_t(); + static kbutton_t in_lookdown = new kbutton_t(); + static kbutton_t in_moveleft = new kbutton_t(); + static kbutton_t in_moveright = new kbutton_t(); + public static kbutton_t in_strafe = new kbutton_t(); + static kbutton_t in_speed = new kbutton_t(); + static kbutton_t in_use = new kbutton_t(); + static kbutton_t in_attack = new kbutton_t(); + static kbutton_t in_up = new kbutton_t(); + static kbutton_t in_down = new kbutton_t(); static int in_impulse; @@ -95,10 +113,10 @@ public class CL_input extends CL_ents { if (c.length() > 0) k = Integer.parseInt(c); else - k = -1; // typed manually at the console for continuous down + k = -1; // typed manually at the console for continuous down if (k == b.down[0] || k == b.down[1]) - return; // repeating key + return; // repeating key if (b.down[0] == 0) b.down[0] = k; @@ -110,15 +128,15 @@ public class CL_input extends CL_ents { } if ((b.state & 1) != 0) - return; // still down + return; // still down // save timestamp c = Cmd.Argv(2); b.downtime = Long.parseLong(c); if (b.downtime == 0) - b.downtime = sys_frame_time - 100; + b.downtime = Globals.sys_frame_time - 100; - b.state |= 3; // down + impulse down + b.state |= 3; // down + impulse down } static void KeyUp(kbutton_t b) { @@ -130,9 +148,10 @@ public class CL_input extends CL_ents { if (c.length() > 0) k = Integer.parseInt(c); else { - // typed manually at the console, assume for unsticking, so clear all + // typed manually at the console, assume for unsticking, so clear + // all b.down[0] = b.down[1] = 0; - b.state = 4; // impulse up + b.state = 4; // impulse up return; } @@ -141,12 +160,12 @@ public class CL_input extends CL_ents { else if (b.down[1] == k) b.down[1] = 0; else - return; // key up without coresponding down (menu pass through) + return; // key up without coresponding down (menu pass through) if (b.down[0] != 0 || b.down[1] != 0) - return; // some other key is still holding it down + return; // some other key is still holding it down if ((b.state & 1) == 0) - return; // still up (this should not happen) + return; // still up (this should not happen) // save timestamp c = Cmd.Argv(2); @@ -156,69 +175,155 @@ public class CL_input extends CL_ents { else b.msec += 10; - b.state &= ~1; // now up - b.state |= 4; // impulse up - } - - static void IN_KLookDown() {KeyDown(in_klook);} - static void IN_KLookUp() {KeyUp(in_klook);} - static void IN_UpDown() {KeyDown(in_up);} - static void IN_UpUp() {KeyUp(in_up);} - static void IN_DownDown() {KeyDown(in_down);} - static void IN_DownUp() {KeyUp(in_down);} - static void IN_LeftDown() {KeyDown(in_left);} - static void IN_LeftUp() {KeyUp(in_left);} - static void IN_RightDown() {KeyDown(in_right);} - static void IN_RightUp() {KeyUp(in_right);} - static void IN_ForwardDown() {KeyDown(in_forward);} - static void IN_ForwardUp() {KeyUp(in_forward);} - static void IN_BackDown() {KeyDown(in_back);} - static void IN_BackUp() {KeyUp(in_back);} - static void IN_LookupDown() {KeyDown(in_lookup);} - static void IN_LookupUp() {KeyUp(in_lookup);} - static void IN_LookdownDown() {KeyDown(in_lookdown);} - static void IN_LookdownUp() {KeyUp(in_lookdown);} - static void IN_MoveleftDown() {KeyDown(in_moveleft);} - static void IN_MoveleftUp() {KeyUp(in_moveleft);} - static void IN_MoverightDown() {KeyDown(in_moveright);} - static void IN_MoverightUp() {KeyUp(in_moveright);} - - static void IN_SpeedDown() {KeyDown(in_speed);} - static void IN_SpeedUp() {KeyUp(in_speed);} - static void IN_StrafeDown() {KeyDown(in_strafe);} - static void IN_StrafeUp() {KeyUp(in_strafe);} - - static void IN_AttackDown() {KeyDown(in_attack);} - static void IN_AttackUp() {KeyUp(in_attack);} - - static void IN_UseDown () {KeyDown(in_use);} - static void IN_UseUp () {KeyUp(in_use);} - - static void IN_Impulse () {in_impulse=Integer.parseInt(Cmd.Argv(1));} + b.state &= ~1; // now up + b.state |= 4; // impulse up + } - /* - =============== - CL_KeyState + static void IN_KLookDown() { + KeyDown(in_klook); + } + + static void IN_KLookUp() { + KeyUp(in_klook); + } + + static void IN_UpDown() { + KeyDown(in_up); + } + + static void IN_UpUp() { + KeyUp(in_up); + } + + static void IN_DownDown() { + KeyDown(in_down); + } + + static void IN_DownUp() { + KeyUp(in_down); + } + + static void IN_LeftDown() { + KeyDown(in_left); + } + + static void IN_LeftUp() { + KeyUp(in_left); + } + + static void IN_RightDown() { + KeyDown(in_right); + } + + static void IN_RightUp() { + KeyUp(in_right); + } + + static void IN_ForwardDown() { + KeyDown(in_forward); + } - Returns the fraction of the frame that the key was down - =============== - */ + static void IN_ForwardUp() { + KeyUp(in_forward); + } + + static void IN_BackDown() { + KeyDown(in_back); + } + + static void IN_BackUp() { + KeyUp(in_back); + } + + static void IN_LookupDown() { + KeyDown(in_lookup); + } + + static void IN_LookupUp() { + KeyUp(in_lookup); + } + + static void IN_LookdownDown() { + KeyDown(in_lookdown); + } + + static void IN_LookdownUp() { + KeyUp(in_lookdown); + } + + static void IN_MoveleftDown() { + KeyDown(in_moveleft); + } + + static void IN_MoveleftUp() { + KeyUp(in_moveleft); + } + + static void IN_MoverightDown() { + KeyDown(in_moveright); + } + + static void IN_MoverightUp() { + KeyUp(in_moveright); + } + + static void IN_SpeedDown() { + KeyDown(in_speed); + } + + static void IN_SpeedUp() { + KeyUp(in_speed); + } + + static void IN_StrafeDown() { + KeyDown(in_strafe); + } + + static void IN_StrafeUp() { + KeyUp(in_strafe); + } + + static void IN_AttackDown() { + KeyDown(in_attack); + } + + static void IN_AttackUp() { + KeyUp(in_attack); + } + + static void IN_UseDown() { + KeyDown(in_use); + } + + static void IN_UseUp() { + KeyUp(in_use); + } + + static void IN_Impulse() { + in_impulse = Integer.parseInt(Cmd.Argv(1)); + } + + /* + * =============== CL_KeyState + * + * Returns the fraction of the frame that the key was down =============== + */ static float KeyState(kbutton_t key) { float val; long msec; - key.state &= 1; // clear impulses + key.state &= 1; // clear impulses msec = key.msec; key.msec = 0; if (key.state != 0) { // still down - msec += sys_frame_time - key.downtime; - key.downtime = sys_frame_time; + msec += Globals.sys_frame_time - key.downtime; + key.downtime = Globals.sys_frame_time; } - val = (float)msec / frame_msec; + val = (float) msec / frame_msec; if (val < 0) val = 0; if (val > 1) @@ -227,105 +332,99 @@ public class CL_input extends CL_ents { return val; } -// ========================================================================== + // ========================================================================== /* - ================ - CL_AdjustAngles - - Moves the local angle positions - ================ - */ + * ================ CL_AdjustAngles + * + * Moves the local angle positions ================ + */ static void AdjustAngles() { float speed; float up, down; if ((in_speed.state & 1) != 0) - speed = cls.frametime * cl_anglespeedkey.value; + speed = Globals.cls.frametime * Globals.cl_anglespeedkey.value; else - speed = cls.frametime; + speed = Globals.cls.frametime; if ((in_strafe.state & 1) == 0) { - cl.viewangles[YAW] -= speed * cl_yawspeed.value * CL.KeyState(in_right); - cl.viewangles[YAW] += speed * cl_yawspeed.value * CL.KeyState(in_left); + Globals.cl.viewangles[Defines.YAW] -= speed * Globals.cl_yawspeed.value * KeyState(in_right); + Globals.cl.viewangles[Defines.YAW] += speed * Globals.cl_yawspeed.value * KeyState(in_left); } if ((in_klook.state & 1) != 0) { - cl.viewangles[PITCH] -= speed * cl_pitchspeed.value * CL.KeyState(in_forward); - cl.viewangles[PITCH] += speed * cl_pitchspeed.value * CL.KeyState(in_back); + Globals.cl.viewangles[Defines.PITCH] -= speed * Globals.cl_pitchspeed.value * KeyState(in_forward); + Globals.cl.viewangles[Defines.PITCH] += speed * Globals.cl_pitchspeed.value * KeyState(in_back); } - up = CL.KeyState(in_lookup); - down = CL.KeyState(in_lookdown); + up = KeyState(in_lookup); + down = KeyState(in_lookdown); - cl.viewangles[PITCH] -= speed * cl_pitchspeed.value * up; - cl.viewangles[PITCH] += speed * cl_pitchspeed.value * down; + Globals.cl.viewangles[Defines.PITCH] -= speed * Globals.cl_pitchspeed.value * up; + Globals.cl.viewangles[Defines.PITCH] += speed * Globals.cl_pitchspeed.value * down; } /* - ================ - CL_BaseMove - - Send the intended movement message to the server - ================ - */ - static void BaseMove(usercmd_t cmd) { - CL.AdjustAngles(); + * ================ CL_BaseMove + * + * Send the intended movement message to the server ================ + */ + static void BaseMove(usercmd_t cmd) { + AdjustAngles(); //memset (cmd, 0, sizeof(*cmd)); cmd.reset(); - VectorCopy(cl.viewangles, cmd.angles); + Math3D.VectorCopy(Globals.cl.viewangles, cmd.angles); if ((in_strafe.state & 1) != 0) { - cmd.sidemove += cl_sidespeed.value * CL.KeyState(in_right); - cmd.sidemove -= cl_sidespeed.value * CL.KeyState(in_left); + cmd.sidemove += Globals.cl_sidespeed.value * KeyState(in_right); + cmd.sidemove -= Globals.cl_sidespeed.value * KeyState(in_left); } - cmd.sidemove += cl_sidespeed.value * CL.KeyState(in_moveright); - cmd.sidemove -= cl_sidespeed.value * CL.KeyState(in_moveleft); + cmd.sidemove += Globals.cl_sidespeed.value * KeyState(in_moveright); + cmd.sidemove -= Globals.cl_sidespeed.value * KeyState(in_moveleft); - cmd.upmove += cl_upspeed.value * CL.KeyState(in_up); - cmd.upmove -= cl_upspeed.value * CL.KeyState(in_down); + cmd.upmove += Globals.cl_upspeed.value * KeyState(in_up); + cmd.upmove -= Globals.cl_upspeed.value * KeyState(in_down); if ((in_klook.state & 1) == 0) { - cmd.forwardmove += cl_forwardspeed.value * CL.KeyState(in_forward); - cmd.forwardmove -= cl_forwardspeed.value * CL.KeyState(in_back); + cmd.forwardmove += Globals.cl_forwardspeed.value * KeyState(in_forward); + cmd.forwardmove -= Globals.cl_forwardspeed.value * KeyState(in_back); } // // adjust for speed key / running // - if (((in_speed.state & 1) ^ (int) (cl_run.value)) != 0) { + if (((in_speed.state & 1) ^ (int) (Globals.cl_run.value)) != 0) { cmd.forwardmove *= 2; cmd.sidemove *= 2; cmd.upmove *= 2; } - + } static void ClampPitch() { - float pitch; + float pitch; - pitch = SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); + pitch = Math3D.SHORT2ANGLE(Globals.cl.frame.playerstate.pmove.delta_angles[Defines.PITCH]); if (pitch > 180) pitch -= 360; - if (cl.viewangles[PITCH] + pitch < -360) - cl.viewangles[PITCH] += 360; // wrapped - if (cl.viewangles[PITCH] + pitch > 360) - cl.viewangles[PITCH] -= 360; // wrapped + if (Globals.cl.viewangles[Defines.PITCH] + pitch < -360) + Globals.cl.viewangles[Defines.PITCH] += 360; // wrapped + if (Globals.cl.viewangles[Defines.PITCH] + pitch > 360) + Globals.cl.viewangles[Defines.PITCH] -= 360; // wrapped - if (cl.viewangles[PITCH] + pitch > 89) - cl.viewangles[PITCH] = 89 - pitch; - if (cl.viewangles[PITCH] + pitch < -89) - cl.viewangles[PITCH] = -89 - pitch; + if (Globals.cl.viewangles[Defines.PITCH] + pitch > 89) + Globals.cl.viewangles[Defines.PITCH] = 89 - pitch; + if (Globals.cl.viewangles[Defines.PITCH] + pitch < -89) + Globals.cl.viewangles[Defines.PITCH] = -89 - pitch; } /* - ============== - CL_FinishMove - ============== - */ + * ============== CL_FinishMove ============== + */ static void FinishMove(usercmd_t cmd) { int ms; int i; @@ -334,140 +433,230 @@ public class CL_input extends CL_ents { // figure button bits // if ((in_attack.state & 3) != 0) - cmd.buttons |= BUTTON_ATTACK; + cmd.buttons |= Defines.BUTTON_ATTACK; in_attack.state &= ~2; if ((in_use.state & 3) != 0) - cmd.buttons |= BUTTON_USE; + cmd.buttons |= Defines.BUTTON_USE; in_use.state &= ~2; - if (Key.anykeydown != 0 && cls.key_dest == key_game) - cmd.buttons |= BUTTON_ANY; + if (Key.anykeydown != 0 && Globals.cls.key_dest == Defines.key_game) + cmd.buttons |= Defines.BUTTON_ANY; // send milliseconds of time to apply the move - ms = (int)(cls.frametime * 1000); + ms = (int) (Globals.cls.frametime * 1000); if (ms > 250) ms = 100; // time was unreasonable - cmd.msec = (byte)ms; + cmd.msec = (byte) ms; - CL.ClampPitch(); + ClampPitch(); for (i = 0; i < 3; i++) - cmd.angles[i] = (short)ANGLE2SHORT(cl.viewangles[i]); + cmd.angles[i] = (short) Math3D.ANGLE2SHORT(Globals.cl.viewangles[i]); - cmd.impulse = (byte)in_impulse; + cmd.impulse = (byte) in_impulse; in_impulse = 0; // send the ambient light level at the player's current position - cmd.lightlevel = (byte)cl_lightlevel.value; + cmd.lightlevel = (byte) Globals.cl_lightlevel.value; } /* - ================= - CL_CreateCmd - ================= - */ + * ================= CL_CreateCmd ================= + */ static usercmd_t CreateCmd() { usercmd_t cmd = new usercmd_t(); - frame_msec = sys_frame_time - old_sys_frame_time; + frame_msec = Globals.sys_frame_time - old_sys_frame_time; if (frame_msec < 1) frame_msec = 1; if (frame_msec > 200) frame_msec = 200; // get basic movement from keyboard - CL.BaseMove(cmd); + BaseMove(cmd); // allow mice or other external controllers to add to the move IN.Move(cmd); - CL.FinishMove(cmd); + FinishMove(cmd); - old_sys_frame_time = sys_frame_time; + old_sys_frame_time = Globals.sys_frame_time; return cmd; } /* - ============ - CL_InitInput - ============ - */ + * ============ CL_InitInput ============ + */ static void InitInput() { Cmd.AddCommand("centerview", new xcommand_t() { - public void execute() {IN.CenterView();}}); + public void execute() { + IN.CenterView(); + } + }); Cmd.AddCommand("+moveup", new xcommand_t() { - public void execute() {IN_UpDown();}}); + public void execute() { + IN_UpDown(); + } + }); Cmd.AddCommand("-moveup", new xcommand_t() { - public void execute() {IN_UpUp();}}); + public void execute() { + IN_UpUp(); + } + }); Cmd.AddCommand("+movedown", new xcommand_t() { - public void execute() {IN_DownDown();}}); + public void execute() { + IN_DownDown(); + } + }); Cmd.AddCommand("-movedown", new xcommand_t() { - public void execute() {IN_DownUp();}}); + public void execute() { + IN_DownUp(); + } + }); Cmd.AddCommand("+left", new xcommand_t() { - public void execute() {IN_LeftDown();}}); + public void execute() { + IN_LeftDown(); + } + }); Cmd.AddCommand("-left", new xcommand_t() { - public void execute() {IN_LeftUp();}}); + public void execute() { + IN_LeftUp(); + } + }); Cmd.AddCommand("+right", new xcommand_t() { - public void execute() {IN_RightDown();}}); + public void execute() { + IN_RightDown(); + } + }); Cmd.AddCommand("-right", new xcommand_t() { - public void execute() {IN_RightUp();}}); + public void execute() { + IN_RightUp(); + } + }); Cmd.AddCommand("+forward", new xcommand_t() { - public void execute() {IN_ForwardDown();}}); + public void execute() { + IN_ForwardDown(); + } + }); Cmd.AddCommand("-forward", new xcommand_t() { - public void execute() {IN_ForwardUp();}}); + public void execute() { + IN_ForwardUp(); + } + }); Cmd.AddCommand("+back", new xcommand_t() { - public void execute() {IN_BackDown();}}); + public void execute() { + IN_BackDown(); + } + }); Cmd.AddCommand("-back", new xcommand_t() { - public void execute() {IN_BackUp();}}); + public void execute() { + IN_BackUp(); + } + }); Cmd.AddCommand("+lookup", new xcommand_t() { - public void execute() {IN_LookupDown();}}); + public void execute() { + IN_LookupDown(); + } + }); Cmd.AddCommand("-lookup", new xcommand_t() { - public void execute() {IN_LookupUp();}}); + public void execute() { + IN_LookupUp(); + } + }); Cmd.AddCommand("+lookdown", new xcommand_t() { - public void execute() {IN_LookdownDown();}}); + public void execute() { + IN_LookdownDown(); + } + }); Cmd.AddCommand("-lookdown", new xcommand_t() { - public void execute() {IN_LookdownUp();}}); + public void execute() { + IN_LookdownUp(); + } + }); Cmd.AddCommand("+strafe", new xcommand_t() { - public void execute() {IN_StrafeDown();}}); + public void execute() { + IN_StrafeDown(); + } + }); Cmd.AddCommand("-strafe", new xcommand_t() { - public void execute() {IN_StrafeUp();}}); + public void execute() { + IN_StrafeUp(); + } + }); Cmd.AddCommand("+moveleft", new xcommand_t() { - public void execute() {IN_MoveleftDown();}}); + public void execute() { + IN_MoveleftDown(); + } + }); Cmd.AddCommand("-moveleft", new xcommand_t() { - public void execute() {IN_MoveleftUp();}}); + public void execute() { + IN_MoveleftUp(); + } + }); Cmd.AddCommand("+moveright", new xcommand_t() { - public void execute() {IN_MoverightDown();}}); + public void execute() { + IN_MoverightDown(); + } + }); Cmd.AddCommand("-moveright", new xcommand_t() { - public void execute() {IN_MoverightUp();}}); + public void execute() { + IN_MoverightUp(); + } + }); Cmd.AddCommand("+speed", new xcommand_t() { - public void execute() {IN_SpeedDown();}}); + public void execute() { + IN_SpeedDown(); + } + }); Cmd.AddCommand("-speed", new xcommand_t() { - public void execute() {IN_SpeedUp();}}); + public void execute() { + IN_SpeedUp(); + } + }); Cmd.AddCommand("+attack", new xcommand_t() { - public void execute() {IN_AttackDown();}}); + public void execute() { + IN_AttackDown(); + } + }); Cmd.AddCommand("-attack", new xcommand_t() { - public void execute() {IN_AttackUp();}}); + public void execute() { + IN_AttackUp(); + } + }); Cmd.AddCommand("+use", new xcommand_t() { - public void execute() {IN_UseDown();}}); + public void execute() { + IN_UseDown(); + } + }); Cmd.AddCommand("-use", new xcommand_t() { - public void execute() {IN_UseUp();}}); + public void execute() { + IN_UseUp(); + } + }); Cmd.AddCommand("impulse", new xcommand_t() { - public void execute() {IN_Impulse();}}); + public void execute() { + IN_Impulse(); + } + }); Cmd.AddCommand("+klook", new xcommand_t() { - public void execute() {IN_KLookDown();}}); + public void execute() { + IN_KLookDown(); + } + }); Cmd.AddCommand("-klook", new xcommand_t() { - public void execute() {IN_KLookUp();}}); + public void execute() { + IN_KLookUp(); + } + }); - cl_nodelta = Cvar.Get("cl_nodelta", "0",0); + cl_nodelta = Cvar.Get("cl_nodelta", "0", 0); } /* - ================= - CL_SendCmd - ================= - */ + * ================= CL_SendCmd ================= + */ static void SendCmd() { sizebuf_t buf = new sizebuf_t(); byte[] data = new byte[128]; @@ -479,42 +668,46 @@ public class CL_input extends CL_ents { // build a command even if not connected // save this command off for prediction - i = cls.netchan.outgoing_sequence & (CMD_BACKUP - 1); - cmd = cl.cmds[i]; - cl.cmd_time[i] = (int)cls.realtime; // for netgraph ping calculation + i = Globals.cls.netchan.outgoing_sequence & (Defines.CMD_BACKUP - 1); + cmd = Globals.cl.cmds[i]; + Globals.cl.cmd_time[i] = (int) Globals.cls.realtime; // for netgraph + // ping calculation - cmd.set(CL.CreateCmd()); + cmd.set(CreateCmd()); - cl.cmd.set(cmd); + Globals.cl.cmd.set(cmd); - if (cls.state == ca_disconnected || cls.state == ca_connecting) + if (Globals.cls.state == Defines.ca_disconnected || Globals.cls.state == Defines.ca_connecting) return; - - if (cls.state == ca_connected) { - if (cls.netchan.message.cursize != 0 || curtime - cls.netchan.last_sent > 1000) - Netchan.Transmit(cls.netchan, 0, new byte[0]); + + if (Globals.cls.state == Defines.ca_connected) { + if (Globals.cls.netchan.message.cursize != 0 || Globals.curtime - Globals.cls.netchan.last_sent > 1000) + Netchan.Transmit(Globals.cls.netchan, 0, new byte[0]); return; } // send a userinfo update if needed - if (userinfo_modified) { + if (Globals.userinfo_modified) { CL.FixUpGender(); - userinfo_modified = false; - MSG.WriteByte(cls.netchan.message, clc_userinfo); - MSG.WriteString(cls.netchan.message, Cvar.Userinfo()); + Globals.userinfo_modified = false; + MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_userinfo); + MSG.WriteString(Globals.cls.netchan.message, Cvar.Userinfo()); } SZ.Init(buf, data, data.length); - if (cmd.buttons != 0 - && cl.cinematictime > 0 - && !cl.attractloop - && cls.realtime - cl.cinematictime > 1000) { // skip the rest of the cinematic + if (cmd.buttons != 0 && Globals.cl.cinematictime > 0 && !Globals.cl.attractloop + && Globals.cls.realtime - Globals.cl.cinematictime > 1000) { // skip + // the + // rest + // of + // the + // cinematic SCR.FinishCinematic(); } // begin a client move command - MSG.WriteByte(buf, clc_move); + MSG.WriteByte(buf, Defines.clc_move); // save the position for a checksum byte checksumIndex = buf.cursize; @@ -522,39 +715,39 @@ public class CL_input extends CL_ents { // let the server know what the last frame we // got was, so the next message can be delta compressed - if (cl_nodelta.value != 0.0f || !cl.frame.valid || cls.demowaiting) + if (cl_nodelta.value != 0.0f || !Globals.cl.frame.valid || Globals.cls.demowaiting) MSG.WriteLong(buf, -1); // no compression else - MSG.WriteLong(buf, cl.frame.serverframe); + MSG.WriteLong(buf, Globals.cl.frame.serverframe); // send this and the previous cmds in the message, so // if the last packet was dropped, it can be recovered - i = (cls.netchan.outgoing_sequence - 2) & (CMD_BACKUP - 1); - cmd = cl.cmds[i]; + i = (Globals.cls.netchan.outgoing_sequence - 2) & (Defines.CMD_BACKUP - 1); + cmd = Globals.cl.cmds[i]; //memset (nullcmd, 0, sizeof(nullcmd)); nullcmd.reset(); MSG.WriteDeltaUsercmd(buf, nullcmd, cmd); oldcmd = cmd; - i = (cls.netchan.outgoing_sequence - 1) & (CMD_BACKUP - 1); - cmd = cl.cmds[i]; - + i = (Globals.cls.netchan.outgoing_sequence - 1) & (Defines.CMD_BACKUP - 1); + cmd = Globals.cl.cmds[i]; + MSG.WriteDeltaUsercmd(buf, oldcmd, cmd); oldcmd = cmd; - i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP - 1); - cmd = cl.cmds[i]; + i = (Globals.cls.netchan.outgoing_sequence) & (Defines.CMD_BACKUP - 1); + cmd = Globals.cl.cmds[i]; MSG.WriteDeltaUsercmd(buf, oldcmd, cmd); // calculate a checksum over the move commands - buf.data[checksumIndex] = Com.BlockSequenceCRCByte(buf.data, checksumIndex + 1, buf.cursize - checksumIndex - 1, cls.netchan.outgoing_sequence); + buf.data[checksumIndex] = Com.BlockSequenceCRCByte(buf.data, checksumIndex + 1, buf.cursize - checksumIndex - 1, + Globals.cls.netchan.outgoing_sequence); // // deliver the message // - Netchan.Transmit(cls.netchan, buf.cursize, buf.data); + Netchan.Transmit(Globals.cls.netchan, buf.cursize, buf.data); } - -} +}
\ No newline at end of file diff --git a/src/jake2/client/CL_inv.java b/src/jake2/client/CL_inv.java index ba219c7..ee7764a 100644 --- a/src/jake2/client/CL_inv.java +++ b/src/jake2/client/CL_inv.java @@ -2,32 +2,33 @@ * CL_fx.java * Copyright (C) 2004 * - * $Id: CL_inv.java,v 1.1 2004-07-07 19:58:37 hzi Exp $ + * $Id: CL_inv.java,v 1.2 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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. -*/ + */ // Created on 31.01.2004 by RST. - package jake2.client; +import jake2.Defines; +import jake2.Globals; import jake2.qcommon.Com; import jake2.qcommon.MSG; import jake2.util.Vargs; @@ -35,28 +36,24 @@ import jake2.util.Vargs; /** * CL_inv */ -public class CL_inv extends CL_newfx { +public class CL_inv { /* - ================ - CL_ParseInventory - ================ - */ + * ================ CL_ParseInventory ================ + */ static void ParseInventory() { int i; - for (i = 0; i < MAX_ITEMS; i++) - cl.inventory[i] = MSG.ReadShort(net_message); + for (i = 0; i < Defines.MAX_ITEMS; i++) + Globals.cl.inventory[i] = MSG.ReadShort(Globals.net_message); } /* - ================ - Inv_DrawString - ================ - */ + * ================ Inv_DrawString ================ + */ static void Inv_DrawString(int x, int y, String string) { for (int i = 0; i < string.length(); i++) { - re.DrawChar(x, y, string.charAt(i)); + Globals.re.DrawChar(x, y, string.charAt(i)); x += 8; } } @@ -70,16 +67,14 @@ public class CL_inv extends CL_newfx { } /* - ================ - CL_DrawInventory - ================ - */ + * ================ CL_DrawInventory ================ + */ static final int DISPLAY_ITEMS = 17; static void DrawInventory() { int i, j; int num, selected_num, item; - int[] index = new int[MAX_ITEMS]; + int[] index = new int[Defines.MAX_ITEMS]; String string; int x, y; String binding; @@ -87,14 +82,14 @@ public class CL_inv extends CL_newfx { int selected; int top; - selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM]; + selected = Globals.cl.frame.playerstate.stats[Defines.STAT_SELECTED_ITEM]; num = 0; selected_num = 0; - for (i = 0; i < MAX_ITEMS; i++) { + for (i = 0; i < Defines.MAX_ITEMS; i++) { if (i == selected) selected_num = num; - if (cl.inventory[i] != 0) { + if (Globals.cl.inventory[i] != 0) { index[num] = i; num++; } @@ -107,13 +102,13 @@ public class CL_inv extends CL_newfx { if (top < 0) top = 0; - x = (viddef.width - 256) / 2; - y = (viddef.height - 240) / 2; + x = (Globals.viddef.width - 256) / 2; + y = (Globals.viddef.height - 240) / 2; // repaint everything next frame SCR.DirtyScreen(); - re.DrawPic(x, y + 8, "inventory"); + Globals.re.DrawPic(x, y + 8, "inventory"); y += 24; x += 24; @@ -123,30 +118,28 @@ public class CL_inv extends CL_newfx { for (i = top; i < num && i < top + DISPLAY_ITEMS; i++) { item = index[i]; // search for a binding - //Com_sprintf (binding, sizeof(binding), "use %s", cl.configstrings[CS_ITEMS+item]); - binding = "use " + cl.configstrings[CS_ITEMS + item]; + //Com_sprintf (binding, sizeof(binding), "use %s", + // cl.configstrings[CS_ITEMS+item]); + binding = "use " + Globals.cl.configstrings[Defines.CS_ITEMS + item]; bind = ""; for (j = 0; j < 256; j++) - if (keybindings[j] != null && keybindings[j].equals(binding)) { + if (Globals.keybindings[j] != null && Globals.keybindings[j].equals(binding)) { bind = Key.KeynumToString(j); break; } - string = - Com.sprintf( - "%6s %3i %s", - new Vargs(3).add(bind).add(cl.inventory[item]).add(cl.configstrings[CS_ITEMS + item])); + string = Com.sprintf("%6s %3i %s", new Vargs(3).add(bind).add(Globals.cl.inventory[item]).add( + Globals.cl.configstrings[Defines.CS_ITEMS + item])); if (item != selected) SetStringHighBit(string); else // draw a blinky cursor by the selected item - { - if (((int) (cls.realtime * 10) & 1) != 0) - re.DrawChar(x - 8, y, 15); + { + if (((int) (Globals.cls.realtime * 10) & 1) != 0) + Globals.re.DrawChar(x - 8, y, 15); } Inv_DrawString(x, y, string); y += 8; } } - -} +}
\ No newline at end of file diff --git a/src/jake2/client/CL_newfx.java b/src/jake2/client/CL_newfx.java index 5346226..690cd57 100644 --- a/src/jake2/client/CL_newfx.java +++ b/src/jake2/client/CL_newfx.java @@ -2,1028 +2,1010 @@ * CL_newfx.java * Copyright (C) 2004 * - * $Id: CL_newfx.java,v 1.3 2004-07-08 20:24:29 hzi Exp $ + * $Id: CL_newfx.java,v 1.4 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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. -*/ + */ // Created on 31.01.2004 by RST. - package jake2.client; +import jake2.Defines; import jake2.Globals; - +import jake2.client.CL_fx.cdlight_t; +import jake2.util.Lib; +import jake2.util.Math3D; /** * CL_newfx */ -public class CL_newfx extends CL_fx { - - - - static void Flashlight(int ent, float[] pos) { - cdlight_t dl; - - dl = CL.AllocDlight(ent); - VectorCopy(pos, dl.origin); - dl.radius = 400; - dl.minlight = 250; - dl.die = cl.time + 100; - dl.color[0] = 1; - dl.color[1] = 1; - dl.color[2] = 1; - } - - /* - ====== - CL_ColorFlash - flash of light - ====== - */ - static void ColorFlash(float[] pos, int ent, int intensity, float r, float g, float b) { - cdlight_t dl; - - if ((vidref_val == VIDREF_SOFT) && ((r < 0) || (g < 0) || (b < 0))) { - intensity = -intensity; - r = -r; - g = -g; - b = -b; - } - - dl = CL.AllocDlight(ent); - VectorCopy(pos, dl.origin); - dl.radius = intensity; - dl.minlight = 250; - dl.die = cl.time + 100; - dl.color[0] = r; - dl.color[1] = g; - dl.color[2] = b; - } - - /* - ====== - CL_DebugTrail - ====== - */ - static void DebugTrail(float[] start, float[] end) { - float[] move = new float[3]; - float[] vec = new float[3]; - - float len; - // int j; - cparticle_t p; - float dec; - float[] right = new float[3]; - float[] up = new float[3]; - // int i; - // float d, c, s; - // float[] dir; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - MakeNormalVectors(vec, right, up); - - // VectorScale(vec, RT2_SKIP, vec); - - // dec = 1.0; - // dec = 0.75; - dec = 3; - VectorScale(vec, dec, vec); - VectorCopy(start, move); - - while (len > 0) { - len -= dec; - - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - VectorClear(p.accel); - VectorClear(p.vel); - p.alpha = 1.0f; - p.alphavel = -0.1f; - // p.alphavel = 0; - p.color = 0x74 + (rand() & 7); - VectorCopy(move, p.org); - /* - for (j=0 ; j<3 ; j++) - { - p.org[j] = move[j] + crand()*2; - p.vel[j] = crand()*3; - p.accel[j] = 0; - } - */ - VectorAdd(move, vec, move); - } - - } - - /* - =============== - CL_SmokeTrail - =============== - */ - static void SmokeTrail(float[] start, float[] end, int colorStart, int colorRun, int spacing) { - float[] move = new float[3]; - float[] vec = new float[3]; - float len; - int j; - cparticle_t p; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - VectorScale(vec, spacing, vec); - - // FIXME: this is a really silly way to have a loop - while (len > 0) { - len -= spacing; - - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.5f); - p.color = colorStart + (rand() % colorRun); - for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 3; - p.accel[j] = 0; - } - p.vel[2] = 20 + crand() * 5; - - VectorAdd(move, vec, move); - } - } - - static void ForceWall(float[] start, float[] end, int color) { - float[] move = new float[3]; - float[] vec = new float[3]; - ; - float len; - int j; - cparticle_t p; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - VectorScale(vec, 4, vec); - - // FIXME: this is a really silly way to have a loop - while (len > 0) { - len -= 4; - - if (free_particles == null) - return; - - if (Globals.rnd.nextFloat() > 0.3) { - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -1.0f / (3.0f + Globals.rnd.nextFloat() * 0.5f); - p.color = color; - for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 3; - p.accel[j] = 0; - } - p.vel[0] = 0; - p.vel[1] = 0; - p.vel[2] = -40 - (crand() * 10); - } - - VectorAdd(move, vec, move); - } - } - -// static void FlameEffects(centity_t ent, float[] origin) { -// int n, count; -// int j; -// cparticle_t p; -// -// count = rand() & 0xF; -// -// for (n = 0; n < count; n++) { -// if (free_particles == null) -// return; -// -// p = free_particles; -// free_particles = p.next; -// p.next = active_particles; -// active_particles = p; -// -// VectorClear(p.accel); -// p.time = cl.time; -// -// p.alpha = 1.0f; -// p.alphavel = -1.0f / (1 + frand() * 0.2f); -// p.color = 226 + (rand() % 4); -// for (j = 0; j < 3; j++) { -// p.org[j] = origin[j] + crand() * 5; -// p.vel[j] = crand() * 5; -// } -// p.vel[2] = crand() * -10; -// p.accel[2] = -PARTICLE_GRAVITY; -// } -// -// count = rand() & 0x7; -// -// for (n = 0; n < count; n++) { -// if (free_particles == null) -// return; -// p = free_particles; -// free_particles = p.next; -// p.next = active_particles; -// active_particles = p; -// VectorClear(p.accel); -// -// p.time = cl.time; -// -// p.alpha = 1.0f; -// p.alphavel = -1.0f / (1 + frand() * 0.5f); -// p.color = 0 + (rand() % 4); -// for (j = 0; j < 3; j++) { -// p.org[j] = origin[j] + crand() * 3; -// } -// p.vel[2] = 20 + crand() * 5; -// } -// -// } - - - /* - =============== - CL_GenericParticleEffect - =============== - */ - static void GenericParticleEffect(float[] org, float[] dir, int color, int count, int numcolors, int dirspread, float alphavel) { - int i, j; - cparticle_t p; - float d; - - for (i = 0; i < count; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - if (numcolors > 1) - p.color = color + (rand() & numcolors); - else - p.color = color; - - d = rand() & dirspread; - for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() & 7) - 4) + d * dir[j]; - p.vel[j] = crand() * 20; - } - - p.accel[0] = p.accel[1] = 0; - p.accel[2] = -PARTICLE_GRAVITY; - // VectorCopy (accel, p.accel); - p.alpha = 1.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * alphavel); - // p.alphavel = alphavel; - } - } - - /* - =============== - CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns) - - =============== - */ - static void BubbleTrail2 (float[] start, float[] end, int dist) - { - float[] move = new float[3]; - float[] vec = new float[3];; - float len; - int i, j; - cparticle_t p; - float dec; - - VectorCopy (start, move); - VectorSubtract (end, start, vec); - len = VectorNormalize (vec); - - dec = dist; - VectorScale (vec, dec, vec); - - for (i=0 ; i<len ; i+=dec) - { - if (free_particles == null) - return; - - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - VectorClear (p.accel); - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -1.0f / (1+Globals.rnd.nextFloat()*0.1f); - p.color = 4 + (rand()&7); - for (j=0 ; j<3 ; j++) - { - p.org[j] = move[j] + crand()*2; - p.vel[j] = crand()*10; - } - p.org[2] -= 4; -// p.vel[2] += 6; - p.vel[2] += 20; - - VectorAdd (move, vec, move); - } - } - - static void Heatbeam(float[] start, float[] forward) { - float[] move = new float[3]; - float[] vec = new float[3]; - float len; - int j; - cparticle_t p; - float[] right = new float[3]; - float[] up = new float[3]; - int i; - float c, s; - float[] dir = new float[3]; - float ltime; - float step = 32.0f, rstep; - float start_pt; - float rot; - float variance; - float[] end = new float[3]; - - VectorMA(start, 4096, forward, end); - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - // FIXME - pmm - these might end up using old values? - // MakeNormalVectors (vec, right, up); - VectorCopy(cl.v_right, right); - VectorCopy(cl.v_up, up); - if (vidref_val == VIDREF_GL) { // GL mode - VectorMA(move, -0.5f, right, move); - VectorMA(move, -0.5f, up, move); - } - // otherwise assume SOFT - - ltime = (float)cl.time / 1000.0f; - start_pt = ltime * 96.0f % step; - VectorMA(move, start_pt, vec, move); - - VectorScale(vec, step, vec); - - // Com_Printf ("%f\n", ltime); - rstep = (float) (Math.PI / 10.0); - float M_PI2 = (float) (Math.PI * 2.0); - 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 < M_PI2; rot += rstep) { - - if (free_particles == null) - return; - - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - VectorClear(p.accel); - // rot+= fmod(ltime, 12.0)*M_PI; - // c = cos(rot)/2.0; - // s = sin(rot)/2.0; - // variance = 0.4 + ((float)rand()/(float)RAND_MAX) *0.2; - 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) { - VectorScale(right, c * (i / 10.0f), dir); - VectorMA(dir, s * (i / 10.0f), up, dir); - } else { - VectorScale(right, c, dir); - VectorMA(dir, s, up, dir); - } - - p.alpha = 0.5f; - // p.alphavel = -1.0 / (1+frand()*0.2); - p.alphavel = -1000.0f; - // p.color = 0x74 + (rand()&7); - p.color = 223 - (rand() & 7); - for (j = 0; j < 3; j++) { - p.org[j] = move[j] + dir[j] * 3; - // p.vel[j] = dir[j]*6; - p.vel[j] = 0; - } - } - VectorAdd(move, vec, move); - } - } - - /* - =============== - CL_ParticleSteamEffect - - Puffs with velocity along direction, with some randomness thrown in - =============== - */ - static void ParticleSteamEffect(float[] org, float[] dir, int color, int count, int magnitude) { - int i, j; - cparticle_t p; - float d; - float[] r = new float[3]; - float[] u = new float[3]; - - // vectoangles2 (dir, angle_dir); - // AngleVectors (angle_dir, f, r, u); - - MakeNormalVectors(dir, r, u); - - for (i = 0; i < count; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = color + (rand() & 7); - - for (j = 0; j < 3; j++) { - p.org[j] = org[j] + magnitude * 0.1f * crand(); - // p.vel[j] = dir[j]*magnitude; - } - VectorScale(dir, magnitude, p.vel); - d = crand() * magnitude / 3; - VectorMA(p.vel, d, r, p.vel); - d = crand() * magnitude / 3; - VectorMA(p.vel, d, u, p.vel); - - p.accel[0] = p.accel[1] = 0; - p.accel[2] = -PARTICLE_GRAVITY / 2; - p.alpha = 1.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - } - - static void ParticleSteamEffect2(cl_sustain_t self) - // float[] org, float[] dir, int color, int count, int magnitude) - { - int i, j; - cparticle_t p; - float d; - float[] r = new float[3]; - float[] u = new float[3]; - float[] dir = new float[3]; - - // vectoangles2 (dir, angle_dir); - // AngleVectors (angle_dir, f, r, u); - - VectorCopy(self.dir, dir); - MakeNormalVectors(dir, r, u); - - for (i = 0; i < self.count; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = self.color + (rand() & 7); - - for (j = 0; j < 3; j++) { - p.org[j] = self.org[j] + self.magnitude * 0.1f * crand(); - // p.vel[j] = dir[j]*magnitude; - } - VectorScale(dir, self.magnitude, p.vel); - d = crand() * self.magnitude / 3; - VectorMA(p.vel, d, r, p.vel); - d = crand() * self.magnitude / 3; - VectorMA(p.vel, d, u, p.vel); - - p.accel[0] = p.accel[1] = 0; - p.accel[2] = -PARTICLE_GRAVITY / 2; - p.alpha = 1.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - self.nextthink += self.thinkinterval; - } - - /* - =============== - CL_TrackerTrail - =============== - */ - static void TrackerTrail(float[] start, float[] end, int particleColor) { - float[] move = new float[3]; - float[] vec = new float[3]; - float[] forward = new float[3]; - float[] right = new float[3]; - float[] up = new float[3]; - float[] angle_dir = new float[3]; - float len; - cparticle_t p; - int dec; - float dist; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - VectorCopy(vec, forward); - vectoangles(forward, angle_dir); - AngleVectors(angle_dir, forward, right, up); - - dec = 3; - VectorScale(vec, 3, vec); - - // FIXME: this is a really silly way to have a loop - while (len > 0) { - len -= dec; - - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -2.0f; - p.color = particleColor; - dist = DotProduct(move, forward); - VectorMA(move, (float)(8 * Math.cos(dist)), up, p.org); - for (int j=0 ; j<3 ; j++) { - p.vel[j] = 0; - p.accel[j] = 0; - } - p.vel[2] = 5; - - VectorAdd (move, vec, move); - } - } - - static void Tracker_Shell(float[] origin) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - for(i=0;i<300;i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = 0; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(origin, 40, dir, p.org); - } - } - - static void MonsterPlasma_Shell(float[] origin) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - for (i = 0; i < 40; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = 0xe0; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(origin, 10, dir, p.org); - // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p.org); - } - } - - private static int[] wb_colortable = {2*8,13*8,21*8,18*8}; - static void Widowbeamout(cl_sustain_t self) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - float ratio; - - ratio = 1.0f - (((float)self.endtime - (float)cl.time) / 2100.0f); - - for (i = 0; i < 300; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = wb_colortable[rand() & 3]; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(self.org, (45.0f * ratio), dir, p.org); - // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p.org); - } - } - - private static int[] nb_colortable = {110, 112, 114, 116}; - static void Nukeblast(cl_sustain_t self) { - float[] dir = new float[3]; - int i; - cparticle_t p; - - float ratio; - - ratio = 1.0f - (((float)self.endtime - (float)cl.time) / 1000.0f); - - for (i = 0; i < 700; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = INSTANT_PARTICLE; - p.color = nb_colortable[rand() & 3]; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - - VectorMA(self.org, (200.0f * ratio), dir, p.org); - // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p.org); - } - } - - private static int[] ws_colortable = {2*8,13*8,21*8,18*8}; - static void WidowSplash(float[] org) { - int i; - cparticle_t p; - float[] dir = new float[3]; - - for (i = 0; i < 256; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = ws_colortable[rand() & 3]; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - VectorMA(org, 45.0f, dir, p.org); - VectorMA(vec3_origin, 40.0f, dir, p.vel); - - p.accel[0] = p.accel[1] = 0; - p.alpha = 1.0f; - - p.alphavel = -0.8f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - - } - - static void Tracker_Explode(float[] origin) { - float[] dir = new float[3]; - float[] backdir = new float[3]; - int i; - cparticle_t p; - - for (i = 0; i < 300; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -1.0f; - p.color = 0; - - dir[0] = crand(); - dir[1] = crand(); - dir[2] = crand(); - VectorNormalize(dir); - VectorScale(dir, -1, backdir); - - VectorMA(origin, 64, dir, p.org); - VectorScale(backdir, 64, p.vel); - } - - } - - /* - =============== - CL_TagTrail - - =============== - */ - static void TagTrail(float[] start, float[] end, float color) { - float[] move = new float[3]; - float[] vec = new float[3]; - float len; - int j; - cparticle_t p; - int dec; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - dec = 5; - VectorScale(vec, 5, vec); - - while (len >= 0) { - len -= dec; - - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -1.0f / (0.8f + Globals.rnd.nextFloat() * 0.2f); - p.color = color; - for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand() * 16; - p.vel[j] = crand() * 5; - p.accel[j] = 0; - } - - VectorAdd(move, vec, move); - } - } - - /* - =============== - CL_ColorExplosionParticles - =============== - */ - static void ColorExplosionParticles(float[] org, int color, int run) { - int i, j; - cparticle_t p; - - for (i = 0; i < 128; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = color + (rand() % run); - - for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() % 32) - 16); - p.vel[j] = (rand() % 256) - 128; - } - - p.accel[0] = p.accel[1] = 0; - p.accel[2] = -PARTICLE_GRAVITY; - p.alpha = 1.0f; - - p.alphavel = -0.4f / (0.6f + Globals.rnd.nextFloat() * 0.2f); - } - } - - /* - =============== - CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity - =============== - */ - static void ParticleSmokeEffect (float[] org, float[] dir, int color, int count, int magnitude) - { - int i, j; - cparticle_t p; - float d; - float[] r = new float[3]; - float[] u = new float[3]; - - MakeNormalVectors (dir, r, u); - - for (i=0 ; i<count ; i++) - { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = color + (rand()&7); - - for (j=0 ; j<3 ; j++) - { - p.org[j] = org[j] + magnitude*0.1f*crand(); -// p.vel[j] = dir[j]*magnitude; - } - VectorScale (dir, magnitude, p.vel); - d = crand()*magnitude/3; - VectorMA (p.vel, d, r, p.vel); - d = crand()*magnitude/3; - VectorMA (p.vel, d, u, p.vel); - - p.accel[0] = p.accel[1] = p.accel[2] = 0; - p.alpha = 1.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat()*0.3f); - } - } - - /* - =============== - CL_BlasterParticles2 - - Wall impact puffs (Green) - =============== - */ - static void BlasterParticles2(float[] org, float[] dir, long color) { - int i, j; - cparticle_t p; - float d; - int count; - - count = 40; - for (i = 0; i < count; i++) { - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - - p.time = cl.time; - p.color = color + (rand() & 7); - - d = rand() & 15; - for (j = 0; j < 3; j++) { - p.org[j] = org[j] + ((rand() & 7) - 4) + d * dir[j]; - p.vel[j] = dir[j] * 30 + crand() * 40; - } - - p.accel[0] = p.accel[1] = 0; - p.accel[2] = -PARTICLE_GRAVITY; - p.alpha = 1.0f; - - p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); - } - } - - /* - =============== - CL_BlasterTrail2 - - Green! - =============== - */ - static void BlasterTrail2(float[] start, float[] end) { - float[] move = new float[3]; - float[] vec = new float[3]; - float len; - int j; - cparticle_t p; - int dec; - - VectorCopy(start, move); - VectorSubtract(end, start, vec); - len = VectorNormalize(vec); - - dec = 5; - VectorScale(vec, 5, vec); - - // FIXME: this is a really silly way to have a loop - while (len > 0) { - len -= dec; - - if (free_particles == null) - return; - p = free_particles; - free_particles = p.next; - p.next = active_particles; - active_particles = p; - VectorClear(p.accel); - - p.time = cl.time; - - p.alpha = 1.0f; - p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); - p.color = 0xd0; - for (j = 0; j < 3; j++) { - p.org[j] = move[j] + crand(); - p.vel[j] = crand() * 5; - p.accel[j] = 0; - } - - VectorAdd(move, vec, move); - } - } - -} +public class CL_newfx { + + static void Flashlight(int ent, float[] pos) { + CL_fx.cdlight_t dl; + + dl = CL_fx.AllocDlight(ent); + Math3D.VectorCopy(pos, dl.origin); + dl.radius = 400; + dl.minlight = 250; + dl.die = Globals.cl.time + 100; + dl.color[0] = 1; + dl.color[1] = 1; + dl.color[2] = 1; + } + + /* + * ====== CL_ColorFlash - flash of light ====== + */ + static void ColorFlash(float[] pos, int ent, int intensity, float r, + float g, float b) { + CL_fx.cdlight_t dl; + + if ((Globals.vidref_val == Defines.VIDREF_SOFT) + && ((r < 0) || (g < 0) || (b < 0))) { + intensity = -intensity; + r = -r; + g = -g; + b = -b; + } + + dl = CL_fx.AllocDlight(ent); + Math3D.VectorCopy(pos, dl.origin); + dl.radius = intensity; + dl.minlight = 250; + dl.die = Globals.cl.time + 100; + dl.color[0] = r; + dl.color[1] = g; + dl.color[2] = b; + } + + /* + * ====== CL_DebugTrail ====== + */ + static void DebugTrail(float[] start, float[] end) { + float[] move = new float[3]; + float[] vec = new float[3]; + + float len; + // int j; + cparticle_t p; + float dec; + float[] right = new float[3]; + float[] up = new float[3]; + // int i; + // float d, c, s; + // float[] dir; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.MakeNormalVectors(vec, right, up); + + // VectorScale(vec, RT2_SKIP, vec); + + // dec = 1.0; + // dec = 0.75; + dec = 3; + Math3D.VectorScale(vec, dec, vec); + Math3D.VectorCopy(start, move); + + while (len > 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + Math3D.VectorClear(p.accel); + Math3D.VectorClear(p.vel); + p.alpha = 1.0f; + p.alphavel = -0.1f; + // p.alphavel = 0; + p.color = 0x74 + (Lib.rand() & 7); + Math3D.VectorCopy(move, p.org); + /* + * for (j=0 ; j <3 ; j++) { p.org[j] = move[j] + crand()*2; p.vel[j] = + * crand()*3; p.accel[j] = 0; } + */ + Math3D.VectorAdd(move, vec, move); + } + + } + + /* + * =============== CL_SmokeTrail =============== + */ + static void SmokeTrail(float[] start, float[] end, int colorStart, + int colorRun, int spacing) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.VectorScale(vec, spacing, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= spacing; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.5f); + p.color = colorStart + (Lib.rand() % colorRun); + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 3; + p.accel[j] = 0; + } + p.vel[2] = 20 + Lib.crand() * 5; + + Math3D.VectorAdd(move, vec, move); + } + } + + static void ForceWall(float[] start, float[] end, int color) { + float[] move = new float[3]; + float[] vec = new float[3]; + ; + float len; + int j; + cparticle_t p; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.VectorScale(vec, 4, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= 4; + + if (CL_fx.free_particles == null) + return; + + if (Globals.rnd.nextFloat() > 0.3) { + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (3.0f + Globals.rnd.nextFloat() * 0.5f); + p.color = color; + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 3; + p.accel[j] = 0; + } + p.vel[0] = 0; + p.vel[1] = 0; + p.vel[2] = -40 - (Lib.crand() * 10); + } + + Math3D.VectorAdd(move, vec, move); + } + } + + // static void FlameEffects(centity_t ent, float[] origin) { + // int n, count; + // int j; + // cparticle_t p; + // + // count = rand() & 0xF; + // + // for (n = 0; n < count; n++) { + // if (free_particles == null) + // return; + // + // p = free_particles; + // free_particles = p.next; + // p.next = active_particles; + // active_particles = p; + // + // VectorClear(p.accel); + // p.time = cl.time; + // + // p.alpha = 1.0f; + // p.alphavel = -1.0f / (1 + frand() * 0.2f); + // p.color = 226 + (rand() % 4); + // for (j = 0; j < 3; j++) { + // p.org[j] = origin[j] + crand() * 5; + // p.vel[j] = crand() * 5; + // } + // p.vel[2] = crand() * -10; + // p.accel[2] = -PARTICLE_GRAVITY; + // } + // + // count = rand() & 0x7; + // + // for (n = 0; n < count; n++) { + // if (free_particles == null) + // return; + // p = free_particles; + // free_particles = p.next; + // p.next = active_particles; + // active_particles = p; + // VectorClear(p.accel); + // + // p.time = cl.time; + // + // p.alpha = 1.0f; + // p.alphavel = -1.0f / (1 + frand() * 0.5f); + // p.color = 0 + (rand() % 4); + // for (j = 0; j < 3; j++) { + // p.org[j] = origin[j] + crand() * 3; + // } + // p.vel[2] = 20 + crand() * 5; + // } + // + // } + + /* + * =============== CL_GenericParticleEffect =============== + */ + static void GenericParticleEffect(float[] org, float[] dir, int color, + int count, int numcolors, int dirspread, float alphavel) { + int i, j; + cparticle_t p; + float d; + + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + if (numcolors > 1) + p.color = color + (Lib.rand() & numcolors); + else + p.color = color; + + d = Lib.rand() & dirspread; + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = Lib.crand() * 20; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY; + // VectorCopy (accel, p.accel); + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * alphavel); + // p.alphavel = alphavel; + } + } + + /* + * =============== CL_BubbleTrail2 (lets you control the # of bubbles by + * setting the distance between the spawns) + * + * =============== + */ + static void BubbleTrail2(float[] start, float[] end, int dist) { + float[] move = new float[3]; + float[] vec = new float[3]; + ; + float len; + int i, j; + cparticle_t p; + float dec; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + dec = dist; + Math3D.VectorScale(vec, dec, vec); + + for (i = 0; i < len; i += dec) { + if (CL_fx.free_particles == null) + return; + + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + Math3D.VectorClear(p.accel); + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (1 + Globals.rnd.nextFloat() * 0.1f); + p.color = 4 + (Lib.rand() & 7); + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 2; + p.vel[j] = Lib.crand() * 10; + } + p.org[2] -= 4; + // p.vel[2] += 6; + p.vel[2] += 20; + + Math3D.VectorAdd(move, vec, move); + } + } + + static void Heatbeam(float[] start, float[] forward) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + float[] right = new float[3]; + float[] up = new float[3]; + int i; + float c, s; + float[] dir = new float[3]; + float ltime; + float step = 32.0f, rstep; + float start_pt; + float rot; + float variance; + float[] end = new float[3]; + + Math3D.VectorMA(start, 4096, forward, end); + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + // FIXME - pmm - these might end up using old values? + // MakeNormalVectors (vec, right, up); + Math3D.VectorCopy(Globals.cl.v_right, right); + Math3D.VectorCopy(Globals.cl.v_up, up); + if (Globals.vidref_val == Defines.VIDREF_GL) { // GL mode + Math3D.VectorMA(move, -0.5f, right, move); + Math3D.VectorMA(move, -0.5f, up, move); + } + // otherwise assume SOFT + + ltime = (float) Globals.cl.time / 1000.0f; + start_pt = ltime * 96.0f % step; + Math3D.VectorMA(move, start_pt, vec, move); + + Math3D.VectorScale(vec, step, vec); + + // Com_Printf ("%f\n", ltime); + rstep = (float) (Math.PI / 10.0); + float M_PI2 = (float) (Math.PI * 2.0); + 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 < M_PI2; rot += rstep) { + + if (CL_fx.free_particles == null) + return; + + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + Math3D.VectorClear(p.accel); + // rot+= fmod(ltime, 12.0)*M_PI; + // c = cos(rot)/2.0; + // s = sin(rot)/2.0; + // variance = 0.4 + ((float)rand()/(float)RAND_MAX) *0.2; + 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.5f; + // p.alphavel = -1.0 / (1+frand()*0.2); + p.alphavel = -1000.0f; + // p.color = 0x74 + (rand()&7); + p.color = 223 - (Lib.rand() & 7); + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + dir[j] * 3; + // p.vel[j] = dir[j]*6; + p.vel[j] = 0; + } + } + Math3D.VectorAdd(move, vec, move); + } + } + + /* + * =============== CL_ParticleSteamEffect + * + * Puffs with velocity along direction, with some randomness thrown in + * =============== + */ + static void ParticleSteamEffect(float[] org, float[] dir, int color, + int count, int magnitude) { + int i, j; + cparticle_t p; + float d; + float[] r = new float[3]; + float[] u = new float[3]; + + // vectoangles2 (dir, angle_dir); + // AngleVectors (angle_dir, f, r, u); + + Math3D.MakeNormalVectors(dir, r, u); + + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); + + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + magnitude * 0.1f * Lib.crand(); + // p.vel[j] = dir[j]*magnitude; + } + Math3D.VectorScale(dir, magnitude, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, r, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, u, p.vel); + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY / 2; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + } + + static void ParticleSteamEffect2(cl_sustain_t self) + // float[] org, float[] dir, int color, int count, int magnitude) + { + int i, j; + cparticle_t p; + float d; + float[] r = new float[3]; + float[] u = new float[3]; + float[] dir = new float[3]; + + // vectoangles2 (dir, angle_dir); + // AngleVectors (angle_dir, f, r, u); + + Math3D.VectorCopy(self.dir, dir); + Math3D.MakeNormalVectors(dir, r, u); + + for (i = 0; i < self.count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = self.color + (Lib.rand() & 7); + + for (j = 0; j < 3; j++) { + p.org[j] = self.org[j] + self.magnitude * 0.1f * Lib.crand(); + // p.vel[j] = dir[j]*magnitude; + } + Math3D.VectorScale(dir, self.magnitude, p.vel); + d = Lib.crand() * self.magnitude / 3; + Math3D.VectorMA(p.vel, d, r, p.vel); + d = Lib.crand() * self.magnitude / 3; + Math3D.VectorMA(p.vel, d, u, p.vel); + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY / 2; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + self.nextthink += self.thinkinterval; + } + + /* + * =============== CL_TrackerTrail =============== + */ + static void TrackerTrail(float[] start, float[] end, int particleColor) { + float[] move = new float[3]; + float[] vec = new float[3]; + float[] forward = new float[3]; + float[] right = new float[3]; + float[] up = new float[3]; + float[] angle_dir = new float[3]; + float len; + cparticle_t p; + int dec; + float dist; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + Math3D.VectorCopy(vec, forward); + Math3D.vectoangles(forward, angle_dir); + Math3D.AngleVectors(angle_dir, forward, right, up); + + dec = 3; + Math3D.VectorScale(vec, 3, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -2.0f; + p.color = particleColor; + dist = Math3D.DotProduct(move, forward); + Math3D.VectorMA(move, (float) (8 * Math.cos(dist)), up, p.org); + for (int j = 0; j < 3; j++) { + p.vel[j] = 0; + p.accel[j] = 0; + } + p.vel[2] = 5; + + Math3D.VectorAdd(move, vec, move); + } + } + + static void Tracker_Shell(float[] origin) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + for (i = 0; i < 300; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = 0; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(origin, 40, dir, p.org); + } + } + + static void MonsterPlasma_Shell(float[] origin) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + for (i = 0; i < 40; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = 0xe0; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(origin, 10, dir, p.org); + // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), + // dir, p.org); + } + } + + private static int[] wb_colortable = { 2 * 8, 13 * 8, 21 * 8, 18 * 8 }; + + static void Widowbeamout(cl_sustain_t self) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + float ratio; + + ratio = 1.0f - (((float) self.endtime - (float) Globals.cl.time) / 2100.0f); + + for (i = 0; i < 300; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = wb_colortable[Lib.rand() & 3]; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(self.org, (45.0f * ratio), dir, p.org); + // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), + // dir, p.org); + } + } + + private static int[] nb_colortable = { 110, 112, 114, 116 }; + + static void Nukeblast(cl_sustain_t self) { + float[] dir = new float[3]; + int i; + cparticle_t p; + + float ratio; + + ratio = 1.0f - (((float) self.endtime - (float) Globals.cl.time) / 1000.0f); + + for (i = 0; i < 700; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = CL_fx.INSTANT_PARTICLE; + p.color = nb_colortable[Lib.rand() & 3]; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + + Math3D.VectorMA(self.org, (200.0f * ratio), dir, p.org); + // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), + // dir, p.org); + } + } + + private static int[] ws_colortable = { 2 * 8, 13 * 8, 21 * 8, 18 * 8 }; + + static void WidowSplash(float[] org) { + int i; + cparticle_t p; + float[] dir = new float[3]; + + for (i = 0; i < 256; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = ws_colortable[Lib.rand() & 3]; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + Math3D.VectorMA(org, 45.0f, dir, p.org); + Math3D.VectorMA(Globals.vec3_origin, 40.0f, dir, p.vel); + + p.accel[0] = p.accel[1] = 0; + p.alpha = 1.0f; + + p.alphavel = -0.8f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + + } + + static void Tracker_Explode(float[] origin) { + float[] dir = new float[3]; + float[] backdir = new float[3]; + int i; + cparticle_t p; + + for (i = 0; i < 300; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f; + p.color = 0; + + dir[0] = Lib.crand(); + dir[1] = Lib.crand(); + dir[2] = Lib.crand(); + Math3D.VectorNormalize(dir); + Math3D.VectorScale(dir, -1, backdir); + + Math3D.VectorMA(origin, 64, dir, p.org); + Math3D.VectorScale(backdir, 64, p.vel); + } + + } + + /* + * =============== CL_TagTrail + * + * =============== + */ + static void TagTrail(float[] start, float[] end, float color) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + int dec; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + dec = 5; + Math3D.VectorScale(vec, 5, vec); + + while (len >= 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (0.8f + Globals.rnd.nextFloat() * 0.2f); + p.color = color; + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand() * 16; + p.vel[j] = Lib.crand() * 5; + p.accel[j] = 0; + } + + Math3D.VectorAdd(move, vec, move); + } + } + + /* + * =============== CL_ColorExplosionParticles =============== + */ + static void ColorExplosionParticles(float[] org, int color, int run) { + int i, j; + cparticle_t p; + + for (i = 0; i < 128; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() % run); + + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + ((Lib.rand() % 32) - 16); + p.vel[j] = (Lib.rand() % 256) - 128; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY; + p.alpha = 1.0f; + + p.alphavel = -0.4f / (0.6f + Globals.rnd.nextFloat() * 0.2f); + } + } + + /* + * =============== CL_ParticleSmokeEffect - like the steam effect, but + * unaffected by gravity =============== + */ + static void ParticleSmokeEffect(float[] org, float[] dir, int color, + int count, int magnitude) { + int i, j; + cparticle_t p; + float d; + float[] r = new float[3]; + float[] u = new float[3]; + + Math3D.MakeNormalVectors(dir, r, u); + + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); + + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + magnitude * 0.1f * Lib.crand(); + // p.vel[j] = dir[j]*magnitude; + } + Math3D.VectorScale(dir, magnitude, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, r, p.vel); + d = Lib.crand() * magnitude / 3; + Math3D.VectorMA(p.vel, d, u, p.vel); + + p.accel[0] = p.accel[1] = p.accel[2] = 0; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + } + + /* + * =============== CL_BlasterParticles2 + * + * Wall impact puffs (Green) =============== + */ + static void BlasterParticles2(float[] org, float[] dir, long color) { + int i, j; + cparticle_t p; + float d; + int count; + + count = 40; + for (i = 0; i < count; i++) { + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + + p.time = Globals.cl.time; + p.color = color + (Lib.rand() & 7); + + d = Lib.rand() & 15; + for (j = 0; j < 3; j++) { + p.org[j] = org[j] + ((Lib.rand() & 7) - 4) + d * dir[j]; + p.vel[j] = dir[j] * 30 + Lib.crand() * 40; + } + + p.accel[0] = p.accel[1] = 0; + p.accel[2] = -CL_fx.PARTICLE_GRAVITY; + p.alpha = 1.0f; + + p.alphavel = -1.0f / (0.5f + Globals.rnd.nextFloat() * 0.3f); + } + } + + /* + * =============== CL_BlasterTrail2 + * + * Green! =============== + */ + static void BlasterTrail2(float[] start, float[] end) { + float[] move = new float[3]; + float[] vec = new float[3]; + float len; + int j; + cparticle_t p; + int dec; + + Math3D.VectorCopy(start, move); + Math3D.VectorSubtract(end, start, vec); + len = Math3D.VectorNormalize(vec); + + dec = 5; + Math3D.VectorScale(vec, 5, vec); + + // FIXME: this is a really silly way to have a loop + while (len > 0) { + len -= dec; + + if (CL_fx.free_particles == null) + return; + p = CL_fx.free_particles; + CL_fx.free_particles = p.next; + p.next = CL_fx.active_particles; + CL_fx.active_particles = p; + Math3D.VectorClear(p.accel); + + p.time = Globals.cl.time; + + p.alpha = 1.0f; + p.alphavel = -1.0f / (0.3f + Globals.rnd.nextFloat() * 0.2f); + p.color = 0xd0; + for (j = 0; j < 3; j++) { + p.org[j] = move[j] + Lib.crand(); + p.vel[j] = Lib.crand() * 5; + p.accel[j] = 0; + } + + Math3D.VectorAdd(move, vec, move); + } + } +}
\ No newline at end of file diff --git a/src/jake2/client/CL_parse.java b/src/jake2/client/CL_parse.java index 432df25..ecc1abe 100644 --- a/src/jake2/client/CL_parse.java +++ b/src/jake2/client/CL_parse.java @@ -2,27 +2,27 @@ * CL_parse.java * Copyright (C) 2004 * - * $Id: CL_parse.java,v 1.8 2004-07-30 06:03:40 hzi Exp $ + * $Id: CL_parse.java,v 1.9 2004-09-22 19:22:07 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; import jake2.Defines; @@ -41,753 +41,750 @@ import java.io.RandomAccessFile; /** * CL_parse */ -public class CL_parse extends CL_view { - - //// cl_parse.c -- parse a message received from the server - - public static String svc_strings[] = - { - "svc_bad", - "svc_muzzleflash", - "svc_muzzlflash2", - "svc_temp_entity", - "svc_layout", - "svc_inventory", - "svc_nop", - "svc_disconnect", - "svc_reconnect", - "svc_sound", - "svc_print", - "svc_stufftext", - "svc_serverdata", - "svc_configstring", - "svc_spawnbaseline", - "svc_centerprint", - "svc_download", - "svc_playerinfo", - "svc_packetentities", - "svc_deltapacketentities", - "svc_frame" }; - - // ============================================================================= - - public static String DownloadFileName(String fn) { - if ("players".equals(fn)) - return BASEDIRNAME + "/" + fn; - else - return FS.Gamedir() + "/" + fn; - } - - /* - =============== - CL_CheckOrDownloadFile - - Returns true if the file exists, otherwise it attempts - to start a download from the server. - =============== - */ - public static boolean CheckOrDownloadFile(String filename) { - RandomAccessFile fp; - String name; - - if (filename.indexOf("..") != -1) { - Com.Printf("Refusing to download a path with ..\n"); - return true; - } - - if (FS.LoadFile(filename) != null) { // it exists, no need to download - return true; - } - - cls.downloadname = filename; - - // download to a temp name, and only rename - // to the real name when done, so if interrupted - // a runt file wont be left - cls.downloadtempname = Com.StripExtension(cls.downloadname); - cls.downloadtempname += ".tmp"; - - // ZOID - // check to see if we already have a tmp for this file, if so, try to resume - // open the file if not opened yet - name = DownloadFileName(cls.downloadtempname); - - fp = fopen(name, "r+b"); - if (fp != null) { // it exists - long len = 0; - - try { - len = fp.length(); - } - catch (IOException e) { - }; - - cls.download = fp; - - // give the server an offset to start the download - Com.Printf("Resuming " + cls.downloadname + "\n"); - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - MSG.WriteString(cls.netchan.message, "download " + cls.downloadname + " " + len); - } - else { - cls.downloadname = cls.downloadname; - - Com.Printf("Downloading " + cls.downloadname + "\n"); - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - MSG.WriteString(cls.netchan.message, "download " + cls.downloadname); - } - - cls.downloadnumber++; - - return false; - } - - /* - =============== - CL_Download_f - - Request a download from the server - =============== - */ - static xcommand_t Download_f = new xcommand_t() { - public void execute() { - String filename; - - if (Cmd.Argc() != 2) { - Com.Printf("Usage: download <filename>\n"); - return; - } - - filename = Cmd.Argv(1); - - if (filename.indexOf("..") != -1) { - Com.Printf("Refusing to download a path with ..\n"); - return; - } - - if (FS.LoadFile(filename) != null) { // it exists, no need to download - Com.Printf("File already exists.\n"); - return; - } - - cls.downloadname = filename; - Com.Printf("Downloading " + cls.downloadname + "\n"); - - // download to a temp name, and only rename - // to the real name when done, so if interrupted - // a runt file wont be left - cls.downloadtempname = Com.StripExtension(cls.downloadname); - cls.downloadtempname += ".tmp"; - - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - MSG.WriteString(cls.netchan.message, "download " + cls.downloadname); - - cls.downloadnumber++; - } - }; - - /* - ====================== - CL_RegisterSounds - ====================== - */ - static void RegisterSounds() { - S.BeginRegistration(); - CL.RegisterTEntSounds(); - for (int i = 1; i < MAX_SOUNDS; i++) { - if (cl.configstrings[CS_SOUNDS + i] == null || cl.configstrings[CS_SOUNDS + i].equals("") || cl.configstrings[CS_SOUNDS + i].equals("\0")) - break; - cl.sound_precache[i] = S.RegisterSound(cl.configstrings[CS_SOUNDS + i]); - Sys.SendKeyEvents(); // pump message loop - } - S.EndRegistration(); - } - - /* - ===================== - CL_ParseDownload - - A download message has been received from the server - ===================== - */ - public static void ParseDownload() { - - // read the data - int size = MSG.ReadShort(net_message); - int percent = MSG.ReadByte(net_message); - if (size == -1) { - Com.Printf("Server does not have this file.\n"); - if (cls.download != null) { - // if here, we tried to resume a file but the server said no - try { - cls.download.close(); - } catch (IOException e) {} - cls.download = null; - } - CL.RequestNextDownload(); - return; - } - - // open the file if not opened yet - if (cls.download == null) { - String name = DownloadFileName(cls.downloadtempname); - - FS.CreatePath(name); - - cls.download = fopen(name, "rw"); - if (cls.download == null) { - net_message.readcount += size; - Com.Printf("Failed to open " + cls.downloadtempname + "\n"); - CL.RequestNextDownload(); - return; - } - } - - //fwrite(net_message.data[net_message.readcount], 1, size, cls.download); - try { - cls.download.write(net_message.data, net_message.readcount, size); - } - catch (Exception e) { - } - net_message.readcount += size; - - if (percent != 100) { - // request next block - // change display routines by zoid - - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - SZ.Print(cls.netchan.message, "nextdl"); - } - else { - String oldn, newn; - //char oldn[MAX_OSPATH]; - //char newn[MAX_OSPATH]; - - // Com.Printf ("100%%\n"); - - try { - cls.download.close(); - } catch (IOException e) {} - - // rename the temp file to it's final name - oldn = DownloadFileName(cls.downloadtempname); - newn = DownloadFileName(cls.downloadname); - int r = Lib.rename(oldn, newn); - if (r != 0) - Com.Printf("failed to rename.\n"); - - cls.download = null; - cls.downloadpercent = 0; - - // get another file if needed - - CL.RequestNextDownload(); - } - } - - /* - ===================================================================== - - SERVER CONNECTING MESSAGES - - ===================================================================== - */ - - /* - ================== - CL_ParseServerData - ================== - */ - //checked once, was ok. - public static void ParseServerData() { - - String str; - int i; - - Com.DPrintf("Serverdata packet received.\n"); - // - // wipe the client_state_t struct - // - CL.ClearState(); - cls.state = ca_connected; - - // parse protocol version number - i = MSG.ReadLong(net_message); - cls.serverProtocol = i; - - // BIG HACK to let demos from release work with the 3.0x patch!!! - if (Globals.server_state != 0 && PROTOCOL_VERSION == 34) { - } - else if (i != PROTOCOL_VERSION) - Com.Error(ERR_DROP, "Server returned version " + i + ", not " + PROTOCOL_VERSION); - - cl.servercount = MSG.ReadLong(net_message); - cl.attractloop = MSG.ReadByte(net_message) != 0; - - // game directory - str = MSG.ReadString(net_message); - cl.gamedir = str; - - // set gamedir - if (str.length() > 0 - && (FS.fs_gamedirvar.string == null || FS.fs_gamedirvar.string.length() == 0 || FS.fs_gamedirvar.string.equals(str)) - || (str.length() == 0 && (FS.fs_gamedirvar.string != null || FS.fs_gamedirvar.string.length() == 0))) - Cvar.Set("game", str); - - // parse player entity number - cl.playernum = MSG.ReadShort(net_message); - - // get the full level name - str = MSG.ReadString(net_message); - - if (cl.playernum == -1) { // playing a cinematic or showing a pic, not a level - SCR.PlayCinematic(str); - } - else { - // seperate the printfs so the server message can have a color -// Com.Printf( -// "\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); -// Com.Printf('\02' + str + "\n"); - Com.Printf("Levelname:" + str + "\n"); - // need to prep refresh at next oportunity - cl.refresh_prepped = false; - } - } - - /* - ================== - CL_ParseBaseline - ================== - */ - public static void ParseBaseline() { - entity_state_t es; - int newnum; - - entity_state_t nullstate = new entity_state_t(null); - //memset(nullstate, 0, sizeof(nullstate)); - int bits[] = {0}; - newnum = CL_ents.ParseEntityBits(bits); - es = cl_entities[newnum].baseline; - CL_ents.ParseDelta(nullstate, es, newnum, bits[0]); - } - - /* - ================ - CL_LoadClientinfo - - ================ - */ - public static void LoadClientinfo(clientinfo_t ci, String s) { - int i; - int t; - - //char model_name[MAX_QPATH]; - //char skin_name[MAX_QPATH]; - //char model_filename[MAX_QPATH]; - //char skin_filename[MAX_QPATH]; - //char weapon_filename[MAX_QPATH]; - - String model_name,skin_name,model_filename, skin_filename, weapon_filename; - - ci.cinfo = s; - //ci.cinfo[sizeof(ci.cinfo) - 1] = 0; - - // isolate the player's name - ci.name = s; - //ci.name[sizeof(ci.name) - 1] = 0; - - t = s.indexOf('\\'); - //t = strstr(s, "\\"); - - if (t!=-1) { - ci.name = s.substring(0,t); - s = s.substring(t + 1, s.length()); - //s = t + 1; - } - - if (cl_noskins.value!=0 || s.length()!=0) { - - model_filename=("players/male/tris.md2"); - weapon_filename=("players/male/weapon.md2"); - skin_filename=("players/male/grunt.pcx"); - ci.iconname=("/players/male/grunt_i.pcx"); - - ci.model = re.RegisterModel(model_filename); - - ci.weaponmodel = new model_t[Defines.MAX_CLIENTWEAPONMODELS]; - ci.weaponmodel[0] = re.RegisterModel(weapon_filename); - ci.skin = re.RegisterSkin(skin_filename); - ci.icon = re.RegisterPic(ci.iconname); - } - else { - // isolate the model name - - int pos = s.indexOf('/'); - - if (pos == -1) - pos = s.indexOf('/'); - if (pos == -1) - { - pos =0; - Com.Error(Defines.ERR_FATAL, "Invalid model name:" + s); - } - - model_name = s.substring(0,pos); - - // isolate the skin name - skin_name = s.substring(pos+1, s.length()); - - // model file - model_filename = "players/" + model_name + "/tris.md2"; - ci.model = re.RegisterModel(model_filename); - - if (ci.model==null) { - model_name = "male"; - model_filename= "players/male/tris.md2"; - ci.model = re.RegisterModel(model_filename); - } - - // skin file - skin_filename = "players/" + model_name +"/"+ skin_name + ".pcx"; - ci.skin = re.RegisterSkin(skin_filename); - - // if we don't have the skin and the model wasn't male, - // see if the male has it (this is for CTF's skins) - if (ci.skin==null && !model_name.equalsIgnoreCase("male")) { - // change model to male - model_name = "male"; - model_filename= "players/male/tris.md2"; - ci.model = re.RegisterModel(model_filename); - - // see if the skin exists for the male model - skin_filename= "players/" + model_name + "/"+ skin_name+".pcx"; - ci.skin = re.RegisterSkin(skin_filename); - } - - // if we still don't have a skin, it means that the male model didn't have - // it, so default to grunt - if (ci.skin==null) { - // see if the skin exists for the male model - skin_filename= "players/" + model_name + "/grunt.pcx"; - ci.skin = re.RegisterSkin(skin_filename); - } - - // weapon file - for (i = 0; i < num_cl_weaponmodels; i++) { - weapon_filename= "players/"+model_name +"/" + cl_weaponmodels[i]; - ci.weaponmodel[i] = re.RegisterModel(weapon_filename); - if (null==ci.weaponmodel[i] && model_name.equals("cyborg")) { - // try male - weapon_filename="players/male/" + cl_weaponmodels[i]; - ci.weaponmodel[i] = re.RegisterModel(weapon_filename); - } - if (0==cl_vwep.value) - break; // only one when vwep is off - } - - // icon file - ci.iconname= "/players/"+model_name+"/" + skin_name+"_i.pcx"; - ci.icon = re.RegisterPic(ci.iconname); - } - - // must have loaded all data types to be valud - if (ci.skin==null || ci.icon==null || ci.model==null || ci.weaponmodel[0]==null) { - ci.skin = null; - ci.icon = null; - ci.model = null; - ci.weaponmodel[0] = null; - return; - } - } - - /* - ================ - CL_ParseClientinfo - - Load the skin, icon, and model for a client - ================ - */ - static void ParseClientinfo(int player) { - String s; - clientinfo_t ci; - - s = cl.configstrings[player + CS_PLAYERSKINS]; - - ci = cl.clientinfo[player]; - - LoadClientinfo(ci, s); - } - - /* - ================ - CL_ParseConfigString - ================ - */ - public static void ParseConfigString() { - int i; - String s; - String olds; - - i = MSG.ReadShort(net_message); - - if (i < 0 || i >= MAX_CONFIGSTRINGS) - Com.Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS"); - - s = MSG.ReadString(net_message); - - olds=cl.configstrings[i]; - cl.configstrings[i] = s; - - // do something apropriate - - if (i >= CS_LIGHTS && i < CS_LIGHTS + MAX_LIGHTSTYLES) { - SetLightstyle(i - CS_LIGHTS); - } - else if (i >= CS_MODELS && i < CS_MODELS + MAX_MODELS) { - if (cl.refresh_prepped) { - cl.model_draw[i - CS_MODELS] = re.RegisterModel(cl.configstrings[i]); - if (cl.configstrings[i].startsWith("*")) - cl.model_clip[i - CS_MODELS] = CM.InlineModel(cl.configstrings[i]); - else - cl.model_clip[i - CS_MODELS] = null; - } - } - else if (i >= CS_SOUNDS && i < CS_SOUNDS + MAX_MODELS) { - if (cl.refresh_prepped) - cl.sound_precache[i - CS_SOUNDS] = S.RegisterSound(cl.configstrings[i]); - } - else if (i >= CS_IMAGES && i < CS_IMAGES + MAX_MODELS) { - if (cl.refresh_prepped) - cl.image_precache[i - CS_IMAGES] = re.RegisterPic(cl.configstrings[i]); - } - else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS + MAX_CLIENTS) { - if (cl.refresh_prepped && !olds.equals(s)) - ParseClientinfo(i - CS_PLAYERSKINS); - } - } - - /* - ===================================================================== - - ACTION MESSAGES - - ===================================================================== - */ - - /* - ================== - CL_ParseStartSoundPacket - ================== - */ - public static void ParseStartSoundPacket() { - float[] pos_v={0,0,0}; - float pos[]; - int channel, ent; - int sound_num; - float volume; - float attenuation; - int flags; - float ofs; - - flags = MSG.ReadByte(net_message); - sound_num = MSG.ReadByte(net_message); - - if ((flags & SND_VOLUME) != 0) - volume = MSG.ReadByte(net_message) / 255.0f; - else - volume = DEFAULT_SOUND_PACKET_VOLUME; - - if ((flags & SND_ATTENUATION) != 0) - attenuation = MSG.ReadByte(net_message) / 64.0f; - else - attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; - - if ((flags & SND_OFFSET) != 0) - ofs = MSG.ReadByte(net_message) / 1000.0f; - else - ofs = 0; - - if ((flags & SND_ENT) != 0) { // entity reletive - channel = MSG.ReadShort(net_message); - ent = channel >> 3; - if (ent > MAX_EDICTS) - Com.Error(ERR_DROP, "CL_ParseStartSoundPacket: ent = " + ent); - - channel &= 7; - } - else { - ent = 0; - channel = 0; - } - - if ((flags & SND_POS) != 0) { // positioned in space - MSG.ReadPos(net_message, pos_v); - - pos = pos_v; - } - else // use entity number - pos = null; - - if (null==cl.sound_precache[sound_num]) - return; - - S.StartSound(pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation, ofs); - } - - public static void SHOWNET(String s) { - if (cl_shownet.value >= 2) - Com.Printf(net_message.readcount - 1 + ":" + s + "\n"); - } - - /* - ===================== - CL_ParseServerMessage - ===================== - */ - public static void ParseServerMessage() { - int cmd; - String s; - int i; - - // - // if recording demos, copy the message out - // - //if (cl_shownet.value == 1) - //Com.Printf(net_message.cursize + " "); - //else if (cl_shownet.value >= 2) - //Com.Printf("------------------\n"); - - // - // parse the message - // - while (true) { - if (net_message.readcount > net_message.cursize) { - Com.Error(ERR_FATAL, "CL_ParseServerMessage: Bad server message:"); - break; - } - - cmd = MSG.ReadByte(net_message); - - if (cmd == -1) { - SHOWNET("END OF MESSAGE"); - break; - } - - if (cl_shownet.value >= 2) { - if (null == svc_strings[cmd]) - Com.Printf(net_message.readcount - 1 + ":BAD CMD " + cmd + "\n"); - else - SHOWNET(svc_strings[cmd]); - } - - // other commands - switch (cmd) { - default : - Com.Error(ERR_DROP, "CL_ParseServerMessage: Illegible server message\n"); - break; - - case svc_nop : - // Com.Printf ("svc_nop\n"); - break; - - case svc_disconnect : - Com.Error(ERR_DISCONNECT, "Server disconnected\n"); - break; - - case svc_reconnect : - Com.Printf("Server disconnected, reconnecting\n"); - if (cls.download != null) { - //ZOID, close download - try { - cls.download.close(); - } catch (IOException e) {} - cls.download = null; - } - cls.state = ca_connecting; - cls.connect_time = -99999; // CL_CheckForResend() will fire immediately - break; - - case svc_print : - i = MSG.ReadByte(net_message); - if (i == PRINT_CHAT) { - S.StartLocalSound("misc/talk.wav"); - con.ormask = 128; - } - Com.Printf(MSG.ReadString(net_message)); - con.ormask = 0; - break; - - case svc_centerprint : - SCR.CenterPrint(MSG.ReadString(net_message)); - break; - - case svc_stufftext : - s = MSG.ReadString(net_message); - Com.DPrintf("stufftext: " + s + "\n"); - Cbuf.AddText(s); - break; - - case svc_serverdata : - Cbuf.Execute(); // make sure any stuffed commands are done - ParseServerData(); - break; - - case svc_configstring : - ParseConfigString(); - break; - - case svc_sound : - ParseStartSoundPacket(); - break; - - case svc_spawnbaseline : - ParseBaseline(); - break; - - case svc_temp_entity : - ParseTEnt(); - break; - - case svc_muzzleflash : - CL_fx.ParseMuzzleFlash(); - break; - - case svc_muzzleflash2 : - ParseMuzzleFlash2(); - break; - - case svc_download : - ParseDownload(); - break; - - case svc_frame : - ParseFrame(); - break; - - case svc_inventory : - CL_inv.ParseInventory(); - break; - - case svc_layout : - s = MSG.ReadString(net_message); - cl.layout = s; - break; - - case svc_playerinfo : - case svc_packetentities : - case svc_deltapacketentities : - Com.Error(ERR_DROP, "Out of place frame data"); - break; - } - } - - CL_view.AddNetgraph(); - - // - // we don't know if it is ok to save a demo message until - // after we have parsed the frame - // - if (cls.demorecording && !cls.demowaiting) - CL.WriteDemoMessage(); - } -} +public class CL_parse { + + //// cl_parse.c -- parse a message received from the server + + public static String svc_strings[] = { "svc_bad", "svc_muzzleflash", + "svc_muzzlflash2", "svc_temp_entity", "svc_layout", + "svc_inventory", "svc_nop", "svc_disconnect", "svc_reconnect", + "svc_sound", "svc_print", "svc_stufftext", "svc_serverdata", + "svc_configstring", "svc_spawnbaseline", "svc_centerprint", + "svc_download", "svc_playerinfo", "svc_packetentities", + "svc_deltapacketentities", "svc_frame" }; + + // ============================================================================= + + public static String DownloadFileName(String fn) { + if ("players".equals(fn)) + return Globals.BASEDIRNAME + "/" + fn; + else + return FS.Gamedir() + "/" + fn; + } + + /* + * =============== CL_CheckOrDownloadFile + * + * Returns true if the file exists, otherwise it attempts to start a + * download from the server. =============== + */ + public static boolean CheckOrDownloadFile(String filename) { + RandomAccessFile fp; + String name; + + if (filename.indexOf("..") != -1) { + Com.Printf("Refusing to download a path with ..\n"); + return true; + } + + if (FS.LoadFile(filename) != null) { // it exists, no need to download + return true; + } + + Globals.cls.downloadname = filename; + + // download to a temp name, and only rename + // to the real name when done, so if interrupted + // a runt file wont be left + Globals.cls.downloadtempname = Com + .StripExtension(Globals.cls.downloadname); + Globals.cls.downloadtempname += ".tmp"; + + // ZOID + // check to see if we already have a tmp for this file, if so, try to + // resume + // open the file if not opened yet + name = DownloadFileName(Globals.cls.downloadtempname); + + fp = Lib.fopen(name, "r+b"); + if (fp != null) { // it exists + long len = 0; + + try { + len = fp.length(); + } catch (IOException e) { + } + ; + + Globals.cls.download = fp; + + // give the server an offset to start the download + Com.Printf("Resuming " + Globals.cls.downloadname + "\n"); + MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_stringcmd); + MSG.WriteString(Globals.cls.netchan.message, "download " + + Globals.cls.downloadname + " " + len); + } else { + Globals.cls.downloadname = Globals.cls.downloadname; + + Com.Printf("Downloading " + Globals.cls.downloadname + "\n"); + MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_stringcmd); + MSG.WriteString(Globals.cls.netchan.message, "download " + + Globals.cls.downloadname); + } + + Globals.cls.downloadnumber++; + + return false; + } + + /* + * =============== CL_Download_f + * + * Request a download from the server =============== + */ + public static xcommand_t Download_f = new xcommand_t() { + public void execute() { + String filename; + + if (Cmd.Argc() != 2) { + Com.Printf("Usage: download <filename>\n"); + return; + } + + filename = Cmd.Argv(1); + + if (filename.indexOf("..") != -1) { + Com.Printf("Refusing to download a path with ..\n"); + return; + } + + if (FS.LoadFile(filename) != null) { // it exists, no need to + // download + Com.Printf("File already exists.\n"); + return; + } + + Globals.cls.downloadname = filename; + Com.Printf("Downloading " + Globals.cls.downloadname + "\n"); + + // download to a temp name, and only rename + // to the real name when done, so if interrupted + // a runt file wont be left + Globals.cls.downloadtempname = Com + .StripExtension(Globals.cls.downloadname); + Globals.cls.downloadtempname += ".tmp"; + + MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_stringcmd); + MSG.WriteString(Globals.cls.netchan.message, "download " + + Globals.cls.downloadname); + + Globals.cls.downloadnumber++; + } + }; + + /* + * ====================== CL_RegisterSounds ====================== + */ + public static void RegisterSounds() { + S.BeginRegistration(); + CL_tent.RegisterTEntSounds(); + for (int i = 1; i < Defines.MAX_SOUNDS; i++) { + if (Globals.cl.configstrings[Defines.CS_SOUNDS + i] == null + || Globals.cl.configstrings[Defines.CS_SOUNDS + i] + .equals("") + || Globals.cl.configstrings[Defines.CS_SOUNDS + i] + .equals("\0")) + break; + Globals.cl.sound_precache[i] = S + .RegisterSound(Globals.cl.configstrings[Defines.CS_SOUNDS + + i]); + Sys.SendKeyEvents(); // pump message loop + } + S.EndRegistration(); + } + + /* + * ===================== CL_ParseDownload + * + * A download message has been received from the server + * ===================== + */ + public static void ParseDownload() { + + // read the data + int size = MSG.ReadShort(Globals.net_message); + int percent = MSG.ReadByte(Globals.net_message); + if (size == -1) { + Com.Printf("Server does not have this file.\n"); + if (Globals.cls.download != null) { + // if here, we tried to resume a file but the server said no + try { + Globals.cls.download.close(); + } catch (IOException e) { + } + Globals.cls.download = null; + } + CL.RequestNextDownload(); + return; + } + + // open the file if not opened yet + if (Globals.cls.download == null) { + String name = DownloadFileName(Globals.cls.downloadtempname); + + FS.CreatePath(name); + + Globals.cls.download = Lib.fopen(name, "rw"); + if (Globals.cls.download == null) { + Globals.net_message.readcount += size; + Com.Printf("Failed to open " + Globals.cls.downloadtempname + + "\n"); + CL.RequestNextDownload(); + return; + } + } + + //fwrite(net_message.data[net_message.readcount], 1, size, + // cls.download); + try { + Globals.cls.download.write(Globals.net_message.data, + Globals.net_message.readcount, size); + } catch (Exception e) { + } + Globals.net_message.readcount += size; + + if (percent != 100) { + // request next block + // change display routines by zoid + + MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_stringcmd); + SZ.Print(Globals.cls.netchan.message, "nextdl"); + } else { + String oldn, newn; + //char oldn[MAX_OSPATH]; + //char newn[MAX_OSPATH]; + + // Com.Printf ("100%%\n"); + + try { + Globals.cls.download.close(); + } catch (IOException e) { + } + + // rename the temp file to it's final name + oldn = DownloadFileName(Globals.cls.downloadtempname); + newn = DownloadFileName(Globals.cls.downloadname); + int r = Lib.rename(oldn, newn); + if (r != 0) + Com.Printf("failed to rename.\n"); + + Globals.cls.download = null; + Globals.cls.downloadpercent = 0; + + // get another file if needed + + CL.RequestNextDownload(); + } + } + + /* + * ===================================================================== + * + * SERVER CONNECTING MESSAGES + * + * ===================================================================== + */ + + /* + * ================== CL_ParseServerData ================== + */ + //checked once, was ok. + public static void ParseServerData() { + + String str; + int i; + + Com.DPrintf("Serverdata packet received.\n"); + // + // wipe the client_state_t struct + // + CL.ClearState(); + Globals.cls.state = Defines.ca_connected; + + // parse protocol version number + i = MSG.ReadLong(Globals.net_message); + Globals.cls.serverProtocol = i; + + // BIG HACK to let demos from release work with the 3.0x patch!!! + if (Globals.server_state != 0 && Defines.PROTOCOL_VERSION == 34) { + } else if (i != Defines.PROTOCOL_VERSION) + Com.Error(Defines.ERR_DROP, "Server returned version " + i + + ", not " + Defines.PROTOCOL_VERSION); + + Globals.cl.servercount = MSG.ReadLong(Globals.net_message); + Globals.cl.attractloop = MSG.ReadByte(Globals.net_message) != 0; + + // game directory + str = MSG.ReadString(Globals.net_message); + Globals.cl.gamedir = str; + + // set gamedir + if (str.length() > 0 + && (FS.fs_gamedirvar.string == null + || FS.fs_gamedirvar.string.length() == 0 || FS.fs_gamedirvar.string + .equals(str)) + || (str.length() == 0 && (FS.fs_gamedirvar.string != null || FS.fs_gamedirvar.string + .length() == 0))) + Cvar.Set("game", str); + + // parse player entity number + Globals.cl.playernum = MSG.ReadShort(Globals.net_message); + + // get the full level name + str = MSG.ReadString(Globals.net_message); + + if (Globals.cl.playernum == -1) { // playing a cinematic or showing a + // pic, not a level + SCR.PlayCinematic(str); + } else { + // seperate the printfs so the server message can have a color + // Com.Printf( + // "\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); + // Com.Printf('\02' + str + "\n"); + Com.Printf("Levelname:" + str + "\n"); + // need to prep refresh at next oportunity + Globals.cl.refresh_prepped = false; + } + } + + /* + * ================== CL_ParseBaseline ================== + */ + public static void ParseBaseline() { + entity_state_t es; + int newnum; + + entity_state_t nullstate = new entity_state_t(null); + //memset(nullstate, 0, sizeof(nullstate)); + int bits[] = { 0 }; + newnum = CL_ents.ParseEntityBits(bits); + es = Globals.cl_entities[newnum].baseline; + CL_ents.ParseDelta(nullstate, es, newnum, bits[0]); + } + + /* + * ================ CL_LoadClientinfo + * + * ================ + */ + public static void LoadClientinfo(clientinfo_t ci, String s) { + int i; + int t; + + //char model_name[MAX_QPATH]; + //char skin_name[MAX_QPATH]; + //char model_filename[MAX_QPATH]; + //char skin_filename[MAX_QPATH]; + //char weapon_filename[MAX_QPATH]; + + String model_name, skin_name, model_filename, skin_filename, weapon_filename; + + ci.cinfo = s; + //ci.cinfo[sizeof(ci.cinfo) - 1] = 0; + + // isolate the player's name + ci.name = s; + //ci.name[sizeof(ci.name) - 1] = 0; + + t = s.indexOf('\\'); + //t = strstr(s, "\\"); + + if (t != -1) { + ci.name = s.substring(0, t); + s = s.substring(t + 1, s.length()); + //s = t + 1; + } + + if (Globals.cl_noskins.value != 0 || s.length() != 0) { + + model_filename = ("players/male/tris.md2"); + weapon_filename = ("players/male/weapon.md2"); + skin_filename = ("players/male/grunt.pcx"); + ci.iconname = ("/players/male/grunt_i.pcx"); + + ci.model = Globals.re.RegisterModel(model_filename); + + ci.weaponmodel = new model_t[Defines.MAX_CLIENTWEAPONMODELS]; + ci.weaponmodel[0] = Globals.re.RegisterModel(weapon_filename); + ci.skin = Globals.re.RegisterSkin(skin_filename); + ci.icon = Globals.re.RegisterPic(ci.iconname); + } else { + // isolate the model name + + int pos = s.indexOf('/'); + + if (pos == -1) + pos = s.indexOf('/'); + if (pos == -1) { + pos = 0; + Com.Error(Defines.ERR_FATAL, "Invalid model name:" + s); + } + + model_name = s.substring(0, pos); + + // isolate the skin name + skin_name = s.substring(pos + 1, s.length()); + + // model file + model_filename = "players/" + model_name + "/tris.md2"; + ci.model = Globals.re.RegisterModel(model_filename); + + if (ci.model == null) { + model_name = "male"; + model_filename = "players/male/tris.md2"; + ci.model = Globals.re.RegisterModel(model_filename); + } + + // skin file + skin_filename = "players/" + model_name + "/" + skin_name + ".pcx"; + ci.skin = Globals.re.RegisterSkin(skin_filename); + + // if we don't have the skin and the model wasn't male, + // see if the male has it (this is for CTF's skins) + if (ci.skin == null && !model_name.equalsIgnoreCase("male")) { + // change model to male + model_name = "male"; + model_filename = "players/male/tris.md2"; + ci.model = Globals.re.RegisterModel(model_filename); + + // see if the skin exists for the male model + skin_filename = "players/" + model_name + "/" + skin_name + + ".pcx"; + ci.skin = Globals.re.RegisterSkin(skin_filename); + } + + // if we still don't have a skin, it means that the male model + // didn't have + // it, so default to grunt + if (ci.skin == null) { + // see if the skin exists for the male model + skin_filename = "players/" + model_name + "/grunt.pcx"; + ci.skin = Globals.re.RegisterSkin(skin_filename); + } + + // weapon file + for (i = 0; i < CL_view.num_cl_weaponmodels; i++) { + weapon_filename = "players/" + model_name + "/" + + CL_view.cl_weaponmodels[i]; + ci.weaponmodel[i] = Globals.re.RegisterModel(weapon_filename); + if (null == ci.weaponmodel[i] && model_name.equals("cyborg")) { + // try male + weapon_filename = "players/male/" + + CL_view.cl_weaponmodels[i]; + ci.weaponmodel[i] = Globals.re + .RegisterModel(weapon_filename); + } + if (0 == Globals.cl_vwep.value) + break; // only one when vwep is off + } + + // icon file + ci.iconname = "/players/" + model_name + "/" + skin_name + "_i.pcx"; + ci.icon = Globals.re.RegisterPic(ci.iconname); + } + + // must have loaded all data types to be valud + if (ci.skin == null || ci.icon == null || ci.model == null + || ci.weaponmodel[0] == null) { + ci.skin = null; + ci.icon = null; + ci.model = null; + ci.weaponmodel[0] = null; + return; + } + } + + /* + * ================ CL_ParseClientinfo + * + * Load the skin, icon, and model for a client ================ + */ + public static void ParseClientinfo(int player) { + String s; + clientinfo_t ci; + + s = Globals.cl.configstrings[player + Defines.CS_PLAYERSKINS]; + + ci = Globals.cl.clientinfo[player]; + + LoadClientinfo(ci, s); + } + + /* + * ================ CL_ParseConfigString ================ + */ + public static void ParseConfigString() { + int i; + String s; + String olds; + + i = MSG.ReadShort(Globals.net_message); + + if (i < 0 || i >= Defines.MAX_CONFIGSTRINGS) + Com.Error(Defines.ERR_DROP, "configstring > MAX_CONFIGSTRINGS"); + + s = MSG.ReadString(Globals.net_message); + + olds = Globals.cl.configstrings[i]; + Globals.cl.configstrings[i] = s; + + // do something apropriate + + if (i >= Defines.CS_LIGHTS + && i < Defines.CS_LIGHTS + Defines.MAX_LIGHTSTYLES) { + CL_fx.SetLightstyle(i - Defines.CS_LIGHTS); + } else if (i >= Defines.CS_MODELS + && i < Defines.CS_MODELS + Defines.MAX_MODELS) { + if (Globals.cl.refresh_prepped) { + Globals.cl.model_draw[i - Defines.CS_MODELS] = Globals.re + .RegisterModel(Globals.cl.configstrings[i]); + if (Globals.cl.configstrings[i].startsWith("*")) + Globals.cl.model_clip[i - Defines.CS_MODELS] = CM + .InlineModel(Globals.cl.configstrings[i]); + else + Globals.cl.model_clip[i - Defines.CS_MODELS] = null; + } + } else if (i >= Defines.CS_SOUNDS + && i < Defines.CS_SOUNDS + Defines.MAX_MODELS) { + if (Globals.cl.refresh_prepped) + Globals.cl.sound_precache[i - Defines.CS_SOUNDS] = S + .RegisterSound(Globals.cl.configstrings[i]); + } else if (i >= Defines.CS_IMAGES + && i < Defines.CS_IMAGES + Defines.MAX_MODELS) { + if (Globals.cl.refresh_prepped) + Globals.cl.image_precache[i - Defines.CS_IMAGES] = Globals.re + .RegisterPic(Globals.cl.configstrings[i]); + } else if (i >= Defines.CS_PLAYERSKINS + && i < Defines.CS_PLAYERSKINS + Defines.MAX_CLIENTS) { + if (Globals.cl.refresh_prepped && !olds.equals(s)) + ParseClientinfo(i - Defines.CS_PLAYERSKINS); + } + } + + /* + * ===================================================================== + * + * ACTION MESSAGES + * + * ===================================================================== + */ + + /* + * ================== CL_ParseStartSoundPacket ================== + */ + public static void ParseStartSoundPacket() { + float[] pos_v = { 0, 0, 0 }; + float pos[]; + int channel, ent; + int sound_num; + float volume; + float attenuation; + int flags; + float ofs; + + flags = MSG.ReadByte(Globals.net_message); + sound_num = MSG.ReadByte(Globals.net_message); + + if ((flags & Defines.SND_VOLUME) != 0) + volume = MSG.ReadByte(Globals.net_message) / 255.0f; + else + volume = Defines.DEFAULT_SOUND_PACKET_VOLUME; + + if ((flags & Defines.SND_ATTENUATION) != 0) + attenuation = MSG.ReadByte(Globals.net_message) / 64.0f; + else + attenuation = Defines.DEFAULT_SOUND_PACKET_ATTENUATION; + + if ((flags & Defines.SND_OFFSET) != 0) + ofs = MSG.ReadByte(Globals.net_message) / 1000.0f; + else + ofs = 0; + + if ((flags & Defines.SND_ENT) != 0) { // entity reletive + channel = MSG.ReadShort(Globals.net_message); + ent = channel >> 3; + if (ent > Defines.MAX_EDICTS) + Com.Error(Defines.ERR_DROP, "CL_ParseStartSoundPacket: ent = " + + ent); + + channel &= 7; + } else { + ent = 0; + channel = 0; + } + + if ((flags & Defines.SND_POS) != 0) { // positioned in space + MSG.ReadPos(Globals.net_message, pos_v); + + pos = pos_v; + } else + // use entity number + pos = null; + + if (null == Globals.cl.sound_precache[sound_num]) + return; + + S.StartSound(pos, ent, channel, Globals.cl.sound_precache[sound_num], + volume, attenuation, ofs); + } + + public static void SHOWNET(String s) { + if (Globals.cl_shownet.value >= 2) + Com.Printf(Globals.net_message.readcount - 1 + ":" + s + "\n"); + } + + /* + * ===================== CL_ParseServerMessage ===================== + */ + public static void ParseServerMessage() { + int cmd; + String s; + int i; + + // + // if recording demos, copy the message out + // + //if (cl_shownet.value == 1) + //Com.Printf(net_message.cursize + " "); + //else if (cl_shownet.value >= 2) + //Com.Printf("------------------\n"); + + // + // parse the message + // + while (true) { + if (Globals.net_message.readcount > Globals.net_message.cursize) { + Com.Error(Defines.ERR_FATAL, + "CL_ParseServerMessage: Bad server message:"); + break; + } + + cmd = MSG.ReadByte(Globals.net_message); + + if (cmd == -1) { + SHOWNET("END OF MESSAGE"); + break; + } + + if (Globals.cl_shownet.value >= 2) { + if (null == svc_strings[cmd]) + Com.Printf(Globals.net_message.readcount - 1 + ":BAD CMD " + + cmd + "\n"); + else + SHOWNET(svc_strings[cmd]); + } + + // other commands + switch (cmd) { + default: + Com.Error(Defines.ERR_DROP, + "CL_ParseServerMessage: Illegible server message\n"); + break; + + case Defines.svc_nop: + // Com.Printf ("svc_nop\n"); + break; + + case Defines.svc_disconnect: + Com.Error(Defines.ERR_DISCONNECT, "Server disconnected\n"); + break; + + case Defines.svc_reconnect: + Com.Printf("Server disconnected, reconnecting\n"); + if (Globals.cls.download != null) { + //ZOID, close download + try { + Globals.cls.download.close(); + } catch (IOException e) { + } + Globals.cls.download = null; + } + Globals.cls.state = Defines.ca_connecting; + Globals.cls.connect_time = -99999; // CL_CheckForResend() will + // fire immediately + break; + + case Defines.svc_print: + i = MSG.ReadByte(Globals.net_message); + if (i == Defines.PRINT_CHAT) { + S.StartLocalSound("misc/talk.wav"); + Globals.con.ormask = 128; + } + Com.Printf(MSG.ReadString(Globals.net_message)); + Globals.con.ormask = 0; + break; + + case Defines.svc_centerprint: + SCR.CenterPrint(MSG.ReadString(Globals.net_message)); + break; + + case Defines.svc_stufftext: + s = MSG.ReadString(Globals.net_message); + Com.DPrintf("stufftext: " + s + "\n"); + Cbuf.AddText(s); + break; + + case Defines.svc_serverdata: + Cbuf.Execute(); // make sure any stuffed commands are done + ParseServerData(); + break; + + case Defines.svc_configstring: + ParseConfigString(); + break; + + case Defines.svc_sound: + ParseStartSoundPacket(); + break; + + case Defines.svc_spawnbaseline: + ParseBaseline(); + break; + + case Defines.svc_temp_entity: + CL_tent.ParseTEnt(); + break; + + case Defines.svc_muzzleflash: + CL_fx.ParseMuzzleFlash(); + break; + + case Defines.svc_muzzleflash2: + CL_fx.ParseMuzzleFlash2(); + break; + + case Defines.svc_download: + ParseDownload(); + break; + + case Defines.svc_frame: + CL_ents.ParseFrame(); + break; + + case Defines.svc_inventory: + CL_inv.ParseInventory(); + break; + + case Defines.svc_layout: + s = MSG.ReadString(Globals.net_message); + Globals.cl.layout = s; + break; + + case Defines.svc_playerinfo: + case Defines.svc_packetentities: + case Defines.svc_deltapacketentities: + Com.Error(Defines.ERR_DROP, "Out of place frame data"); + break; + } + } + + CL_view.AddNetgraph(); + + // + // we don't know if it is ok to save a demo message until + // after we have parsed the frame + // + if (Globals.cls.demorecording && !Globals.cls.demowaiting) + CL.WriteDemoMessage(); + } +}
\ No newline at end of file diff --git a/src/jake2/client/CL_pred.java b/src/jake2/client/CL_pred.java index 7f6a279..4b07099 100644 --- a/src/jake2/client/CL_pred.java +++ b/src/jake2/client/CL_pred.java @@ -2,286 +2,302 @@ * CL_pred.java * Copyright (C) 2004 * - * $Id: CL_pred.java,v 1.4 2004-07-19 19:20:22 hzi Exp $ + * $Id: CL_pred.java,v 1.5 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; +import jake2.Defines; +import jake2.Globals; +import jake2.Defines; +import jake2.game.pmove_t.PointContentsAdapter; +import jake2.game.pmove_t.TraceAdapter; + +import jake2.Globals; import jake2.game.*; import jake2.qcommon.*; +import jake2.util.Math3D; /** * CL_pred */ -public class CL_pred extends CL_parse { - - /* - =================== - CL_CheckPredictionError - =================== - */ - static void CheckPredictionError() { - int frame; - int[] delta = new int[3]; - int i; - int len; - - if (cl_predict.value == 0.0f || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION) != 0) - return; - - // calculate the last usercmd_t we sent that the server has processed - frame = cls.netchan.incoming_acknowledged; - frame &= (CMD_BACKUP - 1); - - // compare what the server returned with what we had predicted it to be - VectorSubtract(cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame], delta); - - // save the prediction error for interpolation - len = Math.abs(delta[0]) + Math.abs(delta[1]) + Math.abs(delta[2]); - if (len > 640) // 80 world units - { // a teleport or something - VectorClear(cl.prediction_error); - } - else { - if (cl_showmiss.value != 0.0f && (delta[0] != 0 || delta[1] != 0 || delta[2] != 0)) - Com.Printf("prediction miss on " + cl.frame.serverframe + ": " + (delta[0] + delta[1] + delta[2]) + "\n"); - - VectorCopy(cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame]); - - // save for error itnerpolation - for (i = 0; i < 3; i++) - cl.prediction_error[i] = delta[i] * 0.125f; - } - } - - /* - ==================== - CL_ClipMoveToEntities - - ==================== - */ - static void ClipMoveToEntities(float[] start, float[] mins, float[] maxs, float[] end, trace_t tr) { - int i, x, zd, zu; - trace_t trace; - int headnode; - float[] angles; - entity_state_t ent; - int num; - cmodel_t cmodel; - float[] bmins = new float[3]; - float[] bmaxs = new float[3]; - - for (i = 0; i < cl.frame.num_entities; i++) { - num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1); - ent = cl_parse_entities[num]; - - if (ent.solid == 0) - continue; - - if (ent.number == cl.playernum + 1) - continue; - - if (ent.solid == 31) { // special value for bmodel - cmodel = cl.model_clip[ent.modelindex]; - if (cmodel == null) - continue; - headnode = cmodel.headnode; - angles = ent.angles; - } - else { // encoded bbox - x = 8 * (ent.solid & 31); - zd = 8 * ((ent.solid >>> 5) & 31); - zu = 8 * ((ent.solid >>> 10) & 63) - 32; - - bmins[0] = bmins[1] = -x; - bmaxs[0] = bmaxs[1] = x; - bmins[2] = -zd; - bmaxs[2] = zu; - - headnode = CM.HeadnodeForBox(bmins, bmaxs); - angles = vec3_origin; // boxes don't rotate - } - - if (tr.allsolid) - return; - - trace = CM.TransformedBoxTrace(start, end, mins, maxs, headnode, MASK_PLAYERSOLID, ent.origin, angles); - - if (trace.allsolid || trace.startsolid || trace.fraction < tr.fraction) { - trace.ent = ent.surrounding_ent; - if (tr.startsolid) { - tr.set(trace); // rst: solved the Z U P P E L - P R O B L E M - tr.startsolid = true; - } - else - tr.set(trace); // rst: solved the Z U P P E L - P R O B L E M - } - else if (trace.startsolid) - tr.startsolid = true; - } - } - - /* - ================ - CL_PMTrace - ================ - */ - - public static edict_t DUMMY_ENT = new edict_t(-1); - - static trace_t PMTrace(float[] start, float[] mins, float[] maxs, float[] end) { - trace_t t; - - // check against world - t = CM.BoxTrace(start, end, mins, maxs, 0, MASK_PLAYERSOLID); - - if (t.fraction < 1.0f) { - t.ent = DUMMY_ENT; - } - - // check all other solid models - CL.ClipMoveToEntities(start, mins, maxs, end, t); - - return t; - } - - /* - ================= - PMpointcontents - - Returns the content identificator of the point. - ================= - */ - static int PMpointcontents(float[] point) { - int i; - entity_state_t ent; - int num; - cmodel_t cmodel; - int contents; - - contents = CM.PointContents(point, 0); - - for (i = 0; i < cl.frame.num_entities; i++) { - num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1); - ent = cl_parse_entities[num]; - - if (ent.solid != 31) // special value for bmodel - continue; - - cmodel = cl.model_clip[ent.modelindex]; - if (cmodel == null) - continue; - - contents |= CM.TransformedPointContents(point, cmodel.headnode, ent.origin, ent.angles); - } - return contents; - } - - /* - ================= - CL_PredictMovement - - Sets cl.predicted_origin and cl.predicted_angles - ================= - */ - static void PredictMovement() { - - if (cls.state != ca_active) - return; - - if (cl_paused.value != 0.0f) - return; - - if (cl_predict.value == 0.0f || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION) != 0) { - // just set angles - for (int i = 0; i < 3; i++) { - cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]); - } - return; - } - - int ack = cls.netchan.incoming_acknowledged; - int current = cls.netchan.outgoing_sequence; - - // if we are too far out of date, just freeze - if (current - ack >= CMD_BACKUP) { - if (cl_showmiss.value != 0.0f) - Com.Printf("exceeded CMD_BACKUP\n"); - return; - } - - // copy current state to pmove - //memset (pm, 0, sizeof(pm)); - pmove_t pm = new pmove_t(); - - pm.trace = new pmove_t.TraceAdapter() { - public trace_t trace(float[] start, float[] mins, float[] maxs, float[] end) { - return CL.PMTrace(start, mins, maxs, end); - } - }; - pm.pointcontents = new pmove_t.PointContentsAdapter() { - public int pointcontents(float[] point) { - return CL.PMpointcontents(point); - } - }; - - try { - PMove.pm_airaccelerate = Float.parseFloat(cl.configstrings[CS_AIRACCEL]); - } catch (Exception e) { - PMove.pm_airaccelerate = 0; - } - - // bugfix (rst) yeah !!!!!!!! found the solution to the B E W E G U N G S P R O B L E M. - pm.s.set(cl.frame.playerstate.pmove); - - // SCR_DebugGraph (current - ack - 1, 0); - int frame = 0; - - // run frames - usercmd_t cmd; - while (++ack < current) { - frame = ack & (CMD_BACKUP - 1); - cmd = cl.cmds[frame]; - - pm.cmd.set(cmd); - - PMove.Pmove(pm); - - // save for debug checking - VectorCopy(pm.s.origin, cl.predicted_origins[frame]); - } - - int oldframe = (ack - 2) & (CMD_BACKUP - 1); - int oldz = cl.predicted_origins[oldframe][2]; - int step = pm.s.origin[2] - oldz; - if (step > 63 && step < 160 && (pm.s.pm_flags & PMF_ON_GROUND) != 0) { - cl.predicted_step = step * 0.125f; - cl.predicted_step_time = (int) (cls.realtime - cls.frametime * 500); - } - - // copy results out for rendering - cl.predicted_origin[0] = pm.s.origin[0] * 0.125f; - cl.predicted_origin[1] = pm.s.origin[1] * 0.125f; - cl.predicted_origin[2] = pm.s.origin[2] * 0.125f; - - VectorCopy(pm.viewangles, cl.predicted_angles); - } -} +public class CL_pred { + + /* + * =================== CL_CheckPredictionError =================== + */ + static void CheckPredictionError() { + int frame; + int[] delta = new int[3]; + int i; + int len; + + if (Globals.cl_predict.value == 0.0f + || (Globals.cl.frame.playerstate.pmove.pm_flags & pmove_t.PMF_NO_PREDICTION) != 0) + return; + + // calculate the last usercmd_t we sent that the server has processed + frame = Globals.cls.netchan.incoming_acknowledged; + frame &= (Defines.CMD_BACKUP - 1); + + // compare what the server returned with what we had predicted it to be + Math3D.VectorSubtract(Globals.cl.frame.playerstate.pmove.origin, + Globals.cl.predicted_origins[frame], delta); + + // save the prediction error for interpolation + len = Math.abs(delta[0]) + Math.abs(delta[1]) + Math.abs(delta[2]); + if (len > 640) // 80 world units + { // a teleport or something + Math3D.VectorClear(Globals.cl.prediction_error); + } else { + if (Globals.cl_showmiss.value != 0.0f + && (delta[0] != 0 || delta[1] != 0 || delta[2] != 0)) + Com.Printf("prediction miss on " + Globals.cl.frame.serverframe + + ": " + (delta[0] + delta[1] + delta[2]) + "\n"); + + Math3D.VectorCopy(Globals.cl.frame.playerstate.pmove.origin, + Globals.cl.predicted_origins[frame]); + + // save for error itnerpolation + for (i = 0; i < 3; i++) + Globals.cl.prediction_error[i] = delta[i] * 0.125f; + } + } + + /* + * ==================== CL_ClipMoveToEntities + * + * ==================== + */ + static void ClipMoveToEntities(float[] start, float[] mins, float[] maxs, + float[] end, trace_t tr) { + int i, x, zd, zu; + trace_t trace; + int headnode; + float[] angles; + entity_state_t ent; + int num; + cmodel_t cmodel; + float[] bmins = new float[3]; + float[] bmaxs = new float[3]; + + for (i = 0; i < Globals.cl.frame.num_entities; i++) { + num = (Globals.cl.frame.parse_entities + i) + & (Defines.MAX_PARSE_ENTITIES - 1); + ent = Globals.cl_parse_entities[num]; + + if (ent.solid == 0) + continue; + + if (ent.number == Globals.cl.playernum + 1) + continue; + + if (ent.solid == 31) { // special value for bmodel + cmodel = Globals.cl.model_clip[ent.modelindex]; + if (cmodel == null) + continue; + headnode = cmodel.headnode; + angles = ent.angles; + } else { // encoded bbox + x = 8 * (ent.solid & 31); + zd = 8 * ((ent.solid >>> 5) & 31); + zu = 8 * ((ent.solid >>> 10) & 63) - 32; + + bmins[0] = bmins[1] = -x; + bmaxs[0] = bmaxs[1] = x; + bmins[2] = -zd; + bmaxs[2] = zu; + + headnode = CM.HeadnodeForBox(bmins, bmaxs); + angles = Globals.vec3_origin; // boxes don't rotate + } + + if (tr.allsolid) + return; + + trace = CM.TransformedBoxTrace(start, end, mins, maxs, headnode, + Defines.MASK_PLAYERSOLID, ent.origin, angles); + + if (trace.allsolid || trace.startsolid + || trace.fraction < tr.fraction) { + trace.ent = ent.surrounding_ent; + if (tr.startsolid) { + tr.set(trace); // rst: solved the Z U P P E L - P R O B L E + // M + tr.startsolid = true; + } else + tr.set(trace); // rst: solved the Z U P P E L - P R O B L E + // M + } else if (trace.startsolid) + tr.startsolid = true; + } + } + + /* + * ================ CL_PMTrace ================ + */ + + public static edict_t DUMMY_ENT = new edict_t(-1); + + static trace_t PMTrace(float[] start, float[] mins, float[] maxs, + float[] end) { + trace_t t; + + // check against world + t = CM.BoxTrace(start, end, mins, maxs, 0, Defines.MASK_PLAYERSOLID); + + if (t.fraction < 1.0f) { + t.ent = DUMMY_ENT; + } + + // check all other solid models + ClipMoveToEntities(start, mins, maxs, end, t); + + return t; + } + + /* + * ================= PMpointcontents + * + * Returns the content identificator of the point. ================= + */ + static int PMpointcontents(float[] point) { + int i; + entity_state_t ent; + int num; + cmodel_t cmodel; + int contents; + + contents = CM.PointContents(point, 0); + + for (i = 0; i < Globals.cl.frame.num_entities; i++) { + num = (Globals.cl.frame.parse_entities + i) + & (Defines.MAX_PARSE_ENTITIES - 1); + ent = Globals.cl_parse_entities[num]; + + if (ent.solid != 31) // special value for bmodel + continue; + + cmodel = Globals.cl.model_clip[ent.modelindex]; + if (cmodel == null) + continue; + + contents |= CM.TransformedPointContents(point, cmodel.headnode, + ent.origin, ent.angles); + } + return contents; + } + + /* + * ================= CL_PredictMovement + * + * Sets cl.predicted_origin and cl.predicted_angles ================= + */ + static void PredictMovement() { + + if (Globals.cls.state != Defines.ca_active) + return; + + if (Globals.cl_paused.value != 0.0f) + return; + + if (Globals.cl_predict.value == 0.0f + || (Globals.cl.frame.playerstate.pmove.pm_flags & pmove_t.PMF_NO_PREDICTION) != 0) { + // just set angles + for (int i = 0; i < 3; i++) { + Globals.cl.predicted_angles[i] = Globals.cl.viewangles[i] + + Math3D + .SHORT2ANGLE(Globals.cl.frame.playerstate.pmove.delta_angles[i]); + } + return; + } + + int ack = Globals.cls.netchan.incoming_acknowledged; + int current = Globals.cls.netchan.outgoing_sequence; + + // if we are too far out of date, just freeze + if (current - ack >= Defines.CMD_BACKUP) { + if (Globals.cl_showmiss.value != 0.0f) + Com.Printf("exceeded CMD_BACKUP\n"); + return; + } + + // copy current state to pmove + //memset (pm, 0, sizeof(pm)); + pmove_t pm = new pmove_t(); + + pm.trace = new pmove_t.TraceAdapter() { + public trace_t trace(float[] start, float[] mins, float[] maxs, + float[] end) { + return PMTrace(start, mins, maxs, end); + } + }; + pm.pointcontents = new pmove_t.PointContentsAdapter() { + public int pointcontents(float[] point) { + return PMpointcontents(point); + } + }; + + try { + PMove.pm_airaccelerate = Float + .parseFloat(Globals.cl.configstrings[Defines.CS_AIRACCEL]); + } catch (Exception e) { + PMove.pm_airaccelerate = 0; + } + + // bugfix (rst) yeah !!!!!!!! found the solution to the B E W E G U N G + // S P R O B L E M. + pm.s.set(Globals.cl.frame.playerstate.pmove); + + // SCR_DebugGraph (current - ack - 1, 0); + int frame = 0; + + // run frames + usercmd_t cmd; + while (++ack < current) { + frame = ack & (Defines.CMD_BACKUP - 1); + cmd = Globals.cl.cmds[frame]; + + pm.cmd.set(cmd); + + PMove.Pmove(pm); + + // save for debug checking + Math3D.VectorCopy(pm.s.origin, Globals.cl.predicted_origins[frame]); + } + + int oldframe = (ack - 2) & (Defines.CMD_BACKUP - 1); + int oldz = Globals.cl.predicted_origins[oldframe][2]; + int step = pm.s.origin[2] - oldz; + if (step > 63 && step < 160 + && (pm.s.pm_flags & pmove_t.PMF_ON_GROUND) != 0) { + Globals.cl.predicted_step = step * 0.125f; + Globals.cl.predicted_step_time = (int) (Globals.cls.realtime - Globals.cls.frametime * 500); + } + + // copy results out for rendering + Globals.cl.predicted_origin[0] = pm.s.origin[0] * 0.125f; + Globals.cl.predicted_origin[1] = pm.s.origin[1] * 0.125f; + Globals.cl.predicted_origin[2] = pm.s.origin[2] * 0.125f; + + Math3D.VectorCopy(pm.viewangles, Globals.cl.predicted_angles); + } +}
\ No newline at end of file diff --git a/src/jake2/client/CL_tent.java b/src/jake2/client/CL_tent.java index bca8edf..132fa4a 100644 --- a/src/jake2/client/CL_tent.java +++ b/src/jake2/client/CL_tent.java @@ -1,1722 +1,1804 @@ /* - * CL_tent.java + * java * Copyright (C) 2004 * - * $Id: CL_tent.java,v 1.4 2004-07-09 10:19:57 hzi Exp $ + * $Id: CL_tent.java,v 1.5 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; +import jake2.Defines; import jake2.Globals; +import jake2.client.cl_sustain_t.ThinkAdapter; import jake2.game.player_state_t; import jake2.qcommon.Com; import jake2.qcommon.MSG; import jake2.render.model_t; import jake2.sound.*; +import jake2.util.Lib; +import jake2.util.Math3D; /** * CL_tent */ -public class CL_tent extends Globals { - - static final int ex_free = 0; - static final int ex_explosion = 1; - static final int ex_misc = 2; - static final int ex_flash = 3; - static final int ex_mflash = 4; - static final int ex_poly = 5; - static final int ex_poly2 = 6; - - - static class explosion_t { - int type; - entity_t ent = new entity_t(); - - int frames; - float light; - float[] lightcolor = new float[3]; - float start; - int baseframe; - void clear() { - lightcolor[0] = lightcolor[1] = lightcolor[2] = - light = start = type = frames = baseframe = 0; - ent = new entity_t(); - } - } - - static final int MAX_EXPLOSIONS = 32; - static explosion_t[] cl_explosions = new explosion_t[MAX_EXPLOSIONS]; - static { - for (int i = 0; i < cl_explosions.length; i++) - cl_explosions[i] = new explosion_t(); - } - - static final int MAX_BEAMS = 32; - - static class beam_t { - int entity; - int dest_entity; - model_t model; - int endtime; - float[] offset = new float[3]; - float[] start = new float[3]; - float[] end = new float[3]; - void clear() { - offset[0] = offset[1] = offset[2] = - start[0] = start[1] = start[2] = - end[0] = end[1] = end[2] = - entity = dest_entity = endtime = 0; - model = null; - } - } - static beam_t[] cl_beams = new beam_t[MAX_BEAMS]; - // PMM - added this for player-linked beams. Currently only used by the plasma beam - static beam_t[] cl_playerbeams = new beam_t[MAX_BEAMS]; - static { - for (int i = 0; i < cl_beams.length; i++) - cl_beams[i] = new beam_t(); - for (int i = 0; i < cl_playerbeams.length; i++) - cl_playerbeams[i] = new beam_t(); - } - - static final int MAX_LASERS = 32; - - static class laser_t { - entity_t ent = new entity_t(); - int endtime; - void clear() { - endtime = 0; - ent = new entity_t(); - } - } - static laser_t[] cl_lasers = new laser_t[MAX_LASERS]; - static { - for (int i = 0; i < cl_lasers.length; i++) - cl_lasers[i] = new laser_t(); - } - -// ROGUE - static final int MAX_SUSTAINS = 32; - static cl_sustain_t[] cl_sustains = new cl_sustain_t[MAX_SUSTAINS]; - static { - for (int i = 0; i < cl_sustains.length; i++) - cl_sustains[i] = new cl_sustain_t(); - } -// ROGUE - - // all are references; - static sfx_t cl_sfx_ric1; - static sfx_t cl_sfx_ric2; - static sfx_t cl_sfx_ric3; - static sfx_t cl_sfx_lashit; - static sfx_t cl_sfx_spark5; - static sfx_t cl_sfx_spark6; - static sfx_t cl_sfx_spark7; - static sfx_t cl_sfx_railg; - static sfx_t cl_sfx_rockexp; - static sfx_t cl_sfx_grenexp; - static sfx_t cl_sfx_watrexp; - // RAFAEL - static sfx_t cl_sfx_plasexp; - static sfx_t cl_sfx_footsteps[] = new sfx_t[4]; - - static model_t cl_mod_explode; - static model_t cl_mod_smoke; - static model_t cl_mod_flash; - static model_t cl_mod_parasite_segment; - static model_t cl_mod_grapple_cable; - static model_t cl_mod_parasite_tip; - static model_t cl_mod_explo4; - static model_t cl_mod_bfg_explo; - static model_t cl_mod_powerscreen; - // RAFAEL - static model_t cl_mod_plasmaexplo; - - // ROGUE - static sfx_t cl_sfx_lightning; - static sfx_t cl_sfx_disrexp; - static model_t cl_mod_lightning; - static model_t cl_mod_heatbeam; - static model_t cl_mod_monster_heatbeam; - static model_t cl_mod_explo4_big; - -// ROGUE - /* - ================= - CL_RegisterTEntSounds - ================= - */ - static void RegisterTEntSounds() { - int i; - String name; - - // PMM - version stuff - // Com_Printf ("%s\n", ROGUE_VERSION_STRING); - // PMM - cl_sfx_ric1 = S.RegisterSound("world/ric1.wav"); - cl_sfx_ric2 = S.RegisterSound("world/ric2.wav"); - cl_sfx_ric3 = S.RegisterSound("world/ric3.wav"); - cl_sfx_lashit = S.RegisterSound("weapons/lashit.wav"); - cl_sfx_spark5 = S.RegisterSound("world/spark5.wav"); - cl_sfx_spark6 = S.RegisterSound("world/spark6.wav"); - cl_sfx_spark7 = S.RegisterSound("world/spark7.wav"); - cl_sfx_railg = S.RegisterSound("weapons/railgf1a.wav"); - cl_sfx_rockexp = S.RegisterSound("weapons/rocklx1a.wav"); - cl_sfx_grenexp = S.RegisterSound("weapons/grenlx1a.wav"); - cl_sfx_watrexp = S.RegisterSound("weapons/xpld_wat.wav"); - // RAFAEL - // cl_sfx_plasexp = S.RegisterSound ("weapons/plasexpl.wav"); - S.RegisterSound("player/land1.wav"); - - S.RegisterSound("player/fall2.wav"); - S.RegisterSound("player/fall1.wav"); - - for (i = 0; i < 4; i++) { - //Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1); - name = "player/step" + (i + 1) + ".wav"; - cl_sfx_footsteps[i] = S.RegisterSound(name); - } - - // PGM - cl_sfx_lightning = S.RegisterSound("weapons/tesla.wav"); - cl_sfx_disrexp = S.RegisterSound("weapons/disrupthit.wav"); - // version stuff - // sprintf (name, "weapons/sound%d.wav", ROGUE_VERSION_ID); - // if (name[0] == 'w') - // name[0] = 'W'; - // PGM - } - - /* - ================= - CL_RegisterTEntModels - ================= - */ - static void RegisterTEntModels() { - cl_mod_explode = re.RegisterModel("models/objects/explode/tris.md2"); - cl_mod_smoke = re.RegisterModel("models/objects/smoke/tris.md2"); - cl_mod_flash = re.RegisterModel("models/objects/flash/tris.md2"); - cl_mod_parasite_segment = re.RegisterModel("models/monsters/parasite/segment/tris.md2"); - cl_mod_grapple_cable = re.RegisterModel("models/ctf/segment/tris.md2"); - cl_mod_parasite_tip = re.RegisterModel("models/monsters/parasite/tip/tris.md2"); - cl_mod_explo4 = re.RegisterModel("models/objects/r_explode/tris.md2"); - cl_mod_bfg_explo = re.RegisterModel("sprites/s_bfg2.sp2"); - cl_mod_powerscreen = re.RegisterModel("models/items/armor/effect/tris.md2"); - - re.RegisterModel("models/objects/laser/tris.md2"); - re.RegisterModel("models/objects/grenade2/tris.md2"); - re.RegisterModel("models/weapons/v_machn/tris.md2"); - re.RegisterModel("models/weapons/v_handgr/tris.md2"); - re.RegisterModel("models/weapons/v_shotg2/tris.md2"); - re.RegisterModel("models/objects/gibs/bone/tris.md2"); - re.RegisterModel("models/objects/gibs/sm_meat/tris.md2"); - re.RegisterModel("models/objects/gibs/bone2/tris.md2"); - // RAFAEL - // re.RegisterModel ("models/objects/blaser/tris.md2"); - - re.RegisterPic("w_machinegun"); - re.RegisterPic("a_bullets"); - re.RegisterPic("i_health"); - re.RegisterPic("a_grenades"); - - // ROGUE - cl_mod_explo4_big = re.RegisterModel("models/objects/r_explode2/tris.md2"); - cl_mod_lightning = re.RegisterModel("models/proj/lightning/tris.md2"); - cl_mod_heatbeam = re.RegisterModel("models/proj/beam/tris.md2"); - cl_mod_monster_heatbeam = re.RegisterModel("models/proj/widowbeam/tris.md2"); - // ROGUE - } - - /* - ================= - CL_ClearTEnts - ================= - */ - static void ClearTEnts() { - // memset (cl_beams, 0, sizeof(cl_beams)); - for (int i = 0; i < cl_beams.length; i++) - cl_beams[i].clear(); - // memset (cl_explosions, 0, sizeof(cl_explosions)); - for (int i = 0; i < cl_explosions.length; i++) - cl_explosions[i].clear(); - // memset (cl_lasers, 0, sizeof(cl_lasers)); - for (int i = 0; i < cl_lasers.length; i++) - cl_lasers[i].clear(); - // - // ROGUE - // memset (cl_playerbeams, 0, sizeof(cl_playerbeams)); - for (int i = 0; i < cl_playerbeams.length; i++) - cl_playerbeams[i].clear(); - // memset (cl_sustains, 0, sizeof(cl_sustains)); - for (int i = 0; i < cl_sustains.length; i++) - cl_sustains[i].clear(); - // ROGUE - } - - /* - ================= - CL_AllocExplosion - ================= - */ - static explosion_t AllocExplosion() { - int i; - int time; - int index; - - for (i = 0; i < MAX_EXPLOSIONS; i++) { - if (cl_explosions[i].type == ex_free) { - //memset (&cl_explosions[i], 0, sizeof (cl_explosions[i])); - cl_explosions[i].clear(); - return cl_explosions[i]; - } - } - // find the oldest explosion - time = cl.time; - index = 0; - - for (i = 0; i < MAX_EXPLOSIONS; i++) - if (cl_explosions[i].start < time) { - time = (int)cl_explosions[i].start; - index = i; - } - //memset (&cl_explosions[index], 0, sizeof (cl_explosions[index])); - cl_explosions[index].clear(); - return cl_explosions[index]; - } - - /* - ================= - CL_SmokeAndFlash - ================= - */ - static void SmokeAndFlash(float[] origin) { - explosion_t ex; - - ex = CL.AllocExplosion(); - VectorCopy(origin, ex.ent.origin); - ex.type = ex_misc; - ex.frames = 4; - ex.ent.flags = RF_TRANSLUCENT; - ex.start = cl.frame.servertime - 100; - ex.ent.model = cl_mod_smoke; - - ex = CL.AllocExplosion(); - VectorCopy(origin, ex.ent.origin); - ex.type = ex_flash; - ex.ent.flags = RF_FULLBRIGHT; - ex.frames = 2; - ex.start = cl.frame.servertime - 100; - ex.ent.model = cl_mod_flash; - } - - /* - ================= - CL_ParseParticles - ================= - */ - static void ParseParticles() { - int color, count; - float[] pos = new float[3]; - float[] dir = new float[3]; - - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - - color = MSG.ReadByte(net_message); - - count = MSG.ReadByte(net_message); - - CL.ParticleEffect(pos, dir, color, count); - } - - /* - ================= - CL_ParseBeam - ================= - */ - static int ParseBeam(model_t model) { - int ent; - float[] start = new float[3]; - float[] end = new float[3]; - beam_t[] b; - int i; - - ent = MSG.ReadShort(net_message); - - MSG.ReadPos(net_message, start); - MSG.ReadPos(net_message, end); - - // override any beam with the same entity - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) - if (b[i].entity == ent) { - b[i].entity = ent; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorClear(b[i].offset); - return ent; - } - - // find a free beam - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) { - if (b[i].model == null || b[i].endtime < cl.time) { - b[i].entity = ent; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorClear(b[i].offset); - return ent; - } - } - Com.Printf("beam list overflow!\n"); - return ent; - } - - /* - ================= - CL_ParseBeam2 - ================= - */ - static int ParseBeam2(model_t model) { - int ent; - float[] start = new float[3]; - float[] end = new float[3]; - float[] offset = new float[3]; - beam_t[] b; - int i; - - ent = MSG.ReadShort(net_message); - - MSG.ReadPos(net_message, start); - MSG.ReadPos(net_message, end); - MSG.ReadPos(net_message, offset); - - // Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]); - - // override any beam with the same entity - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) - if (b[i].entity == ent) { - b[i].entity = ent; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorCopy(offset, b[i].offset); - return ent; - } - - // find a free beam - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) { - if (b[i].model == null || b[i].endtime < cl.time) { - b[i].entity = ent; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorCopy(offset, b[i].offset); - return ent; - } - } - Com.Printf("beam list overflow!\n"); - return ent; - } - - // ROGUE - /* - ================= - CL_ParsePlayerBeam - - adds to the cl_playerbeam array instead of the cl_beams array - ================= - */ - static int ParsePlayerBeam(model_t model) { - int ent; - float[] start = new float[3]; - float[] end = new float[3]; - float[] offset = new float[3]; - beam_t[] b; - int i; - - ent = MSG.ReadShort(net_message); - - MSG.ReadPos(net_message, start); - MSG.ReadPos(net_message, end); - // PMM - network optimization - if (model == cl_mod_heatbeam) - VectorSet(offset, 2, 7, -3); - else if (model == cl_mod_monster_heatbeam) { - model = cl_mod_heatbeam; - VectorSet(offset, 0, 0, 0); - } else - MSG.ReadPos(net_message, offset); - - // Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]); - - // override any beam with the same entity - // PMM - For player beams, we only want one per player (entity) so.. - b = cl_playerbeams; - for (i = 0; i < MAX_BEAMS; i++) { - if (b[i].entity == ent) { - b[i].entity = ent; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorCopy(offset, b[i].offset); - return ent; - } - } - - // find a free beam - b = cl_playerbeams; - for (i = 0; i < MAX_BEAMS; i++) { - if (b[i].model == null || b[i].endtime < cl.time) { - b[i].entity = ent; - b[i].model = model; - b[i].endtime = cl.time + 100; // PMM - this needs to be 100 to prevent multiple heatbeams - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorCopy(offset, b[i].offset); - return ent; - } - } - Com.Printf("beam list overflow!\n"); - return ent; - } -// rogue - - /* - ================= - CL_ParseLightning - ================= - */ - static int ParseLightning(model_t model) { - int srcEnt, destEnt; - float[] start = new float[3]; - float[] end = new float[3]; - beam_t[] b; - int i; - - srcEnt = MSG.ReadShort(net_message); - destEnt = MSG.ReadShort(net_message); - - MSG.ReadPos(net_message, start); - MSG.ReadPos(net_message, end); - - // override any beam with the same source AND destination entities - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) - if (b[i].entity == srcEnt && b[i].dest_entity == destEnt) { - // Com_Printf("%d: OVERRIDE %d . %d\n", cl.time, srcEnt, destEnt); - b[i].entity = srcEnt; - b[i].dest_entity = destEnt; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorClear(b[i].offset); - return srcEnt; - } - - // find a free beam - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) { - if (b[i].model == null || b[i].endtime < cl.time) { - // Com_Printf("%d: NORMAL %d . %d\n", cl.time, srcEnt, destEnt); - b[i].entity = srcEnt; - b[i].dest_entity = destEnt; - b[i].model = model; - b[i].endtime = cl.time + 200; - VectorCopy(start, b[i].start); - VectorCopy(end, b[i].end); - VectorClear(b[i].offset); - return srcEnt; - } - } - Com.Printf("beam list overflow!\n"); - return srcEnt; - } - - /* - ================= - CL_ParseLaser - ================= - */ - static void ParseLaser(int colors) { - float[] start = new float[3]; - float[] end = new float[3]; - laser_t[] l; - int i; - - MSG.ReadPos(net_message, start); - MSG.ReadPos(net_message, end); - - l = cl_lasers; - for (i = 0; i < MAX_LASERS; i++) { - if (l[i].endtime < cl.time) { - l[i].ent.flags = RF_TRANSLUCENT | RF_BEAM; - VectorCopy(start, l[i].ent.origin); - VectorCopy(end, l[i].ent.oldorigin); - l[i].ent.alpha = 0.30f; - l[i].ent.skinnum = (colors >> ((rand() % 4) * 8)) & 0xff; - l[i].ent.model = null; - l[i].ent.frame = 4; - l[i].endtime = cl.time + 100; - return; - } - } - } - -// ============= -// ROGUE - static void ParseSteam() { - float[] pos = new float[3]; - float[] dir = new float[3]; - int id, i; - int r; - int cnt; - int color; - int magnitude; - cl_sustain_t[] s; - cl_sustain_t free_sustain; - - id = MSG.ReadShort(net_message); // an id of -1 is an instant effect - if (id != -1) // sustains - { - // Com_Printf ("Sustain effect id %d\n", id); - free_sustain = null; - s = cl_sustains; - for (i = 0; i < MAX_SUSTAINS; i++) { - if (s[i].id == 0) { - free_sustain = s[i]; - break; - } - } - if (free_sustain != null) { - s[i].id = id; - s[i].count = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, s[i].org); - MSG.ReadDir(net_message, s[i].dir); - r = MSG.ReadByte(net_message); - s[i].color = r & 0xff; - s[i].magnitude = MSG.ReadShort(net_message); - s[i].endtime = cl.time + MSG.ReadLong(net_message); - s[i].think = new cl_sustain_t.ThinkAdapter() { - void think(cl_sustain_t self) { - CL.ParticleSteamEffect2(self); - } - }; - s[i].thinkinterval = 100; - s[i].nextthink = cl.time; - } else { - // Com_Printf ("No free sustains!\n"); - // FIXME - read the stuff anyway - cnt = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - r = MSG.ReadByte(net_message); - magnitude = MSG.ReadShort(net_message); - magnitude = MSG.ReadLong(net_message); // really interval - } - } else // instant - { - cnt = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - r = MSG.ReadByte(net_message); - magnitude = MSG.ReadShort(net_message); - color = r & 0xff; - CL.ParticleSteamEffect(pos, dir, color, cnt, magnitude); - // S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - } - } - - static void ParseWidow() { - float[] pos = new float[3]; - int id, i; - cl_sustain_t[] s; - cl_sustain_t free_sustain; - - id = MSG.ReadShort(net_message); - - free_sustain = null; - s = cl_sustains; - for (i = 0; i < MAX_SUSTAINS; i++) { - if (s[i].id == 0) { - free_sustain = s[i]; - break; - } - } - if (free_sustain != null) { - s[i].id = id; - MSG.ReadPos(net_message, s[i].org); - s[i].endtime = cl.time + 2100; - s[i].think = new cl_sustain_t.ThinkAdapter() { - void think(cl_sustain_t self) { - CL.Widowbeamout(self); - } - }; - s[i].thinkinterval = 1; - s[i].nextthink = cl.time; - } else // no free sustains - { - // FIXME - read the stuff anyway - MSG.ReadPos(net_message, pos); - } - } - - static void ParseNuke() { - float[] pos = new float[3]; - int i; - cl_sustain_t[] s; - cl_sustain_t free_sustain; - - free_sustain = null; - s = cl_sustains; - for (i = 0; i < MAX_SUSTAINS; i++) { - if (s[i].id == 0) { - free_sustain = s[i]; - break; - } - } - if (free_sustain != null) { - s[i].id = 21000; - MSG.ReadPos(net_message, s[i].org); - s[i].endtime = cl.time + 1000; - s[i].think = new cl_sustain_t.ThinkAdapter() { - void think(cl_sustain_t self) { - CL.Nukeblast(self); - } - }; - s[i].thinkinterval = 1; - s[i].nextthink = cl.time; - } else // no free sustains - { - // FIXME - read the stuff anyway - MSG.ReadPos(net_message, pos); - } - } - -// ROGUE -// ============= - - - /* - ================= - CL_ParseTEnt - ================= - */ - static int[] splash_color = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8}; - static void ParseTEnt() { - int type; - float[] pos = new float[3]; - float[] pos2 = new float[3]; - float[] dir = new float[3]; - explosion_t ex; - int cnt; - int color; - int r; - int ent; - int magnitude; - - type = MSG.ReadByte(net_message); - - switch (type) { - case TE_BLOOD : // bullet hitting flesh - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - CL.ParticleEffect(pos, dir, 0xe8, 60); - break; - - case TE_GUNSHOT : // bullet hitting wall - case TE_SPARKS : - case TE_BULLET_SPARKS : - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - if (type == TE_GUNSHOT) - CL.ParticleEffect(pos, dir, 0, 40); - else - CL.ParticleEffect(pos, dir, 0xe0, 6); - - if (type != TE_SPARKS) { - CL.SmokeAndFlash(pos); - - // impact sound - cnt = rand() & 15; - if (cnt == 1) - S.StartSound(pos, 0, 0, cl_sfx_ric1, 1, ATTN_NORM, 0); - else if (cnt == 2) - S.StartSound(pos, 0, 0, cl_sfx_ric2, 1, ATTN_NORM, 0); - else if (cnt == 3) - S.StartSound(pos, 0, 0, cl_sfx_ric3, 1, ATTN_NORM, 0); - } - - break; - - case TE_SCREEN_SPARKS : - case TE_SHIELD_SPARKS : - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - if (type == TE_SCREEN_SPARKS) - CL.ParticleEffect(pos, dir, 0xd0, 40); - else - CL.ParticleEffect(pos, dir, 0xb0, 40); - //FIXME : replace or remove this sound - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_SHOTGUN : // bullet hitting wall - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - CL.ParticleEffect(pos, dir, 0, 20); - CL.SmokeAndFlash(pos); - break; - - case TE_SPLASH : // bullet hitting water - cnt = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - r = MSG.ReadByte(net_message); - if (r > 6) - color = 0x00; - else - color = splash_color[r]; - CL.ParticleEffect(pos, dir, color, cnt); - - if (r == SPLASH_SPARKS) { - r = rand() & 3; - if (r == 0) - S.StartSound(pos, 0, 0, cl_sfx_spark5, 1, ATTN_STATIC, 0); - else if (r == 1) - S.StartSound(pos, 0, 0, cl_sfx_spark6, 1, ATTN_STATIC, 0); - else - S.StartSound(pos, 0, 0, cl_sfx_spark7, 1, ATTN_STATIC, 0); - } - break; - - case TE_LASER_SPARKS : - cnt = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - color = MSG.ReadByte(net_message); - CL.ParticleEffect2(pos, dir, color, cnt); - break; - - // RAFAEL - case TE_BLUEHYPERBLASTER : - MSG.ReadPos(net_message, pos); - MSG.ReadPos(net_message, dir); - CL.BlasterParticles(pos, dir); - break; - - case TE_BLASTER : // blaster hitting wall - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - CL.BlasterParticles(pos, dir); - - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.ent.angles[0] = (float) (Math.acos(dir[2]) / Math.PI * 180); - // PMM - fixed to correct for pitch of 0 - if (dir[0] != 0.0f) - ex.ent.angles[1] = (float) (Math.atan2(dir[1], dir[0]) / Math.PI * 180); - else if (dir[1] > 0) - ex.ent.angles[1] = 90; - else if (dir[1] < 0) - ex.ent.angles[1] = 270; - else - ex.ent.angles[1] = 0; - - ex.type = ex_misc; - ex.ent.flags = RF_FULLBRIGHT | RF_TRANSLUCENT; - ex.start = cl.frame.servertime - 100; - ex.light = 150; - ex.lightcolor[0] = 1; - ex.lightcolor[1] = 1; - ex.ent.model = cl_mod_explode; - ex.frames = 4; - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_RAILTRAIL : // railgun effect - MSG.ReadPos(net_message, pos); - MSG.ReadPos(net_message, pos2); - CL.RailTrail(pos, pos2); - S.StartSound(pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0); - break; - - case TE_EXPLOSION2 : - case TE_GRENADE_EXPLOSION : - case TE_GRENADE_EXPLOSION_WATER : - MSG.ReadPos(net_message, pos); - - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.type = ex_poly; - ex.ent.flags = RF_FULLBRIGHT; - ex.start = cl.frame.servertime - 100; - ex.light = 350; - ex.lightcolor[0] = 1.0f; - ex.lightcolor[1] = 0.5f; - ex.lightcolor[2] = 0.5f; - ex.ent.model = cl_mod_explo4; - ex.frames = 19; - ex.baseframe = 30; - ex.ent.angles[1] = rand() % 360; - CL.ExplosionParticles(pos); - if (type == TE_GRENADE_EXPLOSION_WATER) - S.StartSound(pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0); - else - S.StartSound(pos, 0, 0, cl_sfx_grenexp, 1, ATTN_NORM, 0); - break; - - // RAFAEL - case TE_PLASMA_EXPLOSION : - MSG.ReadPos(net_message, pos); - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.type = ex_poly; - ex.ent.flags = RF_FULLBRIGHT; - ex.start = cl.frame.servertime - 100; - ex.light = 350; - ex.lightcolor[0] = 1.0f; - ex.lightcolor[1] = 0.5f; - ex.lightcolor[2] = 0.5f; - ex.ent.angles[1] = rand() % 360; - ex.ent.model = cl_mod_explo4; - if (Globals.rnd.nextFloat() < 0.5) - ex.baseframe = 15; - ex.frames = 15; - CL.ExplosionParticles(pos); - S.StartSound(pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0); - break; - - case TE_EXPLOSION1 : - case TE_EXPLOSION1_BIG : // PMM - case TE_ROCKET_EXPLOSION : - case TE_ROCKET_EXPLOSION_WATER : - case TE_EXPLOSION1_NP : // PMM - MSG.ReadPos(net_message, pos); - - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.type = ex_poly; - ex.ent.flags = RF_FULLBRIGHT; - ex.start = cl.frame.servertime - 100; - ex.light = 350; - ex.lightcolor[0] = 1.0f; - ex.lightcolor[1] = 0.5f; - ex.lightcolor[2] = 0.5f; - ex.ent.angles[1] = rand() % 360; - if (type != TE_EXPLOSION1_BIG) // PMM - ex.ent.model = cl_mod_explo4; // PMM - else - ex.ent.model = cl_mod_explo4_big; - if (Globals.rnd.nextFloat() < 0.5) - ex.baseframe = 15; - ex.frames = 15; - if ((type != TE_EXPLOSION1_BIG) && (type != TE_EXPLOSION1_NP)) // PMM - CL.ExplosionParticles(pos); // PMM - if (type == TE_ROCKET_EXPLOSION_WATER) - S.StartSound(pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0); - else - S.StartSound(pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0); - break; - - case TE_BFG_EXPLOSION : - MSG.ReadPos(net_message, pos); - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.type = ex_poly; - ex.ent.flags = RF_FULLBRIGHT; - ex.start = cl.frame.servertime - 100; - ex.light = 350; - ex.lightcolor[0] = 0.0f; - ex.lightcolor[1] = 1.0f; - ex.lightcolor[2] = 0.0f; - ex.ent.model = cl_mod_bfg_explo; - ex.ent.flags |= RF_TRANSLUCENT; - ex.ent.alpha = 0.30f; - ex.frames = 4; - break; - - case TE_BFG_BIGEXPLOSION : - MSG.ReadPos(net_message, pos); - CL.BFGExplosionParticles(pos); - break; - - case TE_BFG_LASER : - CL.ParseLaser(0xd0d1d2d3); - break; - - case TE_BUBBLETRAIL : - MSG.ReadPos(net_message, pos); - MSG.ReadPos(net_message, pos2); - CL.BubbleTrail(pos, pos2); - break; - - case TE_PARASITE_ATTACK : - case TE_MEDIC_CABLE_ATTACK : - ent = CL.ParseBeam(cl_mod_parasite_segment); - break; - - case TE_BOSSTPORT : // boss teleporting to station - MSG.ReadPos(net_message, pos); - CL.BigTeleportParticles(pos); - S.StartSound(pos, 0, 0, S.RegisterSound("misc/bigtele.wav"), 1, ATTN_NONE, 0); - break; - - case TE_GRAPPLE_CABLE : - ent = CL.ParseBeam2(cl_mod_grapple_cable); - break; - - // RAFAEL - case TE_WELDING_SPARKS : - cnt = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - color = MSG.ReadByte(net_message); - CL.ParticleEffect2(pos, dir, color, cnt); - - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.type = ex_flash; - // note to self - // we need a better no draw flag - ex.ent.flags = RF_BEAM; - ex.start = cl.frame.servertime - 0.1f; - ex.light = 100 + (rand() % 75); - ex.lightcolor[0] = 1.0f; - ex.lightcolor[1] = 1.0f; - ex.lightcolor[2] = 0.3f; - ex.ent.model = cl_mod_flash; - ex.frames = 2; - break; - - case TE_GREENBLOOD : - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - CL.ParticleEffect2(pos, dir, 0xdf, 30); - break; - - // RAFAEL - case TE_TUNNEL_SPARKS : - cnt = MSG.ReadByte(net_message); - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - color = MSG.ReadByte(net_message); - CL.ParticleEffect3(pos, dir, color, cnt); - break; - - // ============= - // PGM - // PMM -following code integrated for flechette (different color) - case TE_BLASTER2 : // green blaster hitting wall - case TE_FLECHETTE : // flechette - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - - // PMM - if (type == TE_BLASTER2) - CL.BlasterParticles2(pos, dir, 0xd0); - else - CL.BlasterParticles2(pos, dir, 0x6f); // 75 - - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.ent.angles[0] = (float) (Math.acos(dir[2]) / Math.PI * 180); - // PMM - fixed to correct for pitch of 0 - if (dir[0] != 0.0f) - ex.ent.angles[1] = (float) (Math.atan2(dir[1], dir[0]) / Math.PI * 180); - else if (dir[1] > 0) - ex.ent.angles[1] = 90; - else if (dir[1] < 0) - ex.ent.angles[1] = 270; - else - ex.ent.angles[1] = 0; - - ex.type = ex_misc; - ex.ent.flags = RF_FULLBRIGHT | RF_TRANSLUCENT; - - // PMM - if (type == TE_BLASTER2) - ex.ent.skinnum = 1; - else // flechette - ex.ent.skinnum = 2; - - ex.start = cl.frame.servertime - 100; - ex.light = 150; - // PMM - if (type == TE_BLASTER2) - ex.lightcolor[1] = 1; - else // flechette - { - ex.lightcolor[0] = 0.19f; - ex.lightcolor[1] = 0.41f; - ex.lightcolor[2] = 0.75f; - } - ex.ent.model = cl_mod_explode; - ex.frames = 4; - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_LIGHTNING : - ent = CL.ParseLightning(cl_mod_lightning); - S.StartSound(null, ent, CHAN_WEAPON, cl_sfx_lightning, 1, ATTN_NORM, 0); - break; - - case TE_DEBUGTRAIL : - MSG.ReadPos(net_message, pos); - MSG.ReadPos(net_message, pos2); - CL.DebugTrail(pos, pos2); - break; - - case TE_PLAIN_EXPLOSION : - MSG.ReadPos(net_message, pos); - - ex = CL.AllocExplosion(); - VectorCopy(pos, ex.ent.origin); - ex.type = ex_poly; - ex.ent.flags = RF_FULLBRIGHT; - ex.start = cl.frame.servertime - 100; - ex.light = 350; - ex.lightcolor[0] = 1.0f; - ex.lightcolor[1] = 0.5f; - ex.lightcolor[2] = 0.5f; - ex.ent.angles[1] = rand() % 360; - ex.ent.model = cl_mod_explo4; - if (Globals.rnd.nextFloat() < 0.5) - ex.baseframe = 15; - ex.frames = 15; - if (type == TE_ROCKET_EXPLOSION_WATER) - S.StartSound(pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0); - else - S.StartSound(pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0); - break; - - case TE_FLASHLIGHT : - MSG.ReadPos(net_message, pos); - ent = MSG.ReadShort(net_message); - CL.Flashlight(ent, pos); - break; - - case TE_FORCEWALL : - MSG.ReadPos(net_message, pos); - MSG.ReadPos(net_message, pos2); - color = MSG.ReadByte(net_message); - CL.ForceWall(pos, pos2, color); - break; - - case TE_HEATBEAM : - ent = CL.ParsePlayerBeam(cl_mod_heatbeam); - break; - - case TE_MONSTER_HEATBEAM : - ent = CL.ParsePlayerBeam(cl_mod_monster_heatbeam); - break; - - case TE_HEATBEAM_SPARKS : - // cnt = MSG.ReadByte (net_message); - cnt = 50; - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - // r = MSG.ReadByte (net_message); - // magnitude = MSG.ReadShort (net_message); - r = 8; - magnitude = 60; - color = r & 0xff; - CL.ParticleSteamEffect(pos, dir, color, cnt, magnitude); - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_HEATBEAM_STEAM : - // cnt = MSG.ReadByte (net_message); - cnt = 20; - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - // r = MSG.ReadByte (net_message); - // magnitude = MSG.ReadShort (net_message); - // color = r & 0xff; - color = 0xe0; - magnitude = 60; - CL.ParticleSteamEffect(pos, dir, color, cnt, magnitude); - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_STEAM : - CL.ParseSteam(); - break; - - case TE_BUBBLETRAIL2 : - // cnt = MSG.ReadByte (net_message); - cnt = 8; - MSG.ReadPos(net_message, pos); - MSG.ReadPos(net_message, pos2); - CL.BubbleTrail2(pos, pos2, cnt); - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_MOREBLOOD : - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - CL.ParticleEffect(pos, dir, 0xe8, 250); - break; - - case TE_CHAINFIST_SMOKE : - dir[0] = 0; - dir[1] = 0; - dir[2] = 1; - MSG.ReadPos(net_message, pos); - CL.ParticleSmokeEffect(pos, dir, 0, 20, 20); - break; - - case TE_ELECTRIC_SPARKS : - MSG.ReadPos(net_message, pos); - MSG.ReadDir(net_message, dir); - // CL_ParticleEffect (pos, dir, 109, 40); - CL.ParticleEffect(pos, dir, 0x75, 40); - //FIXME : replace or remove this sound - S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); - break; - - case TE_TRACKER_EXPLOSION : - MSG.ReadPos(net_message, pos); - CL.ColorFlash(pos, 0, 150, -1, -1, -1); - CL.ColorExplosionParticles(pos, 0, 1); - // CL_Tracker_Explode (pos); - S.StartSound(pos, 0, 0, cl_sfx_disrexp, 1, ATTN_NORM, 0); - break; - - case TE_TELEPORT_EFFECT : - case TE_DBALL_GOAL : - MSG.ReadPos(net_message, pos); - CL.TeleportParticles(pos); - break; - - case TE_WIDOWBEAMOUT : - CL.ParseWidow(); - break; - - case TE_NUKEBLAST : - ParseNuke(); - break; - - case TE_WIDOWSPLASH : - MSG.ReadPos(net_message, pos); - CL.WidowSplash(pos); - break; - // PGM - // ============== - - default : - Com.Error(ERR_DROP, "CL_ParseTEnt: bad type"); - } - } - - /* - ================= - CL_AddBeams - ================= - */ - static void AddBeams() { - int i, j; - beam_t[] b; - float[] dist = new float[3]; - float[] org = new float[3]; - float d; - entity_t ent = new entity_t(); - float yaw, pitch; - float forward; - float len, steps; - float model_length; - - // update beams - b = cl_beams; - for (i = 0; i < MAX_BEAMS; i++) { - if (b[i].model == null || b[i].endtime < cl.time) - continue; - - // if coming from the player, update the start position - if (b[i].entity == cl.playernum + 1) // entity 0 is the world - { - VectorCopy(cl.refdef.vieworg, b[i].start); - b[i].start[2] -= 22; // adjust for view height - } - VectorAdd(b[i].start, b[i].offset, org); - - // calculate pitch and yaw - VectorSubtract(b[i].end, org, dist); - - if (dist[1] == 0 && dist[0] == 0) { - yaw = 0; - if (dist[2] > 0) - pitch = 90; - else - pitch = 270; - } else { - // PMM - fixed to correct for pitch of 0 - if (dist[0] != 0.0f) - yaw = (float) (Math.atan2(dist[1], dist[0]) * 180 / Math.PI); - else if (dist[1] > 0) - yaw = 90; - else - yaw = 270; - if (yaw < 0) - yaw += 360; - - forward = (float)Math.sqrt(dist[0] * dist[0] + dist[1] * dist[1]); - pitch = (float) (Math.atan2(dist[2], forward) * -180.0 / Math.PI); - if (pitch < 0) - pitch += 360.0; - } - - // add new entities for the beams - d = VectorNormalize(dist); - - //memset (&ent, 0, sizeof(ent)); - ent = new entity_t(); - if (b[i].model == cl_mod_lightning) { - model_length = 35.0f; - d -= 20.0; // correction so it doesn't end in middle of tesla - } else { - model_length = 30.0f; - } - steps = (float)Math.ceil(d / model_length); - len = (d - model_length) / (steps - 1); - - // PMM - special case for lightning model .. if the real length is shorter than the model, - // flip it around & draw it from the end to the start. This prevents the model from going - // through the tesla mine (instead it goes through the target) - if ((b[i].model == cl_mod_lightning) && (d <= model_length)) { - // Com_Printf ("special case\n"); - VectorCopy(b[i].end, ent.origin); - // offset to push beam outside of tesla model (negative because dist is from end to start - // for this beam) - // for (j=0 ; j<3 ; j++) - // ent.origin[j] -= dist[j]*10.0; - ent.model = b[i].model; - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand() % 360; - V.AddEntity(ent); - return; - } - while (d > 0) { - VectorCopy(org, ent.origin); - ent.model = b[i].model; - if (b[i].model == cl_mod_lightning) { - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0f; - ent.angles[2] = rand() % 360; - } else { - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand() % 360; - } - - // Com_Printf("B: %d . %d\n", b[i].entity, b[i].dest_entity); - V.AddEntity(ent); - - for (j = 0; j < 3; j++) - org[j] += dist[j] * len; - d -= model_length; - } - } - } - - //extern cvar_t *hand; - - /* - ================= - ROGUE - draw player locked beams - CL_AddPlayerBeams - ================= - */ - static void AddPlayerBeams() { - float[] dist = new float[3]; - float[] org = new float[3]; - float d; - entity_t ent = new entity_t(); - float yaw, pitch; - float forward; - float len, steps; - int framenum = 0; - float model_length; - - float hand_multiplier; - frame_t oldframe; - player_state_t ps, ops; - - // PMM - if (hand != null) { - if (hand.value == 2) - hand_multiplier = 0; - else if (hand.value == 1) - hand_multiplier = -1; - else - hand_multiplier = 1; - } else { - hand_multiplier = 1; - } - // PMM - - // update beams - beam_t[] b = cl_playerbeams; - float[] f = new float[3]; - float[] u = new float[3]; - float[] r = new float[3]; - for (int i = 0; i < MAX_BEAMS; i++) { - - if (b[i].model == null || b[i].endtime < cl.time) - continue; - - if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam)) { - - // if coming from the player, update the start position - if (b[i].entity == cl.playernum + 1) // entity 0 is the world - { - // set up gun position - // code straight out of CL_AddViewWeapon - ps = cl.frame.playerstate; - int j = (cl.frame.serverframe - 1) & UPDATE_MASK; - oldframe = cl.frames[j]; - - if (oldframe.serverframe != cl.frame.serverframe - 1 || !oldframe.valid) - oldframe = cl.frame; // previous frame was dropped or involid - - ops = oldframe.playerstate; - for (j = 0; j < 3; j++) { - b[i].start[j] = - cl.refdef.vieworg[j] - + ops.gunoffset[j] - + cl.lerpfrac * (ps.gunoffset[j] - ops.gunoffset[j]); - } - VectorMA(b[i].start, (hand_multiplier * b[i].offset[0]), cl.v_right, org); - VectorMA(org, b[i].offset[1], cl.v_forward, org); - VectorMA(org, b[i].offset[2], cl.v_up, org); - if ((hand != null) && (hand.value == 2)) { - VectorMA(org, -1, cl.v_up, org); - } - // FIXME - take these out when final - VectorCopy(cl.v_right, r); - VectorCopy(cl.v_forward, f); - VectorCopy(cl.v_up, u); - - } else - VectorCopy(b[i].start, org); - } else { - // if coming from the player, update the start position - if (b[i].entity == cl.playernum + 1) // entity 0 is the world - { - VectorCopy(cl.refdef.vieworg, b[i].start); - b[i].start[2] -= 22; // adjust for view height - } - VectorAdd(b[i].start, b[i].offset, org); - } - - // calculate pitch and yaw - VectorSubtract(b[i].end, org, dist); - - // PMM - if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam) && (b[i].entity == cl.playernum + 1)) { - - len = VectorLength(dist); - VectorScale(f, len, dist); - VectorMA(dist, (hand_multiplier * b[i].offset[0]), r, dist); - VectorMA(dist, b[i].offset[1], f, dist); - VectorMA(dist, b[i].offset[2], u, dist); - if ((hand != null) && (hand.value == 2)) { - VectorMA(org, -1, cl.v_up, org); - } - } - // PMM - - if (dist[1] == 0 && dist[0] == 0) { - yaw = 0; - if (dist[2] > 0) - pitch = 90; - else - pitch = 270; - } else { - // PMM - fixed to correct for pitch of 0 - if (dist[0] != 0.0f) - yaw = (float) (Math.atan2(dist[1], dist[0]) * 180 / Math.PI); - else if (dist[1] > 0) - yaw = 90; - else - yaw = 270; - if (yaw < 0) - yaw += 360; - - forward = (float)Math.sqrt(dist[0] * dist[0] + dist[1] * dist[1]); - pitch = (float) (Math.atan2(dist[2], forward) * -180.0 / Math.PI); - if (pitch < 0) - pitch += 360.0; - } - - if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam)) { - if (b[i].entity != cl.playernum + 1) { - framenum = 2; - // Com_Printf ("Third person\n"); - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0f; - ent.angles[2] = 0; - // Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, b[i].offset[0], b[i].offset[1], b[i].offset[2]); - AngleVectors(ent.angles, f, r, u); - - // if it's a non-origin offset, it's a player, so use the hardcoded player offset - if (VectorCompare(b[i].offset, vec3_origin) == 0) { - VectorMA(org, - (b[i].offset[0]) + 1, r, org); - VectorMA(org, - (b[i].offset[1]), f, org); - VectorMA(org, - (b[i].offset[2]) - 10, u, org); - } else { - // if it's a monster, do the particle effect - CL.MonsterPlasma_Shell(b[i].start); - } - } else { - framenum = 1; - } - } - - // if it's the heatbeam, draw the particle effect - if ((cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam) && (b[i].entity == cl.playernum + 1))) { - CL.Heatbeam(org, dist); - } - - // add new entities for the beams - d = VectorNormalize(dist); - - //memset (&ent, 0, sizeof(ent)); - //ent = new entity_t(); - // this is not required. hoz - - if (b[i].model == cl_mod_heatbeam) { - model_length = 32.0f; - } else if (b[i].model == cl_mod_lightning) { - model_length = 35.0f; - d -= 20.0; // correction so it doesn't end in middle of tesla - } else { - model_length = 30.0f; - } - steps = (float)Math.ceil(d / model_length); - len = (d - model_length) / (steps - 1); - - // PMM - special case for lightning model .. if the real length is shorter than the model, - // flip it around & draw it from the end to the start. This prevents the model from going - // through the tesla mine (instead it goes through the target) - if ((b[i].model == cl_mod_lightning) && (d <= model_length)) { - // Com_Printf ("special case\n"); - VectorCopy(b[i].end, ent.origin); - // offset to push beam outside of tesla model (negative because dist is from end to start - // for this beam) - // for (j=0 ; j<3 ; j++) - // ent.origin[j] -= dist[j]*10.0; - ent.model = b[i].model; - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand() % 360; - V.AddEntity(ent); - return; - } - while (d > 0) { - VectorCopy(org, ent.origin); - ent.model = b[i].model; - if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam)) { - // ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT; - // ent.alpha = 0.3; - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0f; - ent.angles[2] = (cl.time) % 360; - // ent.angles[2] = rand()%360; - ent.frame = framenum; - } else if (b[i].model == cl_mod_lightning) { - ent.flags = RF_FULLBRIGHT; - ent.angles[0] = -pitch; - ent.angles[1] = yaw + 180.0f; - ent.angles[2] = rand() % 360; - } else { - ent.angles[0] = pitch; - ent.angles[1] = yaw; - ent.angles[2] = rand() % 360; - } - - // Com_Printf("B: %d . %d\n", b[i].entity, b[i].dest_entity); - V.AddEntity(ent); - - for (int j = 0; j < 3; j++) - org[j] += dist[j] * len; - d -= model_length; - } - } - } - - /* - ================= - CL_AddExplosions - ================= - */ - static void AddExplosions() { - entity_t ent; - int i; - explosion_t[] ex; - float frac; - int f; - - //memset (&ent, 0, sizeof(ent)); Pointer! - ent = null; - ex = cl_explosions; - for (i = 0; i < MAX_EXPLOSIONS; i++) { - if (ex[i].type == ex_free) - continue; - frac = (cl.time - ex[i].start) / 100.0f; - f = (int)Math.floor(frac); - - ent = ex[i].ent; - - switch (ex[i].type) { - case ex_mflash : - if (f >= ex[i].frames - 1) - ex[i].type = ex_free; - break; - case ex_misc : - if (f >= ex[i].frames - 1) { - ex[i].type = ex_free; - break; - } - ent.alpha = 1.0f - frac / (ex[i].frames - 1); - break; - case ex_flash : - if (f >= 1) { - ex[i].type = ex_free; - break; - } - ent.alpha = 1.0f; - break; - case ex_poly : - if (f >= ex[i].frames - 1) { - ex[i].type = ex_free; - break; - } - - ent.alpha = (16.0f - (float)f) / 16.0f; - - if (f < 10) { - ent.skinnum = (f >> 1); - if (ent.skinnum < 0) - ent.skinnum = 0; - } else { - ent.flags |= RF_TRANSLUCENT; - if (f < 13) - ent.skinnum = 5; - else - ent.skinnum = 6; - } - break; - case ex_poly2 : - if (f >= ex[i].frames - 1) { - ex[i].type = ex_free; - break; - } - - ent.alpha = (5.0f - (float)f) / 5.0f; - ent.skinnum = 0; - ent.flags |= RF_TRANSLUCENT; - break; - } - - if (ex[i].type == ex_free) - continue; - if (ex[i].light != 0.0f) { - V.AddLight( - ent.origin, - ex[i].light * ent.alpha, - ex[i].lightcolor[0], - ex[i].lightcolor[1], - ex[i].lightcolor[2]); - } - - VectorCopy(ent.origin, ent.oldorigin); - - if (f < 0) - f = 0; - ent.frame = ex[i].baseframe + f + 1; - ent.oldframe = ex[i].baseframe + f; - ent.backlerp = 1.0f - cl.lerpfrac; - - V.AddEntity(ent); - } - } - - /* - ================= - CL_AddLasers - ================= - */ - static void AddLasers() { - laser_t[] l; - int i; - - l = cl_lasers; - for (i = 0; i < MAX_LASERS; i++) { - if (l[i].endtime >= cl.time) - V.AddEntity(l[i].ent); - } - } - - /* PMM - CL_Sustains */ - static void ProcessSustain() { - cl_sustain_t[] s; - int i; - - s = cl_sustains; - for (i = 0; i < MAX_SUSTAINS; i++) { - if (s[i].id != 0) - if ((s[i].endtime >= cl.time) && (cl.time >= s[i].nextthink)) { - s[i].think.think(s[i]); - } else if (s[i].endtime < cl.time) - s[i].id = 0; - } - } - - /* - ================= - CL_AddTEnts - ================= - */ - static void AddTEnts() { - CL.AddBeams(); - // PMM - draw plasma beams - CL.AddPlayerBeams(); - CL.AddExplosions(); - CL.AddLasers(); - // PMM - set up sustain - CL.ProcessSustain(); - } -} +public class CL_tent { + + static class explosion_t { + int type; + + entity_t ent = new entity_t(); + + int frames; + + float light; + + float[] lightcolor = new float[3]; + + float start; + + int baseframe; + + void clear() { + lightcolor[0] = lightcolor[1] = lightcolor[2] = light = start = type = frames = baseframe = 0; + ent = new entity_t(); + } + } + + static final int MAX_EXPLOSIONS = 32; + + static explosion_t[] cl_explosions = new explosion_t[MAX_EXPLOSIONS]; + + static final int MAX_BEAMS = 32; + + static beam_t[] cl_beams = new beam_t[MAX_BEAMS]; + + // PMM - added this for player-linked beams. Currently only used by the + // plasma beam + static beam_t[] cl_playerbeams = new beam_t[MAX_BEAMS]; + + static final int MAX_LASERS = 32; + + static laser_t[] cl_lasers = new laser_t[MAX_LASERS]; + + // ROGUE + static final int MAX_SUSTAINS = 32; + + static cl_sustain_t[] cl_sustains = new cl_sustain_t[MAX_SUSTAINS]; + + static class beam_t { + int entity; + + int dest_entity; + + model_t model; + + int endtime; + + float[] offset = new float[3]; + + float[] start = new float[3]; + + float[] end = new float[3]; + + void clear() { + offset[0] = offset[1] = offset[2] = start[0] = start[1] = start[2] = end[0] = end[1] = end[2] = entity = dest_entity = endtime = 0; + model = null; + } + } + + static { + for (int i = 0; i < cl_explosions.length; i++) + cl_explosions[i] = new explosion_t(); + } + static { + for (int i = 0; i < cl_beams.length; i++) + cl_beams[i] = new beam_t(); + for (int i = 0; i < cl_playerbeams.length; i++) + cl_playerbeams[i] = new beam_t(); + } + + static class laser_t { + entity_t ent = new entity_t(); + + int endtime; + + void clear() { + endtime = 0; + ent = new entity_t(); + } + } + + static { + for (int i = 0; i < cl_lasers.length; i++) + cl_lasers[i] = new laser_t(); + } + + static { + for (int i = 0; i < cl_sustains.length; i++) + cl_sustains[i] = new cl_sustain_t(); + } + + static final int ex_free = 0; + + static final int ex_explosion = 1; + + static final int ex_misc = 2; + + static final int ex_flash = 3; + + static final int ex_mflash = 4; + + static final int ex_poly = 5; + + static final int ex_poly2 = 6; + + // ROGUE + + // all are references; + static sfx_t cl_sfx_ric1; + + static sfx_t cl_sfx_ric2; + + static sfx_t cl_sfx_ric3; + + static sfx_t cl_sfx_lashit; + + static sfx_t cl_sfx_spark5; + + static sfx_t cl_sfx_spark6; + + static sfx_t cl_sfx_spark7; + + static sfx_t cl_sfx_railg; + + static sfx_t cl_sfx_rockexp; + + static sfx_t cl_sfx_grenexp; + + static sfx_t cl_sfx_watrexp; + + // RAFAEL + static sfx_t cl_sfx_plasexp; + + static sfx_t cl_sfx_footsteps[] = new sfx_t[4]; + + static model_t cl_mod_explode; + + static model_t cl_mod_smoke; + + static model_t cl_mod_flash; + + static model_t cl_mod_parasite_segment; + + static model_t cl_mod_grapple_cable; + + static model_t cl_mod_parasite_tip; + + static model_t cl_mod_explo4; + + static model_t cl_mod_bfg_explo; + + static model_t cl_mod_powerscreen; + + // RAFAEL + static model_t cl_mod_plasmaexplo; + + // ROGUE + static sfx_t cl_sfx_lightning; + + static sfx_t cl_sfx_disrexp; + + static model_t cl_mod_lightning; + + static model_t cl_mod_heatbeam; + + static model_t cl_mod_monster_heatbeam; + + static model_t cl_mod_explo4_big; + + // ROGUE + /* + * ================= CL_RegisterTEntSounds ================= + */ + static void RegisterTEntSounds() { + int i; + String name; + + // PMM - version stuff + // Com_Printf ("%s\n", ROGUE_VERSION_STRING); + // PMM + cl_sfx_ric1 = S.RegisterSound("world/ric1.wav"); + cl_sfx_ric2 = S.RegisterSound("world/ric2.wav"); + cl_sfx_ric3 = S.RegisterSound("world/ric3.wav"); + cl_sfx_lashit = S.RegisterSound("weapons/lashit.wav"); + cl_sfx_spark5 = S.RegisterSound("world/spark5.wav"); + cl_sfx_spark6 = S.RegisterSound("world/spark6.wav"); + cl_sfx_spark7 = S.RegisterSound("world/spark7.wav"); + cl_sfx_railg = S.RegisterSound("weapons/railgf1a.wav"); + cl_sfx_rockexp = S.RegisterSound("weapons/rocklx1a.wav"); + cl_sfx_grenexp = S.RegisterSound("weapons/grenlx1a.wav"); + cl_sfx_watrexp = S.RegisterSound("weapons/xpld_wat.wav"); + // RAFAEL + // cl_sfx_plasexp = S.RegisterSound ("weapons/plasexpl.wav"); + S.RegisterSound("player/land1.wav"); + + S.RegisterSound("player/fall2.wav"); + S.RegisterSound("player/fall1.wav"); + + for (i = 0; i < 4; i++) { + //Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1); + name = "player/step" + (i + 1) + ".wav"; + cl_sfx_footsteps[i] = S.RegisterSound(name); + } + + // PGM + cl_sfx_lightning = S.RegisterSound("weapons/tesla.wav"); + cl_sfx_disrexp = S.RegisterSound("weapons/disrupthit.wav"); + // version stuff + // sprintf (name, "weapons/sound%d.wav", ROGUE_VERSION_ID); + // if (name[0] == 'w') + // name[0] = 'W'; + // PGM + } + + /* + * ================= CL_RegisterTEntModels ================= + */ + static void RegisterTEntModels() { + cl_mod_explode = Globals.re + .RegisterModel("models/objects/explode/tris.md2"); + cl_mod_smoke = Globals.re + .RegisterModel("models/objects/smoke/tris.md2"); + cl_mod_flash = Globals.re + .RegisterModel("models/objects/flash/tris.md2"); + cl_mod_parasite_segment = Globals.re + .RegisterModel("models/monsters/parasite/segment/tris.md2"); + cl_mod_grapple_cable = Globals.re + .RegisterModel("models/ctf/segment/tris.md2"); + cl_mod_parasite_tip = Globals.re + .RegisterModel("models/monsters/parasite/tip/tris.md2"); + cl_mod_explo4 = Globals.re + .RegisterModel("models/objects/r_explode/tris.md2"); + cl_mod_bfg_explo = Globals.re.RegisterModel("sprites/s_bfg2.sp2"); + cl_mod_powerscreen = Globals.re + .RegisterModel("models/items/armor/effect/tris.md2"); + + Globals.re.RegisterModel("models/objects/laser/tris.md2"); + Globals.re.RegisterModel("models/objects/grenade2/tris.md2"); + Globals.re.RegisterModel("models/weapons/v_machn/tris.md2"); + Globals.re.RegisterModel("models/weapons/v_handgr/tris.md2"); + Globals.re.RegisterModel("models/weapons/v_shotg2/tris.md2"); + Globals.re.RegisterModel("models/objects/gibs/bone/tris.md2"); + Globals.re.RegisterModel("models/objects/gibs/sm_meat/tris.md2"); + Globals.re.RegisterModel("models/objects/gibs/bone2/tris.md2"); + // RAFAEL + // re.RegisterModel ("models/objects/blaser/tris.md2"); + + Globals.re.RegisterPic("w_machinegun"); + Globals.re.RegisterPic("a_bullets"); + Globals.re.RegisterPic("i_health"); + Globals.re.RegisterPic("a_grenades"); + + // ROGUE + cl_mod_explo4_big = Globals.re + .RegisterModel("models/objects/r_explode2/tris.md2"); + cl_mod_lightning = Globals.re + .RegisterModel("models/proj/lightning/tris.md2"); + cl_mod_heatbeam = Globals.re.RegisterModel("models/proj/beam/tris.md2"); + cl_mod_monster_heatbeam = Globals.re + .RegisterModel("models/proj/widowbeam/tris.md2"); + // ROGUE + } + + /* + * ================= CL_ClearTEnts ================= + */ + static void ClearTEnts() { + // memset (cl_beams, 0, sizeof(cl_beams)); + for (int i = 0; i < cl_beams.length; i++) + cl_beams[i].clear(); + // memset (cl_explosions, 0, sizeof(cl_explosions)); + for (int i = 0; i < cl_explosions.length; i++) + cl_explosions[i].clear(); + // memset (cl_lasers, 0, sizeof(cl_lasers)); + for (int i = 0; i < cl_lasers.length; i++) + cl_lasers[i].clear(); + // + // ROGUE + // memset (cl_playerbeams, 0, sizeof(cl_playerbeams)); + for (int i = 0; i < cl_playerbeams.length; i++) + cl_playerbeams[i].clear(); + // memset (cl_sustains, 0, sizeof(cl_sustains)); + for (int i = 0; i < cl_sustains.length; i++) + cl_sustains[i].clear(); + // ROGUE + } + + /* + * ================= CL_AllocExplosion ================= + */ + static explosion_t AllocExplosion() { + int i; + int time; + int index; + + for (i = 0; i < MAX_EXPLOSIONS; i++) { + if (cl_explosions[i].type == ex_free) { + //memset (&cl_explosions[i], 0, sizeof (cl_explosions[i])); + cl_explosions[i].clear(); + return cl_explosions[i]; + } + } + // find the oldest explosion + time = Globals.cl.time; + index = 0; + + for (i = 0; i < MAX_EXPLOSIONS; i++) + if (cl_explosions[i].start < time) { + time = (int) cl_explosions[i].start; + index = i; + } + //memset (&cl_explosions[index], 0, sizeof (cl_explosions[index])); + cl_explosions[index].clear(); + return cl_explosions[index]; + } + + /* + * ================= CL_SmokeAndFlash ================= + */ + static void SmokeAndFlash(float[] origin) { + explosion_t ex; + + ex = AllocExplosion(); + Math3D.VectorCopy(origin, ex.ent.origin); + ex.type = ex_misc; + ex.frames = 4; + ex.ent.flags = Defines.RF_TRANSLUCENT; + ex.start = Globals.cl.frame.servertime - 100; + ex.ent.model = cl_mod_smoke; + + ex = AllocExplosion(); + Math3D.VectorCopy(origin, ex.ent.origin); + ex.type = ex_flash; + ex.ent.flags = Defines.RF_FULLBRIGHT; + ex.frames = 2; + ex.start = Globals.cl.frame.servertime - 100; + ex.ent.model = cl_mod_flash; + } + + /* + * ================= CL_ParseParticles ================= + */ + static void ParseParticles() { + int color, count; + float[] pos = new float[3]; + float[] dir = new float[3]; + + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + + color = MSG.ReadByte(Globals.net_message); + + count = MSG.ReadByte(Globals.net_message); + + CL_fx.ParticleEffect(pos, dir, color, count); + } + + /* + * ================= CL_ParseBeam ================= + */ + static int ParseBeam(model_t model) { + int ent; + float[] start = new float[3]; + float[] end = new float[3]; + beam_t[] b; + int i; + + ent = MSG.ReadShort(Globals.net_message); + + MSG.ReadPos(Globals.net_message, start); + MSG.ReadPos(Globals.net_message, end); + + // override any beam with the same entity + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) + if (b[i].entity == ent) { + b[i].entity = ent; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorClear(b[i].offset); + return ent; + } + + // find a free beam + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) { + if (b[i].model == null || b[i].endtime < Globals.cl.time) { + b[i].entity = ent; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorClear(b[i].offset); + return ent; + } + } + Com.Printf("beam list overflow!\n"); + return ent; + } + + /* + * ================= CL_ParseBeam2 ================= + */ + static int ParseBeam2(model_t model) { + int ent; + float[] start = new float[3]; + float[] end = new float[3]; + float[] offset = new float[3]; + beam_t[] b; + int i; + + ent = MSG.ReadShort(Globals.net_message); + + MSG.ReadPos(Globals.net_message, start); + MSG.ReadPos(Globals.net_message, end); + MSG.ReadPos(Globals.net_message, offset); + + // Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]); + + // override any beam with the same entity + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) + if (b[i].entity == ent) { + b[i].entity = ent; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorCopy(offset, b[i].offset); + return ent; + } + + // find a free beam + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) { + if (b[i].model == null || b[i].endtime < Globals.cl.time) { + b[i].entity = ent; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorCopy(offset, b[i].offset); + return ent; + } + } + Com.Printf("beam list overflow!\n"); + return ent; + } + + // ROGUE + /* + * ================= CL_ParsePlayerBeam - adds to the cl_playerbeam array + * instead of the cl_beams array ================= + */ + static int ParsePlayerBeam(model_t model) { + int ent; + float[] start = new float[3]; + float[] end = new float[3]; + float[] offset = new float[3]; + beam_t[] b; + int i; + + ent = MSG.ReadShort(Globals.net_message); + + MSG.ReadPos(Globals.net_message, start); + MSG.ReadPos(Globals.net_message, end); + // PMM - network optimization + if (model == cl_mod_heatbeam) + Math3D.VectorSet(offset, 2, 7, -3); + else if (model == cl_mod_monster_heatbeam) { + model = cl_mod_heatbeam; + Math3D.VectorSet(offset, 0, 0, 0); + } else + MSG.ReadPos(Globals.net_message, offset); + + // Com_Printf ("end- %f %f %f\n", end[0], end[1], end[2]); + + // override any beam with the same entity + // PMM - For player beams, we only want one per player (entity) so.. + b = cl_playerbeams; + for (i = 0; i < MAX_BEAMS; i++) { + if (b[i].entity == ent) { + b[i].entity = ent; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorCopy(offset, b[i].offset); + return ent; + } + } + + // find a free beam + b = cl_playerbeams; + for (i = 0; i < MAX_BEAMS; i++) { + if (b[i].model == null || b[i].endtime < Globals.cl.time) { + b[i].entity = ent; + b[i].model = model; + b[i].endtime = Globals.cl.time + 100; // PMM - this needs to be + // 100 to prevent multiple + // heatbeams + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorCopy(offset, b[i].offset); + return ent; + } + } + Com.Printf("beam list overflow!\n"); + return ent; + } + + // rogue + + /* + * ================= CL_ParseLightning ================= + */ + static int ParseLightning(model_t model) { + int srcEnt, destEnt; + float[] start = new float[3]; + float[] end = new float[3]; + beam_t[] b; + int i; + + srcEnt = MSG.ReadShort(Globals.net_message); + destEnt = MSG.ReadShort(Globals.net_message); + + MSG.ReadPos(Globals.net_message, start); + MSG.ReadPos(Globals.net_message, end); + + // override any beam with the same source AND destination entities + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) + if (b[i].entity == srcEnt && b[i].dest_entity == destEnt) { + // Com_Printf("%d: OVERRIDE %d . %d\n", cl.time, srcEnt, + // destEnt); + b[i].entity = srcEnt; + b[i].dest_entity = destEnt; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorClear(b[i].offset); + return srcEnt; + } + + // find a free beam + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) { + if (b[i].model == null || b[i].endtime < Globals.cl.time) { + // Com_Printf("%d: NORMAL %d . %d\n", cl.time, srcEnt, destEnt); + b[i].entity = srcEnt; + b[i].dest_entity = destEnt; + b[i].model = model; + b[i].endtime = Globals.cl.time + 200; + Math3D.VectorCopy(start, b[i].start); + Math3D.VectorCopy(end, b[i].end); + Math3D.VectorClear(b[i].offset); + return srcEnt; + } + } + Com.Printf("beam list overflow!\n"); + return srcEnt; + } + + /* + * ================= CL_ParseLaser ================= + */ + static void ParseLaser(int colors) { + float[] start = new float[3]; + float[] end = new float[3]; + laser_t[] l; + int i; + + MSG.ReadPos(Globals.net_message, start); + MSG.ReadPos(Globals.net_message, end); + + l = cl_lasers; + for (i = 0; i < MAX_LASERS; i++) { + if (l[i].endtime < Globals.cl.time) { + l[i].ent.flags = Defines.RF_TRANSLUCENT | Defines.RF_BEAM; + Math3D.VectorCopy(start, l[i].ent.origin); + Math3D.VectorCopy(end, l[i].ent.oldorigin); + l[i].ent.alpha = 0.30f; + l[i].ent.skinnum = (colors >> ((Lib.rand() % 4) * 8)) & 0xff; + l[i].ent.model = null; + l[i].ent.frame = 4; + l[i].endtime = Globals.cl.time + 100; + return; + } + } + } + + // ============= + // ROGUE + static void ParseSteam() { + float[] pos = new float[3]; + float[] dir = new float[3]; + int id, i; + int r; + int cnt; + int color; + int magnitude; + cl_sustain_t[] s; + cl_sustain_t free_sustain; + + id = MSG.ReadShort(Globals.net_message); // an id of -1 is an instant + // effect + if (id != -1) // sustains + { + // Com_Printf ("Sustain effect id %d\n", id); + free_sustain = null; + s = cl_sustains; + for (i = 0; i < MAX_SUSTAINS; i++) { + if (s[i].id == 0) { + free_sustain = s[i]; + break; + } + } + if (free_sustain != null) { + s[i].id = id; + s[i].count = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, s[i].org); + MSG.ReadDir(Globals.net_message, s[i].dir); + r = MSG.ReadByte(Globals.net_message); + s[i].color = r & 0xff; + s[i].magnitude = MSG.ReadShort(Globals.net_message); + s[i].endtime = Globals.cl.time + + MSG.ReadLong(Globals.net_message); + s[i].think = new cl_sustain_t.ThinkAdapter() { + void think(cl_sustain_t self) { + CL_newfx.ParticleSteamEffect2(self); + } + }; + s[i].thinkinterval = 100; + s[i].nextthink = Globals.cl.time; + } else { + // Com_Printf ("No free sustains!\n"); + // FIXME - read the stuff anyway + cnt = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + r = MSG.ReadByte(Globals.net_message); + magnitude = MSG.ReadShort(Globals.net_message); + magnitude = MSG.ReadLong(Globals.net_message); // really + // interval + } + } else // instant + { + cnt = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + r = MSG.ReadByte(Globals.net_message); + magnitude = MSG.ReadShort(Globals.net_message); + color = r & 0xff; + CL_newfx.ParticleSteamEffect(pos, dir, color, cnt, magnitude); + // S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0); + } + } + + static void ParseWidow() { + float[] pos = new float[3]; + int id, i; + cl_sustain_t[] s; + cl_sustain_t free_sustain; + + id = MSG.ReadShort(Globals.net_message); + + free_sustain = null; + s = cl_sustains; + for (i = 0; i < MAX_SUSTAINS; i++) { + if (s[i].id == 0) { + free_sustain = s[i]; + break; + } + } + if (free_sustain != null) { + s[i].id = id; + MSG.ReadPos(Globals.net_message, s[i].org); + s[i].endtime = Globals.cl.time + 2100; + s[i].think = new cl_sustain_t.ThinkAdapter() { + void think(cl_sustain_t self) { + CL_newfx.Widowbeamout(self); + } + }; + s[i].thinkinterval = 1; + s[i].nextthink = Globals.cl.time; + } else // no free sustains + { + // FIXME - read the stuff anyway + MSG.ReadPos(Globals.net_message, pos); + } + } + + static void ParseNuke() { + float[] pos = new float[3]; + int i; + cl_sustain_t[] s; + cl_sustain_t free_sustain; + + free_sustain = null; + s = cl_sustains; + for (i = 0; i < MAX_SUSTAINS; i++) { + if (s[i].id == 0) { + free_sustain = s[i]; + break; + } + } + if (free_sustain != null) { + s[i].id = 21000; + MSG.ReadPos(Globals.net_message, s[i].org); + s[i].endtime = Globals.cl.time + 1000; + s[i].think = new cl_sustain_t.ThinkAdapter() { + void think(cl_sustain_t self) { + CL_newfx.Nukeblast(self); + } + }; + s[i].thinkinterval = 1; + s[i].nextthink = Globals.cl.time; + } else // no free sustains + { + // FIXME - read the stuff anyway + MSG.ReadPos(Globals.net_message, pos); + } + } + + // ROGUE + // ============= + + /* + * ================= CL_ParseTEnt ================= + */ + static int[] splash_color = { 0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8 }; + + static void ParseTEnt() { + int type; + float[] pos = new float[3]; + float[] pos2 = new float[3]; + float[] dir = new float[3]; + explosion_t ex; + int cnt; + int color; + int r; + int ent; + int magnitude; + + type = MSG.ReadByte(Globals.net_message); + + switch (type) { + case Defines.TE_BLOOD: // bullet hitting flesh + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + CL_fx.ParticleEffect(pos, dir, 0xe8, 60); + break; + + case Defines.TE_GUNSHOT: // bullet hitting wall + case Defines.TE_SPARKS: + case Defines.TE_BULLET_SPARKS: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + if (type == Defines.TE_GUNSHOT) + CL_fx.ParticleEffect(pos, dir, 0, 40); + else + CL_fx.ParticleEffect(pos, dir, 0xe0, 6); + + if (type != Defines.TE_SPARKS) { + SmokeAndFlash(pos); + + // impact sound + cnt = Lib.rand() & 15; + if (cnt == 1) + S.StartSound(pos, 0, 0, cl_sfx_ric1, 1, Defines.ATTN_NORM, + 0); + else if (cnt == 2) + S.StartSound(pos, 0, 0, cl_sfx_ric2, 1, Defines.ATTN_NORM, + 0); + else if (cnt == 3) + S.StartSound(pos, 0, 0, cl_sfx_ric3, 1, Defines.ATTN_NORM, + 0); + } + + break; + + case Defines.TE_SCREEN_SPARKS: + case Defines.TE_SHIELD_SPARKS: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + if (type == Defines.TE_SCREEN_SPARKS) + CL_fx.ParticleEffect(pos, dir, 0xd0, 40); + else + CL_fx.ParticleEffect(pos, dir, 0xb0, 40); + //FIXME : replace or remove this sound + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_SHOTGUN: // bullet hitting wall + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + CL_fx.ParticleEffect(pos, dir, 0, 20); + SmokeAndFlash(pos); + break; + + case Defines.TE_SPLASH: // bullet hitting water + cnt = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + r = MSG.ReadByte(Globals.net_message); + if (r > 6) + color = 0x00; + else + color = splash_color[r]; + CL_fx.ParticleEffect(pos, dir, color, cnt); + + if (r == Defines.SPLASH_SPARKS) { + r = Lib.rand() & 3; + if (r == 0) + S.StartSound(pos, 0, 0, cl_sfx_spark5, 1, + Defines.ATTN_STATIC, 0); + else if (r == 1) + S.StartSound(pos, 0, 0, cl_sfx_spark6, 1, + Defines.ATTN_STATIC, 0); + else + S.StartSound(pos, 0, 0, cl_sfx_spark7, 1, + Defines.ATTN_STATIC, 0); + } + break; + + case Defines.TE_LASER_SPARKS: + cnt = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + color = MSG.ReadByte(Globals.net_message); + CL_fx.ParticleEffect2(pos, dir, color, cnt); + break; + + // RAFAEL + case Defines.TE_BLUEHYPERBLASTER: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadPos(Globals.net_message, dir); + CL_fx.BlasterParticles(pos, dir); + break; + + case Defines.TE_BLASTER: // blaster hitting wall + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + CL_fx.BlasterParticles(pos, dir); + + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.ent.angles[0] = (float) (Math.acos(dir[2]) / Math.PI * 180); + // PMM - fixed to correct for pitch of 0 + if (dir[0] != 0.0f) + ex.ent.angles[1] = (float) (Math.atan2(dir[1], dir[0]) + / Math.PI * 180); + else if (dir[1] > 0) + ex.ent.angles[1] = 90; + else if (dir[1] < 0) + ex.ent.angles[1] = 270; + else + ex.ent.angles[1] = 0; + + ex.type = ex_misc; + ex.ent.flags = Defines.RF_FULLBRIGHT | Defines.RF_TRANSLUCENT; + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 150; + ex.lightcolor[0] = 1; + ex.lightcolor[1] = 1; + ex.ent.model = cl_mod_explode; + ex.frames = 4; + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_RAILTRAIL: // railgun effect + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadPos(Globals.net_message, pos2); + CL_fx.RailTrail(pos, pos2); + S.StartSound(pos2, 0, 0, cl_sfx_railg, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_EXPLOSION2: + case Defines.TE_GRENADE_EXPLOSION: + case Defines.TE_GRENADE_EXPLOSION_WATER: + MSG.ReadPos(Globals.net_message, pos); + + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.type = ex_poly; + ex.ent.flags = Defines.RF_FULLBRIGHT; + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 350; + ex.lightcolor[0] = 1.0f; + ex.lightcolor[1] = 0.5f; + ex.lightcolor[2] = 0.5f; + ex.ent.model = cl_mod_explo4; + ex.frames = 19; + ex.baseframe = 30; + ex.ent.angles[1] = Lib.rand() % 360; + CL_fx.ExplosionParticles(pos); + if (type == Defines.TE_GRENADE_EXPLOSION_WATER) + S + .StartSound(pos, 0, 0, cl_sfx_watrexp, 1, + Defines.ATTN_NORM, 0); + else + S + .StartSound(pos, 0, 0, cl_sfx_grenexp, 1, + Defines.ATTN_NORM, 0); + break; + + // RAFAEL + case Defines.TE_PLASMA_EXPLOSION: + MSG.ReadPos(Globals.net_message, pos); + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.type = ex_poly; + ex.ent.flags = Defines.RF_FULLBRIGHT; + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 350; + ex.lightcolor[0] = 1.0f; + ex.lightcolor[1] = 0.5f; + ex.lightcolor[2] = 0.5f; + ex.ent.angles[1] = Lib.rand() % 360; + ex.ent.model = cl_mod_explo4; + if (Globals.rnd.nextFloat() < 0.5) + ex.baseframe = 15; + ex.frames = 15; + CL_fx.ExplosionParticles(pos); + S.StartSound(pos, 0, 0, cl_sfx_rockexp, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_EXPLOSION1: + case Defines.TE_EXPLOSION1_BIG: // PMM + case Defines.TE_ROCKET_EXPLOSION: + case Defines.TE_ROCKET_EXPLOSION_WATER: + case Defines.TE_EXPLOSION1_NP: // PMM + MSG.ReadPos(Globals.net_message, pos); + + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.type = ex_poly; + ex.ent.flags = Defines.RF_FULLBRIGHT; + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 350; + ex.lightcolor[0] = 1.0f; + ex.lightcolor[1] = 0.5f; + ex.lightcolor[2] = 0.5f; + ex.ent.angles[1] = Lib.rand() % 360; + if (type != Defines.TE_EXPLOSION1_BIG) // PMM + ex.ent.model = cl_mod_explo4; // PMM + else + ex.ent.model = cl_mod_explo4_big; + if (Globals.rnd.nextFloat() < 0.5) + ex.baseframe = 15; + ex.frames = 15; + if ((type != Defines.TE_EXPLOSION1_BIG) + && (type != Defines.TE_EXPLOSION1_NP)) // PMM + CL_fx.ExplosionParticles(pos); // PMM + if (type == Defines.TE_ROCKET_EXPLOSION_WATER) + S + .StartSound(pos, 0, 0, cl_sfx_watrexp, 1, + Defines.ATTN_NORM, 0); + else + S + .StartSound(pos, 0, 0, cl_sfx_rockexp, 1, + Defines.ATTN_NORM, 0); + break; + + case Defines.TE_BFG_EXPLOSION: + MSG.ReadPos(Globals.net_message, pos); + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.type = ex_poly; + ex.ent.flags = Defines.RF_FULLBRIGHT; + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 350; + ex.lightcolor[0] = 0.0f; + ex.lightcolor[1] = 1.0f; + ex.lightcolor[2] = 0.0f; + ex.ent.model = cl_mod_bfg_explo; + ex.ent.flags |= Defines.RF_TRANSLUCENT; + ex.ent.alpha = 0.30f; + ex.frames = 4; + break; + + case Defines.TE_BFG_BIGEXPLOSION: + MSG.ReadPos(Globals.net_message, pos); + CL_fx.BFGExplosionParticles(pos); + break; + + case Defines.TE_BFG_LASER: + ParseLaser(0xd0d1d2d3); + break; + + case Defines.TE_BUBBLETRAIL: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadPos(Globals.net_message, pos2); + CL_fx.BubbleTrail(pos, pos2); + break; + + case Defines.TE_PARASITE_ATTACK: + case Defines.TE_MEDIC_CABLE_ATTACK: + ent = ParseBeam(cl_mod_parasite_segment); + break; + + case Defines.TE_BOSSTPORT: // boss teleporting to station + MSG.ReadPos(Globals.net_message, pos); + CL_fx.BigTeleportParticles(pos); + S.StartSound(pos, 0, 0, S.RegisterSound("misc/bigtele.wav"), 1, + Defines.ATTN_NONE, 0); + break; + + case Defines.TE_GRAPPLE_CABLE: + ent = ParseBeam2(cl_mod_grapple_cable); + break; + + // RAFAEL + case Defines.TE_WELDING_SPARKS: + cnt = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + color = MSG.ReadByte(Globals.net_message); + CL_fx.ParticleEffect2(pos, dir, color, cnt); + + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.type = ex_flash; + // note to self + // we need a better no draw flag + ex.ent.flags = Defines.RF_BEAM; + ex.start = Globals.cl.frame.servertime - 0.1f; + ex.light = 100 + (Lib.rand() % 75); + ex.lightcolor[0] = 1.0f; + ex.lightcolor[1] = 1.0f; + ex.lightcolor[2] = 0.3f; + ex.ent.model = cl_mod_flash; + ex.frames = 2; + break; + + case Defines.TE_GREENBLOOD: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + CL_fx.ParticleEffect2(pos, dir, 0xdf, 30); + break; + + // RAFAEL + case Defines.TE_TUNNEL_SPARKS: + cnt = MSG.ReadByte(Globals.net_message); + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + color = MSG.ReadByte(Globals.net_message); + CL_fx.ParticleEffect3(pos, dir, color, cnt); + break; + + // ============= + // PGM + // PMM -following code integrated for flechette (different color) + case Defines.TE_BLASTER2: // green blaster hitting wall + case Defines.TE_FLECHETTE: // flechette + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + + // PMM + if (type == Defines.TE_BLASTER2) + CL_newfx.BlasterParticles2(pos, dir, 0xd0); + else + CL_newfx.BlasterParticles2(pos, dir, 0x6f); // 75 + + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.ent.angles[0] = (float) (Math.acos(dir[2]) / Math.PI * 180); + // PMM - fixed to correct for pitch of 0 + if (dir[0] != 0.0f) + ex.ent.angles[1] = (float) (Math.atan2(dir[1], dir[0]) + / Math.PI * 180); + else if (dir[1] > 0) + ex.ent.angles[1] = 90; + else if (dir[1] < 0) + ex.ent.angles[1] = 270; + else + ex.ent.angles[1] = 0; + + ex.type = ex_misc; + ex.ent.flags = Defines.RF_FULLBRIGHT | Defines.RF_TRANSLUCENT; + + // PMM + if (type == Defines.TE_BLASTER2) + ex.ent.skinnum = 1; + else + // flechette + ex.ent.skinnum = 2; + + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 150; + // PMM + if (type == Defines.TE_BLASTER2) + ex.lightcolor[1] = 1; + else // flechette + { + ex.lightcolor[0] = 0.19f; + ex.lightcolor[1] = 0.41f; + ex.lightcolor[2] = 0.75f; + } + ex.ent.model = cl_mod_explode; + ex.frames = 4; + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_LIGHTNING: + ent = ParseLightning(cl_mod_lightning); + S.StartSound(null, ent, Defines.CHAN_WEAPON, cl_sfx_lightning, 1, + Defines.ATTN_NORM, 0); + break; + + case Defines.TE_DEBUGTRAIL: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadPos(Globals.net_message, pos2); + CL_newfx.DebugTrail(pos, pos2); + break; + + case Defines.TE_PLAIN_EXPLOSION: + MSG.ReadPos(Globals.net_message, pos); + + ex = AllocExplosion(); + Math3D.VectorCopy(pos, ex.ent.origin); + ex.type = ex_poly; + ex.ent.flags = Defines.RF_FULLBRIGHT; + ex.start = Globals.cl.frame.servertime - 100; + ex.light = 350; + ex.lightcolor[0] = 1.0f; + ex.lightcolor[1] = 0.5f; + ex.lightcolor[2] = 0.5f; + ex.ent.angles[1] = Lib.rand() % 360; + ex.ent.model = cl_mod_explo4; + if (Globals.rnd.nextFloat() < 0.5) + ex.baseframe = 15; + ex.frames = 15; + if (type == Defines.TE_ROCKET_EXPLOSION_WATER) + S + .StartSound(pos, 0, 0, cl_sfx_watrexp, 1, + Defines.ATTN_NORM, 0); + else + S + .StartSound(pos, 0, 0, cl_sfx_rockexp, 1, + Defines.ATTN_NORM, 0); + break; + + case Defines.TE_FLASHLIGHT: + MSG.ReadPos(Globals.net_message, pos); + ent = MSG.ReadShort(Globals.net_message); + CL_newfx.Flashlight(ent, pos); + break; + + case Defines.TE_FORCEWALL: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadPos(Globals.net_message, pos2); + color = MSG.ReadByte(Globals.net_message); + CL_newfx.ForceWall(pos, pos2, color); + break; + + case Defines.TE_HEATBEAM: + ent = ParsePlayerBeam(cl_mod_heatbeam); + break; + + case Defines.TE_MONSTER_HEATBEAM: + ent = ParsePlayerBeam(cl_mod_monster_heatbeam); + break; + + case Defines.TE_HEATBEAM_SPARKS: + // cnt = MSG.ReadByte (net_message); + cnt = 50; + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + // r = MSG.ReadByte (net_message); + // magnitude = MSG.ReadShort (net_message); + r = 8; + magnitude = 60; + color = r & 0xff; + CL_newfx.ParticleSteamEffect(pos, dir, color, cnt, magnitude); + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_HEATBEAM_STEAM: + // cnt = MSG.ReadByte (net_message); + cnt = 20; + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + // r = MSG.ReadByte (net_message); + // magnitude = MSG.ReadShort (net_message); + // color = r & 0xff; + color = 0xe0; + magnitude = 60; + CL_newfx.ParticleSteamEffect(pos, dir, color, cnt, magnitude); + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_STEAM: + ParseSteam(); + break; + + case Defines.TE_BUBBLETRAIL2: + // cnt = MSG.ReadByte (net_message); + cnt = 8; + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadPos(Globals.net_message, pos2); + CL_newfx.BubbleTrail2(pos, pos2, cnt); + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_MOREBLOOD: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + CL_fx.ParticleEffect(pos, dir, 0xe8, 250); + break; + + case Defines.TE_CHAINFIST_SMOKE: + dir[0] = 0; + dir[1] = 0; + dir[2] = 1; + MSG.ReadPos(Globals.net_message, pos); + CL_newfx.ParticleSmokeEffect(pos, dir, 0, 20, 20); + break; + + case Defines.TE_ELECTRIC_SPARKS: + MSG.ReadPos(Globals.net_message, pos); + MSG.ReadDir(Globals.net_message, dir); + // CL_ParticleEffect (pos, dir, 109, 40); + CL_fx.ParticleEffect(pos, dir, 0x75, 40); + //FIXME : replace or remove this sound + S.StartSound(pos, 0, 0, cl_sfx_lashit, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_TRACKER_EXPLOSION: + MSG.ReadPos(Globals.net_message, pos); + CL_newfx.ColorFlash(pos, 0, 150, -1, -1, -1); + CL_newfx.ColorExplosionParticles(pos, 0, 1); + // CL_Tracker_Explode (pos); + S.StartSound(pos, 0, 0, cl_sfx_disrexp, 1, Defines.ATTN_NORM, 0); + break; + + case Defines.TE_TELEPORT_EFFECT: + case Defines.TE_DBALL_GOAL: + MSG.ReadPos(Globals.net_message, pos); + CL_fx.TeleportParticles(pos); + break; + + case Defines.TE_WIDOWBEAMOUT: + ParseWidow(); + break; + + case Defines.TE_NUKEBLAST: + ParseNuke(); + break; + + case Defines.TE_WIDOWSPLASH: + MSG.ReadPos(Globals.net_message, pos); + CL_newfx.WidowSplash(pos); + break; + // PGM + // ============== + + default: + Com.Error(Defines.ERR_DROP, "CL_ParseTEnt: bad type"); + } + } + + /* + * ================= CL_AddBeams ================= + */ + static void AddBeams() { + int i, j; + beam_t[] b; + float[] dist = new float[3]; + float[] org = new float[3]; + float d; + entity_t ent = new entity_t(); + float yaw, pitch; + float forward; + float len, steps; + float model_length; + + // update beams + b = cl_beams; + for (i = 0; i < MAX_BEAMS; i++) { + if (b[i].model == null || b[i].endtime < Globals.cl.time) + continue; + + // if coming from the player, update the start position + if (b[i].entity == Globals.cl.playernum + 1) // entity 0 is the + // world + { + Math3D.VectorCopy(Globals.cl.refdef.vieworg, b[i].start); + b[i].start[2] -= 22; // adjust for view height + } + Math3D.VectorAdd(b[i].start, b[i].offset, org); + + // calculate pitch and yaw + Math3D.VectorSubtract(b[i].end, org, dist); + + if (dist[1] == 0 && dist[0] == 0) { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } else { + // PMM - fixed to correct for pitch of 0 + if (dist[0] != 0.0f) + yaw = (float) (Math.atan2(dist[1], dist[0]) * 180 / Math.PI); + else if (dist[1] > 0) + yaw = 90; + else + yaw = 270; + if (yaw < 0) + yaw += 360; + + forward = (float) Math.sqrt(dist[0] * dist[0] + dist[1] + * dist[1]); + pitch = (float) (Math.atan2(dist[2], forward) * -180.0 / Math.PI); + if (pitch < 0) + pitch += 360.0; + } + + // add new entities for the beams + d = Math3D.VectorNormalize(dist); + + //memset (&ent, 0, sizeof(ent)); + ent = new entity_t(); + if (b[i].model == cl_mod_lightning) { + model_length = 35.0f; + d -= 20.0; // correction so it doesn't end in middle of tesla + } else { + model_length = 30.0f; + } + steps = (float) Math.ceil(d / model_length); + len = (d - model_length) / (steps - 1); + + // PMM - special case for lightning model .. if the real length is + // shorter than the model, + // flip it around & draw it from the end to the start. This prevents + // the model from going + // through the tesla mine (instead it goes through the target) + if ((b[i].model == cl_mod_lightning) && (d <= model_length)) { + // Com_Printf ("special case\n"); + Math3D.VectorCopy(b[i].end, ent.origin); + // offset to push beam outside of tesla model (negative because + // dist is from end to start + // for this beam) + // for (j=0 ; j<3 ; j++) + // ent.origin[j] -= dist[j]*10.0; + ent.model = b[i].model; + ent.flags = Defines.RF_FULLBRIGHT; + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = Lib.rand() % 360; + V.AddEntity(ent); + return; + } + while (d > 0) { + Math3D.VectorCopy(org, ent.origin); + ent.model = b[i].model; + if (b[i].model == cl_mod_lightning) { + ent.flags = Defines.RF_FULLBRIGHT; + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0f; + ent.angles[2] = Lib.rand() % 360; + } else { + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = Lib.rand() % 360; + } + + // Com_Printf("B: %d . %d\n", b[i].entity, b[i].dest_entity); + V.AddEntity(ent); + + for (j = 0; j < 3; j++) + org[j] += dist[j] * len; + d -= model_length; + } + } + } + + //extern cvar_t *hand; + + /* + * ================= ROGUE - draw player locked beams CL_AddPlayerBeams + * ================= + */ + static void AddPlayerBeams() { + float[] dist = new float[3]; + float[] org = new float[3]; + float d; + entity_t ent = new entity_t(); + float yaw, pitch; + float forward; + float len, steps; + int framenum = 0; + float model_length; + + float hand_multiplier; + frame_t oldframe; + player_state_t ps, ops; + + // PMM + if (Globals.hand != null) { + if (Globals.hand.value == 2) + hand_multiplier = 0; + else if (Globals.hand.value == 1) + hand_multiplier = -1; + else + hand_multiplier = 1; + } else { + hand_multiplier = 1; + } + // PMM + + // update beams + beam_t[] b = cl_playerbeams; + float[] f = new float[3]; + float[] u = new float[3]; + float[] r = new float[3]; + for (int i = 0; i < MAX_BEAMS; i++) { + + if (b[i].model == null || b[i].endtime < Globals.cl.time) + continue; + + if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam)) { + + // if coming from the player, update the start position + if (b[i].entity == Globals.cl.playernum + 1) // entity 0 is the + // world + { + // set up gun position + // code straight out of CL_AddViewWeapon + ps = Globals.cl.frame.playerstate; + int j = (Globals.cl.frame.serverframe - 1) + & Defines.UPDATE_MASK; + oldframe = Globals.cl.frames[j]; + + if (oldframe.serverframe != Globals.cl.frame.serverframe - 1 + || !oldframe.valid) + oldframe = Globals.cl.frame; // previous frame was + // dropped or involid + + ops = oldframe.playerstate; + for (j = 0; j < 3; j++) { + b[i].start[j] = Globals.cl.refdef.vieworg[j] + + ops.gunoffset[j] + Globals.cl.lerpfrac + * (ps.gunoffset[j] - ops.gunoffset[j]); + } + Math3D.VectorMA(b[i].start, + (hand_multiplier * b[i].offset[0]), + Globals.cl.v_right, org); + Math3D.VectorMA(org, b[i].offset[1], Globals.cl.v_forward, + org); + Math3D.VectorMA(org, b[i].offset[2], Globals.cl.v_up, org); + if ((Globals.hand != null) && (Globals.hand.value == 2)) { + Math3D.VectorMA(org, -1, Globals.cl.v_up, org); + } + // FIXME - take these out when final + Math3D.VectorCopy(Globals.cl.v_right, r); + Math3D.VectorCopy(Globals.cl.v_forward, f); + Math3D.VectorCopy(Globals.cl.v_up, u); + + } else + Math3D.VectorCopy(b[i].start, org); + } else { + // if coming from the player, update the start position + if (b[i].entity == Globals.cl.playernum + 1) // entity 0 is the + // world + { + Math3D.VectorCopy(Globals.cl.refdef.vieworg, b[i].start); + b[i].start[2] -= 22; // adjust for view height + } + Math3D.VectorAdd(b[i].start, b[i].offset, org); + } + + // calculate pitch and yaw + Math3D.VectorSubtract(b[i].end, org, dist); + + // PMM + if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam) + && (b[i].entity == Globals.cl.playernum + 1)) { + + len = Math3D.VectorLength(dist); + Math3D.VectorScale(f, len, dist); + Math3D.VectorMA(dist, (hand_multiplier * b[i].offset[0]), r, + dist); + Math3D.VectorMA(dist, b[i].offset[1], f, dist); + Math3D.VectorMA(dist, b[i].offset[2], u, dist); + if ((Globals.hand != null) && (Globals.hand.value == 2)) { + Math3D.VectorMA(org, -1, Globals.cl.v_up, org); + } + } + // PMM + + if (dist[1] == 0 && dist[0] == 0) { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } else { + // PMM - fixed to correct for pitch of 0 + if (dist[0] != 0.0f) + yaw = (float) (Math.atan2(dist[1], dist[0]) * 180 / Math.PI); + else if (dist[1] > 0) + yaw = 90; + else + yaw = 270; + if (yaw < 0) + yaw += 360; + + forward = (float) Math.sqrt(dist[0] * dist[0] + dist[1] + * dist[1]); + pitch = (float) (Math.atan2(dist[2], forward) * -180.0 / Math.PI); + if (pitch < 0) + pitch += 360.0; + } + + if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam)) { + if (b[i].entity != Globals.cl.playernum + 1) { + framenum = 2; + // Com_Printf ("Third person\n"); + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0f; + ent.angles[2] = 0; + // Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, + // b[i].offset[0], b[i].offset[1], b[i].offset[2]); + Math3D.AngleVectors(ent.angles, f, r, u); + + // if it's a non-origin offset, it's a player, so use the + // hardcoded player offset + if (Math3D.VectorCompare(b[i].offset, Globals.vec3_origin) == 0) { + Math3D.VectorMA(org, -(b[i].offset[0]) + 1, r, org); + Math3D.VectorMA(org, -(b[i].offset[1]), f, org); + Math3D.VectorMA(org, -(b[i].offset[2]) - 10, u, org); + } else { + // if it's a monster, do the particle effect + CL_newfx.MonsterPlasma_Shell(b[i].start); + } + } else { + framenum = 1; + } + } + + // if it's the heatbeam, draw the particle effect + if ((cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam) && (b[i].entity == Globals.cl.playernum + 1))) { + CL_newfx.Heatbeam(org, dist); + } + + // add new entities for the beams + d = Math3D.VectorNormalize(dist); + + //memset (&ent, 0, sizeof(ent)); + //ent = new entity_t(); + // this is not required. hoz + + if (b[i].model == cl_mod_heatbeam) { + model_length = 32.0f; + } else if (b[i].model == cl_mod_lightning) { + model_length = 35.0f; + d -= 20.0; // correction so it doesn't end in middle of tesla + } else { + model_length = 30.0f; + } + steps = (float) Math.ceil(d / model_length); + len = (d - model_length) / (steps - 1); + + // PMM - special case for lightning model .. if the real length is + // shorter than the model, + // flip it around & draw it from the end to the start. This prevents + // the model from going + // through the tesla mine (instead it goes through the target) + if ((b[i].model == cl_mod_lightning) && (d <= model_length)) { + // Com_Printf ("special case\n"); + Math3D.VectorCopy(b[i].end, ent.origin); + // offset to push beam outside of tesla model (negative because + // dist is from end to start + // for this beam) + // for (j=0 ; j<3 ; j++) + // ent.origin[j] -= dist[j]*10.0; + ent.model = b[i].model; + ent.flags = Defines.RF_FULLBRIGHT; + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = Lib.rand() % 360; + V.AddEntity(ent); + return; + } + while (d > 0) { + Math3D.VectorCopy(org, ent.origin); + ent.model = b[i].model; + if (cl_mod_heatbeam != null && (b[i].model == cl_mod_heatbeam)) { + // ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT; + // ent.alpha = 0.3; + ent.flags = Defines.RF_FULLBRIGHT; + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0f; + ent.angles[2] = (Globals.cl.time) % 360; + // ent.angles[2] = rand()%360; + ent.frame = framenum; + } else if (b[i].model == cl_mod_lightning) { + ent.flags = Defines.RF_FULLBRIGHT; + ent.angles[0] = -pitch; + ent.angles[1] = yaw + 180.0f; + ent.angles[2] = Lib.rand() % 360; + } else { + ent.angles[0] = pitch; + ent.angles[1] = yaw; + ent.angles[2] = Lib.rand() % 360; + } + + // Com_Printf("B: %d . %d\n", b[i].entity, b[i].dest_entity); + V.AddEntity(ent); + + for (int j = 0; j < 3; j++) + org[j] += dist[j] * len; + d -= model_length; + } + } + } + + /* + * ================= CL_AddExplosions ================= + */ + static void AddExplosions() { + entity_t ent; + int i; + explosion_t[] ex; + float frac; + int f; + + //memset (&ent, 0, sizeof(ent)); Pointer! + ent = null; + ex = cl_explosions; + for (i = 0; i < MAX_EXPLOSIONS; i++) { + if (ex[i].type == ex_free) + continue; + frac = (Globals.cl.time - ex[i].start) / 100.0f; + f = (int) Math.floor(frac); + + ent = ex[i].ent; + + switch (ex[i].type) { + case ex_mflash: + if (f >= ex[i].frames - 1) + ex[i].type = ex_free; + break; + case ex_misc: + if (f >= ex[i].frames - 1) { + ex[i].type = ex_free; + break; + } + ent.alpha = 1.0f - frac / (ex[i].frames - 1); + break; + case ex_flash: + if (f >= 1) { + ex[i].type = ex_free; + break; + } + ent.alpha = 1.0f; + break; + case ex_poly: + if (f >= ex[i].frames - 1) { + ex[i].type = ex_free; + break; + } + + ent.alpha = (16.0f - (float) f) / 16.0f; + + if (f < 10) { + ent.skinnum = (f >> 1); + if (ent.skinnum < 0) + ent.skinnum = 0; + } else { + ent.flags |= Defines.RF_TRANSLUCENT; + if (f < 13) + ent.skinnum = 5; + else + ent.skinnum = 6; + } + break; + case ex_poly2: + if (f >= ex[i].frames - 1) { + ex[i].type = ex_free; + break; + } + + ent.alpha = (5.0f - (float) f) / 5.0f; + ent.skinnum = 0; + ent.flags |= Defines.RF_TRANSLUCENT; + break; + } + + if (ex[i].type == ex_free) + continue; + if (ex[i].light != 0.0f) { + V.AddLight(ent.origin, ex[i].light * ent.alpha, + ex[i].lightcolor[0], ex[i].lightcolor[1], + ex[i].lightcolor[2]); + } + + Math3D.VectorCopy(ent.origin, ent.oldorigin); + + if (f < 0) + f = 0; + ent.frame = ex[i].baseframe + f + 1; + ent.oldframe = ex[i].baseframe + f; + ent.backlerp = 1.0f - Globals.cl.lerpfrac; + + V.AddEntity(ent); + } + } + + /* + * ================= CL_AddLasers ================= + */ + static void AddLasers() { + laser_t[] l; + int i; + + l = cl_lasers; + for (i = 0; i < MAX_LASERS; i++) { + if (l[i].endtime >= Globals.cl.time) + V.AddEntity(l[i].ent); + } + } + + /* PMM - CL_Sustains */ + static void ProcessSustain() { + cl_sustain_t[] s; + int i; + + s = cl_sustains; + for (i = 0; i < MAX_SUSTAINS; i++) { + if (s[i].id != 0) + if ((s[i].endtime >= Globals.cl.time) + && (Globals.cl.time >= s[i].nextthink)) { + s[i].think.think(s[i]); + } else if (s[i].endtime < Globals.cl.time) + s[i].id = 0; + } + } + + /* + * ================= CL_AddTEnts ================= + */ + static void AddTEnts() { + AddBeams(); + // PMM - draw plasma beams + AddPlayerBeams(); + AddExplosions(); + AddLasers(); + // PMM - set up sustain + ProcessSustain(); + } +}
\ No newline at end of file diff --git a/src/jake2/client/CL_view.java b/src/jake2/client/CL_view.java index ab9efa7..8a834d9 100644 --- a/src/jake2/client/CL_view.java +++ b/src/jake2/client/CL_view.java @@ -1,174 +1,190 @@ /* - * CL_view.java - * Copyright (C) 2004 + * CL_view.java Copyright (C) 2004 * - * $Id: CL_view.java,v 1.3 2004-07-09 06:50:50 hzi Exp $ + * $Id: CL_view.java,v 1.4 2004-09-22 19:22:07 salomo 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. - -*/ + * 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.client; +import jake2.Defines; +import jake2.Globals; import jake2.qcommon.CM; import jake2.qcommon.Com; import jake2.sys.Sys; import java.util.StringTokenizer; -public class CL_view extends CL_input { - - static int num_cl_weaponmodels; - static String[] cl_weaponmodels = new String[MAX_CLIENTWEAPONMODELS]; - - - /* - ================= - CL_PrepRefresh - - Call before entering a new level, or after changing dlls - ================= - */ - static void PrepRefresh() { - String mapname; - int i; - String name; - float rotate; - float[] axis = new float[3]; - - if ((i=cl.configstrings[CS_MODELS+1].length()) == 0) - return; // no map loaded - - SCR.AddDirtyPoint(0, 0); - SCR.AddDirtyPoint(viddef.width-1, viddef.height-1); - - // let the render dll load the map - mapname = cl.configstrings[CS_MODELS+1].substring(5, i - 4); // skip "maps/" - // cut off ".bsp" - - // register models, pics, and skins - Com.Printf("Map: " + mapname + "\r"); - SCR.UpdateScreen(); - re.BeginRegistration(mapname); - Com.Printf(" \r"); - - // precache status bar pics - Com.Printf("pics\r"); - SCR.UpdateScreen(); - SCR.TouchPics(); - Com.Printf(" \r"); - - CL.RegisterTEntModels(); - - num_cl_weaponmodels = 1; - cl_weaponmodels[0] = "weapon.md2"; - - for (i=1 ; i<MAX_MODELS && cl.configstrings[CS_MODELS+i].length() != 0 ; i++) { - name = new String(cl.configstrings[CS_MODELS+i]); - if (name.length() > 37) name = name.substring(0, 36); - - - if (name.charAt(0) != '*') - Com.Printf(name + "\r"); - - SCR.UpdateScreen(); - Sys.SendKeyEvents(); // pump message loop - if (name.charAt(0) == '#') { - // special player weapon model - if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS) { - cl_weaponmodels[num_cl_weaponmodels] = cl.configstrings[CS_MODELS+i].substring(1); - num_cl_weaponmodels++; - } - } else { - cl.model_draw[i] = re.RegisterModel(cl.configstrings[CS_MODELS+i]); - if (name.charAt(0) == '*') - cl.model_clip[i] = CM.InlineModel(cl.configstrings[CS_MODELS+i]); - else - cl.model_clip[i] = null; - } - if (name.charAt(0) != '*') - Com.Printf(" \r"); - } - - Com.Printf("images\r"); - SCR.UpdateScreen(); - for (i=1 ; i<MAX_IMAGES && cl.configstrings[CS_IMAGES+i].length() > 0 ; i++) { - cl.image_precache[i] = re.RegisterPic(cl.configstrings[CS_IMAGES+i]); - Sys.SendKeyEvents(); // pump message loop - } - - Com.Printf(" \r"); - for (i=0 ; i<MAX_CLIENTS ; i++) { - if (cl.configstrings[CS_PLAYERSKINS+i].length() == 0) - continue; - Com.Printf("client " + i + '\r'); - SCR.UpdateScreen(); - Sys.SendKeyEvents(); // pump message loop - CL.ParseClientinfo(i); - Com.Printf(" \r"); - } - - CL_parse.LoadClientinfo(cl.baseclientinfo, "unnamed\\male/grunt"); - - // set sky textures and speed - Com.Printf("sky\r"); - SCR.UpdateScreen(); - rotate = Float.parseFloat(cl.configstrings[CS_SKYROTATE]); - StringTokenizer st = new StringTokenizer(cl.configstrings[CS_SKYAXIS]); - axis[0] = Float.parseFloat(st.nextToken()); - axis[1] = Float.parseFloat(st.nextToken()); - axis[2] = Float.parseFloat(st.nextToken()); - re.SetSky(cl.configstrings[CS_SKY], rotate, axis); - Com.Printf(" \r"); - - // the renderer can now free unneeded stuff - re.EndRegistration (); - - // clear any lines of console text - Console.ClearNotify(); - - SCR.UpdateScreen(); - cl.refresh_prepped = true; - cl.force_refdef = true; // make sure we have a valid refdef - } - - public static void AddNetgraph() { - int i; - int in; - int ping; - - // if using the debuggraph for something else, don't - // add the net lines - if (SCR.scr_debuggraph.value == 0.0f || SCR.scr_timegraph.value == 0.0f) - return; - - for (i=0 ; i<cls.netchan.dropped ; i++) - SCR.DebugGraph(30, 0x40); - - for (i=0 ; i<cl.surpressCount ; i++) - SCR.DebugGraph(30, 0xdf); - - // see what the latency was on this packet - in = cls.netchan.incoming_acknowledged & (CMD_BACKUP-1); - ping = (int)(cls.realtime - cl.cmd_time[in]); - ping /= 30; - if (ping > 30) - ping = 30; - SCR.DebugGraph (ping, 0xd0); - } -} +public class CL_view { + + static int num_cl_weaponmodels; + + static String[] cl_weaponmodels = new String[Defines.MAX_CLIENTWEAPONMODELS]; + + /* + * ================= + * + * CL_PrepRefresh + * + * Call before entering a new level, or after changing dlls + * ================= + */ + static void PrepRefresh() { + String mapname; + int i; + String name; + float rotate; + float[] axis = new float[3]; + + if ((i = Globals.cl.configstrings[Defines.CS_MODELS + 1].length()) == 0) + return; // no map loaded + + SCR.AddDirtyPoint(0, 0); + SCR.AddDirtyPoint(Globals.viddef.width - 1, Globals.viddef.height - 1); + + // let the render dll load the map + mapname = Globals.cl.configstrings[Defines.CS_MODELS + 1].substring(5, + i - 4); // skip "maps/" + // cut off ".bsp" + + // register models, pics, and skins + Com.Printf("Map: " + mapname + "\r"); + SCR.UpdateScreen(); + Globals.re.BeginRegistration(mapname); + Com.Printf(" \r"); + + // precache status bar pics + Com.Printf("pics\r"); + SCR.UpdateScreen(); + SCR.TouchPics(); + Com.Printf(" \r"); + + CL_tent.RegisterTEntModels(); + + num_cl_weaponmodels = 1; + cl_weaponmodels[0] = "weapon.md2"; + + for (i = 1; i < Defines.MAX_MODELS + && Globals.cl.configstrings[Defines.CS_MODELS + i].length() != 0; i++) { + name = new String(Globals.cl.configstrings[Defines.CS_MODELS + i]); + if (name.length() > 37) + name = name.substring(0, 36); + + if (name.charAt(0) != '*') + Com.Printf(name + "\r"); + + SCR.UpdateScreen(); + Sys.SendKeyEvents(); // pump message loop + if (name.charAt(0) == '#') { + // special player weapon model + if (num_cl_weaponmodels < Defines.MAX_CLIENTWEAPONMODELS) { + cl_weaponmodels[num_cl_weaponmodels] = Globals.cl.configstrings[Defines.CS_MODELS + + i].substring(1); + num_cl_weaponmodels++; + } + } else { + Globals.cl.model_draw[i] = Globals.re + .RegisterModel(Globals.cl.configstrings[Defines.CS_MODELS + + i]); + if (name.charAt(0) == '*') + Globals.cl.model_clip[i] = CM + .InlineModel(Globals.cl.configstrings[Defines.CS_MODELS + + i]); + else + Globals.cl.model_clip[i] = null; + } + if (name.charAt(0) != '*') + Com.Printf(" \r"); + } + + Com.Printf("images\r"); + SCR.UpdateScreen(); + for (i = 1; i < Defines.MAX_IMAGES + && Globals.cl.configstrings[Defines.CS_IMAGES + i].length() > 0; i++) { + Globals.cl.image_precache[i] = Globals.re + .RegisterPic(Globals.cl.configstrings[Defines.CS_IMAGES + i]); + Sys.SendKeyEvents(); // pump message loop + } + + Com.Printf(" \r"); + for (i = 0; i < Defines.MAX_CLIENTS; i++) { + if (Globals.cl.configstrings[Defines.CS_PLAYERSKINS + i].length() == 0) + continue; + Com.Printf("client " + i + '\r'); + SCR.UpdateScreen(); + Sys.SendKeyEvents(); // pump message loop + CL_parse.ParseClientinfo(i); + Com.Printf(" \r"); + } + + CL_parse.LoadClientinfo(Globals.cl.baseclientinfo, + "unnamed\\male/grunt"); + + // set sky textures and speed + Com.Printf("sky\r"); + SCR.UpdateScreen(); + rotate = Float + .parseFloat(Globals.cl.configstrings[Defines.CS_SKYROTATE]); + StringTokenizer st = new StringTokenizer( + Globals.cl.configstrings[Defines.CS_SKYAXIS]); + axis[0] = Float.parseFloat(st.nextToken()); + axis[1] = Float.parseFloat(st.nextToken()); + axis[2] = Float.parseFloat(st.nextToken()); + Globals.re.SetSky(Globals.cl.configstrings[Defines.CS_SKY], rotate, + axis); + Com.Printf(" \r"); + + // the renderer can now free unneeded stuff + Globals.re.EndRegistration(); + + // clear any lines of console text + Console.ClearNotify(); + + SCR.UpdateScreen(); + Globals.cl.refresh_prepped = true; + Globals.cl.force_refdef = true; // make sure we have a valid refdef + } + + public static void AddNetgraph() { + int i; + int in; + int ping; + + // if using the debuggraph for something else, don't + // add the net lines + if (SCR.scr_debuggraph.value == 0.0f || SCR.scr_timegraph.value == 0.0f) + return; + + for (i = 0; i < Globals.cls.netchan.dropped; i++) + SCR.DebugGraph(30, 0x40); + + for (i = 0; i < Globals.cl.surpressCount; i++) + SCR.DebugGraph(30, 0xdf); + + // see what the latency was on this packet + in = Globals.cls.netchan.incoming_acknowledged + & (Defines.CMD_BACKUP - 1); + ping = (int) (Globals.cls.realtime - Globals.cl.cmd_time[in]); + ping /= 30; + if (ping > 30) + ping = 30; + SCR.DebugGraph(ping, 0xd0); + } +}
\ No newline at end of file diff --git a/src/jake2/client/Console.java b/src/jake2/client/Console.java index b37a1f8..65bf253 100644 --- a/src/jake2/client/Console.java +++ b/src/jake2/client/Console.java @@ -2,27 +2,27 @@ * Con.java * Copyright (C) 2003 * - * $Id: Console.java,v 1.4 2004-07-30 06:03:40 hzi Exp $ + * $Id: Console.java,v 1.5 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; import java.io.IOException; @@ -33,574 +33,582 @@ import jake2.Defines; import jake2.Globals; import jake2.game.Cmd; import jake2.qcommon.*; +import jake2.util.Lib; import jake2.util.Vargs; /** * Console */ public final class Console extends Globals { - - public static xcommand_t ToggleConsole_f = new xcommand_t() { - public void execute() { - SCR.EndLoadingPlaque(); // get rid of loading plaque - - if (Globals.cl.attractloop) { - Cbuf.AddText("killserver\n"); - return; - } - - if (Globals.cls.state == Defines.ca_disconnected) { - // start the demo loop again - Cbuf.AddText("d1\n"); - return; - } - - Key.ClearTyping(); - Console.ClearNotify(); - - if (Globals.cls.key_dest == Defines.key_console) { - Menu.ForceMenuOff(); - Cvar.Set("paused", "0"); - } - else { - Menu.ForceMenuOff(); - Globals.cls.key_dest = Defines.key_console; - - if (Cvar.VariableValue("maxclients") == 1 && Globals.server_state!= 0) - Cvar.Set("paused", "1"); - } - } - }; - - public static xcommand_t Clear_f = new xcommand_t() { - public void execute() { - Arrays.fill(Globals.con.text, (byte)' '); - } - }; - public static xcommand_t Dump_f = new xcommand_t() { - public void execute() { - - int l, x; - int line; - RandomAccessFile f; - byte[] buffer = new byte[1024]; - String name; - - if (Cmd.Argc() != 2) { - Com.Printf("usage: condump <filename>\n"); - return; - } - - //Com_sprintf (name, sizeof(name), "%s/%s.txt", FS_Gamedir(), Cmd_Argv(1)); - name = FS.Gamedir() + "/" + Cmd.Argv(1) + ".txt"; - - Com.Printf("Dumped console text to " + name + ".\n"); - FS.CreatePath(name); - f = fopen(name, "rw"); - if (f == null) { - Com.Printf("ERROR: couldn't open.\n"); - return; - } - - // skip empty lines - for (l = con.current - con.totallines + 1; l <= con.current; l++) { - line = (l % con.totallines) * con.linewidth; - for (x = 0; x < con.linewidth; x++) - if (con.text[line + x] != ' ') - break; - if (x != con.linewidth) - break; - } - - // write the remaining lines - buffer[con.linewidth] = 0; - for (; l <= con.current; l++) { - line = (l % con.totallines) * con.linewidth; - //strncpy (buffer, line, con.linewidth); - System.arraycopy(con.text, line, buffer, 0, con.linewidth); - for (x = con.linewidth - 1; x >= 0; x--) { - if (buffer[x] == ' ') - buffer[x] = 0; - else - break; - } - for (x = 0; buffer[x] != 0; x++) - buffer[x] &= 0x7f; - - buffer[x] = '\n'; - // fprintf (f, "%s\n", buffer); - try { - f.write(buffer, 0, x+1); - } catch (IOException e) {} - } - - fclose(f); - - } - }; - - /** - * - */ - public static void Init() { - Globals.con.linewidth = -1; - - CheckResize(); - - Com.Printf("Console initialized.\n"); - - // - // register our commands - // - Globals.con_notifytime = Cvar.Get("con_notifytime", "3", 0); - - Cmd.AddCommand("toggleconsole", ToggleConsole_f); - Cmd.AddCommand("togglechat", ToggleChat_f); - Cmd.AddCommand("messagemode", MessageMode_f); - Cmd.AddCommand("messagemode2", MessageMode2_f); - Cmd.AddCommand("clear", Clear_f); - Cmd.AddCommand("condump", Dump_f); - Globals.con.initialized = true; - } - - /** - * If the line width has changed, reformat the buffer. - */ - public static void CheckResize() { - - int width = (Globals.viddef.width >> 3) - 2; - - if (width == Globals.con.linewidth) - return; - - if (width < 1) { // video hasn't been initialized yet - width = 38; - Globals.con.linewidth = width; - Globals.con.totallines = Defines.CON_TEXTSIZE / Globals.con.linewidth; - Arrays.fill(Globals.con.text, (byte)' '); - } - else { - int oldwidth = Globals.con.linewidth; - Globals.con.linewidth = width; - int oldtotallines = Globals.con.totallines; - Globals.con.totallines = Defines.CON_TEXTSIZE / Globals.con.linewidth; - int numlines = oldtotallines; - - if (Globals.con.totallines < numlines) - numlines = Globals.con.totallines; - - int numchars = oldwidth; - - if (Globals.con.linewidth < numchars) - numchars = Globals.con.linewidth; - - byte[] tbuf = new byte[Defines.CON_TEXTSIZE]; - System.arraycopy(Globals.con.text, 0, tbuf, 0, Defines.CON_TEXTSIZE); - Arrays.fill(Globals.con.text, (byte)' '); - - for (int i=0 ; i<numlines ; i++) { - for (int j=0 ; j<numchars ; j++) { - Globals.con.text[(Globals.con.totallines - 1 - i) * Globals.con.linewidth + j] = - tbuf[((Globals.con.current - i + oldtotallines) % oldtotallines) * oldwidth + j]; - } - } - - Console.ClearNotify(); - } - - Globals.con.current = Globals.con.totallines - 1; - Globals.con.display = Globals.con.current; - } - - public static void ClearNotify() { - int i; - for (i=0 ; i<Defines.NUM_CON_TIMES ; i++) - Globals.con.times[i] = 0; - } - - static void DrawString(int x, int y, String s) { - for (int i = 0; i < s.length(); i++) { - Globals.re.DrawChar(x, y, s.charAt(i)); - x+=8; - } - } - - static void DrawAltString(int x, int y, String s) { - for (int i = 0; i < s.length(); i++) { - Globals.re.DrawChar(x, y, s.charAt(i) ^ 0x80); - x+=8; - } - } - - - /* - ================ - Con_ToggleChat_f - ================ - */ - static xcommand_t ToggleChat_f = new xcommand_t() { - public void execute() { - Key.ClearTyping(); - - if (cls.key_dest == key_console) { - if (cls.state == ca_active) { - Menu.ForceMenuOff(); - cls.key_dest = key_game; - } - } else - cls.key_dest = key_console; - - ClearNotify(); - } - }; - - /* - ================ - Con_MessageMode_f - ================ - */ - static xcommand_t MessageMode_f = new xcommand_t() { - public void execute() { - chat_team = false; - cls.key_dest = key_message; - } - }; - - /* - ================ - Con_MessageMode2_f - ================ - */ - static xcommand_t MessageMode2_f = new xcommand_t() { - public void execute() { - chat_team = true; - cls.key_dest = key_message; - } - }; - - /* - =============== - Con_Linefeed - =============== - */ - static void Linefeed() { - Globals.con.x = 0; - if (Globals.con.display == Globals.con.current) - Globals.con.display++; - Globals.con.current++; - int i = (Globals.con.current%Globals.con.totallines)*Globals.con.linewidth; - int e = i + Globals.con.linewidth; - while (i++ < e) Globals.con.text[i] = ' '; - } - - /* - ================ - Con_Print - - Handles cursor positioning, line wrapping, etc - All console printing must go through this in order to be logged to disk - If no console is visible, the text will appear at the top of the game window - ================ - */ - private static int cr; - public static void Print(String txt) { - int y; - int c, l; - int mask; - int txtpos = 0; - - if (!con.initialized) return; - - if (txt.charAt(0) == 1 || txt.charAt(0) == 2) { - mask = 128; // go to colored text - txtpos++; - } else mask = 0; - - while ( txtpos < txt.length() ) { - c = txt.charAt(txtpos); - // count word length - for (l=0 ; l < con.linewidth && l < (txt.length() - txtpos) ; l++) - if ( txt.charAt(l + txtpos) <= ' ') break; - - // word wrap - if (l != con.linewidth && (con.x + l > con.linewidth) ) - con.x = 0; - - txtpos++; - - if (cr != 0) { - con.current--; - cr = 0; - } - - if (con.x == 0) { - Console.Linefeed(); - // mark time for transparent overlay - if (con.current >= 0) - con.times[con.current % NUM_CON_TIMES] = cls.realtime; - } - - switch (c) { - case '\n': - con.x = 0; - break; - - case '\r': - con.x = 0; - cr = 1; - break; - - default: // display character and advance - y = con.current % con.totallines; - con.text[y*con.linewidth+con.x] = (byte)(c | mask | con.ormask); - con.x++; - if (con.x >= con.linewidth) - con.x = 0; - break; - } - } - } - - /* - ============== - Con_CenteredPrint - ============== - */ - static void CenteredPrint(String text) { - int l = text.length(); - l = (con.linewidth-l)/2; - if (l < 0) l = 0; - - StringBuffer sb = new StringBuffer(1024); - for (int i = 0; i < l; i++) sb.append(' '); - sb.append(text); - sb.append('\n'); - - sb.setLength(1024); - - Console.Print(sb.toString()); - } - - /* - ============================================================================== - - DRAWING - - ============================================================================== - */ - - /* - ================ - Con_DrawInput - - The input line scrolls horizontally if typing goes beyond the right edge - ================ - */ - static void DrawInput() { - int i; - byte[] text; - int start = 0; - - if (cls.key_dest == key_menu) - return; - if (cls.key_dest != key_console && cls.state == ca_active) - return; // don't draw anything (always draw if not active) - - text = key_lines[edit_line]; - - // add the cursor frame - text[key_linepos] = (byte)(10+((int)(cls.realtime>>8)&1)); - - // fill out remainder with spaces - for (i=key_linepos+1 ; i< con.linewidth ; i++) - text[i] = ' '; - - // prestep if horizontally scrolling - if (key_linepos >= con.linewidth) - start += 1 + key_linepos - con.linewidth; - - // draw it -// y = con.vislines-16; - - for (i=0 ; i<con.linewidth ; i++) - re.DrawChar ( (i+1)<<3, con.vislines - 22, text[i]); - - // remove cursor - key_lines[edit_line][key_linepos] = 0; - } - - - /* - ================ - Con_DrawNotify - - Draws the last few lines of output transparently over the game top - ================ - */ - static void DrawNotify() { - int x, v; - int text; - int i; - int time; - String s; - int skip; - - v = 0; - for (i= con.current-NUM_CON_TIMES+1 ; i<=con.current ; i++) { - if (i < 0) continue; - - time = (int)con.times[i % NUM_CON_TIMES]; - if (time == 0) continue; - - time = (int)(cls.realtime - time); - if (time > con_notifytime.value*1000) continue; - - text = (i % con.totallines)*con.linewidth; - - for (x = 0 ; x < con.linewidth ; x++) - re.DrawChar( (x+1)<<3, v, con.text[text+x]); - - v += 8; - } - - if (cls.key_dest == key_message) { - if (chat_team) { - DrawString(8, v, "say_team:"); - skip = 11; - } else { - DrawString (8, v, "say:"); - skip = 5; - } - - s = chat_buffer; - if (chat_bufferlen > (viddef.width>>3)-(skip+1)) - s = s.substring(chat_bufferlen - ((viddef.width>>3)-(skip+1))); - - for (x = 0; x < s.length(); x++) { - re.DrawChar( (x+skip)<<3, v, s.charAt(x)); - } - re.DrawChar( (x+skip)<<3, v, (int)(10+((cls.realtime>>8)&1))); - v += 8; - } - - if (v != 0) { - SCR.AddDirtyPoint(0,0); - SCR.AddDirtyPoint(viddef.width-1, v); - } - } - - /* - ================ - Con_DrawConsole - - Draws the console with the solid background - ================ - */ - static void DrawConsole(float frac) { - int i, j, x, y, n; - int rows; - int text; - int row; - int lines; - String version; - String dlbar; - - lines = (int)(viddef.height * frac); - if (lines <= 0) - return; - - if (lines > viddef.height) - lines = viddef.height; - - // draw the background - re.DrawStretchPic(0, -viddef.height+lines, viddef.width, viddef.height, "conback"); - SCR.AddDirtyPoint(0,0); - SCR.AddDirtyPoint(viddef.width-1,lines-1); - - version = Com.sprintf("v%4.2f", new Vargs(1).add(VERSION)); - for (x=0 ; x<5 ; x++) - re.DrawChar (viddef.width-44+x*8, lines-12, 128 + version.charAt(x)); - - // draw the text - con.vislines = lines; - - rows = (lines-22)>>3; // rows of text to draw - - y = lines - 30; - - // draw from the bottom up - if (con.display != con.current) { - // draw arrows to show the buffer is backscrolled - for (x=0 ; x<con.linewidth ; x+=4) - re.DrawChar ( (x+1)<<3, y, '^'); - - y -= 8; - rows--; - } - - row = con.display; - for (i=0 ; i<rows ; i++, y-=8, row--) { - if (row < 0) - break; - if (con.current - row >= con.totallines) - break; // past scrollback wrap point - - int first = (row % con.totallines)*con.linewidth; - - for (x=0 ; x<con.linewidth ; x++) - re.DrawChar( (x+1)<<3, y, con.text[x+first]); - } - - //ZOID - // draw the download bar - // figure out width - if (cls.download != null) { - if ((text = cls.downloadname.lastIndexOf('/')) != 0) - text++; - else - text = 0; - - x = con.linewidth - ((con.linewidth * 7) / 40); - y = x - (cls.downloadname.length()-text) - 8; - i = con.linewidth/3; - if (cls.downloadname.length()-text > i) { - y = x - i - 11; - int end = text + i - 1;; - dlbar = cls.downloadname.substring(text, end); - dlbar += "..."; - } else { - dlbar = cls.downloadname.substring(text); - } - dlbar += ": "; - dlbar += (char)0x80; - - // where's the dot go? - if (cls.downloadpercent == 0) - n = 0; - else - n = y * cls.downloadpercent / 100; - - StringBuffer sb = new StringBuffer(dlbar); - sb.ensureCapacity(1024); - for (j = 0; j < y; j++) { - if (j == n) - sb.append((char)0x83); - else - sb.append((char)0x81); - } - sb.append((char)0x82); - - dlbar = sb.toString(); - dlbar += Com.sprintf(" %02d%%", new Vargs(1).add(cls.downloadpercent)); - - // draw it - y = con.vislines-12; - for (i = 0; i < dlbar.length(); i++) - re.DrawChar ( (i+1)<<3, y, dlbar.charAt(i)); - } - //ZOID - - // draw the input prompt, user text, and cursor if desired - DrawInput(); - } -} + + public static xcommand_t ToggleConsole_f = new xcommand_t() { + public void execute() { + SCR.EndLoadingPlaque(); // get rid of loading plaque + + if (Globals.cl.attractloop) { + Cbuf.AddText("killserver\n"); + return; + } + + if (Globals.cls.state == Defines.ca_disconnected) { + // start the demo loop again + Cbuf.AddText("d1\n"); + return; + } + + Key.ClearTyping(); + Console.ClearNotify(); + + if (Globals.cls.key_dest == Defines.key_console) { + Menu.ForceMenuOff(); + Cvar.Set("paused", "0"); + } else { + Menu.ForceMenuOff(); + Globals.cls.key_dest = Defines.key_console; + + if (Cvar.VariableValue("maxclients") == 1 + && Globals.server_state != 0) + Cvar.Set("paused", "1"); + } + } + }; + + public static xcommand_t Clear_f = new xcommand_t() { + public void execute() { + Arrays.fill(Globals.con.text, (byte) ' '); + } + }; + + public static xcommand_t Dump_f = new xcommand_t() { + public void execute() { + + int l, x; + int line; + RandomAccessFile f; + byte[] buffer = new byte[1024]; + String name; + + if (Cmd.Argc() != 2) { + Com.Printf("usage: condump <filename>\n"); + return; + } + + //Com_sprintf (name, sizeof(name), "%s/%s.txt", FS_Gamedir(), + // Cmd_Argv(1)); + name = FS.Gamedir() + "/" + Cmd.Argv(1) + ".txt"; + + Com.Printf("Dumped console text to " + name + ".\n"); + FS.CreatePath(name); + f = Lib.fopen(name, "rw"); + if (f == null) { + Com.Printf("ERROR: couldn't open.\n"); + return; + } + + // skip empty lines + for (l = con.current - con.totallines + 1; l <= con.current; l++) { + line = (l % con.totallines) * con.linewidth; + for (x = 0; x < con.linewidth; x++) + if (con.text[line + x] != ' ') + break; + if (x != con.linewidth) + break; + } + + // write the remaining lines + buffer[con.linewidth] = 0; + for (; l <= con.current; l++) { + line = (l % con.totallines) * con.linewidth; + //strncpy (buffer, line, con.linewidth); + System.arraycopy(con.text, line, buffer, 0, con.linewidth); + for (x = con.linewidth - 1; x >= 0; x--) { + if (buffer[x] == ' ') + buffer[x] = 0; + else + break; + } + for (x = 0; buffer[x] != 0; x++) + buffer[x] &= 0x7f; + + buffer[x] = '\n'; + // fprintf (f, "%s\n", buffer); + try { + f.write(buffer, 0, x + 1); + } catch (IOException e) { + } + } + + Lib.fclose(f); + + } + }; + + /** + * + */ + public static void Init() { + Globals.con.linewidth = -1; + + CheckResize(); + + Com.Printf("Console initialized.\n"); + + // + // register our commands + // + Globals.con_notifytime = Cvar.Get("con_notifytime", "3", 0); + + Cmd.AddCommand("toggleconsole", ToggleConsole_f); + Cmd.AddCommand("togglechat", ToggleChat_f); + Cmd.AddCommand("messagemode", MessageMode_f); + Cmd.AddCommand("messagemode2", MessageMode2_f); + Cmd.AddCommand("clear", Clear_f); + Cmd.AddCommand("condump", Dump_f); + Globals.con.initialized = true; + } + + /** + * If the line width has changed, reformat the buffer. + */ + public static void CheckResize() { + + int width = (Globals.viddef.width >> 3) - 2; + + if (width == Globals.con.linewidth) + return; + + if (width < 1) { // video hasn't been initialized yet + width = 38; + Globals.con.linewidth = width; + Globals.con.totallines = Defines.CON_TEXTSIZE + / Globals.con.linewidth; + Arrays.fill(Globals.con.text, (byte) ' '); + } else { + int oldwidth = Globals.con.linewidth; + Globals.con.linewidth = width; + int oldtotallines = Globals.con.totallines; + Globals.con.totallines = Defines.CON_TEXTSIZE + / Globals.con.linewidth; + int numlines = oldtotallines; + + if (Globals.con.totallines < numlines) + numlines = Globals.con.totallines; + + int numchars = oldwidth; + + if (Globals.con.linewidth < numchars) + numchars = Globals.con.linewidth; + + byte[] tbuf = new byte[Defines.CON_TEXTSIZE]; + System + .arraycopy(Globals.con.text, 0, tbuf, 0, + Defines.CON_TEXTSIZE); + Arrays.fill(Globals.con.text, (byte) ' '); + + for (int i = 0; i < numlines; i++) { + for (int j = 0; j < numchars; j++) { + Globals.con.text[(Globals.con.totallines - 1 - i) + * Globals.con.linewidth + j] = tbuf[((Globals.con.current + - i + oldtotallines) % oldtotallines) + * oldwidth + j]; + } + } + + Console.ClearNotify(); + } + + Globals.con.current = Globals.con.totallines - 1; + Globals.con.display = Globals.con.current; + } + + public static void ClearNotify() { + int i; + for (i = 0; i < Defines.NUM_CON_TIMES; i++) + Globals.con.times[i] = 0; + } + + static void DrawString(int x, int y, String s) { + for (int i = 0; i < s.length(); i++) { + Globals.re.DrawChar(x, y, s.charAt(i)); + x += 8; + } + } + + static void DrawAltString(int x, int y, String s) { + for (int i = 0; i < s.length(); i++) { + Globals.re.DrawChar(x, y, s.charAt(i) ^ 0x80); + x += 8; + } + } + + /* + * ================ Con_ToggleChat_f ================ + */ + static xcommand_t ToggleChat_f = new xcommand_t() { + public void execute() { + Key.ClearTyping(); + + if (cls.key_dest == key_console) { + if (cls.state == ca_active) { + Menu.ForceMenuOff(); + cls.key_dest = key_game; + } + } else + cls.key_dest = key_console; + + ClearNotify(); + } + }; + + /* + * ================ Con_MessageMode_f ================ + */ + static xcommand_t MessageMode_f = new xcommand_t() { + public void execute() { + chat_team = false; + cls.key_dest = key_message; + } + }; + + /* + * ================ Con_MessageMode2_f ================ + */ + static xcommand_t MessageMode2_f = new xcommand_t() { + public void execute() { + chat_team = true; + cls.key_dest = key_message; + } + }; + + /* + * =============== Con_Linefeed =============== + */ + static void Linefeed() { + Globals.con.x = 0; + if (Globals.con.display == Globals.con.current) + Globals.con.display++; + Globals.con.current++; + int i = (Globals.con.current % Globals.con.totallines) + * Globals.con.linewidth; + int e = i + Globals.con.linewidth; + while (i++ < e) + Globals.con.text[i] = ' '; + } + + /* + * ================ Con_Print + * + * Handles cursor positioning, line wrapping, etc All console printing must + * go through this in order to be logged to disk If no console is visible, + * the text will appear at the top of the game window ================ + */ + private static int cr; + + public static void Print(String txt) { + int y; + int c, l; + int mask; + int txtpos = 0; + + if (!con.initialized) + return; + + if (txt.charAt(0) == 1 || txt.charAt(0) == 2) { + mask = 128; // go to colored text + txtpos++; + } else + mask = 0; + + while (txtpos < txt.length()) { + c = txt.charAt(txtpos); + // count word length + for (l = 0; l < con.linewidth && l < (txt.length() - txtpos); l++) + if (txt.charAt(l + txtpos) <= ' ') + break; + + // word wrap + if (l != con.linewidth && (con.x + l > con.linewidth)) + con.x = 0; + + txtpos++; + + if (cr != 0) { + con.current--; + cr = 0; + } + + if (con.x == 0) { + Console.Linefeed(); + // mark time for transparent overlay + if (con.current >= 0) + con.times[con.current % NUM_CON_TIMES] = cls.realtime; + } + + switch (c) { + case '\n': + con.x = 0; + break; + + case '\r': + con.x = 0; + cr = 1; + break; + + default: // display character and advance + y = con.current % con.totallines; + con.text[y * con.linewidth + con.x] = (byte) (c | mask | con.ormask); + con.x++; + if (con.x >= con.linewidth) + con.x = 0; + break; + } + } + } + + /* + * ============== Con_CenteredPrint ============== + */ + static void CenteredPrint(String text) { + int l = text.length(); + l = (con.linewidth - l) / 2; + if (l < 0) + l = 0; + + StringBuffer sb = new StringBuffer(1024); + for (int i = 0; i < l; i++) + sb.append(' '); + sb.append(text); + sb.append('\n'); + + sb.setLength(1024); + + Console.Print(sb.toString()); + } + + /* + * ============================================================================== + * + * DRAWING + * + * ============================================================================== + */ + + /* + * ================ Con_DrawInput + * + * The input line scrolls horizontally if typing goes beyond the right edge + * ================ + */ + static void DrawInput() { + int i; + byte[] text; + int start = 0; + + if (cls.key_dest == key_menu) + return; + if (cls.key_dest != key_console && cls.state == ca_active) + return; // don't draw anything (always draw if not active) + + text = key_lines[edit_line]; + + // add the cursor frame + text[key_linepos] = (byte) (10 + ((int) (cls.realtime >> 8) & 1)); + + // fill out remainder with spaces + for (i = key_linepos + 1; i < con.linewidth; i++) + text[i] = ' '; + + // prestep if horizontally scrolling + if (key_linepos >= con.linewidth) + start += 1 + key_linepos - con.linewidth; + + // draw it + // y = con.vislines-16; + + for (i = 0; i < con.linewidth; i++) + re.DrawChar((i + 1) << 3, con.vislines - 22, text[i]); + + // remove cursor + key_lines[edit_line][key_linepos] = 0; + } + + /* + * ================ Con_DrawNotify + * + * Draws the last few lines of output transparently over the game top + * ================ + */ + static void DrawNotify() { + int x, v; + int text; + int i; + int time; + String s; + int skip; + + v = 0; + for (i = con.current - NUM_CON_TIMES + 1; i <= con.current; i++) { + if (i < 0) + continue; + + time = (int) con.times[i % NUM_CON_TIMES]; + if (time == 0) + continue; + + time = (int) (cls.realtime - time); + if (time > con_notifytime.value * 1000) + continue; + + text = (i % con.totallines) * con.linewidth; + + for (x = 0; x < con.linewidth; x++) + re.DrawChar((x + 1) << 3, v, con.text[text + x]); + + v += 8; + } + + if (cls.key_dest == key_message) { + if (chat_team) { + DrawString(8, v, "say_team:"); + skip = 11; + } else { + DrawString(8, v, "say:"); + skip = 5; + } + + s = chat_buffer; + if (chat_bufferlen > (viddef.width >> 3) - (skip + 1)) + s = s.substring(chat_bufferlen + - ((viddef.width >> 3) - (skip + 1))); + + for (x = 0; x < s.length(); x++) { + re.DrawChar((x + skip) << 3, v, s.charAt(x)); + } + re.DrawChar((x + skip) << 3, v, + (int) (10 + ((cls.realtime >> 8) & 1))); + v += 8; + } + + if (v != 0) { + SCR.AddDirtyPoint(0, 0); + SCR.AddDirtyPoint(viddef.width - 1, v); + } + } + + /* + * ================ Con_DrawConsole + * + * Draws the console with the solid background ================ + */ + static void DrawConsole(float frac) { + int i, j, x, y, n; + int rows; + int text; + int row; + int lines; + String version; + String dlbar; + + lines = (int) (viddef.height * frac); + if (lines <= 0) + return; + + if (lines > viddef.height) + lines = viddef.height; + + // draw the background + re.DrawStretchPic(0, -viddef.height + lines, viddef.width, + viddef.height, "conback"); + SCR.AddDirtyPoint(0, 0); + SCR.AddDirtyPoint(viddef.width - 1, lines - 1); + + version = Com.sprintf("v%4.2f", new Vargs(1).add(VERSION)); + for (x = 0; x < 5; x++) + re.DrawChar(viddef.width - 44 + x * 8, lines - 12, 128 + version + .charAt(x)); + + // draw the text + con.vislines = lines; + + rows = (lines - 22) >> 3; // rows of text to draw + + y = lines - 30; + + // draw from the bottom up + if (con.display != con.current) { + // draw arrows to show the buffer is backscrolled + for (x = 0; x < con.linewidth; x += 4) + re.DrawChar((x + 1) << 3, y, '^'); + + y -= 8; + rows--; + } + + row = con.display; + for (i = 0; i < rows; i++, y -= 8, row--) { + if (row < 0) + break; + if (con.current - row >= con.totallines) + break; // past scrollback wrap point + + int first = (row % con.totallines) * con.linewidth; + + for (x = 0; x < con.linewidth; x++) + re.DrawChar((x + 1) << 3, y, con.text[x + first]); + } + + //ZOID + // draw the download bar + // figure out width + if (cls.download != null) { + if ((text = cls.downloadname.lastIndexOf('/')) != 0) + text++; + else + text = 0; + + x = con.linewidth - ((con.linewidth * 7) / 40); + y = x - (cls.downloadname.length() - text) - 8; + i = con.linewidth / 3; + if (cls.downloadname.length() - text > i) { + y = x - i - 11; + int end = text + i - 1; + ; + dlbar = cls.downloadname.substring(text, end); + dlbar += "..."; + } else { + dlbar = cls.downloadname.substring(text); + } + dlbar += ": "; + dlbar += (char) 0x80; + + // where's the dot go? + if (cls.downloadpercent == 0) + n = 0; + else + n = y * cls.downloadpercent / 100; + + StringBuffer sb = new StringBuffer(dlbar); + sb.ensureCapacity(1024); + for (j = 0; j < y; j++) { + if (j == n) + sb.append((char) 0x83); + else + sb.append((char) 0x81); + } + sb.append((char) 0x82); + + dlbar = sb.toString(); + dlbar += Com.sprintf(" %02d%%", new Vargs(1) + .add(cls.downloadpercent)); + + // draw it + y = con.vislines - 12; + for (i = 0; i < dlbar.length(); i++) + re.DrawChar((i + 1) << 3, y, dlbar.charAt(i)); + } + //ZOID + + // draw the input prompt, user text, and cursor if desired + DrawInput(); + } +}
\ No newline at end of file diff --git a/src/jake2/client/M.java b/src/jake2/client/M.java index 3e076a6..2ea0d01 100644 --- a/src/jake2/client/M.java +++ b/src/jake2/client/M.java @@ -2,27 +2,27 @@ * M.java * Copyright (C) 2003 * - * $Id: M.java,v 1.4 2004-07-08 20:56:50 hzi Exp $ + * $Id: M.java,v 1.5 2004-09-22 19:22:07 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; import jake2.Defines; @@ -35,606 +35,529 @@ import jake2.util.Math3D; /** * M */ -public final class M -{ - - public static void M_CheckGround(edict_t ent) - { - float[] point = { 0, 0, 0 }; - trace_t trace; - - if ((ent.flags & (Defines.FL_SWIM | Defines.FL_FLY)) != 0) - return; - - if (ent.velocity[2] > 100) - { - ent.groundentity = null; - return; - } - - // if the hull point one-quarter unit down is solid the entity is on ground - point[0] = ent.s.origin[0]; - point[1] = ent.s.origin[1]; - point[2] = ent.s.origin[2] - 0.25f; - - trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, point, ent, Defines.MASK_MONSTERSOLID); - - // check steepness - if (trace.plane.normal[2] < 0.7 && !trace.startsolid) - { - ent.groundentity = null; - return; - } - - // ent.groundentity = trace.ent; - // ent.groundentity_linkcount = trace.ent.linkcount; - // if (!trace.startsolid && !trace.allsolid) - // VectorCopy (trace.endpos, ent.s.origin); - if (!trace.startsolid && !trace.allsolid) - { - Math3D.VectorCopy(trace.endpos, ent.s.origin); - ent.groundentity = trace.ent; - ent.groundentity_linkcount = trace.ent.linkcount; - ent.velocity[2] = 0; - } - } - - public static boolean M_CheckBottom(edict_t ent) - { - float[] mins = { 0, 0, 0 }; - float[] maxs = { 0, 0, 0 }; - float[] start = { 0, 0, 0 }; - float[] stop = { 0, 0, 0 }; - - trace_t trace; - int x, y; - float mid, bottom; - - Math3D.VectorAdd(ent.s.origin, ent.mins, mins); - Math3D.VectorAdd(ent.s.origin, ent.maxs, maxs); - - // if all of the points under the corners are solid world, don't bother - // with the tougher checks - // the corners must be within 16 of the midpoint - start[2] = mins[2] - 1; - for (x = 0; x <= 1; x++) - for (y = 0; y <= 1; y++) - { - start[0] = x != 0 ? maxs[0] : mins[0]; - start[1] = y != 0 ? maxs[1] : mins[1]; - if (GameBase.gi.pointcontents.pointcontents(start) != Defines.CONTENTS_SOLID) - { - GameBase.c_no++; - // - // check it for real... - // - start[2] = mins[2]; - - // the midpoint must be within 16 of the bottom - start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5f; - start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5f; - stop[2] = start[2] - 2 * GameBase.STEPSIZE; - trace = GameBase.gi.trace(start, GameBase.vec3_origin, GameBase.vec3_origin, stop, ent, Defines.MASK_MONSTERSOLID); - - if (trace.fraction == 1.0) - return false; - mid = bottom = trace.endpos[2]; - - // the corners must be within 16 of the midpoint - for (x = 0; x <= 1; x++) - for (y = 0; y <= 1; y++) - { - start[0] = stop[0] = x != 0 ? maxs[0] : mins[0]; - start[1] = stop[1] = y != 0 ? maxs[1] : mins[1]; - - trace = - GameBase.gi.trace( - start, - GameBase.vec3_origin, - GameBase.vec3_origin, - stop, - ent, - Defines.MASK_MONSTERSOLID); - - if (trace.fraction != 1.0 && trace.endpos[2] > bottom) - bottom = trace.endpos[2]; - if (trace.fraction == 1.0 || mid - trace.endpos[2] > GameBase.STEPSIZE) - return false; - } - - GameBase.c_yes++; - return true; - } - } - - GameBase.c_yes++; - return true; // we got out easy - } - - /* - =============== - M_ChangeYaw - - =============== - */ //ok - public static void M_ChangeYaw(edict_t ent) - { - float ideal; - float current; - float move; - float speed; - - current = Math3D.anglemod(ent.s.angles[Defines.YAW]); - ideal = ent.ideal_yaw; - - if (current == ideal) - return; - - move = ideal - current; - speed = ent.yaw_speed; - if (ideal > current) - { - if (move >= 180) - move = move - 360; - } - else - { - if (move <= -180) - move = move + 360; - } - if (move > 0) - { - if (move > speed) - move = speed; - } - else - { - if (move < -speed) - move = -speed; - } - - ent.s.angles[Defines.YAW] = Math3D.anglemod(current + move); - } - - /* - ====================== - M_MoveToGoal - ====================== - */ // ok - public static void M_MoveToGoal(edict_t ent, float dist) - { - edict_t goal = ent.goalentity; - - if (ent.groundentity == null && (ent.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == 0) - return; - - // if the next step hits the enemy, return immediately - if (ent.enemy != null && SV.SV_CloseEnough(ent, ent.enemy, dist)) - return; - - // bump around... - if ((Lib.rand() & 3) == 1 || !SV.SV_StepDirection(ent, ent.ideal_yaw, dist)) - { - if (ent.inuse) - SV.SV_NewChaseDir(ent, goal, dist); - } - } - - /* - =============== - M_walkmove - =============== - */ - public static boolean M_walkmove(edict_t ent, float yaw, float dist) - { - float[] move = { 0, 0, 0 }; - - if ((ent.groundentity == null) && (ent.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == 0) - return false; - - yaw = (float) (yaw * Math.PI * 2 / 360); - - move[0] = (float) Math.cos(yaw) * dist; - move[1] = (float) Math.sin(yaw) * dist; - move[2] = 0; - - return SV.SV_movestep(ent, move, true); - } - - public static void M_CatagorizePosition(edict_t ent) - { - float[] point = { 0, 0, 0 }; - int cont; - - // - // get waterlevel - // - point[0] = ent.s.origin[0]; - point[1] = ent.s.origin[1]; - point[2] = ent.s.origin[2] + ent.mins[2] + 1; - cont = Game.gi.pointcontents.pointcontents(point); - - if (0 == (cont & Defines.MASK_WATER)) - { - ent.waterlevel = 0; - ent.watertype = 0; - return; - } - - ent.watertype = cont; - ent.waterlevel = 1; - point[2] += 26; - cont = GameBase.gi.pointcontents.pointcontents(point); - if (0 == (cont & Defines.MASK_WATER)) - return; - - ent.waterlevel = 2; - point[2] += 22; - cont = GameBase.gi.pointcontents.pointcontents(point); - if (0 != (cont & Defines.MASK_WATER)) - ent.waterlevel = 3; - } - - public static void M_WorldEffects(edict_t ent) - { - int dmg; - - if (ent.health > 0) - { - if (0 == (ent.flags & Defines.FL_SWIM)) - { - if (ent.waterlevel < 3) - { - ent.air_finished = GameBase.level.time + 12; - } - else if (ent.air_finished < GameBase.level.time) - { - // drown! - if (ent.pain_debounce_time < GameBase.level.time) - { - dmg = (int) (2f + 2f * Math.floor(GameBase.level.time - ent.air_finished)); - if (dmg > 15) - dmg = 15; - GameUtil.T_Damage( - ent, - GameBase.g_edicts[0], - GameBase.g_edicts[0], - GameBase.vec3_origin, - ent.s.origin, - GameBase.vec3_origin, - dmg, - 0, - Defines.DAMAGE_NO_ARMOR, - Defines.MOD_WATER); - ent.pain_debounce_time = GameBase.level.time + 1; - } - } - } - else - { - if (ent.waterlevel > 0) - { - ent.air_finished = GameBase.level.time + 9; - } - else if (ent.air_finished < GameBase.level.time) - { - // suffocate! - if (ent.pain_debounce_time < GameBase.level.time) - { - dmg = (int) (2 + 2 * Math.floor(GameBase.level.time - ent.air_finished)); - if (dmg > 15) - dmg = 15; - GameUtil.T_Damage( - ent, - GameBase.g_edicts[0], - GameBase.g_edicts[0], - GameBase.vec3_origin, - ent.s.origin, - GameBase.vec3_origin, - dmg, - 0, - Defines.DAMAGE_NO_ARMOR, - Defines.MOD_WATER); - ent.pain_debounce_time = GameBase.level.time + 1; - } - } - } - } - - if (ent.waterlevel == 0) - { - if ((ent.flags & Defines.FL_INWATER) != 0) - { - GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_out.wav"), 1, Defines.ATTN_NORM, 0); - ent.flags &= ~Defines.FL_INWATER; - } - return; - } - - if ((ent.watertype & Defines.CONTENTS_LAVA) != 0 && 0 == (ent.flags & Defines.FL_IMMUNE_LAVA)) - { - if (ent.damage_debounce_time < GameBase.level.time) - { - ent.damage_debounce_time = GameBase.level.time + 0.2f; - GameUtil.T_Damage( - ent, - GameBase.g_edicts[0], - GameBase.g_edicts[0], - GameBase.vec3_origin, - ent.s.origin, - GameBase.vec3_origin, - 10 * ent.waterlevel, - 0, - 0, - Defines.MOD_LAVA); - } - } - if ((ent.watertype & Defines.CONTENTS_SLIME) != 0 && 0 == (ent.flags & Defines.FL_IMMUNE_SLIME)) - { - if (ent.damage_debounce_time < GameBase.level.time) - { - ent.damage_debounce_time = GameBase.level.time + 1; - GameUtil.T_Damage( - ent, - GameBase.g_edicts[0], - GameBase.g_edicts[0], - GameBase.vec3_origin, - ent.s.origin, - GameBase.vec3_origin, - 4 * ent.waterlevel, - 0, - 0, - Defines.MOD_SLIME); - } - } - - if (0 == (ent.flags & Defines.FL_INWATER)) - { - if (0 == (ent.svflags & Defines.SVF_DEADMONSTER)) - { - if ((ent.watertype & Defines.CONTENTS_LAVA) != 0) - if (Globals.rnd.nextFloat() <= 0.5) - GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi.soundindex("player/lava1.wav"), 1, Defines.ATTN_NORM, 0); - else - GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi.soundindex("player/lava2.wav"), 1, Defines.ATTN_NORM, 0); - else if ((ent.watertype & Defines.CONTENTS_SLIME) != 0) - GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_in.wav"), 1, Defines.ATTN_NORM, 0); - else if ((ent.watertype & Defines.CONTENTS_WATER) != 0) - GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi.soundindex("player/watr_in.wav"), 1, Defines.ATTN_NORM, 0); - } - - ent.flags |= Defines.FL_INWATER; - ent.damage_debounce_time = 0; - } - } - - public static EntThinkAdapter M_droptofloor = new EntThinkAdapter() - { - public boolean think(edict_t ent) - { - float[] end = { 0, 0, 0 }; - trace_t trace; - - ent.s.origin[2] += 1; - Math3D.VectorCopy(ent.s.origin, end); - end[2] -= 256; - - trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, end, ent, Defines.MASK_MONSTERSOLID); - - if (trace.fraction == 1 || trace.allsolid) - return true; - - Math3D.VectorCopy(trace.endpos, ent.s.origin); - - GameBase.gi.linkentity(ent); - M.M_CheckGround(ent); - M_CatagorizePosition(ent); - return true; - } - }; - - public static void M_SetEffects(edict_t ent) - { - ent.s.effects &= ~(Defines.EF_COLOR_SHELL | Defines.EF_POWERSCREEN); - ent.s.renderfx &= ~(Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE); - - if ((ent.monsterinfo.aiflags & Defines.AI_RESURRECTING) != 0) - { - ent.s.effects |= Defines.EF_COLOR_SHELL; - ent.s.renderfx |= Defines.RF_SHELL_RED; - } - - if (ent.health <= 0) - return; - - if (ent.powerarmor_time > GameBase.level.time) - { - if (ent.monsterinfo.power_armor_type == Defines.POWER_ARMOR_SCREEN) - { - ent.s.effects |= Defines.EF_POWERSCREEN; - } - else if (ent.monsterinfo.power_armor_type == Defines.POWER_ARMOR_SHIELD) - { - ent.s.effects |= Defines.EF_COLOR_SHELL; - ent.s.renderfx |= Defines.RF_SHELL_GREEN; - } - } - }; - - //ok - public static void M_MoveFrame(edict_t self) - { - mmove_t move; //ptr - int index; - - move = self.monsterinfo.currentmove; - self.nextthink = GameBase.level.time + Defines.FRAMETIME; - - if ((self.monsterinfo.nextframe != 0) - && (self.monsterinfo.nextframe >= move.firstframe) - && (self.monsterinfo.nextframe <= move.lastframe)) - { - self.s.frame = self.monsterinfo.nextframe; - self.monsterinfo.nextframe = 0; - } - else - { - if (self.s.frame == move.lastframe) - { - if (move.endfunc != null) - { - move.endfunc.think(self); - - // regrab move, endfunc is very likely to change it - move = self.monsterinfo.currentmove; - - // check for death - if ((self.svflags & Defines.SVF_DEADMONSTER) != 0) - return; - } - } - - if (self.s.frame < move.firstframe || self.s.frame > move.lastframe) - { - self.monsterinfo.aiflags &= ~Defines.AI_HOLD_FRAME; - self.s.frame = move.firstframe; - } - else - { - if (0 == (self.monsterinfo.aiflags & Defines.AI_HOLD_FRAME)) - { - self.s.frame++; - if (self.s.frame > move.lastframe) - self.s.frame = move.firstframe; - } - } - } - - index = self.s.frame - move.firstframe; - if (move.frame[index].ai != null) - if (0 == (self.monsterinfo.aiflags & Defines.AI_HOLD_FRAME)) - move.frame[index].ai.ai(self, move.frame[index].dist * self.monsterinfo.scale); - else - move.frame[index].ai.ai(self, 0); - - if (move.frame[index].think != null) - move.frame[index].think.think(self); - } - - public static void M_ReactToDamage(edict_t targ, edict_t attacker) - { - if ((null != attacker.client) && 0 != (attacker.svflags & Defines.SVF_MONSTER)) - return; - - if (attacker == targ || attacker == targ.enemy) - return; - - // if we are a good guy monster and our attacker is a player - // or another good guy, do not get mad at them - if (0 != (targ.monsterinfo.aiflags & Defines.AI_GOOD_GUY)) - { - if (attacker.client != null || (attacker.monsterinfo.aiflags & Defines.AI_GOOD_GUY) != 0) - return; - } - - // we now know that we are not both good guys - - // if attacker is a client, get mad at them because he's good and we're not - if (attacker.client != null) - { - targ.monsterinfo.aiflags &= ~Defines.AI_SOUND_TARGET; - - // this can only happen in coop (both new and old enemies are clients) - // only switch if can't see the current enemy - if (targ.enemy != null && targ.enemy.client != null) - { - if (GameUtil.visible(targ, targ.enemy)) - { - targ.oldenemy = attacker; - return; - } - targ.oldenemy = targ.enemy; - } - targ.enemy = attacker; - if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) - GameUtil.FoundTarget(targ); - return; - } - - // it's the same base (walk/swim/fly) type and a different classname and it's not a tank - // (they spray too much), get mad at them - if (((targ.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == (attacker.flags & (Defines.FL_FLY | Defines.FL_SWIM))) - && (Lib.strcmp(targ.classname, attacker.classname) != 0) - && (Lib.strcmp(attacker.classname, "monster_tank") != 0) - && (Lib.strcmp(attacker.classname, "monster_supertank") != 0) - && (Lib.strcmp(attacker.classname, "monster_makron") != 0) - && (Lib.strcmp(attacker.classname, "monster_jorg") != 0)) - { - if (targ.enemy != null && targ.enemy.client != null) - targ.oldenemy = targ.enemy; - targ.enemy = attacker; - if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) - GameUtil.FoundTarget(targ); - } - // if they *meant* to shoot us, then shoot back - else if (attacker.enemy == targ) - { - if (targ.enemy != null && targ.enemy.client != null) - targ.oldenemy = targ.enemy; - targ.enemy = attacker; - if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) - GameUtil.FoundTarget(targ); - } - // otherwise get mad at whoever they are mad at (help our buddy) unless it is us! - else if (attacker.enemy != null && attacker.enemy != targ) - { - if (targ.enemy != null && targ.enemy.client != null) - targ.oldenemy = targ.enemy; - targ.enemy = attacker.enemy; - if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) - GameUtil.FoundTarget(targ); - } - } - /** Stops the Flies. */ - public static EntThinkAdapter M_FliesOff = new EntThinkAdapter() - { - public boolean think(edict_t self) - { - self.s.effects &= ~Defines.EF_FLIES; - self.s.sound = 0; - return true; - } - }; - /** Starts the Flies as setting the animation flag in the entity. */ - public static EntThinkAdapter M_FliesOn = new EntThinkAdapter() - { - public boolean think(edict_t self) - { - if (self.waterlevel != 0) - return true; - - self.s.effects |= Defines.EF_FLIES; - self.s.sound = GameBase.gi.soundindex("infantry/inflies1.wav"); - self.think = M_FliesOff; - self.nextthink = GameBase.level.time + 60; - return true; - } - }; - /** Adds some flies after a random time */ - public static EntThinkAdapter M_FlyCheck = new EntThinkAdapter() - { - public boolean think(edict_t self) - { - - if (self.waterlevel != 0) - return true; - - if (Globals.rnd.nextFloat() > 0.5) - return true; - - self.think = M_FliesOn; - self.nextthink = GameBase.level.time + 5 + 10 * Globals.rnd.nextFloat(); - return true; - } - }; -} +public final class M { + + public static void M_CheckGround(edict_t ent) { + float[] point = { 0, 0, 0 }; + trace_t trace; + + if ((ent.flags & (Defines.FL_SWIM | Defines.FL_FLY)) != 0) + return; + + if (ent.velocity[2] > 100) { + ent.groundentity = null; + return; + } + + // if the hull point one-quarter unit down is solid the entity is on + // ground + point[0] = ent.s.origin[0]; + point[1] = ent.s.origin[1]; + point[2] = ent.s.origin[2] - 0.25f; + + trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, point, ent, + Defines.MASK_MONSTERSOLID); + + // check steepness + if (trace.plane.normal[2] < 0.7 && !trace.startsolid) { + ent.groundentity = null; + return; + } + + // ent.groundentity = trace.ent; + // ent.groundentity_linkcount = trace.ent.linkcount; + // if (!trace.startsolid && !trace.allsolid) + // VectorCopy (trace.endpos, ent.s.origin); + if (!trace.startsolid && !trace.allsolid) { + Math3D.VectorCopy(trace.endpos, ent.s.origin); + ent.groundentity = trace.ent; + ent.groundentity_linkcount = trace.ent.linkcount; + ent.velocity[2] = 0; + } + } + + public static boolean M_CheckBottom(edict_t ent) { + float[] mins = { 0, 0, 0 }; + float[] maxs = { 0, 0, 0 }; + float[] start = { 0, 0, 0 }; + float[] stop = { 0, 0, 0 }; + + trace_t trace; + int x, y; + float mid, bottom; + + Math3D.VectorAdd(ent.s.origin, ent.mins, mins); + Math3D.VectorAdd(ent.s.origin, ent.maxs, maxs); + + // if all of the points under the corners are solid world, don't bother + // with the tougher checks + // the corners must be within 16 of the midpoint + start[2] = mins[2] - 1; + for (x = 0; x <= 1; x++) + for (y = 0; y <= 1; y++) { + start[0] = x != 0 ? maxs[0] : mins[0]; + start[1] = y != 0 ? maxs[1] : mins[1]; + if (GameBase.gi.pointcontents.pointcontents(start) != Defines.CONTENTS_SOLID) { + GameBase.c_no++; + // + // check it for real... + // + start[2] = mins[2]; + + // the midpoint must be within 16 of the bottom + start[0] = stop[0] = (mins[0] + maxs[0]) * 0.5f; + start[1] = stop[1] = (mins[1] + maxs[1]) * 0.5f; + stop[2] = start[2] - 2 * GameBase.STEPSIZE; + trace = GameBase.gi.trace(start, Globals.vec3_origin, + Globals.vec3_origin, stop, ent, + Defines.MASK_MONSTERSOLID); + + if (trace.fraction == 1.0) + return false; + mid = bottom = trace.endpos[2]; + + // the corners must be within 16 of the midpoint + for (x = 0; x <= 1; x++) + for (y = 0; y <= 1; y++) { + start[0] = stop[0] = x != 0 ? maxs[0] : mins[0]; + start[1] = stop[1] = y != 0 ? maxs[1] : mins[1]; + + trace = GameBase.gi.trace(start, + Globals.vec3_origin, Globals.vec3_origin, + stop, ent, Defines.MASK_MONSTERSOLID); + + if (trace.fraction != 1.0 + && trace.endpos[2] > bottom) + bottom = trace.endpos[2]; + if (trace.fraction == 1.0 + || mid - trace.endpos[2] > GameBase.STEPSIZE) + return false; + } + + GameBase.c_yes++; + return true; + } + } + + GameBase.c_yes++; + return true; // we got out easy + } + + /* + * =============== M_ChangeYaw + * + * =============== + *///ok + public static void M_ChangeYaw(edict_t ent) { + float ideal; + float current; + float move; + float speed; + + current = Math3D.anglemod(ent.s.angles[Defines.YAW]); + ideal = ent.ideal_yaw; + + if (current == ideal) + return; + + move = ideal - current; + speed = ent.yaw_speed; + if (ideal > current) { + if (move >= 180) + move = move - 360; + } else { + if (move <= -180) + move = move + 360; + } + if (move > 0) { + if (move > speed) + move = speed; + } else { + if (move < -speed) + move = -speed; + } + + ent.s.angles[Defines.YAW] = Math3D.anglemod(current + move); + } + + /* + * ====================== M_MoveToGoal ====================== + */// ok + public static void M_MoveToGoal(edict_t ent, float dist) { + edict_t goal = ent.goalentity; + + if (ent.groundentity == null + && (ent.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == 0) + return; + + // if the next step hits the enemy, return immediately + if (ent.enemy != null && SV.SV_CloseEnough(ent, ent.enemy, dist)) + return; + + // bump around... + if ((Lib.rand() & 3) == 1 + || !SV.SV_StepDirection(ent, ent.ideal_yaw, dist)) { + if (ent.inuse) + SV.SV_NewChaseDir(ent, goal, dist); + } + } + + /* + * =============== M_walkmove =============== + */ + public static boolean M_walkmove(edict_t ent, float yaw, float dist) { + float[] move = { 0, 0, 0 }; + + if ((ent.groundentity == null) + && (ent.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == 0) + return false; + + yaw = (float) (yaw * Math.PI * 2 / 360); + + move[0] = (float) Math.cos(yaw) * dist; + move[1] = (float) Math.sin(yaw) * dist; + move[2] = 0; + + return SV.SV_movestep(ent, move, true); + } + + public static void M_CatagorizePosition(edict_t ent) { + float[] point = { 0, 0, 0 }; + int cont; + + // + // get waterlevel + // + point[0] = ent.s.origin[0]; + point[1] = ent.s.origin[1]; + point[2] = ent.s.origin[2] + ent.mins[2] + 1; + cont = GameBase.gi.pointcontents.pointcontents(point); + + if (0 == (cont & Defines.MASK_WATER)) { + ent.waterlevel = 0; + ent.watertype = 0; + return; + } + + ent.watertype = cont; + ent.waterlevel = 1; + point[2] += 26; + cont = GameBase.gi.pointcontents.pointcontents(point); + if (0 == (cont & Defines.MASK_WATER)) + return; + + ent.waterlevel = 2; + point[2] += 22; + cont = GameBase.gi.pointcontents.pointcontents(point); + if (0 != (cont & Defines.MASK_WATER)) + ent.waterlevel = 3; + } + + public static void M_WorldEffects(edict_t ent) { + int dmg; + + if (ent.health > 0) { + if (0 == (ent.flags & Defines.FL_SWIM)) { + if (ent.waterlevel < 3) { + ent.air_finished = GameBase.level.time + 12; + } else if (ent.air_finished < GameBase.level.time) { + // drown! + if (ent.pain_debounce_time < GameBase.level.time) { + dmg = (int) (2f + 2f * Math.floor(GameBase.level.time + - ent.air_finished)); + if (dmg > 15) + dmg = 15; + GameUtil.T_Damage(ent, GameBase.g_edicts[0], + GameBase.g_edicts[0], Globals.vec3_origin, + ent.s.origin, Globals.vec3_origin, dmg, 0, + Defines.DAMAGE_NO_ARMOR, Defines.MOD_WATER); + ent.pain_debounce_time = GameBase.level.time + 1; + } + } + } else { + if (ent.waterlevel > 0) { + ent.air_finished = GameBase.level.time + 9; + } else if (ent.air_finished < GameBase.level.time) { + // suffocate! + if (ent.pain_debounce_time < GameBase.level.time) { + dmg = (int) (2 + 2 * Math.floor(GameBase.level.time + - ent.air_finished)); + if (dmg > 15) + dmg = 15; + GameUtil.T_Damage(ent, GameBase.g_edicts[0], + GameBase.g_edicts[0], Globals.vec3_origin, + ent.s.origin, Globals.vec3_origin, dmg, 0, + Defines.DAMAGE_NO_ARMOR, Defines.MOD_WATER); + ent.pain_debounce_time = GameBase.level.time + 1; + } + } + } + } + + if (ent.waterlevel == 0) { + if ((ent.flags & Defines.FL_INWATER) != 0) { + GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi + .soundindex("player/watr_out.wav"), 1, + Defines.ATTN_NORM, 0); + ent.flags &= ~Defines.FL_INWATER; + } + return; + } + + if ((ent.watertype & Defines.CONTENTS_LAVA) != 0 + && 0 == (ent.flags & Defines.FL_IMMUNE_LAVA)) { + if (ent.damage_debounce_time < GameBase.level.time) { + ent.damage_debounce_time = GameBase.level.time + 0.2f; + GameUtil.T_Damage(ent, GameBase.g_edicts[0], + GameBase.g_edicts[0], Globals.vec3_origin, + ent.s.origin, Globals.vec3_origin, 10 * ent.waterlevel, + 0, 0, Defines.MOD_LAVA); + } + } + if ((ent.watertype & Defines.CONTENTS_SLIME) != 0 + && 0 == (ent.flags & Defines.FL_IMMUNE_SLIME)) { + if (ent.damage_debounce_time < GameBase.level.time) { + ent.damage_debounce_time = GameBase.level.time + 1; + GameUtil.T_Damage(ent, GameBase.g_edicts[0], + GameBase.g_edicts[0], Globals.vec3_origin, + ent.s.origin, Globals.vec3_origin, 4 * ent.waterlevel, + 0, 0, Defines.MOD_SLIME); + } + } + + if (0 == (ent.flags & Defines.FL_INWATER)) { + if (0 == (ent.svflags & Defines.SVF_DEADMONSTER)) { + if ((ent.watertype & Defines.CONTENTS_LAVA) != 0) + if (Globals.rnd.nextFloat() <= 0.5) + GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi + .soundindex("player/lava1.wav"), 1, + Defines.ATTN_NORM, 0); + else + GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi + .soundindex("player/lava2.wav"), 1, + Defines.ATTN_NORM, 0); + else if ((ent.watertype & Defines.CONTENTS_SLIME) != 0) + GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi + .soundindex("player/watr_in.wav"), 1, + Defines.ATTN_NORM, 0); + else if ((ent.watertype & Defines.CONTENTS_WATER) != 0) + GameBase.gi.sound(ent, Defines.CHAN_BODY, GameBase.gi + .soundindex("player/watr_in.wav"), 1, + Defines.ATTN_NORM, 0); + } + + ent.flags |= Defines.FL_INWATER; + ent.damage_debounce_time = 0; + } + } + + public static EntThinkAdapter M_droptofloor = new EntThinkAdapter() { + public boolean think(edict_t ent) { + float[] end = { 0, 0, 0 }; + trace_t trace; + + ent.s.origin[2] += 1; + Math3D.VectorCopy(ent.s.origin, end); + end[2] -= 256; + + trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, end, + ent, Defines.MASK_MONSTERSOLID); + + if (trace.fraction == 1 || trace.allsolid) + return true; + + Math3D.VectorCopy(trace.endpos, ent.s.origin); + + GameBase.gi.linkentity(ent); + M.M_CheckGround(ent); + M_CatagorizePosition(ent); + return true; + } + }; + + public static void M_SetEffects(edict_t ent) { + ent.s.effects &= ~(Defines.EF_COLOR_SHELL | Defines.EF_POWERSCREEN); + ent.s.renderfx &= ~(Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE); + + if ((ent.monsterinfo.aiflags & Defines.AI_RESURRECTING) != 0) { + ent.s.effects |= Defines.EF_COLOR_SHELL; + ent.s.renderfx |= Defines.RF_SHELL_RED; + } + + if (ent.health <= 0) + return; + + if (ent.powerarmor_time > GameBase.level.time) { + if (ent.monsterinfo.power_armor_type == Defines.POWER_ARMOR_SCREEN) { + ent.s.effects |= Defines.EF_POWERSCREEN; + } else if (ent.monsterinfo.power_armor_type == Defines.POWER_ARMOR_SHIELD) { + ent.s.effects |= Defines.EF_COLOR_SHELL; + ent.s.renderfx |= Defines.RF_SHELL_GREEN; + } + } + }; + + //ok + public static void M_MoveFrame(edict_t self) { + mmove_t move; //ptr + int index; + + move = self.monsterinfo.currentmove; + self.nextthink = GameBase.level.time + Defines.FRAMETIME; + + if ((self.monsterinfo.nextframe != 0) + && (self.monsterinfo.nextframe >= move.firstframe) + && (self.monsterinfo.nextframe <= move.lastframe)) { + self.s.frame = self.monsterinfo.nextframe; + self.monsterinfo.nextframe = 0; + } else { + if (self.s.frame == move.lastframe) { + if (move.endfunc != null) { + move.endfunc.think(self); + + // regrab move, endfunc is very likely to change it + move = self.monsterinfo.currentmove; + + // check for death + if ((self.svflags & Defines.SVF_DEADMONSTER) != 0) + return; + } + } + + if (self.s.frame < move.firstframe || self.s.frame > move.lastframe) { + self.monsterinfo.aiflags &= ~Defines.AI_HOLD_FRAME; + self.s.frame = move.firstframe; + } else { + if (0 == (self.monsterinfo.aiflags & Defines.AI_HOLD_FRAME)) { + self.s.frame++; + if (self.s.frame > move.lastframe) + self.s.frame = move.firstframe; + } + } + } + + index = self.s.frame - move.firstframe; + if (move.frame[index].ai != null) + if (0 == (self.monsterinfo.aiflags & Defines.AI_HOLD_FRAME)) + move.frame[index].ai.ai(self, move.frame[index].dist + * self.monsterinfo.scale); + else + move.frame[index].ai.ai(self, 0); + + if (move.frame[index].think != null) + move.frame[index].think.think(self); + } + + public static void M_ReactToDamage(edict_t targ, edict_t attacker) { + if ((null != attacker.client) + && 0 != (attacker.svflags & Defines.SVF_MONSTER)) + return; + + if (attacker == targ || attacker == targ.enemy) + return; + + // if we are a good guy monster and our attacker is a player + // or another good guy, do not get mad at them + if (0 != (targ.monsterinfo.aiflags & Defines.AI_GOOD_GUY)) { + if (attacker.client != null + || (attacker.monsterinfo.aiflags & Defines.AI_GOOD_GUY) != 0) + return; + } + + // we now know that we are not both good guys + + // if attacker is a client, get mad at them because he's good and we're + // not + if (attacker.client != null) { + targ.monsterinfo.aiflags &= ~Defines.AI_SOUND_TARGET; + + // this can only happen in coop (both new and old enemies are + // clients) + // only switch if can't see the current enemy + if (targ.enemy != null && targ.enemy.client != null) { + if (GameUtil.visible(targ, targ.enemy)) { + targ.oldenemy = attacker; + return; + } + targ.oldenemy = targ.enemy; + } + targ.enemy = attacker; + if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) + GameUtil.FoundTarget(targ); + return; + } + + // it's the same base (walk/swim/fly) type and a different classname and + // it's not a tank + // (they spray too much), get mad at them + if (((targ.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == (attacker.flags & (Defines.FL_FLY | Defines.FL_SWIM))) + && (Lib.strcmp(targ.classname, attacker.classname) != 0) + && (Lib.strcmp(attacker.classname, "monster_tank") != 0) + && (Lib.strcmp(attacker.classname, "monster_supertank") != 0) + && (Lib.strcmp(attacker.classname, "monster_makron") != 0) + && (Lib.strcmp(attacker.classname, "monster_jorg") != 0)) { + if (targ.enemy != null && targ.enemy.client != null) + targ.oldenemy = targ.enemy; + targ.enemy = attacker; + if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) + GameUtil.FoundTarget(targ); + } + // if they *meant* to shoot us, then shoot back + else if (attacker.enemy == targ) { + if (targ.enemy != null && targ.enemy.client != null) + targ.oldenemy = targ.enemy; + targ.enemy = attacker; + if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) + GameUtil.FoundTarget(targ); + } + // otherwise get mad at whoever they are mad at (help our buddy) unless + // it is us! + else if (attacker.enemy != null && attacker.enemy != targ) { + if (targ.enemy != null && targ.enemy.client != null) + targ.oldenemy = targ.enemy; + targ.enemy = attacker.enemy; + if (0 == (targ.monsterinfo.aiflags & Defines.AI_DUCKED)) + GameUtil.FoundTarget(targ); + } + } + + /** Stops the Flies. */ + public static EntThinkAdapter M_FliesOff = new EntThinkAdapter() { + public boolean think(edict_t self) { + self.s.effects &= ~Defines.EF_FLIES; + self.s.sound = 0; + return true; + } + }; + + /** Starts the Flies as setting the animation flag in the entity. */ + public static EntThinkAdapter M_FliesOn = new EntThinkAdapter() { + public boolean think(edict_t self) { + if (self.waterlevel != 0) + return true; + + self.s.effects |= Defines.EF_FLIES; + self.s.sound = GameBase.gi.soundindex("infantry/inflies1.wav"); + self.think = M_FliesOff; + self.nextthink = GameBase.level.time + 60; + return true; + } + }; + + /** Adds some flies after a random time */ + public static EntThinkAdapter M_FlyCheck = new EntThinkAdapter() { + public boolean think(edict_t self) { + + if (self.waterlevel != 0) + return true; + + if (Globals.rnd.nextFloat() > 0.5) + return true; + + self.think = M_FliesOn; + self.nextthink = GameBase.level.time + 5 + 10 + * Globals.rnd.nextFloat(); + return true; + } + }; +}
\ No newline at end of file diff --git a/src/jake2/client/Menu.java b/src/jake2/client/Menu.java index b718b19..50797f5 100644 --- a/src/jake2/client/Menu.java +++ b/src/jake2/client/Menu.java @@ -2,27 +2,27 @@ * Menu.java * Copyright (C) 2004 * - * $Id: Menu.java,v 1.8 2004-09-12 19:52:58 hzi Exp $ + * $Id: Menu.java,v 1.9 2004-09-22 19:22:07 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; import jake2.Globals; @@ -42,4968 +42,4882 @@ import java.util.Comparator; /** * Menu * - * + * */ abstract class keyfunc_t { - abstract String execute(int key); + abstract String execute(int key); } public final class Menu extends Key { - static int m_main_cursor; - static final int NUM_CURSOR_FRAMES= 15; + static int m_main_cursor; - static final String menu_in_sound= "misc/menu1.wav"; - static final String menu_move_sound= "misc/menu2.wav"; - static final String menu_out_sound= "misc/menu3.wav"; + static final int NUM_CURSOR_FRAMES = 15; - static boolean m_entersound; // play after drawing a frame, so caching - // won't disrupt the sound + static final String menu_in_sound = "misc/menu1.wav"; - static xcommand_t m_drawfunc; + static final String menu_move_sound = "misc/menu2.wav"; - static keyfunc_t m_keyfunc; + static final String menu_out_sound = "misc/menu3.wav"; - // ============================================================================= - /* Support Routines */ + static boolean m_entersound; // play after drawing a frame, so caching - public final static int MAX_MENU_DEPTH= 8; + // won't disrupt the sound - public static class menulayer_t { - xcommand_t draw; - keyfunc_t key; - } + static xcommand_t m_drawfunc; - static class menuframework_s { - int x, y; - int cursor; + static keyfunc_t m_keyfunc; - int nitems; - int nslots; - menucommon_s items[]= new menucommon_s[64]; + // ============================================================================= + /* Support Routines */ - String statusbar; + public final static int MAX_MENU_DEPTH = 8; - //void (*cursordraw)( struct _tag_menuframework *m ); - mcallback cursordraw; + public static class menulayer_t { + xcommand_t draw; - } + keyfunc_t key; + } - abstract static class mcallback { - abstract public void execute(Object self); - } + static class menuframework_s { + int x, y; - static class menucommon_s { - int type; - String name= ""; - int x, y; - menuframework_s parent; - int cursor_offset; - int localdata[]= { 0, 0, 0, 0 }; - int flags; - int n= -1; //position in an array. + int cursor; - String statusbar; + int nitems; - mcallback callback; - mcallback statusbarfunc; - mcallback ownerdraw; - mcallback cursordraw; - } + int nslots; - static class menufield_s extends menucommon_s { - //char buffer[80]; - StringBuffer buffer; //allow deletion. + menucommon_s items[] = new menucommon_s[64]; - int cursor; - int length; - int visible_length; - int visible_offset; - } + String statusbar; - static class menuslider_s extends menucommon_s { + //void (*cursordraw)( struct _tag_menuframework *m ); + mcallback cursordraw; - float minvalue; - float maxvalue; - float curvalue; + } - float range; - } + abstract static class mcallback { + abstract public void execute(Object self); + } - static class menulist_s extends menucommon_s { - int curvalue; - String itemnames[]; - } - - static class menuaction_s extends menucommon_s { - - } - - static class menuseparator_s extends menucommon_s { - - } - - public static menulayer_t m_layers[]= new menulayer_t[MAX_MENU_DEPTH]; - public static int m_menudepth; - - static void Banner(String name) { - Dimension dim= new Dimension(); - Globals.re.DrawGetPicSize(dim, name); - - Globals.re.DrawPic(viddef.width / 2 - dim.width / 2, viddef.height / 2 - 110, name); - } - - static void PushMenu(xcommand_t draw, keyfunc_t key) { //, String(*key) (int k) ) { - int i; - - if (Cvar.VariableValue("maxclients") == 1 && Globals.server_state != 0) - Cvar.Set("paused", "1"); - - // if this menu is already present, drop back to that level - // to avoid stacking menus by hotkeys - for (i= 0; i < m_menudepth; i++) - if (m_layers[i].draw == draw && m_layers[i].key == key) { - m_menudepth= i; - } - - if (i == m_menudepth) { - if (m_menudepth >= MAX_MENU_DEPTH) - Com.Error(ERR_FATAL, "PushMenu: MAX_MENU_DEPTH"); - - m_layers[m_menudepth].draw= m_drawfunc; - m_layers[m_menudepth].key= m_keyfunc; - m_menudepth++; - } - - m_drawfunc= draw; - m_keyfunc= key; - - m_entersound= true; - - cls.key_dest= key_menu; - } - - static void ForceMenuOff() { - m_drawfunc= null; - m_keyfunc= null; - cls.key_dest= key_game; - m_menudepth= 0; - Key.ClearStates(); - Cvar.Set("paused", "0"); - } - - static void PopMenu() { - S.StartLocalSound(menu_out_sound); - if (m_menudepth < 1) - Com.Error(ERR_FATAL, "PopMenu: depth < 1"); - m_menudepth--; - - m_drawfunc= m_layers[m_menudepth].draw; - m_keyfunc= m_layers[m_menudepth].key; - - if (0 == m_menudepth) - ForceMenuOff(); - } - - static String Default_MenuKey(menuframework_s m, int key) { - String sound= null; - menucommon_s item; - - if (m != null) { - if ((item= ((menucommon_s) Menu_ItemAtCursor(m))) != null) { - if (item.type == MTYPE_FIELD) { - if (Field_Key((menufield_s) item, key)) - return null; - } - } - } - - switch (key) { - case K_ESCAPE : - PopMenu(); - return menu_out_sound; - case K_KP_UPARROW : - case K_UPARROW : - if (m != null) { - m.cursor--; - Menu_AdjustCursor(m, -1); - sound= menu_move_sound; - } - break; - case K_TAB : - if (m != null) { - m.cursor++; - Menu_AdjustCursor(m, 1); - sound= menu_move_sound; - } - break; - case K_KP_DOWNARROW : - case K_DOWNARROW : - if (m != null) { - m.cursor++; - Menu_AdjustCursor(m, 1); - sound= menu_move_sound; - } - break; - case K_KP_LEFTARROW : - case K_LEFTARROW : - if (m != null) { - Menu_SlideItem(m, -1); - sound= menu_move_sound; - } - break; - case K_KP_RIGHTARROW : - case K_RIGHTARROW : - if (m != null) { - Menu_SlideItem(m, 1); - sound= menu_move_sound; - } - break; - - case K_MOUSE1 : - case K_MOUSE2 : - case K_MOUSE3 : - case K_JOY1 : - case K_JOY2 : - case K_JOY3 : - case K_JOY4 : - /* - case K_AUX1 : - case K_AUX2 : - case K_AUX3 : - case K_AUX4 : - case K_AUX5 : - case K_AUX6 : - case K_AUX7 : - case K_AUX8 : - case K_AUX9 : - case K_AUX10 : - case K_AUX11 : - case K_AUX12 : - case K_AUX13 : - case K_AUX14 : - case K_AUX15 : - case K_AUX16 : - case K_AUX17 : - case K_AUX18 : - case K_AUX19 : - case K_AUX20 : - case K_AUX21 : - case K_AUX22 : - case K_AUX23 : - case K_AUX24 : - case K_AUX25 : - case K_AUX26 : - case K_AUX27 : - case K_AUX28 : - case K_AUX29 : - case K_AUX30 : - case K_AUX31 : - case K_AUX32 : - */ - case K_KP_ENTER : - case K_ENTER : - if (m != null) - Menu_SelectItem(m); - sound= menu_move_sound; - break; - } - - return sound; - } - - /* - ================ - DrawCharacter - - Draws one solid graphics character - cx and cy are in 320*240 coordinates, and will be centered on - higher res screens. - ================ - */ - public static void DrawCharacter(int cx, int cy, int num) { - re.DrawChar(cx + ((viddef.width - 320) >> 1), cy + ((viddef.height - 240) >> 1), num); - } - - public static void Print(int cx, int cy, String str) { - //while (*str) - for (int n= 0; n < str.length(); n++) { - DrawCharacter(cx, cy, str.charAt(n) + 128); - //str++; - cx += 8; - } - } - - public static void PrintWhite(int cx, int cy, String str) { - for (int n= 0; n < str.length(); n++) { - DrawCharacter(cx, cy, str.charAt(n)); - //str++; - cx += 8; - } - } - - public static void DrawPic(int x, int y, String pic) { - re.DrawPic(x + ((viddef.width - 320) >> 1), y + ((viddef.height - 240) >> 1), pic); - } - - /* - ============= - DrawCursor - - Draws an animating cursor with the point at - x,y. The pic will extend to the left of x, - and both above and below y. - ============= - */ - static boolean cached; - static void DrawCursor(int x, int y, int f) { - //char cursorname[80]; - String cursorname; - - assert(f >= 0) : "negative time and cursor bug"; - - f= Math.abs(f); - - if (!cached) { - int i; - - for (i= 0; i < NUM_CURSOR_FRAMES; i++) { - cursorname= "m_cursor" + i; - - re.RegisterPic(cursorname); - } - cached= true; - } - - cursorname= "m_cursor" + f; - re.DrawPic(x, y, cursorname); - } - - public static void DrawTextBox(int x, int y, int width, int lines) { - int cx, cy; - int n; - - // draw left side - cx= x; - cy= y; - DrawCharacter(cx, cy, 1); - - for (n= 0; n < lines; n++) { - cy += 8; - DrawCharacter(cx, cy, 4); - } - DrawCharacter(cx, cy + 8, 7); - - // draw middle - cx += 8; - while (width > 0) { - cy= y; - DrawCharacter(cx, cy, 2); - - for (n= 0; n < lines; n++) { - cy += 8; - DrawCharacter(cx, cy, 5); - } - DrawCharacter(cx, cy + 8, 8); - - width -= 1; - cx += 8; - } - - // draw right side - cy= y; - DrawCharacter(cx, cy, 3); - for (n= 0; n < lines; n++) { - cy += 8; - DrawCharacter(cx, cy, 6); - - } - DrawCharacter(cx, cy + 8, 9); - - } - - /* - ======================================================================= - - MAIN MENU - - ======================================================================= - */ - static final int MAIN_ITEMS= 5; - - static xcommand_t Main_Draw= new xcommand_t() { - public void execute() { - Main_Draw(); - } - }; - static void Main_Draw() { - int i; - int w, h; - int ystart; - int xoffset; - int widest= -1; - int totalheight= 0; - String litname; - String[] names= { "m_main_game", "m_main_multiplayer", "m_main_options", "m_main_video", "m_main_quit" }; - Dimension dim= new Dimension(); - - for (i= 0; i < names.length; i++) { - Globals.re.DrawGetPicSize(dim, names[i]); - w= dim.width; - h= dim.height; - - if (w > widest) - widest= w; - totalheight += (h + 12); - } - - ystart= (Globals.viddef.height / 2 - 110); - xoffset= (Globals.viddef.width - widest + 70) / 2; - - for (i= 0; i < names.length; i++) { - if (i != m_main_cursor) - Globals.re.DrawPic(xoffset, ystart + i * 40 + 13, names[i]); - } - - //strcat(litname, "_sel"); - litname= names[m_main_cursor] + "_sel"; - Globals.re.DrawPic(xoffset, ystart + m_main_cursor * 40 + 13, litname); - - DrawCursor(xoffset - 25, ystart + m_main_cursor * 40 + 11, (int) ((Globals.cls.realtime / 100)) % NUM_CURSOR_FRAMES); - - Globals.re.DrawGetPicSize(dim, "m_main_plaque"); - w= dim.width; - h= dim.height; - Globals.re.DrawPic(xoffset - 30 - w, ystart, "m_main_plaque"); - - Globals.re.DrawPic(xoffset - 30 - w, ystart + h + 5, "m_main_logo"); - } - - static keyfunc_t Main_Key= new keyfunc_t() { - public String execute(int key) { - return Main_Key(key); - } - }; - - static String Main_Key(int key) { - String sound= menu_move_sound; - - switch (key) { - case Key.K_ESCAPE : - PopMenu(); - break; - - case Key.K_KP_DOWNARROW : - case Key.K_DOWNARROW : - if (++m_main_cursor >= MAIN_ITEMS) - m_main_cursor= 0; - return sound; - - case Key.K_KP_UPARROW : - case Key.K_UPARROW : - if (--m_main_cursor < 0) - m_main_cursor= MAIN_ITEMS - 1; - return sound; - - case Key.K_KP_ENTER : - case Key.K_ENTER : - m_entersound= true; - - switch (m_main_cursor) { - case 0 : - Menu_Game_f(); - break; - - case 1 : - Menu_Multiplayer_f(); - break; - - case 2 : - Menu_Options_f(); - break; - - case 3 : - Menu_Video_f(); - break; - - case 4 : - Menu_Quit_f(); - break; - } - } - - return null; - } - - static xcommand_t Menu_Main= new xcommand_t() { - public void execute() { - Menu_Main_f(); - } - }; - - static void Menu_Main_f() { - PushMenu(new xcommand_t() { - public void execute() { - Main_Draw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Main_Key(key); - } - }); - } - - /* - ======================================================================= - - MULTIPLAYER MENU - - ======================================================================= - */ - static menuframework_s s_multiplayer_menu= new menuframework_s(); - static menuaction_s s_join_network_server_action= new menuaction_s(); - static menuaction_s s_start_network_server_action= new menuaction_s(); - static menuaction_s s_player_setup_action= new menuaction_s(); - - static void Multiplayer_MenuDraw() { - Banner("m_banner_multiplayer"); - - Menu_AdjustCursor(s_multiplayer_menu, 1); - Menu_Draw(s_multiplayer_menu); - } - - static void PlayerSetupFunc(Object unused) { - Menu_PlayerConfig_f(); - } - - static void JoinNetworkServerFunc(Object unused) { - Menu_JoinServer_f(); - } - - static void StartNetworkServerFunc(Object unused) { - Menu_StartServer_f(); - } - - static void Multiplayer_MenuInit() { - s_multiplayer_menu.x= (int) (viddef.width * 0.50f - 64); - s_multiplayer_menu.nitems= 0; - - s_join_network_server_action.type= MTYPE_ACTION; - s_join_network_server_action.flags= QMF_LEFT_JUSTIFY; - s_join_network_server_action.x= 0; - s_join_network_server_action.y= 0; - s_join_network_server_action.name= " join network server"; - s_join_network_server_action.callback= new mcallback() { - public void execute(Object o) { - JoinNetworkServerFunc(o); - }; - }; - - s_start_network_server_action.type= MTYPE_ACTION; - s_start_network_server_action.flags= QMF_LEFT_JUSTIFY; - s_start_network_server_action.x= 0; - s_start_network_server_action.y= 10; - s_start_network_server_action.name= " start network server"; - s_start_network_server_action.callback= new mcallback() { - public void execute(Object o) { - StartNetworkServerFunc(o); - } - }; - - s_player_setup_action.type= MTYPE_ACTION; - s_player_setup_action.flags= QMF_LEFT_JUSTIFY; - s_player_setup_action.x= 0; - s_player_setup_action.y= 20; - s_player_setup_action.name= " player setup"; - s_player_setup_action.callback= new mcallback() { - public void execute(Object o) { - PlayerSetupFunc(o); - } - }; - - Menu_AddItem(s_multiplayer_menu, s_join_network_server_action); - Menu_AddItem(s_multiplayer_menu, s_start_network_server_action); - Menu_AddItem(s_multiplayer_menu, s_player_setup_action); - - Menu_SetStatusBar(s_multiplayer_menu, null); - - Menu_Center(s_multiplayer_menu); - } - - static String Multiplayer_MenuKey(int key) { - return Default_MenuKey(s_multiplayer_menu, key); - } - - static xcommand_t Menu_Multiplayer= new xcommand_t() { - public void execute() { - Menu_Multiplayer_f(); - } - }; - - static void Menu_Multiplayer_f() { - Multiplayer_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - Multiplayer_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Multiplayer_MenuKey(key); - } - }); - } - - /* - ======================================================================= - - KEYS MENU - - ======================================================================= - */ - static String bindnames[][]= { { "+attack", "attack" }, { - "weapnext", "next weapon" }, { - "+forward", "walk forward" }, { - "+back", "backpedal" }, { - "+left", "turn left" }, { - "+right", "turn right" }, { - "+speed", "run" }, { - "+moveleft", "step left" }, { - "+moveright", "step right" }, { - "+strafe", "sidestep" }, { - "+lookup", "look up" }, { - "+lookdown", "look down" }, { - "centerview", "center view" }, { - "+mlook", "mouse look" }, { - "+klook", "keyboard look" }, { - "+moveup", "up / jump" }, { - "+movedown", "down / crouch" }, { - - "inven", "inventory" }, { - "invuse", "use item" }, { - "invdrop", "drop item" }, { - "invprev", "prev item" }, { - "invnext", "next item" }, { - - "cmd help", "help computer" }, { - null, null } - }; - - int keys_cursor; - static boolean bind_grab; - - static menuframework_s s_keys_menu= new menuframework_s(); - static menuaction_s s_keys_attack_action= new menuaction_s(); - static menuaction_s s_keys_change_weapon_action= new menuaction_s(); - static menuaction_s s_keys_walk_forward_action= new menuaction_s(); - static menuaction_s s_keys_backpedal_action= new menuaction_s(); - static menuaction_s s_keys_turn_left_action= new menuaction_s(); - static menuaction_s s_keys_turn_right_action= new menuaction_s(); - static menuaction_s s_keys_run_action= new menuaction_s(); - static menuaction_s s_keys_step_left_action= new menuaction_s(); - static menuaction_s s_keys_step_right_action= new menuaction_s(); - static menuaction_s s_keys_sidestep_action= new menuaction_s(); - static menuaction_s s_keys_look_up_action= new menuaction_s(); - static menuaction_s s_keys_look_down_action= new menuaction_s(); - static menuaction_s s_keys_center_view_action= new menuaction_s(); - static menuaction_s s_keys_mouse_look_action= new menuaction_s(); - static menuaction_s s_keys_keyboard_look_action= new menuaction_s(); - static menuaction_s s_keys_move_up_action= new menuaction_s(); - static menuaction_s s_keys_move_down_action= new menuaction_s(); - static menuaction_s s_keys_inventory_action= new menuaction_s(); - static menuaction_s s_keys_inv_use_action= new menuaction_s(); - static menuaction_s s_keys_inv_drop_action= new menuaction_s(); - static menuaction_s s_keys_inv_prev_action= new menuaction_s(); - static menuaction_s s_keys_inv_next_action= new menuaction_s(); - - static menuaction_s s_keys_help_computer_action= new menuaction_s(); - - static void UnbindCommand(String command) { - int j; - String b; - - for (j= 0; j < 256; j++) { - b= keybindings[j]; - if (b == null) - continue; - if (b.equals(command)) - Key.SetBinding(j, ""); - } - } - - static void FindKeysForCommand(String command, int twokeys[]) { - int count; - int j; - String b; - - twokeys[0]= twokeys[1]= -1; - count= 0; - - for (j= 0; j < 256; j++) { - b= keybindings[j]; - if (b == null) - continue; - - if (b.equals(command)) { - twokeys[count]= j; - count++; - if (count == 2) - break; - } - } - } - - static void KeyCursorDrawFunc(menuframework_s menu) { - if (bind_grab) - re.DrawChar(menu.x, menu.y + menu.cursor * 9, '='); - else - re.DrawChar(menu.x, menu.y + menu.cursor * 9, 12 + ((int) (Sys.Milliseconds() / 250) & 1)); - } - - static void DrawKeyBindingFunc(Object self) { - int keys[]= { 0, 0 }; - menuaction_s a= (menuaction_s) self; - - FindKeysForCommand(bindnames[a.localdata[0]][0], keys); - - if (keys[0] == -1) { - Menu_DrawString(a.x + a.parent.x + 16, a.y + a.parent.y, "???"); - } - else { - int x; - String name; - - name= Key.KeynumToString(keys[0]); - - Menu_DrawString(a.x + a.parent.x + 16, a.y + a.parent.y, name); - - x= name.length() * 8; - - if (keys[1] != -1) { - Menu_DrawString(a.x + a.parent.x + 24 + x, a.y + a.parent.y, "or"); - Menu_DrawString(a.x + a.parent.x + 48 + x, a.y + a.parent.y, Key.KeynumToString(keys[1])); - } - } - } - - static void KeyBindingFunc(Object self) { - menuaction_s a= (menuaction_s) self; - int keys[]= { 0, 0 }; - - FindKeysForCommand(bindnames[a.localdata[0]][0], keys); - - if (keys[1] != -1) - UnbindCommand(bindnames[a.localdata[0]][0]); - - bind_grab= true; - - Menu_SetStatusBar(s_keys_menu, "press a key or button for this action"); - } - - static void Keys_MenuInit() { - int y= 0; - int i= 0; - - s_keys_menu.x= (int) (viddef.width * 0.50); - s_keys_menu.nitems= 0; - s_keys_menu.cursordraw= new mcallback() { - public void execute(Object o) { - KeyCursorDrawFunc((menuframework_s) o); - } - }; - - s_keys_attack_action.type= MTYPE_ACTION; - s_keys_attack_action.flags= QMF_GRAYED; - s_keys_attack_action.x= 0; - s_keys_attack_action.y= y; - s_keys_attack_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_attack_action.localdata[0]= i; - s_keys_attack_action.name= bindnames[s_keys_attack_action.localdata[0]][1]; - - s_keys_change_weapon_action.type= MTYPE_ACTION; - s_keys_change_weapon_action.flags= QMF_GRAYED; - s_keys_change_weapon_action.x= 0; - s_keys_change_weapon_action.y= y += 9; - s_keys_change_weapon_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_change_weapon_action.localdata[0]= ++i; - s_keys_change_weapon_action.name= bindnames[s_keys_change_weapon_action.localdata[0]][1]; - - s_keys_walk_forward_action.type= MTYPE_ACTION; - s_keys_walk_forward_action.flags= QMF_GRAYED; - s_keys_walk_forward_action.x= 0; - s_keys_walk_forward_action.y= y += 9; - s_keys_walk_forward_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_walk_forward_action.localdata[0]= ++i; - s_keys_walk_forward_action.name= bindnames[s_keys_walk_forward_action.localdata[0]][1]; - - s_keys_backpedal_action.type= MTYPE_ACTION; - s_keys_backpedal_action.flags= QMF_GRAYED; - s_keys_backpedal_action.x= 0; - s_keys_backpedal_action.y= y += 9; - s_keys_backpedal_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_backpedal_action.localdata[0]= ++i; - s_keys_backpedal_action.name= bindnames[s_keys_backpedal_action.localdata[0]][1]; - - s_keys_turn_left_action.type= MTYPE_ACTION; - s_keys_turn_left_action.flags= QMF_GRAYED; - s_keys_turn_left_action.x= 0; - s_keys_turn_left_action.y= y += 9; - s_keys_turn_left_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_turn_left_action.localdata[0]= ++i; - s_keys_turn_left_action.name= bindnames[s_keys_turn_left_action.localdata[0]][1]; - - s_keys_turn_right_action.type= MTYPE_ACTION; - s_keys_turn_right_action.flags= QMF_GRAYED; - s_keys_turn_right_action.x= 0; - s_keys_turn_right_action.y= y += 9; - s_keys_turn_right_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_turn_right_action.localdata[0]= ++i; - s_keys_turn_right_action.name= bindnames[s_keys_turn_right_action.localdata[0]][1]; - - s_keys_run_action.type= MTYPE_ACTION; - s_keys_run_action.flags= QMF_GRAYED; - s_keys_run_action.x= 0; - s_keys_run_action.y= y += 9; - s_keys_run_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_run_action.localdata[0]= ++i; - s_keys_run_action.name= bindnames[s_keys_run_action.localdata[0]][1]; - - s_keys_step_left_action.type= MTYPE_ACTION; - s_keys_step_left_action.flags= QMF_GRAYED; - s_keys_step_left_action.x= 0; - s_keys_step_left_action.y= y += 9; - s_keys_step_left_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - s_keys_step_left_action.localdata[0]= ++i; - s_keys_step_left_action.name= bindnames[s_keys_step_left_action.localdata[0]][1]; - - s_keys_step_right_action.type= MTYPE_ACTION; - s_keys_step_right_action.flags= QMF_GRAYED; - s_keys_step_right_action.x= 0; - s_keys_step_right_action.y= y += 9; - s_keys_step_right_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_step_right_action.localdata[0]= ++i; - s_keys_step_right_action.name= bindnames[s_keys_step_right_action.localdata[0]][1]; - - s_keys_sidestep_action.type= MTYPE_ACTION; - s_keys_sidestep_action.flags= QMF_GRAYED; - s_keys_sidestep_action.x= 0; - s_keys_sidestep_action.y= y += 9; - s_keys_sidestep_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_sidestep_action.localdata[0]= ++i; - s_keys_sidestep_action.name= bindnames[s_keys_sidestep_action.localdata[0]][1]; - - s_keys_look_up_action.type= MTYPE_ACTION; - s_keys_look_up_action.flags= QMF_GRAYED; - s_keys_look_up_action.x= 0; - s_keys_look_up_action.y= y += 9; - s_keys_look_up_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_look_up_action.localdata[0]= ++i; - s_keys_look_up_action.name= bindnames[s_keys_look_up_action.localdata[0]][1]; - - s_keys_look_down_action.type= MTYPE_ACTION; - s_keys_look_down_action.flags= QMF_GRAYED; - s_keys_look_down_action.x= 0; - s_keys_look_down_action.y= y += 9; - s_keys_look_down_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_look_down_action.localdata[0]= ++i; - s_keys_look_down_action.name= bindnames[s_keys_look_down_action.localdata[0]][1]; - - s_keys_center_view_action.type= MTYPE_ACTION; - s_keys_center_view_action.flags= QMF_GRAYED; - s_keys_center_view_action.x= 0; - s_keys_center_view_action.y= y += 9; - s_keys_center_view_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_center_view_action.localdata[0]= ++i; - s_keys_center_view_action.name= bindnames[s_keys_center_view_action.localdata[0]][1]; - - s_keys_mouse_look_action.type= MTYPE_ACTION; - s_keys_mouse_look_action.flags= QMF_GRAYED; - s_keys_mouse_look_action.x= 0; - s_keys_mouse_look_action.y= y += 9; - s_keys_mouse_look_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_mouse_look_action.localdata[0]= ++i; - s_keys_mouse_look_action.name= bindnames[s_keys_mouse_look_action.localdata[0]][1]; - - s_keys_keyboard_look_action.type= MTYPE_ACTION; - s_keys_keyboard_look_action.flags= QMF_GRAYED; - s_keys_keyboard_look_action.x= 0; - s_keys_keyboard_look_action.y= y += 9; - s_keys_keyboard_look_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_keyboard_look_action.localdata[0]= ++i; - s_keys_keyboard_look_action.name= bindnames[s_keys_keyboard_look_action.localdata[0]][1]; - - s_keys_move_up_action.type= MTYPE_ACTION; - s_keys_move_up_action.flags= QMF_GRAYED; - s_keys_move_up_action.x= 0; - s_keys_move_up_action.y= y += 9; - s_keys_move_up_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_move_up_action.localdata[0]= ++i; - s_keys_move_up_action.name= bindnames[s_keys_move_up_action.localdata[0]][1]; - - s_keys_move_down_action.type= MTYPE_ACTION; - s_keys_move_down_action.flags= QMF_GRAYED; - s_keys_move_down_action.x= 0; - s_keys_move_down_action.y= y += 9; - s_keys_move_down_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_move_down_action.localdata[0]= ++i; - s_keys_move_down_action.name= bindnames[s_keys_move_down_action.localdata[0]][1]; - - s_keys_inventory_action.type= MTYPE_ACTION; - s_keys_inventory_action.flags= QMF_GRAYED; - s_keys_inventory_action.x= 0; - s_keys_inventory_action.y= y += 9; - s_keys_inventory_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_inventory_action.localdata[0]= ++i; - s_keys_inventory_action.name= bindnames[s_keys_inventory_action.localdata[0]][1]; - - s_keys_inv_use_action.type= MTYPE_ACTION; - s_keys_inv_use_action.flags= QMF_GRAYED; - s_keys_inv_use_action.x= 0; - s_keys_inv_use_action.y= y += 9; - s_keys_inv_use_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_inv_use_action.localdata[0]= ++i; - s_keys_inv_use_action.name= bindnames[s_keys_inv_use_action.localdata[0]][1]; - - s_keys_inv_drop_action.type= MTYPE_ACTION; - s_keys_inv_drop_action.flags= QMF_GRAYED; - s_keys_inv_drop_action.x= 0; - s_keys_inv_drop_action.y= y += 9; - s_keys_inv_drop_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_inv_drop_action.localdata[0]= ++i; - s_keys_inv_drop_action.name= bindnames[s_keys_inv_drop_action.localdata[0]][1]; - - s_keys_inv_prev_action.type= MTYPE_ACTION; - s_keys_inv_prev_action.flags= QMF_GRAYED; - s_keys_inv_prev_action.x= 0; - s_keys_inv_prev_action.y= y += 9; - s_keys_inv_prev_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_inv_prev_action.localdata[0]= ++i; - s_keys_inv_prev_action.name= bindnames[s_keys_inv_prev_action.localdata[0]][1]; - - s_keys_inv_next_action.type= MTYPE_ACTION; - s_keys_inv_next_action.flags= QMF_GRAYED; - s_keys_inv_next_action.x= 0; - s_keys_inv_next_action.y= y += 9; - s_keys_inv_next_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_inv_next_action.localdata[0]= ++i; - s_keys_inv_next_action.name= bindnames[s_keys_inv_next_action.localdata[0]][1]; - - s_keys_help_computer_action.type= MTYPE_ACTION; - s_keys_help_computer_action.flags= QMF_GRAYED; - s_keys_help_computer_action.x= 0; - s_keys_help_computer_action.y= y += 9; - s_keys_help_computer_action.ownerdraw= new mcallback() { - public void execute(Object o) { - DrawKeyBindingFunc(o); - } - }; - - s_keys_help_computer_action.localdata[0]= ++i; - s_keys_help_computer_action.name= bindnames[s_keys_help_computer_action.localdata[0]][1]; - - Menu_AddItem(s_keys_menu, s_keys_attack_action); - Menu_AddItem(s_keys_menu, s_keys_change_weapon_action); - Menu_AddItem(s_keys_menu, s_keys_walk_forward_action); - Menu_AddItem(s_keys_menu, s_keys_backpedal_action); - Menu_AddItem(s_keys_menu, s_keys_turn_left_action); - Menu_AddItem(s_keys_menu, s_keys_turn_right_action); - Menu_AddItem(s_keys_menu, s_keys_run_action); - Menu_AddItem(s_keys_menu, s_keys_step_left_action); - Menu_AddItem(s_keys_menu, s_keys_step_right_action); - Menu_AddItem(s_keys_menu, s_keys_sidestep_action); - Menu_AddItem(s_keys_menu, s_keys_look_up_action); - Menu_AddItem(s_keys_menu, s_keys_look_down_action); - Menu_AddItem(s_keys_menu, s_keys_center_view_action); - Menu_AddItem(s_keys_menu, s_keys_mouse_look_action); - Menu_AddItem(s_keys_menu, s_keys_keyboard_look_action); - Menu_AddItem(s_keys_menu, s_keys_move_up_action); - Menu_AddItem(s_keys_menu, s_keys_move_down_action); - - Menu_AddItem(s_keys_menu, s_keys_inventory_action); - Menu_AddItem(s_keys_menu, s_keys_inv_use_action); - Menu_AddItem(s_keys_menu, s_keys_inv_drop_action); - Menu_AddItem(s_keys_menu, s_keys_inv_prev_action); - Menu_AddItem(s_keys_menu, s_keys_inv_next_action); - - Menu_AddItem(s_keys_menu, s_keys_help_computer_action); - - Menu_SetStatusBar(s_keys_menu, "enter to change, backspace to clear"); - Menu_Center(s_keys_menu); - } - - static xcommand_t Keys_MenuDraw= new xcommand_t() { - public void execute() { - Keys_MenuDraw_f(); - } - }; - - static void Keys_MenuDraw_f() { - Menu_AdjustCursor(s_keys_menu, 1); - Menu_Draw(s_keys_menu); - } - - static keyfunc_t Keys_MenuKey= new keyfunc_t() { - public String execute(int key) { - return Keys_MenuKey_f(key); - } - }; - static String Keys_MenuKey_f(int key) { - menuaction_s item= (menuaction_s) Menu_ItemAtCursor(s_keys_menu); - - if (bind_grab) { - if (key != K_ESCAPE && key != '`') { - //char cmd[1024]; - String cmd; - - //Com_sprintf(cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n", Key_KeynumToString(key), bindnames[item.localdata[0]][0]); - cmd= "bind \"" + Key.KeynumToString(key) + "\" \"" + bindnames[item.localdata[0]][0] + "\""; - Cbuf.InsertText(cmd); - } - - Menu_SetStatusBar(s_keys_menu, "enter to change, backspace to clear"); - bind_grab= false; - return menu_out_sound; - } - - switch (key) { - case K_KP_ENTER : - case K_ENTER : - KeyBindingFunc(item); - return menu_in_sound; - case K_BACKSPACE : // delete bindings - case K_DEL : // delete bindings - case K_KP_DEL : - UnbindCommand(bindnames[item.localdata[0]][0]); - return menu_out_sound; - default : - return Default_MenuKey(s_keys_menu, key); - } - } - - static xcommand_t Menu_Keys= new xcommand_t() { - public void execute() { - Menu_Keys_f(); - } - }; - static void Menu_Keys_f() { - Keys_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - Keys_MenuDraw_f(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Keys_MenuKey_f(key); - } - }); - } - - /* - ======================================================================= - - CONTROLS MENU - - ======================================================================= - */ - static cvar_t win_noalttab; - - static menuframework_s s_options_menu= new menuframework_s(); - static menuaction_s s_options_defaults_action= new menuaction_s(); - static menuaction_s s_options_customize_options_action= new menuaction_s(); - static menuslider_s s_options_sensitivity_slider= new menuslider_s(); - static menulist_s s_options_freelook_box= new menulist_s(); - static menulist_s s_options_noalttab_box= new menulist_s(); - static menulist_s s_options_alwaysrun_box= new menulist_s(); - static menulist_s s_options_invertmouse_box= new menulist_s(); - static menulist_s s_options_lookspring_box= new menulist_s(); - static menulist_s s_options_lookstrafe_box= new menulist_s(); - static menulist_s s_options_crosshair_box= new menulist_s(); - static menuslider_s s_options_sfxvolume_slider= new menuslider_s(); - static menulist_s s_options_joystick_box= new menulist_s(); - static menulist_s s_options_cdvolume_box= new menulist_s(); - static menulist_s s_options_quality_list= new menulist_s(); - //static menulist_s s_options_compatibility_list = new menulist_s(); - static menuaction_s s_options_console_action= new menuaction_s(); - - static void CrosshairFunc(Object unused) { - Cvar.SetValue("crosshair", s_options_crosshair_box.curvalue); - } - - static void JoystickFunc(Object unused) { - Cvar.SetValue("in_joystick", s_options_joystick_box.curvalue); - } - - static void CustomizeControlsFunc(Object unused) { - Menu_Keys_f(); - } - - static void AlwaysRunFunc(Object unused) { - Cvar.SetValue("cl_run", s_options_alwaysrun_box.curvalue); - } - - static void FreeLookFunc(Object unused) { - Cvar.SetValue("freelook", s_options_freelook_box.curvalue); - } - - static void MouseSpeedFunc(Object unused) { - Cvar.SetValue("sensitivity", s_options_sensitivity_slider.curvalue / 2.0F); - } - - static void NoAltTabFunc(Object unused) { - Cvar.SetValue("win_noalttab", s_options_noalttab_box.curvalue); - } - - static float ClampCvar(float min, float max, float value) { - if (value < min) - return min; - if (value > max) - return max; - return value; - } - - static void ControlsSetMenuItemValues() { - s_options_sfxvolume_slider.curvalue= Cvar.VariableValue("s_volume") * 10; - s_options_cdvolume_box.curvalue= 1 - ((int) Cvar.VariableValue("cd_nocd")); - //s_options_quality_list.curvalue = 1 - ((int) Cvar.VariableValue("s_loadas8bit")); - if ("joal".equals(Cvar.VariableString("s_impl"))) { - s_options_quality_list.curvalue= 0; - } - else { - s_options_quality_list.curvalue= 1; - } - - s_options_sensitivity_slider.curvalue= (sensitivity.value) * 2; - - Cvar.SetValue("cl_run", ClampCvar(0, 1, cl_run.value)); - s_options_alwaysrun_box.curvalue= (int) cl_run.value; - - s_options_invertmouse_box.curvalue= m_pitch.value < 0 ? 1 : 0; - - Cvar.SetValue("lookspring", ClampCvar(0, 1, lookspring.value)); - s_options_lookspring_box.curvalue= (int) lookspring.value; - - Cvar.SetValue("lookstrafe", ClampCvar(0, 1, lookstrafe.value)); - s_options_lookstrafe_box.curvalue= (int) lookstrafe.value; - - Cvar.SetValue("freelook", ClampCvar(0, 1, freelook.value)); - s_options_freelook_box.curvalue= (int) freelook.value; - - Cvar.SetValue("crosshair", ClampCvar(0, 3, Globals.crosshair.value)); - s_options_crosshair_box.curvalue= (int) Globals.crosshair.value; - - Cvar.SetValue("in_joystick", ClampCvar(0, 1, in_joystick.value)); - s_options_joystick_box.curvalue= (int) in_joystick.value; - - s_options_noalttab_box.curvalue= (int) win_noalttab.value; - } - - static void ControlsResetDefaultsFunc(Object unused) { - Cbuf.AddText("exec default.cfg\n"); - Cbuf.Execute(); - - ControlsSetMenuItemValues(); - } - - static void InvertMouseFunc(Object unused) { - Cvar.SetValue("m_pitch", -m_pitch.value); - } - - static void LookspringFunc(Object unused) { - Cvar.SetValue("lookspring", 1 - lookspring.value); - } - - static void LookstrafeFunc(Object unused) { - Cvar.SetValue("lookstrafe", 1 - lookstrafe.value); - } - - static void UpdateVolumeFunc(Object unused) { - Cvar.SetValue("s_volume", s_options_sfxvolume_slider.curvalue / 10); - } - - static void UpdateCDVolumeFunc(Object unused) { - Cvar.SetValue("cd_nocd", 1 - s_options_cdvolume_box.curvalue); - } - - static void ConsoleFunc(Object unused) { - /* - ** the proper way to do this is probably to have ToggleConsole_f accept a parameter - */ - - if (cl.attractloop) { - Cbuf.AddText("killserver\n"); - return; - } - - Key.ClearTyping(); - Console.ClearNotify(); - - ForceMenuOff(); - cls.key_dest= key_console; - } - - static void UpdateSoundQualityFunc(Object unused) { - boolean driverNotChanged= false; - if (s_options_quality_list.curvalue != 0) { - // Cvar.SetValue("s_khz", 22); - // Cvar.SetValue("s_loadas8bit", 0); - driverNotChanged= S.getDriverName().equals("dummy"); - Cvar.Set("s_impl", "dummy"); - } - else { - // Cvar.SetValue("s_khz", 11); - // Cvar.SetValue("s_loadas8bit", 1); - driverNotChanged= S.getDriverName().equals("joal"); - Cvar.Set("s_impl", "joal"); - } - - //Cvar.SetValue("s_primary", s_options_compatibility_list.curvalue); - - if (driverNotChanged) { - re.EndFrame(); - return; - } - else { - - DrawTextBox(8, 120 - 48, 36, 3); - Print(16 + 16, 120 - 48 + 8, "Restarting the sound system. This"); - Print(16 + 16, 120 - 48 + 16, "could take up to a minute, so"); - Print(16 + 16, 120 - 48 + 24, "please be patient."); - - // the text box won't show up unless we do a buffer swap - re.EndFrame(); - - CL.Snd_Restart_f.execute(); - } - } - - static String cd_music_items[]= { "disabled", "enabled", null }; - static String soundstate_items[]= { "on", "off", null }; - - static String compatibility_items[]= { "max compatibility", "max performance", null }; - - static String yesno_names[]= { "no", "yes", null }; - - static String crosshair_names[]= { "none", "cross", "dot", "angle", null }; - - static void Options_MenuInit() { - - win_noalttab= Cvar.Get("win_noalttab", "0", CVAR_ARCHIVE); - - /* - ** configure controls menu and menu items - */ - s_options_menu.x= viddef.width / 2; - s_options_menu.y= viddef.height / 2 - 58; - s_options_menu.nitems= 0; - - s_options_sfxvolume_slider.type= MTYPE_SLIDER; - s_options_sfxvolume_slider.x= 0; - s_options_sfxvolume_slider.y= 0; - s_options_sfxvolume_slider.name= "effects volume"; - s_options_sfxvolume_slider.callback= new mcallback() { - public void execute(Object o) { - UpdateVolumeFunc(o); - } - }; - s_options_sfxvolume_slider.minvalue= 0; - s_options_sfxvolume_slider.maxvalue= 10; - s_options_sfxvolume_slider.curvalue= Cvar.VariableValue("s_volume") * 10; - - s_options_cdvolume_box.type= MTYPE_SPINCONTROL; - s_options_cdvolume_box.x= 0; - s_options_cdvolume_box.y= 10; - s_options_cdvolume_box.name= "CD music"; - s_options_cdvolume_box.callback= new mcallback() { - public void execute(Object o) { - UpdateCDVolumeFunc(o); - } - }; - s_options_cdvolume_box.itemnames= cd_music_items; - s_options_cdvolume_box.curvalue= 1 - (int) Cvar.VariableValue("cd_nocd"); - - s_options_quality_list.type= MTYPE_SPINCONTROL; - s_options_quality_list.x= 0; - s_options_quality_list.y= 20; - ; - s_options_quality_list.name= "sound"; - s_options_quality_list.callback= new mcallback() { - public void execute(Object o) { - UpdateSoundQualityFunc(o); - } - }; - s_options_quality_list.itemnames= soundstate_items; - //s_options_quality_list.curvalue = 1 - (int) Cvar.VariableValue("s_loadas8bit"); - - // s_options_compatibility_list.type = MTYPE_SPINCONTROL; - // s_options_compatibility_list.x = 0; - // s_options_compatibility_list.y = 30; - // s_options_compatibility_list.name = "sound compatibility"; - // s_options_compatibility_list.callback = new mcallback() { - // public void execute(Object o) { - // UpdateSoundQualityFunc(o); - // } - // }; - // s_options_compatibility_list.itemnames = compatibility_items; - // s_options_compatibility_list.curvalue = (int) Cvar.VariableValue("s_primary"); - - s_options_sensitivity_slider.type= MTYPE_SLIDER; - s_options_sensitivity_slider.x= 0; - s_options_sensitivity_slider.y= 50; - s_options_sensitivity_slider.name= "mouse speed"; - s_options_sensitivity_slider.callback= new mcallback() { - public void execute(Object o) { - MouseSpeedFunc(o); - } - }; - s_options_sensitivity_slider.minvalue= 2; - s_options_sensitivity_slider.maxvalue= 22; - - s_options_alwaysrun_box.type= MTYPE_SPINCONTROL; - s_options_alwaysrun_box.x= 0; - s_options_alwaysrun_box.y= 60; - s_options_alwaysrun_box.name= "always run"; - s_options_alwaysrun_box.callback= new mcallback() { - public void execute(Object o) { - AlwaysRunFunc(o); - } - }; - s_options_alwaysrun_box.itemnames= yesno_names; - - s_options_invertmouse_box.type= MTYPE_SPINCONTROL; - s_options_invertmouse_box.x= 0; - s_options_invertmouse_box.y= 70; - s_options_invertmouse_box.name= "invert mouse"; - s_options_invertmouse_box.callback= new mcallback() { - public void execute(Object o) { - InvertMouseFunc(o); - } - }; - s_options_invertmouse_box.itemnames= yesno_names; - - s_options_lookspring_box.type= MTYPE_SPINCONTROL; - s_options_lookspring_box.x= 0; - s_options_lookspring_box.y= 80; - s_options_lookspring_box.name= "lookspring"; - s_options_lookspring_box.callback= new mcallback() { - public void execute(Object o) { - LookspringFunc(o); - } - }; - s_options_lookspring_box.itemnames= yesno_names; - - s_options_lookstrafe_box.type= MTYPE_SPINCONTROL; - s_options_lookstrafe_box.x= 0; - s_options_lookstrafe_box.y= 90; - s_options_lookstrafe_box.name= "lookstrafe"; - s_options_lookstrafe_box.callback= new mcallback() { - public void execute(Object o) { - LookstrafeFunc(o); - } - }; - s_options_lookstrafe_box.itemnames= yesno_names; - - s_options_freelook_box.type= MTYPE_SPINCONTROL; - s_options_freelook_box.x= 0; - s_options_freelook_box.y= 100; - s_options_freelook_box.name= "free look"; - s_options_freelook_box.callback= new mcallback() { - public void execute(Object o) { - FreeLookFunc(o); - } - }; - s_options_freelook_box.itemnames= yesno_names; - - s_options_crosshair_box.type= MTYPE_SPINCONTROL; - s_options_crosshair_box.x= 0; - s_options_crosshair_box.y= 110; - s_options_crosshair_box.name= "crosshair"; - s_options_crosshair_box.callback= new mcallback() { - public void execute(Object o) { - CrosshairFunc(o); - } - }; - s_options_crosshair_box.itemnames= crosshair_names; - /* - s_options_noalttab_box.type = MTYPE_SPINCONTROL; - s_options_noalttab_box.x = 0; - s_options_noalttab_box.y = 110; - s_options_noalttab_box.name = "disable alt-tab"; - s_options_noalttab_box.callback = NoAltTabFunc; - s_options_noalttab_box.itemnames = yesno_names; - */ - s_options_joystick_box.type= MTYPE_SPINCONTROL; - s_options_joystick_box.x= 0; - s_options_joystick_box.y= 120; - s_options_joystick_box.name= "use joystick"; - s_options_joystick_box.callback= new mcallback() { - public void execute(Object o) { - JoystickFunc(o); - } - }; - s_options_joystick_box.itemnames= yesno_names; - - s_options_customize_options_action.type= MTYPE_ACTION; - s_options_customize_options_action.x= 0; - s_options_customize_options_action.y= 140; - s_options_customize_options_action.name= "customize controls"; - s_options_customize_options_action.callback= new mcallback() { - public void execute(Object o) { - CustomizeControlsFunc(o); - } - }; - - s_options_defaults_action.type= MTYPE_ACTION; - s_options_defaults_action.x= 0; - s_options_defaults_action.y= 150; - s_options_defaults_action.name= "reset defaults"; - s_options_defaults_action.callback= new mcallback() { - public void execute(Object o) { - ControlsResetDefaultsFunc(o); - } - }; - - s_options_console_action.type= MTYPE_ACTION; - s_options_console_action.x= 0; - s_options_console_action.y= 160; - s_options_console_action.name= "go to console"; - s_options_console_action.callback= new mcallback() { - public void execute(Object o) { - ConsoleFunc(o); - } - }; - - ControlsSetMenuItemValues(); - - Menu_AddItem(s_options_menu, s_options_sfxvolume_slider); - - Menu_AddItem(s_options_menu, s_options_cdvolume_box); - Menu_AddItem(s_options_menu, s_options_quality_list); - // Menu_AddItem(s_options_menu, s_options_compatibility_list); - Menu_AddItem(s_options_menu, s_options_sensitivity_slider); - Menu_AddItem(s_options_menu, s_options_alwaysrun_box); - Menu_AddItem(s_options_menu, s_options_invertmouse_box); - Menu_AddItem(s_options_menu, s_options_lookspring_box); - Menu_AddItem(s_options_menu, s_options_lookstrafe_box); - Menu_AddItem(s_options_menu, s_options_freelook_box); - Menu_AddItem(s_options_menu, s_options_crosshair_box); - // Menu_AddItem(s_options_menu, s_options_joystick_box); - Menu_AddItem(s_options_menu, s_options_customize_options_action); - Menu_AddItem(s_options_menu, s_options_defaults_action); - Menu_AddItem(s_options_menu, s_options_console_action); - } - - static void Options_MenuDraw() { - Banner("m_banner_options"); - Menu_AdjustCursor(s_options_menu, 1); - Menu_Draw(s_options_menu); - } - - static String Options_MenuKey(int key) { - return Default_MenuKey(s_options_menu, key); - } - - static xcommand_t Menu_Options= new xcommand_t() { - public void execute() { - Menu_Options_f(); - } - }; - - static void Menu_Options_f() { - Options_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - Options_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Options_MenuKey(key); - } - }); - } - - /* - ======================================================================= - - VIDEO MENU - - ======================================================================= - */ - - static xcommand_t Menu_Video= new xcommand_t() { - public void execute() { - Menu_Video_f(); - } - }; - - static void Menu_Video_f() { - VID.MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - VID.MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return VID.MenuKey(key); - } - }); - } - - /* - ============================================================================= - - END GAME MENU - - ============================================================================= - */ - static int credits_start_time; - - static String creditsIndex[]= new String[256]; - static String creditsBuffer; - static String idcredits[]= - { - "+QUAKE II BY ID SOFTWARE", - "", - "+PROGRAMMING", - "John Carmack", - "John Cash", - "Brian Hook", - "", - "+JAVA PORT BY BYTONIC", - "CWEI", - "HOZ", - "RST", - "", - "+ART", - "Adrian Carmack", - "Kevin Cloud", - "Paul Steed", - "", - "+LEVEL DESIGN", - "Tim Willits", - "American McGee", - "Christian Antkow", - "Paul Jaquays", - "Brandon James", - "", - "+BIZ", - "Todd Hollenshead", - "Barrett (Bear) Alexander", - "Donna Jackson", - "", - "", - "+SPECIAL THANKS", - "Ben Donges for beta testing", - "", - "", - "", - "", - "", - "", - "+ADDITIONAL SUPPORT", - "", - "+LINUX PORT AND CTF", - "Dave \"Zoid\" Kirsch", - "", - "+CINEMATIC SEQUENCES", - "Ending Cinematic by Blur Studio - ", - "Venice, CA", - "", - "Environment models for Introduction", - "Cinematic by Karl Dolgener", - "", - "Assistance with environment design", - "by Cliff Iwai", - "", - "+SOUND EFFECTS AND MUSIC", - "Sound Design by Soundelux Media Labs.", - "Music Composed and Produced by", - "Soundelux Media Labs. Special thanks", - "to Bill Brown, Tom Ozanich, Brian", - "Celano, Jeff Eisner, and The Soundelux", - "Players.", - "", - "\"Level Music\" by Sonic Mayhem", - "www.sonicmayhem.com", - "", - "\"Quake II Theme Song\"", - "(C) 1997 Rob Zombie. All Rights", - "Reserved.", - "", - "Track 10 (\"Climb\") by Jer Sypult", - "", - "Voice of computers by", - "Carly Staehlin-Taylor", - "", - "+THANKS TO ACTIVISION", - "+IN PARTICULAR:", - "", - "John Tam", - "Steve Rosenthal", - "Marty Stratton", - "Henk Hartong", - "", - "Quake II(tm) (C)1997 Id Software, Inc.", - "All Rights Reserved. Distributed by", - "Activision, Inc. under license.", - "Quake II(tm), the Id Software name,", - "the \"Q II\"(tm) logo and id(tm)", - "logo are trademarks of Id Software,", - "Inc. Activision(R) is a registered", - "trademark of Activision, Inc. All", - "other trademarks and trade names are", - "properties of their respective owners.", - null }; - static String credits[]= idcredits; - static String xatcredits[]= - { - "+QUAKE II MISSION PACK: THE RECKONING", - "+BY", - "+XATRIX ENTERTAINMENT, INC.", - "", - "+DESIGN AND DIRECTION", - "Drew Markham", - "", - "+PRODUCED BY", - "Greg Goodrich", - "", - "+PROGRAMMING", - "Rafael Paiz", - "", - "+LEVEL DESIGN / ADDITIONAL GAME DESIGN", - "Alex Mayberry", - "", - "+LEVEL DESIGN", - "Mal Blackwell", - "Dan Koppel", - "", - "+ART DIRECTION", - "Michael \"Maxx\" Kaufman", - "", - "+COMPUTER GRAPHICS SUPERVISOR AND", - "+CHARACTER ANIMATION DIRECTION", - "Barry Dempsey", - "", - "+SENIOR ANIMATOR AND MODELER", - "Jason Hoover", - "", - "+CHARACTER ANIMATION AND", - "+MOTION CAPTURE SPECIALIST", - "Amit Doron", - "", - "+ART", - "Claire Praderie-Markham", - "Viktor Antonov", - "Corky Lehmkuhl", - "", - "+INTRODUCTION ANIMATION", - "Dominique Drozdz", - "", - "+ADDITIONAL LEVEL DESIGN", - "Aaron Barber", - "Rhett Baldwin", - "", - "+3D CHARACTER ANIMATION TOOLS", - "Gerry Tyra, SA Technology", - "", - "+ADDITIONAL EDITOR TOOL PROGRAMMING", - "Robert Duffy", - "", - "+ADDITIONAL PROGRAMMING", - "Ryan Feltrin", - "", - "+PRODUCTION COORDINATOR", - "Victoria Sylvester", - "", - "+SOUND DESIGN", - "Gary Bradfield", - "", - "+MUSIC BY", - "Sonic Mayhem", - "", - "", - "", - "+SPECIAL THANKS", - "+TO", - "+OUR FRIENDS AT ID SOFTWARE", - "", - "John Carmack", - "John Cash", - "Brian Hook", - "Adrian Carmack", - "Kevin Cloud", - "Paul Steed", - "Tim Willits", - "Christian Antkow", - "Paul Jaquays", - "Brandon James", - "Todd Hollenshead", - "Barrett (Bear) Alexander", - "Dave \"Zoid\" Kirsch", - "Donna Jackson", - "", - "", - "", - "+THANKS TO ACTIVISION", - "+IN PARTICULAR:", - "", - "Marty Stratton", - "Henk \"The Original Ripper\" Hartong", - "Kevin Kraff", - "Jamey Gottlieb", - "Chris Hepburn", - "", - "+AND THE GAME TESTERS", - "", - "Tim Vanlaw", - "Doug Jacobs", - "Steven Rosenthal", - "David Baker", - "Chris Campbell", - "Aaron Casillas", - "Steve Elwell", - "Derek Johnstone", - "Igor Krinitskiy", - "Samantha Lee", - "Michael Spann", - "Chris Toft", - "Juan Valdes", - "", - "+THANKS TO INTERGRAPH COMPUTER SYTEMS", - "+IN PARTICULAR:", - "", - "Michael T. Nicolaou", - "", - "", - "Quake II Mission Pack: The Reckoning", - "(tm) (C)1998 Id Software, Inc. All", - "Rights Reserved. Developed by Xatrix", - "Entertainment, Inc. for Id Software,", - "Inc. Distributed by Activision Inc.", - "under license. Quake(R) is a", - "registered trademark of Id Software,", - "Inc. Quake II Mission Pack: The", - "Reckoning(tm), Quake II(tm), the Id", - "Software name, the \"Q II\"(tm) logo", - "and id(tm) logo are trademarks of Id", - "Software, Inc. Activision(R) is a", - "registered trademark of Activision,", - "Inc. Xatrix(R) is a registered", - "trademark of Xatrix Entertainment,", - "Inc. All other trademarks and trade", - "names are properties of their", - "respective owners.", - null }; - - static String roguecredits[]= - { - "+QUAKE II MISSION PACK 2: GROUND ZERO", - "+BY", - "+ROGUE ENTERTAINMENT, INC.", - "", - "+PRODUCED BY", - "Jim Molinets", - "", - "+PROGRAMMING", - "Peter Mack", - "Patrick Magruder", - "", - "+LEVEL DESIGN", - "Jim Molinets", - "Cameron Lamprecht", - "Berenger Fish", - "Robert Selitto", - "Steve Tietze", - "Steve Thoms", - "", - "+ART DIRECTION", - "Rich Fleider", - "", - "+ART", - "Rich Fleider", - "Steve Maines", - "Won Choi", - "", - "+ANIMATION SEQUENCES", - "Creat Studios", - "Steve Maines", - "", - "+ADDITIONAL LEVEL DESIGN", - "Rich Fleider", - "Steve Maines", - "Peter Mack", - "", - "+SOUND", - "James Grunke", - "", - "+GROUND ZERO THEME", - "+AND", - "+MUSIC BY", - "Sonic Mayhem", - "", - "+VWEP MODELS", - "Brent \"Hentai\" Dill", - "", - "", - "", - "+SPECIAL THANKS", - "+TO", - "+OUR FRIENDS AT ID SOFTWARE", - "", - "John Carmack", - "John Cash", - "Brian Hook", - "Adrian Carmack", - "Kevin Cloud", - "Paul Steed", - "Tim Willits", - "Christian Antkow", - "Paul Jaquays", - "Brandon James", - "Todd Hollenshead", - "Barrett (Bear) Alexander", - "Katherine Anna Kang", - "Donna Jackson", - "Dave \"Zoid\" Kirsch", - "", - "", - "", - "+THANKS TO ACTIVISION", - "+IN PARTICULAR:", - "", - "Marty Stratton", - "Henk Hartong", - "Mitch Lasky", - "Steve Rosenthal", - "Steve Elwell", - "", - "+AND THE GAME TESTERS", - "", - "The Ranger Clan", - "Dave \"Zoid\" Kirsch", - "Nihilistic Software", - "Robert Duffy", - "", - "And Countless Others", - "", - "", - "", - "Quake II Mission Pack 2: Ground Zero", - "(tm) (C)1998 Id Software, Inc. All", - "Rights Reserved. Developed by Rogue", - "Entertainment, Inc. for Id Software,", - "Inc. Distributed by Activision Inc.", - "under license. Quake(R) is a", - "registered trademark of Id Software,", - "Inc. Quake II Mission Pack 2: Ground", - "Zero(tm), Quake II(tm), the Id", - "Software name, the \"Q II\"(tm) logo", - "and id(tm) logo are trademarks of Id", - "Software, Inc. Activision(R) is a", - "registered trademark of Activision,", - "Inc. Rogue(R) is a registered", - "trademark of Rogue Entertainment,", - "Inc. All other trademarks and trade", - "names are properties of their", - "respective owners.", - null }; - - public static void Credits_MenuDraw() { - int i, y; - - /* - ** draw the credits - */ - for (i= 0, y= (int) (viddef.height - ((cls.realtime - credits_start_time) / 40.0F)); - credits[i] != null && y < viddef.height; - y += 10, i++) { - int j, stringoffset= 0; - boolean bold= false; - - if (y <= -8) - continue; - - if (credits[i].length() > 0 && credits[i].charAt(0) == '+') { - bold= true; - stringoffset= 1; - } - else { - bold= false; - stringoffset= 0; - } - - for (j= 0; j + stringoffset < credits[i].length(); j++) { - int x; - - x= (viddef.width - credits[i].length() * 8 - stringoffset * 8) / 2 + (j + stringoffset) * 8; - - if (bold) - re.DrawChar(x, y, credits[i].charAt(j + stringoffset) + 128); - else - re.DrawChar(x, y, credits[i].charAt(j + stringoffset)); - } - } - - if (y < 0) - credits_start_time= cls.realtime; - } - - public static String Credits_Key(int key) { - switch (key) { - case K_ESCAPE : - if (creditsBuffer != null) - //FS.FreeFile(creditsBuffer); - ; - PopMenu(); - break; - } - - return menu_out_sound; - - } - - static xcommand_t Menu_Credits= new xcommand_t() { - public void execute() { - Menu_Credits_f(); - } - }; - static void Menu_Credits_f() { - int n; - int isdeveloper= 0; - - byte b[]= FS.LoadFile("credits"); - - if (b != null) { - creditsBuffer= new String(b); - String line[]= Lib.linesplit(creditsBuffer); - - for (n= 0; n < line.length; n++) { - creditsIndex[n]= line[n]; - } - - creditsIndex[n]= null; - credits= creditsIndex; - } - else { - isdeveloper= FS.Developer_searchpath(1); - - if (isdeveloper == 1) // xatrix - credits= xatcredits; - else if (isdeveloper == 2) // ROGUE - credits= roguecredits; - else { - credits= idcredits; - } - - } - - credits_start_time= cls.realtime; - PushMenu(new xcommand_t() { - public void execute() { - Credits_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Credits_Key(key); - } - }); - } - - /* - ============================================================================= - - GAME MENU - - ============================================================================= - */ - - static int m_game_cursor; - - static menuframework_s s_game_menu= new menuframework_s(); - static menuaction_s s_easy_game_action= new menuaction_s(); - static menuaction_s s_medium_game_action= new menuaction_s(); - static menuaction_s s_hard_game_action= new menuaction_s(); - static menuaction_s s_load_game_action= new menuaction_s(); - static menuaction_s s_save_game_action= new menuaction_s(); - static menuaction_s s_credits_action= new menuaction_s(); - static menuseparator_s s_blankline= new menuseparator_s(); - - static void StartGame() { - // disable updates and start the cinematic going - cl.servercount= -1; - ForceMenuOff(); - Cvar.SetValue("deathmatch", 0); - Cvar.SetValue("coop", 0); - - Cvar.SetValue("gamerules", 0); //PGM - - Cbuf.AddText("loading ; killserver ; wait ; newgame\n"); - cls.key_dest= key_game; - } - - static void EasyGameFunc(Object data) { - Cvar.ForceSet("skill", "0"); - StartGame(); - } - - static void MediumGameFunc(Object data) { - Cvar.ForceSet("skill", "1"); - StartGame(); - } - - static void HardGameFunc(Object data) { - Cvar.ForceSet("skill", "2"); - StartGame(); - } - - static void LoadGameFunc(Object unused) { - Menu_LoadGame_f(); - } - - static void SaveGameFunc(Object unused) { - Menu_SaveGame_f(); - } - - static void CreditsFunc(Object unused) { - Menu_Credits_f(); - } - - static String difficulty_names[]= { "easy", "medium", "fuckin shitty hard", null }; - static void Game_MenuInit() { - - s_game_menu.x= (int) (viddef.width * 0.50); - s_game_menu.nitems= 0; - - s_easy_game_action.type= MTYPE_ACTION; - s_easy_game_action.flags= QMF_LEFT_JUSTIFY; - s_easy_game_action.x= 0; - s_easy_game_action.y= 0; - s_easy_game_action.name= "easy"; - s_easy_game_action.callback= new mcallback() { - public void execute(Object o) { - EasyGameFunc(o); - } - }; - - s_medium_game_action.type= MTYPE_ACTION; - s_medium_game_action.flags= QMF_LEFT_JUSTIFY; - s_medium_game_action.x= 0; - s_medium_game_action.y= 10; - s_medium_game_action.name= "medium"; - s_medium_game_action.callback= new mcallback() { - public void execute(Object o) { - MediumGameFunc(o); - } - }; - - s_hard_game_action.type= MTYPE_ACTION; - s_hard_game_action.flags= QMF_LEFT_JUSTIFY; - s_hard_game_action.x= 0; - s_hard_game_action.y= 20; - s_hard_game_action.name= "hard"; - s_hard_game_action.callback= new mcallback() { - public void execute(Object o) { - HardGameFunc(o); - } - }; - - s_blankline.type= MTYPE_SEPARATOR; - - s_load_game_action.type= MTYPE_ACTION; - s_load_game_action.flags= QMF_LEFT_JUSTIFY; - s_load_game_action.x= 0; - s_load_game_action.y= 40; - s_load_game_action.name= "load game"; - s_load_game_action.callback= new mcallback() { - public void execute(Object o) { - LoadGameFunc(o); - } - }; - - s_save_game_action.type= MTYPE_ACTION; - s_save_game_action.flags= QMF_LEFT_JUSTIFY; - s_save_game_action.x= 0; - s_save_game_action.y= 50; - s_save_game_action.name= "save game"; - s_save_game_action.callback= new mcallback() { - public void execute(Object o) { - SaveGameFunc(o); - } - }; - - s_credits_action.type= MTYPE_ACTION; - s_credits_action.flags= QMF_LEFT_JUSTIFY; - s_credits_action.x= 0; - s_credits_action.y= 60; - s_credits_action.name= "credits"; - s_credits_action.callback= new mcallback() { - public void execute(Object o) { - CreditsFunc(o); - } - }; - - Menu_AddItem(s_game_menu, s_easy_game_action); - Menu_AddItem(s_game_menu, s_medium_game_action); - Menu_AddItem(s_game_menu, s_hard_game_action); - Menu_AddItem(s_game_menu, s_blankline); - Menu_AddItem(s_game_menu, s_load_game_action); - Menu_AddItem(s_game_menu, s_save_game_action); - Menu_AddItem(s_game_menu, s_blankline); - Menu_AddItem(s_game_menu, s_credits_action); - - Menu_Center(s_game_menu); - } - - static void Game_MenuDraw() { - Banner("m_banner_game"); - Menu_AdjustCursor(s_game_menu, 1); - Menu_Draw(s_game_menu); - } - - static String Game_MenuKey(int key) { - return Default_MenuKey(s_game_menu, key); - } - - static xcommand_t Menu_Game= new xcommand_t() { - public void execute() { - Menu_Game_f(); - } - }; - - static void Menu_Game_f() { - Game_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - Game_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Game_MenuKey(key); - } - }); - m_game_cursor= 1; - } - - /* - ============================================================================= - - LOADGAME MENU - - ============================================================================= - */ - - public final static int MAX_SAVEGAMES= 15; - - static menuframework_s s_savegame_menu= new menuframework_s(); - static menuframework_s s_loadgame_menu= new menuframework_s(); - - static menuaction_s s_loadgame_actions[]= new menuaction_s[MAX_SAVEGAMES]; - - static { - for (int n= 0; n < MAX_SAVEGAMES; n++) - s_loadgame_actions[n]= new menuaction_s(); - } - - //String m_savestrings[] = new String [MAX_SAVEGAMES][32]; - static String m_savestrings[]= new String[MAX_SAVEGAMES]; - - static { - for (int n= 0; n < MAX_SAVEGAMES; n++) - m_savestrings[n]= ""; - } - - static boolean m_savevalid[]= new boolean[MAX_SAVEGAMES]; - - /** Search the save dir for saved games and their names. */ - static void Create_Savestrings() { - int i; - QuakeFile f; - String name; - - for (i= 0; i < MAX_SAVEGAMES; i++) { - - m_savestrings[i]= "<EMPTY>"; - name= FS.Gamedir() + "/save/save" + i + "/server.ssv"; - - try { - f= new QuakeFile(name, "r"); - if (f == null) { - m_savestrings[i]= "<EMPTY>"; - m_savevalid[i]= false; - } - else { - String str= f.readString(); - if (str != null) - m_savestrings[i]= str; - f.close(); - m_savevalid[i]= true; - } - } - catch (Exception e) { - m_savestrings[i]= "<EMPTY>"; - m_savevalid[i]= false; - }; - } - } - - static void LoadGameCallback(Object self) { - menuaction_s a= (menuaction_s) self; - - if (m_savevalid[a.localdata[0]]) - Cbuf.AddText("load save" + a.localdata[0] + "\n"); - ForceMenuOff(); - } - - static void LoadGame_MenuInit() { - int i; - - s_loadgame_menu.x= viddef.width / 2 - 120; - s_loadgame_menu.y= viddef.height / 2 - 58; - s_loadgame_menu.nitems= 0; - - Create_Savestrings(); - - for (i= 0; i < MAX_SAVEGAMES; i++) { - s_loadgame_actions[i].name= m_savestrings[i]; - s_loadgame_actions[i].flags= QMF_LEFT_JUSTIFY; - s_loadgame_actions[i].localdata[0]= i; - s_loadgame_actions[i].callback= new mcallback() { - public void execute(Object o) { - LoadGameCallback(o); - } - }; - - s_loadgame_actions[i].x= 0; - s_loadgame_actions[i].y= (i) * 10; - if (i > 0) // separate from autosave - s_loadgame_actions[i].y += 10; - - s_loadgame_actions[i].type= MTYPE_ACTION; - - Menu_AddItem(s_loadgame_menu, s_loadgame_actions[i]); - } - } - - static void LoadGame_MenuDraw() { - Banner("m_banner_load_game"); - // Menu_AdjustCursor( &s_loadgame_menu, 1 ); - Menu_Draw(s_loadgame_menu); - } - - static String LoadGame_MenuKey(int key) { - if (key == K_ESCAPE || key == K_ENTER) { - s_savegame_menu.cursor= s_loadgame_menu.cursor - 1; - if (s_savegame_menu.cursor < 0) - s_savegame_menu.cursor= 0; - } - return Default_MenuKey(s_loadgame_menu, key); - } - - static xcommand_t Menu_LoadGame= new xcommand_t() { - public void execute() { - Menu_LoadGame_f(); - } - }; - static void Menu_LoadGame_f() { - LoadGame_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - LoadGame_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return LoadGame_MenuKey(key); - } - }); - } - - /* - ============================================================================= - - SAVEGAME MENU - - ============================================================================= - */ - //static menuframework_s s_savegame_menu; - static menuaction_s s_savegame_actions[]= new menuaction_s[MAX_SAVEGAMES]; - - static { - for (int n= 0; n < MAX_SAVEGAMES; n++) - s_savegame_actions[n]= new menuaction_s(); - - } - - static void SaveGameCallback(Object self) { - menuaction_s a= (menuaction_s) self; - - Cbuf.AddText("save save" + a.localdata[0] + "\n"); - ForceMenuOff(); - } - - static void SaveGame_MenuDraw() { - Banner("m_banner_save_game"); - Menu_AdjustCursor(s_savegame_menu, 1); - Menu_Draw(s_savegame_menu); - } - - static void SaveGame_MenuInit() { - int i; - - s_savegame_menu.x= viddef.width / 2 - 120; - s_savegame_menu.y= viddef.height / 2 - 58; - s_savegame_menu.nitems= 0; - - Create_Savestrings(); - - // don't include the autosave slot - for (i= 0; i < MAX_SAVEGAMES - 1; i++) { - s_savegame_actions[i].name= m_savestrings[i + 1]; - s_savegame_actions[i].localdata[0]= i + 1; - s_savegame_actions[i].flags= QMF_LEFT_JUSTIFY; - s_savegame_actions[i].callback= new mcallback() { - public void execute(Object o) { - SaveGameCallback(o); - } - }; - - s_savegame_actions[i].x= 0; - s_savegame_actions[i].y= (i) * 10; - - s_savegame_actions[i].type= MTYPE_ACTION; - - Menu_AddItem(s_savegame_menu, s_savegame_actions[i]); - } - } - - static String SaveGame_MenuKey(int key) { - if (key == K_ENTER || key == K_ESCAPE) { - s_loadgame_menu.cursor= s_savegame_menu.cursor - 1; - if (s_loadgame_menu.cursor < 0) - s_loadgame_menu.cursor= 0; - } - return Default_MenuKey(s_savegame_menu, key); - } - - static xcommand_t Menu_SaveGame= new xcommand_t() { - public void execute() { - Menu_SaveGame_f(); - } - }; - - static void Menu_SaveGame_f() { - if (0 == Globals.server_state) - return; // not playing a game - - SaveGame_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - SaveGame_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return SaveGame_MenuKey(key); - } - }); - Create_Savestrings(); - } - - /* - ============================================================================= - - JOIN SERVER MENU - - ============================================================================= - */ - - static menuframework_s s_joinserver_menu= new menuframework_s(); - static menuseparator_s s_joinserver_server_title= new menuseparator_s(); - static menuaction_s s_joinserver_search_action= new menuaction_s(); - static menuaction_s s_joinserver_address_book_action= new menuaction_s(); - - static netadr_t local_server_netadr[]= new netadr_t[MAX_LOCAL_SERVERS]; - static String local_server_names[]= new String[MAX_LOCAL_SERVERS]; //[80]; - static menuaction_s s_joinserver_server_actions[]= new menuaction_s[MAX_LOCAL_SERVERS]; - - // user readable information - // network address - static { - for (int n= 0; n < MAX_LOCAL_SERVERS; n++) { - local_server_netadr[n]= new netadr_t(); - local_server_names[n]= ""; - s_joinserver_server_actions[n]= new menuaction_s(); - s_joinserver_server_actions[n].n= n; - } - } - - static int m_num_servers; - - static void AddToServerList(netadr_t adr, String info) { - int i; - - if (m_num_servers == MAX_LOCAL_SERVERS) - return; - - String x= info.trim(); - - // ignore if duplicated - - for (i= 0; i < m_num_servers; i++) - if (x.equals(local_server_names[i])) - return; - - local_server_netadr[m_num_servers]= adr; - local_server_names[m_num_servers]= x; - m_num_servers++; - } - - static void JoinServerFunc(Object self) { - String buffer; - int index; - - index= ((menucommon_s) self).n; - - if (Q_stricmp(local_server_names[index], NO_SERVER_STRING) == 0) - return; - - if (index >= m_num_servers) - return; - - buffer= "connect " + NET.AdrToString(local_server_netadr[index]) + "\n"; - Cbuf.AddText(buffer); - ForceMenuOff(); - } - - static void AddressBookFunc(Object self) { - Menu_AddressBook_f(); - } - - static void NullCursorDraw(Object self) { - } - - static void SearchLocalGames() { - int i; - - m_num_servers= 0; - for (i= 0; i < MAX_LOCAL_SERVERS; i++) - local_server_names[i]= NO_SERVER_STRING; - - DrawTextBox(8, 120 - 48, 36, 3); - Print(16 + 16, 120 - 48 + 8, "Searching for local servers, this"); - Print(16 + 16, 120 - 48 + 16, "could take up to a minute, so"); - Print(16 + 16, 120 - 48 + 24, "please be patient."); - - // the text box won't show up unless we do a buffer swap - re.EndFrame(); - - // send out info packets - CL.PingServers_f.execute(); - } - - static void SearchLocalGamesFunc(Object self) { - SearchLocalGames(); - } - - static void JoinServer_MenuInit() { - int i; - - s_joinserver_menu.x= (int) (viddef.width * 0.50 - 120); - s_joinserver_menu.nitems= 0; - - s_joinserver_address_book_action.type= MTYPE_ACTION; - s_joinserver_address_book_action.name= "address book"; - s_joinserver_address_book_action.flags= QMF_LEFT_JUSTIFY; - s_joinserver_address_book_action.x= 0; - s_joinserver_address_book_action.y= 0; - s_joinserver_address_book_action.callback= new mcallback() { - public void execute(Object o) { - AddressBookFunc(o); - } - }; - - s_joinserver_search_action.type= MTYPE_ACTION; - s_joinserver_search_action.name= "refresh server list"; - s_joinserver_search_action.flags= QMF_LEFT_JUSTIFY; - s_joinserver_search_action.x= 0; - s_joinserver_search_action.y= 10; - s_joinserver_search_action.callback= new mcallback() { - public void execute(Object o) { - SearchLocalGamesFunc(o); - } - }; - s_joinserver_search_action.statusbar= "search for servers"; - - s_joinserver_server_title.type= MTYPE_SEPARATOR; - s_joinserver_server_title.name= "connect to..."; - s_joinserver_server_title.x= 80; - s_joinserver_server_title.y= 30; - - for (i= 0; i < MAX_LOCAL_SERVERS; i++) { - s_joinserver_server_actions[i].type= MTYPE_ACTION; - local_server_names[i]= NO_SERVER_STRING; - s_joinserver_server_actions[i].name= local_server_names[i]; - s_joinserver_server_actions[i].flags= QMF_LEFT_JUSTIFY; - s_joinserver_server_actions[i].x= 0; - s_joinserver_server_actions[i].y= 40 + i * 10; - s_joinserver_server_actions[i].callback= new mcallback() { - public void execute(Object o) { - JoinServerFunc(o); - } - }; - s_joinserver_server_actions[i].statusbar= "press ENTER to connect"; - } - - Menu_AddItem(s_joinserver_menu, s_joinserver_address_book_action); - Menu_AddItem(s_joinserver_menu, s_joinserver_server_title); - Menu_AddItem(s_joinserver_menu, s_joinserver_search_action); - - for (i= 0; i < 8; i++) - Menu_AddItem(s_joinserver_menu, s_joinserver_server_actions[i]); - - Menu_Center(s_joinserver_menu); - - SearchLocalGames(); - } - - static void JoinServer_MenuDraw() { - Banner("m_banner_join_server"); - Menu_Draw(s_joinserver_menu); - } - - static String JoinServer_MenuKey(int key) { - return Default_MenuKey(s_joinserver_menu, key); - } - - static xcommand_t Menu_JoinServer= new xcommand_t() { - public void execute() { - Menu_JoinServer_f(); - } - }; - static void Menu_JoinServer_f() { - JoinServer_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - JoinServer_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return JoinServer_MenuKey(key); - } - }); - } - - /* - ============================================================================= - - START SERVER MENU - - ============================================================================= - */ - static menuframework_s s_startserver_menu= new menuframework_s(); - static String mapnames[]; - static int nummaps; - - static menuaction_s s_startserver_start_action= new menuaction_s(); - static menuaction_s s_startserver_dmoptions_action= new menuaction_s(); - static menufield_s s_timelimit_field= new menufield_s(); - static menufield_s s_fraglimit_field= new menufield_s(); - static menufield_s s_maxclients_field= new menufield_s(); - static menufield_s s_hostname_field= new menufield_s(); - static menulist_s s_startmap_list= new menulist_s(); - static menulist_s s_rules_box= new menulist_s(); - - static void DMOptionsFunc(Object self) { - if (s_rules_box.curvalue == 1) - return; - Menu_DMOptions_f(); - } - - static void RulesChangeFunc(Object self) { - // DM - if (s_rules_box.curvalue == 0) { - s_maxclients_field.statusbar= null; - s_startserver_dmoptions_action.statusbar= null; - } - else if (s_rules_box.curvalue == 1) - // coop // PGM - { - s_maxclients_field.statusbar= "4 maximum for cooperative"; - if (atoi(s_maxclients_field.buffer.toString()) > 4) - s_maxclients_field.buffer= new StringBuffer("4"); - s_startserver_dmoptions_action.statusbar= "N/A for cooperative"; - } - // ===== - // PGM - // ROGUE GAMES - else if (FS.Developer_searchpath(2) == 2) { - if (s_rules_box.curvalue == 2) // tag - { - s_maxclients_field.statusbar= null; - s_startserver_dmoptions_action.statusbar= null; - } - /* - else if(s_rules_box.curvalue == 3) // deathball - { - s_maxclients_field.statusbar = null; - s_startserver_dmoptions_action.statusbar = null; - } - */ - } - // PGM - // ===== - } - - static void StartServerActionFunc(Object self) { - //char startmap[1024]; - String startmap; - int timelimit; - int fraglimit; - int maxclients; - String spot; - - //strcpy(startmap, strchr(mapnames[s_startmap_list.curvalue], '\n') + 1); - String x= mapnames[s_startmap_list.curvalue]; - - int pos= x.indexOf('\n'); - if (pos == -1) - startmap= x; - else - startmap= x.substring(pos + 1, x.length()); - - maxclients= atoi(s_maxclients_field.buffer.toString()); - timelimit= atoi(s_timelimit_field.buffer.toString()); - fraglimit= atoi(s_fraglimit_field.buffer.toString()); - - Cvar.SetValue("maxclients", ClampCvar(0, maxclients, maxclients)); - Cvar.SetValue("timelimit", ClampCvar(0, timelimit, timelimit)); - Cvar.SetValue("fraglimit", ClampCvar(0, fraglimit, fraglimit)); - Cvar.Set("hostname", s_hostname_field.buffer.toString()); - // Cvar.SetValue ("deathmatch", !s_rules_box.curvalue ); - // Cvar.SetValue ("coop", s_rules_box.curvalue ); - - // PGM - if ((s_rules_box.curvalue < 2) || (FS.Developer_searchpath(2) != 2)) { - Cvar.SetValue("deathmatch", 1 - (int) (s_rules_box.curvalue)); - Cvar.SetValue("coop", s_rules_box.curvalue); - Cvar.SetValue("gamerules", 0); - } - else { - Cvar.SetValue("deathmatch", 1); - // deathmatch is always true for rogue games, right? - Cvar.SetValue("coop", 0); - // FIXME - this might need to depend on which game we're running - Cvar.SetValue("gamerules", s_rules_box.curvalue); - } - // PGM - - spot= null; - if (s_rules_box.curvalue == 1) // PGM - { - if (Q_stricmp(startmap, "bunk1") == 0) - spot= "start"; - else if (Q_stricmp(startmap, "mintro") == 0) - spot= "start"; - else if (Q_stricmp(startmap, "fact1") == 0) - spot= "start"; - else if (Q_stricmp(startmap, "power1") == 0) - spot= "pstart"; - else if (Q_stricmp(startmap, "biggun") == 0) - spot= "bstart"; - else if (Q_stricmp(startmap, "hangar1") == 0) - spot= "unitstart"; - else if (Q_stricmp(startmap, "city1") == 0) - spot= "unitstart"; - else if (Q_stricmp(startmap, "boss1") == 0) - spot= "bosstart"; - } - - if (spot != null) { - if (Globals.server_state != 0) - Cbuf.AddText("disconnect\n"); - Cbuf.AddText("gamemap \"*" + startmap + "$" + spot + "\"\n"); - } - else { - Cbuf.AddText("map " + startmap + "\n"); - } - - ForceMenuOff(); - } - - static String dm_coop_names[]= { "deathmatch", "cooperative", null }; - static String dm_coop_names_rogue[]= { "deathmatch", "cooperative", "tag", - // "deathball", - null }; - - static void StartServer_MenuInit() { - - // ======= - // PGM - // ======= - - byte[] buffer= null; - String mapsname; - String s; - int i; - RandomAccessFile fp; - - /* - ** load the list of map names - */ - mapsname= FS.Gamedir() + "/maps.lst"; - - if ((fp= fopen(mapsname, "r")) == null) { - buffer= FS.LoadFile("maps.lst"); - if (buffer == null) - //if ((length = FS_LoadFile("maps.lst", (Object *) & buffer)) == -1) - Com.Error(ERR_DROP, "couldn't find maps.lst\n"); - } - else { - try { - int len= (int) fp.length(); - buffer= new byte[len]; - fp.readFully(buffer); - } - catch (Exception e) { - Com.Error(ERR_DROP, "couldn't load maps.lst\n"); - } - } - - s= new String(buffer); - String lines[]= Lib.linesplit(s); - - nummaps= lines.length; - - if (nummaps == 0) - Com.Error(ERR_DROP, "no maps in maps.lst\n"); - - mapnames= new String[nummaps + 1]; - - for (i= 0; i < nummaps; i++) { - String shortname, longname, scratch; - - Com.ParseHelp ph= new Com.ParseHelp(lines[i]); - - shortname= Com.Parse(ph).toUpperCase(); - longname= Com.Parse(ph); - scratch= longname + "\n" + shortname; - mapnames[i]= scratch; - } - mapnames[nummaps]= null; - - if (fp != null) { - fclose(fp); - fp= null; - - } - else { - FS.FreeFile(buffer); - } - - /* - ** initialize the menu stuff - */ - s_startserver_menu.x= (int) (viddef.width * 0.50); - s_startserver_menu.nitems= 0; - - s_startmap_list.type= MTYPE_SPINCONTROL; - s_startmap_list.x= 0; - s_startmap_list.y= 0; - s_startmap_list.name= "initial map"; - s_startmap_list.itemnames= mapnames; - - s_rules_box.type= MTYPE_SPINCONTROL; - s_rules_box.x= 0; - s_rules_box.y= 20; - s_rules_box.name= "rules"; - - // PGM - rogue games only available with rogue DLL. - if (FS.Developer_searchpath(2) == 2) - s_rules_box.itemnames= dm_coop_names_rogue; - else - s_rules_box.itemnames= dm_coop_names; - // PGM - - if (Cvar.VariableValue("coop") != 0) - s_rules_box.curvalue= 1; - else - s_rules_box.curvalue= 0; - s_rules_box.callback= new mcallback() { - public void execute(Object o) { - RulesChangeFunc(o); - } - }; - - s_timelimit_field.type= MTYPE_FIELD; - s_timelimit_field.name= "time limit"; - s_timelimit_field.flags= QMF_NUMBERSONLY; - s_timelimit_field.x= 0; - s_timelimit_field.y= 36; - s_timelimit_field.statusbar= "0 = no limit"; - s_timelimit_field.length= 3; - s_timelimit_field.visible_length= 3; - s_timelimit_field.buffer= new StringBuffer(Cvar.VariableString("timelimit")); - - s_fraglimit_field.type= MTYPE_FIELD; - s_fraglimit_field.name= "frag limit"; - s_fraglimit_field.flags= QMF_NUMBERSONLY; - s_fraglimit_field.x= 0; - s_fraglimit_field.y= 54; - s_fraglimit_field.statusbar= "0 = no limit"; - s_fraglimit_field.length= 3; - s_fraglimit_field.visible_length= 3; - s_fraglimit_field.buffer= new StringBuffer(Cvar.VariableString("fraglimit")); - - /* - ** maxclients determines the maximum number of players that can join - ** the game. If maxclients is only "1" then we should default the menu - ** option to 8 players, otherwise use whatever its current value is. - ** Clamping will be done when the server is actually started. - */ - s_maxclients_field.type= MTYPE_FIELD; - s_maxclients_field.name= "max players"; - s_maxclients_field.flags= QMF_NUMBERSONLY; - s_maxclients_field.x= 0; - s_maxclients_field.y= 72; - s_maxclients_field.statusbar= null; - s_maxclients_field.length= 3; - s_maxclients_field.visible_length= 3; - if (Cvar.VariableValue("maxclients") == 1) - s_maxclients_field.buffer= new StringBuffer("8"); - else - s_maxclients_field.buffer= new StringBuffer(Cvar.VariableString("maxclients")); - - s_hostname_field.type= MTYPE_FIELD; - s_hostname_field.name= "hostname"; - s_hostname_field.flags= 0; - s_hostname_field.x= 0; - s_hostname_field.y= 90; - s_hostname_field.statusbar= null; - s_hostname_field.length= 12; - s_hostname_field.visible_length= 12; - s_hostname_field.buffer= new StringBuffer(Cvar.VariableString("hostname")); - s_hostname_field.cursor= s_hostname_field.buffer.length(); - - s_startserver_dmoptions_action.type= MTYPE_ACTION; - s_startserver_dmoptions_action.name= " deathmatch flags"; - s_startserver_dmoptions_action.flags= QMF_LEFT_JUSTIFY; - s_startserver_dmoptions_action.x= 24; - s_startserver_dmoptions_action.y= 108; - s_startserver_dmoptions_action.statusbar= null; - s_startserver_dmoptions_action.callback= new mcallback() { - public void execute(Object o) { - DMOptionsFunc(o); - } - }; - - s_startserver_start_action.type= MTYPE_ACTION; - s_startserver_start_action.name= " begin"; - s_startserver_start_action.flags= QMF_LEFT_JUSTIFY; - s_startserver_start_action.x= 24; - s_startserver_start_action.y= 128; - s_startserver_start_action.callback= new mcallback() { - public void execute(Object o) { - StartServerActionFunc(o); - } - }; - - Menu_AddItem(s_startserver_menu, s_startmap_list); - Menu_AddItem(s_startserver_menu, s_rules_box); - Menu_AddItem(s_startserver_menu, s_timelimit_field); - Menu_AddItem(s_startserver_menu, s_fraglimit_field); - Menu_AddItem(s_startserver_menu, s_maxclients_field); - Menu_AddItem(s_startserver_menu, s_hostname_field); - Menu_AddItem(s_startserver_menu, s_startserver_dmoptions_action); - Menu_AddItem(s_startserver_menu, s_startserver_start_action); - - Menu_Center(s_startserver_menu); - - // call this now to set proper inital state - RulesChangeFunc(null); - } - - static void StartServer_MenuDraw() { - Menu_Draw(s_startserver_menu); - } - - static String StartServer_MenuKey(int key) { - if (key == K_ESCAPE) { - if (mapnames != null) { - int i; - - for (i= 0; i < nummaps; i++) - mapnames[i]= null; - - } - mapnames= null; - nummaps= 0; - } - - return Default_MenuKey(s_startserver_menu, key); - } - - static xcommand_t Menu_StartServer= new xcommand_t() { - public void execute() { - Menu_StartServer_f(); - } - }; - static void Menu_StartServer_f() { - StartServer_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - StartServer_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return StartServer_MenuKey(key); - } - }); - } - - /* - ============================================================================= - - DMOPTIONS BOOK MENU - - ============================================================================= - */ - static String dmoptions_statusbar; //[128]; - - static menuframework_s s_dmoptions_menu= new menuframework_s(); - - static menulist_s s_friendlyfire_box= new menulist_s(); - static menulist_s s_falls_box= new menulist_s(); - static menulist_s s_weapons_stay_box= new menulist_s(); - static menulist_s s_instant_powerups_box= new menulist_s(); - static menulist_s s_powerups_box= new menulist_s(); - static menulist_s s_health_box= new menulist_s(); - static menulist_s s_spawn_farthest_box= new menulist_s(); - static menulist_s s_teamplay_box= new menulist_s(); - static menulist_s s_samelevel_box= new menulist_s(); - static menulist_s s_force_respawn_box= new menulist_s(); - static menulist_s s_armor_box= new menulist_s(); - static menulist_s s_allow_exit_box= new menulist_s(); - static menulist_s s_infinite_ammo_box= new menulist_s(); - static menulist_s s_fixed_fov_box= new menulist_s(); - static menulist_s s_quad_drop_box= new menulist_s(); - - // ROGUE - static menulist_s s_no_mines_box= new menulist_s(); - static menulist_s s_no_nukes_box= new menulist_s(); - static menulist_s s_stack_double_box= new menulist_s(); - static menulist_s s_no_spheres_box= new menulist_s(); - // ROGUE - - static void setvalue(int flags) { - Cvar.SetValue("dmflags", flags); - dmoptions_statusbar= "dmflags = " + flags; - } - - static void DMFlagCallback(Object self) { - menulist_s f= (menulist_s) self; - int flags; - int bit= 0; - - flags= (int) Cvar.VariableValue("dmflags"); - - if (f == s_friendlyfire_box) { - if (f.curvalue != 0) - flags &= ~DF_NO_FRIENDLY_FIRE; - else - flags |= DF_NO_FRIENDLY_FIRE; - setvalue(flags); - return; - } - else if (f == s_falls_box) { - if (f.curvalue != 0) - flags &= ~DF_NO_FALLING; - else - flags |= DF_NO_FALLING; - setvalue(flags); - return; - } - else if (f == s_weapons_stay_box) { - bit= DF_WEAPONS_STAY; - } - else if (f == s_instant_powerups_box) { - bit= DF_INSTANT_ITEMS; - } - else if (f == s_allow_exit_box) { - bit= DF_ALLOW_EXIT; - } - else if (f == s_powerups_box) { - if (f.curvalue != 0) - flags &= ~DF_NO_ITEMS; - else - flags |= DF_NO_ITEMS; - setvalue(flags); - return; - } - else if (f == s_health_box) { - if (f.curvalue != 0) - flags &= ~DF_NO_HEALTH; - else - flags |= DF_NO_HEALTH; - setvalue(flags); - return; - } - else if (f == s_spawn_farthest_box) { - bit= DF_SPAWN_FARTHEST; - } - else if (f == s_teamplay_box) { - if (f.curvalue == 1) { - flags |= DF_SKINTEAMS; - flags &= ~DF_MODELTEAMS; - } - else if (f.curvalue == 2) { - flags |= DF_MODELTEAMS; - flags &= ~DF_SKINTEAMS; - } - else { - flags &= ~(DF_MODELTEAMS | DF_SKINTEAMS); - } - - setvalue(flags); - return; - } - else if (f == s_samelevel_box) { - bit= DF_SAME_LEVEL; - } - else if (f == s_force_respawn_box) { - bit= DF_FORCE_RESPAWN; - } - else if (f == s_armor_box) { - if (f.curvalue != 0) - flags &= ~DF_NO_ARMOR; - else - flags |= DF_NO_ARMOR; - setvalue(flags); - return; - } - else if (f == s_infinite_ammo_box) { - bit= DF_INFINITE_AMMO; - } - else if (f == s_fixed_fov_box) { - bit= DF_FIXED_FOV; - } - else if (f == s_quad_drop_box) { - bit= DF_QUAD_DROP; - } - - // ======= - // ROGUE - else if (FS.Developer_searchpath(2) == 2) { - if (f == s_no_mines_box) { - bit= DF_NO_MINES; - } - else if (f == s_no_nukes_box) { - bit= DF_NO_NUKES; - } - else if (f == s_stack_double_box) { - bit= DF_NO_STACK_DOUBLE; - } - else if (f == s_no_spheres_box) { - bit= DF_NO_SPHERES; - } - } - // ROGUE - // ======= - - if (f != null) { - if (f.curvalue == 0) - flags &= ~bit; - else - flags |= bit; - } - - Cvar.SetValue("dmflags", flags); - - dmoptions_statusbar= "dmflags = " + flags; - - } - - //static String yes_no_names[] = { "no", "yes", 0 }; - static String teamplay_names[]= { "disabled", "by skin", "by model", null }; - - static void DMOptions_MenuInit() { - - int dmflags= (int) Cvar.VariableValue("dmflags"); - int y= 0; - - s_dmoptions_menu.x= (int) (viddef.width * 0.50); - s_dmoptions_menu.nitems= 0; - - s_falls_box.type= MTYPE_SPINCONTROL; - s_falls_box.x= 0; - s_falls_box.y= y; - s_falls_box.name= "falling damage"; - s_falls_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_falls_box.itemnames= yes_no_names; - s_falls_box.curvalue= (dmflags & DF_NO_FALLING) == 0 ? 1 : 0; - - s_weapons_stay_box.type= MTYPE_SPINCONTROL; - s_weapons_stay_box.x= 0; - s_weapons_stay_box.y= y += 10; - s_weapons_stay_box.name= "weapons stay"; - s_weapons_stay_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_weapons_stay_box.itemnames= yes_no_names; - s_weapons_stay_box.curvalue= (dmflags & DF_WEAPONS_STAY) != 0 ? 1 : 0; - - s_instant_powerups_box.type= MTYPE_SPINCONTROL; - s_instant_powerups_box.x= 0; - s_instant_powerups_box.y= y += 10; - s_instant_powerups_box.name= "instant powerups"; - s_instant_powerups_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_instant_powerups_box.itemnames= yes_no_names; - s_instant_powerups_box.curvalue= (dmflags & DF_INSTANT_ITEMS) != 0 ? 1 : 0; - - s_powerups_box.type= MTYPE_SPINCONTROL; - s_powerups_box.x= 0; - s_powerups_box.y= y += 10; - s_powerups_box.name= "allow powerups"; - s_powerups_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_powerups_box.itemnames= yes_no_names; - s_powerups_box.curvalue= (dmflags & DF_NO_ITEMS) == 0 ? 1 : 0; - - s_health_box.type= MTYPE_SPINCONTROL; - s_health_box.x= 0; - s_health_box.y= y += 10; - s_health_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_health_box.name= "allow health"; - s_health_box.itemnames= yes_no_names; - s_health_box.curvalue= (dmflags & DF_NO_HEALTH) == 0 ? 1 : 0; - - s_armor_box.type= MTYPE_SPINCONTROL; - s_armor_box.x= 0; - s_armor_box.y= y += 10; - s_armor_box.name= "allow armor"; - s_armor_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_armor_box.itemnames= yes_no_names; - s_armor_box.curvalue= (dmflags & DF_NO_ARMOR) == 0 ? 1 : 0; - - s_spawn_farthest_box.type= MTYPE_SPINCONTROL; - s_spawn_farthest_box.x= 0; - s_spawn_farthest_box.y= y += 10; - s_spawn_farthest_box.name= "spawn farthest"; - s_spawn_farthest_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_spawn_farthest_box.itemnames= yes_no_names; - s_spawn_farthest_box.curvalue= (dmflags & DF_SPAWN_FARTHEST) != 0 ? 1 : 0; - - s_samelevel_box.type= MTYPE_SPINCONTROL; - s_samelevel_box.x= 0; - s_samelevel_box.y= y += 10; - s_samelevel_box.name= "same map"; - s_samelevel_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_samelevel_box.itemnames= yes_no_names; - s_samelevel_box.curvalue= (dmflags & DF_SAME_LEVEL) != 0 ? 1 : 0; - - s_force_respawn_box.type= MTYPE_SPINCONTROL; - s_force_respawn_box.x= 0; - s_force_respawn_box.y= y += 10; - s_force_respawn_box.name= "force respawn"; - s_force_respawn_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_force_respawn_box.itemnames= yes_no_names; - s_force_respawn_box.curvalue= (dmflags & DF_FORCE_RESPAWN) != 0 ? 1 : 0; - - s_teamplay_box.type= MTYPE_SPINCONTROL; - s_teamplay_box.x= 0; - s_teamplay_box.y= y += 10; - s_teamplay_box.name= "teamplay"; - s_teamplay_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_teamplay_box.itemnames= teamplay_names; - - s_allow_exit_box.type= MTYPE_SPINCONTROL; - s_allow_exit_box.x= 0; - s_allow_exit_box.y= y += 10; - s_allow_exit_box.name= "allow exit"; - s_allow_exit_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_allow_exit_box.itemnames= yes_no_names; - s_allow_exit_box.curvalue= (dmflags & DF_ALLOW_EXIT) != 0 ? 1 : 0; - - s_infinite_ammo_box.type= MTYPE_SPINCONTROL; - s_infinite_ammo_box.x= 0; - s_infinite_ammo_box.y= y += 10; - s_infinite_ammo_box.name= "infinite ammo"; - s_infinite_ammo_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_infinite_ammo_box.itemnames= yes_no_names; - s_infinite_ammo_box.curvalue= (dmflags & DF_INFINITE_AMMO) != 0 ? 1 : 0; - - s_fixed_fov_box.type= MTYPE_SPINCONTROL; - s_fixed_fov_box.x= 0; - s_fixed_fov_box.y= y += 10; - s_fixed_fov_box.name= "fixed FOV"; - s_fixed_fov_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_fixed_fov_box.itemnames= yes_no_names; - s_fixed_fov_box.curvalue= (dmflags & DF_FIXED_FOV) != 0 ? 1 : 0; - - s_quad_drop_box.type= MTYPE_SPINCONTROL; - s_quad_drop_box.x= 0; - s_quad_drop_box.y= y += 10; - s_quad_drop_box.name= "quad drop"; - s_quad_drop_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_quad_drop_box.itemnames= yes_no_names; - s_quad_drop_box.curvalue= (dmflags & DF_QUAD_DROP) != 0 ? 1 : 0; - - s_friendlyfire_box.type= MTYPE_SPINCONTROL; - s_friendlyfire_box.x= 0; - s_friendlyfire_box.y= y += 10; - s_friendlyfire_box.name= "friendly fire"; - s_friendlyfire_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_friendlyfire_box.itemnames= yes_no_names; - s_friendlyfire_box.curvalue= (dmflags & DF_NO_FRIENDLY_FIRE) == 0 ? 1 : 0; - - // ============ - // ROGUE - if (FS.Developer_searchpath(2) == 2) { - s_no_mines_box.type= MTYPE_SPINCONTROL; - s_no_mines_box.x= 0; - s_no_mines_box.y= y += 10; - s_no_mines_box.name= "remove mines"; - s_no_mines_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_no_mines_box.itemnames= yes_no_names; - s_no_mines_box.curvalue= (dmflags & DF_NO_MINES) != 0 ? 1 : 0; - - s_no_nukes_box.type= MTYPE_SPINCONTROL; - s_no_nukes_box.x= 0; - s_no_nukes_box.y= y += 10; - s_no_nukes_box.name= "remove nukes"; - s_no_nukes_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_no_nukes_box.itemnames= yes_no_names; - s_no_nukes_box.curvalue= (dmflags & DF_NO_NUKES) != 0 ? 1 : 0; - - s_stack_double_box.type= MTYPE_SPINCONTROL; - s_stack_double_box.x= 0; - s_stack_double_box.y= y += 10; - s_stack_double_box.name= "2x/4x stacking off"; - s_stack_double_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_stack_double_box.itemnames= yes_no_names; - s_stack_double_box.curvalue= (dmflags & DF_NO_STACK_DOUBLE); - - s_no_spheres_box.type= MTYPE_SPINCONTROL; - s_no_spheres_box.x= 0; - s_no_spheres_box.y= y += 10; - s_no_spheres_box.name= "remove spheres"; - s_no_spheres_box.callback= new mcallback() { - public void execute(Object o) { - DMFlagCallback(o); - } - }; - s_no_spheres_box.itemnames= yes_no_names; - s_no_spheres_box.curvalue= (dmflags & DF_NO_SPHERES) != 0 ? 1 : 0; - - } - // ROGUE - // ============ - - Menu_AddItem(s_dmoptions_menu, s_falls_box); - Menu_AddItem(s_dmoptions_menu, s_weapons_stay_box); - Menu_AddItem(s_dmoptions_menu, s_instant_powerups_box); - Menu_AddItem(s_dmoptions_menu, s_powerups_box); - Menu_AddItem(s_dmoptions_menu, s_health_box); - Menu_AddItem(s_dmoptions_menu, s_armor_box); - Menu_AddItem(s_dmoptions_menu, s_spawn_farthest_box); - Menu_AddItem(s_dmoptions_menu, s_samelevel_box); - Menu_AddItem(s_dmoptions_menu, s_force_respawn_box); - Menu_AddItem(s_dmoptions_menu, s_teamplay_box); - Menu_AddItem(s_dmoptions_menu, s_allow_exit_box); - Menu_AddItem(s_dmoptions_menu, s_infinite_ammo_box); - Menu_AddItem(s_dmoptions_menu, s_fixed_fov_box); - Menu_AddItem(s_dmoptions_menu, s_quad_drop_box); - Menu_AddItem(s_dmoptions_menu, s_friendlyfire_box); - - // ======= - // ROGUE - if (FS.Developer_searchpath(2) == 2) { - Menu_AddItem(s_dmoptions_menu, s_no_mines_box); - Menu_AddItem(s_dmoptions_menu, s_no_nukes_box); - Menu_AddItem(s_dmoptions_menu, s_stack_double_box); - Menu_AddItem(s_dmoptions_menu, s_no_spheres_box); - } - // ROGUE - // ======= - - Menu_Center(s_dmoptions_menu); - - // set the original dmflags statusbar - DMFlagCallback(null); - Menu_SetStatusBar(s_dmoptions_menu, dmoptions_statusbar); - } - - static void DMOptions_MenuDraw() { - Menu_Draw(s_dmoptions_menu); - } - - static String DMOptions_MenuKey(int key) { - return Default_MenuKey(s_dmoptions_menu, key); - } - - static xcommand_t Menu_DMOptions= new xcommand_t() { - public void execute() { - Menu_DMOptions_f(); - } - }; - static void Menu_DMOptions_f() { - DMOptions_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - DMOptions_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return DMOptions_MenuKey(key); - } - }); - } - - /* - ============================================================================= - - DOWNLOADOPTIONS BOOK MENU - - ============================================================================= - */ - static menuframework_s s_downloadoptions_menu= new menuframework_s(); - - static menuseparator_s s_download_title= new menuseparator_s(); - static menulist_s s_allow_download_box= new menulist_s(); - static menulist_s s_allow_download_maps_box= new menulist_s(); - static menulist_s s_allow_download_models_box= new menulist_s(); - static menulist_s s_allow_download_players_box= new menulist_s(); - static menulist_s s_allow_download_sounds_box= new menulist_s(); - - static void DownloadCallback(Object self) { - menulist_s f= (menulist_s) self; - - if (f == s_allow_download_box) { - Cvar.SetValue("allow_download", f.curvalue); - } - - else if (f == s_allow_download_maps_box) { - Cvar.SetValue("allow_download_maps", f.curvalue); - } - - else if (f == s_allow_download_models_box) { - Cvar.SetValue("allow_download_models", f.curvalue); - } - - else if (f == s_allow_download_players_box) { - Cvar.SetValue("allow_download_players", f.curvalue); - } - - else if (f == s_allow_download_sounds_box) { - Cvar.SetValue("allow_download_sounds", f.curvalue); - } - } - - static String yes_no_names[]= { "no", "yes", null }; - static void DownloadOptions_MenuInit() { - - int y= 0; - - s_downloadoptions_menu.x= (int) (viddef.width * 0.50); - s_downloadoptions_menu.nitems= 0; - - s_download_title.type= MTYPE_SEPARATOR; - s_download_title.name= "Download Options"; - s_download_title.x= 48; - s_download_title.y= y; - - s_allow_download_box.type= MTYPE_SPINCONTROL; - s_allow_download_box.x= 0; - s_allow_download_box.y= y += 20; - s_allow_download_box.name= "allow downloading"; - s_allow_download_box.callback= new mcallback() { - public void execute(Object o) { - DownloadCallback(o); - } - }; - s_allow_download_box.itemnames= yes_no_names; - s_allow_download_box.curvalue= (Cvar.VariableValue("allow_download") != 0) ? 1 : 0; - - s_allow_download_maps_box.type= MTYPE_SPINCONTROL; - s_allow_download_maps_box.x= 0; - s_allow_download_maps_box.y= y += 20; - s_allow_download_maps_box.name= "maps"; - s_allow_download_maps_box.callback= new mcallback() { - public void execute(Object o) { - DownloadCallback(o); - } - }; - s_allow_download_maps_box.itemnames= yes_no_names; - s_allow_download_maps_box.curvalue= (Cvar.VariableValue("allow_download_maps") != 0) ? 1 : 0; - - s_allow_download_players_box.type= MTYPE_SPINCONTROL; - s_allow_download_players_box.x= 0; - s_allow_download_players_box.y= y += 10; - s_allow_download_players_box.name= "player models/skins"; - s_allow_download_players_box.callback= new mcallback() { - public void execute(Object o) { - DownloadCallback(o); - } - }; - s_allow_download_players_box.itemnames= yes_no_names; - s_allow_download_players_box.curvalue= (Cvar.VariableValue("allow_download_players") != 0) ? 1 : 0; - - s_allow_download_models_box.type= MTYPE_SPINCONTROL; - s_allow_download_models_box.x= 0; - s_allow_download_models_box.y= y += 10; - s_allow_download_models_box.name= "models"; - s_allow_download_models_box.callback= new mcallback() { - public void execute(Object o) { - DownloadCallback(o); - } - }; - s_allow_download_models_box.itemnames= yes_no_names; - s_allow_download_models_box.curvalue= (Cvar.VariableValue("allow_download_models") != 0) ? 1 : 0; - - s_allow_download_sounds_box.type= MTYPE_SPINCONTROL; - s_allow_download_sounds_box.x= 0; - s_allow_download_sounds_box.y= y += 10; - s_allow_download_sounds_box.name= "sounds"; - s_allow_download_sounds_box.callback= new mcallback() { - public void execute(Object o) { - DownloadCallback(o); - } - }; - s_allow_download_sounds_box.itemnames= yes_no_names; - s_allow_download_sounds_box.curvalue= (Cvar.VariableValue("allow_download_sounds") != 0) ? 1 : 0; - - Menu_AddItem(s_downloadoptions_menu, s_download_title); - Menu_AddItem(s_downloadoptions_menu, s_allow_download_box); - Menu_AddItem(s_downloadoptions_menu, s_allow_download_maps_box); - Menu_AddItem(s_downloadoptions_menu, s_allow_download_players_box); - Menu_AddItem(s_downloadoptions_menu, s_allow_download_models_box); - Menu_AddItem(s_downloadoptions_menu, s_allow_download_sounds_box); - - Menu_Center(s_downloadoptions_menu); - - // skip over title - if (s_downloadoptions_menu.cursor == 0) - s_downloadoptions_menu.cursor= 1; - } - - static void DownloadOptions_MenuDraw() { - Menu_Draw(s_downloadoptions_menu); - } - - static String DownloadOptions_MenuKey(int key) { - return Default_MenuKey(s_downloadoptions_menu, key); - } - - static xcommand_t Menu_DownloadOptions= new xcommand_t() { - public void execute() { - Menu_DownloadOptions_f(); - } - }; - static void Menu_DownloadOptions_f() { - DownloadOptions_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - DownloadOptions_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return DownloadOptions_MenuKey(key); - } - }); - } - /* - ============================================================================= - - ADDRESS BOOK MENU - - ============================================================================= - */ - - static menuframework_s s_addressbook_menu= new menuframework_s(); - static menufield_s s_addressbook_fields[]= new menufield_s[NUM_ADDRESSBOOK_ENTRIES]; - static { - for (int n= 0; n < NUM_ADDRESSBOOK_ENTRIES; n++) - s_addressbook_fields[n]= new menufield_s(); - } - - static void AddressBook_MenuInit() { - int i; - - s_addressbook_menu.x= viddef.width / 2 - 142; - s_addressbook_menu.y= viddef.height / 2 - 58; - s_addressbook_menu.nitems= 0; - - for (i= 0; i < NUM_ADDRESSBOOK_ENTRIES; i++) { - cvar_t adr; - //char buffer[20]; - String buffer; - - //Com_sprintf(buffer, sizeof(buffer), "adr%d", i); - buffer= "adr" + i; - - adr= Cvar.Get(buffer, "", CVAR_ARCHIVE); - - s_addressbook_fields[i].type= MTYPE_FIELD; - s_addressbook_fields[i].name= null; - s_addressbook_fields[i].callback= null; - s_addressbook_fields[i].x= 0; - s_addressbook_fields[i].y= i * 18 + 0; - s_addressbook_fields[i].localdata[0]= i; - s_addressbook_fields[i].cursor= 0; - s_addressbook_fields[i].length= 60; - s_addressbook_fields[i].visible_length= 30; - - s_addressbook_fields[i].buffer= new StringBuffer(adr.string); - - Menu_AddItem(s_addressbook_menu, s_addressbook_fields[i]); - } - } - - static keyfunc_t AddressBook_MenuKey= new keyfunc_t() { - public String execute(int key) { - return AddressBook_MenuKey_f(key); - } - }; - - static String AddressBook_MenuKey_f(int key) { - if (key == K_ESCAPE) { - int index; - //char buffer[20]; - String buffer; - - for (index= 0; index < NUM_ADDRESSBOOK_ENTRIES; index++) { - buffer= "adr" + index; - //Com_sprintf(buffer, sizeof(buffer), "adr%d", index); - Cvar.Set(buffer, s_addressbook_fields[index].buffer.toString()); - } - } - return Default_MenuKey(s_addressbook_menu, key); - } - - static xcommand_t AddressBook_MenuDraw= new xcommand_t() { - public void execute() { - AddressBook_MenuDraw_f(); - } - }; - static void AddressBook_MenuDraw_f() { - Banner("m_banner_addressbook"); - Menu_Draw(s_addressbook_menu); - } - - static xcommand_t Menu_AddressBook= new xcommand_t() { - public void execute() { - Menu_AddressBook_f(); - } - }; - static void Menu_AddressBook_f() { - AddressBook_MenuInit(); - PushMenu(new xcommand_t() { - public void execute() { - AddressBook_MenuDraw_f(); - } - }, new keyfunc_t() { - public String execute(int key) { - return AddressBook_MenuKey_f(key); - } - }); - } - /* - ============================================================================= - - PLAYER CONFIG MENU - - ============================================================================= - */ - static menuframework_s s_player_config_menu= new menuframework_s(); - static menufield_s s_player_name_field= new menufield_s(); - static menulist_s s_player_model_box= new menulist_s(); - static menulist_s s_player_skin_box= new menulist_s(); - static menulist_s s_player_handedness_box= new menulist_s(); - static menulist_s s_player_rate_box= new menulist_s(); - static menuseparator_s s_player_skin_title= new menuseparator_s(); - static menuseparator_s s_player_model_title= new menuseparator_s(); - static menuseparator_s s_player_hand_title= new menuseparator_s(); - static menuseparator_s s_player_rate_title= new menuseparator_s(); - static menuaction_s s_player_download_action= new menuaction_s(); - - static class playermodelinfo_s { - int nskins; - String skindisplaynames[]; - //char displayname[MAX_DISPLAYNAME]; - String displayname; - //char directory[MAX_QPATH]; - String directory; - }; - - static playermodelinfo_s s_pmi[]= new playermodelinfo_s[MAX_PLAYERMODELS]; - static String s_pmnames[]= new String[MAX_PLAYERMODELS]; - static int s_numplayermodels; - - static int rate_tbl[]= { 2500, 3200, 5000, 10000, 25000, 0 }; - static String rate_names[]= { "28.8 Modem", "33.6 Modem", "Single ISDN", "Dual ISDN/Cable", "T1/LAN", "User defined", null }; - - static void DownloadOptionsFunc(Object self) { - Menu_DownloadOptions_f(); - } - - static void HandednessCallback(Object unused) { - Cvar.SetValue("hand", s_player_handedness_box.curvalue); - } - - static void RateCallback(Object unused) { - if (s_player_rate_box.curvalue != rate_tbl.length - 1) //sizeof(rate_tbl) / sizeof(* rate_tbl) - 1) - Cvar.SetValue("rate", rate_tbl[s_player_rate_box.curvalue]); - } - - static void ModelCallback(Object unused) { - s_player_skin_box.itemnames= s_pmi[s_player_model_box.curvalue].skindisplaynames; - s_player_skin_box.curvalue= 0; - } - - static boolean IconOfSkinExists(String skin, String pcxfiles[], int npcxfiles) { - int i; - //char scratch[1024]; - String scratch; - - //strcpy(scratch, skin); - scratch= skin; - int pos= scratch.lastIndexOf('.'); - if (pos != -1) - scratch= scratch.substring(0, pos) + "_i.pcx"; - - else - scratch += "_i.pcx"; - - for (i= 0; i < npcxfiles; i++) { - if (strcmp(pcxfiles[i], scratch) == 0) - return true; - } - - return false; - } - - static boolean PlayerConfig_ScanDirectories() { - //char findname[1024]; - String findname; - //char scratch[1024]; - String scratch; - - int ndirs= 0, npms= 0; - int a, b, c; - String dirnames[]; - - String path= null; - - int i; - - //extern String * FS_ListFiles(String , int *, unsigned, unsigned); - - s_numplayermodels= 0; - - /* - ** get a list of directories - */ - do { - path= FS.NextPath(path); - findname= path + "/players/*.*"; - - if ((dirnames= FS.ListFiles(findname, 0, SFF_SUBDIR)) != null) { - ndirs= dirnames.length; - break; - } - } - while (path != null); - - if (dirnames == null) - return false; - - /* - ** go through the subdirectories - */ - npms= ndirs; - if (npms > MAX_PLAYERMODELS) - npms= MAX_PLAYERMODELS; - - for (i= 0; i < npms; i++) { - int k, s; - //String a, b, c; - String pcxnames[]; - String skinnames[]; - int npcxfiles; - int nskins= 0; - - if (dirnames[i] == null) - continue; - - // verify the existence of tris.md2 - scratch= dirnames[i]; - scratch += "/tris.md2"; - if (Sys.FindFirst(scratch, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) == null) { - //free(dirnames[i]); - dirnames[i]= null; - Sys.FindClose(); - continue; - } - Sys.FindClose(); - - // verify the existence of at least one pcx skin - scratch= dirnames[i] + "/*.pcx"; - pcxnames= FS.ListFiles(scratch, 0, 0); - npcxfiles= pcxnames.length; - - if (pcxnames == null) { - - dirnames[i]= null; - continue; - } - - // count valid skins, which consist of a skin with a matching "_i" icon - for (k= 0; k < npcxfiles - 1; k++) { - if (!pcxnames[k].endsWith("_i.pcx")) { - //if (!strstr(pcxnames[k], "_i.pcx")) { - if (IconOfSkinExists(pcxnames[k], pcxnames, npcxfiles - 1)) { - nskins++; - } - } - } - if (nskins == 0) - continue; - - skinnames= new String[nskins + 1]; //malloc(sizeof(String) * (nskins + 1)); - //memset(skinnames, 0, sizeof(String) * (nskins + 1)); - - // copy the valid skins - for (s= 0, k= 0; k < npcxfiles - 1; k++) { - - if (pcxnames[k].indexOf("_i.pcx") < 0) { - if (IconOfSkinExists(pcxnames[k], pcxnames, npcxfiles - 1)) { - a= pcxnames[k].lastIndexOf('/'); - b= pcxnames[k].lastIndexOf('\\'); - - if (a > b) - c= a; - else - c= b; - - scratch= pcxnames[k].substring(c + 1, pcxnames[k].length()); - int pos= scratch.lastIndexOf('.'); - if (pos != -1) - scratch= scratch.substring(0, pos); - - skinnames[s]= scratch; - s++; - } - } - } - - // at this point we have a valid player model - if (s_pmi[s_numplayermodels] == null) - s_pmi[s_numplayermodels]= new playermodelinfo_s(); - - s_pmi[s_numplayermodels].nskins= nskins; - s_pmi[s_numplayermodels].skindisplaynames= skinnames; - - // make short name for the model - a= dirnames[i].lastIndexOf('/'); - b= dirnames[i].lastIndexOf('\\'); - - if (a > b) - c= a; - else - c= b; - - s_pmi[s_numplayermodels].displayname= dirnames[i].substring(c + 1); - s_pmi[s_numplayermodels].directory= dirnames[i].substring(c + 1); - - s_numplayermodels++; - } - - return true; - - } - - static int pmicmpfnc(Object _a, Object _b) { - playermodelinfo_s a= (playermodelinfo_s) _a; - playermodelinfo_s b= (playermodelinfo_s) _b; - - /* - ** sort by male, female, then alphabetical - */ - if (strcmp(a.directory, "male") == 0) - return -1; - else if (strcmp(b.directory, "male") == 0) - return 1; - - if (strcmp(a.directory, "female") == 0) - return -1; - else if (strcmp(b.directory, "female") == 0) - return 1; - - return strcmp(a.directory, b.directory); - } - - static String handedness[]= { "right", "left", "center", null }; - - static boolean PlayerConfig_MenuInit() { - /* - extern cvar_t * name; - extern cvar_t * team; - extern cvar_t * skin; - */ - //har currentdirectory[1024]; - String currentdirectory; - //char currentskin[1024]; - String currentskin; - - int i= 0; - - int currentdirectoryindex= 0; - int currentskinindex= 0; - - cvar_t hand= Cvar.Get("hand", "0", CVAR_USERINFO | CVAR_ARCHIVE); - - PlayerConfig_ScanDirectories(); - - if (s_numplayermodels == 0) - return false; - - if (hand.value < 0 || hand.value > 2) - Cvar.SetValue("hand", 0); - - currentdirectory= skin.string; - - if (currentdirectory.lastIndexOf('/') != -1) { - currentskin= rightFrom(currentdirectory, '/'); - currentdirectory= leftFrom(currentdirectory, '/'); - } - else if (currentdirectory.lastIndexOf('\\') != -1) { - currentskin= rightFrom(currentdirectory, '\\'); - currentdirectory= leftFrom(currentdirectory, '\\'); - } - else { - currentdirectory= "male"; - currentskin= "grunt"; - } - - //qsort(s_pmi, s_numplayermodels, sizeof(s_pmi[0]), pmicmpfnc); - Arrays.sort(s_pmi, 0, s_numplayermodels, new Comparator() { - public int compare(Object o1, Object o2) { - return pmicmpfnc(o1, o2); - } - }); - - //memset(s_pmnames, 0, sizeof(s_pmnames)); - s_pmnames= new String[MAX_PLAYERMODELS]; - - for (i= 0; i < s_numplayermodels; i++) { - s_pmnames[i]= s_pmi[i].displayname; - if (Q_stricmp(s_pmi[i].directory, currentdirectory) == 0) { - int j; - - currentdirectoryindex= i; - - for (j= 0; j < s_pmi[i].nskins; j++) { - if (Q_stricmp(s_pmi[i].skindisplaynames[j], currentskin) == 0) { - currentskinindex= j; - break; - } - } - } - } - - s_player_config_menu.x= viddef.width / 2 - 95; - s_player_config_menu.y= viddef.height / 2 - 97; - s_player_config_menu.nitems= 0; - - s_player_name_field.type= MTYPE_FIELD; - s_player_name_field.name= "name"; - s_player_name_field.callback= null; - s_player_name_field.x= 0; - s_player_name_field.y= 0; - s_player_name_field.length= 20; - s_player_name_field.visible_length= 20; - s_player_name_field.buffer= new StringBuffer(name.string); - s_player_name_field.cursor= name.string.length(); - - s_player_model_title.type= MTYPE_SEPARATOR; - s_player_model_title.name= "model"; - s_player_model_title.x= -8; - s_player_model_title.y= 60; - - s_player_model_box.type= MTYPE_SPINCONTROL; - s_player_model_box.x= -56; - s_player_model_box.y= 70; - s_player_model_box.callback= new mcallback() { - public void execute(Object o) { - ModelCallback(o); - } - }; - s_player_model_box.cursor_offset= -48; - s_player_model_box.curvalue= currentdirectoryindex; - s_player_model_box.itemnames= s_pmnames; - - s_player_skin_title.type= MTYPE_SEPARATOR; - s_player_skin_title.name= "skin"; - s_player_skin_title.x= -16; - s_player_skin_title.y= 84; - - s_player_skin_box.type= MTYPE_SPINCONTROL; - s_player_skin_box.x= -56; - s_player_skin_box.y= 94; - s_player_skin_box.name= null; - s_player_skin_box.callback= null; - s_player_skin_box.cursor_offset= -48; - s_player_skin_box.curvalue= currentskinindex; - s_player_skin_box.itemnames= s_pmi[currentdirectoryindex].skindisplaynames; - - s_player_hand_title.type= MTYPE_SEPARATOR; - s_player_hand_title.name= "handedness"; - s_player_hand_title.x= 32; - s_player_hand_title.y= 108; - - s_player_handedness_box.type= MTYPE_SPINCONTROL; - s_player_handedness_box.x= -56; - s_player_handedness_box.y= 118; - s_player_handedness_box.name= null; - s_player_handedness_box.cursor_offset= -48; - s_player_handedness_box.callback= new mcallback() { - public void execute(Object o) { - HandednessCallback(o); - } - }; - s_player_handedness_box.curvalue= (int) Cvar.VariableValue("hand"); - s_player_handedness_box.itemnames= handedness; - - for (i= 0; i < rate_tbl.length - 1; i++) - if (Cvar.VariableValue("rate") == rate_tbl[i]) - break; - - s_player_rate_title.type= MTYPE_SEPARATOR; - s_player_rate_title.name= "connect speed"; - s_player_rate_title.x= 56; - s_player_rate_title.y= 156; - - s_player_rate_box.type= MTYPE_SPINCONTROL; - s_player_rate_box.x= -56; - s_player_rate_box.y= 166; - s_player_rate_box.name= null; - s_player_rate_box.cursor_offset= -48; - s_player_rate_box.callback= new mcallback() { - public void execute(Object o) { - RateCallback(o); - } - }; - s_player_rate_box.curvalue= i; - s_player_rate_box.itemnames= rate_names; - - s_player_download_action.type= MTYPE_ACTION; - s_player_download_action.name= "download options"; - s_player_download_action.flags= QMF_LEFT_JUSTIFY; - s_player_download_action.x= -24; - s_player_download_action.y= 186; - s_player_download_action.statusbar= null; - s_player_download_action.callback= new mcallback() { - public void execute(Object o) { - DownloadOptionsFunc(o); - } - }; - - Menu_AddItem(s_player_config_menu, s_player_name_field); - Menu_AddItem(s_player_config_menu, s_player_model_title); - Menu_AddItem(s_player_config_menu, s_player_model_box); - if (s_player_skin_box.itemnames != null) { - Menu_AddItem(s_player_config_menu, s_player_skin_title); - Menu_AddItem(s_player_config_menu, s_player_skin_box); - } - Menu_AddItem(s_player_config_menu, s_player_hand_title); - Menu_AddItem(s_player_config_menu, s_player_handedness_box); - Menu_AddItem(s_player_config_menu, s_player_rate_title); - Menu_AddItem(s_player_config_menu, s_player_rate_box); - Menu_AddItem(s_player_config_menu, s_player_download_action); - - return true; - } - - static int yaw; - - static void PlayerConfig_MenuDraw() { - - refdef_t refdef= new refdef_t(); - //char scratch[MAX_QPATH]; - String scratch; - - //memset(refdef, 0, sizeof(refdef)); - - refdef.x= viddef.width / 2; - refdef.y= viddef.height / 2 - 72; - refdef.width= 144; - refdef.height= 168; - refdef.fov_x= 40; - refdef.fov_y= Math3D.CalcFov(refdef.fov_x, refdef.width, refdef.height); - refdef.time= cls.realtime * 0.001f; - - if (s_pmi[s_player_model_box.curvalue].skindisplaynames != null) { - - int maxframe= 29; - entity_t entity= new entity_t(); - - //memset(entity, 0, sizeof(entity)); - - scratch= "players/" + s_pmi[s_player_model_box.curvalue].directory + "/tris.md2"; - - entity.model= re.RegisterModel(scratch); - - scratch= - "players/" - + s_pmi[s_player_model_box.curvalue].directory - + "/" - + s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] - + ".pcx"; - - entity.skin= re.RegisterSkin(scratch); - entity.flags= RF_FULLBRIGHT; - entity.origin[0]= 80; - entity.origin[1]= 0; - entity.origin[2]= 0; - VectorCopy(entity.origin, entity.oldorigin); - entity.frame= 0; - entity.oldframe= 0; - entity.backlerp= 0.0f; - entity.angles[1]= yaw++; - if (++yaw > 360) - yaw -= 360; - - refdef.areabits= null; - refdef.num_entities= 1; - refdef.entities= new entity_t[] { entity }; - refdef.lightstyles= null; - refdef.rdflags= RDF_NOWORLDMODEL; - - Menu_Draw(s_player_config_menu); - - 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); - - scratch= - "/players/" - + s_pmi[s_player_model_box.curvalue].directory - + "/" - + s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] - + "_i.pcx"; - - re.DrawPic(s_player_config_menu.x - 40, refdef.y, scratch); - } - } - - static String PlayerConfig_MenuKey(int key) { - int i; - - if (key == K_ESCAPE) { - //char scratch[1024]; - String scratch; - - Cvar.Set("name", s_player_name_field.buffer.toString()); - - scratch= - s_pmi[s_player_model_box.curvalue].directory - + "/" - + s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue]; - - Cvar.Set("skin", scratch); - - for (i= 0; i < s_numplayermodels; i++) { - int j; - - for (j= 0; j < s_pmi[i].nskins; j++) { - if (s_pmi[i].skindisplaynames[j] != null) - s_pmi[i].skindisplaynames[j]= null; - } - s_pmi[i].skindisplaynames= null; - s_pmi[i].nskins= 0; - } - } - return Default_MenuKey(s_player_config_menu, key); - } - - static xcommand_t Menu_PlayerConfig= new xcommand_t() { - public void execute() { - Menu_PlayerConfig_f(); - } - }; - static void Menu_PlayerConfig_f() { - if (!PlayerConfig_MenuInit()) { - Menu_SetStatusBar(s_multiplayer_menu, "No valid player models found"); - return; - } - Menu_SetStatusBar(s_multiplayer_menu, null); - PushMenu(new xcommand_t() { - public void execute() { - PlayerConfig_MenuDraw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return PlayerConfig_MenuKey(key); - } - }); - } - - /* - ======================================================================= - - QUIT MENU - - ======================================================================= - */ - - static String Quit_Key(int key) { - switch (key) { - case K_ESCAPE : - case 'n' : - case 'N' : - PopMenu(); - break; - - case 'Y' : - case 'y' : - cls.key_dest= key_console; - CL.Quit_f.execute(); - break; - - default : - break; - } - - return null; - - } - - static void Quit_Draw() { - int w, h; - Dimension d= new Dimension(); - re.DrawGetPicSize(d, "quit"); - w= d.width; - h= d.height; - re.DrawPic((viddef.width - w) / 2, (viddef.height - h) / 2, "quit"); - } - - static xcommand_t Menu_Quit= new xcommand_t() { - public void execute() { - Menu_Quit_f(); - } - }; - - static void Menu_Quit_f() { - PushMenu(new xcommand_t() { - public void execute() { - Quit_Draw(); - } - }, new keyfunc_t() { - public String execute(int key) { - return Quit_Key(key); - } - }); - } - - // ============================================================================= - /* Menu Subsystem */ - - /** - * Init - */ - public static void Init() { - Cmd.AddCommand("menu_main", Menu_Main); - Cmd.AddCommand("menu_game", Menu_Game); - Cmd.AddCommand("menu_loadgame", Menu_LoadGame); - Cmd.AddCommand("menu_savegame", Menu_SaveGame); - Cmd.AddCommand("menu_joinserver", Menu_JoinServer); - Cmd.AddCommand("menu_addressbook", Menu_AddressBook); - Cmd.AddCommand("menu_startserver", Menu_StartServer); - Cmd.AddCommand("menu_dmoptions", Menu_DMOptions); - Cmd.AddCommand("menu_playerconfig", Menu_PlayerConfig); - Cmd.AddCommand("menu_downloadoptions", Menu_DownloadOptions); - Cmd.AddCommand("menu_credits", Menu_Credits); - Cmd.AddCommand("menu_multiplayer", Menu_Multiplayer); - Cmd.AddCommand("menu_video", Menu_Video); - Cmd.AddCommand("menu_options", Menu_Options); - Cmd.AddCommand("menu_keys", Menu_Keys); - Cmd.AddCommand("menu_quit", Menu_Quit); - - for (int i= 0; i < m_layers.length; i++) { - m_layers[i]= new menulayer_t(); - } - } - - /* - ================= - Draw - ================= - */ - static void Draw() { - if (cls.key_dest != key_menu) - return; - - // repaint everything next frame - SCR.DirtyScreen(); - - // dim everything behind it down - if (cl.cinematictime > 0) - re.DrawFill(0, 0, viddef.width, viddef.height, 0); - else - re.DrawFadeScreen(); - - m_drawfunc.execute(); - - // delay playing the enter sound until after the - // menu has been drawn, to avoid delay while - // caching images - if (m_entersound) { - S.StartLocalSound(menu_in_sound); - m_entersound= false; - } - } - - /* - ================= - Keydown - ================= - */ - static void Keydown(int key) { - String s; - - if (m_keyfunc != null) - if ((s= m_keyfunc.execute(key)) != null) - S.StartLocalSound(s); - } - - public static void Action_DoEnter(menuaction_s a) { - if (a.callback != null) - a.callback.execute(a); - } - - public static void Action_Draw(menuaction_s a) { - if ((a.flags & QMF_LEFT_JUSTIFY) != 0) { - if ((a.flags & QMF_GRAYED) != 0) - Menu_DrawStringDark(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + a.parent.y, a.name); - else - Menu_DrawString(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + a.parent.y, a.name); - } - else { - if ((a.flags & QMF_GRAYED) != 0) - Menu_DrawStringR2LDark(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + a.parent.y, a.name); - else - Menu_DrawStringR2L(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + a.parent.y, a.name); - } - if (a.ownerdraw != null) - a.ownerdraw.execute(a); - } - - public static boolean Field_DoEnter(menufield_s f) { - if (f.callback != null) { - f.callback.execute(f); - return true; - } - return false; - } - - public static void Field_Draw(menufield_s f) { - int i; - String tempbuffer; - //[128] = ""; - - if (f.name != null) - Menu_DrawStringR2LDark(f.x + f.parent.x + LCOLUMN_OFFSET, f.y + f.parent.y, f.name); - - //strncpy(tempbuffer, f.buffer + f.visible_offset, f.visible_length); - String s= f.buffer.toString(); - tempbuffer= s.substring(f.visible_offset, s.length()); - re.DrawChar(f.x + f.parent.x + 16, f.y + f.parent.y - 4, 18); - re.DrawChar(f.x + f.parent.x + 16, f.y + f.parent.y + 4, 24); - - re.DrawChar(f.x + f.parent.x + 24 + f.visible_length * 8, f.y + f.parent.y - 4, 20); - re.DrawChar(f.x + f.parent.x + 24 + f.visible_length * 8, f.y + f.parent.y + 4, 26); - - for (i= 0; i < f.visible_length; i++) { - re.DrawChar(f.x + f.parent.x + 24 + i * 8, f.y + f.parent.y - 4, 19); - re.DrawChar(f.x + f.parent.x + 24 + i * 8, f.y + f.parent.y + 4, 25); - } - - Menu_DrawString(f.x + f.parent.x + 24, f.y + f.parent.y, tempbuffer); - - if (Menu_ItemAtCursor(f.parent) == f) { - int offset; - - if (f.visible_offset != 0) - offset= f.visible_length; - else - offset= f.cursor; - - if ((((int) (Sys.Milliseconds() / 250)) & 1) != 0) { - re.DrawChar(f.x + f.parent.x + (offset + 2) * 8 + 8, f.y + f.parent.y, 11); - } - else { - re.DrawChar(f.x + f.parent.x + (offset + 2) * 8 + 8, f.y + f.parent.y, ' '); - } - } - } - - public static boolean Field_Key(menufield_s f, int k) { - char key= (char) k; - - switch (key) { - case K_KP_SLASH : - key= '/'; - break; - case K_KP_MINUS : - key= '-'; - break; - case K_KP_PLUS : - key= '+'; - break; - case K_KP_HOME : - key= '7'; - break; - case K_KP_UPARROW : - key= '8'; - break; - case K_KP_PGUP : - key= '9'; - break; - case K_KP_LEFTARROW : - key= '4'; - break; - case K_KP_5 : - key= '5'; - break; - case K_KP_RIGHTARROW : - key= '6'; - break; - case K_KP_END : - key= '1'; - break; - case K_KP_DOWNARROW : - key= '2'; - break; - case K_KP_PGDN : - key= '3'; - break; - case K_KP_INS : - key= '0'; - break; - case K_KP_DEL : - key= '.'; - break; - } - - if (key > 127) { - switch (key) { - case K_DEL : - default : - return false; - } - } - - /* - ** support pasting from the clipboard - */ - if ((Character.toUpperCase(key) == 'V' && keydown[K_CTRL]) || (((key == K_INS) || (key == K_KP_INS)) && keydown[K_SHIFT])) { - String cbd; - - if ((cbd= Sys.GetClipboardData()) != null) { - //strtok(cbd, "\n\r\b"); - String lines[]= Lib.linesplit(cbd); - if (lines.length > 0 && lines[0].length() != 0) { - //strncpy(f.buffer, cbd, f.length - 1); - f.buffer= new StringBuffer(lines[0]); - f.cursor= f.buffer.length(); - - f.visible_offset= f.cursor - f.visible_length; - - if (f.visible_offset < 0) - f.visible_offset= 0; - } - } - return true; - } - - switch (key) { - case K_KP_LEFTARROW : - case K_LEFTARROW : - case K_BACKSPACE : - if (f.cursor > 0) { - f.buffer.deleteCharAt(f.cursor - 1); - //memmove(f.buffer[f.cursor - 1], f.buffer[f.cursor], strlen(& f.buffer[f.cursor]) + 1); - f.cursor--; - - if (f.visible_offset != 0) { - f.visible_offset--; - } - } - break; - - case K_KP_DEL : - case K_DEL : - //memmove(& f.buffer[f.cursor], & f.buffer[f.cursor + 1], strlen(& f.buffer[f.cursor + 1]) + 1); - f.buffer.deleteCharAt(f.cursor); - break; - - case K_KP_ENTER : - case K_ENTER : - case K_ESCAPE : - case K_TAB : - return false; - - case K_SPACE : - default : - if (!Character.isDigit(key) && (f.flags & QMF_NUMBERSONLY) != 0) - return false; - - if (f.cursor < f.length) { - f.buffer.append(key); - f.cursor++; - - if (f.cursor > f.visible_length) { - f.visible_offset++; - } - } - } - - return true; - } - - public static void Menu_AddItem(menuframework_s menu, menucommon_s item) { - if (menu.nitems == 0) - menu.nslots= 0; - - if (menu.nitems < MAXMENUITEMS) { - menu.items[menu.nitems]= item; - ((menucommon_s) menu.items[menu.nitems]).parent= menu; - menu.nitems++; - } - - menu.nslots= Menu_TallySlots(menu); - } - - /* - ** Menu_AdjustCursor - ** - ** This function takes the given menu, the direction, and attempts - ** to adjust the menu's cursor so that it's at the next available - ** slot. - */ - public static void Menu_AdjustCursor(menuframework_s m, int dir) { - menucommon_s citem; - - /* - ** see if it's in a valid spot - */ - if (m.cursor >= 0 && m.cursor < m.nitems) { - if ((citem= Menu_ItemAtCursor(m)) != null) { - if (citem.type != MTYPE_SEPARATOR) - return; - } - } - - /* - ** it's not in a valid spot, so crawl in the direction indicated until we - ** find a valid spot - */ - if (dir == 1) { - while (true) { - citem= Menu_ItemAtCursor(m); - if (citem != null) - if (citem.type != MTYPE_SEPARATOR) - break; - m.cursor += dir; - if (m.cursor >= m.nitems) - m.cursor= 0; - } - } - else { - while (true) { - citem= Menu_ItemAtCursor(m); - if (citem != null) - if (citem.type != MTYPE_SEPARATOR) - break; - m.cursor += dir; - if (m.cursor < 0) - m.cursor= m.nitems - 1; - } - } - } - - public static void Menu_Center(menuframework_s menu) { - int height; - - height= ((menucommon_s) menu.items[menu.nitems - 1]).y; - height += 10; - - menu.y= (viddef.height - height) / 2; - } - - public static void Menu_Draw(menuframework_s menu) { - int i; - menucommon_s item; - - /* - ** draw contents - */ - for (i= 0; i < menu.nitems; i++) { - switch (((menucommon_s) menu.items[i]).type) { - case MTYPE_FIELD : - Field_Draw((menufield_s) menu.items[i]); - break; - case MTYPE_SLIDER : - Slider_Draw((menuslider_s) menu.items[i]); - break; - case MTYPE_LIST : - MenuList_Draw((menulist_s) menu.items[i]); - break; - case MTYPE_SPINCONTROL : - SpinControl_Draw((menulist_s) menu.items[i]); - break; - case MTYPE_ACTION : - Action_Draw((menuaction_s) menu.items[i]); - break; - case MTYPE_SEPARATOR : - Separator_Draw((menuseparator_s) menu.items[i]); - break; - } - } - - item= Menu_ItemAtCursor(menu); - - if (item != null && item.cursordraw != null) { - item.cursordraw.execute(item); - } - else if (menu.cursordraw != null) { - menu.cursordraw.execute(menu); - } - else if (item != null && item.type != MTYPE_FIELD) { - if ((item.flags & QMF_LEFT_JUSTIFY) != 0) { - re.DrawChar(menu.x + item.x - 24 + item.cursor_offset, menu.y + item.y, 12 + ((int) (Sys.Milliseconds() / 250) & 1)); - } - else { - re.DrawChar(menu.x + item.cursor_offset, menu.y + item.y, 12 + ((int) (Sys.Milliseconds() / 250) & 1)); - } - } - - if (item != null) { - if (item.statusbarfunc != null) - item.statusbarfunc.execute(item); - else if (item.statusbar != null) - Menu_DrawStatusBar(item.statusbar); - else - Menu_DrawStatusBar(menu.statusbar); - - } - else { - Menu_DrawStatusBar(menu.statusbar); - } - } - - public static void Menu_DrawStatusBar(String string) { - if (string != null) { - int l= string.length(); - int maxrow= viddef.height / 8; - int maxcol= viddef.width / 8; - int col= maxcol / 2 - l / 2; - - re.DrawFill(0, viddef.height - 8, viddef.width, 8, 4); - Menu_DrawString(col * 8, viddef.height - 8, string); - } - else { - re.DrawFill(0, viddef.height - 8, viddef.width, 8, 0); - } - } - - public static void Menu_DrawString(int x, int y, String string) { - int i; - - for (i= 0; i < string.length(); i++) { - re.DrawChar((x + i * 8), y, string.charAt(i)); - } - } - - public static void Menu_DrawStringDark(int x, int y, String string) { - int i; - - for (i= 0; i < string.length(); i++) { - re.DrawChar((x + i * 8), y, string.charAt(i) + 128); - } - } - - public static void Menu_DrawStringR2L(int x, int y, String string) { - int i; - - int l= string.length(); - for (i= 0; i < l; i++) { - re.DrawChar((x - i * 8), y, string.charAt(l - i - 1)); - } - } - - public static void Menu_DrawStringR2LDark(int x, int y, String string) { - int i; - - int l= string.length(); - for (i= 0; i < l; i++) { - re.DrawChar((x - i * 8), y, string.charAt(l - i - 1) + 128); - } - } - - public static menucommon_s Menu_ItemAtCursor(menuframework_s m) { - if (m.cursor < 0 || m.cursor >= m.nitems) - return null; - - return (menucommon_s) m.items[m.cursor]; - } - - static boolean Menu_SelectItem(menuframework_s s) { - menucommon_s item= Menu_ItemAtCursor(s); - - if (item != null) { - switch (item.type) { - case MTYPE_FIELD : - return Field_DoEnter((menufield_s) item); - case MTYPE_ACTION : - Action_DoEnter((menuaction_s) item); - return true; - case MTYPE_LIST : - // Menulist_DoEnter( ( menulist_s ) item ); - return false; - case MTYPE_SPINCONTROL : - // SpinControl_DoEnter( ( menulist_s ) item ); - return false; - } - } - return false; - } - - public static void Menu_SetStatusBar(menuframework_s m, String string) { - m.statusbar= string; - } - - public static void Menu_SlideItem(menuframework_s s, int dir) { - menucommon_s item= (menucommon_s) Menu_ItemAtCursor(s); - - if (item != null) { - switch (item.type) { - case MTYPE_SLIDER : - Slider_DoSlide((menuslider_s) item, dir); - break; - case MTYPE_SPINCONTROL : - SpinControl_DoSlide((menulist_s) item, dir); - break; - } - } - } - - public static int Menu_TallySlots(menuframework_s menu) { - int i; - int total= 0; - - for (i= 0; i < menu.nitems; i++) { - if (((menucommon_s) menu.items[i]).type == MTYPE_LIST) { - int nitems= 0; - String n[]= ((menulist_s) menu.items[i]).itemnames; - - while (n[nitems] != null) - nitems++; - - total += nitems; - } - else { - total++; - } - } - - return total; - } - - public static void Menulist_DoEnter(menulist_s l) { - int start; - - start= l.y / 10 + 1; - - l.curvalue= l.parent.cursor - start; - - if (l.callback != null) - l.callback.execute(l); - } - - public static void MenuList_Draw(menulist_s l) { - String n[]; - int y= 0; - - Menu_DrawStringR2LDark(l.x + l.parent.x + LCOLUMN_OFFSET, l.y + l.parent.y, l.name); - - n= l.itemnames; - - re.DrawFill(l.x - 112 + l.parent.x, l.parent.y + l.y + l.curvalue * 10 + 10, 128, 10, 16); - int i= 0; - - while (n[i] != null) { - Menu_DrawStringR2LDark(l.x + l.parent.x + LCOLUMN_OFFSET, l.y + l.parent.y + y + 10, n[i]); - - i++; - y += 10; - } - } - - public static void Separator_Draw(menuseparator_s s) { - if (s.name != null) - Menu_DrawStringR2LDark(s.x + s.parent.x, s.y + s.parent.y, s.name); - } - - public static void Slider_DoSlide(menuslider_s s, int dir) { - s.curvalue += dir; - - if (s.curvalue > s.maxvalue) - s.curvalue= s.maxvalue; - else if (s.curvalue < s.minvalue) - s.curvalue= s.minvalue; - - if (s.callback != null) - s.callback.execute(s); - } - - public static final int SLIDER_RANGE= 10; - - public static void Slider_Draw(menuslider_s s) { - int i; - - Menu_DrawStringR2LDark(s.x + s.parent.x + LCOLUMN_OFFSET, s.y + s.parent.y, s.name); - - s.range= (s.curvalue - s.minvalue) / (float) (s.maxvalue - s.minvalue); - - if (s.range < 0) - s.range= 0; - if (s.range > 1) - s.range= 1; - re.DrawChar(s.x + s.parent.x + RCOLUMN_OFFSET, s.y + s.parent.y, 128); - for (i= 0; i < SLIDER_RANGE; i++) - re.DrawChar(RCOLUMN_OFFSET + s.x + i * 8 + s.parent.x + 8, s.y + s.parent.y, 129); - re.DrawChar(RCOLUMN_OFFSET + s.x + i * 8 + s.parent.x + 8, s.y + s.parent.y, 130); - re.DrawChar((int) (8 + RCOLUMN_OFFSET + s.parent.x + s.x + (SLIDER_RANGE - 1) * 8 * s.range), s.y + s.parent.y, 131); - } - - public static void SpinControl_DoEnter(menulist_s s) { - s.curvalue++; - if (s.itemnames[s.curvalue] == null) - s.curvalue= 0; + static class menucommon_s { + int type; - if (s.callback != null) - s.callback.execute(s); - } + String name = ""; - public static void SpinControl_DoSlide(menulist_s s, int dir) { - s.curvalue += dir; + int x, y; - if (s.curvalue < 0) - s.curvalue= 0; - else if (s.itemnames[s.curvalue] == null) - s.curvalue--; + menuframework_s parent; - if (s.callback != null) - s.callback.execute(s); - } + int cursor_offset; - public static void SpinControl_Draw(menulist_s s) { - //char buffer[100]; - String buffer; + int localdata[] = { 0, 0, 0, 0 }; - if (s.name != null) { - Menu_DrawStringR2LDark(s.x + s.parent.x + LCOLUMN_OFFSET, s.y + s.parent.y, s.name); - } + int flags; - if (s.itemnames[s.curvalue].indexOf('\n') == -1) { - Menu_DrawString(RCOLUMN_OFFSET + s.x + s.parent.x, s.y + s.parent.y, s.itemnames[s.curvalue]); - } - else { - String line1, line2; - line1= Lib.leftFrom(s.itemnames[s.curvalue], '\n'); - Menu_DrawString(RCOLUMN_OFFSET + s.x + s.parent.x, s.y + s.parent.y, line1); + int n = -1; //position in an array. - line2= Lib.rightFrom(s.itemnames[s.curvalue], '\n'); + String statusbar; - int pos= line2.indexOf('\n'); - if (pos != -1) - line2= line2.substring(0, pos); + mcallback callback; - Menu_DrawString(RCOLUMN_OFFSET + s.x + s.parent.x, s.y + s.parent.y + 10, line2); - } - } -} + mcallback statusbarfunc; + + mcallback ownerdraw; + + mcallback cursordraw; + } + + static class menufield_s extends menucommon_s { + //char buffer[80]; + StringBuffer buffer; //allow deletion. + + int cursor; + + int length; + + int visible_length; + + int visible_offset; + } + + static class menuslider_s extends menucommon_s { + + float minvalue; + + float maxvalue; + + float curvalue; + + float range; + } + + static class menulist_s extends menucommon_s { + int curvalue; + + String itemnames[]; + } + + static class menuaction_s extends menucommon_s { + + } + + static class menuseparator_s extends menucommon_s { + + } + + public static menulayer_t m_layers[] = new menulayer_t[MAX_MENU_DEPTH]; + + public static int m_menudepth; + + static void Banner(String name) { + Dimension dim = new Dimension(); + Globals.re.DrawGetPicSize(dim, name); + + Globals.re.DrawPic(viddef.width / 2 - dim.width / 2, + viddef.height / 2 - 110, name); + } + + static void PushMenu(xcommand_t draw, keyfunc_t key) { //, String(*key) + // (int k) ) { + int i; + + if (Cvar.VariableValue("maxclients") == 1 && Globals.server_state != 0) + Cvar.Set("paused", "1"); + + // if this menu is already present, drop back to that level + // to avoid stacking menus by hotkeys + for (i = 0; i < m_menudepth; i++) + if (m_layers[i].draw == draw && m_layers[i].key == key) { + m_menudepth = i; + } + + if (i == m_menudepth) { + if (m_menudepth >= MAX_MENU_DEPTH) + Com.Error(ERR_FATAL, "PushMenu: MAX_MENU_DEPTH"); + + m_layers[m_menudepth].draw = m_drawfunc; + m_layers[m_menudepth].key = m_keyfunc; + m_menudepth++; + } + + m_drawfunc = draw; + m_keyfunc = key; + + m_entersound = true; + + cls.key_dest = key_menu; + } + + static void ForceMenuOff() { + m_drawfunc = null; + m_keyfunc = null; + cls.key_dest = key_game; + m_menudepth = 0; + Key.ClearStates(); + Cvar.Set("paused", "0"); + } + + static void PopMenu() { + S.StartLocalSound(menu_out_sound); + if (m_menudepth < 1) + Com.Error(ERR_FATAL, "PopMenu: depth < 1"); + m_menudepth--; + + m_drawfunc = m_layers[m_menudepth].draw; + m_keyfunc = m_layers[m_menudepth].key; + + if (0 == m_menudepth) + ForceMenuOff(); + } + + static String Default_MenuKey(menuframework_s m, int key) { + String sound = null; + menucommon_s item; + + if (m != null) { + if ((item = ((menucommon_s) Menu_ItemAtCursor(m))) != null) { + if (item.type == MTYPE_FIELD) { + if (Field_Key((menufield_s) item, key)) + return null; + } + } + } + + switch (key) { + case K_ESCAPE: + PopMenu(); + return menu_out_sound; + case K_KP_UPARROW: + case K_UPARROW: + if (m != null) { + m.cursor--; + Menu_AdjustCursor(m, -1); + sound = menu_move_sound; + } + break; + case K_TAB: + if (m != null) { + m.cursor++; + Menu_AdjustCursor(m, 1); + sound = menu_move_sound; + } + break; + case K_KP_DOWNARROW: + case K_DOWNARROW: + if (m != null) { + m.cursor++; + Menu_AdjustCursor(m, 1); + sound = menu_move_sound; + } + break; + case K_KP_LEFTARROW: + case K_LEFTARROW: + if (m != null) { + Menu_SlideItem(m, -1); + sound = menu_move_sound; + } + break; + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + if (m != null) { + Menu_SlideItem(m, 1); + sound = menu_move_sound; + } + break; + + case K_MOUSE1: + case K_MOUSE2: + case K_MOUSE3: + case K_JOY1: + case K_JOY2: + case K_JOY3: + case K_JOY4: + /* + * case K_AUX1 : case K_AUX2 : case K_AUX3 : case K_AUX4 : case K_AUX5 : + * case K_AUX6 : case K_AUX7 : case K_AUX8 : case K_AUX9 : case K_AUX10 : + * case K_AUX11 : case K_AUX12 : case K_AUX13 : case K_AUX14 : case + * K_AUX15 : case K_AUX16 : case K_AUX17 : case K_AUX18 : case K_AUX19 : + * case K_AUX20 : case K_AUX21 : case K_AUX22 : case K_AUX23 : case + * K_AUX24 : case K_AUX25 : case K_AUX26 : case K_AUX27 : case K_AUX28 : + * case K_AUX29 : case K_AUX30 : case K_AUX31 : case K_AUX32 : + */ + case K_KP_ENTER: + case K_ENTER: + if (m != null) + Menu_SelectItem(m); + sound = menu_move_sound; + break; + } + + return sound; + } + + /* + * ================ DrawCharacter + * + * Draws one solid graphics character cx and cy are in 320*240 coordinates, + * and will be centered on higher res screens. ================ + */ + public static void DrawCharacter(int cx, int cy, int num) { + re.DrawChar(cx + ((viddef.width - 320) >> 1), cy + + ((viddef.height - 240) >> 1), num); + } + + public static void Print(int cx, int cy, String str) { + //while (*str) + for (int n = 0; n < str.length(); n++) { + DrawCharacter(cx, cy, str.charAt(n) + 128); + //str++; + cx += 8; + } + } + + public static void PrintWhite(int cx, int cy, String str) { + for (int n = 0; n < str.length(); n++) { + DrawCharacter(cx, cy, str.charAt(n)); + //str++; + cx += 8; + } + } + + public static void DrawPic(int x, int y, String pic) { + re.DrawPic(x + ((viddef.width - 320) >> 1), y + + ((viddef.height - 240) >> 1), pic); + } + + /* + * ============= DrawCursor + * + * Draws an animating cursor with the point at x,y. The pic will extend to + * the left of x, and both above and below y. ============= + */ + static boolean cached; + + static void DrawCursor(int x, int y, int f) { + //char cursorname[80]; + String cursorname; + + assert (f >= 0) : "negative time and cursor bug"; + + f = Math.abs(f); + + if (!cached) { + int i; + + for (i = 0; i < NUM_CURSOR_FRAMES; i++) { + cursorname = "m_cursor" + i; + + re.RegisterPic(cursorname); + } + cached = true; + } + + cursorname = "m_cursor" + f; + re.DrawPic(x, y, cursorname); + } + + public static void DrawTextBox(int x, int y, int width, int lines) { + int cx, cy; + int n; + + // draw left side + cx = x; + cy = y; + DrawCharacter(cx, cy, 1); + + for (n = 0; n < lines; n++) { + cy += 8; + DrawCharacter(cx, cy, 4); + } + DrawCharacter(cx, cy + 8, 7); + + // draw middle + cx += 8; + while (width > 0) { + cy = y; + DrawCharacter(cx, cy, 2); + + for (n = 0; n < lines; n++) { + cy += 8; + DrawCharacter(cx, cy, 5); + } + DrawCharacter(cx, cy + 8, 8); + + width -= 1; + cx += 8; + } + + // draw right side + cy = y; + DrawCharacter(cx, cy, 3); + for (n = 0; n < lines; n++) { + cy += 8; + DrawCharacter(cx, cy, 6); + + } + DrawCharacter(cx, cy + 8, 9); + + } + + /* + * ======================================================================= + * + * MAIN MENU + * + * ======================================================================= + */ + static final int MAIN_ITEMS = 5; + + static xcommand_t Main_Draw = new xcommand_t() { + public void execute() { + Main_Draw(); + } + }; + + static void Main_Draw() { + int i; + int w, h; + int ystart; + int xoffset; + int widest = -1; + int totalheight = 0; + String litname; + String[] names = { "m_main_game", "m_main_multiplayer", + "m_main_options", "m_main_video", "m_main_quit" }; + Dimension dim = new Dimension(); + + for (i = 0; i < names.length; i++) { + Globals.re.DrawGetPicSize(dim, names[i]); + w = dim.width; + h = dim.height; + + if (w > widest) + widest = w; + totalheight += (h + 12); + } + + ystart = (Globals.viddef.height / 2 - 110); + xoffset = (Globals.viddef.width - widest + 70) / 2; + + for (i = 0; i < names.length; i++) { + if (i != m_main_cursor) + Globals.re.DrawPic(xoffset, ystart + i * 40 + 13, names[i]); + } + + //strcat(litname, "_sel"); + litname = names[m_main_cursor] + "_sel"; + Globals.re.DrawPic(xoffset, ystart + m_main_cursor * 40 + 13, litname); + + DrawCursor(xoffset - 25, ystart + m_main_cursor * 40 + 11, + (int) ((Globals.cls.realtime / 100)) % NUM_CURSOR_FRAMES); + + Globals.re.DrawGetPicSize(dim, "m_main_plaque"); + w = dim.width; + h = dim.height; + Globals.re.DrawPic(xoffset - 30 - w, ystart, "m_main_plaque"); + + Globals.re.DrawPic(xoffset - 30 - w, ystart + h + 5, "m_main_logo"); + } + + static keyfunc_t Main_Key = new keyfunc_t() { + public String execute(int key) { + return Main_Key(key); + } + }; + + static String Main_Key(int key) { + String sound = menu_move_sound; + + switch (key) { + case Key.K_ESCAPE: + PopMenu(); + break; + + case Key.K_KP_DOWNARROW: + case Key.K_DOWNARROW: + if (++m_main_cursor >= MAIN_ITEMS) + m_main_cursor = 0; + return sound; + + case Key.K_KP_UPARROW: + case Key.K_UPARROW: + if (--m_main_cursor < 0) + m_main_cursor = MAIN_ITEMS - 1; + return sound; + + case Key.K_KP_ENTER: + case Key.K_ENTER: + m_entersound = true; + + switch (m_main_cursor) { + case 0: + Menu_Game_f(); + break; + + case 1: + Menu_Multiplayer_f(); + break; + + case 2: + Menu_Options_f(); + break; + + case 3: + Menu_Video_f(); + break; + + case 4: + Menu_Quit_f(); + break; + } + } + + return null; + } + + static xcommand_t Menu_Main = new xcommand_t() { + public void execute() { + Menu_Main_f(); + } + }; + + static void Menu_Main_f() { + PushMenu(new xcommand_t() { + public void execute() { + Main_Draw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Main_Key(key); + } + }); + } + + /* + * ======================================================================= + * + * MULTIPLAYER MENU + * + * ======================================================================= + */ + static menuframework_s s_multiplayer_menu = new menuframework_s(); + + static menuaction_s s_join_network_server_action = new menuaction_s(); + + static menuaction_s s_start_network_server_action = new menuaction_s(); + + static menuaction_s s_player_setup_action = new menuaction_s(); + + static void Multiplayer_MenuDraw() { + Banner("m_banner_multiplayer"); + + Menu_AdjustCursor(s_multiplayer_menu, 1); + Menu_Draw(s_multiplayer_menu); + } + + static void PlayerSetupFunc(Object unused) { + Menu_PlayerConfig_f(); + } + + static void JoinNetworkServerFunc(Object unused) { + Menu_JoinServer_f(); + } + + static void StartNetworkServerFunc(Object unused) { + Menu_StartServer_f(); + } + + static void Multiplayer_MenuInit() { + s_multiplayer_menu.x = (int) (viddef.width * 0.50f - 64); + s_multiplayer_menu.nitems = 0; + + s_join_network_server_action.type = MTYPE_ACTION; + s_join_network_server_action.flags = QMF_LEFT_JUSTIFY; + s_join_network_server_action.x = 0; + s_join_network_server_action.y = 0; + s_join_network_server_action.name = " join network server"; + s_join_network_server_action.callback = new mcallback() { + public void execute(Object o) { + JoinNetworkServerFunc(o); + }; + }; + + s_start_network_server_action.type = MTYPE_ACTION; + s_start_network_server_action.flags = QMF_LEFT_JUSTIFY; + s_start_network_server_action.x = 0; + s_start_network_server_action.y = 10; + s_start_network_server_action.name = " start network server"; + s_start_network_server_action.callback = new mcallback() { + public void execute(Object o) { + StartNetworkServerFunc(o); + } + }; + + s_player_setup_action.type = MTYPE_ACTION; + s_player_setup_action.flags = QMF_LEFT_JUSTIFY; + s_player_setup_action.x = 0; + s_player_setup_action.y = 20; + s_player_setup_action.name = " player setup"; + s_player_setup_action.callback = new mcallback() { + public void execute(Object o) { + PlayerSetupFunc(o); + } + }; + + Menu_AddItem(s_multiplayer_menu, s_join_network_server_action); + Menu_AddItem(s_multiplayer_menu, s_start_network_server_action); + Menu_AddItem(s_multiplayer_menu, s_player_setup_action); + + Menu_SetStatusBar(s_multiplayer_menu, null); + + Menu_Center(s_multiplayer_menu); + } + + static String Multiplayer_MenuKey(int key) { + return Default_MenuKey(s_multiplayer_menu, key); + } + + static xcommand_t Menu_Multiplayer = new xcommand_t() { + public void execute() { + Menu_Multiplayer_f(); + } + }; + + static void Menu_Multiplayer_f() { + Multiplayer_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + Multiplayer_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Multiplayer_MenuKey(key); + } + }); + } + + /* + * ======================================================================= + * + * KEYS MENU + * + * ======================================================================= + */ + static String bindnames[][] = { { "+attack", "attack" }, + { "weapnext", "next weapon" }, { "+forward", "walk forward" }, + { "+back", "backpedal" }, { "+left", "turn left" }, + { "+right", "turn right" }, { "+speed", "run" }, + { "+moveleft", "step left" }, { "+moveright", "step right" }, + { "+strafe", "sidestep" }, { "+lookup", "look up" }, + { "+lookdown", "look down" }, { "centerview", "center view" }, + { "+mlook", "mouse look" }, { "+klook", "keyboard look" }, + { "+moveup", "up / jump" }, { "+movedown", "down / crouch" }, { + + "inven", "inventory" }, { "invuse", "use item" }, + { "invdrop", "drop item" }, { "invprev", "prev item" }, + { "invnext", "next item" }, { + + "cmd help", "help computer" }, { null, null } }; + + int keys_cursor; + + static boolean bind_grab; + + static menuframework_s s_keys_menu = new menuframework_s(); + + static menuaction_s s_keys_attack_action = new menuaction_s(); + + static menuaction_s s_keys_change_weapon_action = new menuaction_s(); + + static menuaction_s s_keys_walk_forward_action = new menuaction_s(); + + static menuaction_s s_keys_backpedal_action = new menuaction_s(); + + static menuaction_s s_keys_turn_left_action = new menuaction_s(); + + static menuaction_s s_keys_turn_right_action = new menuaction_s(); + + static menuaction_s s_keys_run_action = new menuaction_s(); + + static menuaction_s s_keys_step_left_action = new menuaction_s(); + + static menuaction_s s_keys_step_right_action = new menuaction_s(); + + static menuaction_s s_keys_sidestep_action = new menuaction_s(); + + static menuaction_s s_keys_look_up_action = new menuaction_s(); + + static menuaction_s s_keys_look_down_action = new menuaction_s(); + + static menuaction_s s_keys_center_view_action = new menuaction_s(); + + static menuaction_s s_keys_mouse_look_action = new menuaction_s(); + + static menuaction_s s_keys_keyboard_look_action = new menuaction_s(); + + static menuaction_s s_keys_move_up_action = new menuaction_s(); + + static menuaction_s s_keys_move_down_action = new menuaction_s(); + + static menuaction_s s_keys_inventory_action = new menuaction_s(); + + static menuaction_s s_keys_inv_use_action = new menuaction_s(); + + static menuaction_s s_keys_inv_drop_action = new menuaction_s(); + + static menuaction_s s_keys_inv_prev_action = new menuaction_s(); + + static menuaction_s s_keys_inv_next_action = new menuaction_s(); + + static menuaction_s s_keys_help_computer_action = new menuaction_s(); + + static void UnbindCommand(String command) { + int j; + String b; + + for (j = 0; j < 256; j++) { + b = keybindings[j]; + if (b == null) + continue; + if (b.equals(command)) + Key.SetBinding(j, ""); + } + } + + static void FindKeysForCommand(String command, int twokeys[]) { + int count; + int j; + String b; + + twokeys[0] = twokeys[1] = -1; + count = 0; + + for (j = 0; j < 256; j++) { + b = keybindings[j]; + if (b == null) + continue; + + if (b.equals(command)) { + twokeys[count] = j; + count++; + if (count == 2) + break; + } + } + } + + static void KeyCursorDrawFunc(menuframework_s menu) { + if (bind_grab) + re.DrawChar(menu.x, menu.y + menu.cursor * 9, '='); + else + re.DrawChar(menu.x, menu.y + menu.cursor * 9, 12 + ((int) (Sys + .Milliseconds() / 250) & 1)); + } + + static void DrawKeyBindingFunc(Object self) { + int keys[] = { 0, 0 }; + menuaction_s a = (menuaction_s) self; + + FindKeysForCommand(bindnames[a.localdata[0]][0], keys); + + if (keys[0] == -1) { + Menu_DrawString(a.x + a.parent.x + 16, a.y + a.parent.y, "???"); + } else { + int x; + String name; + + name = Key.KeynumToString(keys[0]); + + Menu_DrawString(a.x + a.parent.x + 16, a.y + a.parent.y, name); + + x = name.length() * 8; + + if (keys[1] != -1) { + Menu_DrawString(a.x + a.parent.x + 24 + x, a.y + a.parent.y, + "or"); + Menu_DrawString(a.x + a.parent.x + 48 + x, a.y + a.parent.y, + Key.KeynumToString(keys[1])); + } + } + } + + static void KeyBindingFunc(Object self) { + menuaction_s a = (menuaction_s) self; + int keys[] = { 0, 0 }; + + FindKeysForCommand(bindnames[a.localdata[0]][0], keys); + + if (keys[1] != -1) + UnbindCommand(bindnames[a.localdata[0]][0]); + + bind_grab = true; + + Menu_SetStatusBar(s_keys_menu, "press a key or button for this action"); + } + + static void Keys_MenuInit() { + int y = 0; + int i = 0; + + s_keys_menu.x = (int) (viddef.width * 0.50); + s_keys_menu.nitems = 0; + s_keys_menu.cursordraw = new mcallback() { + public void execute(Object o) { + KeyCursorDrawFunc((menuframework_s) o); + } + }; + + s_keys_attack_action.type = MTYPE_ACTION; + s_keys_attack_action.flags = QMF_GRAYED; + s_keys_attack_action.x = 0; + s_keys_attack_action.y = y; + s_keys_attack_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_attack_action.localdata[0] = i; + s_keys_attack_action.name = bindnames[s_keys_attack_action.localdata[0]][1]; + + s_keys_change_weapon_action.type = MTYPE_ACTION; + s_keys_change_weapon_action.flags = QMF_GRAYED; + s_keys_change_weapon_action.x = 0; + s_keys_change_weapon_action.y = y += 9; + s_keys_change_weapon_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_change_weapon_action.localdata[0] = ++i; + s_keys_change_weapon_action.name = bindnames[s_keys_change_weapon_action.localdata[0]][1]; + + s_keys_walk_forward_action.type = MTYPE_ACTION; + s_keys_walk_forward_action.flags = QMF_GRAYED; + s_keys_walk_forward_action.x = 0; + s_keys_walk_forward_action.y = y += 9; + s_keys_walk_forward_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_walk_forward_action.localdata[0] = ++i; + s_keys_walk_forward_action.name = bindnames[s_keys_walk_forward_action.localdata[0]][1]; + + s_keys_backpedal_action.type = MTYPE_ACTION; + s_keys_backpedal_action.flags = QMF_GRAYED; + s_keys_backpedal_action.x = 0; + s_keys_backpedal_action.y = y += 9; + s_keys_backpedal_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_backpedal_action.localdata[0] = ++i; + s_keys_backpedal_action.name = bindnames[s_keys_backpedal_action.localdata[0]][1]; + + s_keys_turn_left_action.type = MTYPE_ACTION; + s_keys_turn_left_action.flags = QMF_GRAYED; + s_keys_turn_left_action.x = 0; + s_keys_turn_left_action.y = y += 9; + s_keys_turn_left_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_turn_left_action.localdata[0] = ++i; + s_keys_turn_left_action.name = bindnames[s_keys_turn_left_action.localdata[0]][1]; + + s_keys_turn_right_action.type = MTYPE_ACTION; + s_keys_turn_right_action.flags = QMF_GRAYED; + s_keys_turn_right_action.x = 0; + s_keys_turn_right_action.y = y += 9; + s_keys_turn_right_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_turn_right_action.localdata[0] = ++i; + s_keys_turn_right_action.name = bindnames[s_keys_turn_right_action.localdata[0]][1]; + + s_keys_run_action.type = MTYPE_ACTION; + s_keys_run_action.flags = QMF_GRAYED; + s_keys_run_action.x = 0; + s_keys_run_action.y = y += 9; + s_keys_run_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_run_action.localdata[0] = ++i; + s_keys_run_action.name = bindnames[s_keys_run_action.localdata[0]][1]; + + s_keys_step_left_action.type = MTYPE_ACTION; + s_keys_step_left_action.flags = QMF_GRAYED; + s_keys_step_left_action.x = 0; + s_keys_step_left_action.y = y += 9; + s_keys_step_left_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + s_keys_step_left_action.localdata[0] = ++i; + s_keys_step_left_action.name = bindnames[s_keys_step_left_action.localdata[0]][1]; + + s_keys_step_right_action.type = MTYPE_ACTION; + s_keys_step_right_action.flags = QMF_GRAYED; + s_keys_step_right_action.x = 0; + s_keys_step_right_action.y = y += 9; + s_keys_step_right_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_step_right_action.localdata[0] = ++i; + s_keys_step_right_action.name = bindnames[s_keys_step_right_action.localdata[0]][1]; + + s_keys_sidestep_action.type = MTYPE_ACTION; + s_keys_sidestep_action.flags = QMF_GRAYED; + s_keys_sidestep_action.x = 0; + s_keys_sidestep_action.y = y += 9; + s_keys_sidestep_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_sidestep_action.localdata[0] = ++i; + s_keys_sidestep_action.name = bindnames[s_keys_sidestep_action.localdata[0]][1]; + + s_keys_look_up_action.type = MTYPE_ACTION; + s_keys_look_up_action.flags = QMF_GRAYED; + s_keys_look_up_action.x = 0; + s_keys_look_up_action.y = y += 9; + s_keys_look_up_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_look_up_action.localdata[0] = ++i; + s_keys_look_up_action.name = bindnames[s_keys_look_up_action.localdata[0]][1]; + + s_keys_look_down_action.type = MTYPE_ACTION; + s_keys_look_down_action.flags = QMF_GRAYED; + s_keys_look_down_action.x = 0; + s_keys_look_down_action.y = y += 9; + s_keys_look_down_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_look_down_action.localdata[0] = ++i; + s_keys_look_down_action.name = bindnames[s_keys_look_down_action.localdata[0]][1]; + + s_keys_center_view_action.type = MTYPE_ACTION; + s_keys_center_view_action.flags = QMF_GRAYED; + s_keys_center_view_action.x = 0; + s_keys_center_view_action.y = y += 9; + s_keys_center_view_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_center_view_action.localdata[0] = ++i; + s_keys_center_view_action.name = bindnames[s_keys_center_view_action.localdata[0]][1]; + + s_keys_mouse_look_action.type = MTYPE_ACTION; + s_keys_mouse_look_action.flags = QMF_GRAYED; + s_keys_mouse_look_action.x = 0; + s_keys_mouse_look_action.y = y += 9; + s_keys_mouse_look_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_mouse_look_action.localdata[0] = ++i; + s_keys_mouse_look_action.name = bindnames[s_keys_mouse_look_action.localdata[0]][1]; + + s_keys_keyboard_look_action.type = MTYPE_ACTION; + s_keys_keyboard_look_action.flags = QMF_GRAYED; + s_keys_keyboard_look_action.x = 0; + s_keys_keyboard_look_action.y = y += 9; + s_keys_keyboard_look_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_keyboard_look_action.localdata[0] = ++i; + s_keys_keyboard_look_action.name = bindnames[s_keys_keyboard_look_action.localdata[0]][1]; + + s_keys_move_up_action.type = MTYPE_ACTION; + s_keys_move_up_action.flags = QMF_GRAYED; + s_keys_move_up_action.x = 0; + s_keys_move_up_action.y = y += 9; + s_keys_move_up_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_move_up_action.localdata[0] = ++i; + s_keys_move_up_action.name = bindnames[s_keys_move_up_action.localdata[0]][1]; + + s_keys_move_down_action.type = MTYPE_ACTION; + s_keys_move_down_action.flags = QMF_GRAYED; + s_keys_move_down_action.x = 0; + s_keys_move_down_action.y = y += 9; + s_keys_move_down_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_move_down_action.localdata[0] = ++i; + s_keys_move_down_action.name = bindnames[s_keys_move_down_action.localdata[0]][1]; + + s_keys_inventory_action.type = MTYPE_ACTION; + s_keys_inventory_action.flags = QMF_GRAYED; + s_keys_inventory_action.x = 0; + s_keys_inventory_action.y = y += 9; + s_keys_inventory_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_inventory_action.localdata[0] = ++i; + s_keys_inventory_action.name = bindnames[s_keys_inventory_action.localdata[0]][1]; + + s_keys_inv_use_action.type = MTYPE_ACTION; + s_keys_inv_use_action.flags = QMF_GRAYED; + s_keys_inv_use_action.x = 0; + s_keys_inv_use_action.y = y += 9; + s_keys_inv_use_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_inv_use_action.localdata[0] = ++i; + s_keys_inv_use_action.name = bindnames[s_keys_inv_use_action.localdata[0]][1]; + + s_keys_inv_drop_action.type = MTYPE_ACTION; + s_keys_inv_drop_action.flags = QMF_GRAYED; + s_keys_inv_drop_action.x = 0; + s_keys_inv_drop_action.y = y += 9; + s_keys_inv_drop_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_inv_drop_action.localdata[0] = ++i; + s_keys_inv_drop_action.name = bindnames[s_keys_inv_drop_action.localdata[0]][1]; + + s_keys_inv_prev_action.type = MTYPE_ACTION; + s_keys_inv_prev_action.flags = QMF_GRAYED; + s_keys_inv_prev_action.x = 0; + s_keys_inv_prev_action.y = y += 9; + s_keys_inv_prev_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_inv_prev_action.localdata[0] = ++i; + s_keys_inv_prev_action.name = bindnames[s_keys_inv_prev_action.localdata[0]][1]; + + s_keys_inv_next_action.type = MTYPE_ACTION; + s_keys_inv_next_action.flags = QMF_GRAYED; + s_keys_inv_next_action.x = 0; + s_keys_inv_next_action.y = y += 9; + s_keys_inv_next_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_inv_next_action.localdata[0] = ++i; + s_keys_inv_next_action.name = bindnames[s_keys_inv_next_action.localdata[0]][1]; + + s_keys_help_computer_action.type = MTYPE_ACTION; + s_keys_help_computer_action.flags = QMF_GRAYED; + s_keys_help_computer_action.x = 0; + s_keys_help_computer_action.y = y += 9; + s_keys_help_computer_action.ownerdraw = new mcallback() { + public void execute(Object o) { + DrawKeyBindingFunc(o); + } + }; + + s_keys_help_computer_action.localdata[0] = ++i; + s_keys_help_computer_action.name = bindnames[s_keys_help_computer_action.localdata[0]][1]; + + Menu_AddItem(s_keys_menu, s_keys_attack_action); + Menu_AddItem(s_keys_menu, s_keys_change_weapon_action); + Menu_AddItem(s_keys_menu, s_keys_walk_forward_action); + Menu_AddItem(s_keys_menu, s_keys_backpedal_action); + Menu_AddItem(s_keys_menu, s_keys_turn_left_action); + Menu_AddItem(s_keys_menu, s_keys_turn_right_action); + Menu_AddItem(s_keys_menu, s_keys_run_action); + Menu_AddItem(s_keys_menu, s_keys_step_left_action); + Menu_AddItem(s_keys_menu, s_keys_step_right_action); + Menu_AddItem(s_keys_menu, s_keys_sidestep_action); + Menu_AddItem(s_keys_menu, s_keys_look_up_action); + Menu_AddItem(s_keys_menu, s_keys_look_down_action); + Menu_AddItem(s_keys_menu, s_keys_center_view_action); + Menu_AddItem(s_keys_menu, s_keys_mouse_look_action); + Menu_AddItem(s_keys_menu, s_keys_keyboard_look_action); + Menu_AddItem(s_keys_menu, s_keys_move_up_action); + Menu_AddItem(s_keys_menu, s_keys_move_down_action); + + Menu_AddItem(s_keys_menu, s_keys_inventory_action); + Menu_AddItem(s_keys_menu, s_keys_inv_use_action); + Menu_AddItem(s_keys_menu, s_keys_inv_drop_action); + Menu_AddItem(s_keys_menu, s_keys_inv_prev_action); + Menu_AddItem(s_keys_menu, s_keys_inv_next_action); + + Menu_AddItem(s_keys_menu, s_keys_help_computer_action); + + Menu_SetStatusBar(s_keys_menu, "enter to change, backspace to clear"); + Menu_Center(s_keys_menu); + } + + static xcommand_t Keys_MenuDraw = new xcommand_t() { + public void execute() { + Keys_MenuDraw_f(); + } + }; + + static void Keys_MenuDraw_f() { + Menu_AdjustCursor(s_keys_menu, 1); + Menu_Draw(s_keys_menu); + } + + static keyfunc_t Keys_MenuKey = new keyfunc_t() { + public String execute(int key) { + return Keys_MenuKey_f(key); + } + }; + + static String Keys_MenuKey_f(int key) { + menuaction_s item = (menuaction_s) Menu_ItemAtCursor(s_keys_menu); + + if (bind_grab) { + if (key != K_ESCAPE && key != '`') { + //char cmd[1024]; + String cmd; + + //Com_sprintf(cmd, sizeof(cmd), "bind \"%s\" \"%s\"\n", + // Key_KeynumToString(key), bindnames[item.localdata[0]][0]); + cmd = "bind \"" + Key.KeynumToString(key) + "\" \"" + + bindnames[item.localdata[0]][0] + "\""; + Cbuf.InsertText(cmd); + } + + Menu_SetStatusBar(s_keys_menu, + "enter to change, backspace to clear"); + bind_grab = false; + return menu_out_sound; + } + + switch (key) { + case K_KP_ENTER: + case K_ENTER: + KeyBindingFunc(item); + return menu_in_sound; + case K_BACKSPACE: // delete bindings + case K_DEL: // delete bindings + case K_KP_DEL: + UnbindCommand(bindnames[item.localdata[0]][0]); + return menu_out_sound; + default: + return Default_MenuKey(s_keys_menu, key); + } + } + + static xcommand_t Menu_Keys = new xcommand_t() { + public void execute() { + Menu_Keys_f(); + } + }; + + static void Menu_Keys_f() { + Keys_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + Keys_MenuDraw_f(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Keys_MenuKey_f(key); + } + }); + } + + /* + * ======================================================================= + * + * CONTROLS MENU + * + * ======================================================================= + */ + static cvar_t win_noalttab; + + static menuframework_s s_options_menu = new menuframework_s(); + + static menuaction_s s_options_defaults_action = new menuaction_s(); + + static menuaction_s s_options_customize_options_action = new menuaction_s(); + + static menuslider_s s_options_sensitivity_slider = new menuslider_s(); + + static menulist_s s_options_freelook_box = new menulist_s(); + + static menulist_s s_options_noalttab_box = new menulist_s(); + + static menulist_s s_options_alwaysrun_box = new menulist_s(); + + static menulist_s s_options_invertmouse_box = new menulist_s(); + + static menulist_s s_options_lookspring_box = new menulist_s(); + + static menulist_s s_options_lookstrafe_box = new menulist_s(); + + static menulist_s s_options_crosshair_box = new menulist_s(); + + static menuslider_s s_options_sfxvolume_slider = new menuslider_s(); + + static menulist_s s_options_joystick_box = new menulist_s(); + + static menulist_s s_options_cdvolume_box = new menulist_s(); + + static menulist_s s_options_quality_list = new menulist_s(); + + //static menulist_s s_options_compatibility_list = new menulist_s(); + static menuaction_s s_options_console_action = new menuaction_s(); + + static void CrosshairFunc(Object unused) { + Cvar.SetValue("crosshair", s_options_crosshair_box.curvalue); + } + + static void JoystickFunc(Object unused) { + Cvar.SetValue("in_joystick", s_options_joystick_box.curvalue); + } + + static void CustomizeControlsFunc(Object unused) { + Menu_Keys_f(); + } + + static void AlwaysRunFunc(Object unused) { + Cvar.SetValue("cl_run", s_options_alwaysrun_box.curvalue); + } + + static void FreeLookFunc(Object unused) { + Cvar.SetValue("freelook", s_options_freelook_box.curvalue); + } + + static void MouseSpeedFunc(Object unused) { + Cvar.SetValue("sensitivity", + s_options_sensitivity_slider.curvalue / 2.0F); + } + + static void NoAltTabFunc(Object unused) { + Cvar.SetValue("win_noalttab", s_options_noalttab_box.curvalue); + } + + static float ClampCvar(float min, float max, float value) { + if (value < min) + return min; + if (value > max) + return max; + return value; + } + + static void ControlsSetMenuItemValues() { + s_options_sfxvolume_slider.curvalue = Cvar.VariableValue("s_volume") * 10; + s_options_cdvolume_box.curvalue = 1 - ((int) Cvar + .VariableValue("cd_nocd")); + //s_options_quality_list.curvalue = 1 - ((int) + // Cvar.VariableValue("s_loadas8bit")); + if ("joal".equals(Cvar.VariableString("s_impl"))) { + s_options_quality_list.curvalue = 0; + } else { + s_options_quality_list.curvalue = 1; + } + + s_options_sensitivity_slider.curvalue = (sensitivity.value) * 2; + + Cvar.SetValue("cl_run", ClampCvar(0, 1, cl_run.value)); + s_options_alwaysrun_box.curvalue = (int) cl_run.value; + + s_options_invertmouse_box.curvalue = m_pitch.value < 0 ? 1 : 0; + + Cvar.SetValue("lookspring", ClampCvar(0, 1, lookspring.value)); + s_options_lookspring_box.curvalue = (int) lookspring.value; + + Cvar.SetValue("lookstrafe", ClampCvar(0, 1, lookstrafe.value)); + s_options_lookstrafe_box.curvalue = (int) lookstrafe.value; + + Cvar.SetValue("freelook", ClampCvar(0, 1, freelook.value)); + s_options_freelook_box.curvalue = (int) freelook.value; + + Cvar.SetValue("crosshair", ClampCvar(0, 3, Globals.crosshair.value)); + s_options_crosshair_box.curvalue = (int) Globals.crosshair.value; + + Cvar.SetValue("in_joystick", ClampCvar(0, 1, in_joystick.value)); + s_options_joystick_box.curvalue = (int) in_joystick.value; + + s_options_noalttab_box.curvalue = (int) win_noalttab.value; + } + + static void ControlsResetDefaultsFunc(Object unused) { + Cbuf.AddText("exec default.cfg\n"); + Cbuf.Execute(); + + ControlsSetMenuItemValues(); + } + + static void InvertMouseFunc(Object unused) { + Cvar.SetValue("m_pitch", -m_pitch.value); + } + + static void LookspringFunc(Object unused) { + Cvar.SetValue("lookspring", 1 - lookspring.value); + } + + static void LookstrafeFunc(Object unused) { + Cvar.SetValue("lookstrafe", 1 - lookstrafe.value); + } + + static void UpdateVolumeFunc(Object unused) { + Cvar.SetValue("s_volume", s_options_sfxvolume_slider.curvalue / 10); + } + + static void UpdateCDVolumeFunc(Object unused) { + Cvar.SetValue("cd_nocd", 1 - s_options_cdvolume_box.curvalue); + } + + static void ConsoleFunc(Object unused) { + /* + * * the proper way to do this is probably to have ToggleConsole_f + * accept a parameter + */ + + if (cl.attractloop) { + Cbuf.AddText("killserver\n"); + return; + } + + Key.ClearTyping(); + Console.ClearNotify(); + + ForceMenuOff(); + cls.key_dest = key_console; + } + + static void UpdateSoundQualityFunc(Object unused) { + boolean driverNotChanged = false; + if (s_options_quality_list.curvalue != 0) { + // Cvar.SetValue("s_khz", 22); + // Cvar.SetValue("s_loadas8bit", 0); + driverNotChanged = S.getDriverName().equals("dummy"); + Cvar.Set("s_impl", "dummy"); + } else { + // Cvar.SetValue("s_khz", 11); + // Cvar.SetValue("s_loadas8bit", 1); + driverNotChanged = S.getDriverName().equals("joal"); + Cvar.Set("s_impl", "joal"); + } + + //Cvar.SetValue("s_primary", s_options_compatibility_list.curvalue); + + if (driverNotChanged) { + re.EndFrame(); + return; + } else { + + DrawTextBox(8, 120 - 48, 36, 3); + Print(16 + 16, 120 - 48 + 8, "Restarting the sound system. This"); + Print(16 + 16, 120 - 48 + 16, "could take up to a minute, so"); + Print(16 + 16, 120 - 48 + 24, "please be patient."); + + // the text box won't show up unless we do a buffer swap + re.EndFrame(); + + CL.Snd_Restart_f.execute(); + } + } + + static String cd_music_items[] = { "disabled", "enabled", null }; + + static String soundstate_items[] = { "on", "off", null }; + + static String compatibility_items[] = { "max compatibility", + "max performance", null }; + + static String yesno_names[] = { "no", "yes", null }; + + static String crosshair_names[] = { "none", "cross", "dot", "angle", null }; + + static void Options_MenuInit() { + + win_noalttab = Cvar.Get("win_noalttab", "0", CVAR_ARCHIVE); + + /* + * * configure controls menu and menu items + */ + s_options_menu.x = viddef.width / 2; + s_options_menu.y = viddef.height / 2 - 58; + s_options_menu.nitems = 0; + + s_options_sfxvolume_slider.type = MTYPE_SLIDER; + s_options_sfxvolume_slider.x = 0; + s_options_sfxvolume_slider.y = 0; + s_options_sfxvolume_slider.name = "effects volume"; + s_options_sfxvolume_slider.callback = new mcallback() { + public void execute(Object o) { + UpdateVolumeFunc(o); + } + }; + s_options_sfxvolume_slider.minvalue = 0; + s_options_sfxvolume_slider.maxvalue = 10; + s_options_sfxvolume_slider.curvalue = Cvar.VariableValue("s_volume") * 10; + + s_options_cdvolume_box.type = MTYPE_SPINCONTROL; + s_options_cdvolume_box.x = 0; + s_options_cdvolume_box.y = 10; + s_options_cdvolume_box.name = "CD music"; + s_options_cdvolume_box.callback = new mcallback() { + public void execute(Object o) { + UpdateCDVolumeFunc(o); + } + }; + s_options_cdvolume_box.itemnames = cd_music_items; + s_options_cdvolume_box.curvalue = 1 - (int) Cvar + .VariableValue("cd_nocd"); + + s_options_quality_list.type = MTYPE_SPINCONTROL; + s_options_quality_list.x = 0; + s_options_quality_list.y = 20; + ; + s_options_quality_list.name = "sound"; + s_options_quality_list.callback = new mcallback() { + public void execute(Object o) { + UpdateSoundQualityFunc(o); + } + }; + s_options_quality_list.itemnames = soundstate_items; + //s_options_quality_list.curvalue = 1 - (int) + // Cvar.VariableValue("s_loadas8bit"); + + // s_options_compatibility_list.type = MTYPE_SPINCONTROL; + // s_options_compatibility_list.x = 0; + // s_options_compatibility_list.y = 30; + // s_options_compatibility_list.name = "sound compatibility"; + // s_options_compatibility_list.callback = new mcallback() { + // public void execute(Object o) { + // UpdateSoundQualityFunc(o); + // } + // }; + // s_options_compatibility_list.itemnames = compatibility_items; + // s_options_compatibility_list.curvalue = (int) + // Cvar.VariableValue("s_primary"); + + s_options_sensitivity_slider.type = MTYPE_SLIDER; + s_options_sensitivity_slider.x = 0; + s_options_sensitivity_slider.y = 50; + s_options_sensitivity_slider.name = "mouse speed"; + s_options_sensitivity_slider.callback = new mcallback() { + public void execute(Object o) { + MouseSpeedFunc(o); + } + }; + s_options_sensitivity_slider.minvalue = 2; + s_options_sensitivity_slider.maxvalue = 22; + + s_options_alwaysrun_box.type = MTYPE_SPINCONTROL; + s_options_alwaysrun_box.x = 0; + s_options_alwaysrun_box.y = 60; + s_options_alwaysrun_box.name = "always run"; + s_options_alwaysrun_box.callback = new mcallback() { + public void execute(Object o) { + AlwaysRunFunc(o); + } + }; + s_options_alwaysrun_box.itemnames = yesno_names; + + s_options_invertmouse_box.type = MTYPE_SPINCONTROL; + s_options_invertmouse_box.x = 0; + s_options_invertmouse_box.y = 70; + s_options_invertmouse_box.name = "invert mouse"; + s_options_invertmouse_box.callback = new mcallback() { + public void execute(Object o) { + InvertMouseFunc(o); + } + }; + s_options_invertmouse_box.itemnames = yesno_names; + + s_options_lookspring_box.type = MTYPE_SPINCONTROL; + s_options_lookspring_box.x = 0; + s_options_lookspring_box.y = 80; + s_options_lookspring_box.name = "lookspring"; + s_options_lookspring_box.callback = new mcallback() { + public void execute(Object o) { + LookspringFunc(o); + } + }; + s_options_lookspring_box.itemnames = yesno_names; + + s_options_lookstrafe_box.type = MTYPE_SPINCONTROL; + s_options_lookstrafe_box.x = 0; + s_options_lookstrafe_box.y = 90; + s_options_lookstrafe_box.name = "lookstrafe"; + s_options_lookstrafe_box.callback = new mcallback() { + public void execute(Object o) { + LookstrafeFunc(o); + } + }; + s_options_lookstrafe_box.itemnames = yesno_names; + + s_options_freelook_box.type = MTYPE_SPINCONTROL; + s_options_freelook_box.x = 0; + s_options_freelook_box.y = 100; + s_options_freelook_box.name = "free look"; + s_options_freelook_box.callback = new mcallback() { + public void execute(Object o) { + FreeLookFunc(o); + } + }; + s_options_freelook_box.itemnames = yesno_names; + + s_options_crosshair_box.type = MTYPE_SPINCONTROL; + s_options_crosshair_box.x = 0; + s_options_crosshair_box.y = 110; + s_options_crosshair_box.name = "crosshair"; + s_options_crosshair_box.callback = new mcallback() { + public void execute(Object o) { + CrosshairFunc(o); + } + }; + s_options_crosshair_box.itemnames = crosshair_names; + /* + * s_options_noalttab_box.type = MTYPE_SPINCONTROL; + * s_options_noalttab_box.x = 0; s_options_noalttab_box.y = 110; + * s_options_noalttab_box.name = "disable alt-tab"; + * s_options_noalttab_box.callback = NoAltTabFunc; + * s_options_noalttab_box.itemnames = yesno_names; + */ + s_options_joystick_box.type = MTYPE_SPINCONTROL; + s_options_joystick_box.x = 0; + s_options_joystick_box.y = 120; + s_options_joystick_box.name = "use joystick"; + s_options_joystick_box.callback = new mcallback() { + public void execute(Object o) { + JoystickFunc(o); + } + }; + s_options_joystick_box.itemnames = yesno_names; + + s_options_customize_options_action.type = MTYPE_ACTION; + s_options_customize_options_action.x = 0; + s_options_customize_options_action.y = 140; + s_options_customize_options_action.name = "customize controls"; + s_options_customize_options_action.callback = new mcallback() { + public void execute(Object o) { + CustomizeControlsFunc(o); + } + }; + + s_options_defaults_action.type = MTYPE_ACTION; + s_options_defaults_action.x = 0; + s_options_defaults_action.y = 150; + s_options_defaults_action.name = "reset defaults"; + s_options_defaults_action.callback = new mcallback() { + public void execute(Object o) { + ControlsResetDefaultsFunc(o); + } + }; + + s_options_console_action.type = MTYPE_ACTION; + s_options_console_action.x = 0; + s_options_console_action.y = 160; + s_options_console_action.name = "go to console"; + s_options_console_action.callback = new mcallback() { + public void execute(Object o) { + ConsoleFunc(o); + } + }; + + ControlsSetMenuItemValues(); + + Menu_AddItem(s_options_menu, s_options_sfxvolume_slider); + + Menu_AddItem(s_options_menu, s_options_cdvolume_box); + Menu_AddItem(s_options_menu, s_options_quality_list); + // Menu_AddItem(s_options_menu, s_options_compatibility_list); + Menu_AddItem(s_options_menu, s_options_sensitivity_slider); + Menu_AddItem(s_options_menu, s_options_alwaysrun_box); + Menu_AddItem(s_options_menu, s_options_invertmouse_box); + Menu_AddItem(s_options_menu, s_options_lookspring_box); + Menu_AddItem(s_options_menu, s_options_lookstrafe_box); + Menu_AddItem(s_options_menu, s_options_freelook_box); + Menu_AddItem(s_options_menu, s_options_crosshair_box); + // Menu_AddItem(s_options_menu, s_options_joystick_box); + Menu_AddItem(s_options_menu, s_options_customize_options_action); + Menu_AddItem(s_options_menu, s_options_defaults_action); + Menu_AddItem(s_options_menu, s_options_console_action); + } + + static void Options_MenuDraw() { + Banner("m_banner_options"); + Menu_AdjustCursor(s_options_menu, 1); + Menu_Draw(s_options_menu); + } + + static String Options_MenuKey(int key) { + return Default_MenuKey(s_options_menu, key); + } + + static xcommand_t Menu_Options = new xcommand_t() { + public void execute() { + Menu_Options_f(); + } + }; + + static void Menu_Options_f() { + Options_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + Options_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Options_MenuKey(key); + } + }); + } + + /* + * ======================================================================= + * + * VIDEO MENU + * + * ======================================================================= + */ + + static xcommand_t Menu_Video = new xcommand_t() { + public void execute() { + Menu_Video_f(); + } + }; + + static void Menu_Video_f() { + VID.MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + VID.MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return VID.MenuKey(key); + } + }); + } + + /* + * ============================================================================= + * + * END GAME MENU + * + * ============================================================================= + */ + static int credits_start_time; + + static String creditsIndex[] = new String[256]; + + static String creditsBuffer; + + static String idcredits[] = { "+QUAKE II BY ID SOFTWARE", "", + "+PROGRAMMING", "John Carmack", "John Cash", "Brian Hook", "", + "+JAVA PORT BY BYTONIC", "CWEI", "HOZ", "RST", "", "+ART", + "Adrian Carmack", "Kevin Cloud", "Paul Steed", "", "+LEVEL DESIGN", + "Tim Willits", "American McGee", "Christian Antkow", + "Paul Jaquays", "Brandon James", "", "+BIZ", "Todd Hollenshead", + "Barrett (Bear) Alexander", "Donna Jackson", "", "", + "+SPECIAL THANKS", "Ben Donges for beta testing", "", "", "", "", + "", "", "+ADDITIONAL SUPPORT", "", "+LINUX PORT AND CTF", + "Dave \"Zoid\" Kirsch", "", "+CINEMATIC SEQUENCES", + "Ending Cinematic by Blur Studio - ", "Venice, CA", "", + "Environment models for Introduction", + "Cinematic by Karl Dolgener", "", + "Assistance with environment design", "by Cliff Iwai", "", + "+SOUND EFFECTS AND MUSIC", + "Sound Design by Soundelux Media Labs.", + "Music Composed and Produced by", + "Soundelux Media Labs. Special thanks", + "to Bill Brown, Tom Ozanich, Brian", + "Celano, Jeff Eisner, and The Soundelux", "Players.", "", + "\"Level Music\" by Sonic Mayhem", "www.sonicmayhem.com", "", + "\"Quake II Theme Song\"", "(C) 1997 Rob Zombie. All Rights", + "Reserved.", "", "Track 10 (\"Climb\") by Jer Sypult", "", + "Voice of computers by", "Carly Staehlin-Taylor", "", + "+THANKS TO ACTIVISION", "+IN PARTICULAR:", "", "John Tam", + "Steve Rosenthal", "Marty Stratton", "Henk Hartong", "", + "Quake II(tm) (C)1997 Id Software, Inc.", + "All Rights Reserved. Distributed by", + "Activision, Inc. under license.", + "Quake II(tm), the Id Software name,", + "the \"Q II\"(tm) logo and id(tm)", + "logo are trademarks of Id Software,", + "Inc. Activision(R) is a registered", + "trademark of Activision, Inc. All", + "other trademarks and trade names are", + "properties of their respective owners.", null }; + + static String credits[] = idcredits; + + static String xatcredits[] = { "+QUAKE II MISSION PACK: THE RECKONING", + "+BY", "+XATRIX ENTERTAINMENT, INC.", "", "+DESIGN AND DIRECTION", + "Drew Markham", "", "+PRODUCED BY", "Greg Goodrich", "", + "+PROGRAMMING", "Rafael Paiz", "", + "+LEVEL DESIGN / ADDITIONAL GAME DESIGN", "Alex Mayberry", "", + "+LEVEL DESIGN", "Mal Blackwell", "Dan Koppel", "", + "+ART DIRECTION", "Michael \"Maxx\" Kaufman", "", + "+COMPUTER GRAPHICS SUPERVISOR AND", + "+CHARACTER ANIMATION DIRECTION", "Barry Dempsey", "", + "+SENIOR ANIMATOR AND MODELER", "Jason Hoover", "", + "+CHARACTER ANIMATION AND", "+MOTION CAPTURE SPECIALIST", + "Amit Doron", "", "+ART", "Claire Praderie-Markham", + "Viktor Antonov", "Corky Lehmkuhl", "", "+INTRODUCTION ANIMATION", + "Dominique Drozdz", "", "+ADDITIONAL LEVEL DESIGN", "Aaron Barber", + "Rhett Baldwin", "", "+3D CHARACTER ANIMATION TOOLS", + "Gerry Tyra, SA Technology", "", + "+ADDITIONAL EDITOR TOOL PROGRAMMING", "Robert Duffy", "", + "+ADDITIONAL PROGRAMMING", "Ryan Feltrin", "", + "+PRODUCTION COORDINATOR", "Victoria Sylvester", "", + "+SOUND DESIGN", "Gary Bradfield", "", "+MUSIC BY", "Sonic Mayhem", + "", "", "", "+SPECIAL THANKS", "+TO", + "+OUR FRIENDS AT ID SOFTWARE", "", "John Carmack", "John Cash", + "Brian Hook", "Adrian Carmack", "Kevin Cloud", "Paul Steed", + "Tim Willits", "Christian Antkow", "Paul Jaquays", "Brandon James", + "Todd Hollenshead", "Barrett (Bear) Alexander", + "Dave \"Zoid\" Kirsch", "Donna Jackson", "", "", "", + "+THANKS TO ACTIVISION", "+IN PARTICULAR:", "", "Marty Stratton", + "Henk \"The Original Ripper\" Hartong", "Kevin Kraff", + "Jamey Gottlieb", "Chris Hepburn", "", "+AND THE GAME TESTERS", "", + "Tim Vanlaw", "Doug Jacobs", "Steven Rosenthal", "David Baker", + "Chris Campbell", "Aaron Casillas", "Steve Elwell", + "Derek Johnstone", "Igor Krinitskiy", "Samantha Lee", + "Michael Spann", "Chris Toft", "Juan Valdes", "", + "+THANKS TO INTERGRAPH COMPUTER SYTEMS", "+IN PARTICULAR:", "", + "Michael T. Nicolaou", "", "", + "Quake II Mission Pack: The Reckoning", + "(tm) (C)1998 Id Software, Inc. All", + "Rights Reserved. Developed by Xatrix", + "Entertainment, Inc. for Id Software,", + "Inc. Distributed by Activision Inc.", + "under license. Quake(R) is a", + "registered trademark of Id Software,", + "Inc. Quake II Mission Pack: The", + "Reckoning(tm), Quake II(tm), the Id", + "Software name, the \"Q II\"(tm) logo", + "and id(tm) logo are trademarks of Id", + "Software, Inc. Activision(R) is a", + "registered trademark of Activision,", + "Inc. Xatrix(R) is a registered", + "trademark of Xatrix Entertainment,", + "Inc. All other trademarks and trade", + "names are properties of their", "respective owners.", null }; + + static String roguecredits[] = { "+QUAKE II MISSION PACK 2: GROUND ZERO", + "+BY", "+ROGUE ENTERTAINMENT, INC.", "", "+PRODUCED BY", + "Jim Molinets", "", "+PROGRAMMING", "Peter Mack", + "Patrick Magruder", "", "+LEVEL DESIGN", "Jim Molinets", + "Cameron Lamprecht", "Berenger Fish", "Robert Selitto", + "Steve Tietze", "Steve Thoms", "", "+ART DIRECTION", + "Rich Fleider", "", "+ART", "Rich Fleider", "Steve Maines", + "Won Choi", "", "+ANIMATION SEQUENCES", "Creat Studios", + "Steve Maines", "", "+ADDITIONAL LEVEL DESIGN", "Rich Fleider", + "Steve Maines", "Peter Mack", "", "+SOUND", "James Grunke", "", + "+GROUND ZERO THEME", "+AND", "+MUSIC BY", "Sonic Mayhem", "", + "+VWEP MODELS", "Brent \"Hentai\" Dill", "", "", "", + "+SPECIAL THANKS", "+TO", "+OUR FRIENDS AT ID SOFTWARE", "", + "John Carmack", "John Cash", "Brian Hook", "Adrian Carmack", + "Kevin Cloud", "Paul Steed", "Tim Willits", "Christian Antkow", + "Paul Jaquays", "Brandon James", "Todd Hollenshead", + "Barrett (Bear) Alexander", "Katherine Anna Kang", "Donna Jackson", + "Dave \"Zoid\" Kirsch", "", "", "", "+THANKS TO ACTIVISION", + "+IN PARTICULAR:", "", "Marty Stratton", "Henk Hartong", + "Mitch Lasky", "Steve Rosenthal", "Steve Elwell", "", + "+AND THE GAME TESTERS", "", "The Ranger Clan", + "Dave \"Zoid\" Kirsch", "Nihilistic Software", "Robert Duffy", "", + "And Countless Others", "", "", "", + "Quake II Mission Pack 2: Ground Zero", + "(tm) (C)1998 Id Software, Inc. All", + "Rights Reserved. Developed by Rogue", + "Entertainment, Inc. for Id Software,", + "Inc. Distributed by Activision Inc.", + "under license. Quake(R) is a", + "registered trademark of Id Software,", + "Inc. Quake II Mission Pack 2: Ground", + "Zero(tm), Quake II(tm), the Id", + "Software name, the \"Q II\"(tm) logo", + "and id(tm) logo are trademarks of Id", + "Software, Inc. Activision(R) is a", + "registered trademark of Activision,", + "Inc. Rogue(R) is a registered", + "trademark of Rogue Entertainment,", + "Inc. All other trademarks and trade", + "names are properties of their", "respective owners.", null }; + + public static void Credits_MenuDraw() { + int i, y; + + /* + * * draw the credits + */ + for (i = 0, y = (int) (viddef.height - ((cls.realtime - credits_start_time) / 40.0F)); credits[i] != null + && y < viddef.height; y += 10, i++) { + int j, stringoffset = 0; + boolean bold = false; + + if (y <= -8) + continue; + + if (credits[i].length() > 0 && credits[i].charAt(0) == '+') { + bold = true; + stringoffset = 1; + } else { + bold = false; + stringoffset = 0; + } + + for (j = 0; j + stringoffset < credits[i].length(); j++) { + int x; + + x = (viddef.width - credits[i].length() * 8 - stringoffset * 8) + / 2 + (j + stringoffset) * 8; + + if (bold) + re + .DrawChar(x, y, + credits[i].charAt(j + stringoffset) + 128); + else + re.DrawChar(x, y, credits[i].charAt(j + stringoffset)); + } + } + + if (y < 0) + credits_start_time = cls.realtime; + } + + public static String Credits_Key(int key) { + switch (key) { + case K_ESCAPE: + if (creditsBuffer != null) + //FS.FreeFile(creditsBuffer); + ; + PopMenu(); + break; + } + + return menu_out_sound; + + } + + static xcommand_t Menu_Credits = new xcommand_t() { + public void execute() { + Menu_Credits_f(); + } + }; + + static void Menu_Credits_f() { + int n; + int isdeveloper = 0; + + byte b[] = FS.LoadFile("credits"); + + if (b != null) { + creditsBuffer = new String(b); + String line[] = Lib.linesplit(creditsBuffer); + + for (n = 0; n < line.length; n++) { + creditsIndex[n] = line[n]; + } + + creditsIndex[n] = null; + credits = creditsIndex; + } else { + isdeveloper = FS.Developer_searchpath(1); + + if (isdeveloper == 1) // xatrix + credits = xatcredits; + else if (isdeveloper == 2) // ROGUE + credits = roguecredits; + else { + credits = idcredits; + } + + } + + credits_start_time = cls.realtime; + PushMenu(new xcommand_t() { + public void execute() { + Credits_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Credits_Key(key); + } + }); + } + + /* + * ============================================================================= + * + * GAME MENU + * + * ============================================================================= + */ + + static int m_game_cursor; + + static menuframework_s s_game_menu = new menuframework_s(); + + static menuaction_s s_easy_game_action = new menuaction_s(); + + static menuaction_s s_medium_game_action = new menuaction_s(); + + static menuaction_s s_hard_game_action = new menuaction_s(); + + static menuaction_s s_load_game_action = new menuaction_s(); + + static menuaction_s s_save_game_action = new menuaction_s(); + + static menuaction_s s_credits_action = new menuaction_s(); + + static menuseparator_s s_blankline = new menuseparator_s(); + + static void StartGame() { + // disable updates and start the cinematic going + cl.servercount = -1; + ForceMenuOff(); + Cvar.SetValue("deathmatch", 0); + Cvar.SetValue("coop", 0); + + Cvar.SetValue("gamerules", 0); //PGM + + Cbuf.AddText("loading ; killserver ; wait ; newgame\n"); + cls.key_dest = key_game; + } + + static void EasyGameFunc(Object data) { + Cvar.ForceSet("skill", "0"); + StartGame(); + } + + static void MediumGameFunc(Object data) { + Cvar.ForceSet("skill", "1"); + StartGame(); + } + + static void HardGameFunc(Object data) { + Cvar.ForceSet("skill", "2"); + StartGame(); + } + + static void LoadGameFunc(Object unused) { + Menu_LoadGame_f(); + } + + static void SaveGameFunc(Object unused) { + Menu_SaveGame_f(); + } + + static void CreditsFunc(Object unused) { + Menu_Credits_f(); + } + + static String difficulty_names[] = { "easy", "medium", + "fuckin shitty hard", null }; + + static void Game_MenuInit() { + + s_game_menu.x = (int) (viddef.width * 0.50); + s_game_menu.nitems = 0; + + s_easy_game_action.type = MTYPE_ACTION; + s_easy_game_action.flags = QMF_LEFT_JUSTIFY; + s_easy_game_action.x = 0; + s_easy_game_action.y = 0; + s_easy_game_action.name = "easy"; + s_easy_game_action.callback = new mcallback() { + public void execute(Object o) { + EasyGameFunc(o); + } + }; + + s_medium_game_action.type = MTYPE_ACTION; + s_medium_game_action.flags = QMF_LEFT_JUSTIFY; + s_medium_game_action.x = 0; + s_medium_game_action.y = 10; + s_medium_game_action.name = "medium"; + s_medium_game_action.callback = new mcallback() { + public void execute(Object o) { + MediumGameFunc(o); + } + }; + + s_hard_game_action.type = MTYPE_ACTION; + s_hard_game_action.flags = QMF_LEFT_JUSTIFY; + s_hard_game_action.x = 0; + s_hard_game_action.y = 20; + s_hard_game_action.name = "hard"; + s_hard_game_action.callback = new mcallback() { + public void execute(Object o) { + HardGameFunc(o); + } + }; + + s_blankline.type = MTYPE_SEPARATOR; + + s_load_game_action.type = MTYPE_ACTION; + s_load_game_action.flags = QMF_LEFT_JUSTIFY; + s_load_game_action.x = 0; + s_load_game_action.y = 40; + s_load_game_action.name = "load game"; + s_load_game_action.callback = new mcallback() { + public void execute(Object o) { + LoadGameFunc(o); + } + }; + + s_save_game_action.type = MTYPE_ACTION; + s_save_game_action.flags = QMF_LEFT_JUSTIFY; + s_save_game_action.x = 0; + s_save_game_action.y = 50; + s_save_game_action.name = "save game"; + s_save_game_action.callback = new mcallback() { + public void execute(Object o) { + SaveGameFunc(o); + } + }; + + s_credits_action.type = MTYPE_ACTION; + s_credits_action.flags = QMF_LEFT_JUSTIFY; + s_credits_action.x = 0; + s_credits_action.y = 60; + s_credits_action.name = "credits"; + s_credits_action.callback = new mcallback() { + public void execute(Object o) { + CreditsFunc(o); + } + }; + + Menu_AddItem(s_game_menu, s_easy_game_action); + Menu_AddItem(s_game_menu, s_medium_game_action); + Menu_AddItem(s_game_menu, s_hard_game_action); + Menu_AddItem(s_game_menu, s_blankline); + Menu_AddItem(s_game_menu, s_load_game_action); + Menu_AddItem(s_game_menu, s_save_game_action); + Menu_AddItem(s_game_menu, s_blankline); + Menu_AddItem(s_game_menu, s_credits_action); + + Menu_Center(s_game_menu); + } + + static void Game_MenuDraw() { + Banner("m_banner_game"); + Menu_AdjustCursor(s_game_menu, 1); + Menu_Draw(s_game_menu); + } + + static String Game_MenuKey(int key) { + return Default_MenuKey(s_game_menu, key); + } + + static xcommand_t Menu_Game = new xcommand_t() { + public void execute() { + Menu_Game_f(); + } + }; + + static void Menu_Game_f() { + Game_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + Game_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Game_MenuKey(key); + } + }); + m_game_cursor = 1; + } + + /* + * ============================================================================= + * + * LOADGAME MENU + * + * ============================================================================= + */ + + public final static int MAX_SAVEGAMES = 15; + + static menuframework_s s_savegame_menu = new menuframework_s(); + + static menuframework_s s_loadgame_menu = new menuframework_s(); + + static menuaction_s s_loadgame_actions[] = new menuaction_s[MAX_SAVEGAMES]; + + static { + for (int n = 0; n < MAX_SAVEGAMES; n++) + s_loadgame_actions[n] = new menuaction_s(); + } + + //String m_savestrings[] = new String [MAX_SAVEGAMES][32]; + static String m_savestrings[] = new String[MAX_SAVEGAMES]; + + static { + for (int n = 0; n < MAX_SAVEGAMES; n++) + m_savestrings[n] = ""; + } + + static boolean m_savevalid[] = new boolean[MAX_SAVEGAMES]; + + /** Search the save dir for saved games and their names. */ + static void Create_Savestrings() { + int i; + QuakeFile f; + String name; + + for (i = 0; i < MAX_SAVEGAMES; i++) { + + m_savestrings[i] = "<EMPTY>"; + name = FS.Gamedir() + "/save/save" + i + "/server.ssv"; + + try { + f = new QuakeFile(name, "r"); + if (f == null) { + m_savestrings[i] = "<EMPTY>"; + m_savevalid[i] = false; + } else { + String str = f.readString(); + if (str != null) + m_savestrings[i] = str; + f.close(); + m_savevalid[i] = true; + } + } catch (Exception e) { + m_savestrings[i] = "<EMPTY>"; + m_savevalid[i] = false; + } + ; + } + } + + static void LoadGameCallback(Object self) { + menuaction_s a = (menuaction_s) self; + + if (m_savevalid[a.localdata[0]]) + Cbuf.AddText("load save" + a.localdata[0] + "\n"); + ForceMenuOff(); + } + + static void LoadGame_MenuInit() { + int i; + + s_loadgame_menu.x = viddef.width / 2 - 120; + s_loadgame_menu.y = viddef.height / 2 - 58; + s_loadgame_menu.nitems = 0; + + Create_Savestrings(); + + for (i = 0; i < MAX_SAVEGAMES; i++) { + s_loadgame_actions[i].name = m_savestrings[i]; + s_loadgame_actions[i].flags = QMF_LEFT_JUSTIFY; + s_loadgame_actions[i].localdata[0] = i; + s_loadgame_actions[i].callback = new mcallback() { + public void execute(Object o) { + LoadGameCallback(o); + } + }; + + s_loadgame_actions[i].x = 0; + s_loadgame_actions[i].y = (i) * 10; + if (i > 0) // separate from autosave + s_loadgame_actions[i].y += 10; + + s_loadgame_actions[i].type = MTYPE_ACTION; + + Menu_AddItem(s_loadgame_menu, s_loadgame_actions[i]); + } + } + + static void LoadGame_MenuDraw() { + Banner("m_banner_load_game"); + // Menu_AdjustCursor( &s_loadgame_menu, 1 ); + Menu_Draw(s_loadgame_menu); + } + + static String LoadGame_MenuKey(int key) { + if (key == K_ESCAPE || key == K_ENTER) { + s_savegame_menu.cursor = s_loadgame_menu.cursor - 1; + if (s_savegame_menu.cursor < 0) + s_savegame_menu.cursor = 0; + } + return Default_MenuKey(s_loadgame_menu, key); + } + + static xcommand_t Menu_LoadGame = new xcommand_t() { + public void execute() { + Menu_LoadGame_f(); + } + }; + + static void Menu_LoadGame_f() { + LoadGame_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + LoadGame_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return LoadGame_MenuKey(key); + } + }); + } + + /* + * ============================================================================= + * + * SAVEGAME MENU + * + * ============================================================================= + */ + //static menuframework_s s_savegame_menu; + static menuaction_s s_savegame_actions[] = new menuaction_s[MAX_SAVEGAMES]; + + static { + for (int n = 0; n < MAX_SAVEGAMES; n++) + s_savegame_actions[n] = new menuaction_s(); + + } + + static void SaveGameCallback(Object self) { + menuaction_s a = (menuaction_s) self; + + Cbuf.AddText("save save" + a.localdata[0] + "\n"); + ForceMenuOff(); + } + + static void SaveGame_MenuDraw() { + Banner("m_banner_save_game"); + Menu_AdjustCursor(s_savegame_menu, 1); + Menu_Draw(s_savegame_menu); + } + + static void SaveGame_MenuInit() { + int i; + + s_savegame_menu.x = viddef.width / 2 - 120; + s_savegame_menu.y = viddef.height / 2 - 58; + s_savegame_menu.nitems = 0; + + Create_Savestrings(); + + // don't include the autosave slot + for (i = 0; i < MAX_SAVEGAMES - 1; i++) { + s_savegame_actions[i].name = m_savestrings[i + 1]; + s_savegame_actions[i].localdata[0] = i + 1; + s_savegame_actions[i].flags = QMF_LEFT_JUSTIFY; + s_savegame_actions[i].callback = new mcallback() { + public void execute(Object o) { + SaveGameCallback(o); + } + }; + + s_savegame_actions[i].x = 0; + s_savegame_actions[i].y = (i) * 10; + + s_savegame_actions[i].type = MTYPE_ACTION; + + Menu_AddItem(s_savegame_menu, s_savegame_actions[i]); + } + } + + static String SaveGame_MenuKey(int key) { + if (key == K_ENTER || key == K_ESCAPE) { + s_loadgame_menu.cursor = s_savegame_menu.cursor - 1; + if (s_loadgame_menu.cursor < 0) + s_loadgame_menu.cursor = 0; + } + return Default_MenuKey(s_savegame_menu, key); + } + + static xcommand_t Menu_SaveGame = new xcommand_t() { + public void execute() { + Menu_SaveGame_f(); + } + }; + + static void Menu_SaveGame_f() { + if (0 == Globals.server_state) + return; // not playing a game + + SaveGame_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + SaveGame_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return SaveGame_MenuKey(key); + } + }); + Create_Savestrings(); + } + + /* + * ============================================================================= + * + * JOIN SERVER MENU + * + * ============================================================================= + */ + + static menuframework_s s_joinserver_menu = new menuframework_s(); + + static menuseparator_s s_joinserver_server_title = new menuseparator_s(); + + static menuaction_s s_joinserver_search_action = new menuaction_s(); + + static menuaction_s s_joinserver_address_book_action = new menuaction_s(); + + static netadr_t local_server_netadr[] = new netadr_t[MAX_LOCAL_SERVERS]; + + static String local_server_names[] = new String[MAX_LOCAL_SERVERS]; //[80]; + + static menuaction_s s_joinserver_server_actions[] = new menuaction_s[MAX_LOCAL_SERVERS]; + + // user readable information + // network address + static { + for (int n = 0; n < MAX_LOCAL_SERVERS; n++) { + local_server_netadr[n] = new netadr_t(); + local_server_names[n] = ""; + s_joinserver_server_actions[n] = new menuaction_s(); + s_joinserver_server_actions[n].n = n; + } + } + + static int m_num_servers; + + static void AddToServerList(netadr_t adr, String info) { + int i; + + if (m_num_servers == MAX_LOCAL_SERVERS) + return; + + String x = info.trim(); + + // ignore if duplicated + + for (i = 0; i < m_num_servers; i++) + if (x.equals(local_server_names[i])) + return; + + local_server_netadr[m_num_servers] = adr; + local_server_names[m_num_servers] = x; + m_num_servers++; + } + + static void JoinServerFunc(Object self) { + String buffer; + int index; + + index = ((menucommon_s) self).n; + + if (Lib.Q_stricmp(local_server_names[index], NO_SERVER_STRING) == 0) + return; + + if (index >= m_num_servers) + return; + + buffer = "connect " + NET.AdrToString(local_server_netadr[index]) + + "\n"; + Cbuf.AddText(buffer); + ForceMenuOff(); + } + + static void AddressBookFunc(Object self) { + Menu_AddressBook_f(); + } + + static void NullCursorDraw(Object self) { + } + + static void SearchLocalGames() { + int i; + + m_num_servers = 0; + for (i = 0; i < MAX_LOCAL_SERVERS; i++) + local_server_names[i] = NO_SERVER_STRING; + + DrawTextBox(8, 120 - 48, 36, 3); + Print(16 + 16, 120 - 48 + 8, "Searching for local servers, this"); + Print(16 + 16, 120 - 48 + 16, "could take up to a minute, so"); + Print(16 + 16, 120 - 48 + 24, "please be patient."); + + // the text box won't show up unless we do a buffer swap + re.EndFrame(); + + // send out info packets + CL.PingServers_f.execute(); + } + + static void SearchLocalGamesFunc(Object self) { + SearchLocalGames(); + } + + static void JoinServer_MenuInit() { + int i; + + s_joinserver_menu.x = (int) (viddef.width * 0.50 - 120); + s_joinserver_menu.nitems = 0; + + s_joinserver_address_book_action.type = MTYPE_ACTION; + s_joinserver_address_book_action.name = "address book"; + s_joinserver_address_book_action.flags = QMF_LEFT_JUSTIFY; + s_joinserver_address_book_action.x = 0; + s_joinserver_address_book_action.y = 0; + s_joinserver_address_book_action.callback = new mcallback() { + public void execute(Object o) { + AddressBookFunc(o); + } + }; + + s_joinserver_search_action.type = MTYPE_ACTION; + s_joinserver_search_action.name = "refresh server list"; + s_joinserver_search_action.flags = QMF_LEFT_JUSTIFY; + s_joinserver_search_action.x = 0; + s_joinserver_search_action.y = 10; + s_joinserver_search_action.callback = new mcallback() { + public void execute(Object o) { + SearchLocalGamesFunc(o); + } + }; + s_joinserver_search_action.statusbar = "search for servers"; + + s_joinserver_server_title.type = MTYPE_SEPARATOR; + s_joinserver_server_title.name = "connect to..."; + s_joinserver_server_title.x = 80; + s_joinserver_server_title.y = 30; + + for (i = 0; i < MAX_LOCAL_SERVERS; i++) { + s_joinserver_server_actions[i].type = MTYPE_ACTION; + local_server_names[i] = NO_SERVER_STRING; + s_joinserver_server_actions[i].name = local_server_names[i]; + s_joinserver_server_actions[i].flags = QMF_LEFT_JUSTIFY; + s_joinserver_server_actions[i].x = 0; + s_joinserver_server_actions[i].y = 40 + i * 10; + s_joinserver_server_actions[i].callback = new mcallback() { + public void execute(Object o) { + JoinServerFunc(o); + } + }; + s_joinserver_server_actions[i].statusbar = "press ENTER to connect"; + } + + Menu_AddItem(s_joinserver_menu, s_joinserver_address_book_action); + Menu_AddItem(s_joinserver_menu, s_joinserver_server_title); + Menu_AddItem(s_joinserver_menu, s_joinserver_search_action); + + for (i = 0; i < 8; i++) + Menu_AddItem(s_joinserver_menu, s_joinserver_server_actions[i]); + + Menu_Center(s_joinserver_menu); + + SearchLocalGames(); + } + + static void JoinServer_MenuDraw() { + Banner("m_banner_join_server"); + Menu_Draw(s_joinserver_menu); + } + + static String JoinServer_MenuKey(int key) { + return Default_MenuKey(s_joinserver_menu, key); + } + + static xcommand_t Menu_JoinServer = new xcommand_t() { + public void execute() { + Menu_JoinServer_f(); + } + }; + + static void Menu_JoinServer_f() { + JoinServer_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + JoinServer_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return JoinServer_MenuKey(key); + } + }); + } + + /* + * ============================================================================= + * + * START SERVER MENU + * + * ============================================================================= + */ + static menuframework_s s_startserver_menu = new menuframework_s(); + + static String mapnames[]; + + static int nummaps; + + static menuaction_s s_startserver_start_action = new menuaction_s(); + + static menuaction_s s_startserver_dmoptions_action = new menuaction_s(); + + static menufield_s s_timelimit_field = new menufield_s(); + + static menufield_s s_fraglimit_field = new menufield_s(); + + static menufield_s s_maxclients_field = new menufield_s(); + + static menufield_s s_hostname_field = new menufield_s(); + + static menulist_s s_startmap_list = new menulist_s(); + + static menulist_s s_rules_box = new menulist_s(); + + static void DMOptionsFunc(Object self) { + if (s_rules_box.curvalue == 1) + return; + Menu_DMOptions_f(); + } + + static void RulesChangeFunc(Object self) { + // DM + if (s_rules_box.curvalue == 0) { + s_maxclients_field.statusbar = null; + s_startserver_dmoptions_action.statusbar = null; + } else if (s_rules_box.curvalue == 1) + // coop // PGM + { + s_maxclients_field.statusbar = "4 maximum for cooperative"; + if (Lib.atoi(s_maxclients_field.buffer.toString()) > 4) + s_maxclients_field.buffer = new StringBuffer("4"); + s_startserver_dmoptions_action.statusbar = "N/A for cooperative"; + } + // ===== + // PGM + // ROGUE GAMES + else if (FS.Developer_searchpath(2) == 2) { + if (s_rules_box.curvalue == 2) // tag + { + s_maxclients_field.statusbar = null; + s_startserver_dmoptions_action.statusbar = null; + } + /* + * else if(s_rules_box.curvalue == 3) // deathball { + * s_maxclients_field.statusbar = null; + * s_startserver_dmoptions_action.statusbar = null; } + */ + } + // PGM + // ===== + } + + static void StartServerActionFunc(Object self) { + //char startmap[1024]; + String startmap; + int timelimit; + int fraglimit; + int maxclients; + String spot; + + //strcpy(startmap, strchr(mapnames[s_startmap_list.curvalue], '\n') + + // 1); + String x = mapnames[s_startmap_list.curvalue]; + + int pos = x.indexOf('\n'); + if (pos == -1) + startmap = x; + else + startmap = x.substring(pos + 1, x.length()); + + maxclients = Lib.atoi(s_maxclients_field.buffer.toString()); + timelimit = Lib.atoi(s_timelimit_field.buffer.toString()); + fraglimit = Lib.atoi(s_fraglimit_field.buffer.toString()); + + Cvar.SetValue("maxclients", ClampCvar(0, maxclients, maxclients)); + Cvar.SetValue("timelimit", ClampCvar(0, timelimit, timelimit)); + Cvar.SetValue("fraglimit", ClampCvar(0, fraglimit, fraglimit)); + Cvar.Set("hostname", s_hostname_field.buffer.toString()); + // Cvar.SetValue ("deathmatch", !s_rules_box.curvalue ); + // Cvar.SetValue ("coop", s_rules_box.curvalue ); + + // PGM + if ((s_rules_box.curvalue < 2) || (FS.Developer_searchpath(2) != 2)) { + Cvar.SetValue("deathmatch", 1 - (int) (s_rules_box.curvalue)); + Cvar.SetValue("coop", s_rules_box.curvalue); + Cvar.SetValue("gamerules", 0); + } else { + Cvar.SetValue("deathmatch", 1); + // deathmatch is always true for rogue games, right? + Cvar.SetValue("coop", 0); + // FIXME - this might need to depend on which game we're running + Cvar.SetValue("gamerules", s_rules_box.curvalue); + } + // PGM + + spot = null; + if (s_rules_box.curvalue == 1) // PGM + { + if (Lib.Q_stricmp(startmap, "bunk1") == 0) + spot = "start"; + else if (Lib.Q_stricmp(startmap, "mintro") == 0) + spot = "start"; + else if (Lib.Q_stricmp(startmap, "fact1") == 0) + spot = "start"; + else if (Lib.Q_stricmp(startmap, "power1") == 0) + spot = "pstart"; + else if (Lib.Q_stricmp(startmap, "biggun") == 0) + spot = "bstart"; + else if (Lib.Q_stricmp(startmap, "hangar1") == 0) + spot = "unitstart"; + else if (Lib.Q_stricmp(startmap, "city1") == 0) + spot = "unitstart"; + else if (Lib.Q_stricmp(startmap, "boss1") == 0) + spot = "bosstart"; + } + + if (spot != null) { + if (Globals.server_state != 0) + Cbuf.AddText("disconnect\n"); + Cbuf.AddText("gamemap \"*" + startmap + "$" + spot + "\"\n"); + } else { + Cbuf.AddText("map " + startmap + "\n"); + } + + ForceMenuOff(); + } + + static String dm_coop_names[] = { "deathmatch", "cooperative", null }; + + static String dm_coop_names_rogue[] = { "deathmatch", "cooperative", "tag", + // "deathball", + null }; + + static void StartServer_MenuInit() { + + // ======= + // PGM + // ======= + + byte[] buffer = null; + String mapsname; + String s; + int i; + RandomAccessFile fp; + + /* + * * load the list of map names + */ + mapsname = FS.Gamedir() + "/maps.lst"; + + if ((fp = Lib.fopen(mapsname, "r")) == null) { + buffer = FS.LoadFile("maps.lst"); + if (buffer == null) + //if ((length = FS_LoadFile("maps.lst", (Object *) & buffer)) + // == -1) + Com.Error(ERR_DROP, "couldn't find maps.lst\n"); + } else { + try { + int len = (int) fp.length(); + buffer = new byte[len]; + fp.readFully(buffer); + } catch (Exception e) { + Com.Error(ERR_DROP, "couldn't load maps.lst\n"); + } + } + + s = new String(buffer); + String lines[] = Lib.linesplit(s); + + nummaps = lines.length; + + if (nummaps == 0) + Com.Error(ERR_DROP, "no maps in maps.lst\n"); + + mapnames = new String[nummaps + 1]; + + for (i = 0; i < nummaps; i++) { + String shortname, longname, scratch; + + Com.ParseHelp ph = new Com.ParseHelp(lines[i]); + + shortname = Com.Parse(ph).toUpperCase(); + longname = Com.Parse(ph); + scratch = longname + "\n" + shortname; + mapnames[i] = scratch; + } + mapnames[nummaps] = null; + + if (fp != null) { + Lib.fclose(fp); + fp = null; + + } else { + FS.FreeFile(buffer); + } + + /* + * * initialize the menu stuff + */ + s_startserver_menu.x = (int) (viddef.width * 0.50); + s_startserver_menu.nitems = 0; + + s_startmap_list.type = MTYPE_SPINCONTROL; + s_startmap_list.x = 0; + s_startmap_list.y = 0; + s_startmap_list.name = "initial map"; + s_startmap_list.itemnames = mapnames; + + s_rules_box.type = MTYPE_SPINCONTROL; + s_rules_box.x = 0; + s_rules_box.y = 20; + s_rules_box.name = "rules"; + + // PGM - rogue games only available with rogue DLL. + if (FS.Developer_searchpath(2) == 2) + s_rules_box.itemnames = dm_coop_names_rogue; + else + s_rules_box.itemnames = dm_coop_names; + // PGM + + if (Cvar.VariableValue("coop") != 0) + s_rules_box.curvalue = 1; + else + s_rules_box.curvalue = 0; + s_rules_box.callback = new mcallback() { + public void execute(Object o) { + RulesChangeFunc(o); + } + }; + + s_timelimit_field.type = MTYPE_FIELD; + s_timelimit_field.name = "time limit"; + s_timelimit_field.flags = QMF_NUMBERSONLY; + s_timelimit_field.x = 0; + s_timelimit_field.y = 36; + s_timelimit_field.statusbar = "0 = no limit"; + s_timelimit_field.length = 3; + s_timelimit_field.visible_length = 3; + s_timelimit_field.buffer = new StringBuffer(Cvar + .VariableString("timelimit")); + + s_fraglimit_field.type = MTYPE_FIELD; + s_fraglimit_field.name = "frag limit"; + s_fraglimit_field.flags = QMF_NUMBERSONLY; + s_fraglimit_field.x = 0; + s_fraglimit_field.y = 54; + s_fraglimit_field.statusbar = "0 = no limit"; + s_fraglimit_field.length = 3; + s_fraglimit_field.visible_length = 3; + s_fraglimit_field.buffer = new StringBuffer(Cvar + .VariableString("fraglimit")); + + /* + * * maxclients determines the maximum number of players that can join * + * the game. If maxclients is only "1" then we should default the menu * + * option to 8 players, otherwise use whatever its current value is. * + * Clamping will be done when the server is actually started. + */ + s_maxclients_field.type = MTYPE_FIELD; + s_maxclients_field.name = "max players"; + s_maxclients_field.flags = QMF_NUMBERSONLY; + s_maxclients_field.x = 0; + s_maxclients_field.y = 72; + s_maxclients_field.statusbar = null; + s_maxclients_field.length = 3; + s_maxclients_field.visible_length = 3; + if (Cvar.VariableValue("maxclients") == 1) + s_maxclients_field.buffer = new StringBuffer("8"); + else + s_maxclients_field.buffer = new StringBuffer(Cvar + .VariableString("maxclients")); + + s_hostname_field.type = MTYPE_FIELD; + s_hostname_field.name = "hostname"; + s_hostname_field.flags = 0; + s_hostname_field.x = 0; + s_hostname_field.y = 90; + s_hostname_field.statusbar = null; + s_hostname_field.length = 12; + s_hostname_field.visible_length = 12; + s_hostname_field.buffer = new StringBuffer(Cvar + .VariableString("hostname")); + s_hostname_field.cursor = s_hostname_field.buffer.length(); + + s_startserver_dmoptions_action.type = MTYPE_ACTION; + s_startserver_dmoptions_action.name = " deathmatch flags"; + s_startserver_dmoptions_action.flags = QMF_LEFT_JUSTIFY; + s_startserver_dmoptions_action.x = 24; + s_startserver_dmoptions_action.y = 108; + s_startserver_dmoptions_action.statusbar = null; + s_startserver_dmoptions_action.callback = new mcallback() { + public void execute(Object o) { + DMOptionsFunc(o); + } + }; + + s_startserver_start_action.type = MTYPE_ACTION; + s_startserver_start_action.name = " begin"; + s_startserver_start_action.flags = QMF_LEFT_JUSTIFY; + s_startserver_start_action.x = 24; + s_startserver_start_action.y = 128; + s_startserver_start_action.callback = new mcallback() { + public void execute(Object o) { + StartServerActionFunc(o); + } + }; + + Menu_AddItem(s_startserver_menu, s_startmap_list); + Menu_AddItem(s_startserver_menu, s_rules_box); + Menu_AddItem(s_startserver_menu, s_timelimit_field); + Menu_AddItem(s_startserver_menu, s_fraglimit_field); + Menu_AddItem(s_startserver_menu, s_maxclients_field); + Menu_AddItem(s_startserver_menu, s_hostname_field); + Menu_AddItem(s_startserver_menu, s_startserver_dmoptions_action); + Menu_AddItem(s_startserver_menu, s_startserver_start_action); + + Menu_Center(s_startserver_menu); + + // call this now to set proper inital state + RulesChangeFunc(null); + } + + static void StartServer_MenuDraw() { + Menu_Draw(s_startserver_menu); + } + + static String StartServer_MenuKey(int key) { + if (key == K_ESCAPE) { + if (mapnames != null) { + int i; + + for (i = 0; i < nummaps; i++) + mapnames[i] = null; + + } + mapnames = null; + nummaps = 0; + } + + return Default_MenuKey(s_startserver_menu, key); + } + + static xcommand_t Menu_StartServer = new xcommand_t() { + public void execute() { + Menu_StartServer_f(); + } + }; + + static void Menu_StartServer_f() { + StartServer_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + StartServer_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return StartServer_MenuKey(key); + } + }); + } + + /* + * ============================================================================= + * + * DMOPTIONS BOOK MENU + * + * ============================================================================= + */ + static String dmoptions_statusbar; //[128]; + + static menuframework_s s_dmoptions_menu = new menuframework_s(); + + static menulist_s s_friendlyfire_box = new menulist_s(); + + static menulist_s s_falls_box = new menulist_s(); + + static menulist_s s_weapons_stay_box = new menulist_s(); + + static menulist_s s_instant_powerups_box = new menulist_s(); + + static menulist_s s_powerups_box = new menulist_s(); + + static menulist_s s_health_box = new menulist_s(); + + static menulist_s s_spawn_farthest_box = new menulist_s(); + + static menulist_s s_teamplay_box = new menulist_s(); + + static menulist_s s_samelevel_box = new menulist_s(); + + static menulist_s s_force_respawn_box = new menulist_s(); + + static menulist_s s_armor_box = new menulist_s(); + + static menulist_s s_allow_exit_box = new menulist_s(); + + static menulist_s s_infinite_ammo_box = new menulist_s(); + + static menulist_s s_fixed_fov_box = new menulist_s(); + + static menulist_s s_quad_drop_box = new menulist_s(); + + // ROGUE + static menulist_s s_no_mines_box = new menulist_s(); + + static menulist_s s_no_nukes_box = new menulist_s(); + + static menulist_s s_stack_double_box = new menulist_s(); + + static menulist_s s_no_spheres_box = new menulist_s(); + + // ROGUE + + static void setvalue(int flags) { + Cvar.SetValue("dmflags", flags); + dmoptions_statusbar = "dmflags = " + flags; + } + + static void DMFlagCallback(Object self) { + menulist_s f = (menulist_s) self; + int flags; + int bit = 0; + + flags = (int) Cvar.VariableValue("dmflags"); + + if (f == s_friendlyfire_box) { + if (f.curvalue != 0) + flags &= ~DF_NO_FRIENDLY_FIRE; + else + flags |= DF_NO_FRIENDLY_FIRE; + setvalue(flags); + return; + } else if (f == s_falls_box) { + if (f.curvalue != 0) + flags &= ~DF_NO_FALLING; + else + flags |= DF_NO_FALLING; + setvalue(flags); + return; + } else if (f == s_weapons_stay_box) { + bit = DF_WEAPONS_STAY; + } else if (f == s_instant_powerups_box) { + bit = DF_INSTANT_ITEMS; + } else if (f == s_allow_exit_box) { + bit = DF_ALLOW_EXIT; + } else if (f == s_powerups_box) { + if (f.curvalue != 0) + flags &= ~DF_NO_ITEMS; + else + flags |= DF_NO_ITEMS; + setvalue(flags); + return; + } else if (f == s_health_box) { + if (f.curvalue != 0) + flags &= ~DF_NO_HEALTH; + else + flags |= DF_NO_HEALTH; + setvalue(flags); + return; + } else if (f == s_spawn_farthest_box) { + bit = DF_SPAWN_FARTHEST; + } else if (f == s_teamplay_box) { + if (f.curvalue == 1) { + flags |= DF_SKINTEAMS; + flags &= ~DF_MODELTEAMS; + } else if (f.curvalue == 2) { + flags |= DF_MODELTEAMS; + flags &= ~DF_SKINTEAMS; + } else { + flags &= ~(DF_MODELTEAMS | DF_SKINTEAMS); + } + + setvalue(flags); + return; + } else if (f == s_samelevel_box) { + bit = DF_SAME_LEVEL; + } else if (f == s_force_respawn_box) { + bit = DF_FORCE_RESPAWN; + } else if (f == s_armor_box) { + if (f.curvalue != 0) + flags &= ~DF_NO_ARMOR; + else + flags |= DF_NO_ARMOR; + setvalue(flags); + return; + } else if (f == s_infinite_ammo_box) { + bit = DF_INFINITE_AMMO; + } else if (f == s_fixed_fov_box) { + bit = DF_FIXED_FOV; + } else if (f == s_quad_drop_box) { + bit = DF_QUAD_DROP; + } + + // ======= + // ROGUE + else if (FS.Developer_searchpath(2) == 2) { + if (f == s_no_mines_box) { + bit = DF_NO_MINES; + } else if (f == s_no_nukes_box) { + bit = DF_NO_NUKES; + } else if (f == s_stack_double_box) { + bit = DF_NO_STACK_DOUBLE; + } else if (f == s_no_spheres_box) { + bit = DF_NO_SPHERES; + } + } + // ROGUE + // ======= + + if (f != null) { + if (f.curvalue == 0) + flags &= ~bit; + else + flags |= bit; + } + + Cvar.SetValue("dmflags", flags); + + dmoptions_statusbar = "dmflags = " + flags; + + } + + //static String yes_no_names[] = { "no", "yes", 0 }; + static String teamplay_names[] = { "disabled", "by skin", "by model", null }; + + static void DMOptions_MenuInit() { + + int dmflags = (int) Cvar.VariableValue("dmflags"); + int y = 0; + + s_dmoptions_menu.x = (int) (viddef.width * 0.50); + s_dmoptions_menu.nitems = 0; + + s_falls_box.type = MTYPE_SPINCONTROL; + s_falls_box.x = 0; + s_falls_box.y = y; + s_falls_box.name = "falling damage"; + s_falls_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_falls_box.itemnames = yes_no_names; + s_falls_box.curvalue = (dmflags & DF_NO_FALLING) == 0 ? 1 : 0; + + s_weapons_stay_box.type = MTYPE_SPINCONTROL; + s_weapons_stay_box.x = 0; + s_weapons_stay_box.y = y += 10; + s_weapons_stay_box.name = "weapons stay"; + s_weapons_stay_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_weapons_stay_box.itemnames = yes_no_names; + s_weapons_stay_box.curvalue = (dmflags & DF_WEAPONS_STAY) != 0 ? 1 : 0; + + s_instant_powerups_box.type = MTYPE_SPINCONTROL; + s_instant_powerups_box.x = 0; + s_instant_powerups_box.y = y += 10; + s_instant_powerups_box.name = "instant powerups"; + s_instant_powerups_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_instant_powerups_box.itemnames = yes_no_names; + s_instant_powerups_box.curvalue = (dmflags & DF_INSTANT_ITEMS) != 0 ? 1 + : 0; + + s_powerups_box.type = MTYPE_SPINCONTROL; + s_powerups_box.x = 0; + s_powerups_box.y = y += 10; + s_powerups_box.name = "allow powerups"; + s_powerups_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_powerups_box.itemnames = yes_no_names; + s_powerups_box.curvalue = (dmflags & DF_NO_ITEMS) == 0 ? 1 : 0; + + s_health_box.type = MTYPE_SPINCONTROL; + s_health_box.x = 0; + s_health_box.y = y += 10; + s_health_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_health_box.name = "allow health"; + s_health_box.itemnames = yes_no_names; + s_health_box.curvalue = (dmflags & DF_NO_HEALTH) == 0 ? 1 : 0; + + s_armor_box.type = MTYPE_SPINCONTROL; + s_armor_box.x = 0; + s_armor_box.y = y += 10; + s_armor_box.name = "allow armor"; + s_armor_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_armor_box.itemnames = yes_no_names; + s_armor_box.curvalue = (dmflags & DF_NO_ARMOR) == 0 ? 1 : 0; + + s_spawn_farthest_box.type = MTYPE_SPINCONTROL; + s_spawn_farthest_box.x = 0; + s_spawn_farthest_box.y = y += 10; + s_spawn_farthest_box.name = "spawn farthest"; + s_spawn_farthest_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_spawn_farthest_box.itemnames = yes_no_names; + s_spawn_farthest_box.curvalue = (dmflags & DF_SPAWN_FARTHEST) != 0 ? 1 + : 0; + + s_samelevel_box.type = MTYPE_SPINCONTROL; + s_samelevel_box.x = 0; + s_samelevel_box.y = y += 10; + s_samelevel_box.name = "same map"; + s_samelevel_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_samelevel_box.itemnames = yes_no_names; + s_samelevel_box.curvalue = (dmflags & DF_SAME_LEVEL) != 0 ? 1 : 0; + + s_force_respawn_box.type = MTYPE_SPINCONTROL; + s_force_respawn_box.x = 0; + s_force_respawn_box.y = y += 10; + s_force_respawn_box.name = "force respawn"; + s_force_respawn_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_force_respawn_box.itemnames = yes_no_names; + s_force_respawn_box.curvalue = (dmflags & DF_FORCE_RESPAWN) != 0 ? 1 + : 0; + + s_teamplay_box.type = MTYPE_SPINCONTROL; + s_teamplay_box.x = 0; + s_teamplay_box.y = y += 10; + s_teamplay_box.name = "teamplay"; + s_teamplay_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_teamplay_box.itemnames = teamplay_names; + + s_allow_exit_box.type = MTYPE_SPINCONTROL; + s_allow_exit_box.x = 0; + s_allow_exit_box.y = y += 10; + s_allow_exit_box.name = "allow exit"; + s_allow_exit_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_allow_exit_box.itemnames = yes_no_names; + s_allow_exit_box.curvalue = (dmflags & DF_ALLOW_EXIT) != 0 ? 1 : 0; + + s_infinite_ammo_box.type = MTYPE_SPINCONTROL; + s_infinite_ammo_box.x = 0; + s_infinite_ammo_box.y = y += 10; + s_infinite_ammo_box.name = "infinite ammo"; + s_infinite_ammo_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_infinite_ammo_box.itemnames = yes_no_names; + s_infinite_ammo_box.curvalue = (dmflags & DF_INFINITE_AMMO) != 0 ? 1 + : 0; + + s_fixed_fov_box.type = MTYPE_SPINCONTROL; + s_fixed_fov_box.x = 0; + s_fixed_fov_box.y = y += 10; + s_fixed_fov_box.name = "fixed FOV"; + s_fixed_fov_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_fixed_fov_box.itemnames = yes_no_names; + s_fixed_fov_box.curvalue = (dmflags & DF_FIXED_FOV) != 0 ? 1 : 0; + + s_quad_drop_box.type = MTYPE_SPINCONTROL; + s_quad_drop_box.x = 0; + s_quad_drop_box.y = y += 10; + s_quad_drop_box.name = "quad drop"; + s_quad_drop_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_quad_drop_box.itemnames = yes_no_names; + s_quad_drop_box.curvalue = (dmflags & DF_QUAD_DROP) != 0 ? 1 : 0; + + s_friendlyfire_box.type = MTYPE_SPINCONTROL; + s_friendlyfire_box.x = 0; + s_friendlyfire_box.y = y += 10; + s_friendlyfire_box.name = "friendly fire"; + s_friendlyfire_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_friendlyfire_box.itemnames = yes_no_names; + s_friendlyfire_box.curvalue = (dmflags & DF_NO_FRIENDLY_FIRE) == 0 ? 1 + : 0; + + // ============ + // ROGUE + if (FS.Developer_searchpath(2) == 2) { + s_no_mines_box.type = MTYPE_SPINCONTROL; + s_no_mines_box.x = 0; + s_no_mines_box.y = y += 10; + s_no_mines_box.name = "remove mines"; + s_no_mines_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_no_mines_box.itemnames = yes_no_names; + s_no_mines_box.curvalue = (dmflags & DF_NO_MINES) != 0 ? 1 : 0; + + s_no_nukes_box.type = MTYPE_SPINCONTROL; + s_no_nukes_box.x = 0; + s_no_nukes_box.y = y += 10; + s_no_nukes_box.name = "remove nukes"; + s_no_nukes_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_no_nukes_box.itemnames = yes_no_names; + s_no_nukes_box.curvalue = (dmflags & DF_NO_NUKES) != 0 ? 1 : 0; + + s_stack_double_box.type = MTYPE_SPINCONTROL; + s_stack_double_box.x = 0; + s_stack_double_box.y = y += 10; + s_stack_double_box.name = "2x/4x stacking off"; + s_stack_double_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_stack_double_box.itemnames = yes_no_names; + s_stack_double_box.curvalue = (dmflags & DF_NO_STACK_DOUBLE); + + s_no_spheres_box.type = MTYPE_SPINCONTROL; + s_no_spheres_box.x = 0; + s_no_spheres_box.y = y += 10; + s_no_spheres_box.name = "remove spheres"; + s_no_spheres_box.callback = new mcallback() { + public void execute(Object o) { + DMFlagCallback(o); + } + }; + s_no_spheres_box.itemnames = yes_no_names; + s_no_spheres_box.curvalue = (dmflags & DF_NO_SPHERES) != 0 ? 1 : 0; + + } + // ROGUE + // ============ + + Menu_AddItem(s_dmoptions_menu, s_falls_box); + Menu_AddItem(s_dmoptions_menu, s_weapons_stay_box); + Menu_AddItem(s_dmoptions_menu, s_instant_powerups_box); + Menu_AddItem(s_dmoptions_menu, s_powerups_box); + Menu_AddItem(s_dmoptions_menu, s_health_box); + Menu_AddItem(s_dmoptions_menu, s_armor_box); + Menu_AddItem(s_dmoptions_menu, s_spawn_farthest_box); + Menu_AddItem(s_dmoptions_menu, s_samelevel_box); + Menu_AddItem(s_dmoptions_menu, s_force_respawn_box); + Menu_AddItem(s_dmoptions_menu, s_teamplay_box); + Menu_AddItem(s_dmoptions_menu, s_allow_exit_box); + Menu_AddItem(s_dmoptions_menu, s_infinite_ammo_box); + Menu_AddItem(s_dmoptions_menu, s_fixed_fov_box); + Menu_AddItem(s_dmoptions_menu, s_quad_drop_box); + Menu_AddItem(s_dmoptions_menu, s_friendlyfire_box); + + // ======= + // ROGUE + if (FS.Developer_searchpath(2) == 2) { + Menu_AddItem(s_dmoptions_menu, s_no_mines_box); + Menu_AddItem(s_dmoptions_menu, s_no_nukes_box); + Menu_AddItem(s_dmoptions_menu, s_stack_double_box); + Menu_AddItem(s_dmoptions_menu, s_no_spheres_box); + } + // ROGUE + // ======= + + Menu_Center(s_dmoptions_menu); + + // set the original dmflags statusbar + DMFlagCallback(null); + Menu_SetStatusBar(s_dmoptions_menu, dmoptions_statusbar); + } + + static void DMOptions_MenuDraw() { + Menu_Draw(s_dmoptions_menu); + } + + static String DMOptions_MenuKey(int key) { + return Default_MenuKey(s_dmoptions_menu, key); + } + + static xcommand_t Menu_DMOptions = new xcommand_t() { + public void execute() { + Menu_DMOptions_f(); + } + }; + + static void Menu_DMOptions_f() { + DMOptions_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + DMOptions_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return DMOptions_MenuKey(key); + } + }); + } + + /* + * ============================================================================= + * + * DOWNLOADOPTIONS BOOK MENU + * + * ============================================================================= + */ + static menuframework_s s_downloadoptions_menu = new menuframework_s(); + + static menuseparator_s s_download_title = new menuseparator_s(); + + static menulist_s s_allow_download_box = new menulist_s(); + + static menulist_s s_allow_download_maps_box = new menulist_s(); + + static menulist_s s_allow_download_models_box = new menulist_s(); + + static menulist_s s_allow_download_players_box = new menulist_s(); + + static menulist_s s_allow_download_sounds_box = new menulist_s(); + + static void DownloadCallback(Object self) { + menulist_s f = (menulist_s) self; + + if (f == s_allow_download_box) { + Cvar.SetValue("allow_download", f.curvalue); + } + + else if (f == s_allow_download_maps_box) { + Cvar.SetValue("allow_download_maps", f.curvalue); + } + + else if (f == s_allow_download_models_box) { + Cvar.SetValue("allow_download_models", f.curvalue); + } + + else if (f == s_allow_download_players_box) { + Cvar.SetValue("allow_download_players", f.curvalue); + } + + else if (f == s_allow_download_sounds_box) { + Cvar.SetValue("allow_download_sounds", f.curvalue); + } + } + + static String yes_no_names[] = { "no", "yes", null }; + + static void DownloadOptions_MenuInit() { + + int y = 0; + + s_downloadoptions_menu.x = (int) (viddef.width * 0.50); + s_downloadoptions_menu.nitems = 0; + + s_download_title.type = MTYPE_SEPARATOR; + s_download_title.name = "Download Options"; + s_download_title.x = 48; + s_download_title.y = y; + + s_allow_download_box.type = MTYPE_SPINCONTROL; + s_allow_download_box.x = 0; + s_allow_download_box.y = y += 20; + s_allow_download_box.name = "allow downloading"; + s_allow_download_box.callback = new mcallback() { + public void execute(Object o) { + DownloadCallback(o); + } + }; + s_allow_download_box.itemnames = yes_no_names; + s_allow_download_box.curvalue = (Cvar.VariableValue("allow_download") != 0) ? 1 + : 0; + + s_allow_download_maps_box.type = MTYPE_SPINCONTROL; + s_allow_download_maps_box.x = 0; + s_allow_download_maps_box.y = y += 20; + s_allow_download_maps_box.name = "maps"; + s_allow_download_maps_box.callback = new mcallback() { + public void execute(Object o) { + DownloadCallback(o); + } + }; + s_allow_download_maps_box.itemnames = yes_no_names; + s_allow_download_maps_box.curvalue = (Cvar + .VariableValue("allow_download_maps") != 0) ? 1 : 0; + + s_allow_download_players_box.type = MTYPE_SPINCONTROL; + s_allow_download_players_box.x = 0; + s_allow_download_players_box.y = y += 10; + s_allow_download_players_box.name = "player models/skins"; + s_allow_download_players_box.callback = new mcallback() { + public void execute(Object o) { + DownloadCallback(o); + } + }; + s_allow_download_players_box.itemnames = yes_no_names; + s_allow_download_players_box.curvalue = (Cvar + .VariableValue("allow_download_players") != 0) ? 1 : 0; + + s_allow_download_models_box.type = MTYPE_SPINCONTROL; + s_allow_download_models_box.x = 0; + s_allow_download_models_box.y = y += 10; + s_allow_download_models_box.name = "models"; + s_allow_download_models_box.callback = new mcallback() { + public void execute(Object o) { + DownloadCallback(o); + } + }; + s_allow_download_models_box.itemnames = yes_no_names; + s_allow_download_models_box.curvalue = (Cvar + .VariableValue("allow_download_models") != 0) ? 1 : 0; + + s_allow_download_sounds_box.type = MTYPE_SPINCONTROL; + s_allow_download_sounds_box.x = 0; + s_allow_download_sounds_box.y = y += 10; + s_allow_download_sounds_box.name = "sounds"; + s_allow_download_sounds_box.callback = new mcallback() { + public void execute(Object o) { + DownloadCallback(o); + } + }; + s_allow_download_sounds_box.itemnames = yes_no_names; + s_allow_download_sounds_box.curvalue = (Cvar + .VariableValue("allow_download_sounds") != 0) ? 1 : 0; + + Menu_AddItem(s_downloadoptions_menu, s_download_title); + Menu_AddItem(s_downloadoptions_menu, s_allow_download_box); + Menu_AddItem(s_downloadoptions_menu, s_allow_download_maps_box); + Menu_AddItem(s_downloadoptions_menu, s_allow_download_players_box); + Menu_AddItem(s_downloadoptions_menu, s_allow_download_models_box); + Menu_AddItem(s_downloadoptions_menu, s_allow_download_sounds_box); + + Menu_Center(s_downloadoptions_menu); + + // skip over title + if (s_downloadoptions_menu.cursor == 0) + s_downloadoptions_menu.cursor = 1; + } + + static void DownloadOptions_MenuDraw() { + Menu_Draw(s_downloadoptions_menu); + } + + static String DownloadOptions_MenuKey(int key) { + return Default_MenuKey(s_downloadoptions_menu, key); + } + + static xcommand_t Menu_DownloadOptions = new xcommand_t() { + public void execute() { + Menu_DownloadOptions_f(); + } + }; + + static void Menu_DownloadOptions_f() { + DownloadOptions_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + DownloadOptions_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return DownloadOptions_MenuKey(key); + } + }); + } + + /* + * ============================================================================= + * + * ADDRESS BOOK MENU + * + * ============================================================================= + */ + + static menuframework_s s_addressbook_menu = new menuframework_s(); + + static menufield_s s_addressbook_fields[] = new menufield_s[NUM_ADDRESSBOOK_ENTRIES]; + static { + for (int n = 0; n < NUM_ADDRESSBOOK_ENTRIES; n++) + s_addressbook_fields[n] = new menufield_s(); + } + + static void AddressBook_MenuInit() { + int i; + + s_addressbook_menu.x = viddef.width / 2 - 142; + s_addressbook_menu.y = viddef.height / 2 - 58; + s_addressbook_menu.nitems = 0; + + for (i = 0; i < NUM_ADDRESSBOOK_ENTRIES; i++) { + cvar_t adr; + //char buffer[20]; + String buffer; + + //Com_sprintf(buffer, sizeof(buffer), "adr%d", i); + buffer = "adr" + i; + + adr = Cvar.Get(buffer, "", CVAR_ARCHIVE); + + s_addressbook_fields[i].type = MTYPE_FIELD; + s_addressbook_fields[i].name = null; + s_addressbook_fields[i].callback = null; + s_addressbook_fields[i].x = 0; + s_addressbook_fields[i].y = i * 18 + 0; + s_addressbook_fields[i].localdata[0] = i; + s_addressbook_fields[i].cursor = 0; + s_addressbook_fields[i].length = 60; + s_addressbook_fields[i].visible_length = 30; + + s_addressbook_fields[i].buffer = new StringBuffer(adr.string); + + Menu_AddItem(s_addressbook_menu, s_addressbook_fields[i]); + } + } + + static keyfunc_t AddressBook_MenuKey = new keyfunc_t() { + public String execute(int key) { + return AddressBook_MenuKey_f(key); + } + }; + + static String AddressBook_MenuKey_f(int key) { + if (key == K_ESCAPE) { + int index; + //char buffer[20]; + String buffer; + + for (index = 0; index < NUM_ADDRESSBOOK_ENTRIES; index++) { + buffer = "adr" + index; + //Com_sprintf(buffer, sizeof(buffer), "adr%d", index); + Cvar.Set(buffer, s_addressbook_fields[index].buffer.toString()); + } + } + return Default_MenuKey(s_addressbook_menu, key); + } + + static xcommand_t AddressBook_MenuDraw = new xcommand_t() { + public void execute() { + AddressBook_MenuDraw_f(); + } + }; + + static void AddressBook_MenuDraw_f() { + Banner("m_banner_addressbook"); + Menu_Draw(s_addressbook_menu); + } + + static xcommand_t Menu_AddressBook = new xcommand_t() { + public void execute() { + Menu_AddressBook_f(); + } + }; + + static void Menu_AddressBook_f() { + AddressBook_MenuInit(); + PushMenu(new xcommand_t() { + public void execute() { + AddressBook_MenuDraw_f(); + } + }, new keyfunc_t() { + public String execute(int key) { + return AddressBook_MenuKey_f(key); + } + }); + } + + /* + * ============================================================================= + * + * PLAYER CONFIG MENU + * + * ============================================================================= + */ + static menuframework_s s_player_config_menu = new menuframework_s(); + + static menufield_s s_player_name_field = new menufield_s(); + + static menulist_s s_player_model_box = new menulist_s(); + + static menulist_s s_player_skin_box = new menulist_s(); + + static menulist_s s_player_handedness_box = new menulist_s(); + + static menulist_s s_player_rate_box = new menulist_s(); + + static menuseparator_s s_player_skin_title = new menuseparator_s(); + + static menuseparator_s s_player_model_title = new menuseparator_s(); + + static menuseparator_s s_player_hand_title = new menuseparator_s(); + + static menuseparator_s s_player_rate_title = new menuseparator_s(); + + static menuaction_s s_player_download_action = new menuaction_s(); + + static class playermodelinfo_s { + int nskins; + + String skindisplaynames[]; + + //char displayname[MAX_DISPLAYNAME]; + String displayname; + + //char directory[MAX_QPATH]; + String directory; + }; + + static playermodelinfo_s s_pmi[] = new playermodelinfo_s[MAX_PLAYERMODELS]; + + static String s_pmnames[] = new String[MAX_PLAYERMODELS]; + + static int s_numplayermodels; + + static int rate_tbl[] = { 2500, 3200, 5000, 10000, 25000, 0 }; + + static String rate_names[] = { "28.8 Modem", "33.6 Modem", "Single ISDN", + "Dual ISDN/Cable", "T1/LAN", "User defined", null }; + + static void DownloadOptionsFunc(Object self) { + Menu_DownloadOptions_f(); + } + + static void HandednessCallback(Object unused) { + Cvar.SetValue("hand", s_player_handedness_box.curvalue); + } + + static void RateCallback(Object unused) { + if (s_player_rate_box.curvalue != rate_tbl.length - 1) //sizeof(rate_tbl) + // / sizeof(* + // rate_tbl) - 1) + Cvar.SetValue("rate", rate_tbl[s_player_rate_box.curvalue]); + } + + static void ModelCallback(Object unused) { + s_player_skin_box.itemnames = s_pmi[s_player_model_box.curvalue].skindisplaynames; + s_player_skin_box.curvalue = 0; + } + + static boolean IconOfSkinExists(String skin, String pcxfiles[], + int npcxfiles) { + int i; + //char scratch[1024]; + String scratch; + + //strcpy(scratch, skin); + scratch = skin; + int pos = scratch.lastIndexOf('.'); + if (pos != -1) + scratch = scratch.substring(0, pos) + "_i.pcx"; + + else + scratch += "_i.pcx"; + + for (i = 0; i < npcxfiles; i++) { + if (Lib.strcmp(pcxfiles[i], scratch) == 0) + return true; + } + + return false; + } + + static boolean PlayerConfig_ScanDirectories() { + //char findname[1024]; + String findname; + //char scratch[1024]; + String scratch; + + int ndirs = 0, npms = 0; + int a, b, c; + String dirnames[]; + + String path = null; + + int i; + + //extern String * FS_ListFiles(String , int *, unsigned, unsigned); + + s_numplayermodels = 0; + + /* + * * get a list of directories + */ + do { + path = FS.NextPath(path); + findname = path + "/players/*.*"; + + if ((dirnames = FS.ListFiles(findname, 0, SFF_SUBDIR)) != null) { + ndirs = dirnames.length; + break; + } + } while (path != null); + + if (dirnames == null) + return false; + + /* + * * go through the subdirectories + */ + npms = ndirs; + if (npms > MAX_PLAYERMODELS) + npms = MAX_PLAYERMODELS; + + for (i = 0; i < npms; i++) { + int k, s; + //String a, b, c; + String pcxnames[]; + String skinnames[]; + int npcxfiles; + int nskins = 0; + + if (dirnames[i] == null) + continue; + + // verify the existence of tris.md2 + scratch = dirnames[i]; + scratch += "/tris.md2"; + if (Sys.FindFirst(scratch, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM) == null) { + //free(dirnames[i]); + dirnames[i] = null; + Sys.FindClose(); + continue; + } + Sys.FindClose(); + + // verify the existence of at least one pcx skin + scratch = dirnames[i] + "/*.pcx"; + pcxnames = FS.ListFiles(scratch, 0, 0); + npcxfiles = pcxnames.length; + + if (pcxnames == null) { + + dirnames[i] = null; + continue; + } + + // count valid skins, which consist of a skin with a matching "_i" + // icon + for (k = 0; k < npcxfiles - 1; k++) { + if (!pcxnames[k].endsWith("_i.pcx")) { + //if (!strstr(pcxnames[k], "_i.pcx")) { + if (IconOfSkinExists(pcxnames[k], pcxnames, npcxfiles - 1)) { + nskins++; + } + } + } + if (nskins == 0) + continue; + + skinnames = new String[nskins + 1]; //malloc(sizeof(String) * + // (nskins + 1)); + //memset(skinnames, 0, sizeof(String) * (nskins + 1)); + + // copy the valid skins + for (s = 0, k = 0; k < npcxfiles - 1; k++) { + + if (pcxnames[k].indexOf("_i.pcx") < 0) { + if (IconOfSkinExists(pcxnames[k], pcxnames, npcxfiles - 1)) { + a = pcxnames[k].lastIndexOf('/'); + b = pcxnames[k].lastIndexOf('\\'); + + if (a > b) + c = a; + else + c = b; + + scratch = pcxnames[k].substring(c + 1, pcxnames[k] + .length()); + int pos = scratch.lastIndexOf('.'); + if (pos != -1) + scratch = scratch.substring(0, pos); + + skinnames[s] = scratch; + s++; + } + } + } + + // at this point we have a valid player model + if (s_pmi[s_numplayermodels] == null) + s_pmi[s_numplayermodels] = new playermodelinfo_s(); + + s_pmi[s_numplayermodels].nskins = nskins; + s_pmi[s_numplayermodels].skindisplaynames = skinnames; + + // make short name for the model + a = dirnames[i].lastIndexOf('/'); + b = dirnames[i].lastIndexOf('\\'); + + if (a > b) + c = a; + else + c = b; + + s_pmi[s_numplayermodels].displayname = dirnames[i].substring(c + 1); + s_pmi[s_numplayermodels].directory = dirnames[i].substring(c + 1); + + s_numplayermodels++; + } + + return true; + + } + + static int pmicmpfnc(Object _a, Object _b) { + playermodelinfo_s a = (playermodelinfo_s) _a; + playermodelinfo_s b = (playermodelinfo_s) _b; + + /* + * * sort by male, female, then alphabetical + */ + if (Lib.strcmp(a.directory, "male") == 0) + return -1; + else if (Lib.strcmp(b.directory, "male") == 0) + return 1; + + if (Lib.strcmp(a.directory, "female") == 0) + return -1; + else if (Lib.strcmp(b.directory, "female") == 0) + return 1; + + return Lib.strcmp(a.directory, b.directory); + } + + static String handedness[] = { "right", "left", "center", null }; + + static boolean PlayerConfig_MenuInit() { + /* + * extern cvar_t * name; extern cvar_t * team; extern cvar_t * skin; + */ + //har currentdirectory[1024]; + String currentdirectory; + //char currentskin[1024]; + String currentskin; + + int i = 0; + + int currentdirectoryindex = 0; + int currentskinindex = 0; + + cvar_t hand = Cvar.Get("hand", "0", CVAR_USERINFO | CVAR_ARCHIVE); + + PlayerConfig_ScanDirectories(); + + if (s_numplayermodels == 0) + return false; + + if (hand.value < 0 || hand.value > 2) + Cvar.SetValue("hand", 0); + + currentdirectory = skin.string; + + if (currentdirectory.lastIndexOf('/') != -1) { + currentskin = Lib.rightFrom(currentdirectory, '/'); + currentdirectory = Lib.leftFrom(currentdirectory, '/'); + } else if (currentdirectory.lastIndexOf('\\') != -1) { + currentskin = Lib.rightFrom(currentdirectory, '\\'); + currentdirectory = Lib.leftFrom(currentdirectory, '\\'); + } else { + currentdirectory = "male"; + currentskin = "grunt"; + } + + //qsort(s_pmi, s_numplayermodels, sizeof(s_pmi[0]), pmicmpfnc); + Arrays.sort(s_pmi, 0, s_numplayermodels, new Comparator() { + public int compare(Object o1, Object o2) { + return pmicmpfnc(o1, o2); + } + }); + + //memset(s_pmnames, 0, sizeof(s_pmnames)); + s_pmnames = new String[MAX_PLAYERMODELS]; + + for (i = 0; i < s_numplayermodels; i++) { + s_pmnames[i] = s_pmi[i].displayname; + if (Lib.Q_stricmp(s_pmi[i].directory, currentdirectory) == 0) { + int j; + + currentdirectoryindex = i; + + for (j = 0; j < s_pmi[i].nskins; j++) { + if (Lib + .Q_stricmp(s_pmi[i].skindisplaynames[j], + currentskin) == 0) { + currentskinindex = j; + break; + } + } + } + } + + s_player_config_menu.x = viddef.width / 2 - 95; + s_player_config_menu.y = viddef.height / 2 - 97; + s_player_config_menu.nitems = 0; + + s_player_name_field.type = MTYPE_FIELD; + s_player_name_field.name = "name"; + s_player_name_field.callback = null; + s_player_name_field.x = 0; + s_player_name_field.y = 0; + s_player_name_field.length = 20; + s_player_name_field.visible_length = 20; + s_player_name_field.buffer = new StringBuffer(name.string); + s_player_name_field.cursor = name.string.length(); + + s_player_model_title.type = MTYPE_SEPARATOR; + s_player_model_title.name = "model"; + s_player_model_title.x = -8; + s_player_model_title.y = 60; + + s_player_model_box.type = MTYPE_SPINCONTROL; + s_player_model_box.x = -56; + s_player_model_box.y = 70; + s_player_model_box.callback = new mcallback() { + public void execute(Object o) { + ModelCallback(o); + } + }; + s_player_model_box.cursor_offset = -48; + s_player_model_box.curvalue = currentdirectoryindex; + s_player_model_box.itemnames = s_pmnames; + + s_player_skin_title.type = MTYPE_SEPARATOR; + s_player_skin_title.name = "skin"; + s_player_skin_title.x = -16; + s_player_skin_title.y = 84; + + s_player_skin_box.type = MTYPE_SPINCONTROL; + s_player_skin_box.x = -56; + s_player_skin_box.y = 94; + s_player_skin_box.name = null; + s_player_skin_box.callback = null; + s_player_skin_box.cursor_offset = -48; + s_player_skin_box.curvalue = currentskinindex; + s_player_skin_box.itemnames = s_pmi[currentdirectoryindex].skindisplaynames; + + s_player_hand_title.type = MTYPE_SEPARATOR; + s_player_hand_title.name = "handedness"; + s_player_hand_title.x = 32; + s_player_hand_title.y = 108; + + s_player_handedness_box.type = MTYPE_SPINCONTROL; + s_player_handedness_box.x = -56; + s_player_handedness_box.y = 118; + s_player_handedness_box.name = null; + s_player_handedness_box.cursor_offset = -48; + s_player_handedness_box.callback = new mcallback() { + public void execute(Object o) { + HandednessCallback(o); + } + }; + s_player_handedness_box.curvalue = (int) Cvar.VariableValue("hand"); + s_player_handedness_box.itemnames = handedness; + + for (i = 0; i < rate_tbl.length - 1; i++) + if (Cvar.VariableValue("rate") == rate_tbl[i]) + break; + + s_player_rate_title.type = MTYPE_SEPARATOR; + s_player_rate_title.name = "connect speed"; + s_player_rate_title.x = 56; + s_player_rate_title.y = 156; + + s_player_rate_box.type = MTYPE_SPINCONTROL; + s_player_rate_box.x = -56; + s_player_rate_box.y = 166; + s_player_rate_box.name = null; + s_player_rate_box.cursor_offset = -48; + s_player_rate_box.callback = new mcallback() { + public void execute(Object o) { + RateCallback(o); + } + }; + s_player_rate_box.curvalue = i; + s_player_rate_box.itemnames = rate_names; + + s_player_download_action.type = MTYPE_ACTION; + s_player_download_action.name = "download options"; + s_player_download_action.flags = QMF_LEFT_JUSTIFY; + s_player_download_action.x = -24; + s_player_download_action.y = 186; + s_player_download_action.statusbar = null; + s_player_download_action.callback = new mcallback() { + public void execute(Object o) { + DownloadOptionsFunc(o); + } + }; + + Menu_AddItem(s_player_config_menu, s_player_name_field); + Menu_AddItem(s_player_config_menu, s_player_model_title); + Menu_AddItem(s_player_config_menu, s_player_model_box); + if (s_player_skin_box.itemnames != null) { + Menu_AddItem(s_player_config_menu, s_player_skin_title); + Menu_AddItem(s_player_config_menu, s_player_skin_box); + } + Menu_AddItem(s_player_config_menu, s_player_hand_title); + Menu_AddItem(s_player_config_menu, s_player_handedness_box); + Menu_AddItem(s_player_config_menu, s_player_rate_title); + Menu_AddItem(s_player_config_menu, s_player_rate_box); + Menu_AddItem(s_player_config_menu, s_player_download_action); + + return true; + } + + static int yaw; + + static void PlayerConfig_MenuDraw() { + + refdef_t refdef = new refdef_t(); + //char scratch[MAX_QPATH]; + String scratch; + + //memset(refdef, 0, sizeof(refdef)); + + refdef.x = viddef.width / 2; + refdef.y = viddef.height / 2 - 72; + refdef.width = 144; + refdef.height = 168; + refdef.fov_x = 40; + refdef.fov_y = Math3D + .CalcFov(refdef.fov_x, refdef.width, refdef.height); + refdef.time = cls.realtime * 0.001f; + + if (s_pmi[s_player_model_box.curvalue].skindisplaynames != null) { + + int maxframe = 29; + entity_t entity = new entity_t(); + + //memset(entity, 0, sizeof(entity)); + + scratch = "players/" + s_pmi[s_player_model_box.curvalue].directory + + "/tris.md2"; + + entity.model = re.RegisterModel(scratch); + + scratch = "players/" + + s_pmi[s_player_model_box.curvalue].directory + + "/" + + s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] + + ".pcx"; + + entity.skin = re.RegisterSkin(scratch); + entity.flags = 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; + entity.angles[1] = yaw++; + if (++yaw > 360) + yaw -= 360; + + refdef.areabits = null; + refdef.num_entities = 1; + refdef.entities = new entity_t[] { entity }; + refdef.lightstyles = null; + refdef.rdflags = RDF_NOWORLDMODEL; + + Menu_Draw(s_player_config_menu); + + 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); + + scratch = "/players/" + + s_pmi[s_player_model_box.curvalue].directory + + "/" + + s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue] + + "_i.pcx"; + + re.DrawPic(s_player_config_menu.x - 40, refdef.y, scratch); + } + } + + static String PlayerConfig_MenuKey(int key) { + int i; + + if (key == K_ESCAPE) { + //char scratch[1024]; + String scratch; + + Cvar.Set("name", s_player_name_field.buffer.toString()); + + scratch = s_pmi[s_player_model_box.curvalue].directory + + "/" + + s_pmi[s_player_model_box.curvalue].skindisplaynames[s_player_skin_box.curvalue]; + + Cvar.Set("skin", scratch); + + for (i = 0; i < s_numplayermodels; i++) { + int j; + + for (j = 0; j < s_pmi[i].nskins; j++) { + if (s_pmi[i].skindisplaynames[j] != null) + s_pmi[i].skindisplaynames[j] = null; + } + s_pmi[i].skindisplaynames = null; + s_pmi[i].nskins = 0; + } + } + return Default_MenuKey(s_player_config_menu, key); + } + + static xcommand_t Menu_PlayerConfig = new xcommand_t() { + public void execute() { + Menu_PlayerConfig_f(); + } + }; + + static void Menu_PlayerConfig_f() { + if (!PlayerConfig_MenuInit()) { + Menu_SetStatusBar(s_multiplayer_menu, + "No valid player models found"); + return; + } + Menu_SetStatusBar(s_multiplayer_menu, null); + PushMenu(new xcommand_t() { + public void execute() { + PlayerConfig_MenuDraw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return PlayerConfig_MenuKey(key); + } + }); + } + + /* + * ======================================================================= + * + * QUIT MENU + * + * ======================================================================= + */ + + static String Quit_Key(int key) { + switch (key) { + case K_ESCAPE: + case 'n': + case 'N': + PopMenu(); + break; + + case 'Y': + case 'y': + cls.key_dest = key_console; + CL.Quit_f.execute(); + break; + + default: + break; + } + + return null; + + } + + static void Quit_Draw() { + int w, h; + Dimension d = new Dimension(); + re.DrawGetPicSize(d, "quit"); + w = d.width; + h = d.height; + re.DrawPic((viddef.width - w) / 2, (viddef.height - h) / 2, "quit"); + } + + static xcommand_t Menu_Quit = new xcommand_t() { + public void execute() { + Menu_Quit_f(); + } + }; + + static void Menu_Quit_f() { + PushMenu(new xcommand_t() { + public void execute() { + Quit_Draw(); + } + }, new keyfunc_t() { + public String execute(int key) { + return Quit_Key(key); + } + }); + } + + // ============================================================================= + /* Menu Subsystem */ + + /** + * Init + */ + public static void Init() { + Cmd.AddCommand("menu_main", Menu_Main); + Cmd.AddCommand("menu_game", Menu_Game); + Cmd.AddCommand("menu_loadgame", Menu_LoadGame); + Cmd.AddCommand("menu_savegame", Menu_SaveGame); + Cmd.AddCommand("menu_joinserver", Menu_JoinServer); + Cmd.AddCommand("menu_addressbook", Menu_AddressBook); + Cmd.AddCommand("menu_startserver", Menu_StartServer); + Cmd.AddCommand("menu_dmoptions", Menu_DMOptions); + Cmd.AddCommand("menu_playerconfig", Menu_PlayerConfig); + Cmd.AddCommand("menu_downloadoptions", Menu_DownloadOptions); + Cmd.AddCommand("menu_credits", Menu_Credits); + Cmd.AddCommand("menu_multiplayer", Menu_Multiplayer); + Cmd.AddCommand("menu_video", Menu_Video); + Cmd.AddCommand("menu_options", Menu_Options); + Cmd.AddCommand("menu_keys", Menu_Keys); + Cmd.AddCommand("menu_quit", Menu_Quit); + + for (int i = 0; i < m_layers.length; i++) { + m_layers[i] = new menulayer_t(); + } + } + + /* + * ================= Draw ================= + */ + static void Draw() { + if (cls.key_dest != key_menu) + return; + + // repaint everything next frame + SCR.DirtyScreen(); + + // dim everything behind it down + if (cl.cinematictime > 0) + re.DrawFill(0, 0, viddef.width, viddef.height, 0); + else + re.DrawFadeScreen(); + + m_drawfunc.execute(); + + // delay playing the enter sound until after the + // menu has been drawn, to avoid delay while + // caching images + if (m_entersound) { + S.StartLocalSound(menu_in_sound); + m_entersound = false; + } + } + + /* + * ================= Keydown ================= + */ + static void Keydown(int key) { + String s; + + if (m_keyfunc != null) + if ((s = m_keyfunc.execute(key)) != null) + S.StartLocalSound(s); + } + + public static void Action_DoEnter(menuaction_s a) { + if (a.callback != null) + a.callback.execute(a); + } + + public static void Action_Draw(menuaction_s a) { + if ((a.flags & QMF_LEFT_JUSTIFY) != 0) { + if ((a.flags & QMF_GRAYED) != 0) + Menu_DrawStringDark(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + + a.parent.y, a.name); + else + Menu_DrawString(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + + a.parent.y, a.name); + } else { + if ((a.flags & QMF_GRAYED) != 0) + Menu_DrawStringR2LDark(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + + a.parent.y, a.name); + else + Menu_DrawStringR2L(a.x + a.parent.x + LCOLUMN_OFFSET, a.y + + a.parent.y, a.name); + } + if (a.ownerdraw != null) + a.ownerdraw.execute(a); + } + + public static boolean Field_DoEnter(menufield_s f) { + if (f.callback != null) { + f.callback.execute(f); + return true; + } + return false; + } + + public static void Field_Draw(menufield_s f) { + int i; + String tempbuffer; + //[128] = ""; + + if (f.name != null) + Menu_DrawStringR2LDark(f.x + f.parent.x + LCOLUMN_OFFSET, f.y + + f.parent.y, f.name); + + //strncpy(tempbuffer, f.buffer + f.visible_offset, f.visible_length); + String s = f.buffer.toString(); + tempbuffer = s.substring(f.visible_offset, s.length()); + re.DrawChar(f.x + f.parent.x + 16, f.y + f.parent.y - 4, 18); + re.DrawChar(f.x + f.parent.x + 16, f.y + f.parent.y + 4, 24); + + re.DrawChar(f.x + f.parent.x + 24 + f.visible_length * 8, f.y + + f.parent.y - 4, 20); + re.DrawChar(f.x + f.parent.x + 24 + f.visible_length * 8, f.y + + f.parent.y + 4, 26); + + for (i = 0; i < f.visible_length; i++) { + re + .DrawChar(f.x + f.parent.x + 24 + i * 8, f.y + f.parent.y + - 4, 19); + re + .DrawChar(f.x + f.parent.x + 24 + i * 8, f.y + f.parent.y + + 4, 25); + } + + Menu_DrawString(f.x + f.parent.x + 24, f.y + f.parent.y, tempbuffer); + + if (Menu_ItemAtCursor(f.parent) == f) { + int offset; + + if (f.visible_offset != 0) + offset = f.visible_length; + else + offset = f.cursor; + + if ((((int) (Sys.Milliseconds() / 250)) & 1) != 0) { + re.DrawChar(f.x + f.parent.x + (offset + 2) * 8 + 8, f.y + + f.parent.y, 11); + } else { + re.DrawChar(f.x + f.parent.x + (offset + 2) * 8 + 8, f.y + + f.parent.y, ' '); + } + } + } + + public static boolean Field_Key(menufield_s f, int k) { + char key = (char) k; + + switch (key) { + case K_KP_SLASH: + key = '/'; + break; + case K_KP_MINUS: + key = '-'; + break; + case K_KP_PLUS: + key = '+'; + break; + case K_KP_HOME: + key = '7'; + break; + case K_KP_UPARROW: + key = '8'; + break; + case K_KP_PGUP: + key = '9'; + break; + case K_KP_LEFTARROW: + key = '4'; + break; + case K_KP_5: + key = '5'; + break; + case K_KP_RIGHTARROW: + key = '6'; + break; + case K_KP_END: + key = '1'; + break; + case K_KP_DOWNARROW: + key = '2'; + break; + case K_KP_PGDN: + key = '3'; + break; + case K_KP_INS: + key = '0'; + break; + case K_KP_DEL: + key = '.'; + break; + } + + if (key > 127) { + switch (key) { + case K_DEL: + default: + return false; + } + } + + /* + * * support pasting from the clipboard + */ + if ((Character.toUpperCase(key) == 'V' && keydown[K_CTRL]) + || (((key == K_INS) || (key == K_KP_INS)) && keydown[K_SHIFT])) { + String cbd; + + if ((cbd = Sys.GetClipboardData()) != null) { + //strtok(cbd, "\n\r\b"); + String lines[] = Lib.linesplit(cbd); + if (lines.length > 0 && lines[0].length() != 0) { + //strncpy(f.buffer, cbd, f.length - 1); + f.buffer = new StringBuffer(lines[0]); + f.cursor = f.buffer.length(); + + f.visible_offset = f.cursor - f.visible_length; + + if (f.visible_offset < 0) + f.visible_offset = 0; + } + } + return true; + } + + switch (key) { + case K_KP_LEFTARROW: + case K_LEFTARROW: + case K_BACKSPACE: + if (f.cursor > 0) { + f.buffer.deleteCharAt(f.cursor - 1); + //memmove(f.buffer[f.cursor - 1], f.buffer[f.cursor], strlen(& + // f.buffer[f.cursor]) + 1); + f.cursor--; + + if (f.visible_offset != 0) { + f.visible_offset--; + } + } + break; + + case K_KP_DEL: + case K_DEL: + //memmove(& f.buffer[f.cursor], & f.buffer[f.cursor + 1], strlen(& + // f.buffer[f.cursor + 1]) + 1); + f.buffer.deleteCharAt(f.cursor); + break; + + case K_KP_ENTER: + case K_ENTER: + case K_ESCAPE: + case K_TAB: + return false; + + case K_SPACE: + default: + if (!Character.isDigit(key) && (f.flags & QMF_NUMBERSONLY) != 0) + return false; + + if (f.cursor < f.length) { + f.buffer.append(key); + f.cursor++; + + if (f.cursor > f.visible_length) { + f.visible_offset++; + } + } + } + + return true; + } + + public static void Menu_AddItem(menuframework_s menu, menucommon_s item) { + if (menu.nitems == 0) + menu.nslots = 0; + + if (menu.nitems < MAXMENUITEMS) { + menu.items[menu.nitems] = item; + ((menucommon_s) menu.items[menu.nitems]).parent = menu; + menu.nitems++; + } + + menu.nslots = Menu_TallySlots(menu); + } + + /* + * * Menu_AdjustCursor * * This function takes the given menu, the + * direction, and attempts * to adjust the menu's cursor so that it's at the + * next available * slot. + */ + public static void Menu_AdjustCursor(menuframework_s m, int dir) { + menucommon_s citem; + + /* + * * see if it's in a valid spot + */ + if (m.cursor >= 0 && m.cursor < m.nitems) { + if ((citem = Menu_ItemAtCursor(m)) != null) { + if (citem.type != MTYPE_SEPARATOR) + return; + } + } + + /* + * * it's not in a valid spot, so crawl in the direction indicated until + * we * find a valid spot + */ + if (dir == 1) { + while (true) { + citem = Menu_ItemAtCursor(m); + if (citem != null) + if (citem.type != MTYPE_SEPARATOR) + break; + m.cursor += dir; + if (m.cursor >= m.nitems) + m.cursor = 0; + } + } else { + while (true) { + citem = Menu_ItemAtCursor(m); + if (citem != null) + if (citem.type != MTYPE_SEPARATOR) + break; + m.cursor += dir; + if (m.cursor < 0) + m.cursor = m.nitems - 1; + } + } + } + + public static void Menu_Center(menuframework_s menu) { + int height; + + height = ((menucommon_s) menu.items[menu.nitems - 1]).y; + height += 10; + + menu.y = (viddef.height - height) / 2; + } + + public static void Menu_Draw(menuframework_s menu) { + int i; + menucommon_s item; + + /* + * * draw contents + */ + for (i = 0; i < menu.nitems; i++) { + switch (((menucommon_s) menu.items[i]).type) { + case MTYPE_FIELD: + Field_Draw((menufield_s) menu.items[i]); + break; + case MTYPE_SLIDER: + Slider_Draw((menuslider_s) menu.items[i]); + break; + case MTYPE_LIST: + MenuList_Draw((menulist_s) menu.items[i]); + break; + case MTYPE_SPINCONTROL: + SpinControl_Draw((menulist_s) menu.items[i]); + break; + case MTYPE_ACTION: + Action_Draw((menuaction_s) menu.items[i]); + break; + case MTYPE_SEPARATOR: + Separator_Draw((menuseparator_s) menu.items[i]); + break; + } + } + + item = Menu_ItemAtCursor(menu); + + if (item != null && item.cursordraw != null) { + item.cursordraw.execute(item); + } else if (menu.cursordraw != null) { + menu.cursordraw.execute(menu); + } else if (item != null && item.type != MTYPE_FIELD) { + if ((item.flags & QMF_LEFT_JUSTIFY) != 0) { + re.DrawChar(menu.x + item.x - 24 + item.cursor_offset, menu.y + + item.y, 12 + ((int) (Sys.Milliseconds() / 250) & 1)); + } else { + re.DrawChar(menu.x + item.cursor_offset, menu.y + item.y, + 12 + ((int) (Sys.Milliseconds() / 250) & 1)); + } + } + + if (item != null) { + if (item.statusbarfunc != null) + item.statusbarfunc.execute(item); + else if (item.statusbar != null) + Menu_DrawStatusBar(item.statusbar); + else + Menu_DrawStatusBar(menu.statusbar); + + } else { + Menu_DrawStatusBar(menu.statusbar); + } + } + + public static void Menu_DrawStatusBar(String string) { + if (string != null) { + int l = string.length(); + int maxrow = viddef.height / 8; + int maxcol = viddef.width / 8; + int col = maxcol / 2 - l / 2; + + re.DrawFill(0, viddef.height - 8, viddef.width, 8, 4); + Menu_DrawString(col * 8, viddef.height - 8, string); + } else { + re.DrawFill(0, viddef.height - 8, viddef.width, 8, 0); + } + } + + public static void Menu_DrawString(int x, int y, String string) { + int i; + + for (i = 0; i < string.length(); i++) { + re.DrawChar((x + i * 8), y, string.charAt(i)); + } + } + + public static void Menu_DrawStringDark(int x, int y, String string) { + int i; + + for (i = 0; i < string.length(); i++) { + re.DrawChar((x + i * 8), y, string.charAt(i) + 128); + } + } + + public static void Menu_DrawStringR2L(int x, int y, String string) { + int i; + + int l = string.length(); + for (i = 0; i < l; i++) { + re.DrawChar((x - i * 8), y, string.charAt(l - i - 1)); + } + } + + public static void Menu_DrawStringR2LDark(int x, int y, String string) { + int i; + + int l = string.length(); + for (i = 0; i < l; i++) { + re.DrawChar((x - i * 8), y, string.charAt(l - i - 1) + 128); + } + } + + public static menucommon_s Menu_ItemAtCursor(menuframework_s m) { + if (m.cursor < 0 || m.cursor >= m.nitems) + return null; + + return (menucommon_s) m.items[m.cursor]; + } + + static boolean Menu_SelectItem(menuframework_s s) { + menucommon_s item = Menu_ItemAtCursor(s); + + if (item != null) { + switch (item.type) { + case MTYPE_FIELD: + return Field_DoEnter((menufield_s) item); + case MTYPE_ACTION: + Action_DoEnter((menuaction_s) item); + return true; + case MTYPE_LIST: + // Menulist_DoEnter( ( menulist_s ) item ); + return false; + case MTYPE_SPINCONTROL: + // SpinControl_DoEnter( ( menulist_s ) item ); + return false; + } + } + return false; + } + + public static void Menu_SetStatusBar(menuframework_s m, String string) { + m.statusbar = string; + } + + public static void Menu_SlideItem(menuframework_s s, int dir) { + menucommon_s item = (menucommon_s) Menu_ItemAtCursor(s); + + if (item != null) { + switch (item.type) { + case MTYPE_SLIDER: + Slider_DoSlide((menuslider_s) item, dir); + break; + case MTYPE_SPINCONTROL: + SpinControl_DoSlide((menulist_s) item, dir); + break; + } + } + } + + public static int Menu_TallySlots(menuframework_s menu) { + int i; + int total = 0; + + for (i = 0; i < menu.nitems; i++) { + if (((menucommon_s) menu.items[i]).type == MTYPE_LIST) { + int nitems = 0; + String n[] = ((menulist_s) menu.items[i]).itemnames; + + while (n[nitems] != null) + nitems++; + + total += nitems; + } else { + total++; + } + } + + return total; + } + + public static void Menulist_DoEnter(menulist_s l) { + int start; + + start = l.y / 10 + 1; + + l.curvalue = l.parent.cursor - start; + + if (l.callback != null) + l.callback.execute(l); + } + + public static void MenuList_Draw(menulist_s l) { + String n[]; + int y = 0; + + Menu_DrawStringR2LDark(l.x + l.parent.x + LCOLUMN_OFFSET, l.y + + l.parent.y, l.name); + + n = l.itemnames; + + re.DrawFill(l.x - 112 + l.parent.x, l.parent.y + l.y + l.curvalue * 10 + + 10, 128, 10, 16); + int i = 0; + + while (n[i] != null) { + Menu_DrawStringR2LDark(l.x + l.parent.x + LCOLUMN_OFFSET, l.y + + l.parent.y + y + 10, n[i]); + + i++; + y += 10; + } + } + + public static void Separator_Draw(menuseparator_s s) { + if (s.name != null) + Menu_DrawStringR2LDark(s.x + s.parent.x, s.y + s.parent.y, s.name); + } + + public static void Slider_DoSlide(menuslider_s s, int dir) { + s.curvalue += dir; + + if (s.curvalue > s.maxvalue) + s.curvalue = s.maxvalue; + else if (s.curvalue < s.minvalue) + s.curvalue = s.minvalue; + + if (s.callback != null) + s.callback.execute(s); + } + + public static final int SLIDER_RANGE = 10; + + public static void Slider_Draw(menuslider_s s) { + int i; + + Menu_DrawStringR2LDark(s.x + s.parent.x + LCOLUMN_OFFSET, s.y + + s.parent.y, s.name); + + s.range = (s.curvalue - s.minvalue) / (float) (s.maxvalue - s.minvalue); + + if (s.range < 0) + s.range = 0; + if (s.range > 1) + s.range = 1; + re.DrawChar(s.x + s.parent.x + RCOLUMN_OFFSET, s.y + s.parent.y, 128); + for (i = 0; i < SLIDER_RANGE; i++) + re.DrawChar(RCOLUMN_OFFSET + s.x + i * 8 + s.parent.x + 8, s.y + + s.parent.y, 129); + re.DrawChar(RCOLUMN_OFFSET + s.x + i * 8 + s.parent.x + 8, s.y + + s.parent.y, 130); + re + .DrawChar( + (int) (8 + RCOLUMN_OFFSET + s.parent.x + s.x + (SLIDER_RANGE - 1) + * 8 * s.range), s.y + s.parent.y, 131); + } + + public static void SpinControl_DoEnter(menulist_s s) { + s.curvalue++; + if (s.itemnames[s.curvalue] == null) + s.curvalue = 0; + + if (s.callback != null) + s.callback.execute(s); + } + + public static void SpinControl_DoSlide(menulist_s s, int dir) { + s.curvalue += dir; + + if (s.curvalue < 0) + s.curvalue = 0; + else if (s.itemnames[s.curvalue] == null) + s.curvalue--; + + if (s.callback != null) + s.callback.execute(s); + } + + public static void SpinControl_Draw(menulist_s s) { + //char buffer[100]; + String buffer; + + if (s.name != null) { + Menu_DrawStringR2LDark(s.x + s.parent.x + LCOLUMN_OFFSET, s.y + + s.parent.y, s.name); + } + + if (s.itemnames[s.curvalue].indexOf('\n') == -1) { + Menu_DrawString(RCOLUMN_OFFSET + s.x + s.parent.x, + s.y + s.parent.y, s.itemnames[s.curvalue]); + } else { + String line1, line2; + line1 = Lib.leftFrom(s.itemnames[s.curvalue], '\n'); + Menu_DrawString(RCOLUMN_OFFSET + s.x + s.parent.x, + s.y + s.parent.y, line1); + + line2 = Lib.rightFrom(s.itemnames[s.curvalue], '\n'); + + int pos = line2.indexOf('\n'); + if (pos != -1) + line2 = line2.substring(0, pos); + + Menu_DrawString(RCOLUMN_OFFSET + s.x + s.parent.x, s.y + s.parent.y + + 10, line2); + } + } +}
\ No newline at end of file diff --git a/src/jake2/client/SCR.java b/src/jake2/client/SCR.java index f92adcc..9ff5021 100644 --- a/src/jake2/client/SCR.java +++ b/src/jake2/client/SCR.java @@ -2,27 +2,27 @@ * SCR.java * Copyright (C) 2003 * - * $Id: SCR.java,v 1.7 2004-08-27 21:07:01 hzi Exp $ + * $Id: SCR.java,v 1.8 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; @@ -32,6 +32,7 @@ import jake2.game.cvar_t; import jake2.qcommon.*; import jake2.sound.*; import jake2.sys.Sys; +import jake2.util.Lib; import jake2.util.Vargs; import java.awt.Dimension; @@ -41,1971 +42,1954 @@ import java.awt.Dimension; */ public final class SCR extends Globals { - // cl_scrn.c -- master for refresh, status bar, console, chat, notify, etc - - static String[][] sb_nums= - { { "num_0", "num_1", "num_2", "num_3", "num_4", "num_5", "num_6", "num_7", "num_8", "num_9", "num_minus" }, { - "anum_0", "anum_1", "anum_2", "anum_3", "anum_4", "anum_5", "anum_6", "anum_7", "anum_8", "anum_9", "anum_minus" } - }; - - /* - full screen console - put up loading plaque - blanked background with loading plaque - blanked background with menu - cinematics - full screen image for quit and victory - - end of unit intermissions - */ - - static float scr_con_current; // aproaches scr_conlines at scr_conspeed - static float scr_conlines; // 0.0 to 1.0 lines of console to display - - static boolean scr_initialized; // ready to draw - - static int scr_draw_loading; - - // scr_vrect ist in Globals definiert - // position of render window on screen - - static cvar_t scr_viewsize; - static cvar_t scr_conspeed; - static cvar_t scr_centertime; - static cvar_t scr_showturtle; - static cvar_t scr_showpause; - static cvar_t scr_printspeed; - - static cvar_t scr_netgraph; - static cvar_t scr_timegraph; - static cvar_t scr_debuggraph; - static cvar_t scr_graphheight; - static cvar_t scr_graphscale; - static cvar_t scr_graphshift; - static cvar_t scr_drawall; - public static cvar_t fps; - - static dirty_t scr_dirty= new dirty_t(); - static dirty_t[] scr_old_dirty= { new dirty_t(), new dirty_t()}; - - static String crosshair_pic; - static int crosshair_width, crosshair_height; - - static class dirty_t { - int x1; - int x2; - int y1; - int y2; - - void set(dirty_t src) { - x1= src.x1; - x2= src.x2; - y1= src.y1; - y2= src.y2; - } - - void clear() { - x1= x2= y1= y2= 0; - } - } - - /* - =============================================================================== - - BAR GRAPHS - - =============================================================================== - */ - - // typedef struct - // { - // float value; - // int color; - // } graphsamp_t; - static class graphsamp_t { - float value; - int color; - } - static int current; - static graphsamp_t[] values= new graphsamp_t[1024]; - - static { - for (int n= 0; n < 1024; n++) - values[n]= new graphsamp_t(); - } - - /* - ============== - SCR_DebugGraph - ============== - */ - public static void DebugGraph(float value, int color) { - values[current & 1023].value= value; - values[current & 1023].color= color; - current++; - } - - /* - ============== - SCR_DrawDebugGraph - ============== - */ - static void DrawDebugGraph() { - int a, x, y, w, i, h; - float v; - int color; - - // draw the graph - - w= scr_vrect.width; - - x= scr_vrect.x; - y= scr_vrect.y + scr_vrect.height; - re.DrawFill(x, (int) (y - scr_graphheight.value), w, (int) scr_graphheight.value, 8); - - for (a= 0; a < w; a++) { - i= (current - 1 - a + 1024) & 1023; - v= values[i].value; - color= values[i].color; - v= v * scr_graphscale.value + scr_graphshift.value; - - if (v < 0) - v += scr_graphheight.value * (1 + (int) (-v / scr_graphheight.value)); - h= (int) v % (int) scr_graphheight.value; - re.DrawFill(x + w - 1 - a, y - h, 1, h, color); - } - } - - /* - =============================================================================== - - CENTER PRINTING - - =============================================================================== - */ - - // char scr_centerstring[1024]; - static String scr_centerstring; - static float scr_centertime_start; // for slow victory printing - static float scr_centertime_off; - static int scr_center_lines; - static int scr_erase_center; - - /* - ============== - SCR_CenterPrint - - Called for important messages that should stay in the center of the screen - for a few moments - ============== - */ - static void CenterPrint(String str) { - //char *s; - int s; - StringBuffer line= new StringBuffer(64); - int i, j, l; - - //strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); - scr_centerstring= str; - scr_centertime_off= scr_centertime.value; - scr_centertime_start= cl.time; - - // count the number of lines for centering - scr_center_lines= 1; - s= 0; - while (s < str.length()) { - if (str.charAt(s) == '\n') - scr_center_lines++; - s++; - } - - // echo it to the console - Com.Printf( - "\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); - - s= 0; - - if (str.length() != 0) { - do { - // scan the width of the line - - for (l= 0; l < 40 && (l + s) < str.length(); l++) - if (str.charAt(s + l) == '\n' || str.charAt(s + l) == 0) - break; - for (i= 0; i < (40 - l) / 2; i++) - line.append(' '); - - for (j= 0; j < l; j++) { - line.append(str.charAt(s + j)); - } - - line.append('\n'); - - Com.Printf(line.toString()); - - while (s < str.length() && str.charAt(s) != '\n') - s++; - - if (s == str.length()) - break; - s++; // skip the \n - } - while (true); - } - Com.Printf( - "\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); - Console.ClearNotify(); - } - - static void DrawCenterString() { - String cs= scr_centerstring + "\0"; - int start; - int l; - int j; - int x, y; - int remaining; - - if (cs == null) - return; - if (cs.length() == 0) - return; - - // the finale prints the characters one at a time - remaining= 9999; - - scr_erase_center= 0; - start= 0; - - if (scr_center_lines <= 4) - y= (int) (viddef.height * 0.35); - else - y= 48; - - do { - // scan the width of the line - for (l= 0; l < 40; l++) - if (start + l == cs.length() - 1 || cs.charAt(start + l) == '\n') - break; - x= (viddef.width - l * 8) / 2; - SCR.AddDirtyPoint(x, y); - for (j= 0; j < l; j++, x += 8) { - re.DrawChar(x, y, cs.charAt(start + j)); - if (remaining == 0) - return; - remaining--; - } - SCR.AddDirtyPoint(x, y + 8); - - y += 8; - - while (start < cs.length() && cs.charAt(start) != '\n') - start++; - - if (start == cs.length()) - break; - start++; // skip the \n - } - while (true); - } - - static void CheckDrawCenterString() { - scr_centertime_off -= cls.frametime; - - if (scr_centertime_off <= 0) - return; - - DrawCenterString(); - } - - // ============================================================================= - - /* - ================= - SCR_CalcVrect - - Sets scr_vrect, the coordinates of the rendered window - ================= - */ - static void CalcVrect() { - int size; - - // bound viewsize - if (scr_viewsize.value < 40) - Cvar.Set("viewsize", "40"); - if (scr_viewsize.value > 100) - Cvar.Set("viewsize", "100"); - - size= (int) scr_viewsize.value; - - scr_vrect.width= viddef.width * size / 100; - scr_vrect.width &= ~7; - - scr_vrect.height= viddef.height * size / 100; - scr_vrect.height &= ~1; - - scr_vrect.x= (viddef.width - scr_vrect.width) / 2; - scr_vrect.y= (viddef.height - scr_vrect.height) / 2; - } - - /* - ================= - SCR_SizeUp_f - - Keybinding command - ================= - */ - static void SizeUp_f() { - Cvar.SetValue("viewsize", scr_viewsize.value + 10); - } - - /* - ================= - SCR_SizeDown_f - - Keybinding command - ================= - */ - static void SizeDown_f() { - Cvar.SetValue("viewsize", scr_viewsize.value - 10); - } - - /* - ================= - SCR_Sky_f - - Set a specific sky and rotation speed - ================= - */ - static void Sky_f() { - float rotate; - float[] axis= { 0, 0, 0 }; - - if (Cmd.Argc() < 2) { - Com.Printf("Usage: sky <basename> <rotate> <axis x y z>\n"); - return; - } - if (Cmd.Argc() > 2) - rotate= Float.parseFloat(Cmd.Argv(2)); - else - rotate= 0; - if (Cmd.Argc() == 6) { - axis[0]= Float.parseFloat(Cmd.Argv(3)); - axis[1]= Float.parseFloat(Cmd.Argv(4)); - axis[2]= Float.parseFloat(Cmd.Argv(5)); - } - else { - axis[0]= 0; - axis[1]= 0; - axis[2]= 1; - } - - re.SetSky(Cmd.Argv(1), rotate, axis); - } - - // ============================================================================ - - /* - ================== - SCR_Init - ================== - */ - static void Init() { - scr_viewsize= Cvar.Get("viewsize", "100", CVAR_ARCHIVE); - scr_conspeed= Cvar.Get("scr_conspeed", "3", 0); - scr_showturtle= Cvar.Get("scr_showturtle", "0", 0); - scr_showpause= Cvar.Get("scr_showpause", "1", 0); - scr_centertime= Cvar.Get("scr_centertime", "2.5", 0); - scr_printspeed= Cvar.Get("scr_printspeed", "8", 0); - scr_netgraph= Cvar.Get("netgraph", "1", 0); - scr_timegraph= Cvar.Get("timegraph", "1", 0); - scr_debuggraph= Cvar.Get("debuggraph", "1", 0); - scr_graphheight= Cvar.Get("graphheight", "32", 0); - scr_graphscale= Cvar.Get("graphscale", "1", 0); - scr_graphshift= Cvar.Get("graphshift", "0", 0); - scr_drawall= Cvar.Get("scr_drawall", "1", 0); - fps= Cvar.Get("fps", "0", 0); - - // - // register our commands - // - Cmd.AddCommand("timerefresh", new xcommand_t() { - public void execute() { - TimeRefresh_f(); - } - }); - Cmd.AddCommand("loading", new xcommand_t() { - public void execute() { - Loading_f(); - } - }); - Cmd.AddCommand("sizeup", new xcommand_t() { - public void execute() { - SizeUp_f(); - } - }); - Cmd.AddCommand("sizedown", new xcommand_t() { - public void execute() { - SizeDown_f(); - } - }); - Cmd.AddCommand("sky", new xcommand_t() { - public void execute() { - Sky_f(); - } - }); - - scr_initialized= true; - } - - /* - ============== - SCR_DrawNet - ============== - */ - static void DrawNet() { - if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP - 1) - return; - - re.DrawPic(scr_vrect.x + 64, scr_vrect.y, "net"); - } - - /* - ============== - SCR_DrawPause - ============== - */ - static void DrawPause() { - Dimension dim= new Dimension(); - - if (scr_showpause.value == 0) // turn off for screenshots - return; - - if (cl_paused.value == 0) - return; - - re.DrawGetPicSize(dim, "pause"); - re.DrawPic((viddef.width - dim.width) / 2, viddef.height / 2 + 8, "pause"); - } - - /* - ============== - SCR_DrawLoading - ============== - */ - static void DrawLoading() { - Dimension dim= new Dimension(); - - if (scr_draw_loading == 0) - return; - - scr_draw_loading= 0; - re.DrawGetPicSize(dim, "loading"); - re.DrawPic((viddef.width - dim.width) / 2, (viddef.height - dim.height) / 2, "loading"); - } - - // ============================================================================= - - /* - ================== - SCR_RunConsole - - Scroll it up or down - ================== - */ - static void RunConsole() { - // decide on the height of the console - if (cls.key_dest == key_console) - scr_conlines= 0.5f; // half screen - else - scr_conlines= 0; // none visible - - if (scr_conlines < scr_con_current) { - scr_con_current -= scr_conspeed.value * cls.frametime; - if (scr_conlines > scr_con_current) - scr_con_current= scr_conlines; - - } - else if (scr_conlines > scr_con_current) { - scr_con_current += scr_conspeed.value * cls.frametime; - if (scr_conlines < scr_con_current) - scr_con_current= scr_conlines; - } - } - - /* - ================== - SCR_DrawConsole - ================== - */ - static void DrawConsole() { - Console.CheckResize(); - - if (cls.state == ca_disconnected || cls.state == ca_connecting) { // forced full screen console - Console.DrawConsole(1.0f); - return; - } - - if (cls.state != ca_active || !cl.refresh_prepped) { // connected, but can't render - Console.DrawConsole(0.5f); - re.DrawFill(0, viddef.height / 2, viddef.width, viddef.height / 2, 0); - return; - } - - if (scr_con_current != 0) { - Console.DrawConsole(scr_con_current); - } - else { - if (cls.key_dest == key_game || cls.key_dest == key_message) - Console.DrawNotify(); // only draw notify in game - } - } - - // ============================================================================= - - /* - ================ - SCR_BeginLoadingPlaque - ================ - */ - public static void BeginLoadingPlaque() { - S.StopAllSounds(); - cl.sound_prepped= false; // don't play ambients - - if (cls.disable_screen != 0) - return; - if (developer.value != 0) - return; - if (cls.state == ca_disconnected) - return; // if at console, don't bring up the plaque - if (cls.key_dest == key_console) - return; - if (cl.cinematictime > 0) - scr_draw_loading= 2; // clear to balack first - else - scr_draw_loading= 1; - - UpdateScreen(); - cls.disable_screen= Sys.Milliseconds(); - cls.disable_servercount= cl.servercount; - } - - /* - ================ - SCR_EndLoadingPlaque - ================ - */ - public static void EndLoadingPlaque() { - cls.disable_screen= 0; - Console.ClearNotify(); - } - - /* - ================ - SCR_Loading_f - ================ - */ - static void Loading_f() { - BeginLoadingPlaque(); - } - - /* - ================ - SCR_TimeRefresh_f - ================ - */ - static void TimeRefresh_f() { - int i; - int start, stop; - float time; - - if (cls.state != ca_active) - return; - - start= Sys.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); - } - 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(); - } - } - - stop= Sys.Milliseconds(); - time= (stop - start) / 1000.0f; - Com.Printf("%f seconds (%f fps)\n", new Vargs(2).add(time).add(128.0f / time)); - } - - static void DirtyScreen() { - AddDirtyPoint(0, 0); - AddDirtyPoint(viddef.width - 1, viddef.height - 1); - } - - /* - ============== - SCR_TileClear - - Clear any parts of the tiled background that were drawn on last frame - ============== - */ - - static dirty_t clear= new dirty_t(); - - static void TileClear() { - int i; - int top, bottom, left, right; - clear.clear(); - - if (scr_drawall.value != 0) - DirtyScreen(); // for power vr or broken page flippers... - - if (scr_con_current == 1.0f) - return; // full screen console - if (scr_viewsize.value == 100) - return; // full screen rendering - if (cl.cinematictime > 0) - return; // full screen cinematic - - // erase rect will be the union of the past three frames - // so tripple buffering works properly - clear.set(scr_dirty); - for (i= 0; i < 2; i++) { - if (scr_old_dirty[i].x1 < clear.x1) - clear.x1= scr_old_dirty[i].x1; - if (scr_old_dirty[i].x2 > clear.x2) - clear.x2= scr_old_dirty[i].x2; - if (scr_old_dirty[i].y1 < clear.y1) - clear.y1= scr_old_dirty[i].y1; - if (scr_old_dirty[i].y2 > clear.y2) - clear.y2= scr_old_dirty[i].y2; - } - - scr_old_dirty[1].set(scr_old_dirty[0]); - scr_old_dirty[0].set(scr_dirty); - - scr_dirty.x1= 9999; - scr_dirty.x2= -9999; - scr_dirty.y1= 9999; - scr_dirty.y2= -9999; - - // don't bother with anything convered by the console) - top= (int) (scr_con_current * viddef.height); - if (top >= clear.y1) - clear.y1= top; - - if (clear.y2 <= clear.y1) - return; // nothing disturbed - - top= scr_vrect.y; - bottom= top + scr_vrect.height - 1; - left= scr_vrect.x; - right= left + scr_vrect.width - 1; - - if (clear.y1 < top) { // clear above view screen - i= clear.y2 < top - 1 ? clear.y2 : top - 1; - re.DrawTileClear(clear.x1, clear.y1, clear.x2 - clear.x1 + 1, i - clear.y1 + 1, "backtile"); - clear.y1= top; - } - if (clear.y2 > bottom) { // clear below view screen - i= clear.y1 > bottom + 1 ? clear.y1 : bottom + 1; - re.DrawTileClear(clear.x1, i, clear.x2 - clear.x1 + 1, clear.y2 - i + 1, "backtile"); - clear.y2= bottom; - } - if (clear.x1 < left) { // clear left of view screen - i= clear.x2 < left - 1 ? clear.x2 : left - 1; - re.DrawTileClear(clear.x1, clear.y1, i - clear.x1 + 1, clear.y2 - clear.y1 + 1, "backtile"); - clear.x1= left; - } - if (clear.x2 > right) { // clear left of view screen - i= clear.x1 > right + 1 ? clear.x1 : right + 1; - re.DrawTileClear(i, clear.y1, clear.x2 - i + 1, clear.y2 - clear.y1 + 1, "backtile"); - clear.x2= right; - } - - } - - // =============================================================== - - static final int STAT_MINUS= 10; // num frame for '-' stats digit - - static final int ICON_WIDTH= 24; - static final int ICON_HEIGHT= 24; - static final int CHAR_WIDTH= 16; - static final int ICON_SPACE= 8; - - /* - ================ - SizeHUDString - - Allow embedded \n in the string - ================ - */ - static void SizeHUDString(String string, Dimension dim) { - int lines, width, current; - - lines= 1; - width= 0; - - current= 0; - for (int i= 0; i < string.length(); i++) { - if (string.charAt(i) == '\n') { - lines++; - current= 0; - } - else { - current++; - if (current > width) - width= current; - } - - } - - dim.width= width * 8; - dim.height= lines * 8; - } - - static void DrawHUDString(String string, int x, int y, int centerwidth, int xor) { - int margin; - //char line[1024]; - StringBuffer line= new StringBuffer(1024); - int i; - - margin= x; - - for (int l= 0; l < string.length();) { - // scan out one line of text from the string - line= new StringBuffer(1024); - while (l < string.length() && string.charAt(l) != '\n') { - line.append(string.charAt(l)); - l++; - } - - if (centerwidth != 0) - x= margin + (centerwidth - line.length() * 8) / 2; - else - x= margin; - for (i= 0; i < line.length(); i++) { - re.DrawChar(x, y, line.charAt(i) ^ xor); - x += 8; - } - if (l < string.length()) { - l++; // skip the \n - x= margin; - y += 8; - } - } - } - - /* - ============== - SCR_DrawField - ============== - */ - static void DrawField(int x, int y, int color, int width, int value) { - char ptr; - String num; - int l; - int frame; - - if (width < 1) - return; - - // draw number string - if (width > 5) - width= 5; - - AddDirtyPoint(x, y); - AddDirtyPoint(x + width * CHAR_WIDTH + 2, y + 23); - - num= "" + value; - l= num.length(); - if (l > width) - l= width; - x += 2 + CHAR_WIDTH * (width - l); - - ptr= num.charAt(0); - - for (int i= 0; i < l; i++) { - ptr= num.charAt(i); - if (ptr == '-') - frame= STAT_MINUS; - else - frame= ptr - '0'; - - re.DrawPic(x, y, sb_nums[color][frame]); - x += CHAR_WIDTH; - } - } - - /* - =============== - SCR_TouchPics - - Allows rendering code to cache all needed sbar graphics - =============== - */ - static void TouchPics() { - int i, j; - - for (i= 0; i < 2; i++) - for (j= 0; j < 11; j++) - re.RegisterPic(sb_nums[i][j]); - - if (crosshair.value != 0.0f) { - if (crosshair.value > 3.0f || crosshair.value < 0.0f) - crosshair.value= 3.0f; - - crosshair_pic= "ch" + (int) crosshair.value; - Dimension dim= new Dimension(); - re.DrawGetPicSize(dim, crosshair_pic); - crosshair_width= dim.width; - crosshair_height= dim.height; - if (crosshair_width == 0) - crosshair_pic= ""; - } - } - - /* - ================ - SCR_ExecuteLayoutString - - ================ - */ - static void ExecuteLayoutString(String s) { - int x, y; - int value; - String token; - int width; - int index; - clientinfo_t ci; - - if (cls.state != ca_active || !cl.refresh_prepped) - return; - - // if (!s[0]) - if (s == null || s.length() == 0) - return; - - x= 0; - y= 0; - width= 3; - - Com.ParseHelp ph= new Com.ParseHelp(s); - - while (!ph.isEof()) { - token= Com.Parse(ph); - if (token.equals("xl")) { - token= Com.Parse(ph); - x= atoi(token); - continue; - } - if (token.equals("xr")) { - token= Com.Parse(ph); - x= viddef.width + atoi(token); - continue; - } - if (token.equals("xv")) { - token= Com.Parse(ph); - x= viddef.width / 2 - 160 + atoi(token); - continue; - } - - if (token.equals("yt")) { - token= Com.Parse(ph); - y= atoi(token); - continue; - } - if (token.equals("yb")) { - token= Com.Parse(ph); - y= viddef.height + atoi(token); - continue; - } - if (token.equals("yv")) { - token= Com.Parse(ph); - y= viddef.height / 2 - 120 + atoi(token); - continue; - } - - if (token.equals("pic")) { // draw a pic from a stat number - token= Com.Parse(ph); - value= cl.frame.playerstate.stats[atoi(token)]; - if (value >= MAX_IMAGES) - Com.Error(ERR_DROP, "Pic >= MAX_IMAGES"); - if (cl.configstrings[CS_IMAGES + value] != null) { - AddDirtyPoint(x, y); - AddDirtyPoint(x + 23, y + 23); - re.DrawPic(x, y, cl.configstrings[CS_IMAGES + value]); - } - continue; - } - - if (token.equals("client")) { // draw a deathmatch client block - int score, ping, time; - - token= Com.Parse(ph); - x= viddef.width / 2 - 160 + atoi(token); - token= Com.Parse(ph); - y= viddef.height / 2 - 120 + atoi(token); - AddDirtyPoint(x, y); - AddDirtyPoint(x + 159, y + 31); - - token= Com.Parse(ph); - value= atoi(token); - if (value >= MAX_CLIENTS || value < 0) - Com.Error(ERR_DROP, "client >= MAX_CLIENTS"); - ci= cl.clientinfo[value]; - - token= Com.Parse(ph); - score= atoi(token); - - token= Com.Parse(ph); - ping= atoi(token); - - token= Com.Parse(ph); - time= atoi(token); - - Console.DrawAltString(x + 32, y, ci.name); - Console.DrawString(x + 32, y + 8, "Score: "); - Console.DrawAltString(x + 32 + 7 * 8, y + 8, "" + score); - Console.DrawString(x + 32, y + 16, "Ping: " + ping); - Console.DrawString(x + 32, y + 24, "Time: " + time); - - if (ci.icon == null) - ci= cl.baseclientinfo; - re.DrawPic(x, y, ci.iconname); - continue; - } - - if (token.equals("ctf")) { // draw a ctf client block - int score, ping; - - token= Com.Parse(ph); - x= viddef.width / 2 - 160 + atoi(token); - token= Com.Parse(ph); - y= viddef.height / 2 - 120 + atoi(token); - AddDirtyPoint(x, y); - AddDirtyPoint(x + 159, y + 31); - - token= Com.Parse(ph); - value= atoi(token); - if (value >= MAX_CLIENTS || value < 0) - Com.Error(ERR_DROP, "client >= MAX_CLIENTS"); - ci= cl.clientinfo[value]; - - token= Com.Parse(ph); - score= atoi(token); - - token= Com.Parse(ph); - ping= atoi(token); - if (ping > 999) - ping= 999; - - // sprintf(block, "%3d %3d %-12.12s", score, ping, ci->name); - String block= Com.sprintf("%3d %3d %-12.12s", new Vargs(3).add(score).add(ping).add(ci.name)); - - if (value == cl.playernum) - Console.DrawAltString(x, y, block); - else - Console.DrawString(x, y, block); - continue; - } - - if (token.equals("picn")) { // draw a pic from a name - token= Com.Parse(ph); - AddDirtyPoint(x, y); - AddDirtyPoint(x + 23, y + 23); - re.DrawPic(x, y, token); - continue; - } - - if (token.equals("num")) { // draw a number - token= Com.Parse(ph); - width= atoi(token); - token= Com.Parse(ph); - value= cl.frame.playerstate.stats[atoi(token)]; - DrawField(x, y, 0, width, value); - continue; - } - - if (token.equals("hnum")) { // health number - int color; - - width= 3; - value= cl.frame.playerstate.stats[STAT_HEALTH]; - if (value > 25) - color= 0; // green - else if (value > 0) - color= (cl.frame.serverframe >> 2) & 1; // flash - else - color= 1; - - if ((cl.frame.playerstate.stats[STAT_FLASHES] & 1) != 0) - re.DrawPic(x, y, "field_3"); - - DrawField(x, y, color, width, value); - continue; - } - - if (token.equals("anum")) { // ammo number - int color; - - width= 3; - value= cl.frame.playerstate.stats[STAT_AMMO]; - if (value > 5) - color= 0; // green - else if (value >= 0) - color= (cl.frame.serverframe >> 2) & 1; // flash - else - continue; // negative number = don't show - - if ((cl.frame.playerstate.stats[STAT_FLASHES] & 4) != 0) - re.DrawPic(x, y, "field_3"); - - DrawField(x, y, color, width, value); - continue; - } - - if (token.equals("rnum")) { // armor number - int color; - - width= 3; - value= cl.frame.playerstate.stats[STAT_ARMOR]; - if (value < 1) - continue; - - color= 0; // green - - if ((cl.frame.playerstate.stats[STAT_FLASHES] & 2) != 0) - re.DrawPic(x, y, "field_3"); - - DrawField(x, y, color, width, value); - continue; - } - - if (token.equals("stat_string")) { - token= Com.Parse(ph); - index= atoi(token); - if (index < 0 || index >= MAX_CONFIGSTRINGS) - Com.Error(ERR_DROP, "Bad stat_string index"); - index= cl.frame.playerstate.stats[index]; - if (index < 0 || index >= MAX_CONFIGSTRINGS) - Com.Error(ERR_DROP, "Bad stat_string index"); - Console.DrawString(x, y, cl.configstrings[index]); - continue; - } - - if (token.equals("cstring")) { - token= Com.Parse(ph); - DrawHUDString(token, x, y, 320, 0); - continue; - } - - if (token.equals("string")) { - token= Com.Parse(ph); - Console.DrawString(x, y, token); - continue; - } - - if (token.equals("cstring2")) { - token= Com.Parse(ph); - DrawHUDString(token, x, y, 320, 0x80); - continue; - } - - if (token.equals("string2")) { - token= Com.Parse(ph); - Console.DrawAltString(x, y, token); - continue; - } - - if (token.equals("if")) { // draw a number - token= Com.Parse(ph); - value= cl.frame.playerstate.stats[atoi(token)]; - if (value == 0) { // skip to endif - // while (s && strcmp(token, "endif") ) - // { - // token = Com.Parse(ph); - // } - - while (!ph.isEof() && !(token= Com.Parse(ph)).equals("endif")); - - } - - continue; - } - - } - } - - /* - ================ - SCR_DrawStats - - The status bar is a small layout program that - is based on the stats array - ================ - */ - static void DrawStats() { - //TODO: - SCR.ExecuteLayoutString(cl.configstrings[CS_STATUSBAR]); - } - - /* - ================ - SCR_DrawLayout - - ================ - */ - static final int STAT_LAYOUTS= 13; - - static void DrawLayout() { - if (cl.frame.playerstate.stats[STAT_LAYOUTS] != 0) - SCR.ExecuteLayoutString(cl.layout); - } - - // ======================================================= - - /* - ================== - SCR_UpdateScreen - - This is called every frame, and can also be called explicitly to flush - text to the screen. - ================== - */ - static void UpdateScreen2() { - int numframes; - int i; - float[] separation= { 0, 0 }; - - // if the screen is disabled (loading plaque is up, or vid mode changing) - // do nothing at all - if (cls.disable_screen != 0) { - if (Sys.Milliseconds() - cls.disable_screen > 120000) { - cls.disable_screen= 0; - Com.Printf("Loading plaque timed out.\n"); - } - return; - } - - if (!scr_initialized || !con.initialized) - return; // not initialized yet - - /* - ** range check cl_camera_separation so we don't inadvertently fry someone's - ** brain - */ - if (cl_stereo_separation.value > 1.0) - Cvar.SetValue("cl_stereo_separation", 1.0f); - else if (cl_stereo_separation.value < 0) - Cvar.SetValue("cl_stereo_separation", 0.0f); - - if (cl_stereo.value != 0) { - numframes= 2; - separation[0]= -cl_stereo_separation.value / 2; - separation[1]= cl_stereo_separation.value / 2; - } - else { - separation[0]= 0; - separation[1]= 0; - numframes= 1; - } - - 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.width - dim.width) / 2, (viddef.height - dim.height) / 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 impl: cl_cin.c for cinematics - DrawCinematic(); - } - } - 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.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(); - } - - /* - ================= - SCR_DrawCrosshair - ================= - */ - static void DrawCrosshair() { - if (crosshair.value == 0.0f) - return; - - if (crosshair.modified) { - crosshair.modified= false; - SCR.TouchPics(); - } - - if (crosshair_pic.length() == 0) - return; - - re.DrawPic( - scr_vrect.x + ((scr_vrect.width - crosshair_width) >> 1), - scr_vrect.y + ((scr_vrect.height - crosshair_height) >> 1), - crosshair_pic); - } - - private static xcommand_t updateScreenCallback= new xcommand_t() { - public void execute() { - UpdateScreen2(); - } - }; - - // wird anstelle von der richtigen UpdateScreen benoetigt - public static void UpdateScreen() { - Globals.re.updateScreen(updateScreenCallback); - } - - /* - ================= - SCR_AddDirtyPoint - ================= - */ - static void AddDirtyPoint(int x, int y) { - if (x < scr_dirty.x1) - scr_dirty.x1= x; - if (x > scr_dirty.x2) - scr_dirty.x2= x; - if (y < scr_dirty.y1) - scr_dirty.y1= y; - if (y > scr_dirty.y2) - scr_dirty.y2= y; - } - - private static int lastframes= 0; - private static int lasttime= 0; - private static String fpsvalue= ""; - - static void DrawFPS() { - if (fps.value > 0.0f) { - if (fps.modified) { - fps.modified= false; - Cvar.SetValue("cl_maxfps", 1000); - } - - int diff= cls.realtime - lasttime; - if (diff > (int) (fps.value * 1000)) { - fpsvalue= (cls.framecount - lastframes) * 100000 / diff / 100.0f + " fps"; - lastframes= cls.framecount; - lasttime= cls.realtime; - } - int x= viddef.width - 8 * fpsvalue.length() - 2; - for (int i= 0; i < fpsvalue.length(); i++) { - re.DrawChar(x, 2, fpsvalue.charAt(i)); - x += 8; - } - } - else if (fps.modified) { - fps.modified= false; - Cvar.SetValue("cl_maxfps", 90); - } - } - - /* - ================================================================= - - cl_cin.c - - Play Cinematics - - ================================================================= - */ - - // typedef struct - // { - // byte *data; - // int count; - // } cblock_t; - // - // typedef struct - // { - // qboolean restart_sound; - // int s_rate; - // int s_width; - // int s_channels; - // - // int width; - // int height; - // byte *pic; - // byte *pic_pending; - // - // // order 1 huffman stuff - // int *hnodes1; // [256][256][2]; - // int numhnodes1[256]; - // - // int h_used[512]; - // int h_count[512]; - // } cinematics_t; - // - // cinematics_t cin; - // - // /* - // ================================================================= - // - // PCX LOADING - // - // ================================================================= - // */ - // - // - // /* - // ============== - // SCR_LoadPCX - // ============== - // */ - // void SCR_LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height) - // { - // byte *raw; - // pcx_t *pcx; - // int x, y; - // int len; - // int dataByte, runLength; - // byte *out, *pix; - // - // *pic = NULL; - // - // // - // // load the file - // // - // len = FS_LoadFile (filename, (void **)&raw); - // if (!raw) - // return; // Com_Printf ("Bad pcx file %s\n", filename); - // - // // - // // parse the PCX file - // // - // pcx = (pcx_t *)raw; - // raw = &pcx->data; - // - // if (pcx->manufacturer != 0x0a - // || pcx->version != 5 - // || pcx->encoding != 1 - // || pcx->bits_per_pixel != 8 - // || pcx->xmax >= 640 - // || pcx->ymax >= 480) - // { - // Com_Printf ("Bad pcx file %s\n", filename); - // return; - // } - // - // out = Z_Malloc ( (pcx->ymax+1) * (pcx->xmax+1) ); - // - // *pic = out; - // - // pix = out; - // - // if (palette) - // { - // *palette = Z_Malloc(768); - // memcpy (*palette, (byte *)pcx + len - 768, 768); - // } - // - // if (width) - // *width = pcx->xmax+1; - // if (height) - // *height = pcx->ymax+1; - // - // for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1) - // { - // for (x=0 ; x<=pcx->xmax ; ) - // { - // dataByte = *raw++; - // - // if((dataByte & 0xC0) == 0xC0) - // { - // runLength = dataByte & 0x3F; - // dataByte = *raw++; - // } - // else - // runLength = 1; - // - // while(runLength-- > 0) - // pix[x++] = dataByte; - // } - // - // } - // - // if ( raw - (byte *)pcx > len) - // { - // Com_Printf ("PCX file %s was malformed", filename); - // Z_Free (*pic); - // *pic = NULL; - // } - // - // FS_FreeFile (pcx); - // } - // - // ============================================================= - - /* - ================== - SCR_StopCinematic - ================== - */ - static void StopCinematic() { - cl.cinematictime= 0; // done - // if (cin.pic) - // { - // Z_Free (cin.pic); - // cin.pic = NULL; - // } - // if (cin.pic_pending) - // { - // Z_Free (cin.pic_pending); - // cin.pic_pending = NULL; - // } - if (cl.cinematicpalette_active) { - re.CinematicSetPalette(null); - cl.cinematicpalette_active= false; - } - // if (cl.cinematic_file) - // { - // fclose (cl.cinematic_file); - // cl.cinematic_file = NULL; - // } - // if (cin.hnodes1) - // { - // Z_Free (cin.hnodes1); - // cin.hnodes1 = NULL; - // } - // - // // switch back down to 11 khz sound if necessary - // if (cin.restart_sound) - // { - // cin.restart_sound = false; - // CL_Snd_Restart_f (); - // } - // - } - - /* - ==================== - SCR_FinishCinematic - - Called when either the cinematic completes, or it is aborted - ==================== - */ - static void FinishCinematic() { - // tell the server to advance to the next map / cinematic - MSG.WriteByte(cls.netchan.message, clc_stringcmd); - SZ.Print(cls.netchan.message, "nextserver " + cl.servercount + '\n'); - } - - // ========================================================================== - - // /* - // ================== - // SmallestNode1 - // ================== - // */ - // int SmallestNode1 (int numhnodes) - // { - // int i; - // int best, bestnode; - // - // best = 99999999; - // bestnode = -1; - // for (i=0 ; i<numhnodes ; i++) - // { - // if (cin.h_used[i]) - // continue; - // if (!cin.h_count[i]) - // continue; - // if (cin.h_count[i] < best) - // { - // best = cin.h_count[i]; - // bestnode = i; - // } - // } - // - // if (bestnode == -1) - // return -1; - // - // cin.h_used[bestnode] = true; - // return bestnode; - // } - // - // - // /* - // ================== - // Huff1TableInit - // - // Reads the 64k counts table and initializes the node trees - // ================== - // */ - // void Huff1TableInit (void) - // { - // int prev; - // int j; - // int *node, *nodebase; - // byte counts[256]; - // int numhnodes; - // - // cin.hnodes1 = Z_Malloc (256*256*2*4); - // memset (cin.hnodes1, 0, 256*256*2*4); - // - // for (prev=0 ; prev<256 ; prev++) - // { - // memset (cin.h_count,0,sizeof(cin.h_count)); - // memset (cin.h_used,0,sizeof(cin.h_used)); - // - // // read a row of counts - // FS_Read (counts, sizeof(counts), cl.cinematic_file); - // for (j=0 ; j<256 ; j++) - // cin.h_count[j] = counts[j]; - // - // // build the nodes - // numhnodes = 256; - // nodebase = cin.hnodes1 + prev*256*2; - // - // while (numhnodes != 511) - // { - // node = nodebase + (numhnodes-256)*2; - // - // // pick two lowest counts - // node[0] = SmallestNode1 (numhnodes); - // if (node[0] == -1) - // break; // no more - // - // node[1] = SmallestNode1 (numhnodes); - // if (node[1] == -1) - // break; - // - // cin.h_count[numhnodes] = cin.h_count[node[0]] + cin.h_count[node[1]]; - // numhnodes++; - // } - // - // cin.numhnodes1[prev] = numhnodes-1; - // } - // } - // - // /* - // ================== - // Huff1Decompress - // ================== - // */ - // cblock_t Huff1Decompress (cblock_t in) - // { - // byte *input; - // byte *out_p; - // int nodenum; - // int count; - // cblock_t out; - // int inbyte; - // int *hnodes, *hnodesbase; - //// int i; - // - // // get decompressed count - // count = in.data[0] + (in.data[1]<<8) + (in.data[2]<<16) + (in.data[3]<<24); - // input = in.data + 4; - // out_p = out.data = Z_Malloc (count); - // - // // read bits - // - // hnodesbase = cin.hnodes1 - 256*2; // nodes 0-255 aren't stored - // - // hnodes = hnodesbase; - // nodenum = cin.numhnodes1[0]; - // while (count) - // { - // inbyte = *input++; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // //----------- - // if (nodenum < 256) - // { - // hnodes = hnodesbase + (nodenum<<9); - // *out_p++ = nodenum; - // if (!--count) - // break; - // nodenum = cin.numhnodes1[nodenum]; - // } - // nodenum = hnodes[nodenum*2 + (inbyte&1)]; - // inbyte >>=1; - // } - // - // if (input - in.data != in.count && input - in.data != in.count+1) - // { - // Com_Printf ("Decompression overread by %i", (input - in.data) - in.count); - // } - // out.count = out_p - out.data; - // - // return out; - // } - // - // /* - // ================== - // SCR_ReadNextFrame - // ================== - // */ - // byte *SCR_ReadNextFrame (void) - // { - // int r; - // int command; - // byte samples[22050/14*4]; - // byte compressed[0x20000]; - // int size; - // byte *pic; - // cblock_t in, huf1; - // int start, end, count; - // - // // read the next frame - // r = fread (&command, 4, 1, cl.cinematic_file); - // if (r == 0) // we'll give it one more chance - // r = fread (&command, 4, 1, cl.cinematic_file); - // - // if (r != 1) - // return NULL; - // command = LittleLong(command); - // if (command == 2) - // return NULL; // last frame marker - // - // if (command == 1) - // { // read palette - // FS_Read (cl.cinematicpalette, sizeof(cl.cinematicpalette), cl.cinematic_file); - // cl.cinematicpalette_active=0; // dubious.... exposes an edge case - // } - // - // // decompress the next frame - // FS_Read (&size, 4, cl.cinematic_file); - // size = LittleLong(size); - // if (size > sizeof(compressed) || size < 1) - // Com_Error (ERR_DROP, "Bad compressed frame size"); - // FS_Read (compressed, size, cl.cinematic_file); - // - // // read sound - // start = cl.cinematicframe*cin.s_rate/14; - // end = (cl.cinematicframe+1)*cin.s_rate/14; - // count = end - start; - // - // FS_Read (samples, count*cin.s_width*cin.s_channels, cl.cinematic_file); - // - // S_RawSamples (count, cin.s_rate, cin.s_width, cin.s_channels, samples); - // - // in.data = compressed; - // in.count = size; - // - // huf1 = Huff1Decompress (in); - // - // pic = huf1.data; - // - // cl.cinematicframe++; - // - // return pic; - // } - // - // - /* - ================== - SCR_RunCinematic - - ================== - */ - static void RunCinematic() { - int frame; - - if (cl.cinematictime <= 0) { - StopCinematic(); - return; - } - - // if (cl.cinematicframe == -1) - // return; // static image - // - // if (cls.key_dest != key_game) - // { // pause if menu or console is up - // cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14; - // return; - // } - // - // frame = (cls.realtime - cl.cinematictime)*14.0/1000; - // if (frame <= cl.cinematicframe) - // return; - // if (frame > cl.cinematicframe+1) - // { - // Com_Printf ("Dropped frame: %i > %i\n", frame, cl.cinematicframe+1); - // cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14; - // } - // if (cin.pic) - // Z_Free (cin.pic); - // cin.pic = cin.pic_pending; - // cin.pic_pending = NULL; - // cin.pic_pending = SCR_ReadNextFrame (); - // if (!cin.pic_pending) - // { - // SCR_StopCinematic (); - // SCR_FinishCinematic (); - // cl.cinematictime = 1; // hack to get the black screen behind loading - // SCR_BeginLoadingPlaque (); - // cl.cinematictime = 0; - // return; - // } - } - - /* - ================== - SCR_DrawCinematic - - Returns true if a cinematic is active, meaning the view rendering - should be skipped - ================== - */ - static boolean DrawCinematic() { - // if (cl.cinematictime <= 0) - // { - return false; - // } - // - // if (cls.key_dest == key_menu) - // { // blank screen and pause if menu is up - // re.CinematicSetPalette(NULL); - // cl.cinematicpalette_active = false; - // return true; - // } - // - // if (!cl.cinematicpalette_active) - // { - // re.CinematicSetPalette(cl.cinematicpalette); - // cl.cinematicpalette_active = true; - // } - // - // if (!cin.pic) - // return true; - // - // re.DrawStretchRaw (0, 0, viddef.width, viddef.height, - // cin.width, cin.height, cin.pic); - // - // return true; - } - - /* - ================== - SCR_PlayCinematic - - ================== - */ - static void PlayCinematic(String arg) { - // int width, height; - // byte *palette; - // char name[MAX_OSPATH], *dot; - // int old_khz; - // - // // make sure CD isn't playing music - //CDAudio.Stop(); - - cl.cinematicframe= 0; - // dot = strstr (arg, "."); - // if (dot && !strcmp (dot, ".pcx")) - // { // static pcx image - // Com_sprintf (name, sizeof(name), "pics/%s", arg); - // SCR_LoadPCX (name, &cin.pic, &palette, &cin.width, &cin.height); - // cl.cinematicframe = -1; - // cl.cinematictime = 1; - // SCR_EndLoadingPlaque (); - // cls.state = ca_active; - // if (!cin.pic) - // { - // Com_Printf ("%s not found.\n", name); - // cl.cinematictime = 0; - // } - // else - // { - // memcpy (cl.cinematicpalette, palette, sizeof(cl.cinematicpalette)); - // Z_Free (palette); - // } - // return; - // } - // - // Com_sprintf (name, sizeof(name), "video/%s", arg); - // FS_FOpenFile (name, &cl.cinematic_file); - // if (!cl.cinematic_file) - // { - // Com_Error (ERR_DROP, "Cinematic %s not found.\n", name); - FinishCinematic(); - cl.cinematictime= 0; // done - return; - // } - // - // SCR_EndLoadingPlaque (); - // - // cls.state = ca_active; - // - // FS_Read (&width, 4, cl.cinematic_file); - // FS_Read (&height, 4, cl.cinematic_file); - // cin.width = LittleLong(width); - // cin.height = LittleLong(height); - // - // FS_Read (&cin.s_rate, 4, cl.cinematic_file); - // cin.s_rate = LittleLong(cin.s_rate); - // FS_Read (&cin.s_width, 4, cl.cinematic_file); - // cin.s_width = LittleLong(cin.s_width); - // FS_Read (&cin.s_channels, 4, cl.cinematic_file); - // cin.s_channels = LittleLong(cin.s_channels); - // - // Huff1TableInit (); - // - // // switch up to 22 khz sound if necessary - // old_khz = Cvar_VariableValue ("s_khz"); - // if (old_khz != cin.s_rate/1000) - // { - // cin.restart_sound = true; - // Cvar_SetValue ("s_khz", cin.s_rate/1000); - // CL_Snd_Restart_f (); - // Cvar_SetValue ("s_khz", old_khz); - // } - // - // cl.cinematicframe = 0; - // cin.pic = SCR_ReadNextFrame (); - // cl.cinematictime = Sys_Milliseconds (); - } + // cl_scrn.c -- master for refresh, status bar, console, chat, notify, etc + + static String[][] sb_nums = { + { "num_0", "num_1", "num_2", "num_3", "num_4", "num_5", "num_6", + "num_7", "num_8", "num_9", "num_minus" }, + { "anum_0", "anum_1", "anum_2", "anum_3", "anum_4", "anum_5", + "anum_6", "anum_7", "anum_8", "anum_9", "anum_minus" } }; + + /* + * full screen console put up loading plaque blanked background with loading + * plaque blanked background with menu cinematics full screen image for quit + * and victory + * + * end of unit intermissions + */ + + static float scr_con_current; // aproaches scr_conlines at scr_conspeed + + static float scr_conlines; // 0.0 to 1.0 lines of console to display + + static boolean scr_initialized; // ready to draw + + static int scr_draw_loading; + + // scr_vrect ist in Globals definiert + // position of render window on screen + + static cvar_t scr_viewsize; + + static cvar_t scr_conspeed; + + static cvar_t scr_centertime; + + static cvar_t scr_showturtle; + + static cvar_t scr_showpause; + + static cvar_t scr_printspeed; + + static cvar_t scr_netgraph; + + static cvar_t scr_timegraph; + + static cvar_t scr_debuggraph; + + static cvar_t scr_graphheight; + + static cvar_t scr_graphscale; + + static cvar_t scr_graphshift; + + static cvar_t scr_drawall; + + public static cvar_t fps; + + static dirty_t scr_dirty = new dirty_t(); + + static dirty_t[] scr_old_dirty = { new dirty_t(), new dirty_t() }; + + static String crosshair_pic; + + static int crosshair_width, crosshair_height; + + static class dirty_t { + int x1; + + int x2; + + int y1; + + int y2; + + void set(dirty_t src) { + x1 = src.x1; + x2 = src.x2; + y1 = src.y1; + y2 = src.y2; + } + + void clear() { + x1 = x2 = y1 = y2 = 0; + } + } + + /* + * =============================================================================== + * + * BAR GRAPHS + * + * =============================================================================== + */ + + // typedef struct + // { + // float value; + // int color; + // } graphsamp_t; + static class graphsamp_t { + float value; + + int color; + } + + static int current; + + static graphsamp_t[] values = new graphsamp_t[1024]; + + static { + for (int n = 0; n < 1024; n++) + values[n] = new graphsamp_t(); + } + + /* + * ============== SCR_DebugGraph ============== + */ + public static void DebugGraph(float value, int color) { + values[current & 1023].value = value; + values[current & 1023].color = color; + current++; + } + + /* + * ============== SCR_DrawDebugGraph ============== + */ + static void DrawDebugGraph() { + int a, x, y, w, i, h; + float v; + int color; + + // draw the graph + + w = scr_vrect.width; + + x = scr_vrect.x; + y = scr_vrect.y + scr_vrect.height; + re.DrawFill(x, (int) (y - scr_graphheight.value), w, + (int) scr_graphheight.value, 8); + + for (a = 0; a < w; a++) { + i = (current - 1 - a + 1024) & 1023; + v = values[i].value; + color = values[i].color; + v = v * scr_graphscale.value + scr_graphshift.value; + + if (v < 0) + v += scr_graphheight.value + * (1 + (int) (-v / scr_graphheight.value)); + h = (int) v % (int) scr_graphheight.value; + re.DrawFill(x + w - 1 - a, y - h, 1, h, color); + } + } + + /* + * =============================================================================== + * + * CENTER PRINTING + * + * =============================================================================== + */ + + // char scr_centerstring[1024]; + static String scr_centerstring; + + static float scr_centertime_start; // for slow victory printing + + static float scr_centertime_off; + + static int scr_center_lines; + + static int scr_erase_center; + + /* + * ============== SCR_CenterPrint + * + * Called for important messages that should stay in the center of the + * screen for a few moments ============== + */ + static void CenterPrint(String str) { + //char *s; + int s; + StringBuffer line = new StringBuffer(64); + int i, j, l; + + //strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1); + scr_centerstring = str; + scr_centertime_off = scr_centertime.value; + scr_centertime_start = cl.time; + + // count the number of lines for centering + scr_center_lines = 1; + s = 0; + while (s < str.length()) { + if (str.charAt(s) == '\n') + scr_center_lines++; + s++; + } + + // echo it to the console + Com + .Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); + + s = 0; + + if (str.length() != 0) { + do { + // scan the width of the line + + for (l = 0; l < 40 && (l + s) < str.length(); l++) + if (str.charAt(s + l) == '\n' || str.charAt(s + l) == 0) + break; + for (i = 0; i < (40 - l) / 2; i++) + line.append(' '); + + for (j = 0; j < l; j++) { + line.append(str.charAt(s + j)); + } + + line.append('\n'); + + Com.Printf(line.toString()); + + while (s < str.length() && str.charAt(s) != '\n') + s++; + + if (s == str.length()) + break; + s++; // skip the \n + } while (true); + } + Com + .Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n"); + Console.ClearNotify(); + } + + static void DrawCenterString() { + String cs = scr_centerstring + "\0"; + int start; + int l; + int j; + int x, y; + int remaining; + + if (cs == null) + return; + if (cs.length() == 0) + return; + + // the finale prints the characters one at a time + remaining = 9999; + + scr_erase_center = 0; + start = 0; + + if (scr_center_lines <= 4) + y = (int) (viddef.height * 0.35); + else + y = 48; + + do { + // scan the width of the line + for (l = 0; l < 40; l++) + if (start + l == cs.length() - 1 + || cs.charAt(start + l) == '\n') + break; + x = (viddef.width - l * 8) / 2; + SCR.AddDirtyPoint(x, y); + for (j = 0; j < l; j++, x += 8) { + re.DrawChar(x, y, cs.charAt(start + j)); + if (remaining == 0) + return; + remaining--; + } + SCR.AddDirtyPoint(x, y + 8); + + y += 8; + + while (start < cs.length() && cs.charAt(start) != '\n') + start++; + + if (start == cs.length()) + break; + start++; // skip the \n + } while (true); + } + + static void CheckDrawCenterString() { + scr_centertime_off -= cls.frametime; + + if (scr_centertime_off <= 0) + return; + + DrawCenterString(); + } + + // ============================================================================= + + /* + * ================= SCR_CalcVrect + * + * Sets scr_vrect, the coordinates of the rendered window ================= + */ + static void CalcVrect() { + int size; + + // bound viewsize + if (scr_viewsize.value < 40) + Cvar.Set("viewsize", "40"); + if (scr_viewsize.value > 100) + Cvar.Set("viewsize", "100"); + + size = (int) scr_viewsize.value; + + scr_vrect.width = viddef.width * size / 100; + scr_vrect.width &= ~7; + + scr_vrect.height = viddef.height * size / 100; + scr_vrect.height &= ~1; + + scr_vrect.x = (viddef.width - scr_vrect.width) / 2; + scr_vrect.y = (viddef.height - scr_vrect.height) / 2; + } + + /* + * ================= SCR_SizeUp_f + * + * Keybinding command ================= + */ + static void SizeUp_f() { + Cvar.SetValue("viewsize", scr_viewsize.value + 10); + } + + /* + * ================= SCR_SizeDown_f + * + * Keybinding command ================= + */ + static void SizeDown_f() { + Cvar.SetValue("viewsize", scr_viewsize.value - 10); + } + + /* + * ================= SCR_Sky_f + * + * Set a specific sky and rotation speed ================= + */ + static void Sky_f() { + float rotate; + float[] axis = { 0, 0, 0 }; + + if (Cmd.Argc() < 2) { + Com.Printf("Usage: sky <basename> <rotate> <axis x y z>\n"); + return; + } + if (Cmd.Argc() > 2) + rotate = Float.parseFloat(Cmd.Argv(2)); + else + rotate = 0; + if (Cmd.Argc() == 6) { + axis[0] = Float.parseFloat(Cmd.Argv(3)); + axis[1] = Float.parseFloat(Cmd.Argv(4)); + axis[2] = Float.parseFloat(Cmd.Argv(5)); + } else { + axis[0] = 0; + axis[1] = 0; + axis[2] = 1; + } + + re.SetSky(Cmd.Argv(1), rotate, axis); + } + + // ============================================================================ + + /* + * ================== SCR_Init ================== + */ + static void Init() { + scr_viewsize = Cvar.Get("viewsize", "100", CVAR_ARCHIVE); + scr_conspeed = Cvar.Get("scr_conspeed", "3", 0); + scr_showturtle = Cvar.Get("scr_showturtle", "0", 0); + scr_showpause = Cvar.Get("scr_showpause", "1", 0); + scr_centertime = Cvar.Get("scr_centertime", "2.5", 0); + scr_printspeed = Cvar.Get("scr_printspeed", "8", 0); + scr_netgraph = Cvar.Get("netgraph", "1", 0); + scr_timegraph = Cvar.Get("timegraph", "1", 0); + scr_debuggraph = Cvar.Get("debuggraph", "1", 0); + scr_graphheight = Cvar.Get("graphheight", "32", 0); + scr_graphscale = Cvar.Get("graphscale", "1", 0); + scr_graphshift = Cvar.Get("graphshift", "0", 0); + scr_drawall = Cvar.Get("scr_drawall", "1", 0); + fps = Cvar.Get("fps", "0", 0); + + // + // register our commands + // + Cmd.AddCommand("timerefresh", new xcommand_t() { + public void execute() { + TimeRefresh_f(); + } + }); + Cmd.AddCommand("loading", new xcommand_t() { + public void execute() { + Loading_f(); + } + }); + Cmd.AddCommand("sizeup", new xcommand_t() { + public void execute() { + SizeUp_f(); + } + }); + Cmd.AddCommand("sizedown", new xcommand_t() { + public void execute() { + SizeDown_f(); + } + }); + Cmd.AddCommand("sky", new xcommand_t() { + public void execute() { + Sky_f(); + } + }); + + scr_initialized = true; + } + + /* + * ============== SCR_DrawNet ============== + */ + static void DrawNet() { + if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < CMD_BACKUP - 1) + return; + + re.DrawPic(scr_vrect.x + 64, scr_vrect.y, "net"); + } + + /* + * ============== SCR_DrawPause ============== + */ + static void DrawPause() { + Dimension dim = new Dimension(); + + if (scr_showpause.value == 0) // turn off for screenshots + return; + + if (cl_paused.value == 0) + return; + + re.DrawGetPicSize(dim, "pause"); + re.DrawPic((viddef.width - dim.width) / 2, viddef.height / 2 + 8, + "pause"); + } + + /* + * ============== SCR_DrawLoading ============== + */ + static void DrawLoading() { + Dimension dim = new Dimension(); + + if (scr_draw_loading == 0) + return; + + scr_draw_loading = 0; + re.DrawGetPicSize(dim, "loading"); + re.DrawPic((viddef.width - dim.width) / 2, + (viddef.height - dim.height) / 2, "loading"); + } + + // ============================================================================= + + /* + * ================== SCR_RunConsole + * + * Scroll it up or down ================== + */ + static void RunConsole() { + // decide on the height of the console + if (cls.key_dest == key_console) + scr_conlines = 0.5f; // half screen + else + scr_conlines = 0; // none visible + + if (scr_conlines < scr_con_current) { + scr_con_current -= scr_conspeed.value * cls.frametime; + if (scr_conlines > scr_con_current) + scr_con_current = scr_conlines; + + } else if (scr_conlines > scr_con_current) { + scr_con_current += scr_conspeed.value * cls.frametime; + if (scr_conlines < scr_con_current) + scr_con_current = scr_conlines; + } + } + + /* + * ================== SCR_DrawConsole ================== + */ + static void DrawConsole() { + Console.CheckResize(); + + if (cls.state == ca_disconnected || cls.state == ca_connecting) { // forced + // full + // screen + // console + Console.DrawConsole(1.0f); + return; + } + + if (cls.state != ca_active || !cl.refresh_prepped) { // connected, but + // can't render + Console.DrawConsole(0.5f); + re.DrawFill(0, viddef.height / 2, viddef.width, viddef.height / 2, + 0); + return; + } + + if (scr_con_current != 0) { + Console.DrawConsole(scr_con_current); + } else { + if (cls.key_dest == key_game || cls.key_dest == key_message) + Console.DrawNotify(); // only draw notify in game + } + } + + // ============================================================================= + + /* + * ================ SCR_BeginLoadingPlaque ================ + */ + public static void BeginLoadingPlaque() { + S.StopAllSounds(); + cl.sound_prepped = false; // don't play ambients + + if (cls.disable_screen != 0) + return; + if (developer.value != 0) + return; + if (cls.state == ca_disconnected) + return; // if at console, don't bring up the plaque + if (cls.key_dest == key_console) + return; + if (cl.cinematictime > 0) + scr_draw_loading = 2; // clear to balack first + else + scr_draw_loading = 1; + + UpdateScreen(); + cls.disable_screen = Sys.Milliseconds(); + cls.disable_servercount = cl.servercount; + } + + /* + * ================ SCR_EndLoadingPlaque ================ + */ + public static void EndLoadingPlaque() { + cls.disable_screen = 0; + Console.ClearNotify(); + } + + /* + * ================ SCR_Loading_f ================ + */ + static void Loading_f() { + BeginLoadingPlaque(); + } + + /* + * ================ SCR_TimeRefresh_f ================ + */ + static void TimeRefresh_f() { + int i; + int start, stop; + float time; + + if (cls.state != ca_active) + return; + + start = Sys.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); + } + 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(); + } + } + + stop = Sys.Milliseconds(); + time = (stop - start) / 1000.0f; + Com.Printf("%f seconds (%f fps)\n", new Vargs(2).add(time).add( + 128.0f / time)); + } + + static void DirtyScreen() { + AddDirtyPoint(0, 0); + AddDirtyPoint(viddef.width - 1, viddef.height - 1); + } + + /* + * ============== SCR_TileClear + * + * Clear any parts of the tiled background that were drawn on last frame + * ============== + */ + + static dirty_t clear = new dirty_t(); + + static void TileClear() { + int i; + int top, bottom, left, right; + clear.clear(); + + if (scr_drawall.value != 0) + DirtyScreen(); // for power vr or broken page flippers... + + if (scr_con_current == 1.0f) + return; // full screen console + if (scr_viewsize.value == 100) + return; // full screen rendering + if (cl.cinematictime > 0) + return; // full screen cinematic + + // erase rect will be the union of the past three frames + // so tripple buffering works properly + clear.set(scr_dirty); + for (i = 0; i < 2; i++) { + if (scr_old_dirty[i].x1 < clear.x1) + clear.x1 = scr_old_dirty[i].x1; + if (scr_old_dirty[i].x2 > clear.x2) + clear.x2 = scr_old_dirty[i].x2; + if (scr_old_dirty[i].y1 < clear.y1) + clear.y1 = scr_old_dirty[i].y1; + if (scr_old_dirty[i].y2 > clear.y2) + clear.y2 = scr_old_dirty[i].y2; + } + + scr_old_dirty[1].set(scr_old_dirty[0]); + scr_old_dirty[0].set(scr_dirty); + + scr_dirty.x1 = 9999; + scr_dirty.x2 = -9999; + scr_dirty.y1 = 9999; + scr_dirty.y2 = -9999; + + // don't bother with anything convered by the console) + top = (int) (scr_con_current * viddef.height); + if (top >= clear.y1) + clear.y1 = top; + + if (clear.y2 <= clear.y1) + return; // nothing disturbed + + top = scr_vrect.y; + bottom = top + scr_vrect.height - 1; + left = scr_vrect.x; + right = left + scr_vrect.width - 1; + + if (clear.y1 < top) { // clear above view screen + i = clear.y2 < top - 1 ? clear.y2 : top - 1; + re.DrawTileClear(clear.x1, clear.y1, clear.x2 - clear.x1 + 1, i + - clear.y1 + 1, "backtile"); + clear.y1 = top; + } + if (clear.y2 > bottom) { // clear below view screen + i = clear.y1 > bottom + 1 ? clear.y1 : bottom + 1; + re.DrawTileClear(clear.x1, i, clear.x2 - clear.x1 + 1, clear.y2 - i + + 1, "backtile"); + clear.y2 = bottom; + } + if (clear.x1 < left) { // clear left of view screen + i = clear.x2 < left - 1 ? clear.x2 : left - 1; + re.DrawTileClear(clear.x1, clear.y1, i - clear.x1 + 1, clear.y2 + - clear.y1 + 1, "backtile"); + clear.x1 = left; + } + if (clear.x2 > right) { // clear left of view screen + i = clear.x1 > right + 1 ? clear.x1 : right + 1; + re.DrawTileClear(i, clear.y1, clear.x2 - i + 1, clear.y2 - clear.y1 + + 1, "backtile"); + clear.x2 = right; + } + + } + + // =============================================================== + + static final int STAT_MINUS = 10; // num frame for '-' stats digit + + static final int ICON_WIDTH = 24; + + static final int ICON_HEIGHT = 24; + + static final int CHAR_WIDTH = 16; + + static final int ICON_SPACE = 8; + + /* + * ================ SizeHUDString + * + * Allow embedded \n in the string ================ + */ + static void SizeHUDString(String string, Dimension dim) { + int lines, width, current; + + lines = 1; + width = 0; + + current = 0; + for (int i = 0; i < string.length(); i++) { + if (string.charAt(i) == '\n') { + lines++; + current = 0; + } else { + current++; + if (current > width) + width = current; + } + + } + + dim.width = width * 8; + dim.height = lines * 8; + } + + static void DrawHUDString(String string, int x, int y, int centerwidth, + int xor) { + int margin; + //char line[1024]; + StringBuffer line = new StringBuffer(1024); + int i; + + margin = x; + + for (int l = 0; l < string.length();) { + // scan out one line of text from the string + line = new StringBuffer(1024); + while (l < string.length() && string.charAt(l) != '\n') { + line.append(string.charAt(l)); + l++; + } + + if (centerwidth != 0) + x = margin + (centerwidth - line.length() * 8) / 2; + else + x = margin; + for (i = 0; i < line.length(); i++) { + re.DrawChar(x, y, line.charAt(i) ^ xor); + x += 8; + } + if (l < string.length()) { + l++; // skip the \n + x = margin; + y += 8; + } + } + } + + /* + * ============== SCR_DrawField ============== + */ + static void DrawField(int x, int y, int color, int width, int value) { + char ptr; + String num; + int l; + int frame; + + if (width < 1) + return; + + // draw number string + if (width > 5) + width = 5; + + AddDirtyPoint(x, y); + AddDirtyPoint(x + width * CHAR_WIDTH + 2, y + 23); + + num = "" + value; + l = num.length(); + if (l > width) + l = width; + x += 2 + CHAR_WIDTH * (width - l); + + ptr = num.charAt(0); + + for (int i = 0; i < l; i++) { + ptr = num.charAt(i); + if (ptr == '-') + frame = STAT_MINUS; + else + frame = ptr - '0'; + + re.DrawPic(x, y, sb_nums[color][frame]); + x += CHAR_WIDTH; + } + } + + /* + * =============== SCR_TouchPics + * + * Allows rendering code to cache all needed sbar graphics =============== + */ + static void TouchPics() { + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 11; j++) + re.RegisterPic(sb_nums[i][j]); + + if (crosshair.value != 0.0f) { + if (crosshair.value > 3.0f || crosshair.value < 0.0f) + crosshair.value = 3.0f; + + crosshair_pic = "ch" + (int) crosshair.value; + Dimension dim = new Dimension(); + re.DrawGetPicSize(dim, crosshair_pic); + crosshair_width = dim.width; + crosshair_height = dim.height; + if (crosshair_width == 0) + crosshair_pic = ""; + } + } + + /* + * ================ SCR_ExecuteLayoutString + * + * ================ + */ + static void ExecuteLayoutString(String s) { + int x, y; + int value; + String token; + int width; + int index; + clientinfo_t ci; + + if (cls.state != ca_active || !cl.refresh_prepped) + return; + + // if (!s[0]) + if (s == null || s.length() == 0) + return; + + x = 0; + y = 0; + width = 3; + + Com.ParseHelp ph = new Com.ParseHelp(s); + + while (!ph.isEof()) { + token = Com.Parse(ph); + if (token.equals("xl")) { + token = Com.Parse(ph); + x = Lib.atoi(token); + continue; + } + if (token.equals("xr")) { + token = Com.Parse(ph); + x = viddef.width + Lib.atoi(token); + continue; + } + if (token.equals("xv")) { + token = Com.Parse(ph); + x = viddef.width / 2 - 160 + Lib.atoi(token); + continue; + } + + if (token.equals("yt")) { + token = Com.Parse(ph); + y = Lib.atoi(token); + continue; + } + if (token.equals("yb")) { + token = Com.Parse(ph); + y = viddef.height + Lib.atoi(token); + continue; + } + if (token.equals("yv")) { + token = Com.Parse(ph); + y = viddef.height / 2 - 120 + Lib.atoi(token); + continue; + } + + if (token.equals("pic")) { // draw a pic from a stat number + token = Com.Parse(ph); + value = cl.frame.playerstate.stats[Lib.atoi(token)]; + if (value >= MAX_IMAGES) + Com.Error(ERR_DROP, "Pic >= MAX_IMAGES"); + if (cl.configstrings[CS_IMAGES + value] != null) { + AddDirtyPoint(x, y); + AddDirtyPoint(x + 23, y + 23); + re.DrawPic(x, y, cl.configstrings[CS_IMAGES + value]); + } + continue; + } + + if (token.equals("client")) { // draw a deathmatch client block + int score, ping, time; + + token = Com.Parse(ph); + x = viddef.width / 2 - 160 + Lib.atoi(token); + token = Com.Parse(ph); + y = viddef.height / 2 - 120 + Lib.atoi(token); + AddDirtyPoint(x, y); + AddDirtyPoint(x + 159, y + 31); + + token = Com.Parse(ph); + value = Lib.atoi(token); + if (value >= MAX_CLIENTS || value < 0) + Com.Error(ERR_DROP, "client >= MAX_CLIENTS"); + ci = cl.clientinfo[value]; + + token = Com.Parse(ph); + score = Lib.atoi(token); + + token = Com.Parse(ph); + ping = Lib.atoi(token); + + token = Com.Parse(ph); + time = Lib.atoi(token); + + Console.DrawAltString(x + 32, y, ci.name); + Console.DrawString(x + 32, y + 8, "Score: "); + Console.DrawAltString(x + 32 + 7 * 8, y + 8, "" + score); + Console.DrawString(x + 32, y + 16, "Ping: " + ping); + Console.DrawString(x + 32, y + 24, "Time: " + time); + + if (ci.icon == null) + ci = cl.baseclientinfo; + re.DrawPic(x, y, ci.iconname); + continue; + } + + if (token.equals("ctf")) { // draw a ctf client block + int score, ping; + + token = Com.Parse(ph); + x = viddef.width / 2 - 160 + Lib.atoi(token); + token = Com.Parse(ph); + y = viddef.height / 2 - 120 + Lib.atoi(token); + AddDirtyPoint(x, y); + AddDirtyPoint(x + 159, y + 31); + + token = Com.Parse(ph); + value = Lib.atoi(token); + if (value >= MAX_CLIENTS || value < 0) + Com.Error(ERR_DROP, "client >= MAX_CLIENTS"); + ci = cl.clientinfo[value]; + + token = Com.Parse(ph); + score = Lib.atoi(token); + + token = Com.Parse(ph); + ping = Lib.atoi(token); + if (ping > 999) + ping = 999; + + // sprintf(block, "%3d %3d %-12.12s", score, ping, ci->name); + String block = Com.sprintf("%3d %3d %-12.12s", new Vargs(3) + .add(score).add(ping).add(ci.name)); + + if (value == cl.playernum) + Console.DrawAltString(x, y, block); + else + Console.DrawString(x, y, block); + continue; + } + + if (token.equals("picn")) { // draw a pic from a name + token = Com.Parse(ph); + AddDirtyPoint(x, y); + AddDirtyPoint(x + 23, y + 23); + re.DrawPic(x, y, token); + continue; + } + + if (token.equals("num")) { // draw a number + token = Com.Parse(ph); + width = Lib.atoi(token); + token = Com.Parse(ph); + value = cl.frame.playerstate.stats[Lib.atoi(token)]; + DrawField(x, y, 0, width, value); + continue; + } + + if (token.equals("hnum")) { // health number + int color; + + width = 3; + value = cl.frame.playerstate.stats[STAT_HEALTH]; + if (value > 25) + color = 0; // green + else if (value > 0) + color = (cl.frame.serverframe >> 2) & 1; // flash + else + color = 1; + + if ((cl.frame.playerstate.stats[STAT_FLASHES] & 1) != 0) + re.DrawPic(x, y, "field_3"); + + DrawField(x, y, color, width, value); + continue; + } + + if (token.equals("anum")) { // ammo number + int color; + + width = 3; + value = cl.frame.playerstate.stats[STAT_AMMO]; + if (value > 5) + color = 0; // green + else if (value >= 0) + color = (cl.frame.serverframe >> 2) & 1; // flash + else + continue; // negative number = don't show + + if ((cl.frame.playerstate.stats[STAT_FLASHES] & 4) != 0) + re.DrawPic(x, y, "field_3"); + + DrawField(x, y, color, width, value); + continue; + } + + if (token.equals("rnum")) { // armor number + int color; + + width = 3; + value = cl.frame.playerstate.stats[STAT_ARMOR]; + if (value < 1) + continue; + + color = 0; // green + + if ((cl.frame.playerstate.stats[STAT_FLASHES] & 2) != 0) + re.DrawPic(x, y, "field_3"); + + DrawField(x, y, color, width, value); + continue; + } + + if (token.equals("stat_string")) { + token = Com.Parse(ph); + index = Lib.atoi(token); + if (index < 0 || index >= MAX_CONFIGSTRINGS) + Com.Error(ERR_DROP, "Bad stat_string index"); + index = cl.frame.playerstate.stats[index]; + if (index < 0 || index >= MAX_CONFIGSTRINGS) + Com.Error(ERR_DROP, "Bad stat_string index"); + Console.DrawString(x, y, cl.configstrings[index]); + continue; + } + + if (token.equals("cstring")) { + token = Com.Parse(ph); + DrawHUDString(token, x, y, 320, 0); + continue; + } + + if (token.equals("string")) { + token = Com.Parse(ph); + Console.DrawString(x, y, token); + continue; + } + + if (token.equals("cstring2")) { + token = Com.Parse(ph); + DrawHUDString(token, x, y, 320, 0x80); + continue; + } + + if (token.equals("string2")) { + token = Com.Parse(ph); + Console.DrawAltString(x, y, token); + continue; + } + + if (token.equals("if")) { // draw a number + token = Com.Parse(ph); + value = cl.frame.playerstate.stats[Lib.atoi(token)]; + if (value == 0) { // skip to endif + // while (s && strcmp(token, "endif") ) + // { + // token = Com.Parse(ph); + // } + + while (!ph.isEof() + && !(token = Com.Parse(ph)).equals("endif")) + ; + + } + + continue; + } + + } + } + + /* + * ================ SCR_DrawStats + * + * The status bar is a small layout program that is based on the stats array + * ================ + */ + static void DrawStats() { + //TODO: + SCR.ExecuteLayoutString(cl.configstrings[CS_STATUSBAR]); + } + + /* + * ================ SCR_DrawLayout + * + * ================ + */ + static final int STAT_LAYOUTS = 13; + + static void DrawLayout() { + if (cl.frame.playerstate.stats[STAT_LAYOUTS] != 0) + SCR.ExecuteLayoutString(cl.layout); + } + + // ======================================================= + + /* + * ================== SCR_UpdateScreen + * + * This is called every frame, and can also be called explicitly to flush + * text to the screen. ================== + */ + static void UpdateScreen2() { + int numframes; + int i; + float[] separation = { 0, 0 }; + + // if the screen is disabled (loading plaque is up, or vid mode + // changing) + // do nothing at all + if (cls.disable_screen != 0) { + if (Sys.Milliseconds() - cls.disable_screen > 120000) { + cls.disable_screen = 0; + Com.Printf("Loading plaque timed out.\n"); + } + return; + } + + if (!scr_initialized || !con.initialized) + return; // not initialized yet + + /* + * * range check cl_camera_separation so we don't inadvertently fry + * someone's * brain + */ + if (cl_stereo_separation.value > 1.0) + Cvar.SetValue("cl_stereo_separation", 1.0f); + else if (cl_stereo_separation.value < 0) + Cvar.SetValue("cl_stereo_separation", 0.0f); + + if (cl_stereo.value != 0) { + numframes = 2; + separation[0] = -cl_stereo_separation.value / 2; + separation[1] = cl_stereo_separation.value / 2; + } else { + separation[0] = 0; + separation[1] = 0; + numframes = 1; + } + + 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.width - dim.width) / 2, + (viddef.height - dim.height) / 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 impl: cl_cin.c for cinematics + DrawCinematic(); + } + } 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(); + Menu.Draw(); + DrawLoading(); + } + } + + Globals.re.EndFrame(); + } + + /* + * ================= SCR_DrawCrosshair ================= + */ + static void DrawCrosshair() { + if (crosshair.value == 0.0f) + return; + + if (crosshair.modified) { + crosshair.modified = false; + SCR.TouchPics(); + } + + if (crosshair_pic.length() == 0) + return; + + re.DrawPic(scr_vrect.x + ((scr_vrect.width - crosshair_width) >> 1), + scr_vrect.y + ((scr_vrect.height - crosshair_height) >> 1), + crosshair_pic); + } + + private static xcommand_t updateScreenCallback = new xcommand_t() { + public void execute() { + UpdateScreen2(); + } + }; + + // wird anstelle von der richtigen UpdateScreen benoetigt + public static void UpdateScreen() { + Globals.re.updateScreen(updateScreenCallback); + } + + /* + * ================= SCR_AddDirtyPoint ================= + */ + static void AddDirtyPoint(int x, int y) { + if (x < scr_dirty.x1) + scr_dirty.x1 = x; + if (x > scr_dirty.x2) + scr_dirty.x2 = x; + if (y < scr_dirty.y1) + scr_dirty.y1 = y; + if (y > scr_dirty.y2) + scr_dirty.y2 = y; + } + + private static int lastframes = 0; + + private static int lasttime = 0; + + private static String fpsvalue = ""; + + static void DrawFPS() { + if (fps.value > 0.0f) { + if (fps.modified) { + fps.modified = false; + Cvar.SetValue("cl_maxfps", 1000); + } + + int diff = cls.realtime - lasttime; + if (diff > (int) (fps.value * 1000)) { + fpsvalue = (cls.framecount - lastframes) * 100000 / diff + / 100.0f + " fps"; + lastframes = cls.framecount; + lasttime = cls.realtime; + } + int x = viddef.width - 8 * fpsvalue.length() - 2; + for (int i = 0; i < fpsvalue.length(); i++) { + re.DrawChar(x, 2, fpsvalue.charAt(i)); + x += 8; + } + } else if (fps.modified) { + fps.modified = false; + Cvar.SetValue("cl_maxfps", 90); + } + } + + /* + * ================================================================= + * + * cl_cin.c + * + * Play Cinematics + * + * ================================================================= + */ + + // typedef struct + // { + // byte *data; + // int count; + // } cblock_t; + // + // typedef struct + // { + // qboolean restart_sound; + // int s_rate; + // int s_width; + // int s_channels; + // + // int width; + // int height; + // byte *pic; + // byte *pic_pending; + // + // // order 1 huffman stuff + // int *hnodes1; // [256][256][2]; + // int numhnodes1[256]; + // + // int h_used[512]; + // int h_count[512]; + // } cinematics_t; + // + // cinematics_t cin; + // + // /* + // ================================================================= + // + // PCX LOADING + // + // ================================================================= + // */ + // + // + // /* + // ============== + // SCR_LoadPCX + // ============== + // */ + // void SCR_LoadPCX (char *filename, byte **pic, byte **palette, int *width, + // int *height) + // { + // byte *raw; + // pcx_t *pcx; + // int x, y; + // int len; + // int dataByte, runLength; + // byte *out, *pix; + // + // *pic = NULL; + // + // // + // // load the file + // // + // len = FS_LoadFile (filename, (void **)&raw); + // if (!raw) + // return; // Com_Printf ("Bad pcx file %s\n", filename); + // + // // + // // parse the PCX file + // // + // pcx = (pcx_t *)raw; + // raw = &pcx->data; + // + // if (pcx->manufacturer != 0x0a + // || pcx->version != 5 + // || pcx->encoding != 1 + // || pcx->bits_per_pixel != 8 + // || pcx->xmax >= 640 + // || pcx->ymax >= 480) + // { + // Com_Printf ("Bad pcx file %s\n", filename); + // return; + // } + // + // out = Z_Malloc ( (pcx->ymax+1) * (pcx->xmax+1) ); + // + // *pic = out; + // + // pix = out; + // + // if (palette) + // { + // *palette = Z_Malloc(768); + // memcpy (*palette, (byte *)pcx + len - 768, 768); + // } + // + // if (width) + // *width = pcx->xmax+1; + // if (height) + // *height = pcx->ymax+1; + // + // for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1) + // { + // for (x=0 ; x<=pcx->xmax ; ) + // { + // dataByte = *raw++; + // + // if((dataByte & 0xC0) == 0xC0) + // { + // runLength = dataByte & 0x3F; + // dataByte = *raw++; + // } + // else + // runLength = 1; + // + // while(runLength-- > 0) + // pix[x++] = dataByte; + // } + // + // } + // + // if ( raw - (byte *)pcx > len) + // { + // Com_Printf ("PCX file %s was malformed", filename); + // Z_Free (*pic); + // *pic = NULL; + // } + // + // FS_FreeFile (pcx); + // } + // + // ============================================================= + /* + * ================== SCR_StopCinematic ================== + */ + static void StopCinematic() { + cl.cinematictime = 0; // done + // if (cin.pic) + // { + // Z_Free (cin.pic); + // cin.pic = NULL; + // } + // if (cin.pic_pending) + // { + // Z_Free (cin.pic_pending); + // cin.pic_pending = NULL; + // } + if (cl.cinematicpalette_active) { + re.CinematicSetPalette(null); + cl.cinematicpalette_active = false; + } + // if (cl.cinematic_file) + // { + // fclose (cl.cinematic_file); + // cl.cinematic_file = NULL; + // } + // if (cin.hnodes1) + // { + // Z_Free (cin.hnodes1); + // cin.hnodes1 = NULL; + // } + // + // // switch back down to 11 khz sound if necessary + // if (cin.restart_sound) + // { + // cin.restart_sound = false; + // CL_Snd_Restart_f (); + // } + // + } + + /* + * ==================== SCR_FinishCinematic + * + * Called when either the cinematic completes, or it is aborted + * ==================== + */ + static void FinishCinematic() { + // tell the server to advance to the next map / cinematic + MSG.WriteByte(cls.netchan.message, clc_stringcmd); + SZ.Print(cls.netchan.message, "nextserver " + cl.servercount + '\n'); + } + + // ========================================================================== + + // /* + // ================== + // SmallestNode1 + // ================== + // */ + // int SmallestNode1 (int numhnodes) + // { + // int i; + // int best, bestnode; + // + // best = 99999999; + // bestnode = -1; + // for (i=0 ; i<numhnodes ; i++) + // { + // if (cin.h_used[i]) + // continue; + // if (!cin.h_count[i]) + // continue; + // if (cin.h_count[i] < best) + // { + // best = cin.h_count[i]; + // bestnode = i; + // } + // } + // + // if (bestnode == -1) + // return -1; + // + // cin.h_used[bestnode] = true; + // return bestnode; + // } + // + // + // /* + // ================== + // Huff1TableInit + // + // Reads the 64k counts table and initializes the node trees + // ================== + // */ + // void Huff1TableInit (void) + // { + // int prev; + // int j; + // int *node, *nodebase; + // byte counts[256]; + // int numhnodes; + // + // cin.hnodes1 = Z_Malloc (256*256*2*4); + // memset (cin.hnodes1, 0, 256*256*2*4); + // + // for (prev=0 ; prev<256 ; prev++) + // { + // memset (cin.h_count,0,sizeof(cin.h_count)); + // memset (cin.h_used,0,sizeof(cin.h_used)); + // + // // read a row of counts + // FS_Read (counts, sizeof(counts), cl.cinematic_file); + // for (j=0 ; j<256 ; j++) + // cin.h_count[j] = counts[j]; + // + // // build the nodes + // numhnodes = 256; + // nodebase = cin.hnodes1 + prev*256*2; + // + // while (numhnodes != 511) + // { + // node = nodebase + (numhnodes-256)*2; + // + // // pick two lowest counts + // node[0] = SmallestNode1 (numhnodes); + // if (node[0] == -1) + // break; // no more + // + // node[1] = SmallestNode1 (numhnodes); + // if (node[1] == -1) + // break; + // + // cin.h_count[numhnodes] = cin.h_count[node[0]] + cin.h_count[node[1]]; + // numhnodes++; + // } + // + // cin.numhnodes1[prev] = numhnodes-1; + // } + // } + // + // /* + // ================== + // Huff1Decompress + // ================== + // */ + // cblock_t Huff1Decompress (cblock_t in) + // { + // byte *input; + // byte *out_p; + // int nodenum; + // int count; + // cblock_t out; + // int inbyte; + // int *hnodes, *hnodesbase; + //// int i; + // + // // get decompressed count + // count = in.data[0] + (in.data[1]<<8) + (in.data[2]<<16) + + // (in.data[3]<<24); + // input = in.data + 4; + // out_p = out.data = Z_Malloc (count); + // + // // read bits + // + // hnodesbase = cin.hnodes1 - 256*2; // nodes 0-255 aren't stored + // + // hnodes = hnodesbase; + // nodenum = cin.numhnodes1[0]; + // while (count) + // { + // inbyte = *input++; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // //----------- + // if (nodenum < 256) + // { + // hnodes = hnodesbase + (nodenum<<9); + // *out_p++ = nodenum; + // if (!--count) + // break; + // nodenum = cin.numhnodes1[nodenum]; + // } + // nodenum = hnodes[nodenum*2 + (inbyte&1)]; + // inbyte >>=1; + // } + // + // if (input - in.data != in.count && input - in.data != in.count+1) + // { + // Com_Printf ("Decompression overread by %i", (input - in.data) - + // in.count); + // } + // out.count = out_p - out.data; + // + // return out; + // } + // + // /* + // ================== + // SCR_ReadNextFrame + // ================== + // */ + // byte *SCR_ReadNextFrame (void) + // { + // int r; + // int command; + // byte samples[22050/14*4]; + // byte compressed[0x20000]; + // int size; + // byte *pic; + // cblock_t in, huf1; + // int start, end, count; + // + // // read the next frame + // r = fread (&command, 4, 1, cl.cinematic_file); + // if (r == 0) // we'll give it one more chance + // r = fread (&command, 4, 1, cl.cinematic_file); + // + // if (r != 1) + // return NULL; + // command = LittleLong(command); + // if (command == 2) + // return NULL; // last frame marker + // + // if (command == 1) + // { // read palette + // FS_Read (cl.cinematicpalette, sizeof(cl.cinematicpalette), + // cl.cinematic_file); + // cl.cinematicpalette_active=0; // dubious.... exposes an edge case + // } + // + // // decompress the next frame + // FS_Read (&size, 4, cl.cinematic_file); + // size = LittleLong(size); + // if (size > sizeof(compressed) || size < 1) + // Com_Error (ERR_DROP, "Bad compressed frame size"); + // FS_Read (compressed, size, cl.cinematic_file); + // + // // read sound + // start = cl.cinematicframe*cin.s_rate/14; + // end = (cl.cinematicframe+1)*cin.s_rate/14; + // count = end - start; + // + // FS_Read (samples, count*cin.s_width*cin.s_channels, cl.cinematic_file); + // + // S_RawSamples (count, cin.s_rate, cin.s_width, cin.s_channels, samples); + // + // in.data = compressed; + // in.count = size; + // + // huf1 = Huff1Decompress (in); + // + // pic = huf1.data; + // + // cl.cinematicframe++; + // + // return pic; + // } + // + // + /* + * ================== SCR_RunCinematic + * + * ================== + */ + static void RunCinematic() { + int frame; + + if (cl.cinematictime <= 0) { + StopCinematic(); + return; + } + + // if (cl.cinematicframe == -1) + // return; // static image + // + // if (cls.key_dest != key_game) + // { // pause if menu or console is up + // cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14; + // return; + // } + // + // frame = (cls.realtime - cl.cinematictime)*14.0/1000; + // if (frame <= cl.cinematicframe) + // return; + // if (frame > cl.cinematicframe+1) + // { + // Com_Printf ("Dropped frame: %i > %i\n", frame, cl.cinematicframe+1); + // cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14; + // } + // if (cin.pic) + // Z_Free (cin.pic); + // cin.pic = cin.pic_pending; + // cin.pic_pending = NULL; + // cin.pic_pending = SCR_ReadNextFrame (); + // if (!cin.pic_pending) + // { + // SCR_StopCinematic (); + // SCR_FinishCinematic (); + // cl.cinematictime = 1; // hack to get the black screen behind loading + // SCR_BeginLoadingPlaque (); + // cl.cinematictime = 0; + // return; + // } + } + + /* + * ================== SCR_DrawCinematic + * + * Returns true if a cinematic is active, meaning the view rendering should + * be skipped ================== + */ + static boolean DrawCinematic() { + // if (cl.cinematictime <= 0) + // { + return false; + // } + // + // if (cls.key_dest == key_menu) + // { // blank screen and pause if menu is up + // re.CinematicSetPalette(NULL); + // cl.cinematicpalette_active = false; + // return true; + // } + // + // if (!cl.cinematicpalette_active) + // { + // re.CinematicSetPalette(cl.cinematicpalette); + // cl.cinematicpalette_active = true; + // } + // + // if (!cin.pic) + // return true; + // + // re.DrawStretchRaw (0, 0, viddef.width, viddef.height, + // cin.width, cin.height, cin.pic); + // + // return true; + } + + /* + * ================== SCR_PlayCinematic + * + * ================== + */ + static void PlayCinematic(String arg) { + // int width, height; + // byte *palette; + // char name[MAX_OSPATH], *dot; + // int old_khz; + // + // // make sure CD isn't playing music + //CDAudio.Stop(); + + cl.cinematicframe = 0; + // dot = strstr (arg, "."); + // if (dot && !strcmp (dot, ".pcx")) + // { // static pcx image + // Com_sprintf (name, sizeof(name), "pics/%s", arg); + // SCR_LoadPCX (name, &cin.pic, &palette, &cin.width, &cin.height); + // cl.cinematicframe = -1; + // cl.cinematictime = 1; + // SCR_EndLoadingPlaque (); + // cls.state = ca_active; + // if (!cin.pic) + // { + // Com_Printf ("%s not found.\n", name); + // cl.cinematictime = 0; + // } + // else + // { + // memcpy (cl.cinematicpalette, palette, sizeof(cl.cinematicpalette)); + // Z_Free (palette); + // } + // return; + // } + // + // Com_sprintf (name, sizeof(name), "video/%s", arg); + // FS_FOpenFile (name, &cl.cinematic_file); + // if (!cl.cinematic_file) + // { + // Com_Error (ERR_DROP, "Cinematic %s not found.\n", name); + FinishCinematic(); + cl.cinematictime = 0; // done + return; + // } + // + // SCR_EndLoadingPlaque (); + // + // cls.state = ca_active; + // + // FS_Read (&width, 4, cl.cinematic_file); + // FS_Read (&height, 4, cl.cinematic_file); + // cin.width = LittleLong(width); + // cin.height = LittleLong(height); + // + // FS_Read (&cin.s_rate, 4, cl.cinematic_file); + // cin.s_rate = LittleLong(cin.s_rate); + // FS_Read (&cin.s_width, 4, cl.cinematic_file); + // cin.s_width = LittleLong(cin.s_width); + // FS_Read (&cin.s_channels, 4, cl.cinematic_file); + // cin.s_channels = LittleLong(cin.s_channels); + // + // Huff1TableInit (); + // + // // switch up to 22 khz sound if necessary + // old_khz = Cvar_VariableValue ("s_khz"); + // if (old_khz != cin.s_rate/1000) + // { + // cin.restart_sound = true; + // Cvar_SetValue ("s_khz", cin.s_rate/1000); + // CL_Snd_Restart_f (); + // Cvar_SetValue ("s_khz", old_khz); + // } + // + // cl.cinematicframe = 0; + // cin.pic = SCR_ReadNextFrame (); + // cl.cinematictime = Sys_Milliseconds (); + } }
\ No newline at end of file diff --git a/src/jake2/client/V.java b/src/jake2/client/V.java index 2fd3005..402d16c 100644 --- a/src/jake2/client/V.java +++ b/src/jake2/client/V.java @@ -2,27 +2,27 @@ * V.java * Copyright (C) 2003 * - * $Id: V.java,v 1.2 2004-07-09 06:50:50 hzi Exp $ + * $Id: V.java,v 1.3 2004-09-22 19:22:08 salomo Exp $ */ /* -Copyright (C) 1997-2001 Id Software, Inc. + 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 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. + 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. + 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. + 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.client; import jake2.Globals; @@ -40,379 +40,373 @@ import java.nio.FloatBuffer; * V */ public final class V extends Globals { - - static cvar_t cl_testblend; - static cvar_t cl_testparticles; - static cvar_t cl_testentities; - static cvar_t cl_testlights; - static cvar_t cl_stats; - - static int r_numdlights; - static dlight_t[] r_dlights = new dlight_t[MAX_DLIGHTS]; - - static int r_numentities; - static entity_t[] r_entities = new entity_t[MAX_ENTITIES]; - - static int r_numparticles; - //static particle_t[] r_particles = new particle_t[MAX_PARTICLES]; - - static lightstyle_t[] r_lightstyles = new lightstyle_t[MAX_LIGHTSTYLES]; - static { - for (int i = 0; i < r_dlights.length; i++) - r_dlights[i] = new dlight_t(); - for (int i = 0; i < r_entities.length; i++) - r_entities[i] = new entity_t(); - for (int i = 0; i < r_lightstyles.length; i++) - r_lightstyles[i] = new lightstyle_t(); - } - - /* - ==================== - V_ClearScene - - Specifies the model that will be used as the world - ==================== - */ - static void ClearScene() { - r_numdlights = 0; - r_numentities = 0; - r_numparticles = 0; - } - - /* - ===================== - V_AddEntity - - ===================== - */ - static void AddEntity(entity_t ent) { - if (r_numentities >= MAX_ENTITIES) - return; - r_entities[r_numentities++].set(ent); - } - - /* - ===================== - V_AddParticle - - ===================== - */ - static void AddParticle(float[] org, int color, float alpha) { - if (r_numparticles >= MAX_PARTICLES) - return; - - int i = r_numparticles++; - - int c = particle_t.colorTable[color]; - c |= (int)(alpha * 255) << 24; - particle_t.colorArray.put(i, c); - - i *= 3; - FloatBuffer vertexBuf = particle_t.vertexArray; - vertexBuf.put(i++, org[0]); - vertexBuf.put(i++, org[1]); - vertexBuf.put(i++, org[2]); - } - - /* - ===================== - V_AddLight - - ===================== - */ - static void AddLight(float[] org, float intensity, float r, float g, float b) { - dlight_t dl; - - if (r_numdlights >= MAX_DLIGHTS) - return; - dl = r_dlights[r_numdlights++]; - VectorCopy(org, dl.origin); - dl.intensity = intensity; - dl.color[0] = r; - dl.color[1] = g; - dl.color[2] = b; - } - - - /* - ===================== - V_AddLightStyle - - ===================== - */ - static void AddLightStyle(int style, float r, float g, float b) { - lightstyle_t ls; - - if (style < 0 || style > MAX_LIGHTSTYLES) - Com.Error(ERR_DROP, "Bad light style " + style); - ls = r_lightstyles[style]; - - ls.white = r + g + b; - ls.rgb[0] = r; - ls.rgb[1] = g; - ls.rgb[2] = b; - } - - /* - ================ - V_TestParticles - - If cl_testparticles is set, create 4096 particles in the view - ================ - */ - static void TestParticles() { - int i, j; - float d, r, u; - - float[] origin = {0,0,0}; - - r_numparticles = 0; - for (i = 0; i < MAX_PARTICLES; i++) { - d = i * 0.25f; - r = 4 * ((i & 7) - 3.5f); - u = 4 * (((i >> 3) & 7) - 3.5f); - - for (j = 0; j < 3; j++) - origin[j] = - cl.refdef.vieworg[j] - + cl.v_forward[j] * d - + cl.v_right[j] * r - + cl.v_up[j] * u; - - AddParticle(origin, 8, cl_testparticles.value); - } - } - - /* - ================ - V_TestEntities - - If cl_testentities is set, create 32 player models - ================ - */ - static void TestEntities() { - int i, j; - float f, r; - entity_t ent; - - r_numentities = 32; - //memset (r_entities, 0, sizeof(r_entities)); - for (i = 0; i < r_entities.length; i++) - r_entities[i] = new entity_t(); - - for (i=0 ; i<r_numentities ; i++) - { - ent = r_entities[i]; - - r = 64 * ( (i%4) - 1.5f ); - f = 64 * (i/4) + 128; - - for (j=0 ; j<3 ; j++) - ent.origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + - cl.v_right[j]*r; - - ent.model = cl.baseclientinfo.model; - ent.skin = cl.baseclientinfo.skin; - } - } - - /* - ================ - V_TestLights - - If cl_testlights is set, create 32 lights models - ================ - */ - static void TestLights() { - int i, j; - float f, r; - dlight_t dl; - - r_numdlights = 32; - //memset (r_dlights, 0, sizeof(r_dlights)); - for (i = 0; i < r_dlights.length; i++) - r_dlights[i] = new dlight_t(); - - for (i=0 ; i<r_numdlights ; i++) - { - dl = r_dlights[i]; - - r = 64 * ( (i%4) - 1.5f ); - f = 64 * (i/4) + 128; - - for (j=0 ; j<3 ; j++) - dl.origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + - cl.v_right[j]*r; - dl.color[0] = ((i%6)+1) & 1; - dl.color[1] = (((i%6)+1) & 2)>>1; - dl.color[2] = (((i%6)+1) & 4)>>2; - dl.intensity = 200; - } - } - - static xcommand_t Gun_Next_f = new xcommand_t() { - public void execute() { - gun_frame++; - Com.Printf("frame " + gun_frame + "\n"); - } - }; - - static xcommand_t Gun_Prev_f = new xcommand_t() { - public void execute() { - gun_frame--; - if (gun_frame < 0) - gun_frame = 0; - Com.Printf("frame " + gun_frame + "\n"); - } - }; - - static xcommand_t Gun_Model_f = new xcommand_t() { - public void execute() { - if (Cmd.Argc() != 2) { - gun_model = null; - return; - } - String name = "models/" + Cmd.Argv(1) + "/tris.md2"; - gun_model = re.RegisterModel(name); - } - }; - - /* - ================== - V_RenderView - - ================== - */ - static void RenderView(float stereo_separation) { -// extern int entitycmpfnc( const entity_t *, const entity_t * ); -// - if (cls.state != ca_active) return; - - if (!cl.refresh_prepped) return; // still loading - - if (cl_timedemo.value != 0.0f) { - if (cl.timedemo_start == 0) - cl.timedemo_start = Sys.Milliseconds(); - cl.timedemo_frames++; - } - - // an invalid frame will just use the exact previous refdef - // we can't use the old frame if the video mode has changed, though... - if ( cl.frame.valid && (cl.force_refdef || cl_paused.value == 0.0f) ) { - cl.force_refdef = false; - - V.ClearScene(); - - // build a refresh entity list and calc cl.sim* - // this also calls CL_CalcViewValues which loads - // v_forward, etc. - CL.AddEntities(); - - if (cl_testparticles.value != 0.0f) - TestParticles(); - if (cl_testentities.value != 0.0f) - TestEntities(); - if (cl_testlights.value != 0.0f) - TestLights(); - if (cl_testblend.value != 0.0f) { - cl.refdef.blend[0] = 1.0f; - cl.refdef.blend[1] = 0.5f; - cl.refdef.blend[2] = 0.25f; - cl.refdef.blend[3] = 0.5f; - } - - // offset vieworg appropriately if we're doing stereo separation - if ( stereo_separation != 0 ) { - float[] tmp = new float[3]; - - Math3D.VectorScale( cl.v_right, stereo_separation, tmp ); - Math3D.VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg ); - } - - // never let it sit exactly on a node line, because a water plane can - // dissapear when viewed with the eye exactly on it. - // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis - cl.refdef.vieworg[0] += 1.0/16; - cl.refdef.vieworg[1] += 1.0/16; - cl.refdef.vieworg[2] += 1.0/16; - - cl.refdef.x = scr_vrect.x; - cl.refdef.y = scr_vrect.y; - cl.refdef.width = scr_vrect.width; - cl.refdef.height = scr_vrect.height; - cl.refdef.fov_y = Math3D.CalcFov(cl.refdef.fov_x, cl.refdef.width, cl.refdef.height); - cl.refdef.time = cl.time*0.001f; - - cl.refdef.areabits = cl.frame.areabits; - - if (cl_add_entities.value == 0.0f) - r_numentities = 0; - if (cl_add_particles.value == 0.0f) - r_numparticles = 0; - if (cl_add_lights.value == 0.0f) - r_numdlights = 0; - if (cl_add_blend.value == 0) { - Math3D.VectorClear(cl.refdef.blend); - } - - cl.refdef.num_entities = r_numentities; - cl.refdef.entities = r_entities; - cl.refdef.num_particles = r_numparticles; - cl.refdef.num_dlights = r_numdlights; - cl.refdef.dlights = r_dlights; - cl.refdef.lightstyles = r_lightstyles; - - cl.refdef.rdflags = cl.frame.playerstate.rdflags; - - // sort entities for better cache locality - // !!! useless in Java !!! - //Arrays.sort(cl.refdef.entities, entitycmpfnc); - } - - re.RenderFrame(cl.refdef); - if (cl_stats.value != 0.0f) - Com.Printf("ent:%i lt:%i part:%i\n", new Vargs(3).add(r_numentities).add( - r_numdlights).add(r_numparticles)); - if ( log_stats.value != 0.0f && ( log_stats_file != null ) ) - try { - log_stats_file.write(r_numentities + "," + r_numdlights + "," + r_numparticles); - } catch (IOException e) {} - - SCR.AddDirtyPoint(scr_vrect.x, scr_vrect.y); - SCR.AddDirtyPoint(scr_vrect.x+scr_vrect.width-1, scr_vrect.y+scr_vrect.height-1); - - SCR.DrawCrosshair(); - } - - /* - ============= - V_Viewpos_f - ============= - */ - static xcommand_t Viewpos_f = new xcommand_t() { - public void execute() { - Com.Printf("(%i %i %i) : %i\n", - new Vargs(4).add((int)cl.refdef.vieworg[0]).add( - (int)cl.refdef.vieworg[1]).add( - (int)cl.refdef.vieworg[2]).add( - (int)cl.refdef.viewangles[YAW])); - } - }; - - public static void Init() { - Cmd.AddCommand("gun_next", Gun_Next_f); - Cmd.AddCommand("gun_prev", Gun_Prev_f); - Cmd.AddCommand("gun_model", Gun_Model_f); - - Cmd.AddCommand("viewpos", Viewpos_f); - - crosshair = Cvar.Get("crosshair", "0", CVAR_ARCHIVE); - - cl_testblend = Cvar.Get("cl_testblend", "0", 0); - cl_testparticles = Cvar.Get("cl_testparticles", "0", 0); - cl_testentities = Cvar.Get("cl_testentities", "0", 0); - cl_testlights = Cvar.Get("cl_testlights", "0", 0); - - cl_stats = Cvar.Get("cl_stats", "0", 0); - } -} + + static cvar_t cl_testblend; + + static cvar_t cl_testparticles; + + static cvar_t cl_testentities; + + static cvar_t cl_testlights; + + static cvar_t cl_stats; + + static int r_numdlights; + + static dlight_t[] r_dlights = new dlight_t[MAX_DLIGHTS]; + + static int r_numentities; + + static entity_t[] r_entities = new entity_t[MAX_ENTITIES]; + + static int r_numparticles; + + //static particle_t[] r_particles = new particle_t[MAX_PARTICLES]; + + static lightstyle_t[] r_lightstyles = new lightstyle_t[MAX_LIGHTSTYLES]; + static { + for (int i = 0; i < r_dlights.length; i++) + r_dlights[i] = new dlight_t(); + for (int i = 0; i < r_entities.length; i++) + r_entities[i] = new entity_t(); + for (int i = 0; i < r_lightstyles.length; i++) + r_lightstyles[i] = new lightstyle_t(); + } + + /* + * ==================== V_ClearScene + * + * Specifies the model that will be used as the world ==================== + */ + static void ClearScene() { + r_numdlights = 0; + r_numentities = 0; + r_numparticles = 0; + } + + /* + * ===================== V_AddEntity + * + * ===================== + */ + static void AddEntity(entity_t ent) { + if (r_numentities >= MAX_ENTITIES) + return; + r_entities[r_numentities++].set(ent); + } + + /* + * ===================== V_AddParticle + * + * ===================== + */ + static void AddParticle(float[] org, int color, float alpha) { + if (r_numparticles >= MAX_PARTICLES) + return; + + int i = r_numparticles++; + + int c = particle_t.colorTable[color]; + c |= (int) (alpha * 255) << 24; + particle_t.colorArray.put(i, c); + + i *= 3; + FloatBuffer vertexBuf = particle_t.vertexArray; + vertexBuf.put(i++, org[0]); + vertexBuf.put(i++, org[1]); + vertexBuf.put(i++, org[2]); + } + + /* + * ===================== V_AddLight + * + * ===================== + */ + static void AddLight(float[] org, float intensity, float r, float g, float b) { + dlight_t dl; + + if (r_numdlights >= MAX_DLIGHTS) + return; + dl = r_dlights[r_numdlights++]; + Math3D.VectorCopy(org, dl.origin); + dl.intensity = intensity; + dl.color[0] = r; + dl.color[1] = g; + dl.color[2] = b; + } + + /* + * ===================== V_AddLightStyle + * + * ===================== + */ + static void AddLightStyle(int style, float r, float g, float b) { + lightstyle_t ls; + + if (style < 0 || style > MAX_LIGHTSTYLES) + Com.Error(ERR_DROP, "Bad light style " + style); + ls = r_lightstyles[style]; + + ls.white = r + g + b; + ls.rgb[0] = r; + ls.rgb[1] = g; + ls.rgb[2] = b; + } + + /* + * ================ V_TestParticles + * + * If cl_testparticles is set, create 4096 particles in the view + * ================ + */ + static void TestParticles() { + int i, j; + float d, r, u; + + float[] origin = { 0, 0, 0 }; + + r_numparticles = 0; + for (i = 0; i < MAX_PARTICLES; i++) { + d = i * 0.25f; + r = 4 * ((i & 7) - 3.5f); + u = 4 * (((i >> 3) & 7) - 3.5f); + + for (j = 0; j < 3; j++) + origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * d + + cl.v_right[j] * r + cl.v_up[j] * u; + + AddParticle(origin, 8, cl_testparticles.value); + } + } + + /* + * ================ V_TestEntities + * + * If cl_testentities is set, create 32 player models ================ + */ + static void TestEntities() { + int i, j; + float f, r; + entity_t ent; + + r_numentities = 32; + //memset (r_entities, 0, sizeof(r_entities)); + for (i = 0; i < r_entities.length; i++) + r_entities[i] = new entity_t(); + + for (i = 0; i < r_numentities; i++) { + ent = r_entities[i]; + + r = 64 * ((i % 4) - 1.5f); + f = 64 * (i / 4) + 128; + + for (j = 0; j < 3; j++) + ent.origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * f + + cl.v_right[j] * r; + + ent.model = cl.baseclientinfo.model; + ent.skin = cl.baseclientinfo.skin; + } + } + + /* + * ================ V_TestLights + * + * If cl_testlights is set, create 32 lights models ================ + */ + static void TestLights() { + int i, j; + float f, r; + dlight_t dl; + + r_numdlights = 32; + //memset (r_dlights, 0, sizeof(r_dlights)); + for (i = 0; i < r_dlights.length; i++) + r_dlights[i] = new dlight_t(); + + for (i = 0; i < r_numdlights; i++) { + dl = r_dlights[i]; + + r = 64 * ((i % 4) - 1.5f); + f = 64 * (i / 4) + 128; + + for (j = 0; j < 3; j++) + dl.origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * f + + cl.v_right[j] * r; + dl.color[0] = ((i % 6) + 1) & 1; + dl.color[1] = (((i % 6) + 1) & 2) >> 1; + dl.color[2] = (((i % 6) + 1) & 4) >> 2; + dl.intensity = 200; + } + } + + static xcommand_t Gun_Next_f = new xcommand_t() { + public void execute() { + gun_frame++; + Com.Printf("frame " + gun_frame + "\n"); + } + }; + + static xcommand_t Gun_Prev_f = new xcommand_t() { + public void execute() { + gun_frame--; + if (gun_frame < 0) + gun_frame = 0; + Com.Printf("frame " + gun_frame + "\n"); + } + }; + + static xcommand_t Gun_Model_f = new xcommand_t() { + public void execute() { + if (Cmd.Argc() != 2) { + gun_model = null; + return; + } + String name = "models/" + Cmd.Argv(1) + "/tris.md2"; + gun_model = re.RegisterModel(name); + } + }; + + /* + * ================== V_RenderView + * + * ================== + */ + static void RenderView(float stereo_separation) { + // extern int entitycmpfnc( const entity_t *, const entity_t * ); + // + if (cls.state != ca_active) + return; + + if (!cl.refresh_prepped) + return; // still loading + + if (cl_timedemo.value != 0.0f) { + if (cl.timedemo_start == 0) + cl.timedemo_start = Sys.Milliseconds(); + cl.timedemo_frames++; + } + + // an invalid frame will just use the exact previous refdef + // we can't use the old frame if the video mode has changed, though... + if (cl.frame.valid && (cl.force_refdef || cl_paused.value == 0.0f)) { + cl.force_refdef = false; + + V.ClearScene(); + + // build a refresh entity list and calc cl.sim* + // this also calls CL_CalcViewValues which loads + // v_forward, etc. + CL_ents.AddEntities(); + + if (cl_testparticles.value != 0.0f) + TestParticles(); + if (cl_testentities.value != 0.0f) + TestEntities(); + if (cl_testlights.value != 0.0f) + TestLights(); + if (cl_testblend.value != 0.0f) { + cl.refdef.blend[0] = 1.0f; + cl.refdef.blend[1] = 0.5f; + cl.refdef.blend[2] = 0.25f; + cl.refdef.blend[3] = 0.5f; + } + + // offset vieworg appropriately if we're doing stereo separation + if (stereo_separation != 0) { + float[] tmp = new float[3]; + + Math3D.VectorScale(cl.v_right, stereo_separation, tmp); + Math3D.VectorAdd(cl.refdef.vieworg, tmp, cl.refdef.vieworg); + } + + // never let it sit exactly on a node line, because a water plane + // can + // dissapear when viewed with the eye exactly on it. + // the server protocol only specifies to 1/8 pixel, so add 1/16 in + // each axis + cl.refdef.vieworg[0] += 1.0 / 16; + cl.refdef.vieworg[1] += 1.0 / 16; + cl.refdef.vieworg[2] += 1.0 / 16; + + cl.refdef.x = scr_vrect.x; + cl.refdef.y = scr_vrect.y; + cl.refdef.width = scr_vrect.width; + cl.refdef.height = scr_vrect.height; + cl.refdef.fov_y = Math3D.CalcFov(cl.refdef.fov_x, cl.refdef.width, + cl.refdef.height); + cl.refdef.time = cl.time * 0.001f; + + cl.refdef.areabits = cl.frame.areabits; + + if (cl_add_entities.value == 0.0f) + r_numentities = 0; + if (cl_add_particles.value == 0.0f) + r_numparticles = 0; + if (cl_add_lights.value == 0.0f) + r_numdlights = 0; + if (cl_add_blend.value == 0) { + Math3D.VectorClear(cl.refdef.blend); + } + + cl.refdef.num_entities = r_numentities; + cl.refdef.entities = r_entities; + cl.refdef.num_particles = r_numparticles; + cl.refdef.num_dlights = r_numdlights; + cl.refdef.dlights = r_dlights; + cl.refdef.lightstyles = r_lightstyles; + + cl.refdef.rdflags = cl.frame.playerstate.rdflags; + + // sort entities for better cache locality + // !!! useless in Java !!! + //Arrays.sort(cl.refdef.entities, entitycmpfnc); + } + + re.RenderFrame(cl.refdef); + if (cl_stats.value != 0.0f) + Com.Printf("ent:%i lt:%i part:%i\n", new Vargs(3).add( + r_numentities).add(r_numdlights).add(r_numparticles)); + if (log_stats.value != 0.0f && (log_stats_file != null)) + try { + log_stats_file.write(r_numentities + "," + r_numdlights + "," + + r_numparticles); + } catch (IOException e) { + } + + SCR.AddDirtyPoint(scr_vrect.x, scr_vrect.y); + SCR.AddDirtyPoint(scr_vrect.x + scr_vrect.width - 1, scr_vrect.y + + scr_vrect.height - 1); + + SCR.DrawCrosshair(); + } + + /* + * ============= V_Viewpos_f ============= + */ + static xcommand_t Viewpos_f = new xcommand_t() { + public void execute() { + Com.Printf("(%i %i %i) : %i\n", new Vargs(4).add( + (int) cl.refdef.vieworg[0]).add((int) cl.refdef.vieworg[1]) + .add((int) cl.refdef.vieworg[2]).add( + (int) cl.refdef.viewangles[YAW])); + } + }; + + public static void Init() { + Cmd.AddCommand("gun_next", Gun_Next_f); + Cmd.AddCommand("gun_prev", Gun_Prev_f); + Cmd.AddCommand("gun_model", Gun_Model_f); + + Cmd.AddCommand("viewpos", Viewpos_f); + + crosshair = Cvar.Get("crosshair", "0", CVAR_ARCHIVE); + + cl_testblend = Cvar.Get("cl_testblend", "0", 0); + cl_testparticles = Cvar.Get("cl_testparticles", "0", 0); + cl_testentities = Cvar.Get("cl_testentities", "0", 0); + cl_testlights = Cvar.Get("cl_testlights", "0", 0); + + cl_stats = Cvar.Get("cl_stats", "0", 0); + } +}
\ No newline at end of file |