ssqc sbar control (darkplaces, psp soon)

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply

Is this nice?

Yes
2
100%
No
0
No votes
 
Total votes: 2

Jukki
Posts: 214
Joined: Wed Apr 07, 2010 4:59 am

ssqc sbar control (darkplaces, psp soon)

Post by Jukki »

When i started with quake i tought, well how i add images to screen? Ok of course i could modify engine or use csqc, but wht if i realy want to do it in ssqc? Like engines like psp doesnt have this feature. Today i desided i could try since i got my nice little achievement code working. This is my "Qc sbar"

(note: this is for DARKPLACES, yes i know there is csqc, SO WHAT :P, psp part included soon when i get it working)

Well lets start:

In protocol.h

After #define svc_skybox 37 add this code

Code: Select all

#define svc_qcsbar          39 //jukki qcsbar
this is just define for svc thing

In cl_parse.c

Find this piece of code in CL_ParseServerMessage:
case svc_skybox:
R_SetSkyBox(MSG_ReadString());
break;

And after it add this:

Code: Select all

case svc_qcsbar: //jukki qcsbar
Sbar_EditQcSbar (MSG_ReadByte(),MSG_ReadByte(),MSG_ReadByte(),MSG_ReadString());
break;
this code calls the Image change function in sbar.c

also find svc_skybox in a list of other svc_ stuff in top of cl_parse and insert svc_qcsbar in second line after the svc_skybox

In sbar.c

Before Sbar_ShowScores add thease pieces of code:

Code: Select all

// jukki draw sbar from qc
typedef struct qcsbar_s
{
    float screenx;
    float screeny;
    char imgpath[MAX_QPATH];
    cachepic_t *qcimage;
}
qcsbar_t;

qcsbar_t QcSbarImage[49]; //change this for how many images you want, now 50
void  Sbar_EditQcSbar (int qcsbarnum, int xplace, int yplace, char *pathname)
{
    QcSbarImage[qcsbarnum].screenx = xplace;
    QcSbarImage[qcsbarnum].screeny = yplace;
    sprintf(QcSbarImage[qcsbarnum].imgpath, pathname);
    QcSbarImage[qcsbarnum].qcimage = Draw_CachePic (pathname);
}
Here we define a new struct that contains the info of our image, then we define a qcsbar_t variable that has all the images, you can edit the [49] for how many qc sbar images you want. By default i made it 50 images. The function is the function that sets the values to our image to image variable

then look for function sbar_newmap and add this code in it:

Code: Select all

    int i;
    for (i = 0; i < 50; i++)
    {
        QcSbarImage[i].screenx = 0;
        QcSbarImage[i].screeny = 0;
        QcSbarImage[i].qcimage = NULL;
    }
this small piece of code clears all the image data when loading new map. If you edited the number of image variables, then edit the 50 to what you did.

Then go to Sbar_Draw function and at the end of function just before crosshair code add this small piece of code

Code: Select all

                for (i = 0;i < 50;i = i + 1)
                {
                    if (QcSbarImage[i].qcimage)
                    {
                        DrawQ_Pic ((vid_conwidth.integer - QcSbarImage[i].qcimage->width)/2 + QcSbarImage[i].screenx,(vid_conheight.integer - QcSbarImage[i].qcimage->height)/2 + QcSbarImage[i].screeny, QcSbarImage[i].qcimage, 0, 0, 1, 1, 1, 1, 0);
                    }
                }[quote]

This code draws the images to the screen. It will draw to center of screen if x and y values are 0[/quote]
In svvm_cmds.c
after VM_SV_centerprint function add this function:

Code: Select all

/*
=================
VM_SetQcSbarImg jukki qc sbar

Draws or edits the image in sbar for client

SetQcSbarImg(clientent, target, x, y, imgpath)
=================
*/
static void VM_SetQcSbarImg (void)
{
	client_t	*client;
	int			entnum, targetnum, xplace, yplace;
	char pathname[VM_STRINGTEMP_LENGTH];

	VM_SAFEPARMCOUNTRANGE(5, 8, VM_SetQcSbarImg);
	VM_VarString(4, pathname, sizeof(pathname));

	entnum = PRVM_G_EDICTNUM(OFS_PARM0);
	targetnum = PRVM_G_FLOAT(OFS_PARM1);
	xplace = PRVM_G_FLOAT(OFS_PARM2);
	yplace = PRVM_G_FLOAT(OFS_PARM3);


	if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
	{
		VM_Warning("tried to edit sbar for a non-client\n");
		return;
	}

	client = svs.clients + entnum-1;
	if (!client->netconnection)
		return;

	MSG_WriteChar(&client->netconnection->message,svc_qcsbar);
	MSG_WriteByte (&client->netconnection->message, yplace);
	MSG_WriteByte (&client->netconnection->message, xplace);
	MSG_WriteByte (&client->netconnection->message, targetnum);
	MSG_WriteString (&client->netconnection->message, pathname);
}
this is the builtin that is basicaly edited centerprint function, it sends the MSG_ thingys and checks if the entity is player (notice the MSG_WriteByte are reversed)

Then look for VM_stof in vm_sv_builtins and above it should be NULL, replace this null with this line:

Code: Select all

VM_SetQcSbarImg
Now saveand complie, it should work REMEBER DARKPLACES.

So now we move to qc, at the end of your defs.qc add this line:

Code: Select all

void SetQcSbarImg(entity clientent, float targetnum, float x, float y, string imgpath) = #80;
and then we can put a 2 new impulses to test this out. add thease lines to your impulseCommands:

Code: Select all

	if (self.impulse == 219)
		SetQcSbarImg(self, 7, -100, -100, "gfx/disk");
	if (self.impulse == 220)
		SetQcSbarImg(self, 8, 100, 100, "gfx/numbers/num_1");
Then launch your game and type thease 2 impulses to console and see the magic of qc sbar. :D

Then little explaining how this works. If you did put that draw code in sbar where i said your images should be top of every other image exept crosshair. the first variable (entity) of builtin function is the entity (should be client) that gets drawn the image, second variiable is the id of the image, it can be from 0 - 49 (or if you desided to have more then more) smaler id is drawn before meaning image with id 49 is top of each other pics. then next 2 floats are the x and y cordinants, and last string is the file (note dont include the extension). If you find any problem s with the code then tell me. I write the psp part of this tutorial later :)

(also my first tut here WOHOO)

comments, suggestions, fixes?
Mexicouger
Posts: 514
Joined: Sat May 01, 2010 10:12 pm
Contact:

Post by Mexicouger »

I am impressed Jukki! I didn't think you had advanced in C enough to create something as complex as QuakeC image drawing.

I had this idea a while back, but never thought to do it or try it.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

how does this interact with svc_showlmp?
Jukki
Posts: 214
Joined: Wed Apr 07, 2010 4:59 am

Post by Jukki »

lol, didnt even know about svc_showlmp. Well this was just a expirement mostly, and psp version doesnt have svc_showlmp
behind_you
Posts: 237
Joined: Sat Feb 05, 2011 6:57 am
Location: Tripoli, Libya

Post by behind_you »

Nice work there.
Post Reply