Tutorial *107*

This is my first tutorial here. Be nice.

When I started coding, my biggest aim was, well, making Quake bigger. If you ever used noclip to walk outside the level and kept on going, you'd soon find out your position will be wraped after not too long and you will pop up on the other side of the level. This is because of the network code in Quake. The coordinate system used in Quake allows you to walk from the point [-4096, -4096] to [4096, 4096] because coordinates are converted to SHORTs (2^16). By increasing this to LONGs, the coordinate system will increase to [-1048576, -1048576] by [1048576, 1048576] meaning you now have the power to walk through 256*256 Quake maps. This will mean a huge increase in potential, however, also in bandwith usage. For single player this is not a problem, however for Deathmatch servers it is. That's why we'll give the server full control over what method to use.

First off, lets add the neccesary definitions to protocol.h. Under the line


#define PROTOCOL_VERSION 15

, add the following lines:


#define PROTOCOL_NEWVERSION 16

int protocolversion;

this is to keep track which protocol the current server is using. Next up, we need to have the host check wether or not long coordinates are used. In Host_Init, find the lines that read


if (COM_CheckParm ("-minmemory"))

parms->memsize = minimum_memory;

and add the following lines:


if (COM_CheckParm ("-longcoords"))

protocolversion = PROTOCOL_NEWVERSION;

else

protocolversion = PROTOCOL_VERSION;

Any clients that log in nead to know what protocol to use. This is the static defined PROTOCOL_VERSION by default, however this should be dynamic. In SV_SendServerinfo find the lines


MSG_WriteLong (&client->message, PROTOCOL_VERSION);

and replace with


MSG_WriteLong (&client->message, protocolversion);

to send the current protocol version. Now we need to send the extra data if neccesary. Replace MSG_WriteCoord with this:


void MSG_WriteCoord (sizebuf_t *sb, float f)

{

if (protocolversion == PROTOCOL_NEWVERSION)

MSG_WriteLong (sb, (int)(f*8));

else

MSG_WriteShort (sb, (int)(f*8));

}

Okay, that takes care of the server-side. The client-side is easy: we can use the already defined protocolversion, since we're either not the host or we're playing single-player, meaning we set the protocolversion when the host is initialised and send it to ourselves, meaning no change in the value of protocolversion. First off, lets have it check what protocol the server uses. In CL_ParseServerinfo, find the line


if (i != PROTOCOL_VERSION)

and replace with


protocolversion = i;

if (i != PROTOCOL_VERSION && i != PROTOCOL_NEWVERSION)

now, all we need to do is receive the extended packages if necessary: replace the function float MSG_ReadCoord with


float MSG_ReadCoord (void)

{

if (protocolversion == PROTOCOL_NEWVERSION)

return MSG_ReadLong() * (1.0/8);

else

return MSG_ReadShort() * (1.0/8);

}

This should take care of the coordinate system. Just start up a map and start walking outside the level... it will take a LOT of time before you wrap and see the map again! As a last remark, it might be usefull to increase the cut-off distance. If you are using OpenGL, you can do that like this: (Thank you wParam for reminding me)
find the line that reads


MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096);

the 4096 is the maximum view distance, but since it is calculated as a cube around you, you can only see 50% of this distance forward. Since I use BIG maps (think Delta Force) i have this set at least to


MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 12288);

however setting it to 8192 should suffice. Remember, the host can switch this on with the command parameter -longcoords, but this will require a great deal of extra bandwith as all positions are sent in 50% bigger packages, limiting the use mostly to single-player or LAN-based play.


 
Not logged in
Sign up
Login:
Passwd: