+int history_line;
+int history_line_idx;
+char history_savedline[MAX_INPUTLINE];
+
+static void Key_History_Init()
+{
+ qfile_t *historyfile = FS_OpenRealFile("dp_history.txt", "r", false);
+ if(historyfile)
+ {
+ char buf[MAX_INPUTLINE];
+ int bufpos;
+ int c;
+
+ *buf = ']';
+ bufpos = 1;
+ for(;;)
+ {
+ c = FS_Getc(historyfile);
+ if(c < 0 || c == 0 || c == '\r' || c == '\n')
+ {
+ if(bufpos > 1)
+ {
+ buf[bufpos] = 0;
+ Con_AddLine(buf, bufpos, CON_MASK_INPUT);
+ bufpos = 1;
+ }
+ if(c < 0)
+ break;
+ }
+ else
+ {
+ if(bufpos < MAX_INPUTLINE - 1)
+ buf[bufpos++] = c;
+ }
+ }
+
+ FS_Close(historyfile);
+ }
+
+ history_line = -1;
+}
+
+static void Key_History_Shutdown()
+{
+ // TODO write history to a file
+
+ qfile_t *historyfile = FS_OpenRealFile("dp_history.txt", "w", false);
+ if(historyfile)
+ {
+ int l = -1;
+ while((l = Con_FindNextLine(CON_MASK_INPUT, 0, l)) != -1)
+ FS_Printf(historyfile, "%s\n", Con_GetLine(l) + 1); // +1: skip the ]
+ FS_Close(historyfile);
+ }
+}
+
+static void Key_History_Push()
+{
+ int mask;
+
+ mask = CON_MASK_INPUT;
+ if(!key_line[1]) // empty?
+ mask = 0;
+ if(!strcmp(key_line, "]quit")) // putting these into the history just sucks
+ mask = 0;
+ Con_AddLine(key_line, strlen(key_line), mask);
+ Con_PrintNotToHistory(key_line); // don't mark empty lines as history
+ Con_PrintNotToHistory("\n");
+ history_line = -1;
+}
+
+static void Key_History_Up()
+{
+ int l;
+
+ if(history_line >= 0)
+ {
+ history_line = Con_GetLineByID(history_line_idx);
+ if(history_line == -1)
+ history_line = -2; // -2 means before first
+ }
+
+ // invalid history line? bad
+ if(history_line == -2)
+ return;
+
+ if(history_line == -1) // editing the "new" line
+ strlcpy(history_savedline, key_line, sizeof(history_savedline));
+ l = Con_FindPrevLine(CON_MASK_INPUT, 0, history_line);
+ if(l != -1)
+ {
+ history_line = l;
+ history_line_idx = Con_GetLineID(l);
+ strlcpy(key_line, Con_GetLine(history_line), sizeof(key_line));
+ }
+
+ key_linepos = strlen(key_line);
+}
+
+static void Key_History_Down()
+{
+ int l;
+
+ if(history_line >= 0)
+ {
+ history_line = Con_GetLineByID(history_line_idx);
+ if(history_line == -1)
+ history_line = -2; // -2 means before first
+ }
+
+ if(history_line == -1) // editing the "new" line
+ return;
+
+ // invalid history line? take the first line then
+ if(history_line == -2)
+ history_line = -1; // next Con_FindNextLine will fix it
+
+ l = Con_FindNextLine(CON_MASK_INPUT, 0, history_line);
+ if(l != -1)
+ {
+ history_line = l;
+ history_line_idx = Con_GetLineID(l);
+ strlcpy(key_line, Con_GetLine(history_line), sizeof(key_line));
+ }
+ else
+ {
+ history_line = -1;
+ strlcpy(key_line, history_savedline, sizeof(key_line));
+ }
+
+ key_linepos = strlen(key_line);
+}