Hosting and domain costs until October 2024 have been generously sponsored by dumptruck_ds. Thank you!

EXT CSQC

From Quake Wiki

Revision as of 21:57, 17 January 2008 by KrimZon (talk | contribs) (CSQC_InputEvent)

Introduction

QuakeC code is normally run only on the server as a progs.dat file. Engines which support the EXT_CSQC extension run QuakeC code on the client. This enables the mod to control certain extra features:

  • Customize the status bar.
  • Adjust models and draw extra things on models (even with only one entity on the server).
  • Implement prediction.
  • Override the FOV.
  • Launch sounds locally.
  • Implement what would otherwise require another QSG extension.


By standard, CSQC should be compiled into and loaded from a csprogs.dat. Engines can provide cvars to specify a different name but that isn't part of this extension.


EXT_CSQC is intended to replace as much of the fixed function engine code as possible, without requiring knowledge of the engine code mechanisms and in a way that is consistent with the existing style of QuakeC.


The extension defines the whole csprogs, as well as adding some builtins and constants on the server.

Header Code

On the server:

// EXT_CSQC
// AddStat
void(float index, float type, ...) AddStat = #232; // third parameter is an entity field
float AS_FLOAT_TRUNCATED = 8;
float AS_FLOAT  = 2;
float AS_STRING = 1;
// Entity Sending
.float(entity viewer) SendEntity;
.float Version;
float MSG_ENTITY = 5;

On the client, EXT_CSQC System Globals Fields and Builtins List lists the core code. The following sections in this article explain their use.

Overview

There are two major design factors to be aware of first when beginning to understand Client Side QuakeC:

First is that the render function overrides the entire process of rendering. That is not to say that the CSQC replaces the low level rendering process - the engine provides functions for the CSQC code to call as the modder desires. However, if the CSQC rendering code does not do anything, then nothing will be rendered.

Secondly, CSQC does not automatically recieve any of the engine entities, even the rendering entities that the local client recieves. This acts as cheat protection, preventing players from making a client-side-only radar mod and such. The server mod must explicitly send the entities to the client as described later. It is also an important note that the server entities must still be linked into the world and viewable by a client in order to be sent to it.

Client Programs Entry Points

CSQC_Init

void() CSQC_Init;

This is called when the csprogs.dat is loaded into memory. It is here that sounds, models and images can be precached with precache_sound precache_model and precache_pic.

CSQC_Shutdown

void() CSQC_Shutdown;

This function is called before the csprogs is fully unloaded, both for shutdown and map change. It is possible to store data in cvars to read in after a map change in CSQC_Init, which is feasible in conjunction with the DP_CON_SET extension.

CSQC_InputEvent

float(float event, float key) CSQC_InputEvent;
float EVENT_KEYDOWN = 0;
float EVENT_KEYUP = 1;
float EVENT_MOUSEMOVE = 2;

This function is called on keyboard and mouse events. The event parameter is one of the EVENT_ constants. For keyboard input the key parameter is the quake key code of the key that was pressed or depressed. For mouse input the vector() getmousepos builtin should be used.

CSQC_UpdateView

void() CSQC_UpdateView;

This function overrides the engine drawing code. It orders the rendering of everything including views, scoreboards and huds. If the csqc were to simply return, nothing would be drawn. Areas that the function fails to draw over will contain undefined pixels.

Example code:

void() CSQC_UpdateView =
{
    R_ClearScene();       //wipe the scene, and apply the default rendering values.

    //These lines, if used, specifiy various global view properties to the engine.
    //The engine returns 0 if it accepted the command, and -1 if it had an error.
    //The names listed here are the basic set required for basic compatability.
    R_SetView(VF_MIN_X, 0);
    R_SetView(VF_MIN_Y, 0);
    R_SetView(VF_SIZE_X, cvar("vid_conwidth"));
    R_SetView(VF_SIZE_Y, cvar("vid_conheight"));
    R_SetView(VF_FOV, cvar("fov"));
    R_SetView(VF_ORIGIN, player_org);
    R_SetView(VF_ANGLES, player_ang);
    R_SetView(VF_DRAWWORLD, 1);
    R_SetView(VF_DRAWCROSSHAIR, 1);
    R_SetView(VF_DRAWENGINESBAR, 0);

    // Add any entities that the csqc does not know about
    R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);

    R_DrawScene();        // draw the view

    csqc_drawsbar();       // call to a custom function drawing the status bar
 };

CSQC_ConsoleCommand

float(string s) CSQC_ConsoleCommand;

This function parses console commands entered on the client. The parameter s contains the entire string entered on the console.

The function must return TRUE if it parses the command or FALSE if it does not. Returning false causes the command to then be parsed by the engine, and will display an error message if the command is then not recognised.

Since the function is called before any engine parsing it is possible to override engine commands, for example +showscores and -showscores which would be useful in building a custom status bar and scoreboard.

Sending Data to the Client

Stats

Entities