/// <summary> /// CL_SignonReply /// /// An svc_signonnum has been received, perform a client side setup /// </summary> static void SignonReply() { Con.DPrint("CL_SignonReply: {0}\n", cls.signon); switch (cls.signon) { case 1: cls.message.WriteByte(Protocol.clc_stringcmd); cls.message.WriteString("prespawn"); break; case 2: cls.message.WriteByte(Protocol.clc_stringcmd); cls.message.WriteString(String.Format("name \"{0}\"\n", _Name.String)); cls.message.WriteByte(Protocol.clc_stringcmd); cls.message.WriteString(String.Format("color {0} {1}\n", ((int)_Color.Value) >> 4, ((int)_Color.Value) & 15)); cls.message.WriteByte(Protocol.clc_stringcmd); cls.message.WriteString("spawn " + cls.spawnparms); break; case 3: cls.message.WriteByte(Protocol.clc_stringcmd); cls.message.WriteString("begin"); Cache.Report(); // print remaining memory break; case 4: Scr.EndLoadingPlaque(); // allow normal screen updates break; } }
/// <summary> /// CDAudio_GetAudioDiskInfo /// </summary> public void ReloadDiskInfo() { _IsValidDisc = false; Mci.StatusParams sp = default(Mci.StatusParams); sp.dwItem = Mci.MCI_STATUS_READY; int ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("CDAudio: drive ready test - get status failed\n"); return; } if (sp.dwReturn == 0) { Con.DPrint("CDAudio: drive not ready\n"); return; } sp.dwItem = Mci.MCI_STATUS_NUMBER_OF_TRACKS; ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("CDAudio: get tracks - status failed\n"); return; } if (sp.dwReturn < 1) { Con.DPrint("CDAudio: no music tracks\n"); return; } _IsValidDisc = true; _MaxTrack = (byte)sp.dwReturn; }
/// <summary> /// Host_EndGame /// </summary> public static void EndGame(string message, params object[] args) { string str = String.Format(message, args); Con.DPrint("Host_EndGame: {0}\n", str); if (Server.IsActive) { Host.ShutdownServer(false); } if (Client.cls.state == cactive_t.ca_dedicated) { Sys.Error("Host_EndGame: {0}\n", str); // dedicated servers exit } if (Client.cls.demonum != -1) { Client.NextDemo(); } else { Client.Disconnect(); } throw new EndGameException(); //longjmp (host_abortserver, 1); }
/// <summary> /// CL_EstablishConnection /// </summary> public static void EstablishConnection(string host) { if (cls.state == cactive_t.ca_dedicated) { return; } if (cls.demoplayback) { return; } Disconnect(); cls.netcon = Net.Connect(host); if (cls.netcon == null) { Host.Error("CL_Connect: connect failed\n"); } Con.DPrint("CL_EstablishConnection: connected to {0}\n", host); cls.demonum = -1; // not in the demo loop now cls.state = cactive_t.ca_connected; cls.signon = 0; // need all the signon messages before playing }
public void Resume() { if (!_IsEnabled) { return; } if (!_IsValidDisc) { return; } if (!_WasPlaying) { return; } Mci.PlayParams pp; pp.dwFrom = Mci.MCI_MAKE_TMSF(_PlayTrack, 0, 0, 0); pp.dwTo = Mci.MCI_MAKE_TMSF(_PlayTrack + 1, 0, 0, 0); pp.dwCallback = _Form.Handle;// (DWORD)mainwindow; int ret = Mci.Play(_DeviceID, Mci.MCI_PLAY, Mci.MCI_TO | Mci.MCI_NOTIFY, ref pp); if (ret != 0) { Con.DPrint("CDAudio: MCI_PLAY failed ({0})\n", ret); } _IsPlaying = (ret == 0); }
public void UnlockBuffer(int bytes) { int processed; AL.GetSource(_Source, ALGetSourcei.BuffersProcessed, out processed); if (processed > 0) { int[] bufs = AL.SourceUnqueueBuffers(_Source, processed); foreach (int buffer in bufs) { if (buffer == 0) { continue; } int idx = Array.IndexOf(_Buffers, buffer); if (idx != -1) { _SamplesSent += _BufferBytes[idx] >> ((Sound.shm.samplebits / 8) - 1); _SamplesSent &= (Sound.shm.samples - 1); _BufferBytes[idx] = 0; } if (!_FreeBuffers.Contains(buffer)) { _FreeBuffers.Enqueue(buffer); } } } if (_FreeBuffers.Count == 0) { Con.DPrint("UnlockBuffer: No free buffers!\n"); return; } int buf = _FreeBuffers.Dequeue(); if (buf != 0) { AL.BufferData(buf, _BufferFormat, Sound.shm.buffer, bytes, Sound.shm.speed); AL.SourceQueueBuffer(_Source, buf); int idx = Array.IndexOf(_Buffers, buf); if (idx != -1) { _BufferBytes[idx] = bytes; } int state; AL.GetSource(_Source, ALGetSourcei.SourceState, out state); if ((ALSourceState)state != ALSourceState.Playing) { AL.SourcePlay(_Source); Con.DPrint("Sound resumed from {0}, free {1} of {2} buffers\n", ((ALSourceState)state).ToString("F"), _FreeBuffers.Count, _Buffers.Length); } } }
/// <summary> /// SV_DropClient /// Called when the player is getting totally kicked off the host /// if (crash = true), don't bother sending signofs /// </summary> public static void DropClient(bool crash) { client_t client = Host.HostClient; if (!crash) { // send any final messages (don't check for errors) if (Net.CanSendMessage(client.netconnection)) { MsgWriter msg = client.message; msg.WriteByte(Protocol.svc_disconnect); Net.SendMessage(client.netconnection, msg); } if (client.edict != null && client.spawned) { // call the prog function for removing a client // this will set the body to a dead frame, among other things int saveSelf = Progs.GlobalStruct.self; Progs.GlobalStruct.self = EdictToProg(client.edict); Progs.Execute(Progs.GlobalStruct.ClientDisconnect); Progs.GlobalStruct.self = saveSelf; } Con.DPrint("Client {0} removed\n", client.name); } // break the net connection Net.Close(client.netconnection); client.netconnection = null; // free the client (the body stays around) client.active = false; client.name = null; client.old_frags = -999999; Net.ActiveConnections--; // send notification to all clients for (int i = 0; i < Server.svs.maxclients; i++) { client_t cl = Server.svs.clients[i]; if (!cl.active) { continue; } cl.message.WriteByte(Protocol.svc_updatename); cl.message.WriteByte(Host.ClientNum); cl.message.WriteString(""); cl.message.WriteByte(Protocol.svc_updatefrags); cl.message.WriteByte(Host.ClientNum); cl.message.WriteShort(0); cl.message.WriteByte(Protocol.svc_updatecolors); cl.message.WriteByte(Host.ClientNum); cl.message.WriteByte(0); } }
static int Main(string[] args) { #if !DEBUG try { #endif // select display device _DisplayDevice = DisplayDevice.Default; if (File.Exists(DumpFilePath)) { File.Delete(DumpFilePath); } quakeparms_t parms = new quakeparms_t(); parms.basedir = Application.StartupPath; string[] args2 = new string[args.Length + 1]; args2[0] = String.Empty; args.CopyTo(args2, 1); Common.InitArgv(args2); parms.argv = new string[Common.Argc]; Common.Args.CopyTo(parms.argv, 0); if (Common.HasParam("-dedicated")) { throw new QuakeException("Dedicated server mode not supported!"); } Size size = new Size(640, 480); GraphicsMode mode = new GraphicsMode(); bool fullScreen = false; using (MainForm form = MainForm.CreateInstance(size, mode, fullScreen)) { Con.DPrint("Host.Init\n"); Host.Init(parms); form.Run(); } Host.Shutdown(); #if !DEBUG } catch (QuakeSystemError se) { HandleException(se); } catch (Exception ex) { HandleException(ex); } #endif return(0); // all Ok }
public void CloseDoor() { int ret = Mci.SendCommand(_DeviceID, Mci.MCI_SET, Mci.MCI_SET_DOOR_CLOSED, IntPtr.Zero); if (ret != 0) { Con.DPrint("MCI_SET_DOOR_CLOSED failed ({0})\n", ret); } }
/// <summary> /// Host_ClearMemory /// </summary> public static void ClearMemory() { Con.DPrint("Clearing memory\n"); Mod.ClearAll(); Client.cls.signon = 0; Server.sv.Clear(); Client.cl.Clear(); }
public static void Init(quakeparms_t parms) { _Params = parms; Cache.Init(1024 * 1024 * 16); // debug Cbuf.Init(); Cmd.Init(); View.Init(); Chase.Init(); InitVCR(parms); Common.Init(parms.basedir, parms.argv); InitLocal(); Wad.LoadWadFile("gfx.wad"); Key.Init(); Con.Init(); Menu.Init(); Progs.Init(); Mod.Init(); Net.Init(); Server.Init(); //Con.Print("Exe: "__TIME__" "__DATE__"\n"); //Con.Print("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0)); Render.InitTextures(); // needed even for dedicated servers if (Client.cls.state != cactive_t.ca_dedicated) { _BasePal = Common.LoadFile("gfx/palette.lmp"); if (_BasePal == null) { Sys.Error("Couldn't load gfx/palette.lmp"); } _ColorMap = Common.LoadFile("gfx/colormap.lmp"); if (_ColorMap == null) { Sys.Error("Couldn't load gfx/colormap.lmp"); } // on non win32, mouse comes before video for security reasons Input.Init(); Vid.Init(_BasePal); Drawer.Init(); Scr.Init(); Render.Init(); Sound.Init(); CDAudio.Init(); Sbar.Init(); Client.Init(); } Cbuf.InsertText("exec quake.rc\n"); _IsInitialized = true; Con.DPrint("========Quake Initialized=========\n"); }
public void Edject() { int ret = Mci.SendCommand(_DeviceID, Mci.MCI_SET, Mci.MCI_SET_DOOR_OPEN, IntPtr.Zero); if (ret != 0) { Con.DPrint("MCI_SET_DOOR_OPEN failed ({0})\n", ret); } }
// CL_SendCmd public static void SendCmd() { if (cls.state != cactive_t.ca_connected) { return; } if (cls.signon == SIGNONS) { usercmd_t cmd = new usercmd_t(); // get basic movement from keyboard BaseMove(ref cmd); // allow mice or other external controllers to add to the move Input.Move(cmd); // send the unreliable message Client.SendMove(ref cmd); } if (cls.demoplayback) { cls.message.Clear();// SZ_Clear (cls.message); return; } // send the reliable message if (cls.message.IsEmpty) { return; // no message at all } if (!Net.CanSendMessage(cls.netcon)) { Con.DPrint("CL_WriteToServer: can't send\n"); return; } if (Net.SendMessage(cls.netcon, cls.message) == -1) { Host.Error("CL_WriteToServer: lost server connection"); } cls.message.Clear(); }
private int MapKey(OpenTK.Input.Key srcKey) { int key = (int)srcKey; key &= 255; if (key >= _KeyTable.Length) { return(0); } if (_KeyTable[key] == 0) { Con.DPrint("key 0x{0:X} has no translation\n", key); } return(_KeyTable[key]); }
public void Shutdown() { if (_Form != null) { _Form.Dispose(); _Form = null; } if (!_IsInitialized) { return; } Stop(); if (Mci.SendCommand(_DeviceID, Mci.MCI_CLOSE, Mci.MCI_WAIT, IntPtr.Zero) != 0) { Con.DPrint("CDAudio_Shutdown: MCI_CLOSE failed\n"); } }
/// <summary> /// SV_ConnectClient /// Initializes a client_t for a new net connection. This will only be called /// once for a player each game, not once for each level change. /// </summary> static void ConnectClient(int clientnum) { client_t client = svs.clients[clientnum]; Con.DPrint("Client {0} connected\n", client.netconnection.address); int edictnum = clientnum + 1; edict_t ent = EdictNum(edictnum); // set up the client_t qsocket_t netconnection = client.netconnection; float[] spawn_parms = new float[NUM_SPAWN_PARMS]; if (sv.loadgame) { Array.Copy(client.spawn_parms, spawn_parms, spawn_parms.Length); } client.Clear(); client.netconnection = netconnection; client.name = "unconnected"; client.active = true; client.spawned = false; client.edict = ent; client.message.AllowOverflow = true; // we can catch it client.privileged = false; if (sv.loadgame) { Array.Copy(spawn_parms, client.spawn_parms, spawn_parms.Length); } else { // call the progs to get default spawn parms for the new client Progs.Execute(Progs.GlobalStruct.SetNewParms); AssignGlobalSpawnparams(client); } SendServerInfo(client); }
/// <summary> /// SV_CheckStuck /// This is a big hack to try and fix the rare case of getting stuck in the world /// clipping hull. /// </summary> private static void CheckStuck(edict_t ent) { if (TestEntityPosition(ent) == null) { ent.v.oldorigin = ent.v.origin; return; } v3f org = ent.v.origin; ent.v.origin = ent.v.oldorigin; if (TestEntityPosition(ent) == null) { Con.DPrint("Unstuck.\n"); LinkEdict(ent, true); return; } for (int z = 0; z < 18; z++) { for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { ent.v.origin.x = org.x + i; ent.v.origin.y = org.y + j; ent.v.origin.z = org.z + z; if (TestEntityPosition(ent) == null) { Con.DPrint("Unstuck.\n"); LinkEdict(ent, true); return; } } } } ent.v.origin = org; Con.DPrint("player is stuck.\n"); }
public void Stop() { if (!_IsEnabled) { return; } if (!_IsPlaying) { return; } int ret = Mci.SendCommand(_DeviceID, Mci.MCI_STOP, 0, IntPtr.Zero); if (ret != 0) { Con.DPrint("MCI_STOP failed ({0})", ret); } _WasPlaying = false; _IsPlaying = false; }
public void Pause() { if (!_IsEnabled) { return; } if (!_IsPlaying) { return; } Mci.GenericParams gp = default(Mci.GenericParams); int ret = Mci.SendCommand(_DeviceID, Mci.MCI_PAUSE, 0, ref gp); if (ret != 0) { Con.DPrint("MCI_PAUSE failed ({0})", ret); } _WasPlaying = _IsPlaying; _IsPlaying = false; }
/// <summary> /// CL_Disconnect /// /// Sends a disconnect message to the server /// This is also called on Host_Error, so it shouldn't cause any errors /// </summary> public static void Disconnect() { // stop sounds (especially looping!) Sound.StopAllSounds(true); // bring the console down and fade the colors back to normal // SCR_BringDownConsole (); // if running a local server, shut it down if (cls.demoplayback) { StopPlayback(); } else if (cls.state == cactive_t.ca_connected) { if (cls.demorecording) { Stop_f(); } Con.DPrint("Sending clc_disconnect\n"); cls.message.Clear(); cls.message.WriteByte(Protocol.clc_disconnect); Net.SendUnreliableMessage(cls.netcon, cls.message); cls.message.Clear(); Net.Close(cls.netcon); cls.state = cactive_t.ca_disconnected; if (Server.sv.active) { Host.ShutdownServer(false); } } cls.demoplayback = cls.timedemo = false; cls.signon = 0; }
public void MessageHandler(ref Message m) { if (m.LParam != _DeviceID) { return; } switch (m.WParam.ToInt32()) { case Mci.MCI_NOTIFY_SUCCESSFUL: if (_IsPlaying) { _IsPlaying = false; if (_IsLooping) { Play(_PlayTrack, true); } } break; case Mci.MCI_NOTIFY_ABORTED: case Mci.MCI_NOTIFY_SUPERSEDED: break; case Mci.MCI_NOTIFY_FAILURE: Con.DPrint("MCI_NOTIFY_FAILURE\n"); Stop(); _IsValidDisc = false; break; default: Con.DPrint("Unexpected MM_MCINOTIFY type ({0})\n", m.WParam); m.Result = new IntPtr(1); break; } }
public void Play(byte track, bool looping) { if (!_IsEnabled) { return; } if (!_IsValidDisc) { ReloadDiskInfo(); if (!_IsValidDisc) { return; } } track = _Remap[track]; if (track < 1 || track > _MaxTrack) { Con.DPrint("CDAudio: Bad track number {0}.\n", track); return; } // don't try to play a non-audio track Mci.StatusParams sp = default(Mci.StatusParams); sp.dwItem = Mci.MCI_CDA_STATUS_TYPE_TRACK; sp.dwTrack = track; int ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_TRACK | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("MCI_STATUS failed ({0})\n", ret); return; } if (sp.dwReturn != Mci.MCI_CDA_TRACK_AUDIO) { Con.Print("CDAudio: track {0} is not audio\n", track); return; } // get the length of the track to be played sp.dwItem = Mci.MCI_STATUS_LENGTH; sp.dwTrack = track; ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_TRACK | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("MCI_STATUS failed ({0})\n", ret); return; } if (_IsPlaying) { if (_PlayTrack == track) { return; } Stop(); } Mci.PlayParams pp; pp.dwFrom = Mci.MCI_MAKE_TMSF(track, 0, 0, 0); pp.dwTo = (sp.dwReturn << 8) | track; pp.dwCallback = _Form.Handle; ret = Mci.Play(_DeviceID, Mci.MCI_PLAY, Mci.MCI_NOTIFY | Mci.MCI_FROM | Mci.MCI_TO, ref pp); if (ret != 0) { Con.DPrint("CDAudio: MCI_PLAY failed ({0})\n", ret); return; } _IsLooping = looping; _PlayTrack = track; _IsPlaying = true; if (_Volume == 0) { Pause(); } }
/// <summary> /// SV_RecursiveHullCheck /// </summary> public static bool RecursiveHullCheck(hull_t hull, int num, float p1f, float p2f, ref Vector3 p1, ref Vector3 p2, trace_t trace) { // check for empty if (num < 0) { if (num != Contents.CONTENTS_SOLID) { trace.allsolid = false; if (num == Contents.CONTENTS_EMPTY) { trace.inopen = true; } else { trace.inwater = true; } } else { trace.startsolid = true; } return(true); // empty } if (num < hull.firstclipnode || num > hull.lastclipnode) { Sys.Error("SV_RecursiveHullCheck: bad node number"); } // // find the point distances // short[] node_children = hull.clipnodes[num].children; mplane_t plane = hull.planes[hull.clipnodes[num].planenum]; float t1, t2; if (plane.type < 3) { t1 = Mathlib.Comp(ref p1, plane.type) - plane.dist; t2 = Mathlib.Comp(ref p2, plane.type) - plane.dist; } else { t1 = Vector3.Dot(plane.normal, p1) - plane.dist; t2 = Vector3.Dot(plane.normal, p2) - plane.dist; } if (t1 >= 0 && t2 >= 0) { return(RecursiveHullCheck(hull, node_children[0], p1f, p2f, ref p1, ref p2, trace)); } if (t1 < 0 && t2 < 0) { return(RecursiveHullCheck(hull, node_children[1], p1f, p2f, ref p1, ref p2, trace)); } // put the crosspoint DIST_EPSILON pixels on the near side float frac; if (t1 < 0) { frac = (t1 + DIST_EPSILON) / (t1 - t2); } else { frac = (t1 - DIST_EPSILON) / (t1 - t2); } if (frac < 0) { frac = 0; } if (frac > 1) { frac = 1; } float midf = p1f + (p2f - p1f) * frac; Vector3 mid = p1 + (p2 - p1) * frac; int side = (t1 < 0) ? 1 : 0; // move up to the node if (!RecursiveHullCheck(hull, node_children[side], p1f, midf, ref p1, ref mid, trace)) { return(false); } if (HullPointContents(hull, node_children[side ^ 1], ref mid) != Contents.CONTENTS_SOLID) { // go past the node return(RecursiveHullCheck(hull, node_children[side ^ 1], midf, p2f, ref mid, ref p2, trace)); } if (trace.allsolid) { return(false); // never got out of the solid area } //================== // the other side of the node is solid, this is the impact point //================== if (side == 0) { trace.plane.normal = plane.normal; trace.plane.dist = plane.dist; } else { trace.plane.normal = -plane.normal; trace.plane.dist = -plane.dist; } while (HullPointContents(hull, hull.firstclipnode, ref mid) == Contents.CONTENTS_SOLID) { // shouldn't really happen, but does occasionally frac -= 0.1f; if (frac < 0) { trace.fraction = midf; trace.endpos = mid; Con.DPrint("backup past 0\n"); return(false); } midf = p1f + (p2f - p1f) * frac; mid = p1 + (p2 - p1) * frac; } trace.fraction = midf; trace.endpos = mid; return(false); }
/// <summary> /// ED_LoadFromFile /// The entities are directly placed in the array, rather than allocated with /// ED_Alloc, because otherwise an error loading the map would have entity /// number references out of order. /// /// Creates a server's entity / program execution context by /// parsing textual entity definitions out of an ent file. /// /// Used for both fresh maps and savegame loads. A fresh map would also need /// to call ED_CallSpawnFunctions () to let the objects initialize themselves. /// </summary> public static void LoadFromFile(string data) { edict_t ent = null; int inhibit = 0; Progs.GlobalStruct.time = (float)Server.sv.time; // parse ents while (true) { // parse the opening brace data = Common.Parse(data); if (data == null) { break; } if (Common.Token != "{") { Sys.Error("ED_LoadFromFile: found {0} when expecting {", Common.Token); } if (ent == null) { ent = Server.EdictNum(0); } else { ent = Server.AllocEdict(); } data = ParseEdict(data, ent); // remove things from different skill levels or deathmatch if (Host.Deathmatch != 0) { if (((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_DEATHMATCH) != 0) { Server.FreeEdict(ent); inhibit++; continue; } } else if ((Host.CurrentSkill == 0 && ((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_EASY) != 0) || (Host.CurrentSkill == 1 && ((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_MEDIUM) != 0) || (Host.CurrentSkill >= 2 && ((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_HARD) != 0)) { Server.FreeEdict(ent); inhibit++; continue; } // // immediately call spawn function // if (ent.v.classname == 0) { Con.Print("No classname for:\n"); Print(ent); Server.FreeEdict(ent); continue; } // look for the spawn function int func = IndexOfFunction(GetString(ent.v.classname)); if (func == -1) { Con.Print("No spawn function for:\n"); Print(ent); Server.FreeEdict(ent); continue; } Progs.GlobalStruct.self = Server.EdictToProg(ent); Execute(func); } Con.DPrint("{0} entities inhibited\n", inhibit); }
/// <summary> /// PR_LoadProgs /// </summary> public static void LoadProgs() { FreeHandles(); QBuiltins.ClearState(); _DynamicStrings.Clear(); // flush the non-C variable lookup cache for (int i = 0; i < GEFV_CACHESIZE; i++) { _gefvCache[i].field = null; } CRC.Init(out _Crc); byte[] buf = Common.LoadFile("progs.dat"); _Progs = Sys.BytesToStructure <dprograms_t>(buf, 0); if (_Progs == null) { Sys.Error("PR_LoadProgs: couldn't load progs.dat"); } Con.DPrint("Programs occupy {0}K.\n", buf.Length / 1024); for (int i = 0; i < buf.Length; i++) { CRC.ProcessByte(ref _Crc, buf[i]); } // byte swap the header _Progs.SwapBytes(); if (_Progs.version != PROG_VERSION) { Sys.Error("progs.dat has wrong version number ({0} should be {1})", _Progs.version, PROG_VERSION); } if (_Progs.crc != PROGHEADER_CRC) { Sys.Error("progs.dat system vars have been modified, progdefs.h is out of date"); } // Functions _Functions = new dfunction_t[_Progs.numfunctions]; int offset = _Progs.ofs_functions; for (int i = 0; i < _Functions.Length; i++, offset += dfunction_t.SizeInBytes) { _Functions[i] = Sys.BytesToStructure <dfunction_t>(buf, offset); _Functions[i].SwapBytes(); } // strings offset = _Progs.ofs_strings; int str0 = offset; for (int i = 0; i < _Progs.numstrings; i++, offset++) { // count string length while (buf[offset] != 0) { offset++; } } int length = offset - str0; _Strings = Encoding.ASCII.GetString(buf, str0, length); // Globaldefs _GlobalDefs = new ddef_t[_Progs.numglobaldefs]; offset = _Progs.ofs_globaldefs; for (int i = 0; i < _GlobalDefs.Length; i++, offset += ddef_t.SizeInBytes) { _GlobalDefs[i] = Sys.BytesToStructure <ddef_t>(buf, offset); _GlobalDefs[i].SwapBytes(); } // Fielddefs _FieldDefs = new ddef_t[_Progs.numfielddefs]; offset = _Progs.ofs_fielddefs; for (int i = 0; i < _FieldDefs.Length; i++, offset += ddef_t.SizeInBytes) { _FieldDefs[i] = Sys.BytesToStructure <ddef_t>(buf, offset); _FieldDefs[i].SwapBytes(); if ((_FieldDefs[i].type & DEF_SAVEGLOBAL) != 0) { Sys.Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); } } // Statements _Statements = new dstatement_t[_Progs.numstatements]; offset = _Progs.ofs_statements; for (int i = 0; i < _Statements.Length; i++, offset += dstatement_t.SizeInBytes) { _Statements[i] = Sys.BytesToStructure <dstatement_t>(buf, offset); _Statements[i].SwapBytes(); } // Swap bytes inplace if needed if (!BitConverter.IsLittleEndian) { offset = _Progs.ofs_globals; for (int i = 0; i < _Progs.numglobals; i++, offset += 4) { SwapHelper.Swap4b(buf, offset); } } GlobalStruct = Sys.BytesToStructure <globalvars_t>(buf, _Progs.ofs_globals); _Globals = new float[_Progs.numglobals - globalvars_t.SizeInBytes / 4]; Buffer.BlockCopy(buf, _Progs.ofs_globals + globalvars_t.SizeInBytes, _Globals, 0, _Globals.Length * 4); _EdictSize = _Progs.entityfields * 4 + dedict_t.SizeInBytes - entvars_t.SizeInBytes; _HGlobals = GCHandle.Alloc(_Globals, GCHandleType.Pinned); _GlobalsAddr = _HGlobals.AddrOfPinnedObject().ToInt64(); _HGlobalStruct = GCHandle.Alloc(Progs.GlobalStruct, GCHandleType.Pinned); _GlobalStructAddr = _HGlobalStruct.AddrOfPinnedObject().ToInt64(); }
/// <summary> /// CL_ParseServerInfo /// </summary> static void ParseServerInfo() { Con.DPrint("Serverinfo packet received.\n"); // // wipe the client_state_t struct // ClearState(); // parse protocol version number int i = Net.Reader.ReadLong(); if (i != Protocol.PROTOCOL_VERSION) { Con.Print("Server returned version {0}, not {1}", i, Protocol.PROTOCOL_VERSION); return; } // parse maxclients cl.maxclients = Net.Reader.ReadByte(); if (cl.maxclients < 1 || cl.maxclients > QDef.MAX_SCOREBOARD) { Con.Print("Bad maxclients ({0}) from server\n", cl.maxclients); return; } cl.scores = new scoreboard_t[cl.maxclients];// Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); for (i = 0; i < cl.scores.Length; i++) { cl.scores[i] = new scoreboard_t(); } // parse gametype cl.gametype = Net.Reader.ReadByte(); // parse signon message string str = Net.Reader.ReadString(); cl.levelname = Common.Copy(str, 40); // seperate the printfs so the server message can have a color Con.Print(ConsoleBar); Con.Print("{0}{1}\n", (char)2, str); // // first we go through and touch all of the precache data that still // happens to be in the cache, so precaching something else doesn't // needlessly purge it // // precache models Array.Clear(cl.model_precache, 0, cl.model_precache.Length); int nummodels; string[] model_precache = new string[QDef.MAX_MODELS]; for (nummodels = 1; ; nummodels++) { str = Net.Reader.ReadString(); if (String.IsNullOrEmpty(str)) { break; } if (nummodels == QDef.MAX_MODELS) { Con.Print("Server sent too many model precaches\n"); return; } model_precache[nummodels] = str; Mod.TouchModel(str); } // precache sounds Array.Clear(cl.sound_precache, 0, cl.sound_precache.Length); int numsounds; string[] sound_precache = new string[QDef.MAX_SOUNDS]; for (numsounds = 1; ; numsounds++) { str = Net.Reader.ReadString(); if (String.IsNullOrEmpty(str)) { break; } if (numsounds == QDef.MAX_SOUNDS) { Con.Print("Server sent too many sound precaches\n"); return; } sound_precache[numsounds] = str; Sound.TouchSound(str); } // // now we try to load everything else until a cache allocation fails // for (i = 1; i < nummodels; i++) { cl.model_precache[i] = Mod.ForName(model_precache[i], false); if (cl.model_precache[i] == null) { Con.Print("Model {0} not found\n", model_precache[i]); return; } KeepaliveMessage(); } Sound.BeginPrecaching(); for (i = 1; i < numsounds; i++) { cl.sound_precache[i] = Sound.PrecacheSound(sound_precache[i]); KeepaliveMessage(); } Sound.EndPrecaching(); // local state _Entities[0].model = cl.worldmodel = cl.model_precache[1]; Render.NewMap(); Host.NoClipAngleHack = false; // noclip is turned off at start GC.Collect(); }
/// <summary> /// Cache_Report /// </summary> public static void Report() { Con.DPrint("{0,4:F1} megabyte data cache, used {1,4:F1} megabyte\n", _Capacity / (float)(1024 * 1024), _BytesAllocated / (float)(1024 * 1024)); }
/// <summary> /// BuildTris /// Generate a list of trifans or strips for the model, which holds for all frames /// </summary> static void BuildTris() { int[] bestverts = new int[1024]; int[] besttris = new int[1024]; // Uze // All references to pheader from model.c changed to _AliasHdr (former paliashdr) // // build tristrips // stvert_t[] stverts = Mod.STVerts; dtriangle_t[] triangles = Mod.Triangles; _NumOrder = 0; _NumCommands = 0; Array.Clear(_Used, 0, _Used.Length); // memset (used, 0, sizeof(used)); int besttype = 0, len; for (int i = 0; i < _AliasHdr.numtris; i++) { // pick an unused triangle and start the trifan if (_Used[i] != 0) { continue; } int bestlen = 0; for (int type = 0; type < 2; type++) { for (int startv = 0; startv < 3; startv++) { if (type == 1) { len = StripLength(i, startv); } else { len = FanLength(i, startv); } if (len > bestlen) { besttype = type; bestlen = len; for (int j = 0; j < bestlen + 2; j++) { bestverts[j] = _StripVerts[j]; } for (int j = 0; j < bestlen; j++) { besttris[j] = _StripTris[j]; } } } } // mark the tris on the best strip as used for (int j = 0; j < bestlen; j++) { _Used[besttris[j]] = 1; } if (besttype == 1) { _Commands[_NumCommands++] = (bestlen + 2); } else { _Commands[_NumCommands++] = -(bestlen + 2); } Union4b uval = Union4b.Empty; for (int j = 0; j < bestlen + 2; j++) { // emit a vertex into the reorder buffer int k = bestverts[j]; _VertexOrder[_NumOrder++] = k; // emit s/t coords into the commands stream float s = stverts[k].s; float t = stverts[k].t; if (triangles[besttris[0]].facesfront == 0 && stverts[k].onseam != 0) { s += _AliasHdr.skinwidth / 2; // on back side } s = (s + 0.5f) / _AliasHdr.skinwidth; t = (t + 0.5f) / _AliasHdr.skinheight; uval.f0 = s; _Commands[_NumCommands++] = uval.i0; uval.f0 = t; _Commands[_NumCommands++] = uval.i0; } } _Commands[_NumCommands++] = 0; // end of list marker Con.DPrint("{0,3} tri {1,3} vert {2,3} cmd\n", _AliasHdr.numtris, _NumOrder, _NumCommands); _AllVerts += _NumOrder; _AllTris += _AliasHdr.numtris; }
// NET_Init (void) public static void Init() { for (int i2 = 0; i2 < _HostCache.Length; i2++) { _HostCache[i2] = new hostcache_t(); } if (_Drivers == null) { if (Common.HasParam("-playback")) { _Drivers = new INetDriver[] { new NetVcr() }; } else { _Drivers = new INetDriver[] { new NetLoop(), NetDatagram.Instance }; } } if (_LanDrivers == null) { _LanDrivers = new INetLanDriver[] { NetTcpIp.Instance }; } if (Common.HasParam("-record")) { _IsRecording = true; } int i = Common.CheckParm("-port"); if (i == 0) { i = Common.CheckParm("-udpport"); } if (i == 0) { i = Common.CheckParm("-ipxport"); } if (i > 0) { if (i < Common.Argc - 1) { _DefHostPort = Common.atoi(Common.Argv(i + 1)); } else { Sys.Error("Net.Init: you must specify a number after -port!"); } } HostPort = _DefHostPort; if (Common.HasParam("-listen") || Client.cls.state == cactive_t.ca_dedicated) { _IsListening = true; } int numsockets = Server.svs.maxclientslimit; if (Client.cls.state != cactive_t.ca_dedicated) { numsockets++; } _FreeSockets = new List <qsocket_t>(numsockets); _ActiveSockets = new List <qsocket_t>(numsockets); for (i = 0; i < numsockets; i++) { _FreeSockets.Add(new qsocket_t()); } SetNetTime(); // allocate space for network message buffer Message = new MsgWriter(NET_MAXMESSAGE); // SZ_Alloc (&net_message, NET_MAXMESSAGE); Reader = new MsgReader(Net.Message); if (_MessageTimeout == null) { _MessageTimeout = new Cvar("net_messagetimeout", "300"); _HostName = new Cvar("hostname", "UNNAMED"); } Cmd.Add("slist", Slist_f); Cmd.Add("listen", Listen_f); Cmd.Add("maxplayers", MaxPlayers_f); Cmd.Add("port", Port_f); // initialize all the drivers _DriverLevel = 0; foreach (INetDriver driver in _Drivers) { driver.Init(); if (driver.IsInitialized && _IsListening) { driver.Listen(true); } _DriverLevel++; } //if (*my_ipx_address) // Con_DPrintf("IPX address %s\n", my_ipx_address); if (!String.IsNullOrEmpty(_MyTcpIpAddress)) { Con.DPrint("TCP/IP address {0}\n", _MyTcpIpAddress); } }
/* * ========= * PF_dprint * ========= */ static void PF_dprint() { Con.DPrint(PF_VarString(0)); }