Dumping status bar layout to file (Q2)

Discuss programming topics for the various GPL'd game engine sources.
Post Reply
Knightmare
Posts: 63
Joined: Thu Feb 09, 2012 1:55 am

Dumping status bar layout to file (Q2)

Post by Knightmare »

In the process of adding scripted client-side HUDs to KMQ2, I found that mod compatibility is an issue. A HUD script made for a vanilla game DLL won't completely support CTF, or Lithium, Rocket Arena, etc. So tailored variants for each mod / gamemode will have to be made.

Sometimes the source for a mod run on a server is not available, and going through the binary .dll with a hex editor to find the correct status layout string (to use as a reference for the tailored client-side HUD script) is a PITA. So I've added a console command that dumps the current status bar layout string to a text file. This is made a bit challenging because the layout string is stored across multiple configstrings. I'm posting it here, as maybe someone else will find it useful.

This code can be pasted into cl_scrn.c right after SCR_Sky_f():

Code: Select all

/*
================
SCR_SetHud_f

Saves the statusbar layout to a file
================
*/
void SCR_DumpStatusLayout_f (void)
{
	char	buffer[2048];
	int		i, j, bufcount;
	FILE	*f;
	char	*p;
	char	name[MAX_OSPATH];

	if (Cmd_Argc() != 2)
	{
		Com_Printf ("usage: dumpstatuslayout <filename>\n");
		return;
	}

	Com_sprintf (name, sizeof(name), "%s/%s.txt", FS_Gamedir(), Cmd_Argv(1));

	Com_Printf ("Dumped statusbar layout to %s.\n", name);
	FS_CreatePath (name);
	f = fopen (name, "w");
	if (!f)
	{
		Com_Printf ("ERROR: couldn't open.\n");
		return;
	}

	// statusbar layout is in multiple configstrings
	// starting at CS_STATUSBAR and ending at CS_AIRACCEL
	p = &buffer[0];
	bufcount = 0;
	for (i=CS_STATUSBAR; i<CS_AIRACCEL; i++)
	{
		for (j=0; j<MAX_QPATH; j++)
		{
			// check for end
			if (cl.configstrings[i][j] == '\0')
				break;

			*p = cl.configstrings[i][j];

			// check for "endif", insert newline after
			if (*p == 'f' && *(p-1) == 'i' && *(p-2) == 'd' && *(p-3) == 'n' && *(p-4) == 'e')
			{
				p++;
				bufcount++;
				*p = '\n';
			}
			p++;
			bufcount++;
		}
	}

	fwrite(&buffer, 1, bufcount, f);

	fclose (f);
}
Don't forget to add the command in SCR_Init():

Code: Select all

void SCR_Init (void)
{
	.
	.
	.
	Cmd_AddCommand ("sky",SCR_Sky_f);
	Cmd_AddCommand ("dumpstatuslayout", SCR_DumpStatusLayout_f);
And remove it in SCR_Shutdown():

Code: Select all

void SCR_Shutdown (void)
{
	.
	.
	.
	Cmd_RemoveCommand ("sky");
	Cmd_RemoveCommand ("dumpstatuslayout");
Post Reply