Page 1 of 1

Session to Session Command History (Human Readable)

Posted: Fri Jun 25, 2010 6:18 am
by Baker
Every engine should have a command history. DarkPlaces recently got one and it makes life so much easier.

PSP engines lack of a command history is a major nuisance when it comes to debugging and testing ... even with the on-screen keyboard it takes WAY too long to get things done.

Anyway, this modification is borrowed almost verbatim from ezQuake 1.9.

I feel it is superior to the incarnation in JoeQuake because the command line history is human readable and editable, whereas the JoeQuake (SonsQuake, actually ... for those who remember that engine) method ends up with a lot of 0x00 characters in it.

Anyways ...

1. Host.c

Find and add the yellow ...
scr_disabled_for_loading = true;

Host_WriteConfiguration ();

if (con_initialized)
History_Shutdown ();


CDAudio_Shutdown ();
2a. Keys.c

Add this above the Key_Init function ...

Code: Select all

// Added by VVD {
void History_Init (void)
{
	int i, c;
	FILE *hf;

	for (i = 0; i < CMDLINES; i++) {
		key_lines[i][0] = ']';
		key_lines[i][1] = 0;
	}
	key_linepos = 1;

//	if (cl_savehistory.value)
		if ((hf = fopen(HISTORY_FILE_NAME, "rt")))
		{
			do
			{
				i = 1;
				do
				{
					c = fgetc(hf);
					key_lines[edit_line][i++] = c;
				} while (c != '\n' && c != EOF && i < MAXCMDLINE);
				key_lines[edit_line][i - 1] = 0;
				edit_line = (edit_line + 1) & (CMDLINES - 1);
			} while (c != EOF && edit_line < CMDLINES);
			fclose(hf);

			history_line = edit_line = (edit_line - 1) & (CMDLINES - 1);
			key_lines[edit_line][0] = ']';
			key_lines[edit_line][1] = 0;
		}
}

void History_Shutdown (void)
{
	int i;
	FILE *hf;

//	if (cl_savehistory.value)
		if ((hf = fopen(HISTORY_FILE_NAME, "wt")))
		{
			i = edit_line;
			do
			{
				i = (i + 1) & (CMDLINES - 1);
			} while (i != edit_line && !key_lines[i][1]);

			do
			{
				// fprintf(hf, "%s\n", wcs2str(key_lines[i] + 1)); // Baker: I commented this line out because byte colored text isn't a feature in most ordinary engines
				fprintf(hf, "%s\n", key_lines[i] + 1);
				i = (i + 1) & (CMDLINES - 1);
			} while (i != edit_line && key_lines[i][1]);
			fclose(hf);
		}
}
// } Added by VVD
2b. Still keys.c ...

Find ...

Code: Select all

#define		MAXCMDLINE	256
char	key_lines[32][MAXCMDLINE];
And replace with ...

Code: Select all

#define		HISTORY_FILE_NAME	"id1/quake_history.txt"

#define		MAXCMDLINE	256
#define		CMDLINES	32

char	key_lines[CMDLINES][MAXCMDLINE];
We are defining the save history name (which I don't believe should be gamedir specific, but that's just my opinion). Plus we are changing the 32 to a #define.

2c. Still in keys.c ... finally ....
void Key_Init (void)
{
int i;

History_Init ();

#if 0 // This section of code is now done in History_Init
for (i=0 ; i<32 ; i++)
{
key_lines[0] = ']';
key_lines[1] = 0;
}
key_linepos = 1;
#endif

Posted: Tue Oct 12, 2010 9:34 am
by Jukki
awesome. thank you. Helped my day alot

Posted: Mon Mar 14, 2011 6:26 pm
by mh
Should probably go through the rest of keys.c and replace appropriate occurrances of 32 with CMDLINES and of 31 with (CMDLINES - 1); just in case you ever change the #define.

CMDLINES always needs to be a power-of-two as well.

Posted: Mon Mar 14, 2011 7:30 pm
by Baker
mh wrote:Should probably go through the rest of keys.c and replace appropriate occurrances of 32 with CMDLINES and of 31 with (CMDLINES - 1); just in case you ever change the #define.

CMDLINES always needs to be a power-of-two as well.
I did that quite a while ago. :D

See ...

Code: Select all

	if (key < CMDLINES || key > 127)
		return;	// non printable
/End joke

Posted: Mon Mar 14, 2011 7:58 pm
by mh
Somebody put the man on a stage - he's too good for this place! :lol:

Posted: Tue Mar 15, 2011 10:57 am
by mankrip
:lol: Ha!

Posted: Fri Mar 25, 2011 12:16 am
by Team Xlink
Thank you for the tutorial Baker.